Decompiled source of Overshoot v0.1.1

Overshoot.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UKMod template")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UKMod template")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3d018c2f-f5bc-47be-a844-3e9888579d1f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Overshoot;

internal static class RailcannonConfig
{
	public static ConfigEntry<bool> AffectRailcannon;

	public static ConfigEntry<float> ZoomRate;

	public static ConfigEntry<float> MinFov;

	public static void Bind(ConfigFile cfg)
	{
		AffectRailcannon = cfg.Bind<bool>("Railcannon", "AffectRailcannon", true, "Endless zoom while holding alt fire (all railcannon variations).");
		ZoomRate = cfg.Bind<float>("Railcannon", "ZoomRate", 3f, "How fast the zoom keeps closing. FOV shrinks by e^(-rate * seconds held) after the normal half-FOV zoom (3 = roughly 2x tighter every 0.23s).");
		MinFov = cfg.Bind<float>("Railcannon", "MinFov", 0f, "Floor for the zoomed FOV in degrees. Values below 0.01 are treated as 0.01, since Unity can't use an FOV of 0.");
	}
}
internal class RailZoomState
{
	public float Held;
}
[HarmonyPatch(typeof(Railcannon), "Update")]
internal static class Railcannon_Update_Patch
{
	[HarmonyPatch(typeof(Railcannon), "OnDisable")]
	internal static class OnDisable_Patch
	{
		private static void Postfix(Railcannon __instance)
		{
			if (States.TryGetValue(__instance, out var value))
			{
				value.Held = 0f;
			}
		}
	}

	private static readonly ConditionalWeakTable<Railcannon, RailZoomState> States = new ConditionalWeakTable<Railcannon, RailZoomState>();

	private static readonly FieldRef<Railcannon, bool> Zooming = AccessTools.FieldRefAccess<Railcannon, bool>("zooming");

	private static readonly FieldRef<Railcannon, CameraController> Cc = AccessTools.FieldRefAccess<Railcannon, CameraController>("cc");

	private static void Postfix(Railcannon __instance)
	{
		RailZoomState orCreateValue = States.GetOrCreateValue(__instance);
		if (!Plugin.Enabled.Value || !RailcannonConfig.AffectRailcannon.Value || !Zooming.Invoke(__instance))
		{
			orCreateValue.Held = 0f;
			return;
		}
		CameraController val = Cc.Invoke(__instance);
		if (!((Object)(object)val == (Object)null))
		{
			orCreateValue.Held += Time.deltaTime;
			float num = val.defaultFov * 0.5f * Mathf.Exp((0f - RailcannonConfig.ZoomRate.Value) * orCreateValue.Held);
			val.Zoom(Mathf.Max(new float[3]
			{
				0.01f,
				RailcannonConfig.MinFov.Value,
				num
			}));
		}
	}
}
internal static class NailgunConfig
{
	public static ConfigEntry<bool> AffectMagnet;

	public static ConfigEntry<float> MagnetInterval;

	public static ConfigEntry<bool> AutoFire;

	public static ConfigEntry<bool> InfiniteMagnets;

	public static ConfigEntry<float> BurstPitchPerShot;

	public static ConfigEntry<float> BurstVolumeScale;

	public static ConfigEntry<bool> AffectOverheatNails;

	public static ConfigEntry<int> NailMultiplier;

	public static ConfigEntry<float> NailExtraSoundVolume;

	public static ConfigEntry<bool> AffectOverheatSaw;

	public static ConfigEntry<int> SawBurstCount;

	public static ConfigEntry<float> SawBurstDelay;

	public static ConfigEntry<float> SawBurstPitchPerSaw;

	public static ConfigEntry<bool> AffectJumpstart;

	public static ConfigEntry<float> ZapChargeMultiplier;

	public static ConfigEntry<int> PlugCount;

	public static ConfigEntry<float> PlugSpread;

	public static ConfigEntry<float> ExtraPlugVolume;

	public static void Bind(ConfigFile cfg)
	{
		RailcannonConfig.Bind(cfg);
		AffectMagnet = cfg.Bind<bool>("Nailgun - Magnet (Blue)", "AffectMagnet", true, "Apply the changes to the blue (magnet) nailgun and sawblade launcher.");
		MagnetInterval = cfg.Bind<float>("Nailgun - Magnet (Blue)", "MagnetInterval", 0.05f, "Seconds between magnet shots.");
		AutoFire = cfg.Bind<bool>("Nailgun - Magnet (Blue)", "AutoFire", true, "Keep firing magnets while alt fire is held.");
		InfiniteMagnets = cfg.Bind<bool>("Nailgun - Magnet (Blue)", "InfiniteMagnets", true, "Magnets never run out.");
		BurstPitchPerShot = cfg.Bind<float>("Nailgun - Magnet (Blue)", "BurstPitchPerShot", 0.03f, "Magnet shot sound rises by this much pitch for each shot in a continuous burst (capped at 2x).");
		BurstVolumeScale = cfg.Bind<float>("Nailgun - Magnet (Blue)", "BurstVolumeScale", 0.6f, "Volume multiplier for shots after the first in a burst, so rapid fire doesn't stack into a roar.");
		AffectOverheatNails = cfg.Bind<bool>("Nailgun - Overheat (Red)", "AffectOverheatNails", true, "Nailgun overheat (red, variation 0): fire more nails per shot while overheated.");
		NailMultiplier = cfg.Bind<int>("Nailgun - Overheat (Red)", "NailMultiplier", 5, "Nails per overheat shot (the game normally fires 1).");
		NailExtraSoundVolume = cfg.Bind<float>("Nailgun - Overheat (Red)", "NailExtraSoundVolume", 0.45f, "Volume of an extra, deeper muzzle blast layered on each multi-nail shot (0 = off).");
		AffectOverheatSaw = cfg.Bind<bool>("Nailgun - Overheat (Red)", "AffectOverheatSaw", true, "Sawblade launcher overheat alt fire (variation 0): at max heat, fire a burst of saws.");
		SawBurstCount = cfg.Bind<int>("Nailgun - Overheat (Red)", "SawBurstCount", 5, "Total saws in the burst (the first is the game's own shot).");
		SawBurstDelay = cfg.Bind<float>("Nailgun - Overheat (Red)", "SawBurstDelay", 0.2f, "Seconds between saws in the burst. They fire automatically; the burst costs one heatsink like a normal alt fire.");
		SawBurstPitchPerSaw = cfg.Bind<float>("Nailgun - Overheat (Red)", "SawBurstPitchPerSaw", 0.08f, "Launch sound rises by this much pitch for each saw in the burst.");
		AffectJumpstart = cfg.Bind<bool>("Nailgun - Jumpstart (Green)", "AffectJumpstart", true, "Green (variation 2) nailgun / sawblade launcher alt fire: multi-plug, faster charge.");
		ZapChargeMultiplier = cfg.Bind<float>("Nailgun - Jumpstart (Green)", "ZapChargeMultiplier", 3f, "How much faster an attached plug charges.");
		PlugCount = cfg.Bind<int>("Nailgun - Jumpstart (Green)", "PlugCount", 25, "Plugs fired per alt fire (the game fires 1).");
		PlugSpread = cfg.Bind<float>("Nailgun - Jumpstart (Green)", "PlugSpread", 30f, "Cone angle (degrees) the extra plugs are scattered in. The first plug flies true.");
		ExtraPlugVolume = cfg.Bind<float>("Nailgun - Jumpstart (Green)", "ExtraPlugVolume", 0.3f, "Volume multiplier for the extra plugs' own sounds, so 25 plugs don't stack into noise.");
	}
}
internal class MagnetState
{
	public float Cooldown;

	public float LastShotTime = -100f;

	public int BurstCount;

	public float OrigPitch = 1f;

	public float OrigVolume = 1f;

	public bool Modified;
}
internal static class NailgunAccess
{
	public static readonly ConditionalWeakTable<Nailgun, MagnetState> States = new ConditionalWeakTable<Nailgun, MagnetState>();

	public static readonly FieldRef<Nailgun, bool> CanShoot = AccessTools.FieldRefAccess<Nailgun, bool>("canShoot");

	public static readonly FieldRef<Nailgun, GunControl> Gc = AccessTools.FieldRefAccess<Nailgun, GunControl>("gc");

	public static readonly FieldRef<Nailgun, WeaponCharges> Wc = AccessTools.FieldRefAccess<Nailgun, WeaponCharges>("wc");

	public static readonly FieldRef<Nailgun, WeaponIdentifier> Wid = AccessTools.FieldRefAccess<Nailgun, WeaponIdentifier>("wid");

	public static bool Applies(Nailgun ng)
	{
		return Plugin.Enabled.Value && NailgunConfig.AffectMagnet.Value && ng.variation == 1;
	}
}
[HarmonyPatch(typeof(Nailgun), "Update")]
internal static class Nailgun_Update_Patch
{
	private static void Prefix(Nailgun __instance)
	{
		if (NailgunAccess.Applies(__instance) && NailgunConfig.InfiniteMagnets.Value)
		{
			WeaponCharges val = NailgunAccess.Wc.Invoke(__instance);
			if ((Object)(object)val != (Object)null)
			{
				val.naiMagnetCharge = 3f;
			}
		}
	}

	private static void Postfix(Nailgun __instance)
	{
		if (!NailgunAccess.Applies(__instance))
		{
			return;
		}
		MagnetState orCreateValue = NailgunAccess.States.GetOrCreateValue(__instance);
		orCreateValue.Cooldown -= Time.deltaTime;
		InputManager instance = MonoSingleton<InputManager>.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		if (instance.InputSource.Fire2.WasPerformedThisFrame)
		{
			orCreateValue.Cooldown = NailgunConfig.MagnetInterval.Value;
		}
		else
		{
			if (!NailgunConfig.AutoFire.Value || !instance.InputSource.Fire2.IsPressed || orCreateValue.Cooldown > 0f || !NailgunAccess.CanShoot.Invoke(__instance) || instance.PerformingCheatMenuCombo())
			{
				return;
			}
			GunControl val = NailgunAccess.Gc.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && val.activated && !GameStateManager.Instance.PlayerInputLocked)
			{
				WeaponIdentifier val2 = NailgunAccess.Wid.Invoke(__instance);
				if (!((Object)(object)val2 != (Object)null) || val2.delay == 0f)
				{
					orCreateValue.Cooldown = NailgunConfig.MagnetInterval.Value;
					__instance.ShootMagnet();
				}
			}
		}
	}
}
[HarmonyPatch(typeof(Nailgun), "ShootMagnet")]
internal static class Nailgun_ShootMagnet_Patch
{
	private static void Prefix(Nailgun __instance)
	{
		if (!NailgunAccess.Applies(__instance))
		{
			return;
		}
		MagnetState orCreateValue = NailgunAccess.States.GetOrCreateValue(__instance);
		float num = Time.time - orCreateValue.LastShotTime;
		orCreateValue.BurstCount = ((num <= Mathf.Max(0.25f, NailgunConfig.MagnetInterval.Value * 3f)) ? (orCreateValue.BurstCount + 1) : 0);
		orCreateValue.LastShotTime = Time.time;
		AudioSource magnetShotSound = __instance.magnetShotSound;
		if (!((Object)(object)magnetShotSound == (Object)null))
		{
			orCreateValue.OrigPitch = magnetShotSound.pitch;
			orCreateValue.OrigVolume = magnetShotSound.volume;
			orCreateValue.Modified = true;
			magnetShotSound.pitch = Mathf.Min(2f, orCreateValue.OrigPitch + (float)orCreateValue.BurstCount * NailgunConfig.BurstPitchPerShot.Value);
			if (orCreateValue.BurstCount > 0)
			{
				magnetShotSound.volume = orCreateValue.OrigVolume * NailgunConfig.BurstVolumeScale.Value;
			}
		}
	}

	private static Exception Finalizer(Nailgun __instance, Exception __exception)
	{
		if (NailgunAccess.States.TryGetValue(__instance, out var value) && value.Modified)
		{
			AudioSource magnetShotSound = __instance.magnetShotSound;
			if ((Object)(object)magnetShotSound != (Object)null)
			{
				magnetShotSound.pitch = value.OrigPitch;
				magnetShotSound.volume = value.OrigVolume;
			}
			value.Modified = false;
		}
		return __exception;
	}
}
internal static class OverheatAccess
{
	public static readonly FieldRef<Nailgun, bool> BurnOut = AccessTools.FieldRefAccess<Nailgun, bool>("burnOut");

	public static readonly FieldRef<Nailgun, float> HeatUp = AccessTools.FieldRefAccess<Nailgun, float>("heatUp");

	public static readonly FieldRef<Nailgun, float> CurrentSpread = AccessTools.FieldRefAccess<Nailgun, float>("currentSpread");

	public static readonly FieldRef<Nailgun, CameraController> Cc = AccessTools.FieldRefAccess<Nailgun, CameraController>("cc");

	public static readonly FieldRef<Nailgun, CameraFrustumTargeter> Targeter = AccessTools.FieldRefAccess<Nailgun, CameraFrustumTargeter>("targeter");

	public static readonly FieldRef<Nailgun, string[]> VariationTypes = AccessTools.FieldRefAccess<Nailgun, string[]>("projectileVariationTypes");

	public static bool NailsApply(Nailgun ng)
	{
		return Plugin.Enabled.Value && NailgunConfig.AffectOverheatNails.Value && ng.variation == 0 && !ng.altVersion;
	}

	public static bool SawApplies(Nailgun ng)
	{
		return Plugin.Enabled.Value && NailgunConfig.AffectOverheatSaw.Value && ng.variation == 0 && ng.altVersion;
	}

	public static GameObject SpawnNail(Nailgun ng, float spread, out Nail nail)
	{
		//IL_003d: 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_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_0050: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_005f: 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_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		nail = null;
		CameraController val = Cc.Invoke(ng);
		if ((Object)(object)val == (Object)null || (Object)(object)ng.heatedNail == (Object)null)
		{
			return null;
		}
		Vector3 position = ((Component)val).transform.position;
		Vector3 forward = ((Component)val).transform.forward;
		Vector3 val2 = position + forward;
		if (Physics.Raycast(position, forward, 1f, LayerMask.op_Implicit(LayerMaskDefaults.Get((LMD)1))))
		{
			val2 = position;
		}
		GameObject val3 = Object.Instantiate<GameObject>(ng.heatedNail, val2, ((Component)ng).transform.rotation);
		CameraFrustumTargeter val4 = Targeter.Invoke(ng);
		if ((Object)(object)val4 != (Object)null && Object.op_Implicit((Object)(object)val4.CurrentTarget) && val4.IsAutoAimed)
		{
			Transform transform = val3.transform;
			Vector3 val5 = val4.CurrentTargetAimPosition - position;
			transform.position = position + ((Vector3)(ref val5)).normalized;
			val3.transform.LookAt(val4.CurrentTargetAimPosition);
		}
		if (spread > 0f)
		{
			val3.transform.Rotate(Random.Range((0f - spread) / 3f, spread / 3f), Random.Range((0f - spread) / 3f, spread / 3f), Random.Range((0f - spread) / 3f, spread / 3f));
		}
		Rigidbody val6 = default(Rigidbody);
		if (val3.TryGetComponent<Rigidbody>(ref val6))
		{
			val6.velocity = val3.transform.forward * 200f;
		}
		if (val3.TryGetComponent<Nail>(ref nail))
		{
			GunControl val7 = NailgunAccess.Gc.Invoke(ng);
			nail.sourceWeapon = (((Object)(object)val7 != (Object)null) ? val7.currentWeapon : null);
			string[] array = VariationTypes.Invoke(ng);
			if (array != null && ng.variation < array.Length)
			{
				nail.weaponType = array[ng.variation];
			}
		}
		return val3;
	}
}
[HarmonyPatch(typeof(Nailgun), "Shoot")]
internal static class Nailgun_Shoot_Patch
{
	private static void Postfix(Nailgun __instance)
	{
		//IL_00c2: 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)
		if (!OverheatAccess.NailsApply(__instance) || !OverheatAccess.BurnOut.Invoke(__instance))
		{
			return;
		}
		int num = NailgunConfig.NailMultiplier.Value - 1;
		if (num <= 0)
		{
			return;
		}
		float spread = OverheatAccess.CurrentSpread.Invoke(__instance);
		for (int i = 0; i < num; i++)
		{
			OverheatAccess.SpawnNail(__instance, spread, out var _);
		}
		float value = NailgunConfig.NailExtraSoundVolume.Value;
		if (value > 0f && (Object)(object)__instance.muzzleFlash2 != (Object)null && __instance.shootPoints != null && __instance.shootPoints.Length != 0)
		{
			GameObject val = Object.Instantiate<GameObject>(__instance.muzzleFlash2, __instance.shootPoints[0].transform.position, __instance.shootPoints[0].transform.rotation);
			AudioSource component = val.GetComponent<AudioSource>();
			if ((Object)(object)component != (Object)null)
			{
				component.volume = Mathf.Min(1f, value);
				component.pitch = 1.2f;
			}
		}
	}
}
internal class SawBurstState
{
	public bool Armed;
}
[HarmonyPatch(typeof(Nailgun), "SuperSaw")]
internal static class Nailgun_SuperSaw_Patch
{
	private static readonly ConditionalWeakTable<Nailgun, SawBurstState> States = new ConditionalWeakTable<Nailgun, SawBurstState>();

	private static void Prefix(Nailgun __instance)
	{
		if (OverheatAccess.SawApplies(__instance))
		{
			States.GetOrCreateValue(__instance).Armed = OverheatAccess.HeatUp.Invoke(__instance) >= 0.999f;
		}
	}

	private static void Postfix(Nailgun __instance)
	{
		if (!OverheatAccess.SawApplies(__instance))
		{
			return;
		}
		SawBurstState orCreateValue = States.GetOrCreateValue(__instance);
		if (orCreateValue.Armed)
		{
			orCreateValue.Armed = false;
			int num = NailgunConfig.SawBurstCount.Value - 1;
			if (num > 0 && ((Behaviour)__instance).isActiveAndEnabled)
			{
				((MonoBehaviour)__instance).StartCoroutine(Burst(__instance, num));
			}
		}
	}

	private static IEnumerator Burst(Nailgun ng, int extra)
	{
		for (int i = 1; i <= extra; i++)
		{
			yield return (object)new WaitForSeconds(Mathf.Max(0.01f, NailgunConfig.SawBurstDelay.Value));
			if ((Object)(object)ng == (Object)null)
			{
				break;
			}
			Nail nail;
			GameObject saw = OverheatAccess.SpawnNail(ng, 0f, out nail);
			if ((Object)(object)saw == (Object)null)
			{
				continue;
			}
			if ((Object)(object)nail != (Object)null)
			{
				nail.multiHitAmount = 3;
				nail.ForceCheckSawbladeRicochet();
			}
			if ((Object)(object)ng.muzzleFlash2 != (Object)null && ng.shootPoints != null && ng.shootPoints.Length != 0)
			{
				Transform sp = ng.shootPoints[0].transform;
				GameObject flash = Object.Instantiate<GameObject>(ng.muzzleFlash2, sp.position, sp.rotation);
				AudioSource a = flash.GetComponent<AudioSource>();
				if ((Object)(object)a != (Object)null)
				{
					a.pitch = Mathf.Min(2.5f, a.pitch + (float)i * NailgunConfig.SawBurstPitchPerSaw.Value);
				}
			}
			CameraController cc = OverheatAccess.Cc.Invoke(ng);
			if ((Object)(object)cc != (Object)null)
			{
				cc.CameraShake(0.5f);
			}
			nail = null;
		}
	}
}
internal class ZapGroup
{
	public readonly List<Zapper> Members = new List<Zapper>();
}
internal static class JumpstartAccess
{
	public static readonly ConditionalWeakTable<Zapper, ZapGroup> Tags = new ConditionalWeakTable<Zapper, ZapGroup>();

	public static readonly ConditionalWeakTable<Nailgun, ZapGroup> Current = new ConditionalWeakTable<Nailgun, ZapGroup>();

	public static readonly FieldRef<Nailgun, Zapper> CurrentZapper = AccessTools.FieldRefAccess<Nailgun, Zapper>("currentZapper");

	public static bool Applies(Nailgun ng)
	{
		return Plugin.Enabled.Value && NailgunConfig.AffectJumpstart.Value && ng.variation == 2;
	}
}
[HarmonyPatch(typeof(Nailgun), "ShootZapper")]
internal static class Nailgun_ShootZapper_Patch
{
	private static void Prefix(Nailgun __instance)
	{
		if (!JumpstartAccess.Applies(__instance) || !JumpstartAccess.Current.TryGetValue(__instance, out var value))
		{
			return;
		}
		foreach (Zapper member in value.Members)
		{
			if ((Object)(object)member != (Object)null)
			{
				member.Break(true);
			}
		}
		value.Members.Clear();
	}

	private static void Postfix(Nailgun __instance)
	{
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		if (!JumpstartAccess.Applies(__instance))
		{
			return;
		}
		Zapper val = JumpstartAccess.CurrentZapper.Invoke(__instance);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ZapGroup zapGroup = new ZapGroup();
		zapGroup.Members.Add(val);
		JumpstartAccess.Tags.Remove(val);
		JumpstartAccess.Tags.Add(val, zapGroup);
		JumpstartAccess.Current.Remove(__instance);
		JumpstartAccess.Current.Add(__instance, zapGroup);
		CameraController val2 = OverheatAccess.Cc.Invoke(__instance);
		if ((Object)(object)val2 == (Object)null || (Object)(object)__instance.zapper == (Object)null)
		{
			return;
		}
		CameraFrustumTargeter val3 = OverheatAccess.Targeter.Invoke(__instance);
		int num = NailgunConfig.PlugCount.Value - 1;
		for (int i = 0; i < num; i++)
		{
			Zapper val4 = Object.Instantiate<Zapper>(__instance.zapper, val2.GetDefaultPos(), ((Component)__instance).transform.rotation);
			((Component)val4).transform.forward = ((Component)__instance).transform.forward;
			if ((Object)(object)val3 != (Object)null && Object.op_Implicit((Object)(object)val3.CurrentTarget) && val3.IsAutoAimed)
			{
				((Component)val4).transform.LookAt(val3.CurrentTargetAimPosition);
			}
			float value = NailgunConfig.PlugSpread.Value;
			if (value > 0f)
			{
				Vector2 val5 = Random.insideUnitCircle * value;
				((Component)val4).transform.Rotate(val5.x, val5.y, 0f);
			}
			Rigidbody component = ((Component)val4).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.AddForce(((Component)val4).transform.forward * 100f, (ForceMode)2);
			}
			val4.lineStartTransform = __instance.zapperAttachTransform;
			val4.connectedRB = MonoSingleton<NewMovement>.Instance.rb;
			val4.sourceWeapon = ((Component)__instance).gameObject;
			Collider[] componentsInChildren = ((Component)val4).GetComponentsInChildren<Collider>();
			foreach (Zapper member in zapGroup.Members)
			{
				if ((Object)(object)member == (Object)null)
				{
					continue;
				}
				Collider[] array = componentsInChildren;
				foreach (Collider val6 in array)
				{
					Collider[] componentsInChildren2 = ((Component)member).GetComponentsInChildren<Collider>();
					foreach (Collider val7 in componentsInChildren2)
					{
						if ((Object)(object)val6 != (Object)null && (Object)(object)val7 != (Object)null)
						{
							Physics.IgnoreCollision(val6, val7);
						}
					}
				}
			}
			AudioSource component2 = ((Component)val4).GetComponent<AudioSource>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.volume *= NailgunConfig.ExtraPlugVolume.Value;
			}
			zapGroup.Members.Add(val4);
			JumpstartAccess.Tags.Add(val4, zapGroup);
		}
	}
}
[HarmonyPatch(typeof(Zapper), "Update")]
internal static class Zapper_Update_Patch
{
	private static void Postfix(Zapper __instance)
	{
		if (!JumpstartAccess.Tags.TryGetValue(__instance, out var value) || !Plugin.Enabled.Value || !NailgunConfig.AffectJumpstart.Value || !__instance.attached)
		{
			return;
		}
		float num = (NailgunConfig.ZapChargeMultiplier.Value - 1f) * Time.deltaTime;
		float num2 = Mathf.Min(5f, __instance.charge + Mathf.Max(0f, num));
		foreach (Zapper member in value.Members)
		{
			if ((Object)(object)member != (Object)null && member.attached && member.charge > num2)
			{
				num2 = member.charge;
			}
		}
		__instance.charge = num2;
	}
}
[BepInPlugin("com.nico.overshoot", "Overshoot", "0.1.1")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.nico.overshoot";

	public const string PluginName = "Overshoot";

	public const string PluginVersion = "0.1.1";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> CheaterMode;

	internal static ConfigEntry<bool> AffectPiercer;

	internal static ConfigEntry<bool> AffectSharpshooter;

	internal static ConfigEntry<float> GrowthPerSecond;

	internal static ConfigEntry<float> AccelerationPerSecond;

	internal static ConfigEntry<float> MaxOvercharge;

	internal static ConfigEntry<float> DamagePerHundred;

	internal static ConfigEntry<float> ForcePerHundred;

	internal static ConfigEntry<float> ExtraRicochetsPerHundred;

	internal static ConfigEntry<float> VisualScaleCap;

	internal static ConfigEntry<float> FadeStartCharge;

	internal static ConfigEntry<float> FadeEndCharge;

	internal static ConfigEntry<float> FadeMinOpacity;

	internal static ConfigEntry<float> SpinPerHundred;

	internal static ConfigEntry<float> MaxDebrisScale;

	private void Awake()
	{
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch.");
		CheaterMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "toopid wimp cheater mode", false, "fuckin wimp!");
		AffectPiercer = ((BaseUnityPlugin)this).Config.Bind<bool>("Revolver - Piercer and Sharpshooter", "AffectPiercer", true, "Apply to the Piercer Revolver (variation 0).");
		AffectSharpshooter = ((BaseUnityPlugin)this).Config.Bind<bool>("Revolver - Piercer and Sharpshooter", "AffectSharpshooter", true, "Apply to the Sharpshooter (variation 2, the twirl charge).");
		GrowthPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "GrowthPerSecond", 100f, "Overcharge gained per second while holding alt fire at full charge (100 = one extra full charge).");
		AccelerationPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "AccelerationPerSecond", 40f, "Extra growth rate added for every second you stay overcharging, so it snowballs. 0 = linear.");
		MaxOvercharge = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "MaxOvercharge", 0f, "Upper limit for overcharge. 0 or less = no limit (keeps growing forever).");
		DamagePerHundred = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "DamagePerHundred", 1f, "Damage multiplier gained per 100 overcharge. 1 means +100% damage per 100 overcharge.");
		ForcePerHundred = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "ForcePerHundred", 1f, "Bullet force multiplier gained per 100 overcharge.");
		ExtraRicochetsPerHundred = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "ExtraRicochetsPerHundred", 1f, "Extra ricochets per 100 overcharge (Sharpshooter only).");
		VisualScaleCap = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "VisualScaleCap", 0f, "Max size multiplier of the charge effect on the gun. 0 or less = no cap (keeps scaling forever).");
		FadeStartCharge = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "FadeStartCharge", 500f, "Total charge (100 + overcharge) at which the charge effect starts to become see-through.");
		FadeEndCharge = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "FadeEndCharge", 1000f, "Total charge at which the charge effect reaches FadeMinOpacity. It stays there beyond this.");
		FadeMinOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "FadeMinOpacity", 0.8f, "Lowest opacity of the charge effect (0.8 = 80%).");
		SpinPerHundred = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "SpinDegreesPerSecondPerHundred", 1500f, "Extra spin speed (degrees/second) added to the Sharpshooter's twirl for every 100 overcharge. Not capped.");
		MaxDebrisScale = ((BaseUnityPlugin)this).Config.Bind<float>("Revolver - Piercer and Sharpshooter", "MaxDebrisScale", 3f, "Revolver beam debris (size and count) never exceeds this multiple of the unmodified super shot's value. 0 or less = no limit.");
		ShotgunConfig.Bind(((BaseUnityPlugin)this).Config);
		NailgunConfig.Bind(((BaseUnityPlugin)this).Config);
		RailcannonConfig.Bind(((BaseUnityPlugin)this).Config);
		RocketLauncherConfig.Bind(((BaseUnityPlugin)this).Config);
		MarksmanConfig.Bind(((BaseUnityPlugin)this).Config);
		new Harmony("com.nico.overshoot").PatchAll(typeof(Plugin).Assembly);
		Log.LogInfo((object)"Overshoot 0.1.1 loaded.");
	}
}
internal class OverState
{
	public float Over;

	public float HeldTime;

	public bool FadeApplied;

	public float SpinSpeed;

	public float ExtraAngle;
}
internal static class Overcharge
{
	private static readonly ConditionalWeakTable<Revolver, OverState> States = new ConditionalWeakTable<Revolver, OverState>();

	public static readonly FieldRef<Revolver, bool> ChargingPierce = AccessTools.FieldRefAccess<Revolver, bool>("chargingPierce");

	public static readonly FieldRef<Revolver, bool> ShootReady = AccessTools.FieldRefAccess<Revolver, bool>("shootReady");

	public static readonly FieldRef<Revolver, bool> GunReady = AccessTools.FieldRefAccess<Revolver, bool>("gunReady");

	public static readonly FieldRef<Revolver, AudioSource> Ceaud = AccessTools.FieldRefAccess<Revolver, AudioSource>("ceaud");

	public static readonly FieldRef<Revolver, Light> Celight = AccessTools.FieldRefAccess<Revolver, Light>("celight");

	public static OverState Get(Revolver r)
	{
		return States.GetOrCreateValue(r);
	}

	public static bool Applies(Revolver r)
	{
		if (!Plugin.Enabled.Value)
		{
			return false;
		}
		if (r.gunVariation == 0)
		{
			return Plugin.AffectPiercer.Value;
		}
		if (r.gunVariation == 2)
		{
			return Plugin.AffectSharpshooter.Value;
		}
		return false;
	}
}
[HarmonyPatch(typeof(StatsManager), "Awake")]
internal static class StatsManager_Awake_CheaterMode_Patch
{
	private static void Postfix()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		if (!Plugin.CheaterMode.Value && (Object)MonoSingleton<StatsManager>.Instance != (Object)null)
		{
			MonoSingleton<StatsManager>.Instance.majorUsed = true;
		}
	}
}
[HarmonyPatch(typeof(Revolver), "Update")]
internal static class Revolver_Update_Patch
{
	private static readonly int[] ColorProps = new int[3]
	{
		Shader.PropertyToID("_Color"),
		Shader.PropertyToID("_TintColor"),
		Shader.PropertyToID("_BaseColor")
	};

	private static readonly MaterialPropertyBlock Block = new MaterialPropertyBlock();

	private static void Postfix(Revolver __instance)
	{
		if (!Overcharge.Applies(__instance))
		{
			return;
		}
		OverState overState = Overcharge.Get(__instance);
		bool flag = Overcharge.ChargingPierce.Invoke(__instance);
		bool flag2 = __instance.pierceShotCharge >= 100f;
		if (flag && flag2 && Overcharge.GunReady.Invoke(__instance))
		{
			overState.HeldTime += Time.deltaTime;
			float num = Plugin.GrowthPerSecond.Value + Plugin.AccelerationPerSecond.Value * overState.HeldTime;
			overState.Over += num * Time.deltaTime;
			float value = Plugin.MaxOvercharge.Value;
			if (value > 0f && overState.Over > value)
			{
				overState.Over = value;
			}
		}
		else if (!flag && Overcharge.ShootReady.Invoke(__instance))
		{
			overState.Over = 0f;
			overState.HeldTime = 0f;
		}
		else if (!flag2)
		{
			overState.Over = 0f;
			overState.HeldTime = 0f;
		}
		if (overState.Over > 0f)
		{
			ApplyVisuals(__instance, overState);
		}
		else if (overState.FadeApplied)
		{
			ClearFade(__instance, overState);
		}
	}

	private static void ApplyVisuals(Revolver r, OverState s)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		if (r.gunVariation != 0)
		{
			return;
		}
		float num = 100f + s.Over;
		ApplyFade(r, s, num);
		if ((Object)(object)r.chargeEffect != (Object)null && r.gunVariation == 0)
		{
			float num2 = num * 0.02f;
			float value = Plugin.VisualScaleCap.Value;
			if (value > 0f)
			{
				num2 = Mathf.Min(num2, value);
			}
			r.chargeEffect.transform.localScale = Vector3.one * num2;
		}
		AudioSource val = Overcharge.Ceaud.Invoke(r);
		if ((Object)(object)val != (Object)null && r.gunVariation == 0)
		{
			val.pitch = Mathf.Min(3f, num * 0.005f);
		}
		Light val2 = Overcharge.Celight.Invoke(r);
		if ((Object)(object)val2 != (Object)null)
		{
			val2.range = num * 0.01f;
		}
	}

	private static void ApplyFade(Revolver r, OverState s, float total)
	{
		//IL_0100: 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_011a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)r.chargeEffect == (Object)null)
		{
			return;
		}
		float value = Plugin.FadeStartCharge.Value;
		float num = Mathf.Max(value + 1f, Plugin.FadeEndCharge.Value);
		float num2 = Mathf.Clamp01((total - value) / (num - value));
		if (num2 <= 0f)
		{
			if (s.FadeApplied)
			{
				ClearFade(r, s);
			}
			return;
		}
		float num3 = Mathf.Lerp(1f, Plugin.FadeMinOpacity.Value, num2);
		Renderer[] componentsInChildren = r.chargeEffect.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			Material sharedMaterial = val.sharedMaterial;
			if ((Object)(object)sharedMaterial == (Object)null)
			{
				continue;
			}
			val.GetPropertyBlock(Block);
			bool flag = false;
			int[] colorProps = ColorProps;
			foreach (int num4 in colorProps)
			{
				if (sharedMaterial.HasProperty(num4))
				{
					Color color = sharedMaterial.GetColor(num4);
					color.a *= num3;
					Block.SetColor(num4, color);
					flag = true;
				}
			}
			if (flag)
			{
				val.SetPropertyBlock(Block);
			}
		}
		s.FadeApplied = true;
	}

	private static void ClearFade(Revolver r, OverState s)
	{
		s.FadeApplied = false;
		if (!((Object)(object)r.chargeEffect == (Object)null))
		{
			Renderer[] componentsInChildren = r.chargeEffect.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				val.SetPropertyBlock((MaterialPropertyBlock)null);
			}
		}
	}
}
[HarmonyPatch(typeof(Revolver), "Shoot")]
internal static class Revolver_Shoot_Patch
{
	private static void Prefix(Revolver __instance, int shotType, out float __state)
	{
		__state = 0f;
		if (shotType == 2 && Overcharge.Applies(__instance))
		{
			__state = Overcharge.Get(__instance).Over;
		}
	}

	private static void Postfix(Revolver __instance, int shotType, float __state)
	{
		if (shotType != 2 || !Overcharge.Applies(__instance))
		{
			return;
		}
		OverState overState = Overcharge.Get(__instance);
		overState.Over = 0f;
		overState.HeldTime = 0f;
		GameObject revolverBeamSuper = __instance.revolverBeamSuper;
		if ((Object)(object)revolverBeamSuper == (Object)null)
		{
			return;
		}
		RevolverBeam component = revolverBeamSuper.GetComponent<RevolverBeam>();
		if ((Object)(object)component != (Object)null)
		{
			DebrisLimit.BaseDamage[__instance.gunVariation] = component.damage;
		}
		if (__state <= 0f)
		{
			return;
		}
		string name = ((Object)revolverBeamSuper).name;
		RevolverBeam[] array = Object.FindObjectsOfType<RevolverBeam>();
		foreach (RevolverBeam val in array)
		{
			if (!(((Object)((Component)val).gameObject).name != name + "(Clone)") && !BeamTracker.IsProcessed(val))
			{
				BeamTracker.MarkProcessed(val);
				BeamBuff.Apply(val, __instance, __state);
			}
		}
	}
}
[HarmonyPatch(typeof(Revolver), "LateUpdate")]
internal static class Revolver_LateUpdate_Patch
{
	private static void Postfix(Revolver __instance)
	{
		//IL_011e: 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_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.gunVariation != 2 || !Overcharge.Applies(__instance))
		{
			return;
		}
		OverState overState = Overcharge.Get(__instance);
		bool flag = Overcharge.ChargingPierce.Invoke(__instance);
		float deltaTime = Time.deltaTime;
		if (flag && overState.Over > 0f)
		{
			overState.SpinSpeed = overState.Over / 100f * Plugin.SpinPerHundred.Value;
		}
		else
		{
			overState.SpinSpeed *= Mathf.Exp(-4f * deltaTime);
		}
		if (overState.SpinSpeed < 1f)
		{
			overState.SpinSpeed = 0f;
			overState.ExtraAngle = 0f;
			return;
		}
		if ((!flag && !__instance.twirlRecovery) || (Object)(object)__instance.twirlBone == (Object)null)
		{
			overState.ExtraAngle = 0f;
			return;
		}
		overState.ExtraAngle = Mathf.Repeat(overState.ExtraAngle + overState.SpinSpeed * deltaTime, 360f);
		Vector3 val = (__instance.altVersion ? Vector3.left : Vector3.forward);
		Transform twirlBone = __instance.twirlBone;
		twirlBone.localRotation *= Quaternion.AngleAxis(overState.ExtraAngle, val);
		AudioSource val2 = Overcharge.Ceaud.Invoke(__instance);
		if ((Object)(object)val2 != (Object)null)
		{
			val2.pitch = Mathf.Min(3f, val2.pitch + overState.Over / 100f * 0.15f);
		}
	}
}
internal static class DebrisLimit
{
	public static readonly Dictionary<int, float> BaseDamage = new Dictionary<int, float>();

	public static RevolverBeam Current;
}
[HarmonyPatch(typeof(RevolverBeam), "ExecuteHits")]
internal static class RevolverBeam_ExecuteHits_Patch
{
	private static void Prefix(RevolverBeam __instance)
	{
		DebrisLimit.Current = __instance;
	}

	private static Exception Finalizer(Exception __exception)
	{
		DebrisLimit.Current = null;
		return __exception;
	}
}
[HarmonyPatch]
internal static class SceneHelper_CreateEnviroGibs_Patch
{
	private static IEnumerable<MethodBase> TargetMethods()
	{
		foreach (MethodInfo m in AccessTools.GetDeclaredMethods(typeof(SceneHelper)))
		{
			if (m.Name != "CreateEnviroGibs")
			{
				continue;
			}
			ParameterInfo[] parameters = m.GetParameters();
			foreach (ParameterInfo p in parameters)
			{
				if (p.ParameterType == typeof(float))
				{
					yield return m;
					break;
				}
			}
		}
	}

	private static void Prefix(object[] __args, MethodBase __originalMethod)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Invalid comparison between Unknown and I4
		float value = Plugin.MaxDebrisScale.Value;
		RevolverBeam current = DebrisLimit.Current;
		if (value <= 0f || (Object)(object)current == (Object)null || (int)current.beamType > 0 || !DebrisLimit.BaseDamage.TryGetValue(current.gunVariation, out var value2) || value2 <= 0f)
		{
			return;
		}
		float num = value2 * value;
		int num2 = Mathf.RoundToInt(3f * num);
		ParameterInfo[] parameters = __originalMethod.GetParameters();
		bool flag = false;
		bool flag2 = false;
		for (int i = 0; i < parameters.Length; i++)
		{
			if (!flag && parameters[i].ParameterType == typeof(float))
			{
				flag = true;
				if ((float)__args[i] > num)
				{
					__args[i] = num;
				}
			}
			else if (!flag2 && parameters[i].ParameterType == typeof(int))
			{
				flag2 = true;
				if ((int)__args[i] > num2)
				{
					__args[i] = num2;
				}
			}
		}
	}
}
internal static class BeamTracker
{
	private static readonly ConditionalWeakTable<RevolverBeam, object> Seen = new ConditionalWeakTable<RevolverBeam, object>();

	public static bool IsProcessed(RevolverBeam b)
	{
		object value;
		return Seen.TryGetValue(b, out value);
	}

	public static void MarkProcessed(RevolverBeam b)
	{
		Seen.Add(b, new object());
	}
}
internal static class BeamBuff
{
	public static void Apply(RevolverBeam beam, Revolver gun, float over)
	{
		float num = over / 100f;
		float num2 = 1f + num * Plugin.DamagePerHundred.Value;
		float num3 = 1f + num * Plugin.ForcePerHundred.Value;
		beam.damage *= num2;
		if (beam.enemyDamageOverride != 0f)
		{
			beam.enemyDamageOverride *= num2;
		}
		beam.bulletForce = Mathf.RoundToInt((float)beam.bulletForce * num3);
		if (gun.gunVariation == 2)
		{
			int num4 = Mathf.FloorToInt(num * Plugin.ExtraRicochetsPerHundred.Value);
			if (num4 > 0)
			{
				beam.ricochetAmount += num4;
			}
		}
		Plugin.Log.LogInfo((object)$"Overshoot shot: +{over:F0} overcharge -> damage x{num2:F2}, force x{num3:F2}");
	}
}
internal static class MarksmanConfig
{
	public static ConfigEntry<bool> AffectMarksman;

	public static ConfigEntry<bool> InfiniteCoins;

	public static ConfigEntry<bool> AutoThrow;

	public static ConfigEntry<float> StartInterval;

	public static ConfigEntry<float> MinInterval;

	public static ConfigEntry<float> SpeedUpRate;

	public static ConfigEntry<float> SpreadPerSecond;

	public static ConfigEntry<float> MaxSpread;

	public static ConfigEntry<bool> MergeCoins;

	public static ConfigEntry<float> MergeRadius;

	public static ConfigEntry<float> MergeMinAge;

	public static ConfigEntry<float> MergePitchPerDoubling;

	public static ConfigEntry<float> SizeScaleExponent;

	public static void Bind(ConfigFile cfg)
	{
		AffectMarksman = cfg.Bind<bool>("Revolver - Marksman", "AffectMarksman", true, "Apply the changes to the marksman revolver (variation 1).");
		InfiniteCoins = cfg.Bind<bool>("Revolver - Marksman", "InfiniteCoins", true, "Coins never run out.");
		AutoThrow = cfg.Bind<bool>("Revolver - Marksman", "AutoThrow", true, "Keep throwing coins while alt fire is held.");
		StartInterval = cfg.Bind<float>("Revolver - Marksman", "StartInterval", 0.35f, "Seconds between coins when you first start holding alt fire.");
		MinInterval = cfg.Bind<float>("Revolver - Marksman", "MinInterval", 0.04f, "The shortest the gap between coins can get.");
		SpeedUpRate = cfg.Bind<float>("Revolver - Marksman", "SpeedUpRate", 0.5f, "How quickly the gap shrinks toward MinInterval the longer you hold (higher = sooner).");
		SpreadPerSecond = cfg.Bind<float>("Revolver - Marksman", "SpreadPerSecond", 6f, "Degrees of throw spread added for each second held.");
		MaxSpread = cfg.Bind<float>("Revolver - Marksman", "MaxSpread", 12f, "Largest throw spread in degrees.");
		MergeCoins = cfg.Bind<bool>("Revolver - Marksman", "MergeCoins", true, "Coins that touch combine into one bigger coin.");
		MergeRadius = cfg.Bind<float>("Revolver - Marksman", "MergeRadius", 0.8f, "How close two coins must be to merge (scaled up for bigger coins).");
		MergeMinAge = cfg.Bind<float>("Revolver - Marksman", "MergeMinAge", 0.12f, "Seconds a coin must be airborne before it can merge, so freshly thrown coins don't merge at your hand.");
		MergePitchPerDoubling = cfg.Bind<float>("Revolver - Marksman", "MergePitchPerDoubling", 0.15f, "Merge sound rises by this much pitch each time the merged size doubles.");
		SizeScaleExponent = cfg.Bind<float>("Revolver - Marksman", "SizeScaleExponent", 1f, "How a merged coin's size turns into visual scale: scale = size ^ this. 1 = scale equals its multiplier (a x5 coin is 5x as wide), 0.5 = square root, 0.33 = cube root.");
	}
}
internal class MarksmanState
{
	public float Held;

	public float Timer;
}
internal static class MarksmanAccess
{
	public static readonly ConditionalWeakTable<Revolver, MarksmanState> States = new ConditionalWeakTable<Revolver, MarksmanState>();

	public static readonly ConditionalWeakTable<Coin, object> Seen = new ConditionalWeakTable<Coin, object>();

	public static readonly ConditionalWeakTable<Coin, object> Age = new ConditionalWeakTable<Coin, object>();

	public static readonly List<Coin> Tracked = new List<Coin>();

	public static readonly FieldRef<Revolver, WeaponIdentifier> Wid = AccessTools.FieldRefAccess<Revolver, WeaponIdentifier>("wid");

	public static readonly FieldRef<Revolver, WeaponCharges> Wc = AccessTools.FieldRefAccess<Revolver, WeaponCharges>("wc");

	public static readonly MethodInfo ThrowCoin = AccessTools.Method(typeof(Revolver), "ThrowCoin", (Type[])null, (Type[])null);

	public static bool Applies(Revolver r)
	{
		return Plugin.Enabled.Value && MarksmanConfig.AffectMarksman.Value && r.gunVariation == 1;
	}

	public static Revolver MarksmanOf(Coin c)
	{
		if ((Object)(object)c == (Object)null || (Object)(object)c.sourceWeapon == (Object)null)
		{
			return null;
		}
		Revolver component = c.sourceWeapon.GetComponent<Revolver>();
		return ((Object)(object)component != (Object)null && Applies(component)) ? component : null;
	}
}
[HarmonyPatch(typeof(Revolver), "Update")]
internal static class Revolver_Marksman_Patch
{
	private static void Prefix(Revolver __instance)
	{
		if (MarksmanAccess.Applies(__instance) && MarksmanConfig.InfiniteCoins.Value)
		{
			WeaponCharges val = MarksmanAccess.Wc.Invoke(__instance);
			if ((Object)(object)val != (Object)null)
			{
				val.rev1charge = 400f;
			}
		}
	}

	private static void Postfix(Revolver __instance)
	{
		if (!MarksmanAccess.Applies(__instance) || !MarksmanConfig.AutoThrow.Value)
		{
			return;
		}
		MarksmanState orCreateValue = MarksmanAccess.States.GetOrCreateValue(__instance);
		InputManager instance = MonoSingleton<InputManager>.Instance;
		if ((Object)(object)instance == (Object)null || !instance.InputSource.Fire2.IsPressed)
		{
			orCreateValue.Held = 0f;
			orCreateValue.Timer = 0f;
			return;
		}
		orCreateValue.Held += Time.deltaTime;
		orCreateValue.Timer -= Time.deltaTime;
		float num = 1f - Mathf.Exp((0f - orCreateValue.Held) * MarksmanConfig.SpeedUpRate.Value);
		float timer = Mathf.Lerp(MarksmanConfig.StartInterval.Value, MarksmanConfig.MinInterval.Value, num);
		if (instance.InputSource.Fire2.WasPerformedThisFrame)
		{
			orCreateValue.Timer = timer;
		}
		else if (!(orCreateValue.Timer > 0f) && !instance.PerformingCheatMenuCombo() && !GameStateManager.Instance.PlayerInputLocked && !((Object)(object)__instance.gc == (Object)null) && __instance.gc.activated)
		{
			WeaponIdentifier val = MarksmanAccess.Wid.Invoke(__instance);
			if (!((Object)(object)val != (Object)null) || val.delay == 0f)
			{
				orCreateValue.Timer = timer;
				MarksmanAccess.ThrowCoin.Invoke(__instance, null);
			}
		}
	}
}
[HarmonyPatch(typeof(Revolver), "ThrowCoin")]
internal static class Revolver_ThrowCoin_Patch
{
	private static void Postfix(Revolver __instance)
	{
		//IL_005e: 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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		if (!MarksmanAccess.Applies(__instance))
		{
			return;
		}
		MarksmanState orCreateValue = MarksmanAccess.States.GetOrCreateValue(__instance);
		float num = Mathf.Min(MarksmanConfig.MaxSpread.Value, orCreateValue.Held * MarksmanConfig.SpreadPerSecond.Value);
		Camera main = Camera.main;
		Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : Vector3.zero);
		Coin val2 = null;
		float num2 = float.MaxValue;
		Coin[] array = Object.FindObjectsOfType<Coin>();
		foreach (Coin val3 in array)
		{
			if (!((Object)(object)val3 == (Object)null) && !val3.shot && !MarksmanAccess.Seen.TryGetValue(val3, out var _) && !((Object)(object)val3.sourceWeapon != (Object)(object)__instance.gc.currentWeapon))
			{
				Vector3 val4 = ((Component)val3).transform.position - val;
				float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
				if (sqrMagnitude < num2)
				{
					num2 = sqrMagnitude;
					val2 = val3;
				}
			}
		}
		if (!((Object)(object)val2 == (Object)null))
		{
			MarksmanAccess.Seen.Add(val2, null);
			if (num > 0f && (Object)(object)main != (Object)null && (Object)(object)val2.rb != (Object)null)
			{
				Vector2 val5 = Random.insideUnitCircle * Mathf.Tan(num * ((float)Math.PI / 180f)) * 20f;
				val2.rb.AddForce(((Component)main).transform.right * val5.x + ((Component)main).transform.up * val5.y, (ForceMode)2);
			}
		}
	}
}
[HarmonyPatch(typeof(Coin), "Start")]
internal static class Coin_Start_Patch
{
	private static void Postfix(Coin __instance)
	{
		if (!((Object)(object)MarksmanAccess.MarksmanOf(__instance) == (Object)null))
		{
			MarksmanAccess.Tracked.Add(__instance);
			MarksmanAccess.Age.Remove(__instance);
			MarksmanAccess.Age.Add(__instance, Time.time);
		}
	}
}
[HarmonyPatch(typeof(Coin), "Update")]
internal static class Coin_Update_Merge_Patch
{
	private static int lastFrame = -1;

	private static float Exponent()
	{
		return Mathf.Max(0.05f, MarksmanConfig.SizeScaleExponent.Value);
	}

	private static float SizeOf(Coin c, float baseScaleX)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		float num = ((Component)c).transform.localScale.x / Mathf.Max(0.0001f, baseScaleX);
		return Mathf.Max(1f, Mathf.Pow(num, 1f / Exponent()));
	}

	private static float AgeOf(Coin c)
	{
		object value;
		return MarksmanAccess.Age.TryGetValue(c, out value) ? (Time.time - (float)value) : 0f;
	}

	private static void Postfix()
	{
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.Enabled.Value || !MarksmanConfig.MergeCoins.Value || Time.frameCount == lastFrame)
		{
			return;
		}
		lastFrame = Time.frameCount;
		List<Coin> tracked = MarksmanAccess.Tracked;
		for (int num = tracked.Count - 1; num >= 0; num--)
		{
			Coin val = tracked[num];
			if ((Object)(object)val == (Object)null || val.shot || !((Component)val).gameObject.activeInHierarchy)
			{
				tracked.RemoveAt(num);
			}
		}
		if (tracked.Count < 2)
		{
			return;
		}
		HashSet<Coin> hashSet = new HashSet<Coin>();
		List<Coin> list = new List<Coin>();
		for (int i = 0; i < tracked.Count; i++)
		{
			Coin val2 = tracked[i];
			if (hashSet.Contains(val2) || AgeOf(val2) < MarksmanConfig.MergeMinAge.Value)
			{
				continue;
			}
			Revolver val3 = MarksmanAccess.MarksmanOf(val2);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val3.coin == (Object)null)
			{
				continue;
			}
			float x = val3.coin.transform.localScale.x;
			for (int j = i + 1; j < tracked.Count; j++)
			{
				Coin val4 = tracked[j];
				if (!hashSet.Contains(val4) && !(AgeOf(val4) < MarksmanConfig.MergeMinAge.Value))
				{
					float num2 = MarksmanConfig.MergeRadius.Value * 0.5f * (((Component)val2).transform.localScale.x + ((Component)val4).transform.localScale.x) / Mathf.Max(0.0001f, x);
					Vector3 val5 = ((Component)val2).transform.position - ((Component)val4).transform.position;
					if (!(((Vector3)(ref val5)).sqrMagnitude > num2 * num2))
					{
						hashSet.Add(val2);
						hashSet.Add(val4);
						list.Add(Merge(val2, val4, val3));
						break;
					}
				}
			}
		}
	}

	private static Coin Merge(Coin a, Coin b, Revolver rev)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0065: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		GameObject coin = rev.coin;
		float x = coin.transform.localScale.x;
		float num = SizeOf(a, x);
		float num2 = SizeOf(b, x);
		float num3 = num + num2;
		float num4 = Mathf.Max(a.power / num, b.power / num2);
		Vector3 val = (((Component)a).transform.position + ((Component)b).transform.position) * 0.5f;
		GameObject val2 = Object.Instantiate<GameObject>(coin, val, Quaternion.identity);
		Coin component = val2.GetComponent<Coin>();
		component.sourceWeapon = a.sourceWeapon;
		component.power = num4 * num3;
		component.ricochets = a.ricochets + b.ricochets;
		val2.transform.localScale = coin.transform.localScale * Mathf.Pow(num3, Exponent());
		((Object)val2).name = "MergedCoin x" + num3.ToString("0.#");
		MarksmanAccess.Seen.Add(component, null);
		Rigidbody val3 = (((Object)(object)component.rb != (Object)null) ? component.rb : val2.GetComponent<Rigidbody>());
		if ((Object)(object)val3 != (Object)null)
		{
			val3.isKinematic = false;
			val3.velocity = Vector3.zero;
			Vector3 down = Vector3.down;
			Vector3 gravity = Physics.gravity;
			PhysicsExtensions.SetCustomGravity(val3, down * ((Vector3)(ref gravity)).magnitude);
			PhysicsExtensions.SetCustomGravityMode(val3, true);
			val3.AddForce(Vector3.up * 25f, (ForceMode)2);
		}
		if ((Object)(object)a.coinHitSound != (Object)null)
		{
			GameObject val4 = Object.Instantiate<GameObject>(a.coinHitSound, val, Quaternion.identity);
			float pitch = Mathf.Min(3f, 1f + Mathf.Log(num3, 2f) * MarksmanConfig.MergePitchPerDoubling.Value);
			AudioSource[] components = val4.GetComponents<AudioSource>();
			foreach (AudioSource val5 in components)
			{
				val5.pitch = pitch;
				val5.Play();
			}
		}
		Retire(a);
		Retire(b);
		return component;
	}

	private static void Retire(Coin c)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		c.UntrackCoin();
		((Component)c).gameObject.SetActive(false);
		new GameObject().AddComponent<CoinCollector>().coin = ((Component)c).gameObject;
		((MonoBehaviour)c).CancelInvoke("GetDeleted");
	}
}
internal static class RocketLauncherConfig
{
	public static ConfigEntry<bool> AffectFreezeframe;

	public static ConfigEntry<float> ReverseSpeedMultiplier;

	public static ConfigEntry<float> TickSpeedMultiplier;

	public static ConfigEntry<bool> AffectCannonball;

	public static ConfigEntry<float> CannonGrowthPerSecond;

	public static ConfigEntry<float> CannonAccelerationPerSecond;

	public static ConfigEntry<float> CannonMaxOvercharge;

	public static ConfigEntry<float> CannonDamagePerFull;

	public static ConfigEntry<float> CannonSizePerFull;

	public static ConfigEntry<float> CannonMaxSizeScale;

	public static ConfigEntry<float> CannonSpeedPerFull;

	public static ConfigEntry<float> CannonGravityPerFull;

	public static ConfigEntry<float> CannonMaxGravityBonus;

	public static ConfigEntry<float> CannonRainbowCycleFulls;

	public static ConfigEntry<float> CannonArmTurnsPerFull;

	public static ConfigEntry<float> CannonChargePitchPerFull;

	public static ConfigEntry<float> CannonShotVolumePerFull;

	public static ConfigEntry<float> CannonShotPitchDropPerFull;

	public static ConfigEntry<bool> AffectFirestarter;

	public static ConfigEntry<bool> InfiniteOil;

	public static ConfigEntry<float> OilRampPerSecond;

	public static ConfigEntry<float> OilDecayPerSecond;

	public static ConfigEntry<float> OilMaxSpread;

	public static ConfigEntry<int> OilMaxPerShot;

	public static ConfigEntry<float> OilExtraPerRamp;

	public static ConfigEntry<float> OilSpreadRiseRate;

	public static ConfigEntry<float> OilSoundPitchRise;

	public static ConfigEntry<float> OilSoundVolumeRise;

	public static void Bind(ConfigFile cfg)
	{
		AffectFreezeframe = cfg.Bind<bool>("Rocket Launcher - Freezeframe", "AffectFreezeframe", true, "Freezeframe: frozen rockets fly backwards and the tick sound speeds up.");
		ReverseSpeedMultiplier = cfg.Bind<float>("Rocket Launcher - Freezeframe", "ReverseSpeedMultiplier", 1f, "Speed of backwards rockets, as a multiple of their normal forward speed.");
		TickSpeedMultiplier = cfg.Bind<float>("Rocket Launcher - Freezeframe", "TickSpeedMultiplier", 5f, "How much faster the clock-tick sound plays (done by raising its pitch).");
		AffectCannonball = cfg.Bind<bool>("Rocket Launcher - SRS Cannonball", "AffectCannonball", true, "SRS (variation 1): keep charging past full for a bigger, harder, heavier cannonball.");
		CannonGrowthPerSecond = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "GrowthPerSecond", 1f, "Extra fulls gained per second once the charge is full.");
		CannonAccelerationPerSecond = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "AccelerationPerSecond", 0.15f, "The growth rate itself rises by this much per second held.");
		CannonMaxOvercharge = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "MaxOvercharge", 0f, "Cap on extra fulls (0 = no cap).");
		CannonDamagePerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "DamagePerFull", 1f, "Cannonball damage goes up by this fraction of its base damage per extra full.");
		CannonSizePerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "SizePerFull", 0.15f, "Cannonball scale goes up by this fraction per extra full.");
		CannonMaxSizeScale = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "MaxSizeScale", 0f, "Largest cannonball scale multiplier (0 = no cap).");
		CannonSpeedPerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "LaunchSpeedPerFull", 0.25f, "Extra launch speed per extra full, as a multiple of the game's full-charge speed (150).");
		CannonGravityPerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "GravityBonusPerFull", 0.05f, "Extra gravity (fraction of normal) per extra full, so it falls slightly faster.");
		CannonMaxGravityBonus = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "MaxGravityBonus", 1E+09f, "Cap on the extra gravity fraction.");
		CannonRainbowCycleFulls = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "RainbowCycleFulls", 3f, "Extra fulls for one trip around the rainbow (the core eject uses 1, so this is slower).");
		CannonArmTurnsPerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "ArmTurnsPerFull", 1f, "How many extra full turns the timer arm makes per extra full.");
		CannonChargePitchPerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "ChargePitchPerFull", 0.15f, "Charge sound keeps rising by this much pitch per extra full (max 3).");
		CannonShotVolumePerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "ShotVolumePerFull", 0.1f, "Launch sound gets this much louder per extra full.");
		CannonShotPitchDropPerFull = cfg.Bind<float>("Rocket Launcher - SRS Cannonball", "ShotPitchDropPerFull", 0.05f, "Launch sound gets this much deeper per extra full (not below 0.3).");
		AffectFirestarter = cfg.Bind<bool>("Rocket Launcher - Firestarter", "AffectFirestarter", true, "Firestarter (variation 2): infinite oil, a rising arm, and spread + oil count that grow with it.");
		InfiniteOil = cfg.Bind<bool>("Rocket Launcher - Firestarter", "InfiniteOil", true, "Oil never runs out.");
		OilRampPerSecond = cfg.Bind<float>("Rocket Launcher - Firestarter", "RampPerSecond", 1f, "How fast the arm climbs while spraying. It never stops: 1 = one full turn of the arm per second.");
		OilDecayPerSecond = cfg.Bind<float>("Rocket Launcher - Firestarter", "DecayPerSecond", 0.5f, "How fast the arm falls back when you stop spraying.");
		OilMaxSpread = cfg.Bind<float>("Rocket Launcher - Firestarter", "MaxSpread", 60f, "The spread cone (degrees) approaches this as the arm climbs; it can't get wider than this.");
		OilSpreadRiseRate = cfg.Bind<float>("Rocket Launcher - Firestarter", "SpreadRiseRate", 0.25f, "How quickly the spread approaches MaxSpread as the arm climbs (higher = wider sooner).");
		OilMaxPerShot = cfg.Bind<int>("Rocket Launcher - Firestarter", "MaxOilPerShot", 6, "Cap on oil projectiles per spray tick (0 = no cap, so it keeps growing). The game sprays 50 ticks a second, so a high count means a LOT of projectiles.");
		OilExtraPerRamp = cfg.Bind<float>("Rocket Launcher - Firestarter", "ExtraOilPerRamp", 5f, "Extra oil projectiles per tick for each full turn of the arm.");
		OilSoundPitchRise = cfg.Bind<float>("Rocket Launcher - Firestarter", "SoundPitchRise", 0.4f, "Spray sound pitch rises by this much with the arm at the top.");
		OilSoundVolumeRise = cfg.Bind<float>("Rocket Launcher - Firestarter", "SoundVolumeRise", 0.4f, "Spray sound gets this much louder (fraction of its volume) with the arm at the top.");
	}
}
internal static class RocketAccess
{
	public static readonly FieldRef<Grenade, Rigidbody> Rb = AccessTools.FieldRefAccess<Grenade, Rigidbody>("rb");

	public static readonly FieldRef<Grenade, GameObject> FreezeEffect = AccessTools.FieldRefAccess<Grenade, GameObject>("freezeEffect");

	public static readonly ConditionalWeakTable<AudioSource, object> TickOrigPitch = new ConditionalWeakTable<AudioSource, object>();

	public static bool Applies()
	{
		return Plugin.Enabled.Value && RocketLauncherConfig.AffectFreezeframe.Value;
	}
}
[HarmonyPatch(typeof(Grenade), "FixedUpdate")]
internal static class Grenade_FixedUpdate_Patch
{
	private static void Postfix(Grenade __instance)
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		if (!RocketAccess.Applies() || !__instance.rocket || __instance.rocketSpeed == 0f || !__instance.frozen)
		{
			return;
		}
		Rigidbody val = RocketAccess.Rb.Invoke(__instance);
		if (!((Object)(object)val == (Object)null) && !val.isKinematic)
		{
			val.velocity = -((Component)__instance).transform.forward * __instance.rocketSpeed * RocketLauncherConfig.ReverseSpeedMultiplier.Value;
			val.angularVelocity = Vector3.zero;
			GameObject val2 = RocketAccess.FreezeEffect.Invoke(__instance);
			if ((Object)(object)val2 != (Object)null && val2.activeSelf)
			{
				val2.SetActive(false);
			}
		}
	}
}
[HarmonyPatch(typeof(RocketLauncher), "Update")]
internal static class RocketLauncher_Update_Patch
{
	private static void Postfix(RocketLauncher __instance)
	{
		if (!RocketAccess.Applies() || __instance.variation != 0)
		{
			return;
		}
		AudioSource currentTimerTickSound = __instance.currentTimerTickSound;
		if (!((Object)(object)currentTimerTickSound == (Object)null))
		{
			if (!RocketAccess.TickOrigPitch.TryGetValue(currentTimerTickSound, out var value))
			{
				value = currentTimerTickSound.pitch;
				RocketAccess.TickOrigPitch.Add(currentTimerTickSound, value);
			}
			currentTimerTickSound.pitch = (float)value * Mathf.Max(0.01f, RocketLauncherConfig.TickSpeedMultiplier.Value);
		}
	}
}
internal class CannonState
{
	public float Over;

	public float Held;

	public float Launching;
}
internal class CannonTag
{
	public float GravityBonus;
}
internal static class CannonAccess
{
	public static readonly ConditionalWeakTable<RocketLauncher, CannonState> States = new ConditionalWeakTable<RocketLauncher, CannonState>();

	public static readonly ConditionalWeakTable<Cannonball, CannonTag> Balls = new ConditionalWeakTable<Cannonball, CannonTag>();

	public static readonly FieldRef<RocketLauncher, float> CbCharge = AccessTools.FieldRefAccess<RocketLauncher, float>("cbCharge");

	public static readonly FieldRef<RocketLauncher, RectTransform> TimerArm = AccessTools.FieldRefAccess<RocketLauncher, RectTransform>("timerArm");

	public static readonly FieldRef<RocketLauncher, Image[]> Colorables = AccessTools.FieldRefAccess<RocketLauncher, Image[]>("variationColorables");

	public static readonly FieldRef<RocketLauncher, float[]> Transparencies = AccessTools.FieldRefAccess<RocketLauncher, float[]>("colorablesTransparencies");

	public static readonly FieldRef<RocketLauncher, AudioSource> ChargeSound = AccessTools.FieldRefAccess<RocketLauncher, AudioSource>("chargeSound");

	public static readonly FieldRef<RocketLauncher, AudioSource> Aud = AccessTools.FieldRefAccess<RocketLauncher, AudioSource>("aud");

	public static readonly FieldRef<Cannonball, Rigidbody> BallRb = AccessTools.FieldRefAccess<Cannonball, Rigidbody>("rb");

	public static bool Applies(RocketLauncher rl)
	{
		return Plugin.Enabled.Value && RocketLauncherConfig.AffectCannonball.Value && rl.variation == 1;
	}
}
[HarmonyPatch(typeof(RocketLauncher), "Update")]
internal static class RocketLauncher_CannonCharge_Patch
{
	private static void Postfix(RocketLauncher __instance)
	{
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: 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_0221: 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)
		if (!CannonAccess.Applies(__instance))
		{
			return;
		}
		CannonState orCreateValue = CannonAccess.States.GetOrCreateValue(__instance);
		float num = CannonAccess.CbCharge.Invoke(__instance);
		InputManager instance = MonoSingleton<InputManager>.Instance;
		bool flag = (Object)(object)instance != (Object)null && instance.InputSource.Fire2.IsPressed;
		if (num >= 1f && flag)
		{
			float num2 = RocketLauncherConfig.CannonGrowthPerSecond.Value + RocketLauncherConfig.CannonAccelerationPerSecond.Value * orCreateValue.Held;
			orCreateValue.Held += Time.deltaTime;
			orCreateValue.Over += num2 * Time.deltaTime;
			float value = RocketLauncherConfig.CannonMaxOvercharge.Value;
			if (value > 0f)
			{
				orCreateValue.Over = Mathf.Min(orCreateValue.Over, value);
			}
		}
		else if (num <= 0f)
		{
			orCreateValue.Over = 0f;
			orCreateValue.Held = 0f;
		}
		if (orCreateValue.Over <= 0f)
		{
			return;
		}
		RectTransform val = CannonAccess.TimerArm.Invoke(__instance);
		if ((Object)(object)val != (Object)null)
		{
			((Transform)val).localRotation = Quaternion.Euler(0f, 0f, (0f - orCreateValue.Over) * 360f * RocketLauncherConfig.CannonArmTurnsPerFull.Value);
		}
		Image[] array = CannonAccess.Colorables.Invoke(__instance);
		float[] array2 = CannonAccess.Transparencies.Invoke(__instance);
		if (array != null)
		{
			float num3 = Mathf.Max(0.01f, RocketLauncherConfig.CannonRainbowCycleFulls.Value);
			Color val2 = Color.HSVToRGB(Mathf.Repeat(orCreateValue.Over / num3, 1f), 1f, 1f);
			for (int i = 0; i < array.Length; i++)
			{
				if (!((Object)(object)array[i] == (Object)null))
				{
					float num4 = ((array2 != null && i < array2.Length) ? array2[i] : ((Graphic)array[i]).color.a);
					((Graphic)array[i]).color = new Color(val2.r, val2.g, val2.b, num4);
				}
			}
		}
		AudioSource val3 = CannonAccess.ChargeSound.Invoke(__instance);
		if ((Object)(object)val3 != (Object)null)
		{
			val3.pitch = Mathf.Min(3f, 1.5f + orCreateValue.Over * RocketLauncherConfig.CannonChargePitchPerFull.Value);
		}
	}
}
[HarmonyPatch(typeof(RocketLauncher), "ShootCannonball")]
internal static class RocketLauncher_ShootCannonball_Patch
{
	private static void Prefix(RocketLauncher __instance)
	{
		if (CannonAccess.Applies(__instance))
		{
			CannonState orCreateValue = CannonAccess.States.GetOrCreateValue(__instance);
			orCreateValue.Launching = orCreateValue.Over;
		}
	}

	private static void Postfix(RocketLauncher __instance)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		if (!CannonAccess.Applies(__instance))
		{
			return;
		}
		CannonState orCreateValue = CannonAccess.States.GetOrCreateValue(__instance);
		float launching = orCreateValue.Launching;
		orCreateValue.Launching = 0f;
		orCreateValue.Over = 0f;
		orCreateValue.Held = 0f;
		if (launching <= 0f)
		{
			return;
		}
		GameObject val = (((Object)(object)MonoSingleton<GunControl>.Instance != (Object)null) ? MonoSingleton<GunControl>.Instance.currentWeapon : null);
		Vector3 position = ((Component)MonoSingleton<CameraController>.Instance).transform.position;
		Cannonball val2 = null;
		float num = float.MaxValue;
		Cannonball[] array = Object.FindObjectsOfType<Cannonball>();
		foreach (Cannonball val3 in array)
		{
			if (!((Object)(object)val3 == (Object)null) && !CannonAccess.Balls.TryGetValue(val3, out var _) && (!((Object)(object)val != (Object)null) || !((Object)(object)val3.sourceWeapon != (Object)(object)val)))
			{
				Vector3 val4 = ((Component)val3).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					val2 = val3;
				}
			}
		}
		if ((Object)(object)val2 != (Object)null)
		{
			Rigidbody val5 = CannonAccess.BallRb.Invoke(val2);
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = ((Component)val2).GetComponent<Rigidbody>();
			}
			if ((Object)(object)val5 != (Object)null)
			{
				Rigidbody obj = val5;
				obj.velocity += ((Component)val2).transform.forward * 150f * launching * RocketLauncherConfig.CannonSpeedPerFull.Value;
			}
			Cannonball obj2 = val2;
			obj2.damage *= 1f + launching * RocketLauncherConfig.CannonDamagePerFull.Value;
			float num2 = 1f + launching * RocketLauncherConfig.CannonSizePerFull.Value;
			float value2 = RocketLauncherConfig.CannonMaxSizeScale.Value;
			if (value2 > 0f)
			{
				num2 = Mathf.Min(num2, value2);
			}
			Transform transform = ((Component)val2).transform;
			transform.localScale *= num2;
			CannonAccess.Balls.Add(val2, new CannonTag
			{
				GravityBonus = Mathf.Min(RocketLauncherConfig.CannonMaxGravityBonus.Value, launching * RocketLauncherConfig.CannonGravityPerFull.Value)
			});
		}
		AudioSource val6 = CannonAccess.Aud.Invoke(__instance);
		if ((Object)(object)val6 != (Object)null)
		{
			val6.volume = Mathf.Min(1f, val6.volume + launching * RocketLauncherConfig.CannonShotVolumePerFull.Value);
			val6.pitch = Mathf.Max(0.3f, val6.pitch - launching * RocketLauncherConfig.CannonShotPitchDropPerFull.Value);
		}
	}
}
[HarmonyPatch(typeof(Cannonball), "FixedUpdate")]
internal static class Cannonball_FixedUpdate_Patch
{
	private static void Postfix(Cannonball __instance)
	{
		//IL_005e: 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)
		if (CannonAccess.Balls.TryGetValue(__instance, out var value) && !(value.GravityBonus <= 0f) && !__instance.launched)
		{
			Rigidbody val = CannonAccess.BallRb.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && !val.isKinematic)
			{
				val.AddForce(PhysicsExtensions.GetGravityVector(val) * value.GravityBonus, (ForceMode)5);
			}
		}
	}
}
internal class OilState
{
	public float Ramp;
}
internal static class OilAccess
{
	public static readonly ConditionalWeakTable<RocketLauncher, OilState> States = new ConditionalWeakTable<RocketLauncher, OilState>();

	public static readonly ConditionalWeakTable<AudioSource, float[]> SoundBase = new ConditionalWeakTable<AudioSource, float[]>();

	public static readonly FieldRef<RocketLauncher, bool> FiringNapalm = AccessTools.FieldRefAccess<RocketLauncher, bool>("firingNapalm");

	public static readonly FieldRef<RocketLauncher, Rigidbody> NapalmProjectile = AccessTools.FieldRefAccess<RocketLauncher, Rigidbody>("napalmProjectile");

	public static readonly FieldRef<RocketLauncher, AudioSource[]> NapalmSounds = AccessTools.FieldRefAccess<RocketLauncher, AudioSource[]>("napalmMuzzleFlashSounds");

	public static readonly FieldRef<RocketLauncher, Image> TimerMeter = AccessTools.FieldRefAccess<RocketLauncher, Image>("timerMeter");

	public static readonly FieldRef<RocketLauncher, RectTransform> TimerArm = AccessTools.FieldRefAccess<RocketLauncher, RectTransform>("timerArm");

	public static bool Applies(RocketLauncher rl)
	{
		return Plugin.Enabled.Value && RocketLauncherConfig.AffectFirestarter.Value && rl.variation == 2;
	}
}
[HarmonyPatch(typeof(RocketLauncher), "Update")]
internal static class RocketLauncher_Firestarter_Patch
{
	private static void Prefix(RocketLauncher __instance)
	{
		if (OilAccess.Applies(__instance) && RocketLauncherConfig.InfiniteOil.Value)
		{
			WeaponCharges instance = MonoSingleton<WeaponCharges>.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.rocketNapalmFuel = 1f;
			}
		}
	}

	private static void Postfix(RocketLauncher __instance)
	{
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		if (!OilAccess.Applies(__instance))
		{
			return;
		}
		OilState orCreateValue = OilAccess.States.GetOrCreateValue(__instance);
		bool flag = OilAccess.FiringNapalm.Invoke(__instance);
		if (flag)
		{
			orCreateValue.Ramp += RocketLauncherConfig.OilRampPerSecond.Value * Time.deltaTime;
		}
		else
		{
			orCreateValue.Ramp = Mathf.MoveTowards(orCreateValue.Ramp, 0f, RocketLauncherConfig.OilDecayPerSecond.Value * Time.deltaTime);
		}
		Image val = OilAccess.TimerMeter.Invoke(__instance);
		if ((Object)(object)val != (Object)null)
		{
			val.fillAmount = ((orCreateValue.Ramp <= 0f) ? 0f : ((Mathf.Repeat(orCreateValue.Ramp, 1f) < 0.001f) ? 1f : Mathf.Repeat(orCreateValue.Ramp, 1f)));
		}
		RectTransform val2 = OilAccess.TimerArm.Invoke(__instance);
		if ((Object)(object)val2 != (Object)null)
		{
			((Transform)val2).localRotation = Quaternion.Euler(0f, 0f, 360f * (1f - orCreateValue.Ramp));
		}
		AudioSource[] array = OilAccess.NapalmSounds.Invoke(__instance);
		if (!(array != null && flag))
		{
			return;
		}
		AudioSource[] array2 = array;
		foreach (AudioSource val3 in array2)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				if (!OilAccess.SoundBase.TryGetValue(val3, out var value))
				{
					value = new float[2] { val3.pitch, val3.volume };
					OilAccess.SoundBase.Add(val3, value);
				}
				float num = 1f - Mathf.Exp(0f - orCreateValue.Ramp);
				val3.pitch = Mathf.Min(3f, value[0] + num * RocketLauncherConfig.OilSoundPitchRise.Value);
				val3.volume = Mathf.Min(1f, value[1] * (1f + num * RocketLauncherConfig.OilSoundVolumeRise.Value));
			}
		}
	}
}
[HarmonyPatch(typeof(RocketLauncher), "ShootNapalm")]
internal static class RocketLauncher_ShootNapalm_Patch
{
	private static void Postfix(RocketLauncher __instance)
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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_0115: 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_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		if (!OilAccess.Applies(__instance))
		{
			return;
		}
		if (RocketLauncherConfig.InfiniteOil.Value)
		{
			WeaponCharges instance = MonoSingleton<WeaponCharges>.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.rocketNapalmFuel = 1f;
			}
		}
		OilState orCreateValue = OilAccess.States.GetOrCreateValue(__instance);
		int num = Mathf.FloorToInt(orCreateValue.Ramp * RocketLauncherConfig.OilExtraPerRamp.Value);
		int value = RocketLauncherConfig.OilMaxPerShot.Value;
		if (value > 0)
		{
			num = Mathf.Min(num, value - 1);
		}
		if (num <= 0)
		{
			return;
		}
		Rigidbody val = OilAccess.NapalmProjectile.Invoke(__instance);
		CameraController instance2 = MonoSingleton<CameraController>.Instance;
		if ((Object)(object)val == (Object)null || (Object)(object)instance2 == (Object)null)
		{
			return;
		}
		Vector3 position = ((Component)instance2).transform.position;
		Vector3 forward = ((Component)instance2).transform.forward;
		Vector3 val2 = position + forward;
		if (Physics.Raycast(position, forward, 1f, LayerMask.op_Implicit(LayerMaskDefaults.Get((LMD)1))))
		{
			val2 = position;
		}
		CameraFrustumTargeter instance3 = MonoSingleton<CameraFrustumTargeter>.Instance;
		float num2 = RocketLauncherConfig.OilMaxSpread.Value * (1f - Mathf.Exp((0f - orCreateValue.Ramp) * RocketLauncherConfig.OilSpreadRiseRate.Value));
		for (int i = 0; i < num; i++)
		{
			Rigidbody val3 = Object.Instantiate<Rigidbody>(val, val2, ((Component)instance2).transform.rotation);
			if ((Object)(object)instance3 != (Object)null && Object.op_Implicit((Object)(object)instance3.CurrentTarget) && instance3.IsAutoAimed)
			{
				((Component)val3).transform.LookAt(instance3.CurrentTargetAimPosition);
			}
			Vector2 val4 = Random.insideUnitCircle * num2;
			((Component)val3).transform.Rotate(val4.x, val4.y, 0f);
			val3.velocity = ((Component)val3).transform.forward * 150f;
		}
	}
}
internal static class ShotgunConfig
{
	public const float FullCharge = 60f;

	public static ConfigEntry<bool> AffectCoreEject;

	public static ConfigEntry<float> GrowthPerSecond;

	public static ConfigEntry<float> AccelerationPerSecond;

	public static ConfigEntry<float> MaxOvercharge;

	public static ConfigEntry<float> DamagePerFull;

	public static ConfigEntry<float> SizePerFull;

	public static ConfigEntry<float> MaxSizeScale;

	public static ConfigEntry<bool> ExtendBar;

	public static ConfigEntry<float> BarLengthCap;

	public static ConfigEntry<float> RainbowCycleLength;

	public static ConfigEntry<bool> AffectSaw;

	public static ConfigEntry<float> OverchargePerExtraSaw;

	public static ConfigEntry<float> ExtraSawSpread;

	public static ConfigEntry<float> ChargePitchPerFull;

	public static ConfigEntry<float> ShotVolumePerFull;

	public static ConfigEntry<float> ShotPitchDropPerFull;

	public static void Bind(ConfigFile cfg)
	{
		AffectCoreEject = cfg.Bind<bool>("Shotgun - Core Eject", "AffectCoreEject", true, "Apply overcharge to the core eject shotgun (variation 0).");
		GrowthPerSecond = cfg.Bind<float>("Shotgun - Core Eject", "GrowthPerSecond", 30f, "Overcharge gained per second while holding alt fire past a full bar (60 = one extra full bar).");
		AccelerationPerSecond = cfg.Bind<float>("Shotgun - Core Eject", "AccelerationPerSecond", 20f, "Extra growth rate added for each second spent overcharging. 0 = linear.");
		MaxOvercharge = cfg.Bind<float>("Shotgun - Core Eject", "MaxOvercharge", 0f, "Upper limit for overcharge. 0 or less = no limit.");
		DamagePerFull = cfg.Bind<float>("Shotgun - Core Eject", "DamagePerFull", 1f, "Explosion damage multiplier gained per extra full bar (60 overcharge).");
		SizePerFull = cfg.Bind<float>("Shotgun - Core Eject", "SizePerFull", 0.5f, "Explosion size multiplier gained per extra full bar (60 overcharge).");
		MaxSizeScale = cfg.Bind<float>("Shotgun - Core Eject", "MaxExplosionSizeScale", 0f, "Largest allowed explosion size multiplier. 0 or less = no limit.");
		ExtendBar = cfg.Bind<bool>("Shotgun - Core Eject", "ExtendBar", true, "Stretch the charge bar as overcharge grows.");
		BarLengthCap = cfg.Bind<float>("Shotgun - Core Eject", "BarLengthCap", 0f, "Largest allowed bar length multiplier. 0 or less = no limit.");
		RainbowCycleLength = cfg.Bind<float>("Shotgun - Core Eject", "RainbowCycleLength", 60f, "Overcharge needed for the bar color to go around the rainbow once.");
		ChargePitchPerFull = cfg.Bind<float>("Shotgun - Core Eject", "ChargePitchPerFull", 0.25f, "How much the charge sound's pitch rises per extra full bar (60 overcharge). Unity caps pitch at 3.");
		ShotVolumePerFull = cfg.Bind<float>("Shotgun - Core Eject", "ShotVolumePerFull", 0.1f, "How much louder the release sound gets per extra full bar (volume tops out at 1).");
		ShotPitchDropPerFull = cfg.Bind<float>("Shotgun - Core Eject", "ShotPitchDropPerFull", 0.05f, "How much deeper the release sound gets per extra full bar (pitch won't go below 0.4).");
		AffectSaw = cfg.Bind<bool>("Shotgun - Chainsaw", "AffectSaw", true, "Apply overcharge to the chainsaw launcher (variation 2). It shares the growth settings in the 'Shotgun - Core Eject' section.");
		OverchargePerExtraSaw = cfg.Bind<float>("Shotgun - Chainsaw", "OverchargePerExtraSaw", 1500f, "One extra chainsaw is launched for every this much overcharge.");
		ExtraSawSpread = cfg.Bind<float>("Shotgun - Chainsaw", "ExtraSawSpread", 0.15f, "Extra chainsaws are knocked sideways by this fraction of the launch speed so they fan out instead of stacking.");
	}
}
internal class ShotgunState
{
	public float Over;

	public float HeldTime;

	public bool HasOrigScale;

	public Vector3 OrigScale;

	public Vector3 OrigPos;

	public bool BarScaled;
}
internal static class ShotgunAccess
{
	private static readonly ConditionalWeakTable<Shotgun, ShotgunState> States = new ConditionalWeakTable<Shotgun, ShotgunState>();

	public static readonly FieldRef<Shotgun, bool> Charging = AccessTools.FieldRefAccess<Shotgun, bool>("charging");

	public static readonly FieldRef<Shotgun, float> Force = AccessTools.FieldRefAccess<Shotgun, float>("grenadeForce");

	public static readonly FieldRef<Shotgun, Vector3> GrenadeVector = AccessTools.FieldRefAccess<Shotgun, Vector3>("grenadeVector");

	public static readonly FieldRef<Shotgun, Slider> Bar = AccessTools.FieldRefAccess<Shotgun, Slider>("chargeSlider");

	public static readonly FieldRef<Shotgun, AudioSource> ChargeSound = AccessTools.FieldRefAccess<Shotgun, AudioSource>("tempChargeSound");

	public static readonly FieldRef<Shotgun, AudioSource> GunAudio = AccessTools.FieldRefAccess<Shotgun, AudioSource>("gunAud");

	public static readonly FieldRef<Shotgun, List<Chainsaw>> Chainsaws = AccessTools.FieldRefAccess<Shotgun, List<Chainsaw>>("currentChainsaws");

	public static readonly FieldRef<Shotgun, GameObject> Cam = AccessTools.FieldRefAccess<Shotgun, GameObject>("cam");

	public static readonly FieldRef<Shotgun, CameraFrustumTargeter> Targeter = AccessTools.FieldRefAccess<Shotgun, CameraFrustumTargeter>("targeter");

	public static ShotgunState Get(Shotgun sg)
	{
		return States.GetOrCreateValue(sg);
	}

	public static bool Applies(Shotgun sg)
	{
		if (!Plugin.Enabled.Value)
		{
			return false;
		}
		if (sg.variation == 0)
		{
			return ShotgunConfig.AffectCoreEject.Value;
		}
		if (sg.variation == 2)
		{
			return ShotgunConfig.AffectSaw.Value;
		}
		return false;
	}

	public static Vector3 AimDirection(Shotgun sg)
	{
		//IL_0024: 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_0029: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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)
		GameObject val = Cam.Invoke(sg);
		Vector3 result = (((Object)(object)val != (Object)null) ? val.transform.forward : Vector3.forward);
		CameraFrustumTargeter val2 = Targeter.Invoke(sg);
		if ((Object)(object)val2 != (Object)null && Object.op_Implicit((Object)(object)val2.CurrentTarget) && val2.IsAutoAimed)
		{
			result = val2.GetAimDirectionFrom(MonoSingleton<CameraController>.Instance.GetDefaultPos());
		}
		return result;
	}

	public static void RestoreBar(Shotgun sg, ShotgunState s)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		if (s.BarScaled)
		{
			s.BarScaled = false;
			Slider val = Bar.Invoke(sg);
			if ((Object)(object)val != (Object)null && s.HasOrigScale)
			{
				((Component)val).transform.localScale = s.OrigScale;
				((Component)val).transform.localPosition = s.OrigPos;
			}
		}
	}

	public static bool IsCore(Rigidbody rb, Shotgun sg)
	{
		return (Object)(object)sg.grenade != (Object)null && ((Object)((Component)rb).gameObject).name == ((Object)sg.grenade).name + "(Clone)";
	}
}
[HarmonyPatch(typeof(Shotgun), "Update")]
internal static class Shotgun_Update_Patch
{
	private static void Postfix(Shotgun __instance)
	{
		if (!ShotgunAccess.Applies(__instance))
		{
			return;
		}
		ShotgunState shotgunState = ShotgunAccess.Get(__instance);
		bool flag = ShotgunAccess.Charging.Invoke(__instance);
		float num = ShotgunAccess.Force.Invoke(__instance);
		if (flag && num >= 60f)
		{
			shotgunState.HeldTime += Time.deltaTime;
			float num2 = ShotgunConfig.GrowthPerSecond.Value + ShotgunConfig.AccelerationPerSecond.Value * shotgunState.HeldTime;
			shotgunState.Over += num2 * Time.deltaTime;
			float value = ShotgunConfig.MaxOvercharge.Value;
			if (value > 0f && shotgunState.Over > value)
			{
				shotgunState.Over = value;
			}
		}
		else if ((!flag && num <= 0.001f) || (flag && num < 60f))
		{
			shotgunState.Over = 0f;
			shotgunState.HeldTime = 0f;
		}
		if (shotgunState.Over > 0f)
		{
			ApplyVisuals(__instance, shotgunState);
		}
		else
		{
			ShotgunAccess.RestoreBar(__instance, shotgunState);
		}
	}

	private static void ApplyVisuals(Shotgun sg, ShotgunState s)
	{
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Invalid comparison between Unknown and I4
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: 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_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Expected I4, but got Unknown
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: 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_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		float num = 60f + s.Over;
		AudioSource val = ShotgunAccess.ChargeSound.Invoke(sg);
		if ((Object)(object)val != (Object)null)
		{
			val.pitch = Mathf.Min(3f, 1f + s.Over / 60f * ShotgunConfig.ChargePitchPerFull.Value);
		}
		if (sg.variation == 0 && (Object)(object)sg.sliderFill != (Object)null)
		{
			float num2 = Mathf.Max(1f, ShotgunConfig.RainbowCycleLength.Value);
			((Graphic)sg.sliderFill).color = Color.HSVToRGB(Mathf.Repeat(s.Over / num2, 1f), 1f, 1f);
		}
		if (!ShotgunConfig.ExtendBar.Value)
		{
			return;
		}
		Slider val2 = ShotgunAccess.Bar.Invoke(sg);
		if (!((Object)(object)val2 != (Object)null))
		{
			return;
		}
		Transform transform = ((Component)val2).transform;
		if (!s.HasOrigScale)
		{
			s.OrigScale = transform.localScale;
			s.OrigPos = transform.localPosition;
			s.HasOrigScale = true;
		}
		float num3 = num / 60f;
		float value = ShotgunConfig.BarLengthCap.Value;
		if (value > 0f)
		{
			num3 = Mathf.Min(num3, value);
		}
		bool flag = (int)val2.direction == 0 || (int)val2.direction == 1;
		Vector3 origScale = s.OrigScale;
		if (flag)
		{
			origScale.x *= num3;
		}
		else
		{
			origScale.y *= num3;
		}
		transform.localScale = origScale;
		RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		if ((Object)(object)val3 != (Object)null)
		{
			Rect rect = val3.rect;
			Vector3 zero = Vector3.zero;
			Direction direction = val2.direction;
			Direction val4 = direction;
			switch ((int)val4)
			{
			case 0:
				zero.x = ((Rect)(ref rect)).xMin;
				break;
			case 1:
				zero.x = ((Rect)(ref rect)).xMax;
				break;
			case 2:
				zero.y = ((Rect)(ref rect)).yMin;
				break;
			case 3:
				zero.y = ((Rect)(ref rect)).yMax;
				break;
			}
			Vector3 val5 = Vector3.Scale(zero, origScale - s.OrigScale);
			transform.localPosition = s.OrigPos - transform.localRotation * val5;
		}
		s.BarScaled = true;
	}
}
[HarmonyPatch(typeof(Shotgun), "OnDisable")]
internal static class Shotgun_OnDisable_Patch
{
	private static void Postfix(Shotgun __instance)
	{
		if (__instance.variation != 1)
		{
			ShotgunState shotgunState = ShotgunAccess.Get(__instance);
			shotgunState.Over = 0f;
			shotgunState.HeldTime = 0f;
			ShotgunAccess.RestoreBar(__instance, shotgunState);
		}
	}
}
internal class SawShotState
{
	public float Over;

	public Transform[] Original;

	public int OriginalCount;

	public int ListCountBefore;
}
[HarmonyPatch(typeof(Shotgun), "ShootSaw", new Type[] { typeof(bool) })]
internal static class Shotgun_ShootSaw_Patch
{
	private static void Prefix(Shotgun __instance, bool noSaw, out SawShotState __state)
	{
		__state = null;
		if (noSaw || __instance.variation != 2 || !ShotgunAccess.Applies(__instance))
		{
			return;
		}
		float over = ShotgunAccess.Get(__instance).Over;
		if (over <= 0f)
		{
			return;
		}
		Transform[] shootPoints = __instance.shootPoints;
		List<Chainsaw> list = ShotgunAccess.Chainsaws.Invoke(__instance);
		__state = new SawShotState
		{
			Over = over,
			Original = shootPoints,
			OriginalCount = ((shootPoints != null) ? shootPoints.Length : 0),
			ListCountBefore = (list?.Count ?? 0)
		};
		int num = Mathf.FloorToInt(over / Mathf.Max(1f, ShotgunConfig.OverchargePerExtraSaw.Value));
		if (num > 0 && shootPoints != null && shootPoints.Length != 0)
		{
			Transform[] array = (Transform[])(object)new Transform[shootPoints.Length + num];
			shootPoints.CopyTo(array, 0);
			for (int i = shootPoints.Length; i < array.Length; i++)
			{
				array[i] = shootPoints[0];
			}
			__instance.shootPoints = array;
		}
	}

	private static void Postfix(Shotgun __instance, SawShotState __state)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		if (__state == null)
		{
			return;
		}
		ShotgunState shotgunState = ShotgunAccess.Get(__instance);
		shotgunState.Over = 0f;
		shotgunState.HeldTime = 0f;
		List<Chainsaw> list = ShotgunAccess.Chainsaws.Invoke(__instance);
		if (list == null)
		{
			return;
		}
		Vector3 val = ShotgunAccess.AimDirection(__instance);
		float over = __state.Over;
		float num = (60f + over + 10f) * 1.5f;
		for (int i = __state.ListCountBefore; i < list.Count; i++)
		{
			Chainsaw val2 = list[i];
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Rigidbody component = ((Component)val2).GetComponent<Rigidbody>();
			if ((Object)(object)component == (Object)null)
			{
				continue;
			}
			component.AddForce(val * over * 1.5f, (ForceMode)2);
			if (i - __state.ListCountBefore >= __state.OriginalCount)
			{
				Vector3 val3 = Vector3.ProjectOnPlane(Random.onUnitSphere, val);
				if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f)
				{
					component.AddForce(((Vector3)(ref val3)).normalized * num * ShotgunConfig.ExtraSawSpread.Value, (ForceMode)2);
				}
			}
		}
		AudioSource val4 = ShotgunAccess.GunAudio.Invoke(__instance);
		if ((Object)(object)val4 != (Object)null)
		{
			float num2 = over / 60f;
			val4.volume = Mathf.Min(1f, val4.volume + num2 * ShotgunConfig.ShotVolumePerFull.Value);
			val4.pitch = Mathf.Max(0.4f, val4.pitch - num2 * ShotgunConfig.ShotPitchDropPerFull.Value);
		}
	}

	private static Exception Finalizer(Shotgun __instance, SawShotState __state, Exception __exception)
	{
		if (__state != null && __state.Original != null)
		{
			__instance.shootPoints = __state.Original;
		}
		return __exception;
	}
}
internal class SinkShotState
{
	public float Over;

	public HashSet<int> Existing;
}
internal class CoreTag
{
	public float Total;
}
internal static class Cores
{
	public static readonly ConditionalWeakTable<Grenade, CoreTag> Tags = new ConditionalWeakTable<Grenade, CoreTag>();

	public static float DamageMult(float total)
	{
		float num = (total - 60f) / 60f;
		return 1f + num * ShotgunConfig.DamagePerFull.Value;
	}

	public static float SizeMult(float total)
	{
		float num = (total - 60f) / 60f;
		float num2 = 1f + num * ShotgunConfig.SizePerFull.Value;
		float value = ShotgunConfig.MaxSizeScale.Value;
		return (value > 0f) ? Mathf.Min(num2, value) : num2;
	}
}
[HarmonyPatch(typeof(Shotgun), "ShootSinks")]
internal static class Shotgun_ShootSinks_Patch
{
	private static void Prefix(Shotgun __instance, out SinkShotState __state)
	{
		__state = null;
		if (!ShotgunAccess.Applies(__instance))
		{
			return;
		}
		float over = ShotgunAccess.Get(__instance).Over;
		if (over <= 0f)
		{
			return;
		}
		__state = new SinkShotState
		{
			Over = over,
			Existing = new HashSet<int>()
		};
		Rigidbody[] array = Object.FindObjectsOfType<Rigidbody>();
		foreach (Rigidbody val in array)
		{
			if (ShotgunAccess.IsCore(val, __instance))
			{
				__state.Existing.Add(((Object)val).GetInstanceID());
			}
		}
	}

	private static void Postfix(Shotgun __instance, SinkShotState __state)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL o