Decompiled source of FeedbackersForEveryone v0.1.0

FeedbackersForEveryone.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Nyxpiri.ULTRAKILL.NyxLib;
using ULTRAKILL.Portal;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Nyxpiri.ULTRAKILL.FeedbackersForEveryone;

public static class Assets
{
	public static AssetReference ParryFlashPrefab { get; private set; }

	public static GameObject EnemyRevolverBullet { get; private set; }

	public static GameObject EnemyRevolverAltBullet { get; private set; }

	internal static void Initialize()
	{
		LevelQuickLoader.AddQuickLoadLevel("uk_construct");
		Assets.EnableExplosionsPicking();
		Assets.EnableProjectilePicking();
		Assets.AddAssetPicker<SwordsMachine>((Func<SwordsMachine, bool>)delegate(SwordsMachine sm)
		{
			ParryFlashPrefab = sm.gunFlash;
			return true;
		});
		Assets.AddAssetPicker<EnemyRevolver>((Func<EnemyRevolver, bool>)delegate(EnemyRevolver revolver)
		{
			EnemyRevolverBullet = Object.Instantiate<GameObject>(revolver.bullet);
			EnemyRevolverBullet.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)EnemyRevolverBullet);
			EnemyRevolverAltBullet = Object.Instantiate<GameObject>(revolver.altBullet);
			EnemyRevolverAltBullet.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)EnemyRevolverAltBullet);
			return true;
		});
	}
}
internal static class Log
{
	private static ManualLogSource _logger;

	public static void Initialize(ManualLogSource logger)
	{
		Assert.IsNull((object)_logger, "Log.Initialize called when _logger wasn't null?");
		_logger = logger;
	}

	public static void Fatal(object data)
	{
		_logger.LogFatal(data);
	}

	public static void Error(object data)
	{
		_logger.LogError(data);
	}

	public static void Warning(object data)
	{
		_logger.LogWarning(data);
	}

	public static void Message(object data)
	{
		_logger.LogMessage(data);
	}

	public static void Info(object data)
	{
		_logger.LogInfo(data);
	}

	public static void Debug(object data)
	{
		if (Options.LogDebugInfo.Value)
		{
			_logger.LogDebug(data);
		}
	}
}
public static class EnemyFeedbackerEnemyComponentsExtension
{
	public static EnemyFeedbacker GetFeedbacker(this EnemyComponents enemy)
	{
		return enemy.GetMonoByIndex<EnemyFeedbacker>(EnemyFeedbacker.MonoRegistrarIndex);
	}
}
public class EnemyFeedbacker : MonoBehaviour
{
	private struct QueuedParry
	{
		public Action<Vector3> ParryAction;

		public FixedTimeStamp InitTime;

		public Vector3 PosAtTheTime;

		public Vector3 ParryPoint;

		public bool hasPlayedMidwayParry;
	}

	private EnemyComponents _eadd = null;

	public FixedTimeStamp LastParryTimestamp;

	private static FieldInfo timeControllerParryLightFi = typeof(TimeController).GetField("parryLight", BindingFlags.Instance | BindingFlags.NonPublic);

	private List<QueuedParry> _queuedParries = new List<QueuedParry>(2);

	private EnemyType _enemyType = (EnemyType)10;

	public bool Enabled => Cheats.IsCheatEnabled("nyxpiri.feedbackers-for-everyone");

	public bool ReadyToParry => ((FixedTimeStamp)(ref LastParryTimestamp)).TimeSince >= (double)ParryCooldown && Stamina >= ParryCost && Enabled;

	public float ParryCost => (float)Options.ParryStaminaCost[_enemyType].Value * Options.StaminaCostScalar.Value;

	public float ParryCooldown => (float)Options.MinParryCooldowns[_enemyType].Value * Options.MinParryCooldownScalar.Value;

	public float Stamina { get; private set; } = 0f;


	public static int MonoRegistrarIndex { get; private set; }

	public void QueueParry(Vector3 fromPoint, Action<Vector3> parryAction)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		FixedTimeStamp initTime = default(FixedTimeStamp);
		((FixedTimeStamp)(ref initTime)).UpdateToNow();
		_queuedParries.Add(new QueuedParry
		{
			ParryAction = parryAction,
			InitTime = initTime,
			PosAtTheTime = ((Component)this).transform.position,
			ParryPoint = fromPoint
		});
	}

	protected void Awake()
	{
		_eadd = ((Component)this).GetComponent<EnemyComponents>();
		Assert.IsNotNull((Object)(object)_eadd, "");
	}

	public bool CanParry(ProjectileBoostTracker boostTracker, double parryability)
	{
		//IL_0063: 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)
		if (!ReadyToParry)
		{
			return false;
		}
		double num = ((boostTracker.NumBoosts != 0 && (boostTracker.NumEnemyBoosts != 0 || !boostTracker.IsPlayerSourced)) ? (Options.MultiHitParrySkills[_enemyType].Value * (double)Options.MultiHitSkillScalar.Value) : (Options.FirstHitParrySkills[_enemyType].Value * (double)Options.FirstHitSkillScalar.Value));
		if (num - (1.0 - parryability) > 0.0)
		{
			return true;
		}
		return false;
	}

	public void ParryEffect(Vector3 fromPoint)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		//IL_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: 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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: 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_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		Assert.IsTrue(ReadyToParry, "EnemyFeedbacker.ParryEffect called when not ReadyToParry?");
		if (Options.HitstopOnEnemyParry.Value)
		{
			TimeScale.Controller.ParryFlash();
		}
		GameObject val = Object.Instantiate<GameObject>((GameObject)timeControllerParryLightFi.GetValue(TimeScale.Controller), fromPoint, Quaternion.identity, ((Component)this).transform);
		AudioSource componentInChildren = val.GetComponentInChildren<AudioSource>();
		AudioSource componentInChildren2 = val.GetComponentInChildren<AudioSource>();
		componentInChildren2.volume *= Options.EnemyParrySoundScalar.Value;
		val.GetComponent<RemoveOnTime>().time = 0.065f;
		AudioSourceExtensions.SetPitch(componentInChildren, AudioSourceExtensions.GetPitch(componentInChildren) * 1.25f);
		GameObject obj = AddressablesExtensions.ToAsset(Assets.ParryFlashPrefab);
		Vector3 val2 = MonoSingleton<NewMovement>.Instance.HeadPosition - fromPoint;
		GameObject val3 = Object.Instantiate<GameObject>(obj, fromPoint, Quaternion.LookRotation(((Vector3)(ref val2)).normalized), Options.ParryFollowsEnemy.Value ? ((Component)this).transform : null);
		val3.transform.localScale = new Vector3(1f / val3.transform.lossyScale.x, 1f / val3.transform.lossyScale.y, 1f / val3.transform.lossyScale.z);
		Transform transform = val3.transform;
		transform.localScale *= 1.5f;
		Stamina -= ParryCost;
		((FixedTimeStamp)(ref LastParryTimestamp)).UpdateToNow();
	}

	public void ParryMidwayEffect(Vector3 fromPoint)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//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_0026: Expected O, but got Unknown
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>((GameObject)timeControllerParryLightFi.GetValue(TimeScale.Controller), fromPoint, Quaternion.identity, ((Component)this).transform);
		AudioSource componentInChildren = val.GetComponentInChildren<AudioSource>();
		componentInChildren.time = 0.05f;
		componentInChildren.volume *= Options.EnemyParrySoundScalar.Value * 0.5f;
		AudioSourceExtensions.SetPitch(componentInChildren, AudioSourceExtensions.GetPitch(componentInChildren) * 1.25f);
		val.GetComponent<RemoveOnTime>().time = Options.EnemyParryDelay.Value;
		GameObject obj = AddressablesExtensions.ToAsset(Assets.ParryFlashPrefab);
		Vector3 val2 = MonoSingleton<NewMovement>.Instance.HeadPosition - fromPoint;
		GameObject val3 = Object.Instantiate<GameObject>(obj, fromPoint, Quaternion.LookRotation(((Vector3)(ref val2)).normalized), Options.ParryFollowsEnemy.Value ? ((Component)this).transform : null);
		val3.transform.localScale = new Vector3(1f / val3.transform.lossyScale.x, 1f / val3.transform.lossyScale.y, 1f / val3.transform.lossyScale.z);
		Transform transform = val3.transform;
		transform.localScale *= 2f;
	}

	public void ParryFinishEffect(Vector3 fromPoint)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//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_0026: Expected O, but got Unknown
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>((GameObject)timeControllerParryLightFi.GetValue(TimeScale.Controller), fromPoint, Quaternion.identity, ((Component)this).transform);
		AudioSource componentInChildren = val.GetComponentInChildren<AudioSource>();
		componentInChildren.time = 0.05f;
		componentInChildren.volume *= Options.EnemyParrySoundScalar.Value * 0.5f;
		AudioSourceExtensions.SetPitch(componentInChildren, AudioSourceExtensions.GetPitch(componentInChildren) * 1.25f);
		val.GetComponent<RemoveOnTime>().time = Options.EnemyParryDelay.Value;
		GameObject obj = AddressablesExtensions.ToAsset(Assets.ParryFlashPrefab);
		Vector3 val2 = MonoSingleton<NewMovement>.Instance.HeadPosition - fromPoint;
		GameObject val3 = Object.Instantiate<GameObject>(obj, fromPoint, Quaternion.LookRotation(((Vector3)(ref val2)).normalized), Options.ParryFollowsEnemy.Value ? ((Component)this).transform : null);
		val3.transform.localScale = new Vector3(1f / val3.transform.lossyScale.x, 1f / val3.transform.lossyScale.y, 1f / val3.transform.lossyScale.z);
		Transform transform = val3.transform;
		transform.localScale *= 3f;
	}

	protected void Start()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_003a: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		_enemyType = _eadd.Eid.enemyType;
		if ((int)_enemyType == 8)
		{
			V2 component = ((Component)this).GetComponent<V2>();
			if (component.secondEncounter)
			{
				_enemyType = (EnemyType)22;
			}
		}
		CancerousRodent component2 = ((Component)this).GetComponent<CancerousRodent>();
		if ((Object)(object)component2 != (Object)null)
		{
			if (component2.harmless)
			{
				_enemyType = (EnemyType)23;
			}
			else
			{
				_enemyType = (EnemyType)24;
			}
		}
	}

	protected void Update()
	{
	}

	protected void FixedUpdate()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: 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_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		Stamina = Mathf.MoveTowards(Stamina, 1f, Time.fixedDeltaTime * (float)Options.ParryStaminaRechargeRate[_enemyType].Value * Options.StaminaRechargeRateScalar.Value);
		for (int i = 0; i < _queuedParries.Count; i++)
		{
			QueuedParry value = _queuedParries[i];
			float value2 = Options.EnemyParryDelay.Value;
			if (((FixedTimeStamp)(ref value.InitTime)).TimeSince > (double)(value2 * 0.5f) && Options.MidwayParryEffect.Value && !value.hasPlayedMidwayParry)
			{
				ParryMidwayEffect(value.ParryPoint + (Options.ParryFollowsEnemy.Value ? (((Component)this).transform.position - value.PosAtTheTime) : Vector3.zero));
				value.hasPlayedMidwayParry = true;
				_queuedParries[i] = value;
			}
			else if (!(((FixedTimeStamp)(ref value.InitTime)).TimeSince < (double)value2))
			{
				_queuedParries.RemoveAt(i);
				i--;
				value.ParryAction?.Invoke(Options.ParryFollowsEnemy.Value ? (((Component)this).transform.position - value.PosAtTheTime) : Vector3.zero);
			}
		}
	}

	protected void OnDestroy()
	{
	}

	public Vector3 SolveParryForce(Vector3 projectilePosition, Vector3 projectileVelocity)
	{
		//IL_0008: 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_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: 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)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		NewMovement instance = MonoSingleton<NewMovement>.Instance;
		Vector3 headPosition = instance.HeadPosition;
		Vector3 travellerVelocity = instance.travellerVelocity;
		Vector3 val = headPosition - projectilePosition;
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Vector3 val2 = Vector3.Project(travellerVelocity, normalized);
		float magnitude = ((Vector3)(ref val2)).magnitude;
		Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
		val = headPosition - projectilePosition;
		float num = magnitude * ((Vector3.Distance(normalized2, ((Vector3)(ref val)).normalized) > 0.5f) ? (-1f) : 1f);
		Vector3 val3 = travellerVelocity - Vector3.Project(travellerVelocity, normalized);
		float num2 = ((Vector3)(ref projectileVelocity)).magnitude + num;
		float num3 = Vector3.Distance(projectilePosition, headPosition + val3);
		val = headPosition + val3 * (num3 / num2) - projectilePosition;
		return ((Vector3)(ref val)).normalized;
	}

	internal static void Initialize()
	{
		MonoRegistrarIndex = EnemyComponents.MonoRegistrar.Register<EnemyFeedbacker>();
	}
}
public static class Cheats
{
	public const string FeedbackersForEveryone = "nyxpiri.feedbackers-for-everyone";
}
[BepInPlugin("nyxpiri.ultrakill.feedbackers-for-everyone", "Feedbackers for Everyone", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInProcess("ULTRAKILL.exe")]
public class FeedbackersForEveryone : BaseUnityPlugin
{
	protected void Awake()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Expected O, but got Unknown
		Log.Initialize(((BaseUnityPlugin)this).Logger);
		Options.Config = ((BaseUnityPlugin)this).Config;
		Options.Initialize();
		EnemyFeedbacker.Initialize();
		ParryabilityTracker.Initialize();
		CannonballPatches.Initialize();
		CoinPatches.Initialize();
		GrenadePatches.Initialize();
		NailPatches.Initialize();
		ProjectilePatches.Initialize();
		PunchPatches.Initialize();
		RevolverBeamPatches.Initialize();
		Assets.Initialize();
		Harmony.CreateAndPatchAll(((object)this).GetType().Assembly, (string)null);
		Assets.EnableProjectilePicking();
		Cheats.ReadyForCheatRegistration += new ReadyForCheatRegistrationEventHandler(RegisterCheats);
		if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}

	private void RegisterCheats(CheatsManager cheatsManager)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		cheatsManager.RegisterCheat((ICheat)new ToggleCheat("Feedbackers for Everyone!", "nyxpiri.feedbackers-for-everyone", (Action<ToggleCheat>)delegate
		{
		}, (Action<ToggleCheat, CheatsManager>)delegate
		{
		}), "FAIRNESS AND EQUALITY");
	}

	protected void OnApplicationFocus(bool hasFocus)
	{
		if (hasFocus)
		{
			((BaseUnityPlugin)this).Config.Reload();
		}
	}

	protected void Start()
	{
	}

	protected void Update()
	{
	}

	protected void LateUpdate()
	{
	}
}
public static class Options
{
	public class ProjectileTypeOptions
	{
		public ConfigEntry<bool> CanBeParried = null;

		public ConfigEntry<float> MinimumParryWindow = null;

		public ProjectileTypeOptions(string name, bool parryable, float minimumParryWindow)
		{
			CanBeParried = Config.Bind<bool>("Balance." + name, "Parryable", parryable, (ConfigDescription)null);
			MinimumParryWindow = Config.Bind<float>("Balance." + name, "MinimumParryabilityWindow", minimumParryWindow, "projectiles become more parryable the longer they exist via an increasing parryability window, this sets the minimum, especially relevant for hitscan attacks. larger numbers means more frequent parries.");
		}
	}

	public static ConfigEntry<bool> LogDebugInfo = null;

	public static ConfigEntry<bool> HitstopOnEnemyParry = null;

	public static ConfigEntry<bool> ParryFollowsEnemy = null;

	public static ConfigEntry<float> EnemyParryDelay = null;

	public static ConfigEntry<float> EnemyParrySoundScalar = null;

	public static ConfigEntry<bool> MidwayParryEffect = null;

	public static ConfigEntry<string> ParryProsString = null;

	public static Dictionary<EnemyType, ConfigEntry<double>> ParryStaminaCost = new Dictionary<EnemyType, ConfigEntry<double>>(64);

	public static Dictionary<EnemyType, ConfigEntry<double>> ParryStaminaRechargeRate = new Dictionary<EnemyType, ConfigEntry<double>>(64);

	public static Dictionary<EnemyType, ConfigEntry<double>> MinParryCooldowns = new Dictionary<EnemyType, ConfigEntry<double>>(64);

	public static Dictionary<EnemyType, ConfigEntry<double>> FirstHitParrySkills = new Dictionary<EnemyType, ConfigEntry<double>>(64);

	public static Dictionary<EnemyType, ConfigEntry<double>> MultiHitParrySkills = new Dictionary<EnemyType, ConfigEntry<double>>(64);

	public static ConfigEntry<int> ParryabilityMemory = null;

	public static ConfigEntry<float> FirstHitSkillScalar = null;

	public static ConfigEntry<float> MultiHitSkillScalar = null;

	public static ConfigEntry<float> MinParryCooldownScalar = null;

	public static ConfigEntry<float> StaminaRechargeRateScalar = null;

	public static ConfigEntry<float> StaminaCostScalar = null;

	public static ProjectileTypeOptions ShotCoinsOptions = null;

	public static ProjectileTypeOptions PunchedCoinsOptions = null;

	public static ProjectileTypeOptions BeamsOptions = null;

	public static ProjectileTypeOptions RailCannonOptions = null;

	public static ProjectileTypeOptions GrenadesOptions = null;

	public static ProjectileTypeOptions PlayerProjectilesOptions = null;

	public static ProjectileTypeOptions EnemyProjectilesOptions = null;

	public static ProjectileTypeOptions CannonballsOptions = null;

	public static ProjectileTypeOptions SawsOptions = null;

	public static ConfigEntry<bool> DifferentiateRailCannonFromBeams = null;

	public static ConfigEntry<bool> DifferentiateElectricity = null;

	public static ConfigEntry<bool> DifferentiateCoinRicochets = null;

	public static ConfigEntry<int> CoinRicochetDivisor = null;

	internal static ConfigFile Config = null;

	public static void Initialize()
	{
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0325: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d8: Expected I4, but got Unknown
		//IL_06f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0733: Unknown result type (might be due to invalid IL or missing references)
		//IL_076f: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
		HitstopOnEnemyParry = Config.Bind<bool>("Preferences", "HitstopOnEnemyParry", false, (ConfigDescription)null);
		EnemyParryDelay = Config.Bind<float>("Balance", "EnemyParryDelay", 0.4f, (ConfigDescription)null);
		ParryFollowsEnemy = Config.Bind<bool>("Balance", "ParryFollowsEnemy", true, (ConfigDescription)null);
		EnemyParrySoundScalar = Config.Bind<float>("Preferences.Audio", "EnemyParrySoundScalar", 4f, (ConfigDescription)null);
		MidwayParryEffect = Config.Bind<bool>("Preferences", "MidwayParryEffect", true, (ConfigDescription)null);
		ShotCoinsOptions = new ProjectileTypeOptions("ShotCoins", parryable: true, 0.75f);
		PunchedCoinsOptions = new ProjectileTypeOptions("PunchedCoins", parryable: true, 0.75f);
		BeamsOptions = new ProjectileTypeOptions("Beams", parryable: true, 0.75f);
		RailCannonOptions = new ProjectileTypeOptions("RailCannon", parryable: true, 0.75f);
		GrenadesOptions = new ProjectileTypeOptions("Grenades", parryable: true, 0.75f);
		PlayerProjectilesOptions = new ProjectileTypeOptions("PlayerProjectiles", parryable: true, 0.75f);
		EnemyProjectilesOptions = new ProjectileTypeOptions("EnemyProjectiles", parryable: true, 0.75f);
		CannonballsOptions = new ProjectileTypeOptions("Cannonballs", parryable: true, 0.75f);
		SawsOptions = new ProjectileTypeOptions("Saws", parryable: true, 0.75f);
		FirstHitSkillScalar = Config.Bind<float>("Balance", "FirstHitSkillScalar", 1f, (ConfigDescription)null);
		MultiHitSkillScalar = Config.Bind<float>("Balance", "MultiHitSkillScalar", 1f, (ConfigDescription)null);
		MinParryCooldownScalar = Config.Bind<float>("Balance", "MinParryCooldownScalar", 1f, (ConfigDescription)null);
		StaminaRechargeRateScalar = Config.Bind<float>("Balance", "StaminaRechargeRateScalar", 1f, (ConfigDescription)null);
		StaminaCostScalar = Config.Bind<float>("Balance", "StaminaCostScalar", 1f, (ConfigDescription)null);
		ParryabilityMemory = Config.Bind<int>("Balance", "ParryabilityMemory", 6, (ConfigDescription)null);
		DifferentiateElectricity = Config.Bind<bool>("Balance", "DifferentiateElectricity", true, (ConfigDescription)null);
		DifferentiateRailCannonFromBeams = Config.Bind<bool>("Balance", "DifferentiateRailCannonFromBeams", true, (ConfigDescription)null);
		DifferentiateCoinRicochets = Config.Bind<bool>("Balance", "DifferentiateCoinRicochets", true, (ConfigDescription)null);
		CoinRicochetDivisor = Config.Bind<int>("Balance", "CoinRicochetDivisor", 3, (ConfigDescription)null);
		LogDebugInfo = Config.Bind<bool>("Diagnostics", "LogDebug", false, (ConfigDescription)null);
		foreach (object value in Enum.GetValues(typeof(EnemyType)))
		{
			double defaultFirstHitSkill = 0.75;
			double defaultMultiHitSkill = 0.5;
			double defaultStaminaCost = 0.4;
			double defaultStaminaRechargeRate = 0.175;
			double defaultMinParryCooldown = 0.1;
			Action action = delegate
			{
				defaultFirstHitSkill = 0.4;
				defaultMultiHitSkill = 0.25;
				defaultStaminaCost = 0.5;
				defaultStaminaRechargeRate = 0.2;
				defaultMinParryCooldown = 0.1;
			};
			Action action2 = delegate
			{
				defaultFirstHitSkill = 0.65;
				defaultMultiHitSkill = 0.5;
				defaultStaminaCost = 0.425;
				defaultStaminaRechargeRate = 0.25;
				defaultMinParryCooldown = 0.1;
			};
			EnemyType val = (EnemyType)value;
			EnemyType val2 = val;
			switch ((int)val2)
			{
			case 8:
				defaultFirstHitSkill = 0.8;
				defaultMultiHitSkill = 0.75;
				break;
			case 22:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.75;
				break;
			case 18:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.75;
				break;
			case 29:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.75;
				break;
			case 28:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.5;
				break;
			case 23:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.85;
				defaultStaminaRechargeRate = 0.30000001192092896;
				break;
			case 24:
				defaultFirstHitSkill = 1.01;
				defaultMultiHitSkill = 0.5;
				defaultStaminaRechargeRate = 0.20000000298023224;
				break;
			case 37:
				action2();
				break;
			case 35:
				action2();
				break;
			case 0:
				action2();
				break;
			case 1:
				action();
				break;
			case 26:
				action2();
				break;
			case 3:
				action();
				break;
			case 30:
				action2();
				break;
			case 17:
				action2();
				break;
			case 16:
				action();
				break;
			case 33:
				action2();
				break;
			case 34:
				action2();
				break;
			case 2:
				action2();
				break;
			case 27:
				action2();
				break;
			case 4:
				action2();
				break;
			case 31:
				action();
				break;
			case 5:
				action2();
				break;
			case 11:
				action();
				break;
			case 32:
				action2();
				break;
			case 41:
				action2();
				break;
			case 40:
				action2();
				break;
			case 38:
				action();
				break;
			case 36:
				action();
				break;
			case 14:
				action();
				break;
			case 19:
				action2();
				break;
			case 15:
				action();
				break;
			case 12:
				action();
				break;
			case 13:
				action();
				break;
			case 6:
				action();
				break;
			case 7:
				action2();
				break;
			case 20:
				action2();
				break;
			case 9:
				action();
				break;
			case 10:
				defaultFirstHitSkill = 0.75;
				defaultMultiHitSkill = 0.5;
				defaultStaminaCost = 0.4;
				defaultStaminaRechargeRate = 0.175;
				defaultMinParryCooldown = 0.1;
				break;
			default:
				defaultStaminaCost = 0.5;
				defaultStaminaRechargeRate = 0.125;
				break;
			case 21:
			case 25:
			case 39:
			case 42:
				break;
			}
			FirstHitParrySkills[(EnemyType)value] = Config.Bind<double>($"Balance.{value}", "FirstHitSkill", defaultFirstHitSkill, $"Sets how good {value} is/are at parrying on first contact with an enemy");
			MultiHitParrySkills[(EnemyType)value] = Config.Bind<double>($"Balance.{value}", "MultiHitSkill", defaultMultiHitSkill, $"Sets how good {value} is/are at parrying past the first contact with an enemy");
			MinParryCooldowns[(EnemyType)value] = Config.Bind<double>($"Balance.{value}", "MinParryCooldown", defaultMinParryCooldown, (ConfigDescription)null);
			ParryStaminaRechargeRate[(EnemyType)value] = Config.Bind<double>($"Balance.{value}", "ParryStaminaRechargeRate", defaultStaminaRechargeRate, (ConfigDescription)null);
			ParryStaminaCost[(EnemyType)value] = Config.Bind<double>($"Balance.{value}", "ParryStaminaCost", defaultStaminaCost, (ConfigDescription)null);
		}
		Config.ConfigReloaded += OnConfigReload;
	}

	private static void OnConfigReload(object sender, EventArgs e)
	{
	}

	internal static ProjectileTypeOptions GetOptionsForType(ProjectileBoostTracker.ProjectileCategory projectileType)
	{
		return projectileType switch
		{
			ProjectileBoostTracker.ProjectileCategory.Null => null, 
			ProjectileBoostTracker.ProjectileCategory.RevolverBeam => BeamsOptions, 
			ProjectileBoostTracker.ProjectileCategory.EnemyRevolverBeam => EnemyProjectilesOptions, 
			ProjectileBoostTracker.ProjectileCategory.PlayerProjectile => PlayerProjectilesOptions, 
			ProjectileBoostTracker.ProjectileCategory.Projectile => EnemyProjectilesOptions, 
			ProjectileBoostTracker.ProjectileCategory.HomingProjectile => EnemyProjectilesOptions, 
			ProjectileBoostTracker.ProjectileCategory.Rocket => GrenadesOptions, 
			ProjectileBoostTracker.ProjectileCategory.Grenade => GrenadesOptions, 
			ProjectileBoostTracker.ProjectileCategory.EnemyRocket => GrenadesOptions, 
			ProjectileBoostTracker.ProjectileCategory.EnemyGrenade => GrenadesOptions, 
			ProjectileBoostTracker.ProjectileCategory.Coin => ShotCoinsOptions, 
			ProjectileBoostTracker.ProjectileCategory.Nail => SawsOptions, 
			ProjectileBoostTracker.ProjectileCategory.Saw => SawsOptions, 
			ProjectileBoostTracker.ProjectileCategory.RailCannon => RailCannonOptions, 
			_ => throw new NotImplementedException(), 
		};
	}
}
public static class ParryabilityTracker
{
	private class ParryabilityInfo
	{
		private struct TimestampsQueue
		{
			private float _bestDiffDist;

			private string _debugName;

			private List<double> _averageDiffs;

			private Queue<FixedTimeStamp> _queue;

			private FixedTimeStamp _decayTimestamp;

			private FixedTimeStamp _LastEnqueueTimestamp;

			private float _decayTime;

			private bool _bestDiffDistDirty;

			public float BestDiffDist
			{
				get
				{
					if (_bestDiffDistDirty)
					{
						UpdateBestDiffDist();
					}
					return _bestDiffDist;
				}
			}

			public static double MaxDecayTime => 20.0;

			internal bool CanPeek => _queue.Count > 0;

			internal void Init(string debugName)
			{
				_debugName = debugName;
				_queue = new Queue<FixedTimeStamp>(QueueCap);
				((FixedTimeStamp)(ref _decayTimestamp)).UpdateToNow();
				_averageDiffs = new List<double>(QueueCap - 1);
				UpdateDecayTime();
				UpdateBestDiffDist();
			}

			internal FixedTimeStamp Peek()
			{
				//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)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				return _queue.Peek();
			}

			internal void EnqueueNew()
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: 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)
				if (!(((FixedTimeStamp)(ref _LastEnqueueTimestamp)).TimeSince < 0.25))
				{
					if (_queue.Count == QueueCap)
					{
						_queue.Dequeue();
					}
					FixedTimeStamp item = default(FixedTimeStamp);
					((FixedTimeStamp)(ref item)).UpdateToNow();
					_queue.Enqueue(item);
					((FixedTimeStamp)(ref _decayTimestamp)).UpdateToNow();
					UpdateDecayTime();
					MarkBestDiffDistDirty();
					((FixedTimeStamp)(ref _LastEnqueueTimestamp)).UpdateToNow();
				}
			}

			private void MarkBestDiffDistDirty()
			{
				_bestDiffDistDirty = true;
			}

			private void UpdateBestDiffDist()
			{
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				_bestDiffDistDirty = false;
				if (_queue.Count <= 2)
				{
					_bestDiffDist = 10000f;
					Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.TimestampsQueue.UpdateBestDiffDist ended with a BestDiffDist of {BestDiffDist} (based on queue being small)");
					return;
				}
				double? num = null;
				double num2 = 0.0;
				double num3 = 0.0;
				_averageDiffs.Clear();
				FixedTimeStamp? val = null;
				_bestDiffDist = 0f;
				foreach (FixedTimeStamp item in _queue.Reverse())
				{
					if (!val.HasValue)
					{
						val = item;
						continue;
					}
					num2 = val.Value.TimeStamp - item.TimeStamp;
					double valueOrDefault = num.GetValueOrDefault();
					if (!num.HasValue)
					{
						valueOrDefault = num2;
						num = valueOrDefault;
					}
					num3 += num2;
					_averageDiffs.Add(num3);
					val = item;
				}
				double num4 = double.PositiveInfinity;
				int num5 = -1;
				for (int i = 1; i < _averageDiffs.Count; i++)
				{
					_averageDiffs[i] /= i + 1;
					double num6 = _averageDiffs[i];
					double num7 = Math.Abs(num6 - num.Value);
					if (num7 < num4)
					{
						num4 = num7;
						num5 = i;
					}
				}
				_bestDiffDist = (float)num4;
				Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.TimestampsQueue.UpdateBestDiffDist ended with a BestDiffDist of {BestDiffDist}, and a lowestDistI of {num5}. _queue.Count: {_queue.Count}");
			}

			internal void FixedUpdate()
			{
				if (_queue.Count != 0 && ((FixedTimeStamp)(ref _decayTimestamp)).TimeSince > (double)_decayTime)
				{
					Decay();
				}
			}

			private void Decay()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				if (_queue.Count != 0)
				{
					((FixedTimeStamp)(ref _decayTimestamp)).UpdateToNow();
					_queue.Dequeue();
					MarkBestDiffDistDirty();
				}
			}

			private void UpdateDecayTime()
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: 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_008e: 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)
				_decayTime = 0f;
				if (_queue.Count <= 2)
				{
					_decayTime = (float)MaxDecayTime;
					return;
				}
				FixedTimeStamp? val = null;
				foreach (FixedTimeStamp item in _queue)
				{
					if (!val.HasValue)
					{
						val = item;
						continue;
					}
					_decayTime += (float)(item.TimeStamp - val.Value.TimeStamp);
					val = item;
				}
				_decayTime /= _queue.Count - 1;
				_decayTime *= 2f;
				_decayTime = Mathf.Clamp(_decayTime, 1f, (float)MaxDecayTime);
				Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.TimestampsQueue.UpdateDecayTime ended with a _decayTime of {_decayTime}, _queue.Count: {_queue.Count}");
			}
		}

		private string _debugName;

		private TimestampsQueue _creationStartTimestamps;

		private TimestampsQueue _creationProgressTimestamps;

		private TimestampsQueue _contactTimestamps;

		public static int QueueCap => Options.ParryabilityMemory.Value;

		public double NotifyContact()
		{
			_contactTimestamps.EnqueueNew();
			Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.NotifyContact called and is giving a bestDiffDist of {_contactTimestamps.BestDiffDist}");
			return _contactTimestamps.BestDiffDist;
		}

		public double NotifyCreationProgress()
		{
			_creationProgressTimestamps.EnqueueNew();
			Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.NotifyCreationProgress called and is giving a bestDiffDist of {_creationProgressTimestamps.BestDiffDist}");
			return _creationProgressTimestamps.BestDiffDist;
		}

		public double NotifyCreationStart()
		{
			_creationStartTimestamps.EnqueueNew();
			Log.Debug($"{_debugName}:ParryabilityTracker.ParryabilityInfo.NotifyCreationStart called and is giving a bestDiffDist of {_creationStartTimestamps.BestDiffDist}");
			return _creationStartTimestamps.BestDiffDist;
		}

		internal void FixedUpdate()
		{
			_creationStartTimestamps.FixedUpdate();
			_creationProgressTimestamps.FixedUpdate();
			_contactTimestamps.FixedUpdate();
		}

		internal ParryabilityInfo(string debugName)
		{
			_debugName = debugName;
			_creationStartTimestamps = default(TimestampsQueue);
			_creationStartTimestamps.Init(_debugName + ".creationStartTimestamps");
			_creationProgressTimestamps = default(TimestampsQueue);
			_creationProgressTimestamps.Init(_debugName + ".creationProgressTimestamps");
			_contactTimestamps = default(TimestampsQueue);
			_contactTimestamps.Init(_debugName + ".contactTimestamps");
		}
	}

	private static Dictionary<int, ParryabilityInfo> _attackParryabilitysDict = new Dictionary<int, ParryabilityInfo>(256);

	private static List<ParryabilityInfo> _parryabilitys = new List<ParryabilityInfo>(256);

	public static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		ScenesEvents.OnSceneWasLoaded += new OnSceneWasLoadedEventHandler(OnSceneLoad);
		UpdateEvents.OnFixedUpdate += new OnFixedUpdateEventHandler(FixedUpdate);
	}

	private static void FixedUpdate()
	{
		for (int i = 0; i < _parryabilitys.Count; i++)
		{
			_parryabilitys[i].FixedUpdate();
		}
	}

	public static double NotifyContact(int hash)
	{
		ParryabilityInfo orMakeParryability = GetOrMakeParryability(hash);
		Log.Debug($"ParryabilityTracker.NotifyContact called with hash {hash}");
		return orMakeParryability.NotifyContact();
	}

	public static double NotifyCreationProgress(int hash)
	{
		ParryabilityInfo orMakeParryability = GetOrMakeParryability(hash);
		Log.Debug($"ParryabilityTracker.NotifyCreationProgress called with hash {hash}");
		return orMakeParryability.NotifyCreationProgress();
	}

	public static double NotifyCreationStart(int hash)
	{
		ParryabilityInfo orMakeParryability = GetOrMakeParryability(hash);
		Log.Debug($"ParryabilityTracker.NotifyCreationStart called with hash {hash}");
		return orMakeParryability.NotifyCreationStart();
	}

	private static ParryabilityInfo GetOrMakeParryability(int hash)
	{
		if (!_attackParryabilitysDict.TryGetValue(hash, out var value))
		{
			value = new ParryabilityInfo($"{hash}");
			_attackParryabilitysDict.Add(hash, value);
			_parryabilitys.Add(value);
		}
		return value;
	}

	private static void OnSceneLoad(Scene sceneIdx, string levelName, string unitySceneName)
	{
		_attackParryabilitysDict.Clear();
		_parryabilitys.Clear();
	}
}
public static class CannonballPatches
{
	private static readonly FieldInfo _checkingForBreakFi = AccessTools.Field(typeof(Cannonball), "checkingForBreak");

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		CannonballEvents.PreCannonballStart += new PreCannonballStartEventHandler(PreCannonballStart);
		CannonballEvents.PreCannonballCollide += new PreCannonballCollideEventHandler(PreCannonballCollide);
		CannonballEvents.PreCannonballLaunch += new PreCannonballLaunchEventHandler(PreCannonballLaunch);
		CannonballEvents.PreCannonballExplode += new PreCannonballExplodeEventHandler(PreCannonballExplode);
	}

	private static void PreCannonballExplode(EventMethodCanceler canceler, Cannonball cannonball)
	{
		ProjectileBoostTracker component = ((Component)cannonball).GetComponent<ProjectileBoostTracker>();
		if (Cheats.Enabled && !((Object)(object)component == (Object)null) && !component.CannonballExplodingForPlayer && component.NumEnemyBoosts != 0)
		{
			if (component.LastBoostedByPlayer)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(100, "<color=#ffab02>PARRY THIS</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
			else
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(50, "<color=#02ff17>HOLD THIS FOR ME</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		}
	}

	private static void PreCannonballLaunch(EventMethodCanceler canceler, Cannonball cannonball)
	{
		if (Cheats.Enabled)
		{
			Log.Debug($"PreCannonballLaunch called on {cannonball}");
			((Component)cannonball).GetComponent<ProjectileBoostTracker>().IncrementPlayerBoosts();
		}
	}

	private static void PreCannonballCollide(EventMethodCanceler canceler, Cannonball cannonball, Collider other)
	{
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_040e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0439: Unknown result type (might be due to invalid IL or missing references)
		if (!Cheats.Enabled)
		{
			return;
		}
		Log.Debug($"PreCannonballCollide called on {cannonball}");
		Collider component = ((Component)cannonball).GetComponent<Collider>();
		ProjectileBoostTracker boostTracker = ((Component)cannonball).GetComponent<ProjectileBoostTracker>();
		Options.ProjectileTypeOptions cannonballsOptions = Options.CannonballsOptions;
		if (!cannonballsOptions.CanBeParried.Value)
		{
			return;
		}
		Action action = delegate
		{
			if (boostTracker.NumPlayerBoosts != 0 && boostTracker.NumEnemyBoosts != 0)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(150, "<color=#00c3ff>VOLLEYBALL</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		};
		NewMovement val = default(NewMovement);
		if (((Component)other).TryGetComponent<NewMovement>(ref val) && !boostTracker.LastBoostedByPlayer && boostTracker.HasBeenBoosted)
		{
			boostTracker.CannonballExplodingForPlayer = true;
			cannonball.Explode();
		}
		else
		{
			if ((cannonball.launched || cannonball.canBreakBeforeLaunched) && !other.isTrigger && (LayerMaskDefaults.IsMatchingLayer(((Component)other).gameObject.layer, (LMD)1) || (cannonball.launched && ((Component)other).gameObject.layer == 0 && (!((Component)other).gameObject.CompareTag("Player") || !component.isTrigger))))
			{
				return;
			}
			bool flag = (bool)_checkingForBreakFi.GetValue(cannonball);
			EnemyIdentifierIdentifier val2 = default(EnemyIdentifierIdentifier);
			if ((!cannonball.launched && !cannonball.physicsCannonball) || (((Component)other).gameObject.layer != 10 && ((Component)other).gameObject.layer != 11 && ((Component)other).gameObject.layer != 12) || flag || !(Object.op_Implicit((Object)(object)other.attachedRigidbody) ? ((Component)other.attachedRigidbody).TryGetComponent<EnemyIdentifierIdentifier>(ref val2) : ((Component)other).TryGetComponent<EnemyIdentifierIdentifier>(ref val2)) || (Object)(object)val2.eid == (Object)null)
			{
				return;
			}
			EnemyComponents enemy = ((Component)val2.eid).GetComponent<EnemyComponents>();
			Assert.IsNotNull((Object)(object)enemy, "");
			if (enemy.Eid.Dead)
			{
				return;
			}
			EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
			if (!feedbacker.Enabled)
			{
				action();
				return;
			}
			if ((Object)(object)boostTracker.SafeEid == (Object)(object)enemy.Eid)
			{
				((EventMethodCanceler)(ref canceler)).CancelMethod();
				return;
			}
			double parryability = boostTracker.NotifyContact();
			boostTracker.MarkCannotBeEnemyParried();
			if (!feedbacker.ReadyToParry)
			{
				action();
				return;
			}
			if (!feedbacker.CanParry(boostTracker, parryability))
			{
				action();
				return;
			}
			boostTracker.IncrementEnemyBoost();
			feedbacker.ParryEffect(((Component)cannonball).transform.position);
			((Component)cannonball).gameObject.SetActive(false);
			boostTracker.IgnoreColliders = enemy.Colliders;
			boostTracker.SafeEid = enemy.Eid;
			cannonball.hitEnemies.Add(enemy.Eid);
			Vector3 velocity = cannonball.Rigidbody.velocity;
			float cannonballSpeed = ((Vector3)(ref velocity)).magnitude;
			feedbacker.QueueParry(((Component)cannonball.Rigidbody).transform.position, delegate(Vector3 offset)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
				Transform transform = ((Component)cannonball.Rigidbody).transform;
				transform.position += offset;
				feedbacker.ParryFinishEffect(((Component)cannonball).transform.position);
				((Component)cannonball).gameObject.SetActive(true);
				Vector3 val3 = enemy.GetFeedbacker().SolveParryForce(((Component)cannonball).transform.position, cannonball.Rigidbody.velocity);
				cannonball.Rigidbody.velocity = val3 * cannonballSpeed;
				((Component)cannonball.Rigidbody).transform.rotation = Quaternion.LookRotation(val3);
			});
			NewMovement instance = MonoSingleton<NewMovement>.Instance;
			Physics.IgnoreCollision(((Component)cannonball).GetComponent<Collider>(), (Collider)(object)instance.playerCollider, false);
			((EventMethodCanceler)(ref canceler)).CancelMethod();
		}
	}

	private static void PreCannonballStart(EventMethodCanceler canceler, Cannonball cannonball)
	{
		Log.Debug($"PreCannonballStart called on {cannonball}");
		ComponentExtensions.GetOrAddComponent<ProjectileBoostTracker>((Component)(object)cannonball);
	}
}
public static class CoinPatches
{
	[HarmonyPatch(typeof(Coin), "SpawnBeam")]
	private static class CoinSpawnBeamPatch
	{
		public static void Prefix(Coin __instance)
		{
			ProjectileBoostTracker orAddComponent = GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(__instance.refBeam);
			orAddComponent.CopyFrom(((Component)__instance).GetComponent<ProjectileBoostTracker>());
			orAddComponent.CoinRicochets += __instance.ricochets + 1;
			MeshFilter componentInChildren = ((Component)__instance).GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = ((Component)__instance).GetComponentInChildren<MeshRenderer>();
			orAddComponent.CustomMesh = ((componentInChildren != null) ? componentInChildren.mesh : null);
			orAddComponent.CustomMaterial = ((componentInChildren2 != null) ? ((Renderer)componentInChildren2).material : null);
		}
	}

	[HarmonyPatch(typeof(Coin), "ReflectRevolver")]
	private static class CoinReflectRevolverPatch
	{
		private static FieldInfo altBeamFi = AccessTools.Field(typeof(Coin), "altBeam");

		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		private static Coin _currentCoin = null;

		private static void DeliverDamageReplacement(EnemyIdentifier eid, GameObject target, Vector3 force, Vector3 hitPoint, float multiplier, bool tryForExplode, float critMultiplier = 0f, GameObject sourceWeapon = null, bool ignoreTotalDamageTakenMultiplier = false, bool fromExplosion = false)
		{
			//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)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug($"DeliverDamageReplacement called on {_currentCoin}");
			Action action = delegate
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				eid.DeliverDamage(target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
			};
			Options.ProjectileTypeOptions shotCoinsOptions = Options.ShotCoinsOptions;
			if (!shotCoinsOptions.CanBeParried.Value)
			{
				action();
				return;
			}
			if (!Cheats.Enabled)
			{
				action();
				return;
			}
			Coin currentCoin = _currentCoin;
			ProjectileBoostTracker component = ((Component)currentCoin).GetComponent<ProjectileBoostTracker>();
			component.CoinRicochets += currentCoin.ricochets + 1;
			GameObject val = (GameObject)altBeamFi.GetValue(currentCoin);
			RevolverBeam val2 = ((val != null) ? val.GetComponentInChildren<RevolverBeam>() : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && val2.attributes.Contains((HitterAttribute)2))
			{
				component.Electric = true;
			}
			double parryability = component.NotifyContact();
			EnemyComponents enemy = ((Component)eid).GetComponent<EnemyComponents>();
			Assert.IsNotNull((Object)(object)enemy, "");
			if (enemy.Eid.Dead)
			{
				action();
				return;
			}
			EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
			if (!feedbacker.CanParry(component, parryability))
			{
				action();
				return;
			}
			if (!feedbacker.Enabled)
			{
				action();
				return;
			}
			if (!feedbacker.ReadyToParry)
			{
				action();
				return;
			}
			feedbacker.ParryEffect(hitPoint);
			MeshFilter componentInChildren = ((Component)currentCoin).GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = ((Component)currentCoin).GetComponentInChildren<MeshRenderer>();
			GameObject counterBeamGo = Object.Instantiate<GameObject>(Assets.EnemyRevolverBullet);
			Projectile counterBeam = counterBeamGo.GetComponent<Projectile>();
			ProjectileBoostTracker counterBeamBoostTracker = GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(counterBeamGo);
			((Component)counterBeam).GetComponentInChildren<MeshFilter>().mesh = componentInChildren.mesh;
			((Renderer)((Component)counterBeam).GetComponentInChildren<MeshRenderer>()).material = ((Renderer)componentInChildren2).material;
			counterBeamBoostTracker.CopyFrom(component);
			float coinPower = currentCoin.power;
			feedbacker.QueueParry(hitPoint, delegate(Vector3 offset)
			{
				//IL_0008: 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_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: 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)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				feedbacker.ParryFinishEffect(hitPoint + offset);
				Vector3 val3 = feedbacker.SolveParryForce(hitPoint + offset, ((Component)counterBeam).transform.rotation * Vector3.forward * counterBeam.speed);
				counterBeamGo.transform.position = hitPoint + offset;
				counterBeamGo.transform.rotation = Quaternion.LookRotation(val3);
				counterBeamGo.SetActive(true);
				counterBeamBoostTracker.IncrementEnemyBoost();
				IReadOnlyList<Collider> colliders = enemy.Colliders;
				counterBeamBoostTracker.IgnoreColliders = colliders;
				counterBeamBoostTracker.SafeEid = eid;
				counterBeamBoostTracker.SetTempSafeEnemyType(enemy.Eid.enemyType);
				counterBeam.playerBullet = true;
				counterBeam.damage = coinPower * 5f;
				counterBeam.enemyDamageMultiplier = 0.8f;
			});
			Object.Destroy((Object)(object)((Component)currentCoin).gameObject);
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instr in instructions)
			{
				if (CodeInstructionExtensions.Calls(instr, typeof(EnemyIdentifier).GetMethod("DeliverDamage")))
				{
					instr.operand = typeof(CoinReflectRevolverPatch).GetMethod("DeliverDamageReplacement", BindingFlags.Static | BindingFlags.NonPublic);
				}
				yield return instr;
			}
		}

		public static void Prefix(Coin __instance)
		{
			_currentCoin = __instance;
			ProjectileBoostTracker component = ((Component)__instance).GetComponent<ProjectileBoostTracker>();
			MeshFilter componentInChildren = ((Component)__instance).GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = ((Component)__instance).GetComponentInChildren<MeshRenderer>();
			FieldInfo field = typeof(Coin).GetField("altBeam", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field2 = typeof(Coin).GetField("pendingBeamHits", BindingFlags.Instance | BindingFlags.NonPublic);
			object? value = field.GetValue(__instance);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			IEnumerable enumerable = field2.GetValue(__instance) as IEnumerable;
			foreach (object item in enumerable)
			{
				if (item == null)
				{
					Log.Warning($"Unexpected null item for coin {__instance} (boostTracker: {component})");
				}
				FieldInfo field3 = item.GetType().GetField("altBeam", BindingFlags.Instance | BindingFlags.Public);
				if (field3 == null)
				{
					Log.Warning($"Unexpected null pendingAltBeamFi for coin {__instance} (boostTracker: {component})");
				}
				Assert.IsNotNull((object)field3, "");
				Assert.IsNotNull(item, "");
				object? value2 = field3.GetValue(item);
				GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					ProjectileBoostTracker projectileBoostTracker = ((val2 != null) ? GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(val2) : null);
					projectileBoostTracker.CopyFrom(component);
					projectileBoostTracker.CustomMesh = ((componentInChildren != null) ? componentInChildren.mesh : null);
					projectileBoostTracker.CustomMaterial = ((componentInChildren2 != null) ? ((Renderer)componentInChildren2).material : null);
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				ProjectileBoostTracker orAddComponent = GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(val);
				orAddComponent.CopyFrom(component);
				orAddComponent.CustomMesh = ((componentInChildren != null) ? componentInChildren.mesh : null);
				orAddComponent.CustomMaterial = ((componentInChildren2 != null) ? ((Renderer)componentInChildren2).material : null);
			}
		}

		public static void Postfix(Coin __instance)
		{
			_currentCoin = null;
		}
	}

	[HarmonyPatch(typeof(Coin), "Punchflection")]
	private static class CoinPunchflectionPatch
	{
		private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker();

		private static Coin _currentCoin = null;

		private static void DeliverDamageReplacement(EnemyIdentifier eid, GameObject target, Vector3 force, Vector3 hitPoint, float multiplier, bool tryForExplode, float critMultiplier = 0f, GameObject sourceWeapon = null, bool ignoreTotalDamageTakenMultiplier = false, bool fromExplosion = false)
		{
			//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)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug($"Punchflection.DeliverDamageReplacement called on {_currentCoin}");
			Action action = delegate
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				eid.DeliverDamage(target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion);
			};
			Options.ProjectileTypeOptions punchedCoinsOptions = Options.PunchedCoinsOptions;
			if (!punchedCoinsOptions.CanBeParried.Value)
			{
				action();
				return;
			}
			if (!Cheats.Enabled)
			{
				action();
				return;
			}
			Coin currentCoin = _currentCoin;
			ProjectileBoostTracker component = ((Component)currentCoin).GetComponent<ProjectileBoostTracker>();
			component.CoinPunched = true;
			double parryability = component.NotifyContact();
			EnemyComponents enemy = ((Component)eid).GetComponent<EnemyComponents>();
			Assert.IsNotNull((Object)(object)enemy, "");
			if (enemy.Eid.Dead)
			{
				action();
				return;
			}
			EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
			if (!feedbacker.CanParry(component, parryability))
			{
				action();
				return;
			}
			if (!feedbacker.Enabled)
			{
				action();
				return;
			}
			if (!feedbacker.ReadyToParry)
			{
				action();
				return;
			}
			feedbacker.ParryEffect(hitPoint);
			float coinPower = currentCoin.power;
			MeshFilter componentInChildren = ((Component)currentCoin).GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = ((Component)currentCoin).GetComponentInChildren<MeshRenderer>();
			GameObject counterBeamGo = Object.Instantiate<GameObject>(Assets.EnemyRevolverBullet);
			Projectile counterBeam = counterBeamGo.GetComponent<Projectile>();
			ProjectileBoostTracker counterBeamBoostTracker = GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(counterBeamGo);
			((Component)counterBeam).GetComponentInChildren<MeshFilter>().mesh = componentInChildren.mesh;
			((Renderer)((Component)counterBeam).GetComponentInChildren<MeshRenderer>()).material = ((Renderer)componentInChildren2).material;
			counterBeamBoostTracker.CopyFrom(component);
			feedbacker.QueueParry(hitPoint, delegate(Vector3 offset)
			{
				//IL_0008: 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_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: 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)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				feedbacker.ParryFinishEffect(hitPoint + offset);
				Vector3 val = feedbacker.SolveParryForce(hitPoint + offset, ((Component)counterBeam).transform.rotation * Vector3.forward * counterBeam.speed);
				counterBeamGo.transform.position = hitPoint + offset;
				counterBeamGo.transform.rotation = Quaternion.LookRotation(val);
				counterBeamGo.SetActive(true);
				counterBeamBoostTracker.IncrementEnemyBoost();
				IReadOnlyList<Collider> colliders = enemy.Colliders;
				counterBeamBoostTracker.IgnoreColliders = colliders;
				counterBeamBoostTracker.SafeEid = eid;
				counterBeam.playerBullet = true;
				counterBeam.damage = coinPower * 5f;
				counterBeamBoostTracker.SetTempSafeEnemyType(enemy.Eid.enemyType);
				counterBeam.enemyDamageMultiplier = 0.8f;
			});
			currentCoin.GetDeleted();
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instr in instructions)
			{
				if (CodeInstructionExtensions.Calls(instr, typeof(EnemyIdentifier).GetMethod("DeliverDamage")))
				{
					instr.operand = typeof(CoinPunchflectionPatch).GetMethod("DeliverDamageReplacement", BindingFlags.Static | BindingFlags.NonPublic);
				}
				yield return instr;
			}
		}

		public static void Prefix(Coin __instance)
		{
			_currentCoin = __instance;
		}

		public static void Postfix(Coin __instance)
		{
			_currentCoin = null;
		}
	}

	private const float EnemyParriedCoinDamageScale = 4f;

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		CoinEvents.PostCoinAwake += new PostCoinAwakeEventHandler(PostCoinAwake);
	}

	private static void PostCoinAwake(EventMethodCancelInfo cancelInfo, Coin coin)
	{
		ComponentExtensions.GetOrAddComponent<ProjectileBoostTracker>((Component)(object)coin);
	}
}
public static class GrenadePatches
{
	private static FieldInfo grenadeBeamFi = typeof(Grenade).GetField("grenadeBeam", BindingFlags.Instance | BindingFlags.NonPublic);

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		GrenadeEvents.PreGrenadeStart += new PreGrenadeStartEventHandler(PreGrenadeStart);
		GrenadeEvents.PreGrenadeBeam += new PreGrenadeBeamEventHandler(PreGrenadeBeam);
		GrenadeEvents.PostGrenadeBeam += new PostGrenadeBeamEventHandler(PostGrenadeBeam);
		GrenadeEvents.PreGrenadeCollision += new PreGrenadeCollisionEventHandler(PreGrenadeCollision);
		GrenadeEvents.PreGrenadeExplode += new PreGrenadeExplodeEventHandler(PreGrenadeExplode);
	}

	private static void PreGrenadeExplode(EventMethodCanceler canceler, Grenade grenade, bool big, bool harmless, bool super, float sizeMultiplier, bool ultrabooster, GameObject exploderWeapon, bool fup)
	{
		if (!Cheats.Enabled || (Object)(object)exploderWeapon == (Object)null)
		{
			return;
		}
		ProjectileBoostTracker component = ((Component)grenade).GetComponent<ProjectileBoostTracker>();
		if (!((Object)(object)component == (Object)null) && component.NumEnemyBoosts != 0)
		{
			if (component.LastBoostedByPlayer)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(150, "<color=#ba42ff>IDK HOW YOU DID THAT</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
			else
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(60, "<color=#d883ff>HIGHLY VOLATILE</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		}
	}

	private static void PreGrenadeStart(EventMethodCanceler canceler, Grenade grenade)
	{
		ComponentExtensions.GetOrAddComponent<ProjectileBoostTracker>((Component)(object)grenade);
	}

	private static void PreGrenadeBeam(EventMethodCanceler canceler, Grenade grenade, Vector3 targetPoint, GameObject newSourceWeapon)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		RevolverBeam val = (RevolverBeam)grenadeBeamFi.GetValue(grenade);
		ProjectileBoostTracker projectileBoostTracker = ((Component)val).gameObject.AddComponent<ProjectileBoostTracker>();
		ProjectileBoostTracker component = ((Component)grenade).GetComponent<ProjectileBoostTracker>();
		Assert.IsNotNull((Object)(object)projectileBoostTracker, "");
		Assert.IsNotNull((Object)(object)grenade, "");
		Assert.IsNotNull((Object)(object)((Component)grenade).GetComponent<ProjectileBoostTracker>(), "");
		if (component.NumEnemyBoosts != 0)
		{
			if (grenade.rocket)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(500, "<color=#ae57ff>MODERN <color=#ff0000>T<color=#ffaa00>E<color=#0dff00>C<color=#ffd500>H<color=#7bff00>N<color=#00ff59>O<color=#00c3ff>L<color=#0080ff>O<color=#7300ff>G<color=#ff00ee>Y</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
			else
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(350, "<color=#00fff7>CONVERSION</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		}
		projectileBoostTracker.CopyFrom(component);
		projectileBoostTracker.IncrementPlayerBoosts();
	}

	private static void PostGrenadeBeam(EventMethodCancelInfo cancelInfo, Grenade grenade, Vector3 targetPoint, GameObject newSourceWeapon)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		RevolverBeam val = (RevolverBeam)grenadeBeamFi.GetValue(grenade);
	}

	private static void PreGrenadeCollision(EventMethodCanceler canceler, Grenade grenade, Collider other, Vector3 velocity)
	{
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		if (!Cheats.Enabled)
		{
			return;
		}
		Options.ProjectileTypeOptions grenadesOptions = Options.GrenadesOptions;
		if (!grenadesOptions.CanBeParried.Value)
		{
			return;
		}
		ProjectileBoostTracker boostTracker = ((Component)grenade).GetComponent<ProjectileBoostTracker>();
		double parryability = boostTracker.NotifyContact();
		Action action = delegate
		{
			if (boostTracker.NumEnemyBoosts != 0 && grenade.playerRiding)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(750, "<color=#ff0000>NOW PARRY US", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		};
		PortalAwarePlayerColliderClone val = default(PortalAwarePlayerColliderClone);
		EnemyIdentifierIdentifier val2 = default(EnemyIdentifierIdentifier);
		if (((Component)other).TryGetComponent<PortalAwarePlayerColliderClone>(ref val) || GrenadeExtensions.IsExploded(grenade) || (!grenade.enemy && ((Component)other).CompareTag("Player")) || ((Component)other).gameObject.layer == 14 || ((Component)other).gameObject.layer == 20 || (((Component)other).gameObject.layer != 11 && ((Component)other).gameObject.layer != 10) || !(Object.op_Implicit((Object)(object)other.attachedRigidbody) ? ((Component)other.attachedRigidbody).TryGetComponent<EnemyIdentifierIdentifier>(ref val2) : ((Component)other).TryGetComponent<EnemyIdentifierIdentifier>(ref val2)) || !Object.op_Implicit((Object)(object)val2.eid))
		{
			return;
		}
		EnemyComponents enemy = ((Component)val2.eid).GetComponent<EnemyComponents>();
		Assert.IsNotNull((Object)(object)enemy, "");
		if (enemy.Eid.Dead || (grenade.ignoreEnemyType.Count > 0 && grenade.ignoreEnemyType.Contains(enemy.Eid.enemyType)))
		{
			return;
		}
		EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
		if (!feedbacker.Enabled)
		{
			return;
		}
		if (grenade.playerRiding)
		{
			action();
			return;
		}
		if (!feedbacker.ReadyToParry)
		{
			action();
			return;
		}
		if (!feedbacker.CanParry(boostTracker, parryability))
		{
			action();
			return;
		}
		feedbacker.ParryEffect(((Component)grenade).transform.position);
		boostTracker.IncrementEnemyBoost();
		((Component)grenade).gameObject.SetActive(false);
		feedbacker.QueueParry(((Component)grenade.rb).transform.position, delegate(Vector3 offset)
		{
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)grenade == (Object)null))
			{
				((Component)grenade).gameObject.SetActive(true);
				feedbacker.ParryFinishEffect(((Component)grenade).transform.position + offset);
				Vector3 velocity2;
				if (grenade.rocket)
				{
					Vector3 val3 = feedbacker.SolveParryForce(((Component)grenade).transform.position + offset, ((Component)grenade).transform.rotation * Vector3.forward * grenade.rocketSpeed);
					Rigidbody rb = grenade.rb;
					Vector3 val4 = val3;
					velocity2 = grenade.rb.velocity;
					rb.velocity = val4 * ((Vector3)(ref velocity2)).magnitude;
					grenade.rb.rotation = Quaternion.LookRotation(val3);
				}
				else
				{
					Vector3 val3 = feedbacker.SolveParryForce(((Component)grenade).transform.position + offset, grenade.rb.velocity * 5f);
					Vector3 val5 = val3;
					velocity2 = grenade.rb.velocity;
					Vector3 velocity3 = val5 * ((Vector3)(ref velocity2)).magnitude * 5f;
					if (((Vector3)(ref velocity3)).magnitude > 80f)
					{
						velocity3 = ((Vector3)(ref velocity3)).normalized * 80f;
					}
					grenade.rb.velocity = velocity3;
				}
				grenade.enemy = true;
				boostTracker.IgnoreColliders = enemy.Colliders;
				boostTracker.SafeEid = enemy.Eid;
				Transform transform = ((Component)grenade).transform;
				transform.position += offset;
				NewMovement instance = MonoSingleton<NewMovement>.Instance;
				Physics.IgnoreCollision(((Component)grenade).GetComponent<Collider>(), (Collider)(object)instance.playerCollider, false);
			}
		});
		((EventMethodCanceler)(ref canceler)).CancelMethod();
	}
}
public static class NailPatches
{
	[HarmonyPatch(typeof(Nail), "FixedUpdate")]
	private static class NailFixedUpdatePatch
	{
		public static void Prefix(Nail __instance)
		{
			if (__instance.sawblade || __instance.chainsaw)
			{
				ProjectileBoostTracker component = ((Component)__instance).GetComponent<ProjectileBoostTracker>();
				component.PreNailFixedUpdate();
			}
		}

		public static void Postfix(Nail __instance)
		{
		}
	}

	private static FieldInfo sameEnemyHitCooldownFi = AccessTools.Field(typeof(Nail), "sameEnemyHitCooldown");

	private static FieldInfo currentHitEnemyFi = AccessTools.Field(typeof(Nail), "currentHitEnemy");

	private static FieldInfo hitLimbsFi = AccessTools.Field(typeof(Nail), "hitLimbs");

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		NailEvents.PreNailStart += new PreNailStartEventHandler(PreNailStart);
		NailEvents.PreNailHitEnemy += new PreNailHitEnemyEventHandler(PreNailHitEnemy);
	}

	private static void PreNailStart(EventMethodCanceler canceler, Nail nail)
	{
		ComponentExtensions.GetOrAddComponent<ProjectileBoostTracker>((Component)(object)nail);
	}

	private static void PreNailHitEnemy(EventMethodCanceler canceler, Nail nail, Transform other, EnemyIdentifierIdentifier eidid)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_00b3: 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_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		if ((!nail.chainsaw && !nail.sawblade) || nail.magnets.Count > 0)
		{
			return;
		}
		float num = (float)sameEnemyHitCooldownFi.GetValue(nail);
		EnemyIdentifier val = (EnemyIdentifier)currentHitEnemyFi.GetValue(nail);
		List<Transform> list = (List<Transform>)hitLimbsFi.GetValue(nail);
		if (((Object)(object)eidid == (Object)null && !((Component)other).TryGetComponent<EnemyIdentifierIdentifier>(ref eidid)) || !Object.op_Implicit((Object)(object)eidid.eid) || (nail.enemy && (Object)(object)eidid != (Object)null && (Object)(object)eidid.eid != (Object)null && eidid.eid.enemyType == nail.safeEnemyType) || (nail.sawblade && ((num > 0f && (Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)eidid.eid) || list.Contains(other))))
		{
			return;
		}
		Assert.IsNotNull((Object)(object)eidid, "");
		Assert.IsNotNull((Object)(object)eidid.eid, "");
		EnemyComponents component = ((Component)eidid.eid).GetComponent<EnemyComponents>();
		Assert.IsNotNull((Object)(object)component, "");
		Options.ProjectileTypeOptions sawsOptions = Options.SawsOptions;
		if (!sawsOptions.CanBeParried.Value || component.Eid.Dead)
		{
			return;
		}
		EnemyFeedbacker feedbacker = component.GetFeedbacker();
		if (!feedbacker.Enabled)
		{
			return;
		}
		ProjectileBoostTracker component2 = ((Component)nail).GetComponent<ProjectileBoostTracker>();
		if ((Object)(object)component2 == (Object)null)
		{
			return;
		}
		if ((Object)(object)component2.SafeEid == (Object)(object)component.Eid)
		{
			((EventMethodCanceler)(ref canceler)).CancelMethod();
			return;
		}
		double parryability = component2.NotifyContact();
		component2.MarkCannotBeEnemyParried();
		if (!feedbacker.ReadyToParry || !feedbacker.CanParry(component2, parryability))
		{
			return;
		}
		Vector3 val2 = feedbacker.SolveParryForce(((Component)nail).transform.position, nail.rb.velocity);
		Rigidbody rb = nail.rb;
		Vector3 velocity = nail.rb.velocity;
		rb.velocity = val2 * ((Vector3)(ref velocity)).magnitude;
		((Component)nail.rb).transform.rotation = Quaternion.LookRotation(val2);
		component2.IncrementEnemyBoost();
		feedbacker.ParryEffect(((Component)nail).transform.position);
		component2.IgnoreColliders = component.Colliders;
		component2.SafeEid = component.Eid;
		nail.enemy = true;
		((Component)nail).gameObject.layer = 2;
		NewMovement instance = MonoSingleton<NewMovement>.Instance;
		foreach (Collider collider in component2.Colliders)
		{
			Physics.IgnoreCollision(collider, (Collider)(object)instance.playerCollider, false);
		}
		((EventMethodCanceler)(ref canceler)).CancelMethod();
	}
}
public static class ProjectilePatches
{
	private static FieldInfo _activeFi = typeof(Projectile).GetField("active", BindingFlags.Instance | BindingFlags.NonPublic);

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		ProjectileEvents.PostProjectileAwake += new PostProjectileAwakeEventHandler(PostProjectileAwake);
		ProjectileEvents.PreProjectileCollided += new PreProjectileCollidedEventHandler(PreProjectileCollided);
	}

	private static void PostProjectileAwake(EventMethodCancelInfo cancelInfo, Projectile projectile)
	{
		ComponentExtensions.GetOrAddComponent<ProjectileBoostTracker>((Component)(object)projectile);
	}

	private static void PreProjectileCollided(EventMethodCanceler canceler, Projectile projectile, Collider other)
	{
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Invalid comparison between Unknown and I4
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_060d: Unknown result type (might be due to invalid IL or missing references)
		if (!(bool)_activeFi.GetValue(projectile) || !Cheats.Enabled)
		{
			return;
		}
		ProjectileBoostTracker boostTracker = ((Component)projectile).GetComponent<ProjectileBoostTracker>();
		Options.ProjectileTypeOptions playerProjectilesOptions = Options.PlayerProjectilesOptions;
		if (boostTracker.IsPlayerSourced && !playerProjectilesOptions.CanBeParried.Value)
		{
			return;
		}
		if (boostTracker.IgnoreColliders.Contains(other))
		{
			((EventMethodCanceler)(ref canceler)).CancelMethod();
		}
		else
		{
			if (!projectile.friendly)
			{
				return;
			}
			double parryability = boostTracker.NotifyContact();
			Action action = delegate
			{
				if (boostTracker.ProjectileType == ProjectileBoostTracker.ProjectileCategory.Coin && boostTracker.NumPlayerBoosts != 0 && boostTracker.NumEnemyBoosts != 0)
				{
					MonoSingleton<StyleHUD>.Instance.AddPoints(200, "<color=#ffd000>KEEP THE CHANGE</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
				}
				if ((boostTracker.ProjectileType == ProjectileBoostTracker.ProjectileCategory.Projectile || boostTracker.ProjectileType == ProjectileBoostTracker.ProjectileCategory.HomingProjectile) && boostTracker.NumPlayerBoosts != 0 && boostTracker.NumEnemyBoosts != 0)
				{
					MonoSingleton<StyleHUD>.Instance.AddPoints(600, "<color=#c165ff>I INSIST</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
				}
			};
			EnemyIdentifierIdentifier val = null;
			if ((!projectile.friendly && !projectile.hittingPlayer && ((Component)other).gameObject.CompareTag("Player")) || (projectile.canHitCoin && ((Component)other).gameObject.CompareTag("Coin")))
			{
				return;
			}
			if ((((Component)other).gameObject.CompareTag("Armor") && (projectile.friendly || !((Component)other).TryGetComponent<EnemyIdentifierIdentifier>(ref val) || !Object.op_Implicit((Object)(object)val.eid) || val.eid.enemyType != projectile.safeEnemyType)) || (projectile.boosted && ((Component)other).gameObject.layer == 11 && ((Component)other).gameObject.CompareTag("Body") && ((Component)other).TryGetComponent<EnemyIdentifierIdentifier>(ref val) && Object.op_Implicit((Object)(object)val.eid) && (int)val.eid.enemyType == 4 && !val.eid.isGasolined))
			{
				EnemyIdentifier val2 = null;
				if ((Object)(object)val != (Object)null && (Object)(object)val.eid != (Object)null)
				{
					val2 = val.eid;
				}
				if (!((Object)(object)val2 == (Object)null))
				{
					EnemyComponents component = ((Component)val2).GetComponent<EnemyComponents>();
					Assert.IsNotNull((Object)(object)component, "");
					EnemyFeedbacker feedbacker2 = component.GetFeedbacker();
					if (feedbacker2.Enabled && (Object)(object)boostTracker.SafeEid == (Object)(object)val2)
					{
						((EventMethodCanceler)(ref canceler)).CancelMethod();
					}
				}
			}
			else
			{
				if ((!((Component)other).gameObject.CompareTag("Head") && !((Component)other).gameObject.CompareTag("Body") && !((Component)other).gameObject.CompareTag("Limb") && !((Component)other).gameObject.CompareTag("EndLimb")) || ((Component)other).gameObject.CompareTag("Armor"))
				{
					return;
				}
				val = ((Component)other).gameObject.GetComponentInParent<EnemyIdentifierIdentifier>();
				EnemyIdentifier val3 = null;
				if ((Object)(object)val != (Object)null && (Object)(object)val.eid != (Object)null)
				{
					val3 = val.eid;
				}
				if ((Object)(object)val3 == (Object)null || (projectile.alreadyHitEnemies.Count != 0 && projectile.alreadyHitEnemies.Contains(val3)) || ((val3.enemyType == projectile.safeEnemyType || EnemyIdentifier.CheckHurtException(projectile.safeEnemyType, val3.enemyType, projectile.targetHandle)) && (!projectile.friendly || val3.immuneToFriendlyFire) && !projectile.playerBullet && !projectile.parried) || val3.Dead)
				{
					return;
				}
				Log.Debug($"Deciding parry capability for enemy {val3}, for projectile {projectile} with a hit that hit collider {other}");
				Log.Debug($"boostTracker.IgnoreEid = {boostTracker.SafeEid}");
				EnemyComponents enemy = ((Component)val3).GetComponent<EnemyComponents>();
				Assert.IsNotNull((Object)(object)enemy, "");
				EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
				if (!feedbacker.Enabled)
				{
					action();
					return;
				}
				if ((Object)(object)boostTracker.SafeEid == (Object)(object)val3)
				{
					((EventMethodCanceler)(ref canceler)).CancelMethod();
					return;
				}
				if (!feedbacker.ReadyToParry)
				{
					action();
					return;
				}
				if (projectile.unparryable || projectile.undeflectable)
				{
					action();
					return;
				}
				if (!feedbacker.CanParry(boostTracker, parryability))
				{
					action();
					return;
				}
				boostTracker.IncrementEnemyBoost();
				feedbacker.ParryEffect(((Component)projectile).transform.position);
				((Component)projectile).gameObject.SetActive(false);
				feedbacker.QueueParry(((Component)projectile).transform.position, delegate(Vector3 offset)
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0044: 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_005e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0063: Unknown result type (might be due to invalid IL or missing references)
					//IL_0070: Unknown result type (might be due to invalid IL or missing references)
					//IL_0085: Unknown result type (might be due to invalid IL or missing references)
					//IL_0086: 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)
					feedbacker.ParryFinishEffect(((Component)projectile).transform.position + offset);
					Vector3 val4 = feedbacker.SolveParryForce(((Component)projectile).transform.position + offset, ((Component)projectile).GetComponent<Rigidbody>().velocity);
					projectile.homingType = (HomingType)0;
					((Component)projectile).transform.rotation = Quaternion.LookRotation(val4);
					boostTracker.IgnoreColliders = enemy.Colliders;
					boostTracker.SetTempSafeEnemyType(enemy.Eid.enemyType);
					boostTracker.SafeEid = enemy.Eid;
					projectile.friendly = false;
					((Component)projectile).gameObject.SetActive(true);
				});
				((EventMethodCanceler)(ref canceler)).CancelMethod();
			}
		}
	}
}
public static class PunchPatches
{
	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		PlayerPunchEvents.PostParryProjectile += new PostParryProjectileEventHandler(PostParryProjectile);
	}

	private static void PostParryProjectile(EventMethodCancelInfo canceler, Punch punch, Projectile proj)
	{
		if (!Cheats.Enabled)
		{
			return;
		}
		ProjectileBoostTracker component = ((Component)proj).GetComponent<ProjectileBoostTracker>();
		if (!((Object)(object)component != (Object)null))
		{
			return;
		}
		component.IncrementPlayerBoosts();
		if (component.NumPlayerBoosts > 1)
		{
			proj.speed *= 0.55f;
		}
		if (component.NumEnemyBoosts != 0)
		{
			if (component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.RevolverBeam || component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.PlayerProjectile)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(75, "<color=#26ff00>PARRY PONG</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
			if (component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.Projectile || component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.HomingProjectile)
			{
				MonoSingleton<StyleHUD>.Instance.AddPoints(125, "<color=#00f2ff>PRO PARRY PONG</color>", (GameObject)null, (EnemyIdentifier)null, -1, "", "");
			}
		}
	}
}
public static class RevolverBeamPatches
{
	private static FieldInfo _enemiesPiercedFi = typeof(RevolverBeam).GetField("enemiesPierced", BindingFlags.Instance | BindingFlags.NonPublic);

	internal static void Initialize()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		RevolverBeamEvents.PreRevolverBeamStart += new PreRevolverBeamStartEventHandler(PreRevolverBeamStart);
		RevolverBeamEvents.PreRevolverBeamHitSomething += new PreRevolverBeamHitSomethingEventHandler(PreRevolverBeamHitSomething);
		RevolverBeamEvents.PreRevolverBeamPiercingShotCheck += new PreRevolverBeamPiercingShotCheckEventHandler(PreRevolverBeamPiercingShotCheck);
	}

	private static void PreRevolverBeamStart(EventMethodCanceler canceler, RevolverBeam revolverBeam)
	{
		if ((Object)(object)((Component)revolverBeam).GetComponent<ProjectileBoostTracker>() == (Object)null)
		{
			((Component)revolverBeam).gameObject.AddComponent<ProjectileBoostTracker>();
		}
	}

	private static void PreRevolverBeamHitSomething(EventMethodCanceler canceler, RevolverBeam revolverBeam, PhysicsCastResult hit)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Invalid comparison between Unknown and I4
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Invalid comparison between Unknown and I4
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		if (!Cheats.Enabled)
		{
			return;
		}
		Options.ProjectileTypeOptions beamsOptions = Options.BeamsOptions;
		if (!beamsOptions.CanBeParried.Value || (int)revolverBeam.beamType == 3 || (int)revolverBeam.beamType == 2)
		{
			return;
		}
		ProjectileBoostTracker component = ((Component)revolverBeam).GetComponent<ProjectileBoostTracker>();
		if ((component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.Coin && !Options.ShotCoinsOptions.CanBeParried.Value) || (component.ProjectileType == ProjectileBoostTracker.ProjectileCategory.Grenade && !Options.GrenadesOptions.CanBeParried.Value))
		{
			return;
		}
		double parryability = component.NotifyContact();
		EnemyIdentifierIdentifier val = default(EnemyIdentifierIdentifier);
		if (!(Object.op_Implicit((Object)(object)hit.collider.attachedRigidbody) ? ((Component)hit.collider.attachedRigidbody).TryGetComponent<EnemyIdentifierIdentifier>(ref val) : ((Component)hit.collider).TryGetComponent<EnemyIdentifierIdentifier>(ref val)) || !Object.op_Implicit((Object)(object)val.eid))
		{
			return;
		}
		EnemyComponents enemy = ((Component)val.eid).GetComponent<EnemyComponents>();
		Assert.IsNotNull((Object)(object)enemy, "");
		if (enemy.Eid.Dead)
		{
			return;
		}
		EnemyFeedbacker feedbacker = enemy.GetFeedbacker();
		if (feedbacker.CanParry(component, parryability) && feedbacker.Enabled && feedbacker.ReadyToParry)
		{
			feedbacker.ParryEffect(hit.point);
			float revBeamDmg = revolverBeam.damage;
			GameObject counterBeamGo = Object.Instantiate<GameObject>(Assets.EnemyRevolverBullet);
			Projectile counterBeam = counterBeamGo.GetComponent<Projectile>();
			ProjectileBoostTracker counterBeamBoostTracker = GameObjectExtensions.GetOrAddComponent<ProjectileBoostTracker>(counterBeamGo);
			component.DebugPrintInfo("revBeam getting parried");
			counterBeamBoostTracker.CopyFrom(component);
			feedbacker.QueueParry(hit.point, delegate(Vector3 offset)
			{
				//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_0024: 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_0045: 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_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: 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_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				counterBeamBoostTracker.IncrementEnemyBoost();
				feedbacker.ParryFinishEffect(hit.point + offset);
				Vector3 val2 = feedbacker.SolveParryForce(hit.point + offset, counterBeamGo.transform.rotation * Vector3.forward * counterBeam.speed);
				counterBeamGo.transform.position = hit.point + offset;
				counterBeamGo.transform.rotation = Quaternion.LookRotation(val2);
				counterBeamGo.SetActive(true);
				IReadOnlyList<Collider> colliders = enemy.Colliders;
				counterBeamBoostTracker.IgnoreColliders = colliders;
				counterBeam.playerBullet = true;
				counterBeam.damage = revBeamDmg * 25f;