Decompiled source of CyclerRework v1.0.0

BepInEx/plugins/CyclerRework.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AK.Wwise;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Math;
using Pigeon.Movement;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CyclerRework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CyclerRework")]
[assembly: AssemblyTitle("CyclerRework")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public sealed class CyclerHeatBehaviour : MonoBehaviour
{
	[Serializable]
	public struct Data
	{
		public float maxHeat;

		public float heatPerShot;

		public float dissipatePerSecond;

		public float dissipateDelay;

		public float overheatCooldown;

		public float warmThreshold;

		public float hotThreshold;

		public float hotDamageMult;

		public float hotElementMult;

		public float redlineFireIntervalMult;

		public float redlineSpreadMult;

		public float redlineDamageMult;

		public float redlineElementMult;

		public bool ventEnabled;

		public float ventMinHeat;

		public float ventSpend;

		public float ventRadius;

		public float ventDamage;

		public float ventRecovery;

		public float ventBypassDissipateDuration;

		public bool cycling;

		public float cyclingEffectAmount;

		public float scorchingDetonationRadius;

		public float scorchingDetonationDamage;

		public float healOnSustainedFire;

		public int healShotsInterval;

		public float overloadSpeedIncrease;

		public float overloadSpeedDuration;

		public float aimRecoilMultiplier;

		public float aimDissipateDelayMult;

		public bool infinityBurn;

		public float infinityBurnDamagePerSecond;

		public float infinityBurnEffectPerSecond;

		public float infinityBurnHardCap;

		public float infinityBurnOutgoingDamagePerOvercap;

		public float infinityBurnOutgoingElementPerOvercap;

		public float infinityBurnOvercapFireIntervalMult;

		public float overheatDamageReduction;

		public float adrenalineDissipateMultiplier;

		public float adrenalineDuration;

		public float adrenalineHeatRefund;

		public float shockHeatRefund;

		public float toxinDamagePerStack;

		public int toxinMaxStacks;

		public float superheatElementPerStack;

		public int superheatMaxStacks;

		public float superheatFalloffSeconds;

		public float liteEnergyBulletSpeedBonus;

		public float massAccelEfficiency;

		public float siphonMaxHeatPer60;

		public float siphonHeatRefundPer60;

		public float fullOutputDamagePerRarity;

		public float energyConvHeatPerStack;

		public float dischargeRadius;

		public float dischargeDamage;

		public float dischargeChargeTime;

		public float dischargeHeatCost;

		public float violentRadius;

		public float violentEffectAmount;

		public float arcDamage;

		public float arcRadius;

		public float arcInterval;

		public float rocketSlideHeatCost;

		public float rocketSlideDamage;

		public float rocketSlideRadius;

		public float rocketSlideInterval;

		public float dumpBeamDps;

		public float dumpSecondsPerFullHeat;

		public float dumpHeatDrainPerSecond;

		public float dumpConeStartAngle;

		public float dumpConeEndAngle;

		public float dumpConeRange;

		public float dumpFireHitch;

		public bool cyclePhasing;

		public float cyclePhasingStrength;

		public float closedLoopSustainSeconds;

		public float closedLoopVentHeat;

		public float closedLoopEfficiencyDuration;

		public float closedLoopHeatPerShotMult;

		public float crossflashBonusRefund;

		public float crossflashSplashRadius;

		public float crossflashSplashDamage;

		public float crossflashSplashFire;

		public float pyrolysisRadius;

		public float pyrolysisDamage;

		public int pyrolysisBankStacks;

		public float triValveFire;

		public float triValveShock;

		public float triValveAcid;

		public float acidSparkArcDamage;

		public float acidSparkArcRadius;

		public float acidSparkShockAmount;

		public float braidWindowSeconds;

		public float braidEfficiencyDuration;

		public float braidHeatPerShotMult;

		public int catalystMaxStacks;

		public float catalystStackDuration;

		public float catalystVentDamagePerStack;

		public float catalystVentRadiusPerStack;
	}

	public enum PhaseMode
	{
		Coolant,
		Pyre,
		Storm,
		Solvent,
		Split,
		Needle,
		BleedOff,
		Spike
	}

	[SerializeField]
	private Data data = CreateDefaultData();

	private Data prefabSnapshot = CreateDefaultData();

	private string description = "A reworked Cycler SMG. Infinite ammo — builds Heat while firing. Ride Soft Redline at max Heat (keep firing, wilder and meaner). Tap R to Pressure Vent.";

	private float lastShotTime = -999f;

	private int firedShotCount;

	private float totalShotsFiredSinceStartedFiring;

	private bool wasFiring;

	private float lastOverloadTime = -999f;

	private float lastKillTime = -999f;

	private bool isDamagedTargetIgnited;

	private bool isUsingDecayUpgrade;

	private bool hooksBound;

	private bool playerDamageHookBound;

	private bool playerDamageDealtHookBound;

	private Gun boundGun;

	private HeatVentSystem ventSystem;

	private int toxinStacks;

	private int superheatStacks;

	private float lastSuperheatTime = -999f;

	private float siphonDamageAccumulator;

	private float baseFireIntervalCaptured;

	private float baseBulletSpeedCaptured;

	private float massAccelAppliedInterval = -1f;

	private int energyConvCounter;

	private const int EnergyConvPerStack = 4;

	private int energyConvStoredStacks;

	private float lastArcTime = -999f;

	private float arcIdleLogTime = -999f;

	private float lastRocketSlideTime = -999f;

	private float redlineSustainTimer;

	private float closedLoopEfficiencyUntil = -999f;

	private float lastFireApplyTime = -999f;

	private float lastShockApplyTime = -999f;

	private float lastAcidApplyTime = -999f;

	private float braidEfficiencyUntil = -999f;

	private int catalystStacks;

	private float catalystExpireTime = -999f;

	private int lockedPhaseMode = -1;

	private bool phaseLockedThisSpray;

	private int nextPhaseMode;

	private float phaseCoolantRefundThisSec;

	private float phaseCoolantSecBucket = -1f;

	private float phaseBleedOffTimer;

	private int phaseBaseBulletsPerShot = -1;

	private readonly List<IBullet> trackedArcBullets = new List<IBullet>(8);

	public static readonly string[] PhaseModeNames = new string[8] { "Coolant", "Pyre", "Storm", "Solvent", "Split", "Needle", "Bleed-Off", "Spike" };

	public float CurrentHeat { get; private set; }

	public bool IsOverheated => false;

	public float OverheatTimer => 0f;

	private HeatVentSystem Vent => ventSystem ?? (ventSystem = new HeatVentSystem(this));

	public int EnergyConvStoredStacks => energyConvStoredStacks;

	public int LockedPhaseMode => lockedPhaseMode;

	public string LockedPhaseModeName
	{
		get
		{
			if (lockedPhaseMode < 0 || lockedPhaseMode >= PhaseModeNames.Length)
			{
				return "—";
			}
			return PhaseModeNames[lockedPhaseMode];
		}
	}

	public int ToxinStacks => toxinStacks;

	public ref Data WeaponData => ref data;

	public string Description => description;

	public float HeatNormalized
	{
		get
		{
			float num = Mathf.Max(0.01f, data.maxHeat);
			return CurrentHeat / num;
		}
	}

	public bool IsOvercapped
	{
		get
		{
			if (data.infinityBurn)
			{
				return CurrentHeat > data.maxHeat + 0.0001f;
			}
			return false;
		}
	}

	public bool IsRedline
	{
		get
		{
			if (!IsOvercapped)
			{
				return CurrentHeat >= data.maxHeat - 0.0001f;
			}
			return false;
		}
	}

	public HeatZone CurrentZone
	{
		get
		{
			if (IsOvercapped)
			{
				return HeatZone.Overcap;
			}
			float heatNormalized = HeatNormalized;
			if (heatNormalized >= 0.9999f)
			{
				return HeatZone.Redline;
			}
			float num = ((data.hotThreshold > 0f) ? data.hotThreshold : 0.7f);
			float num2 = ((data.warmThreshold > 0f) ? data.warmThreshold : 0.4f);
			if (heatNormalized >= num)
			{
				return HeatZone.Hot;
			}
			if (heatNormalized >= num2)
			{
				return HeatZone.Warm;
			}
			return HeatZone.Cold;
		}
	}

	private float EffectiveDissipatePerSecond
	{
		get
		{
			float num = data.dissipatePerSecond;
			if (data.adrenalineDissipateMultiplier > 1f && Time.time - lastKillTime < data.adrenalineDuration)
			{
				num *= data.adrenalineDissipateMultiplier;
			}
			return num;
		}
	}

	public void SetData(Data newData)
	{
		data = newData;
	}

	public static Data CreateDefaultData()
	{
		return new Data
		{
			maxHeat = 100f,
			heatPerShot = 2.4f,
			dissipatePerSecond = 65f,
			dissipateDelay = 0.15f,
			overheatCooldown = 0f,
			warmThreshold = 0.4f,
			hotThreshold = 0.7f,
			hotDamageMult = 1.08f,
			hotElementMult = 1.1f,
			redlineFireIntervalMult = 1.18f,
			redlineSpreadMult = 1.25f,
			redlineDamageMult = 1.12f,
			redlineElementMult = 1.2f,
			ventEnabled = true,
			ventMinHeat = 15f,
			ventSpend = 35f,
			ventRadius = 3.5f,
			ventDamage = 20f,
			ventRecovery = 0.45f,
			ventBypassDissipateDuration = 0.35f,
			cycling = false,
			cyclingEffectAmount = 0f,
			scorchingDetonationRadius = 0f,
			scorchingDetonationDamage = 0f,
			healOnSustainedFire = 0f,
			healShotsInterval = 15,
			overloadSpeedIncrease = 0f,
			overloadSpeedDuration = 0f,
			aimRecoilMultiplier = 0f,
			aimDissipateDelayMult = 1f,
			infinityBurn = false,
			infinityBurnDamagePerSecond = 0f,
			infinityBurnEffectPerSecond = 0f,
			infinityBurnHardCap = 0f,
			infinityBurnOutgoingDamagePerOvercap = 0.35f,
			infinityBurnOutgoingElementPerOvercap = 0.25f,
			infinityBurnOvercapFireIntervalMult = 0.92f,
			overheatDamageReduction = 0f,
			adrenalineDissipateMultiplier = 0f,
			adrenalineDuration = 1.25f,
			adrenalineHeatRefund = 0f,
			shockHeatRefund = 0f,
			toxinDamagePerStack = 0f,
			toxinMaxStacks = 0,
			superheatElementPerStack = 0f,
			superheatMaxStacks = 0,
			superheatFalloffSeconds = 3f,
			liteEnergyBulletSpeedBonus = 0f,
			massAccelEfficiency = 0f,
			siphonMaxHeatPer60 = 0f,
			siphonHeatRefundPer60 = 0f,
			fullOutputDamagePerRarity = 0f,
			energyConvHeatPerStack = 0f,
			dischargeRadius = 0f,
			dischargeDamage = 0f,
			dischargeChargeTime = 0.55f,
			dischargeHeatCost = 40f,
			violentRadius = 0f,
			violentEffectAmount = 0f,
			arcDamage = 0f,
			arcRadius = 0f,
			arcInterval = 0.4f,
			rocketSlideHeatCost = 0f,
			rocketSlideDamage = 0f,
			rocketSlideRadius = 0f,
			rocketSlideInterval = 0.45f,
			dumpBeamDps = 0f,
			dumpSecondsPerFullHeat = 0f,
			dumpHeatDrainPerSecond = 0f,
			dumpConeStartAngle = 38f,
			dumpConeEndAngle = 7f,
			dumpConeRange = 28f,
			dumpFireHitch = 0.15f,
			cyclePhasing = false,
			cyclePhasingStrength = 0f,
			closedLoopSustainSeconds = 0f,
			closedLoopVentHeat = 0f,
			closedLoopEfficiencyDuration = 0f,
			closedLoopHeatPerShotMult = 0f,
			crossflashBonusRefund = 0f,
			crossflashSplashRadius = 0f,
			crossflashSplashDamage = 0f,
			crossflashSplashFire = 0f,
			pyrolysisRadius = 0f,
			pyrolysisDamage = 0f,
			pyrolysisBankStacks = 0,
			triValveFire = 0f,
			triValveShock = 0f,
			triValveAcid = 0f,
			acidSparkArcDamage = 0f,
			acidSparkArcRadius = 0f,
			acidSparkShockAmount = 0f,
			braidWindowSeconds = 0f,
			braidEfficiencyDuration = 0f,
			braidHeatPerShotMult = 0f,
			catalystMaxStacks = 0,
			catalystStackDuration = 0f,
			catalystVentDamagePerStack = 0f,
			catalystVentRadiusPerStack = 0f
		};
	}

	public static Data CreateDataFromConfig()
	{
		Data result = CreateDefaultData();
		if (SparrohPlugin.MaxHeat != null)
		{
			result.maxHeat = Mathf.Max(1f, SparrohPlugin.MaxHeat.Value);
		}
		if (SparrohPlugin.HeatPerShot != null)
		{
			result.heatPerShot = Mathf.Max(0f, SparrohPlugin.HeatPerShot.Value);
		}
		if (SparrohPlugin.DissipatePerSecond != null)
		{
			result.dissipatePerSecond = Mathf.Max(0f, SparrohPlugin.DissipatePerSecond.Value);
		}
		if (SparrohPlugin.DissipateDelay != null)
		{
			result.dissipateDelay = Mathf.Max(0f, SparrohPlugin.DissipateDelay.Value);
		}
		if (SparrohPlugin.HotThreshold != null)
		{
			result.hotThreshold = Mathf.Clamp01(SparrohPlugin.HotThreshold.Value);
		}
		if (SparrohPlugin.WarmThreshold != null)
		{
			result.warmThreshold = Mathf.Clamp01(SparrohPlugin.WarmThreshold.Value);
		}
		if (SparrohPlugin.HotDamageMult != null)
		{
			result.hotDamageMult = Mathf.Max(0.1f, SparrohPlugin.HotDamageMult.Value);
		}
		if (SparrohPlugin.RedlineFireIntervalMult != null)
		{
			result.redlineFireIntervalMult = Mathf.Max(1f, SparrohPlugin.RedlineFireIntervalMult.Value);
		}
		if (SparrohPlugin.RedlineSpreadMult != null)
		{
			result.redlineSpreadMult = Mathf.Max(1f, SparrohPlugin.RedlineSpreadMult.Value);
		}
		if (SparrohPlugin.RedlineDamageMult != null)
		{
			result.redlineDamageMult = Mathf.Max(0.1f, SparrohPlugin.RedlineDamageMult.Value);
		}
		if (SparrohPlugin.VentSpend != null)
		{
			result.ventSpend = Mathf.Max(1f, SparrohPlugin.VentSpend.Value);
		}
		if (SparrohPlugin.VentMinHeat != null)
		{
			result.ventMinHeat = Mathf.Max(0f, SparrohPlugin.VentMinHeat.Value);
		}
		if (SparrohPlugin.VentRecovery != null)
		{
			result.ventRecovery = Mathf.Max(0f, SparrohPlugin.VentRecovery.Value);
		}
		return result;
	}

	public void InitializeAsPrefab(string desc)
	{
		description = desc ?? "A reworked Cycler SMG. Infinite ammo — builds Heat while firing. Ride Soft Redline at max Heat (keep firing, wilder and meaner). Tap R to Pressure Vent.";
		data = CreateDataFromConfig();
		prefabSnapshot = data;
		ResetHeatState();
		ResetUpgradeRuntimeState();
	}

	public void RestoreFromPrefab()
	{
		data = prefabSnapshot;
	}

	public void CapturePrefabSnapshot()
	{
		prefabSnapshot = data;
	}

	public Data GetPrefabSnapshot()
	{
		return prefabSnapshot;
	}

	public void CopySnapshotFrom(CyclerHeatBehaviour template)
	{
		if (!((Object)(object)template == (Object)null))
		{
			prefabSnapshot = template.prefabSnapshot;
			data = prefabSnapshot;
			description = template.description;
			ResetHeatState();
			ResetUpgradeRuntimeState();
		}
	}

	public void ResetHeatState()
	{
		CurrentHeat = 0f;
		lastShotTime = -999f;
	}

	public void ResetUpgradeRuntimeState()
	{
		firedShotCount = 0;
		totalShotsFiredSinceStartedFiring = 0f;
		wasFiring = false;
		lastOverloadTime = -999f;
		lastKillTime = -999f;
		isDamagedTargetIgnited = false;
		isUsingDecayUpgrade = false;
		toxinStacks = 0;
		superheatStacks = 0;
		lastSuperheatTime = -999f;
		siphonDamageAccumulator = 0f;
		massAccelAppliedInterval = -1f;
		energyConvCounter = 0;
		energyConvStoredStacks = 0;
		lastArcTime = -999f;
		lastRocketSlideTime = -999f;
		redlineSustainTimer = 0f;
		closedLoopEfficiencyUntil = -999f;
		lastFireApplyTime = -999f;
		lastShockApplyTime = -999f;
		lastAcidApplyTime = -999f;
		braidEfficiencyUntil = -999f;
		catalystStacks = 0;
		catalystExpireTime = -999f;
		lockedPhaseMode = -1;
		phaseLockedThisSpray = false;
		nextPhaseMode = 0;
		phaseCoolantRefundThisSec = 0f;
		phaseCoolantSecBucket = -1f;
		phaseBleedOffTimer = 0f;
		phaseBaseBulletsPerShot = -1;
		trackedArcBullets.Clear();
		Vent.Reset();
	}

	public void AddHeat(float amount)
	{
		if (!(amount <= 0f))
		{
			float num = ((!data.infinityBurn) ? data.maxHeat : ((data.infinityBurnHardCap > 0f) ? data.infinityBurnHardCap : (data.maxHeat * 2f)));
			CurrentHeat = Mathf.Min(num, CurrentHeat + amount);
		}
	}

	public void RefundHeat(float amount)
	{
		if (!(amount <= 0f))
		{
			CurrentHeat = Mathf.Max(0f, CurrentHeat - amount);
			if (toxinStacks > 0 && CurrentHeat <= 0.0001f)
			{
				toxinStacks = 0;
			}
		}
	}

	public float SpendHeatUpTo(float maxSpend)
	{
		if (maxSpend <= 0f || CurrentHeat <= 0f)
		{
			return 0f;
		}
		float num = Mathf.Min(CurrentHeat, maxSpend);
		CurrentHeat = Mathf.Max(0f, CurrentHeat - num);
		if (toxinStacks > 0 && CurrentHeat <= 0.0001f)
		{
			toxinStacks = 0;
		}
		return num;
	}

	public bool SpendHeat(float amount)
	{
		if (amount <= 0f || CurrentHeat < amount)
		{
			return false;
		}
		SpendHeatUpTo(amount);
		return true;
	}

	public void CaptureBaseFireInterval(float interval)
	{
		if (interval > 0f && (baseFireIntervalCaptured <= 0f || interval < baseFireIntervalCaptured))
		{
			baseFireIntervalCaptured = interval;
		}
	}

	public void CaptureBaseBulletSpeed(float speed)
	{
		if (speed > 0f && baseBulletSpeedCaptured <= 0f)
		{
			baseBulletSpeedCaptured = speed;
		}
	}

	public static void ApplyInfiniteAmmo(Gun gun)
	{
		if (!((Object)(object)gun == (Object)null))
		{
			ref GunData gunData = ref gun.GunData;
			gunData.useAmmoOnFire = 0;
			gunData.magazineSize = 7777777;
			gunData.hasLimitedAmmo = false;
			gunData.autoReloadWhenEmpty = false;
			gun.RemainingAmmo = 7777777f;
			gun.StoredAmmo = 0f;
		}
	}

	public void OnUpgradesApplied(Gun gun)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_005d: 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)
		boundGun = gun;
		isUsingDecayUpgrade = (Object)(object)gun != (Object)null && (int)gun.GunData.damageEffect == 4;
		if ((Object)(object)gun != (Object)null)
		{
			CaptureBaseFireInterval(gun.GunData.fireInterval);
		}
		if (data.cycling && (Object)(object)gun != (Object)null)
		{
			if ((int)gun.GunData.damageEffect == 0)
			{
				gun.GunData.damageEffect = (EffectType)1;
			}
			if (gun.GunData.damageEffectAmount <= 0f && data.cyclingEffectAmount > 0f)
			{
				gun.GunData.damageEffectAmount = data.cyclingEffectAmount;
			}
			TrySetElementSwitch(gun);
		}
		BindHooks(gun, bind: true);
	}

	public void OnUpgradesCleared(Gun gun)
	{
		BindHooks(gun, bind: false);
		ResetUpgradeRuntimeState();
	}

	private void BindHooks(Gun gun, bool bind)
	{
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Expected O, but got Unknown
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Expected O, but got Unknown
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Expected O, but got Unknown
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Expected O, but got Unknown
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Expected O, but got Unknown
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Expected O, but got Unknown
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Expected O, but got Unknown
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Expected O, but got Unknown
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Expected O, but got Unknown
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: 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_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Expected O, but got Unknown
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Expected O, but got Unknown
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Expected O, but got Unknown
		if ((Object)(object)gun == (Object)null || (bind && hooksBound) || (!bind && !hooksBound))
		{
			return;
		}
		try
		{
			if (bind)
			{
				gun.OnKillTarget = (KillCallback)Delegate.Combine((Delegate?)(object)gun.OnKillTarget, (Delegate?)new KillCallback(HandleOnKill));
				gun.OnBeforeDamage = (MutableDamageCallback)Delegate.Combine((Delegate?)(object)gun.OnBeforeDamage, (Delegate?)new MutableDamageCallback(HandleOnBeforeDamage));
				gun.OnSaturateTarget = (EffectCallback)Delegate.Combine((Delegate?)(object)gun.OnSaturateTarget, (Delegate?)new EffectCallback(HandleOnSaturate));
				gun.OnDamageTarget = (DamageCallback)Delegate.Combine((Delegate?)(object)gun.OnDamageTarget, (Delegate?)new DamageCallback(HandleGunDamageTarget));
				if ((Object)(object)gun.Player != (Object)null)
				{
					Player player = gun.Player;
					player.OnSetMovementSpeed += (RefAction<float>)HandleSetMoveSpeed;
					if (data.overheatDamageReduction > 0f && data.overheatDamageReduction < 1f)
					{
						gun.Player.OnBeforeTakeDamage += OnBeforePlayerTakeDamage;
						playerDamageHookBound = true;
					}
					if (data.siphonMaxHeatPer60 > 0f || data.siphonHeatRefundPer60 > 0f)
					{
						gun.Player.OnDamageTarget = (DamageCallback)Delegate.Combine((Delegate?)(object)gun.Player.OnDamageTarget, (Delegate?)new DamageCallback(HandlePlayerDamageDealt));
						playerDamageDealtHookBound = true;
					}
				}
				hooksBound = true;
				return;
			}
			gun.OnKillTarget = (KillCallback)Delegate.Remove((Delegate?)(object)gun.OnKillTarget, (Delegate?)new KillCallback(HandleOnKill));
			gun.OnBeforeDamage = (MutableDamageCallback)Delegate.Remove((Delegate?)(object)gun.OnBeforeDamage, (Delegate?)new MutableDamageCallback(HandleOnBeforeDamage));
			gun.OnSaturateTarget = (EffectCallback)Delegate.Remove((Delegate?)(object)gun.OnSaturateTarget, (Delegate?)new EffectCallback(HandleOnSaturate));
			gun.OnDamageTarget = (DamageCallback)Delegate.Remove((Delegate?)(object)gun.OnDamageTarget, (Delegate?)new DamageCallback(HandleGunDamageTarget));
			if ((Object)(object)gun.Player != (Object)null)
			{
				Player player2 = gun.Player;
				player2.OnSetMovementSpeed -= (RefAction<float>)HandleSetMoveSpeed;
				if (playerDamageHookBound)
				{
					gun.Player.OnBeforeTakeDamage -= OnBeforePlayerTakeDamage;
					playerDamageHookBound = false;
				}
				if (playerDamageDealtHookBound)
				{
					gun.Player.OnDamageTarget = (DamageCallback)Delegate.Remove((Delegate?)(object)gun.Player.OnDamageTarget, (Delegate?)new DamageCallback(HandlePlayerDamageDealt));
					playerDamageDealtHookBound = false;
				}
			}
			hooksBound = false;
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"[CyclerRework] BindHooks({bind}) failed: {ex.Message}");
			}
		}
	}

	public void AddHeatFromShot(int numBullets, Gun gun)
	{
		if (numBullets <= 0)
		{
			return;
		}
		lastShotTime = Time.time;
		float num = data.heatPerShot;
		if (data.closedLoopHeatPerShotMult > 0f && data.closedLoopHeatPerShotMult < 1f && Time.time < closedLoopEfficiencyUntil)
		{
			num *= data.closedLoopHeatPerShotMult;
		}
		if (data.braidHeatPerShotMult > 0f && data.braidHeatPerShotMult < 1f && Time.time < braidEfficiencyUntil)
		{
			num *= data.braidHeatPerShotMult;
		}
		if (data.cyclePhasing && lockedPhaseMode == 4)
		{
			num *= 1.25f * Mathf.Max(0.1f, data.cyclePhasingStrength);
		}
		float num2 = num * (float)numBullets;
		if (!(num2 <= 0f))
		{
			float num3 = data.maxHeat;
			if (data.infinityBurn)
			{
				num3 = ((data.infinityBurnHardCap > 0f) ? data.infinityBurnHardCap : (data.maxHeat * 2f));
			}
			else if (data.cyclePhasing && lockedPhaseMode == 7)
			{
				num3 = data.maxHeat * 1.2f;
			}
			CurrentHeat = Mathf.Min(num3, CurrentHeat + num2);
			SyncFireLock(gun);
		}
	}

	public void OnShotFired(int numBullets, Gun gun)
	{
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gun == (Object)null || !((NetworkBehaviour)gun).IsOwner)
		{
			return;
		}
		if (!gun.IsFiring)
		{
			totalShotsFiredSinceStartedFiring = 0f;
		}
		if (data.cyclePhasing && !phaseLockedThisSpray)
		{
			LockPhaseModeForSpray(gun);
		}
		if (data.healOnSustainedFire > 0f)
		{
			totalShotsFiredSinceStartedFiring += 1f;
			int num = Mathf.Max(1, data.healShotsInterval);
			if ((int)totalShotsFiredSinceStartedFiring % num == 0)
			{
				float num2 = data.healOnSustainedFire;
				if (HeatNormalized >= ((data.hotThreshold > 0f) ? data.hotThreshold : 0.7f))
				{
					num2 *= 1.5f;
				}
				try
				{
					Player player = gun.Player;
					if (player != null)
					{
						player.Heal(num2, (IDamageSource)(object)gun);
					}
					gun.TriggerEffectHeal((EffectType)5);
				}
				catch
				{
				}
			}
		}
		if (!data.cycling)
		{
			return;
		}
		firedShotCount++;
		if (firedShotCount < 3)
		{
			return;
		}
		firedShotCount = 0;
		int num3 = (sbyte)(gun.GunData.damageEffect + 1);
		if (num3 > 3)
		{
			num3 = 1;
		}
		if (num3 < 1)
		{
			num3 = 1;
		}
		gun.GunData.damageEffect = (EffectType)(sbyte)num3;
		TrySetElementSwitch(gun);
		try
		{
			gun.RefreshHUD();
		}
		catch
		{
		}
	}

	public void Tick(float dt, Gun gun)
	{
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gun == (Object)null || dt <= 0f)
		{
			return;
		}
		if (wasFiring && !gun.IsFiring)
		{
			totalShotsFiredSinceStartedFiring = 0f;
			EndPhaseSpray(gun);
		}
		if (data.cyclePhasing && gun.IsFiring && !phaseLockedThisSpray && ((NetworkBehaviour)gun).IsOwner)
		{
			LockPhaseModeForSpray(gun);
		}
		wasFiring = gun.IsFiring;
		Vent.Tick(dt, gun);
		TickClosedLoop(dt, gun);
		TickRocketSlide(dt, gun);
		TickProjectileArcs(dt, gun);
		TickCyclePhasing(dt, gun);
		float effectiveDissipatePerSecond = EffectiveDissipatePerSecond;
		if ((!gun.IsFiring || Vent.HasDissipateDelayBypass) && effectiveDissipatePerSecond > 0f && CurrentHeat > 0f)
		{
			float num = data.dissipateDelay;
			if (data.aimDissipateDelayMult > 0f && data.aimDissipateDelayMult < 1f && gun.IsAiming)
			{
				num *= data.aimDissipateDelayMult;
			}
			if (Vent.HasDissipateDelayBypass || Time.time - lastShotTime >= num)
			{
				CurrentHeat = Mathf.Max(0f, CurrentHeat - effectiveDissipatePerSecond * dt);
			}
		}
		if (toxinStacks > 0 && CurrentHeat <= 0.0001f)
		{
			toxinStacks = 0;
		}
		if (superheatStacks > 0 && data.superheatFalloffSeconds > 0f && Time.time - lastSuperheatTime >= data.superheatFalloffSeconds)
		{
			superheatStacks = 0;
		}
		ApplyDynamicFireStats(gun);
		if (data.infinityBurn && IsOvercapped && ((NetworkBehaviour)gun).IsOwner && (Object)(object)gun.Player != (Object)null)
		{
			float infinityBurnDamagePerSecond = data.infinityBurnDamagePerSecond;
			if (infinityBurnDamagePerSecond > 0f)
			{
				try
				{
					float num2 = infinityBurnDamagePerSecond * dt;
					float num3 = data.infinityBurnEffectPerSecond * dt;
					IDamageSource.DamageTarget((IDamageSource)(object)gun, (ITarget)(object)gun.Player, new DamageData(num2, gun.GunData.damageEffect, num3, (DamageFlags)1), gun.Player.InterpolatedPosition, (Collider)null);
				}
				catch (Exception ex)
				{
					ManualLogSource logger = SparrohPlugin.Logger;
					if (logger != null)
					{
						logger.LogDebug((object)("[CyclerRework] Infinity Burn self-DoT failed: " + ex.Message));
					}
				}
			}
		}
		SyncFireLock(gun);
		TryApplyOverheatVisual(gun);
	}

	public void ModifyRecoilMultiplier(Gun gun, ref float multiplier)
	{
		if (data.aimRecoilMultiplier > 0f && (Object)(object)gun != (Object)null && gun.IsAiming)
		{
			multiplier *= data.aimRecoilMultiplier;
		}
	}

	public void ApplyDynamicFireStats(Gun gun)
	{
		if ((Object)(object)gun == (Object)null)
		{
			return;
		}
		if (baseFireIntervalCaptured <= 0f)
		{
			CaptureBaseFireInterval(gun.GunData.fireInterval);
		}
		HeatStatLayers.ApplyFireIntervalLayers(gun, in data, CurrentHeat, HeatNormalized, baseFireIntervalCaptured, out massAccelAppliedInterval);
		if (baseBulletSpeedCaptured <= 0f)
		{
			try
			{
				IUpgradable prefab = gun.Prefab;
				IWeapon val = (IWeapon)(object)((prefab is IWeapon) ? prefab : null);
				if (val != null && val.GunData.bulletSpeed > 0f)
				{
					baseBulletSpeedCaptured = val.GunData.bulletSpeed;
				}
				else if (gun.GunData.bulletSpeed > 0f)
				{
					baseBulletSpeedCaptured = gun.GunData.bulletSpeed;
				}
			}
			catch
			{
			}
		}
		HeatStatLayers.ApplyLiteEnergyBulletSpeed(gun, in data, baseFireIntervalCaptured, baseBulletSpeedCaptured);
	}

	public void SyncFireLock(Gun gun)
	{
		if ((Object)(object)gun == (Object)null || !((NetworkBehaviour)gun).IsOwner)
		{
			return;
		}
		if (Vent.IsFireHitched)
		{
			if (gun.RemainingAmmo > 0f)
			{
				gun.RemainingAmmo = 0f;
			}
		}
		else if (gun.RemainingAmmo < 1f || gun.GunData.useAmmoOnFire != 0 || gun.GunData.magazineSize != 7777777)
		{
			ApplyInfiniteAmmo(gun);
		}
	}

	private void TryApplyOverheatVisual(Gun gun)
	{
		try
		{
			Renderer[] skinRenderers = gun.SkinRenderers;
			if (skinRenderers != null && skinRenderers.Length != 0 && !((Object)(object)skinRenderers[0] == (Object)null))
			{
				Material sharedMaterial = skinRenderers[0].sharedMaterial;
				if (!((Object)(object)sharedMaterial == (Object)null))
				{
					float num = ((IsOvercapped || IsRedline) ? 1f : Mathf.Clamp01(HeatNormalized - 0.15f));
					sharedMaterial.SetFloat(Global._Overheat, num);
				}
			}
		}
		catch
		{
		}
	}

	private void TrySetElementSwitch(Gun gun)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)gun == (Object)null) && !((Object)(object)gun.playerLook == (Object)null))
			{
				AkUnitySoundEngine.SetSwitch(Global.Element_Switch, Global.GetEffect(gun.GunData.damageEffect).ElementSwitchID, ((Component)gun.playerLook).gameObject);
			}
		}
		catch
		{
		}
	}

	private void HandleOnBeforeDamage(ref DamageCallbackData callbackData)
	{
		if (data.scorchingDetonationRadius > 0f)
		{
			isDamagedTargetIgnited = ITarget.IsSaturated(callbackData.target, (EffectType)1);
		}
	}

	private void HandleOnKill(in KillCallbackData callbackData)
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		if (callbackData.damageData.damage <= 0f)
		{
			return;
		}
		if (data.adrenalineDissipateMultiplier > 1f || data.adrenalineHeatRefund > 0f)
		{
			lastKillTime = Time.time;
			if (data.adrenalineHeatRefund > 0f)
			{
				RefundHeat(data.adrenalineHeatRefund);
			}
			try
			{
				Gun obj = boundGun;
				if (obj != null)
				{
					obj.TriggerEffectBuff((EffectType)0);
				}
			}
			catch
			{
			}
		}
		if (data.scorchingDetonationRadius <= 0f || !isDamagedTargetIgnited || (Object)(object)boundGun == (Object)null)
		{
			return;
		}
		try
		{
			GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)boundGun, ((IFollowable)callbackData.target).GetHealthbarPosition(), data.scorchingDetonationRadius, (TargetType)5, new DamageData(data.scorchingDetonationDamage, (DamageFlags)16), ((NetworkBehaviour)boundGun).OwnerClientId, 0f);
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Scorching detonation failed: " + ex.Message));
			}
		}
	}

	private void OnBeforePlayerTakeDamage(ref DamageData damageData, ref IDamageSource source)
	{
		if (!(data.overheatDamageReduction <= 0f) && !(data.overheatDamageReduction >= 1f))
		{
			HeatZone currentZone = CurrentZone;
			if (currentZone == HeatZone.Hot || currentZone == HeatZone.Redline || currentZone == HeatZone.Overcap)
			{
				damageData.damage *= data.overheatDamageReduction;
			}
		}
	}

	private void HandleOnSaturate(in EffectCallbackData effectData)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Invalid comparison between Unknown and I4
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Invalid comparison between Unknown and I4
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Invalid comparison between Unknown and I4
		ITarget val = EffectCallbackUtil.TryGetTarget(in effectData);
		if ((int)effectData.effect == 1 || (int)effectData.effect == 2 || (int)effectData.effect == 3)
		{
			NoteElementApplied(effectData.effect);
			TryAddCatalystStack();
		}
		if ((int)effectData.effect == 2)
		{
			if (data.shockHeatRefund > 0f)
			{
				RefundHeat(data.shockHeatRefund);
			}
			if (data.cyclePhasing && lockedPhaseMode == 2)
			{
				RefundHeat(4f * Mathf.Max(0.1f, data.cyclePhasingStrength));
			}
			if (data.crossflashBonusRefund > 0f && val != null && ITarget.IsSaturated(val, (EffectType)1))
			{
				RefundHeat(data.crossflashBonusRefund);
				TryCrossflashSplash(val);
			}
			if (data.acidSparkArcDamage > 0f && val != null && ITarget.IsSaturated(val, (EffectType)3) && toxinStacks > 0)
			{
				TryAcidSpark(val);
			}
			if (data.overloadSpeedDuration > 0f)
			{
				lastOverloadTime = Time.time;
				try
				{
					Gun obj = boundGun;
					if (obj != null)
					{
						obj.TriggerEffectSpeedBoost((EffectType)2);
					}
				}
				catch
				{
				}
			}
		}
		if ((int)effectData.effect == 3)
		{
			TryAddToxinStack();
		}
		if ((int)effectData.effect == 1)
		{
			if (data.superheatElementPerStack > 0f && data.superheatMaxStacks > 0)
			{
				superheatStacks = Mathf.Min(data.superheatMaxStacks, superheatStacks + 1);
				lastSuperheatTime = Time.time;
			}
			if (data.pyrolysisRadius > 0f && val != null && ITarget.IsSaturated(val, (EffectType)3))
			{
				TryPyrolysis(val);
			}
		}
	}

	private void TryCrossflashSplash(ITarget target)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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)
		if ((Object)(object)boundGun == (Object)null || target == null)
		{
			return;
		}
		try
		{
			Vector3 healthbarPosition = ((IFollowable)target).GetHealthbarPosition();
			float num = ((data.crossflashSplashRadius > 0f) ? data.crossflashSplashRadius : 3f);
			float crossflashSplashDamage = data.crossflashSplashDamage;
			float crossflashSplashFire = data.crossflashSplashFire;
			GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)boundGun, healthbarPosition, num, (TargetType)5, new DamageData(crossflashSplashDamage, (EffectType)1, crossflashSplashFire, (DamageFlags)16), ((NetworkBehaviour)boundGun).OwnerClientId, 0f);
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Crossflash splash failed: " + ex.Message));
			}
		}
	}

	private void TryPyrolysis(ITarget target)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)boundGun == (Object)null || target == null)
		{
			return;
		}
		try
		{
			Vector3 healthbarPosition = ((IFollowable)target).GetHealthbarPosition();
			float num = ((data.pyrolysisRadius > 0f) ? data.pyrolysisRadius : 2.8f);
			float pyrolysisDamage = data.pyrolysisDamage;
			GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)boundGun, healthbarPosition, num, (TargetType)5, new DamageData(pyrolysisDamage, (EffectType)1, pyrolysisDamage * 0.25f, (DamageFlags)16), ((NetworkBehaviour)boundGun).OwnerClientId, 0f);
			int num2 = Mathf.Max(1, data.pyrolysisBankStacks);
			if (data.toxinMaxStacks > 0)
			{
				toxinStacks = Mathf.Min(data.toxinMaxStacks, toxinStacks + num2);
			}
			else
			{
				toxinStacks += num2;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Pyrolysis failed: " + ex.Message));
			}
		}
	}

	private void TickClosedLoop(float dt, Gun gun)
	{
		if (data.closedLoopVentHeat <= 0f || data.closedLoopSustainSeconds <= 0f)
		{
			redlineSustainTimer = 0f;
			return;
		}
		bool flag = IsRedline || IsOvercapped;
		if (gun.IsFiring && flag)
		{
			redlineSustainTimer += dt;
		}
		else
		{
			redlineSustainTimer = 0f;
		}
		if (redlineSustainTimer < data.closedLoopSustainSeconds)
		{
			return;
		}
		redlineSustainTimer = 0f;
		float num = SpendHeatUpTo(data.closedLoopVentHeat);
		if (!(num <= 0f))
		{
			if (data.closedLoopEfficiencyDuration > 0f)
			{
				closedLoopEfficiencyUntil = Time.time + data.closedLoopEfficiencyDuration;
			}
			try
			{
				gun.TriggerEffectReload((EffectType)0);
			}
			catch
			{
			}
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"[CyclerRework] Closed Loop micro-vent −{num:0.#} heat");
			}
		}
	}

	private void HandlePlayerDamageDealt(in DamageCallbackData callbackData)
	{
		if ((Object)(object)boundGun == (Object)null || callbackData.damageData.damage <= 0f || (data.siphonMaxHeatPer60 <= 0f && data.siphonHeatRefundPer60 <= 0f))
		{
			return;
		}
		try
		{
			IDamageSource val = callbackData.source;
			while (val != null && val.ParentSource != null && (object)val.ParentSource != boundGun.Player)
			{
				val = val.ParentSource;
			}
			if (val == null || (object)val == boundGun)
			{
				return;
			}
			siphonDamageAccumulator += callbackData.damageData.damage;
			int num = Mathf.FloorToInt(siphonDamageAccumulator) / 60;
			if (num > 0)
			{
				siphonDamageAccumulator -= num * 60;
				if (data.siphonHeatRefundPer60 > 0f)
				{
					RefundHeat((float)num * data.siphonHeatRefundPer60);
				}
				else if (data.siphonMaxHeatPer60 > 0f)
				{
					data.maxHeat += (float)num * data.siphonMaxHeatPer60;
				}
			}
		}
		catch
		{
		}
	}

	private void HandleGunDamageTarget(in DamageCallbackData callbackData)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Invalid comparison between Unknown and I4
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		if (data.energyConvHeatPerStack > 0f && (int)callbackData.damageData.effect > 0 && callbackData.damageData.effectAmount == 0f)
		{
			energyConvCounter++;
			int num = energyConvCounter / 4;
			if (num > 0)
			{
				energyConvCounter -= num * 4;
				energyConvStoredStacks += num;
			}
		}
		if (data.cyclePhasing && lockedPhaseMode == 0)
		{
			TryPhaseCoolantRefund();
		}
		if (data.cyclePhasing && lockedPhaseMode == 3 && callbackData.damageData.damage > 0f)
		{
			float num2 = 0.18f * Mathf.Max(0.1f, data.cyclePhasingStrength);
			if (Random.value < num2)
			{
				int num3 = ((data.toxinMaxStacks > 0) ? data.toxinMaxStacks : 8);
				toxinStacks = Mathf.Min(num3, toxinStacks + 1);
			}
		}
		if (callbackData.target != null && (Object)(object)boundGun != (Object)null && (data.triValveFire > 0f || data.triValveShock > 0f || data.triValveAcid > 0f))
		{
			ApplyTriValveStatus(callbackData.target);
		}
		if (data.violentRadius > 0f && (Object)(object)boundGun != (Object)null && callbackData.target != null)
		{
			try
			{
				int num4 = 0;
				for (int i = 1; i <= 3; i++)
				{
					if (ITarget.IsSaturated(callbackData.target, (EffectType)(sbyte)i))
					{
						num4++;
					}
				}
				if (num4 >= 2)
				{
					Vector3 healthbarPosition = ((IFollowable)callbackData.target).GetHealthbarPosition();
					GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)boundGun, healthbarPosition, data.violentRadius, (TargetType)5, new DamageData(0f, boundGun.GunData.damageEffect, data.violentEffectAmount, (DamageFlags)16), ((NetworkBehaviour)boundGun).OwnerClientId, 0f);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = SparrohPlugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("[CyclerRework] Violent Reaction failed: " + ex.Message));
				}
			}
		}
		if (!(data.toxinDamagePerStack <= 0f) && data.toxinMaxStacks > 0 && (int)callbackData.damageData.effect == 3 && !(callbackData.damageData.effectAmount <= 0f))
		{
			TryAddToxinStack();
		}
	}

	private void ApplyTriValveStatus(ITarget target)
	{
		if ((Object)(object)boundGun == (Object)null || target == null)
		{
			return;
		}
		try
		{
			if (data.triValveFire > 0f)
			{
				target.ApplyStatusEffect((EffectType)1, data.triValveFire, (IDamageSource)(object)boundGun, (DamageFlags)0);
				NoteElementApplied((EffectType)1);
			}
			if (data.triValveShock > 0f)
			{
				target.ApplyStatusEffect((EffectType)2, data.triValveShock, (IDamageSource)(object)boundGun, (DamageFlags)0);
				NoteElementApplied((EffectType)2);
			}
			if (data.triValveAcid > 0f)
			{
				target.ApplyStatusEffect((EffectType)3, data.triValveAcid, (IDamageSource)(object)boundGun, (DamageFlags)0);
				NoteElementApplied((EffectType)3);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Tri-Valve status apply failed: " + ex.Message));
			}
		}
	}

	private void NoteElementApplied(EffectType element)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected I4, but got Unknown
		float time = Time.time;
		switch (element - 1)
		{
		default:
			return;
		case 0:
			lastFireApplyTime = time;
			break;
		case 1:
			lastShockApplyTime = time;
			break;
		case 2:
			lastAcidApplyTime = time;
			break;
		}
		if (data.braidWindowSeconds <= 0f || data.braidHeatPerShotMult <= 0f)
		{
			return;
		}
		float braidWindowSeconds = data.braidWindowSeconds;
		if (time - lastFireApplyTime <= braidWindowSeconds && time - lastShockApplyTime <= braidWindowSeconds && time - lastAcidApplyTime <= braidWindowSeconds)
		{
			float num = ((data.braidEfficiencyDuration > 0f) ? data.braidEfficiencyDuration : 2f);
			braidEfficiencyUntil = time + num;
			lastFireApplyTime = -999f;
			lastShockApplyTime = -999f;
			lastAcidApplyTime = -999f;
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"[CyclerRework] Braid Protocol efficiency {num:0.#}s");
			}
		}
	}

	private void TryAddCatalystStack()
	{
		if (data.catalystMaxStacks > 0)
		{
			float time = Time.time;
			if (catalystStacks > 0 && time >= catalystExpireTime)
			{
				catalystStacks = 0;
			}
			catalystStacks = Mathf.Min(data.catalystMaxStacks, catalystStacks + 1);
			float num = ((data.catalystStackDuration > 0f) ? data.catalystStackDuration : 4.5f);
			catalystExpireTime = time + num;
		}
	}

	public void ConsumeCatalystForVent(out float damageAdd, out float radiusAdd)
	{
		damageAdd = 0f;
		radiusAdd = 0f;
		if (catalystStacks > 0 && data.catalystMaxStacks > 0)
		{
			if (Time.time >= catalystExpireTime)
			{
				catalystStacks = 0;
				return;
			}
			int num = catalystStacks;
			catalystStacks = 0;
			catalystExpireTime = -999f;
			damageAdd = (float)num * Mathf.Max(0f, data.catalystVentDamagePerStack);
			radiusAdd = (float)num * Mathf.Max(0f, data.catalystVentRadiusPerStack);
		}
	}

	public bool TrySpendToxinBankStack()
	{
		if (toxinStacks <= 0)
		{
			return false;
		}
		toxinStacks--;
		return true;
	}

	private void TryAcidSpark(ITarget sourceTarget)
	{
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: 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_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: 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_00ee: 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)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: 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_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)boundGun == (Object)null || sourceTarget == null || !TrySpendToxinBankStack())
		{
			return;
		}
		try
		{
			Vector3 healthbarPosition = ((IFollowable)sourceTarget).GetHealthbarPosition();
			float num = ((data.acidSparkArcRadius > 0f) ? data.acidSparkArcRadius : 7f);
			float acidSparkArcDamage = data.acidSparkArcDamage;
			float num2 = ((data.acidSparkShockAmount > 0f) ? data.acidSparkShockAmount : (acidSparkArcDamage * 0.4f));
			int num3 = LayerMask.op_Implicit(boundGun.GunData.targetCollisionMask);
			Collider[] array = Physics.OverlapSphere(healthbarPosition, num, num3);
			ITarget val = null;
			float num4 = float.MaxValue;
			Vector3 val2 = healthbarPosition;
			foreach (Collider val3 in array)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				ITarget target = IDamageSource.GetTarget((Component)(object)val3);
				if (target == null || target == sourceTarget)
				{
					continue;
				}
				try
				{
					if (target.IsPlayer())
					{
						continue;
					}
				}
				catch
				{
				}
				Vector3 val4;
				try
				{
					val4 = ((IFollowable)target).GetHealthbarPosition();
				}
				catch
				{
					Bounds bounds = val3.bounds;
					val4 = ((Bounds)(ref bounds)).center;
				}
				Vector3 val5 = val4 - healthbarPosition;
				float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude;
				if (sqrMagnitude < num4)
				{
					num4 = sqrMagnitude;
					val = target;
					val2 = val4;
				}
			}
			if (val == null)
			{
				val2 = healthbarPosition;
			}
			GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)boundGun, val2, 0.9f, (TargetType)5, new DamageData(acidSparkArcDamage, (EffectType)2, num2, (DamageFlags)16), ((NetworkBehaviour)boundGun).OwnerClientId, 0f);
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Acid Spark failed: " + ex.Message));
			}
		}
	}

	private void TryAddToxinStack()
	{
		if (!(data.toxinDamagePerStack <= 0f) && data.toxinMaxStacks > 0)
		{
			toxinStacks = Mathf.Min(data.toxinMaxStacks, toxinStacks + 1);
		}
	}

	public void ModifyOutgoingBullet(ref BulletData bullet)
	{
		if (toxinStacks > 0 && data.toxinDamagePerStack > 0f)
		{
			bullet.damage += (float)toxinStacks * data.toxinDamagePerStack;
		}
		if (superheatStacks > 0 && data.superheatElementPerStack > 0f)
		{
			bullet.damageEffectAmount += (float)superheatStacks * data.superheatElementPerStack;
		}
		if (data.fullOutputDamagePerRarity > 0f && (Object)(object)boundGun != (Object)null)
		{
			int num = CountDistinctEquippedRarities((IGear)(object)boundGun);
			if (num > 0)
			{
				bullet.damage += data.fullOutputDamagePerRarity * (float)num;
			}
		}
		HeatZone currentZone = CurrentZone;
		HeatStatLayers.ApplyZoneToBullet(ref bullet, in data, currentZone, HeatNormalized);
		HeatStatLayers.ApplyRedlineSpreadToBullet(ref bullet, in data, currentZone);
		if (data.cyclePhasing && !phaseLockedThisSpray && (Object)(object)boundGun != (Object)null && ((NetworkBehaviour)boundGun).IsOwner)
		{
			LockPhaseModeForSpray(boundGun);
		}
		ApplyCyclePhasingToBullet(ref bullet);
	}

	public bool TryTapReload(Gun gun)
	{
		return Vent.TryHeatAbility(gun);
	}

	public bool TryConsumeEnergyConvergence(Gun gun)
	{
		if (data.energyConvHeatPerStack <= 0f || energyConvStoredStacks <= 0)
		{
			return false;
		}
		float num = (float)energyConvStoredStacks * data.energyConvHeatPerStack;
		energyConvStoredStacks = 0;
		AddHeat(num);
		try
		{
			gun.TriggerEffectReload((EffectType)0);
		}
		catch
		{
		}
		ManualLogSource logger = SparrohPlugin.Logger;
		if (logger != null)
		{
			logger.LogInfo((object)$"[CyclerRework] Energy Convergence → +{num:0.#} heat");
		}
		return true;
	}

	public void OnBulletFired(IBullet bullet)
	{
		if (!(data.arcDamage <= 0f) && bullet != null && !bullet.IsContinuous && bullet is Component)
		{
			if (trackedArcBullets.Count > 24)
			{
				trackedArcBullets.RemoveAt(0);
			}
			trackedArcBullets.Add(bullet);
		}
	}

	public static int CountDistinctEquippedRarities(IGear gear)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			HashSet<Rarity> hashSet = new HashSet<Rarity>();
			List<UpgradeInstance> list = ((gear != null) ? gear.ActiveUpgrades : null);
			if (list == null)
			{
				return 0;
			}
			for (int i = 0; i < list.Count; i++)
			{
				UpgradeInstance val = list[i];
				if (!((Object)(object)((val != null) ? val.Upgrade : null) == (Object)null) && val.Upgrade.ID.ID != 92048)
				{
					hashSet.Add(val.Upgrade.Rarity);
				}
			}
			return hashSet.Count;
		}
		catch
		{
			return 0;
		}
	}

	private void HandleSetMoveSpeed(ref float speed)
	{
		if (!(data.overloadSpeedDuration <= 0f) && Time.time - lastOverloadTime < data.overloadSpeedDuration)
		{
			speed += data.overloadSpeedIncrease;
		}
	}

	public void OnFirePressedWhileHot(Gun gun)
	{
	}

	private void TickProjectileArcs(float dt, Gun gun)
	{
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: 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_013c: Unknown result type (might be due to invalid IL or missing references)
		if (data.arcDamage <= 0f || data.arcRadius <= 0f || Time.time - lastArcTime < Mathf.Max(0.12f, data.arcInterval))
		{
			return;
		}
		for (int num = trackedArcBullets.Count - 1; num >= 0; num--)
		{
			IBullet val = trackedArcBullets[num];
			if (val == null)
			{
				trackedArcBullets.RemoveAt(num);
			}
			else
			{
				Component val2 = (Component)(object)((val is Component) ? val : null);
				if (val2 != null && ((Object)(object)val2 == (Object)null || !val2.gameObject.activeInHierarchy))
				{
					trackedArcBullets.RemoveAt(num);
				}
			}
		}
		if (trackedArcBullets.Count == 0)
		{
			if (gun.IsFiring && Time.time - arcIdleLogTime > 3f)
			{
				arcIdleLogTime = Time.time;
				ManualLogSource logger = SparrohPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"[CyclerRework] Condensed arcs idle — no tracked projectiles. Plasma prefab may not have applied (check resolve log).");
				}
			}
			return;
		}
		lastArcTime = Time.time;
		float radius = ((data.arcRadius > 0f) ? data.arcRadius : 7f);
		float arcDamage = data.arcDamage;
		int targetMask = LayerMask.op_Implicit(gun.GunData.targetCollisionMask);
		for (int i = 0; i < trackedArcBullets.Count; i++)
		{
			try
			{
				IBullet obj = trackedArcBullets[i];
				Component val3 = (Component)(object)((obj is Component) ? obj : null);
				if (val3 != null && !((Object)(object)val3 == (Object)null))
				{
					Vector3 position = val3.transform.position;
					SpawnLightningArcFromProjectile(gun, position, radius, arcDamage, targetMask);
				}
			}
			catch
			{
			}
		}
	}

	private void SpawnLightningArcFromProjectile(Gun gun, Vector3 origin, float radius, float damage, int targetMask)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		Collider[] array = Physics.OverlapSphere(origin, radius, targetMask);
		ITarget val = null;
		float num = float.MaxValue;
		Vector3 val2 = origin;
		foreach (Collider val3 in array)
		{
			if ((Object)(object)val3 == (Object)null)
			{
				continue;
			}
			ITarget target = IDamageSource.GetTarget((Component)(object)val3);
			if (target == null)
			{
				continue;
			}
			try
			{
				if (target.IsPlayer())
				{
					continue;
				}
			}
			catch
			{
			}
			Vector3 val4;
			try
			{
				val4 = ((IFollowable)target).GetHealthbarPosition();
			}
			catch
			{
				Bounds bounds = val3.bounds;
				val4 = ((Bounds)(ref bounds)).center;
			}
			Vector3 val5 = val4 - origin;
			float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude;
			if (sqrMagnitude < num)
			{
				num = sqrMagnitude;
				val = target;
				val2 = val4;
			}
		}
		if (val == null)
		{
			return;
		}
		try
		{
			DamageData val6 = default(DamageData);
			((DamageData)(ref val6))..ctor(damage, (EffectType)2, damage * 0.4f, (DamageFlags)16);
			GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)gun, val2, 0.85f, (TargetType)5, val6, ((NetworkBehaviour)gun).OwnerClientId, 0f);
		}
		catch
		{
		}
		try
		{
			SpawnArcLineVisual(origin, val2);
		}
		catch
		{
		}
	}

	private static void SpawnArcLineVisual(Vector3 start, Vector3 end)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Expected O, but got Unknown
		//IL_00d0: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("HeatCycler_PlasmaArc")
		{
			hideFlags = (HideFlags)61
		};
		LineRenderer obj = val.AddComponent<LineRenderer>();
		obj.positionCount = 2;
		obj.useWorldSpace = true;
		obj.SetPosition(0, start);
		obj.SetPosition(1, end);
		obj.startWidth = 0.045f;
		obj.endWidth = 0.02f;
		obj.numCapVertices = 2;
		((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)obj).receiveShadows = false;
		Material val2 = new Material(Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"));
		Color val3 = default(Color);
		((Color)(ref val3))..ctor(0.45f, 0.85f, 1f, 0.9f);
		if (val2.HasProperty("_BaseColor"))
		{
			val2.SetColor("_BaseColor", val3);
		}
		val2.color = val3;
		((Renderer)obj).sharedMaterial = val2;
		obj.startColor = val3;
		obj.endColor = new Color(0.7f, 0.95f, 1f, 0.35f);
		Object.Destroy((Object)val, 0.12f);
	}

	private void TickRocketSlide(float dt, Gun gun)
	{
		if (!(data.rocketSlideHeatCost <= 0f) && !((Object)(object)gun.Player == (Object)null))
		{
			bool flag = false;
			try
			{
				flag = gun.Player.Sliding;
			}
			catch
			{
				return;
			}
			if (flag && !(CurrentHeat < data.rocketSlideHeatCost) && !(Time.time - lastRocketSlideTime < Mathf.Max(0.15f, data.rocketSlideInterval)))
			{
				lastRocketSlideTime = Time.time;
				SpendHeatUpTo(data.rocketSlideHeatCost);
				FireRocketSalvo(gun);
			}
		}
	}

	private void FireRocketSalvo(Gun gun)
	{
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: 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)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: 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_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: 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_01db: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			RocketSalvoBullet prefab = null;
			CartridgeSMG val = (CartridgeSMG)(object)((gun is CartridgeSMG) ? gun : null);
			if (val != null)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(CartridgeSMG), "rocketBulletPrefab");
				if (fieldInfo != null)
				{
					ref RocketSalvoBullet reference = ref prefab;
					object? value = fieldInfo.GetValue(val);
					reference = (RocketSalvoBullet)((value is RocketSalvoBullet) ? value : null);
				}
				if ((Object)(object)prefab == (Object)null)
				{
					IUpgradable prefab2 = ((Gun)val).Prefab;
					CartridgeSMG val2 = (CartridgeSMG)(object)((prefab2 is CartridgeSMG) ? prefab2 : null);
					if (val2 != null)
					{
						ref RocketSalvoBullet reference2 = ref prefab;
						object? obj = fieldInfo?.GetValue(val2);
						reference2 = (RocketSalvoBullet)((obj is RocketSalvoBullet) ? obj : null);
					}
				}
			}
			Vector3 val3 = ((Component)gun).transform.position + ((Component)gun).transform.forward * 1.2f + Vector3.up * 0.25f;
			Quaternion rotation = ((Component)gun).transform.rotation;
			if ((Object)(object)prefab != (Object)null)
			{
				BulletData bulletData = ((GunData)(ref gun.GunData)).GetBulletData(ref val3, ref rotation);
				bulletData.speed = 110f;
				bulletData.gravity = 33f;
				bulletData.force = ((data.rocketSlideRadius > 0f) ? data.rocketSlideRadius : 1.5f);
				if (data.rocketSlideDamage > 0f)
				{
					bulletData.damage = data.rocketSlideDamage;
				}
				RocketSalvoBullet val4 = SimplePool.Get<RocketSalvoBullet>(prefab, (Transform)null);
				val4.UpgradeFlags = gun.UpgradeFlags;
				val4.Initialize(bulletData, (IDamageSource)(object)gun, (Action<IBullet>)delegate(IBullet b)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Expected O, but got Unknown
					SimplePool.Release<RocketSalvoBullet>(prefab, (RocketSalvoBullet)b);
				}, (BulletFlags)11);
				RaycastHit val5 = default(RaycastHit);
				if (Physics.Raycast(val3, ((Component)gun).transform.forward, ref val5, 80f, LayerMask.op_Implicit(gun.GunData.targetCollisionMask)))
				{
					ITarget target = IDamageSource.GetTarget((Component)(object)((RaycastHit)(ref val5)).collider);
					if (target != null)
					{
						Vector3 val6 = ((ISelectable)target).transform.InverseTransformPoint(((RaycastHit)(ref val5)).point);
						val4.SetTarget(target, val6, -1f);
					}
				}
			}
			else
			{
				GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)gun, val3 + ((Component)gun).transform.forward * 10f, Mathf.Max(1.5f, data.rocketSlideRadius), (TargetType)5, new DamageData(Mathf.Max(20f, data.rocketSlideDamage), (DamageFlags)16), ((NetworkBehaviour)gun).OwnerClientId, 0f);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[CyclerRework] Rocket slide failed: " + ex.Message));
			}
		}
	}

	private void LockPhaseModeForSpray(Gun gun)
	{
		if (phaseLockedThisSpray)
		{
			return;
		}
		int num = PhaseModeNames.Length;
		lockedPhaseMode = Mathf.Clamp(nextPhaseMode, 0, num - 1);
		nextPhaseMode = (lockedPhaseMode + 1) % num;
		phaseLockedThisSpray = true;
		phaseCoolantRefundThisSec = 0f;
		phaseCoolantSecBucket = Mathf.Floor(Time.time);
		phaseBleedOffTimer = 0f;
		float num2 = Mathf.Max(0.1f, data.cyclePhasingStrength);
		if (lockedPhaseMode == 4 && (Object)(object)gun != (Object)null)
		{
			try
			{
				if (phaseBaseBulletsPerShot < 0)
				{
					phaseBaseBulletsPerShot = gun.GunData.bulletsPerShot;
				}
				int num3 = Mathf.Max(1, Mathf.RoundToInt(num2));
				gun.GunData.bulletsPerShot = phaseBaseBulletsPerShot + num3;
			}
			catch
			{
			}
		}
		string lockedPhaseModeName = LockedPhaseModeName;
		ManualLogSource logger = SparrohPlugin.Logger;
		if (logger != null)
		{
			logger.LogInfo((object)("[CyclerRework] Cycle Phasing locked: " + lockedPhaseModeName + " (next: " + PhaseModeNames[nextPhaseMode] + ")"));
		}
		try
		{
			if (gun != null)
			{
				gun.TriggerEffectBuff((EffectType)0);
			}
		}
		catch
		{
		}
	}

	private void EndPhaseSpray(Gun gun)
	{
		if (lockedPhaseMode == 4 && (Object)(object)gun != (Object)null && phaseBaseBulletsPerShot >= 0)
		{
			try
			{
				gun.GunData.bulletsPerShot = phaseBaseBulletsPerShot;
			}
			catch
			{
			}
		}
		if (lockedPhaseMode == 7 && !data.infinityBurn && CurrentHeat > data.maxHeat)
		{
			CurrentHeat = data.maxHeat;
		}
		lockedPhaseMode = -1;
		phaseLockedThisSpray = false;
		phaseCoolantRefundThisSec = 0f;
		phaseBleedOffTimer = 0f;
		phaseBaseBulletsPerShot = -1;
	}

	private void TickCyclePhasing(float dt, Gun gun)
	{
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		if (!data.cyclePhasing || !phaseLockedThisSpray || lockedPhaseMode < 0)
		{
			return;
		}
		float num = Mathf.Max(0.1f, data.cyclePhasingStrength);
		if (lockedPhaseMode == 6 && (Object)(object)gun != (Object)null && gun.IsFiring)
		{
			phaseBleedOffTimer += dt;
			if (phaseBleedOffTimer >= 0.5f)
			{
				phaseBleedOffTimer = 0f;
				if (SpendHeatUpTo(5f * num) > 0f)
				{
					try
					{
						VanillaCyclerAssets.TryGetMuzzle(gun, out var origin, out var forward);
						Vector3 val = origin + forward * 12f;
						RaycastHit val2 = default(RaycastHit);
						if (Physics.Raycast(origin, forward, ref val2, 40f, LayerMask.op_Implicit(gun.GunData.targetCollisionMask)))
						{
							val = ((RaycastHit)(ref val2)).point;
						}
						GameManager.Instance.SpawnExplosionObserverSeeThrough((IDamageSource)(object)gun, val, 1.4f, (TargetType)5, new DamageData(8f * num, (DamageFlags)16), ((NetworkBehaviour)gun).OwnerClientId, 0f);
					}
					catch
					{
					}
				}
			}
		}
		if (lockedPhaseMode != 7 || !(CurrentHeat > data.maxHeat + 0.01f) || !((Object)(object)gun != (Object)null) || !((NetworkBehaviour)gun).IsOwner || !((Object)(object)gun.Player != (Object)null))
		{
			return;
		}
		try
		{
			float num2 = 6f * num * dt;
			IDamageSource.DamageTarget((IDamageSource)(object)gun, (ITarget)(object)gun.Player, new DamageData(num2, (EffectType)1, 0f, (DamageFlags)1), gun.Player.InterpolatedPosition, (Collider)null);
		}
		catch
		{
		}
	}

	private void TryPhaseCoolantRefund()
	{
		float num = Mathf.Floor(Time.time);
		if (!Mathf.Approximately(num, phaseCoolantSecBucket))
		{
			phaseCoolantSecBucket = num;
			phaseCoolantRefundThisSec = 0f;
		}
		float num2 = Mathf.Max(0.1f, data.cyclePhasingStrength);
		float num3 = 0.75f * num2;
		float num4 = 8f * num2;
		if (!(phaseCoolantRefundThisSec >= num4))
		{
			float num5 = Mathf.Min(num3, num4 - phaseCoolantRefundThisSec);
			phaseCoolantRefundThisSec += num5;
			RefundHeat(num5);
		}
	}

	private void ApplyCyclePhasingToBullet(ref BulletData bullet)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Invalid comparison between Unknown and I4
		if (!data.cyclePhasing || lockedPhaseMode < 0)
		{
			return;
		}
		float num = Mathf.Max(0.1f, data.cyclePhasingStrength);
		switch ((PhaseMode)lockedPhaseMode)
		{
		case PhaseMode.Pyre:
			bullet.damageEffect = (EffectType)1;
			bullet.damageEffectAmount += 12f * num;
			break;
		case PhaseMode.Storm:
			bullet.damageEffect = (EffectType)2;
			bullet.damageEffectAmount += 12f * num;
			break;
		case PhaseMode.Solvent:
			bullet.damageEffect = (EffectType)3;
			bullet.damageEffectAmount += 10f * num;
			break;
		case PhaseMode.Split:
			bullet.damage *= 1f + 0.05f * num;
			break;
		case PhaseMode.Needle:
			bullet.maxBounces = Mathf.Max(bullet.maxBounces, Mathf.RoundToInt(1f * num));
			bullet.speed *= 1f + 0.12f * num;
			bullet.damage *= 1f + 0.08f * num;
			break;
		case PhaseMode.Spike:
			bullet.damage *= 1f + 0.12f * num;
			if ((int)bullet.damageEffect > 0)
			{
				bullet.damageEffectAmount += 6f * num;
			}
			break;
		case PhaseMode.Coolant:
		case PhaseMode.BleedOff:
			break;
		}
	}

	private void OnDestroy()
	{
		if ((Object)(object)boundGun != (Object)null)
		{
			BindHooks(boundGun, bind: false);
		}
		ventSystem?.Destroy();
	}

	public static bool TryGet(IGear gear, out CyclerHeatBehaviour behaviour)
	{
		behaviour = null;
		if ((Object)(object)((gear != null) ? gear.gameObject : null) == (Object)null)
		{
			return false;
		}
		behaviour = gear.gameObject.GetComponent<CyclerHeatBehaviour>();
		if ((Object)(object)behaviour != (Object)null)
		{
			return true;
		}
		bool num = (Object)(object)((IUpgradable)gear).Info != (Object)null && (((IUpgradable)gear).Info.APIName == "sparroh_cycler" || ((IUpgradable)gear).Info.ID == 92010);
		CyclerHeatBehaviour cyclerHeatBehaviour = null;
		IUpgradable prefab = ((IUpgradable)gear).Prefab;
		Component val = (Component)(object)((prefab is Component) ? prefab : null);
		if (val != null)
		{
			cyclerHeatBehaviour = val.GetComponent<CyclerHeatBehaviour>();
		}
		if (!num && (Object)(object)cyclerHeatBehaviour == (Object)null)
		{
			return false;
		}
		string desc = (((Object)(object)cyclerHeatBehaviour != (Object)null) ? cyclerHeatBehaviour.Description : "A reworked Cycler SMG. Infinite ammo — builds Heat while firing. Ride Soft Redline at max Heat (keep firing, wilder and meaner). Tap R to Pressure Vent.");
		behaviour = gear.gameObject.AddComponent<CyclerHeatBehaviour>();
		behaviour.InitializeAsPrefab(desc);
		if ((Object)(object)cyclerHeatBehaviour != (Object)null)
		{
			behaviour.CopySnapshotFrom(cyclerHeatBehaviour);
		}
		behaviour.CapturePrefabSnapshot();
		return true;
	}

	public static bool IsOurGear(IUpgradable gear)
	{
		if (gear == null)
		{
			return false;
		}
		if (gear == SparrohPlugin.CustomWeaponPrefab || gear == WeaponRegistration.CatalogGear)
		{
			return true;
		}
		if ((Object)(object)gear.Info != (Object)null && (gear.Info.APIName == "sparroh_cycler" || gear.Info.ID == 92010))
		{
			return true;
		}
		return false;
	}
}
internal static class CyclerHeatHooks
{
	[HarmonyPatch(typeof(CartridgeSMG), "OnUpgradesRemoved")]
	[HarmonyPostfix]
	private static void OnUpgradesRemovedPostfix(CartridgeSMG __instance)
	{
		ResetHeatBaseline((Gun)(object)__instance);
	}

	[HarmonyPatch(typeof(Gun), "OnUpgradesRemoved")]
	[HarmonyPostfix]
	private static void OnUpgradesRemovedGunPostfix(Gun __instance)
	{
		if (!(__instance is CartridgeSMG))
		{
			ResetHeatBaseline(__instance);
		}
	}

	private static void ResetHeatBaseline(Gun gun)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)gun, out var behaviour))
		{
			behaviour.SetData(CyclerHeatBehaviour.CreateDataFromConfig());
			behaviour.CapturePrefabSnapshot();
			behaviour.ResetUpgradeRuntimeState();
		}
	}

	[HarmonyPatch(typeof(Gun), "OnUpgradesEnabled")]
	[HarmonyPostfix]
	private static void OnUpgradesEnabledPostfix(Gun __instance)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			CyclerHeatBehaviour.ApplyInfiniteAmmo(__instance);
			behaviour.OnUpgradesApplied(__instance);
			if (behaviour.WeaponData.arcDamage > 0f)
			{
				VanillaCyclerAssets.TryApplyPlasmaBullet(__instance);
			}
			behaviour.SyncFireLock(__instance);
		}
	}

	[HarmonyPatch(typeof(Gun), "AfterUpgradesEnabled")]
	[HarmonyPostfix]
	private static void AfterUpgradesEnabledPostfix(Gun __instance)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			CyclerHeatBehaviour.ApplyInfiniteAmmo(__instance);
			if (behaviour.WeaponData.arcDamage > 0f)
			{
				VanillaCyclerAssets.TryApplyPlasmaBullet(__instance);
			}
			behaviour.SyncFireLock(__instance);
		}
	}

	[HarmonyPatch(typeof(Gun), "OnUpgradesDisabled")]
	[HarmonyPrefix]
	private static void OnUpgradesDisabledPrefix(Gun __instance)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.OnUpgradesCleared(__instance);
		}
	}

	[HarmonyPatch(typeof(CartridgeSMG), "OnFire")]
	[HarmonyPostfix]
	private static void CartridgeOnFirePostfix(CartridgeSMG __instance, int numBullets)
	{
		try
		{
			if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour) && ((NetworkBehaviour)__instance).IsOwner)
			{
				int numBullets2 = Mathf.Max(1, numBullets);
				behaviour.AddHeatFromShot(numBullets2, (Gun)(object)__instance);
				behaviour.OnShotFired(numBullets2, (Gun)(object)__instance);
				PushHeatHud((Gun)(object)__instance, behaviour);
			}
		}
		catch (Exception arg)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogError((object)$"[CyclerRework] OnFire heat hook failed: {arg}");
			}
		}
	}

	[HarmonyPatch(typeof(Gun), "AddRecoil")]
	[HarmonyPrefix]
	private static void AddRecoilPrefix(Gun __instance, ref float multiplier)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.ModifyRecoilMultiplier(__instance, ref multiplier);
		}
	}

	[HarmonyPatch(typeof(CartridgeSMG), "ModifyBulletData")]
	[HarmonyPostfix]
	private static void CartridgeModifyBulletDataPostfix(CartridgeSMG __instance, ref BulletData data, BulletFlags flags)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.ModifyOutgoingBullet(ref data);
		}
	}

	[HarmonyPatch(typeof(Gun), "ModifyBulletData")]
	[HarmonyPostfix]
	private static void GunModifyBulletDataPostfix(Gun __instance, ref BulletData data)
	{
		if (!(__instance is CartridgeSMG) && CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.ModifyOutgoingBullet(ref data);
		}
	}

	[HarmonyPatch(typeof(Gun), "Update")]
	[HarmonyPostfix]
	private static void GunUpdatePostfix(Gun __instance)
	{
		try
		{
			if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && __instance.Active && CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
			{
				behaviour.Tick(Time.deltaTime, __instance);
				PushHeatHud(__instance, behaviour);
			}
		}
		catch (Exception arg)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogError((object)$"[CyclerRework] Heat tick failed: {arg}");
			}
		}
	}

	[HarmonyPatch(typeof(Gun), "CanReload")]
	[HarmonyPrefix]
	private static bool CanReloadPrefix(Gun __instance, ref bool __result)
	{
		if (!CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var _))
		{
			return true;
		}
		__result = false;
		return false;
	}

	[HarmonyPatch(typeof(CartridgeSMG), "OverrideHoldReload")]
	[HarmonyPrefix]
	private static bool OverrideHoldReloadPrefix(CartridgeSMG __instance, ref bool __result)
	{
		if (!CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return true;
		}
		if (behaviour.TryTapReload((Gun)(object)__instance))
		{
			__result = true;
			return false;
		}
		__result = false;
		return false;
	}

	[HarmonyPatch(typeof(Gun), "OnReloadPerformed")]
	[HarmonyPrefix]
	private static bool OnReloadPerformedPrefix(Gun __instance, CallbackContext context)
	{
		if (!CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return true;
		}
		if (!((NetworkBehaviour)__instance).IsOwner)
		{
			return true;
		}
		behaviour.TryTapReload(__instance);
		return false;
	}

	[HarmonyPatch(typeof(Gun), "OnFirePressed")]
	[HarmonyPostfix]
	private static void OnFirePressedPostfix(Gun __instance)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour) && ((NetworkBehaviour)__instance).IsOwner)
		{
			behaviour.OnFirePressedWhileHot(__instance);
		}
	}

	[HarmonyPatch(typeof(Gun), "OnFiredBullet")]
	[HarmonyPostfix]
	private static void OnFiredBulletPostfix(Gun __instance, IBullet bullet, BulletFlags flags, int shotIndex, ref BulletData bulletData)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.OnBulletFired(bullet);
		}
	}

	[HarmonyPatch(typeof(Gun), "AfterBulletFired")]
	[HarmonyPostfix]
	private static void AfterBulletFiredPostfix(Gun __instance, IBullet bullet, BulletFlags flags, int shotIndex)
	{
		if (CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			behaviour.OnBulletFired(bullet);
		}
	}

	[HarmonyPatch(typeof(Gun), "GetPrimaryHUDText")]
	[HarmonyPrefix]
	private static bool GetPrimaryHUDTextPrefix(Gun __instance, char[] buffer, ref int __result)
	{
		if (!CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return true;
		}
		__result = WriteHeatHud(buffer, behaviour);
		return false;
	}

	[HarmonyPatch(typeof(Gun), "InvokeAmmoChangedAsHUDUpdate")]
	[HarmonyPrefix]
	private static bool InvokeAmmoChangedAsHUDUpdatePrefix(Gun __instance, float ammo)
	{
		if (!CyclerHeatBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return true;
		}
		WriteHeatHud(Global.charBuffer, behaviour);
		__instance.RefreshHUD();
		return false;
	}

	private static void PushHeatHud(Gun gun, CyclerHeatBehaviour heat)
	{
		if ((Object)(object)gun == (Object)null || (Object)(object)heat == (Object)null)
		{
			return;
		}
		try
		{
			int num = WriteHeatHud(Global.charBuffer, heat);
			gun.RefreshHUD();
			MethodInfo methodInfo = AccessTools.Method(typeof(Gun), "InvokeOnUpdatePrimaryHUDText", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				methodInfo.Invoke(gun, new object[2]
				{
					num,
					Global.charBuffer
				});
			}
		}
		catch
		{
		}
	}

	private static int WriteHeatHud(char[] buffer, CyclerHeatBehaviour heat)
	{
		if (buffer == null || buffer.Length == 0)
		{
			return 0;
		}
		int num = MathUtil.FillArrayWithNumber(Mathf.Max(0, Mathf.RoundToInt(heat.HeatNormalized * 100f)), buffer);
		if (num < buffer.Length)
		{
			buffer[num++] = '%';
		}
		if (heat.IsOvercapped && num + 2 <= buffer.Length)
		{
			buffer[num++] = 'O';
			buffer[num++] = 'C';
		}
		else if (heat.IsRedline && num + 2 <= buffer.Length)
		{
			buffer[num++] = 'R';
			buffer[num++] = 'L';
		}
		return num;
	}
}
public static class HeatCyclerUpgrades
{
	public const int IdChargedCartridges = 92020;

	public const int IdCorrosivePlasma = 92021;

	public const int IdDecayEnergy = 92022;

	public const int IdHeatedBattery = 92023;

	public const int IdFocusedLenses = 92024;

	public const int IdPrecisionFire = 92025;

	public const int IdRicochet = 92026;

	public const int IdOverclockedFiring = 92027;

	public const int IdExtralightFrame = 92028;

	public const int IdDoubleShot = 92029;

	public const int IdCyclotron = 92030;

	public const int IdScorchingDetonation = 92031;

	public const int IdCyclingRepairs = 92032;

	public const int IdMomentumOverload = 92033;

	public const int IdStabilityModule = 92034;

	public const int IdInfinityBurn = 92035;

	public const int IdBigazine = 92036;

	public const int IdBulgingCartridge = 92037;

	public const int IdCompactCartridge = 92038;

	public const int IdDoublestackCartridge = 92039;

	public const int IdAdrenalineReload = 92040;

	public const int IdChargeShield = 92041;

	public const int IdShockRecursion = 92042;

	public const int IdToxinRecycling = 92043;

	public const int IdSuperheatReaction = 92044;

	public const int IdLiteEnergy = 92045;

	public const int IdMassAcceleration = 92046;

	public const int IdEquipmentSiphon = 92047;

	public const int IdFullOutput = 92048;

	public const int IdEnergyConvergence = 92049;

	public const int IdElementalDischarge = 92050;

	public const int IdViolentReaction = 92051;

	public const int IdCondensedEjection = 92052;

	public const int IdRocketSlide = 92053;

	public const int IdDumpCharge = 92054;

	public const int IdCyclePhasing = 92055;

	public const int IdBoundaryIncursion = 92056;

	public const int IdClosedLoop = 92057;

	public const int IdCrossflash = 92058;

	public const int IdPyrolysis = 92059;

	public const int IdTriValve = 92060;

	public const int IdAcidSpark = 92061;

	public const int IdBraidProtocol = 92062;

	public const int IdSaturateCatalyst = 92063;

	private const UpgradeFlags FlagMissionStack = (UpgradeFlags)16384u;

	private const UpgradeFlags FlagNoRandom = (UpgradeFlags)32u;

	private const UpgradeFlags FlagSpatialMissionStack = (UpgradeFlags)540672u;

	private static bool _registered;

	public static void RegisterAll(ManualLogSource log = null)
	{
		if (_registered)
		{
			return;
		}
		IUpgradable val = SparrohPlugin.ResolveRegisteredGear();
		if (val == null)
		{
			if (log != null)
			{
				log.LogDebug((object)"[HeatCyclerUpgrades] Gear not ready — deferring.");
			}
			return;
		}
		if (PlayerData.Instance == null)
		{
			if (log != null)
			{
				log.LogDebug((object)"[HeatCyclerUpgrades] PlayerData not ready — deferring.");
			}
			return;
		}
		try
		{
			WeaponRegistration.EnsureGearData(val, autoUnlock: true, log);
			GearData val2 = PlayerData.GetGearData(val) ?? (((Object)(object)val.Info != (Object)null) ? PlayerData.GetGearData(val.Info.ID) : null);
			if (val2 == null)
			{
				if (log != null)
				{
					log.LogDebug((object)"[HeatCyclerUpgrades] GearData missing — deferring upgrades.");
				}
				return;
			}
			if (val2.Gear == null)
			{
				val2.Gear = val;
			}
		}
		catch (Exception ex)
		{
			if (log != null)
			{
				log.LogDebug((object)("[HeatCyclerUpgrades] GearData gate failed — deferring: " + ex.Message));
			}
			return;
		}
		int num = 0;
		if (RegisterChargedCartridges(val, log))
		{
			num++;
		}
		if (RegisterCorrosivePlasma(val, log))
		{
			num++;
		}
		if (RegisterHeatedBattery(val, log))
		{
			num++;
		}
		if (RegisterFocusedLenses(val, log))
		{
			num++;
		}
		if (RegisterPrecisionFire(val, log))
		{
			num++;
		}
		if (RegisterRicochet(val, log))
		{
			num++;
		}
		if (RegisterOverclockedFiring(val, log))
		{
			num++;
		}
		if (RegisterExtralightFrame(val, log))
		{
			num++;
		}
		if (RegisterDoubleShot(val, log))
		{
			num++;
		}
		if (RegisterCyclotron(val, log))
		{
			num++;
		}
		if (RegisterScorchingDetonation(val, log))
		{
			num++;
		}
		if (RegisterCyclingRepairs(val, log))
		{
			num++;
		}
		if (RegisterMomentumOverload(val, log))
		{
			num++;
		}
		if (RegisterStabilityModule(val, log))
		{
			num++;
		}
		if (RegisterInfinityBurn(val, log))
		{
			num++;
		}
		if (RegisterBigazine(val, log))
		{
			num++;
		}
		if (RegisterBulgingCartridge(val, log))
		{
			num++;
		}
		if (RegisterCompactCartridge(val, log))
		{
			num++;
		}
		if (RegisterDoublestackCartridge(val, log))
		{
			num++;
		}
		if (RegisterAdrenalineReload(val, log))
		{
			num++;
		}
		if (RegisterChargeShield(val, log))
		{
			num++;
		}
		if (RegisterShockRecursion(val, log))
		{
			num++;
		}
		if (RegisterToxinRecycling(val, log))
		{
			num++;
		}
		if (RegisterSuperheatReaction(val, log))
		{
			num++;
		}
		if (RegisterLiteEnergy(val, log))
		{
			num++;
		}
		if (RegisterMassAcceleration(val, log))
		{
			num++;
		}
		if (RegisterEquipmentSiphon(val, log))
		{
			num++;
		}
		if (RegisterFullOutput(val, log))
		{
			num++;
		}
		if (RegisterEnergyConvergence(val, log))
		{
			num++;
		}
		if (RegisterElementalDischarge(val, log))
		{
			num++;
		}
		if (RegisterViolentReaction(val, log))
		{
			num++;
		}
		if (RegisterCondensedEjection(val, log))
		{
			num++;
		}
		if (RegisterRocketSlide(val, log))
		{
			num++;
		}
		if (RegisterDumpCharge(val, log))
		{
			num++;
		}
		if (RegisterCyclePhasing(val, log))
		{
			num++;
		}
		if (RegisterBoundaryIncursion(val, log))
		{
			num++;
		}
		if (RegisterClosedLoop(val, log))
		{
			num++;
		}
		if (RegisterCrossflash(val, log))
		{
			num++;
		}
		if (RegisterPyrolysis(val, log))
		{
			num++;
		}
		if (RegisterTriValve(val, log))
		{
			num++;
		}
		if (RegisterAcidSpark(val, log))
		{
			num++;
		}
		if (RegisterBraidProtocol(val, log))
		{
			num++;
		}
		if (RegisterSaturateCatalyst(val, log))
		{
			num++;
		}
		if (num == 43)
		{
			_registered = true;
			if (log != null)
			{
				log.LogInfo((object)$"[HeatCyclerUpgrades] Registered {num}/{43} upgrades (Tier A–E3 + Boundary + Interlace).");
			}
			return;
		}
		if (log != null)
		{
			log.LogWarning((object)$"[HeatCyclerUpgrades] Registered {num}/{43} upgrades (partial).");
		}
		if (num > 0)
		{
			_registered = true;
		}
	}

	private static bool RegisterChargedCartridges(IUpgradable gear, ManualLogSource log)
	{
		return Create(gear, 92020, "Charged Cartridges", "Rounds apply Shock buildup.", (Rarity)1, (UpgradeFlags)16384, -10, UpgradePatterns.ElementApplicator(), (UpgradeProperty[])(object)new UpgradeProperty[1] { (UpgradeProperty)ElementDamage((EffectType)2, 1.85f, 2.15f) }, log, "Charged_Cartridges_Icon.png");
	}

	private static bool RegisterCorrosivePlasma(IUpgradable gear, ManualLogSource log)
	{
		return Create(gear, 92021, "Corrosive Plasma", "Rounds apply Acid buildup.", (Rarity)1, (UpgradeFlags)16384, -10, UpgradePatterns.ElementApplicator(), (UpgradeProperty[])(object)new UpgradeProperty[1] { (UpgradeProperty)ElementDamage((EffectType)3, 1.85f, 2.15f) }, log, "Corrosive_Plasma_Icon.png");
	}

	private static bool RegisterHeatedBattery(IUpgradable gear, ManualLogSource log)
	{
		return Create(gear, 92023, "Heated Battery", "Rounds apply Fire buildup.", (Rarity)1, (UpgradeFlags)16384, -10, UpgradePatterns.ElementApplicator(), (UpgradeProperty[])(object)new UpgradeProperty[1] { (UpgradeProperty)ElementDamage((EffectType)1, 1.85f, 2.15f) }, log, "Heated_Battery_Icon.png");
	}

	private static UpgradeProperty_Damage ElementDamage(EffectType element, float amountMin, float amountMax)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		return new UpgradeProperty_Damage
		{
			damage = new OverrideData<Range<float>>(new Range<float>(0f, 0f), (OverrideType)0),
			effectType = new OverrideData<EffectType>(element, (OverrideType)3),
			effectAmount = new OverrideData<Range<float>>(new Range<float>(amountMin, amountMax), (OverrideType)1),
			stackModifier = 0f
		};
	}

	private static bool RegisterFocusedLenses(IUpgradable gear, ManualLogSource log)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		UpgradeProperty_Range val = new UpgradeProperty_Range
		{
			falloffStartDistance = new OverrideData<Range<float>>(new Range<float>(8f, 11f), (OverrideType)1),
			falloffEndDistance = new OverrideData<Range<float>>(new Range<float>(8f, 11f), (OverrideType)1),
			maxDamageRange = new OverrideData<Range<float>>(new Range<float>(0f, 0f), (OverrideType)0),
			maxFalloffDamageMultiplier = new OverrideData<Range<float>>(new Range<float>(0f, 0f), (OverrideType)0),
			isMinRangeBetter = false,
			stackMultiplier = 0f
		};
		return Create(gear, 92024, "Focused Lenses", "Increases effective range before damage falloff.", (Rarity)0, (UpgradeFlags)16384, 0, UpgradePatterns.FocusedLenses(), (UpgradeProperty[])(object)new UpgradeProperty[1] { (UpgradeProperty)val }, log, "Focused_Lenses_Icon.png");
	}

	private static bool RegisterPrecisionFire(IUpgradable gear, ManualLogSource log)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		UpgradeProperty_Spread val = new UpgradeProperty_Spread
		{
			spreadSize = new OverrideData<Range<Vector2>>(new Range<Vector2>(new Vector2(0.2f, 0.2f), new Vector2(0.3f, 0.3f)), (OverrideType)2),
			spreadType = new OverrideData<SpreadType>((SpreadType)0, (OverrideType)0),
			stackMultiplier = 0f
		};
		UpgradeProperty_FireInterval val2 = new UpgradeProperty_FireInterval
		{
			fireInterval = new OverrideData<Range<float>>(new Range<float>(1.23f, 1.27f), (OverrideType)2)
		};
		return Create(gear, 92025, "Precision Fire", "Tighter spread at the cost of fire rate.", (Rarity)0, (UpgradeFlags)16384, 0, UpgradePatterns.PrecisionFire(), (UpgradeProperty[])(object)new UpgradeProperty[2]
		{
			(UpgradeProperty)val,
			(UpgradeProperty)val2
		}, log, "Precision_Fire_Icon.png");
	}

	private static bool RegisterRicochet(IUpgradable gear, ManualLogSource log)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		UpgradeProperty_MaxBounces val = new UpgradeProperty_MaxBounces
		{
			maxBounces = new OverrideData<Range<int>>(new Range<int>(1, 1), (OverrideType)1)
		};
		return Create(gear, 92026, "Ricochet", "Bullets bounce once off surfaces.", (Rarity)1, (UpgradeFlags)16416, 0, UpgradePatterns.Ricochet(), (UpgradeProperty[])(object)new UpgradeProperty[1] { (UpgradeProperty)val }, log, "Ricochet_Icon.png");
	}

	private static bool RegisterOverclockedFiring(IUpgradable gear, ManualLogSource log)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		//IL_007e: 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)
		UpgradeProperty_Spread val = new UpgradeProperty_Spread
		{
			spreadSize = new OverrideData<Range<Vector2>>(new Range<Vector2>(new Vector2(4.5f, 4.5f), new Vector2(5.8f, 5.8f)), (OverrideType)1),
			spreadType = new OverrideData<SpreadType>((SpreadType)0, (OverrideType)0),
			stackMultiplier = 0.25f
		};
		UpgradeProperty_FireInterval val2 = new UpgradeProperty_FireInterval
		{
			fireInterval = new OverrideData<Range<float>>(new Range<float>(0.8f, 0.9f), (OverrideType)2)
		};
		UpgradeProperty_Heat_HeatPerShotMult upgradeProperty_Heat_HeatPerShotMult = new UpgradeProperty_Heat_HeatPerShotMult
		{
			heatPerShotMultiplier = new Range<float>(1.08f, 1.14f)
		};
		return Create(gear, 92027, "Overclocked Firing Mechanism", "Increases fire rate with wider spread. Slightly more Heat per shot.", (Rarity)0, (UpgradeFlags)16384, 0, UpgradePatterns.OverclockedFiring(), (UpgradeProperty[])(object)new UpgradeProperty[3]
		{
			(UpgradeProperty)val,
			(UpgradeProperty)val2,
			upgradeProperty_Heat_HeatPerShotMult
		}, log, "Overclocked_Firing_Mechanism_Icon.png");
	}

	private static bool RegisterExtralightFrame(IUpgradable gear, ManualLogSource log)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		UpgradeProperty_FireConstraints val = new UpgradeProperty_FireConstraints
		{
			canFireWhileSprinting = new OverrideData<ActionFireMode>((ActionFireMode)1, (OverrideType)3),
			canFireWhileJumping = new OverrideData<bool>(false, (OverrideType)0),
			canFireWhileSliding = new OverrideData<ActionFireMode>((ActionFireMode)0, (OverrideType)0),
			canAimWhileSliding = new OverrideData<ActionFireMode>((ActionFireMode)0, (OverrideType)0)
		};
		return Create(gear, 92