Decompiled source of Overshoot v0.1.1
Overshoot.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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