Decompiled source of DMLRRework v1.0.0

BepInEx/plugins/DMLRRework.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Math;
using Pigeon.Movement;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Pool;

[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("DMLRRework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DMLRRework")]
[assembly: AssemblyTitle("DMLRRework")]
[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 CondensedPierceTracker : MonoBehaviour
{
	public int maxPierces;

	public int piercedCount;

	public float ammoSpent;

	public bool chargeGranted;

	public bool CanPierceMore => piercedCount < maxPierces;

	public void RegisterHit()
	{
		piercedCount++;
	}

	public void ResetState()
	{
		maxPierces = 0;
		piercedCount = 0;
		ammoSpent = 0f;
		chargeGranted = false;
		((Behaviour)this).enabled = false;
	}
}
public sealed class DmlrReworkBehaviour : MonoBehaviour
{
	[Serializable]
	public struct Data
	{
		public bool voltaicBattery;

		public float voltaicLaserDamageFraction;

		public bool pulverizer;

		public float limbDamageMult;

		public float shellDamageMult;

		public float shellInwardSplashPercent;

		public bool tripleElement;

		public EffectType tripleEffect;

		public float tripleEffectAmount;

		public bool reverseFalloff;

		public float reverseFalloffMaxMult;

		public bool overheatedCapacitor;

		public float overheatDamagePerSecond;

		public float overheatMaxBonus;

		public bool dmrKillExplosion;

		public float dmrKillExplosionRadius;

		public float dmrKillExplosionDamageScale;

		public EffectType dmrKillExplosionEffect;

		public bool shredder;

		public float shredderInterval;

		public bool demonstratorsTrick;

		public float demoBuffDuration;

		public float demoBuffDamageMult;

		public bool gravitationalCollapse;

		public float gravPullForce;

		public float gravPullRadius;

		public bool condensedMunitions;

		public float condensedDamagePerAmmo;

		public int condensedPierceBudget;

		public bool incendiaryWave;

		public float incendiaryInterval;

		public float incendiaryRadius;

		public float incendiaryDamageScale;

		public float incendiaryEffectAmount;

		public float transferDmrPercent;

		public float transferLaserPercent;

		public bool hotSwapRoles;

		public bool transferFromLimbs;

		public bool arterialShred;

		public float openArteryDuration;

		public float openArteryTransferBonus;

		public bool overkillConduit;

		public float overkillTransferMult;

		public float overkillMarkedBonusMult;

		public bool hardLightDesignator;

		public float exposeDuration;

		public float exposeDamageMult;

		public float exposeChargeRefund;

		public bool markOnDmrHit;

		public float markDuration;

		public bool jointBreaker;

		public int jointBreakerEveryN;

		public float jointBreakerDecayAmount;

		public bool rotThread;

		public int rotThreadEveryN;

		public float rotThreadRotAmount;

		public bool faultLine;

		public float faultLineBonusPerHit;

		public float faultLineMaxBonus;

		public float faultLineResetTime;

		public bool reactorTap;

		public float reactorTapCharge;

		public int reactorTapAmmoOnExposed;

		public bool coreBrand;

		public int coreBrandMaxStacks;

		public float coreBrandExposeDuration;

		public bool phantomPain;

		public float phantomPainDamageMult;

		public float phantomPainChargeRefund;

		public bool bleedCharge;

		public float bleedChargeAmount;

		public bool breachCharge;

		public float breachChargeAmount;

		public bool markedRecycling;

		public float markedRecyclingAmmoPerHit;

		public bool elementalEmitter;

		public EffectType elementalLaserEffect;

		public float elementalLaserAmount;

		public bool sympatheticArc;

		public float arcRadius;

		public float arcDamageScale;

		public int arcMaxJumps;

		public float arcTransferScale;

		public bool sympatheticResonance;

		public float resonanceEchoScale;

		public bool collapseWave;

		public float collapseRadius;

		public float collapseHpScale;

		public EffectType collapseEffect;

		public bool voltaicBatteryV2;

		public float batteryFuseTime;

		public float batteryBaseDamage;

		public float batteryEmptyMagBonus;

		public float batteryTransferPercent;

		public float batteryRadius;

		public bool demoTrickV2;

		public float demoMarkSpreadRadius;

		public float demoHeavyMarkDuration;

		public float demoHeavyMarkDamageMult;

		public bool breachAmmoSystem;

		public float breachAmmoMax;

		public float breachAmmoPerLaserHit;

		public float breachAmmoPerLaserTick;

		public float breachSlugCost;

		public float breachSlugDamageMult;

		public float breachSlugShellMult;

		public float breachBreakTransferBonus;

		public bool severanceCycle;

		public float cycleInterval;

		public float cycleLaserWindow;

		public int dissectionStacksPerLimbHit;

		public int dissectionStacksToPulse;

		public float dissectionPulseTransferPercent;

		public float dissectionPulseDamageScale;
	}

	[SerializeField]
	private Data data = CreateDefaultData();

	private Data prefabSnapshot = CreateDefaultData();

	private string description = "Marksman Laser Rifle";

	[NonSerialized]
	public bool forcingSecondaryFire;

	[NonSerialized]
	public bool wantLaserMode;

	[NonSerialized]
	public int dmrShotCounter;

	[NonSerialized]
	public int limbHitCounter;

	[NonSerialized]
	public int shellHitCounter;

	[NonSerialized]
	public int faultLinePartId;

	[NonSerialized]
	public int faultLineStacks;

	[NonSerialized]
	public float faultLineLastHitTime;

	[NonSerialized]
	public Dictionary<int, int> brandStacks;

	[NonSerialized]
	public HashSet<int> phantomKilledLimbIds;

	[NonSerialized]
	public HashSet<string> phantomKilledLimbKeys;

	[NonSerialized]
	public float laserBeamAirTime;

	[NonSerialized]
	public bool killHookSubscribed;

	[NonSerialized]
	public bool severanceHooksSubscribed;

	[NonSerialized]
	public float shredderTimer;

	[NonSerialized]
	public bool shredderDecayActive;

	[NonSerialized]
	public int lastFiredMode;

	[NonSerialized]
	public float demoBuffRemaining;

	[NonSerialized]
	public int demoPendingEmpower;

	[NonSerialized]
	public bool batteryThrowPending;

	[NonSerialized]
	public float batteryPowerMult;

	[NonSerialized]
	public float lastBatteryThrowTime;

	[NonSerialized]
	public float breachAmmo;

	[NonSerialized]
	public bool breachSlugArmed;

	[NonSerialized]
	public float cycleTimer;

	[NonSerialized]
	public bool cycleLaserPhase;

	[NonSerialized]
	public int dissectionStacks;

	[NonSerialized]
	public int lastLimbBrainId;

	[NonSerialized]
	public Vector3 lastLimbHitPos;

	[NonSerialized]
	public float incendiaryTimer;

	[NonSerialized]
	public float lastGravPullTime;

	[NonSerialized]
	public int pendingCondensedPierces;

	[NonSerialized]
	public float pendingCondensedAmmoSpent;

	[NonSerialized]
	public Dictionary<int, float> markExpiries;

	[NonSerialized]
	public Dictionary<int, float> exposeExpiries;

	[NonSerialized]
	public int openArteryBrainId;

	[NonSerialized]
	public float openArteryExpiry;

	[NonSerialized]
	public int pendingOverkillPartId;

	[NonSerialized]
	public float pendingOverkillAmount;

	[NonSerialized]
	public float pendingOverkillTime;

	[NonSerialized]
	public bool isApplyingTransfer;

	[NonSerialized]
	public int drillFocusBrainId;

	[NonSerialized]
	public int drillFocusPartId;

	[NonSerialized]
	public Vector3 drillFocusLastPos;

	[NonSerialized]
	public int drillFocusDepth;

	public ref Data WeaponData => ref data;

	public string Description => description;

	public static Data CreateDefaultData()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0313: Unknown result type (might be due to invalid IL or missing references)
		//IL_038f: Unknown result type (might be due to invalid IL or missing references)
		return new Data
		{
			voltaicBattery = false,
			voltaicLaserDamageFraction = 0f,
			pulverizer = false,
			limbDamageMult = 1f,
			shellDamageMult = 1f,
			shellInwardSplashPercent = 0f,
			tripleElement = false,
			tripleEffect = (EffectType)0,
			tripleEffectAmount = 0f,
			reverseFalloff = false,
			reverseFalloffMaxMult = 1f,
			overheatedCapacitor = false,
			overheatDamagePerSecond = 0f,
			overheatMaxBonus = 0f,
			dmrKillExplosion = false,
			dmrKillExplosionRadius = 0f,
			dmrKillExplosionDamageScale = 0f,
			dmrKillExplosionEffect = (EffectType)0,
			shredder = false,
			shredderInterval = 1.5f,
			demonstratorsTrick = false,
			demoBuffDuration = 3f,
			demoBuffDamageMult = 1.25f,
			gravitationalCollapse = false,
			gravPullForce = 18f,
			gravPullRadius = 8f,
			condensedMunitions = false,
			condensedDamagePerAmmo = 0.35f,
			condensedPierceBudget = 0,
			incendiaryWave = false,
			incendiaryInterval = 1.25f,
			incendiaryRadius = 2.5f,
			incendiaryDamageScale = 0.6f,
			incendiaryEffectAmount = 10f,
			transferDmrPercent = 0f,
			transferLaserPercent = 0f,
			hotSwapRoles = false,
			transferFromLimbs = false,
			arterialShred = false,
			openArteryDuration = 3f,
			openArteryTransferBonus = 0f,
			overkillConduit = false,
			overkillTransferMult = 1f,
			overkillMarkedBonusMult = 1f,
			hardLightDesignator = false,
			exposeDuration = 4f,
			exposeDamageMult = 1f,
			exposeChargeRefund = 0f,
			markOnDmrHit = false,
			markDuration = 4f,
			jointBreaker = false,
			jointBreakerEveryN = 3,
			jointBreakerDecayAmount = 10f,
			rotThread = false,
			rotThreadEveryN = 3,
			rotThreadRotAmount = 10f,
			faultLine = false,
			faultLineBonusPerHit = 0.08f,
			faultLineMaxBonus = 0.5f,
			faultLineResetTime = 2.5f,
			reactorTap = false,
			reactorTapCharge = 4f,
			reactorTapAmmoOnExposed = 2,
			coreBrand = false,
			coreBrandMaxStacks = 5,
			coreBrandExposeDuration = 3.5f,
			phantomPain = false,
			phantomPainDamageMult = 1.35f,
			phantomPainChargeRefund = 2f,
			bleedCharge = false,
			bleedChargeAmount = 1f,
			breachCharge = false,
			breachChargeAmount = 1f,
			markedRecycling = false,
			markedRecyclingAmmoPerHit = 0.35f,
			elementalEmitter = false,
			elementalLaserEffect = (EffectType)0,
			elementalLaserAmount = 0f,
			sympatheticArc = false,
			arcRadius = 8f,
			arcDamageScale = 0.45f,
			arcMaxJumps = 3,
			arcTransferScale = 0.35f,
			sympatheticResonance = false,
			resonanceEchoScale = 0.2f,
			collapseWave = false,
			collapseRadius = 5f,
			collapseHpScale = 0.15f,
			collapseEffect = (EffectType)2,
			voltaicBatteryV2 = false,
			batteryFuseTime = 2.5f,
			batteryBaseDamage = 40f,
			batteryEmptyMagBonus = 1.5f,
			batteryTransferPercent = 0.35f,
			batteryRadius = 3.5f,
			demoTrickV2 = false,
			demoMarkSpreadRadius = 6f,
			demoHeavyMarkDuration = 5f,
			demoHeavyMarkDamageMult = 1.35f,
			breachAmmoSystem = false,
			breachAmmoMax = 100f,
			breachAmmoPerLaserHit = 4f,
			breachAmmoPerLaserTick = 2.5f,
			breachSlugCost = 20f,
			breachSlugDamageMult = 1.75f,
			breachSlugShellMult = 1.35f,
			breachBreakTransferBonus = 0.25f,
			severanceCycle = false,
			cycleInterval = 4f,
			cycleLaserWindow = 2f,
			dissectionStacksPerLimbHit = 1,
			dissectionStacksToPulse = 4,
			dissectionPulseTransferPercent = 0.35f,
			dissectionPulseDamageScale = 1f
		};
	}

	public void InitializeAsPrefab(string desc)
	{
		description = desc ?? "A dual-mode marksman rifle that reads enemy anatomy. Automatic DMR tags and cracks parts; hold aim to discharge the laser. Upgrades unlock Mark, Expose, and Transfer payoffs.";
		data = CreateDefaultData();
		prefabSnapshot = data;
		ResetRuntimeState();
	}

	public void RestoreFromPrefab()
	{
		data = prefabSnapshot;
		ResetRuntimeState();
	}

	public void CapturePrefabSnapshot()
	{
		prefabSnapshot = data;
	}

	public void CopySnapshotFrom(DmlrReworkBehaviour template)
	{
		if (!((Object)(object)template == (Object)null))
		{
			prefabSnapshot = template.prefabSnapshot;
			data = prefabSnapshot;
			description = template.description;
			ResetRuntimeState();
		}
	}

	public void ResetRuntimeState()
	{
		//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_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		forcingSecondaryFire = false;
		wantLaserMode = false;
		dmrShotCounter = 0;
		limbHitCounter = 0;
		shellHitCounter = 0;
		faultLinePartId = 0;
		faultLineStacks = 0;
		faultLineLastHitTime = 0f;
		brandStacks?.Clear();
		phantomKilledLimbIds?.Clear();
		phantomKilledLimbKeys?.Clear();
		laserBeamAirTime = 0f;
		shredderTimer = 0f;
		shredderDecayActive = false;
		lastFiredMode = -1;
		demoBuffRemaining = 0f;
		demoPendingEmpower = 0;
		batteryThrowPending = false;
		batteryPowerMult = 1f;
		lastBatteryThrowTime = 0f;
		breachAmmo = 0f;
		breachSlugArmed = false;
		cycleTimer = 0f;
		cycleLaserPhase = false;
		dissectionStacks = 0;
		lastLimbBrainId = 0;
		lastLimbHitPos = Vector3.zero;
		incendiaryTimer = 0f;
		lastGravPullTime = 0f;
		pendingCondensedPierces = 0;
		pendingCondensedAmmoSpent = 0f;
		markExpiries?.Clear();
		exposeExpiries?.Clear();
		openArteryBrainId = 0;
		openArteryExpiry = 0f;
		pendingOverkillPartId = 0;
		pendingOverkillAmount = 0f;
		pendingOverkillTime = 0f;
		isApplyingTransfer = false;
		drillFocusBrainId = 0;
		drillFocusPartId = 0;
		drillFocusLastPos = Vector3.zero;
		drillFocusDepth = 0;
	}

	public Dictionary<int, float> EnsureMarkMap()
	{
		return markExpiries ?? (markExpiries = new Dictionary<int, float>(16));
	}

	public Dictionary<int, float> EnsureExposeMap()
	{
		return exposeExpiries ?? (exposeExpiries = new Dictionary<int, float>(8));
	}

	public Dictionary<int, int> EnsureBrandMap()
	{
		return brandStacks ?? (brandStacks = new Dictionary<int, int>(8));
	}

	public HashSet<int> EnsurePhantomLimbIds()
	{
		return phantomKilledLimbIds ?? (phantomKilledLimbIds = new HashSet<int>());
	}

	public HashSet<string> EnsurePhantomLimbKeys()
	{
		return phantomKilledLimbKeys ?? (phantomKilledLimbKeys = new HashSet<string>());
	}

	public static string PhantomLimbKey(EnemyPart limb)
	{
		if ((Object)(object)limb == (Object)null)
		{
			return null;
		}
		EnemyBrain brain = limb.Brain;
		int num = (((Object)(object)brain != (Object)null) ? ((Object)brain).GetInstanceID() : 0);
		string text = ((Object)limb).name ?? ((object)limb).GetType().Name;
		int num2 = text.IndexOf('(');
		if (num2 > 0)
		{
			text = text.Substring(0, num2).Trim();
		}
		return num + ":" + text;
	}

	public bool IsPhantomRegrownLimb(EnemyPart limb)
	{
		if ((Object)(object)limb == (Object)null)
		{
			return false;
		}
		int partId = SeveranceSystem.GetPartId(limb);
		if (partId != 0 && phantomKilledLimbIds != null && phantomKilledLimbIds.Contains(partId))
		{
			return true;
		}
		string text = PhantomLimbKey(limb);
		if (text != null && phantomKilledLimbKeys != null)
		{
			return phantomKilledLimbKeys.Contains(text);
		}
		return false;
	}

	public void RecordPhantomLimbKill(EnemyPart limb)
	{
		if (!((Object)(object)limb == (Object)null))
		{
			int partId = SeveranceSystem.GetPartId(limb);
			if (partId != 0)
			{
				EnsurePhantomLimbIds().Add(partId);
			}
			string text = PhantomLimbKey(limb);
			if (!string.IsNullOrEmpty(text))
			{
				EnsurePhantomLimbKeys().Add(text);
			}
		}
	}

	public bool NeedsSeveranceHooks()
	{
		ref Data reference = ref data;
		if (!reference.transferFromLimbs && !(reference.transferDmrPercent > 0f) && !(reference.transferLaserPercent > 0f) && !reference.arterialShred && !reference.overkillConduit && !reference.hardLightDesignator && !reference.pulverizer && Mathf.Approximately(reference.limbDamageMult, 1f) && Mathf.Approximately(reference.shellDamageMult, 1f) && !(reference.shellInwardSplashPercent > 0f) && !(reference.exposeDamageMult > 1.001f) && !reference.markOnDmrHit && !reference.jointBreaker && !reference.rotThread && !reference.faultLine && !reference.reactorTap && !reference.coreBrand && !reference.phantomPain && !reference.bleedCharge && !reference.breachCharge && !reference.markedRecycling && !reference.elementalEmitter && !reference.sympatheticArc && !reference.sympatheticResonance && !reference.collapseWave && !reference.voltaicBatteryV2 && !reference.demoTrickV2 && !reference.breachAmmoSystem)
		{
			return reference.severanceCycle;
		}
		return true;
	}

	public static bool TryGet(IGear gear, out DmlrReworkBehaviour behaviour)
	{
		behaviour = null;
		if ((Object)(object)((gear != null) ? gear.gameObject : null) == (Object)null)
		{
			return false;
		}
		behaviour = gear.gameObject.GetComponent<DmlrReworkBehaviour>();
		if ((Object)(object)behaviour != (Object)null)
		{
			return true;
		}
		bool num = SparrohPlugin.IsOurGear((IUpgradable)(object)gear);
		DmlrReworkBehaviour dmlrReworkBehaviour = null;
		IUpgradable prefab = ((IUpgradable)gear).Prefab;
		Component val = (Component)(object)((prefab is Component) ? prefab : null);
		if (val != null)
		{
			dmlrReworkBehaviour = val.GetComponent<DmlrReworkBehaviour>();
		}
		if (!num && (Object)(object)dmlrReworkBehaviour == (Object)null)
		{
			return false;
		}
		string desc = (((Object)(object)dmlrReworkBehaviour != (Object)null) ? dmlrReworkBehaviour.Description : "A dual-mode marksman rifle that reads enemy anatomy. Automatic DMR tags and cracks parts; hold aim to discharge the laser. Upgrades unlock Mark, Expose, and Transfer payoffs.");
		behaviour = gear.gameObject.AddComponent<DmlrReworkBehaviour>();
		behaviour.InitializeAsPrefab(desc);
		if ((Object)(object)dmlrReworkBehaviour != (Object)null)
		{
			behaviour.data = dmlrReworkBehaviour.prefabSnapshot;
		}
		behaviour.CapturePrefabSnapshot();
		return true;
	}
}
[HarmonyPatch]
internal static class DmlrReworkPatches
{
	[CompilerGenerated]
	private static class <>O
	{
		public static KillCallback <0>__OnMlrKillTarget;

		public static MutableDamageCallback <1>__OnMlrBeforeDamage;

		public static DamageCallback <2>__OnMlrDamageTarget;
	}

	private static readonly FieldInfo IsFireInputHeldField = AccessTools.Field(typeof(Gun), "isFireInputHeld");

	private static readonly FieldInfo ForceEnableFireField = AccessTools.Field(typeof(Gun), "forceEnableFire");

	private static readonly FieldInfo ToggleLaserOnUpgradesEnabledField = AccessTools.Field(typeof(ScoutLaserRifle), "toggleLaserOnUpgradesEnabled");

	private static readonly FieldInfo DmrAutomaticField = AccessTools.Field(typeof(ScoutLaserRifle), "dmrAutomatic");

	private static readonly FieldInfo IsMovementLockedField = AccessTools.Field(typeof(ScoutLaserRifle), "isMovementLocked");

	private static readonly FieldInfo AmmoRefilledFromLaserField = AccessTools.Field(typeof(ScoutLaserRifle), "ammoRefilledFromLaserDamage");

	private static readonly FieldInfo OnModeChangedField = AccessTools.Field(typeof(ScoutLaserRifle), "OnModeChanged");

	private static readonly MethodInfo StopFiringMethod = AccessTools.Method(typeof(Gun), "StopFiring", (Type[])null, (Type[])null);

	private static readonly MethodInfo OnStopAimMethod = AccessTools.Method(typeof(Gun), "OnStopAim", (Type[])null, (Type[])null);

	private static readonly PropertyInfo IsAimingProperty = AccessTools.Property(typeof(Gun), "IsAiming");

	[HarmonyPatch(typeof(Gun), "Update")]
	[HarmonyPrefix]
	private static void GunUpdate_Prefix(Gun __instance)
	{
		ScoutLaserRifle val = (ScoutLaserRifle)(object)((__instance is ScoutLaserRifle) ? __instance : null);
		if (val != null && ((NetworkBehaviour)val).IsOwner && ((Gun)val).Active && SparrohPlugin.IsOurGear((IUpgradable)(object)val))
		{
			TickDualModeInput(val);
		}
	}

	private static void TickDualModeInput(ScoutLaserRifle scout)
	{
		//IL_005c: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!DmlrReworkBehaviour.TryGet((IGear)(object)scout, out var behaviour))
		{
			return;
		}
		bool flag = false;
		bool flag2 = false;
		try
		{
			if (PlayerInput.Controls != null)
			{
				PlayerActions player = PlayerInput.Controls.Player;
				flag = ((PlayerActions)(ref player)).Fire.IsPressed();
				player = PlayerInput.Controls.Player;
				flag2 = ((PlayerActions)(ref player)).Aim.IsPressed();
			}
		}
		catch
		{
			flag = GetBool(IsFireInputHeldField, scout);
			flag2 = false;
		}
		bool flag3 = UpgradeFlagsExtensions.IsEnabled(((Gun)scout).UpgradeFlags, (DMLRUpgradeFlags)8);
		float laserCharge = scout.LaserCharge;
		float num = 0f;
		try
		{
			num = ((Gun)scout).RemainingAmmo;
		}
		catch
		{
			num = 0f;
		}
		bool flag4;
		bool flag5;
		if (!flag3)
		{
			if (flag2 && laserCharge > 0f)
			{
				flag4 = true;
				flag5 = true;
			}
			else
			{
				flag4 = false;
				flag5 = flag;
			}
		}
		else if (!flag && !flag2)
		{
			flag4 = false;
			flag5 = false;
		}
		else if (flag2)
		{
			flag4 = false;
			flag5 = num > 0f;
		}
		else if (flag && laserCharge > 0f)
		{
			flag4 = true;
			flag5 = true;
		}
		else
		{
			flag4 = false;
			flag5 = false;
		}
		if (flag4 && !scout.IsLaserModeActive)
		{
			float minLaserChargeNonNormalized = ((LaserGunData)(ref scout.LaserData)).MinLaserChargeNonNormalized;
			if (minLaserChargeNonNormalized > 0f && laserCharge < minLaserChargeNonNormalized)
			{
				flag4 = false;
				flag5 = !flag3 && flag;
			}
		}
		if (flag4 && laserCharge <= 0f)
		{
			flag4 = false;
			flag5 = !flag3 && flag;
		}
		if (flag3 && flag4 && !flag)
		{
			flag4 = false;
			flag5 = false;
		}
		behaviour.wantLaserMode = flag4;
		if (scout.IsLaserModeActive != flag4)
		{
			SetLaserMode(scout, flag4);
		}
		bool flag6 = flag5 && !flag;
		if (flag3 && num <= 0f && !flag)
		{
			flag6 = false;
		}
		behaviour.forcingSecondaryFire = flag6;
		SetBool(ForceEnableFireField, scout, flag6);
		if (flag3 && !flag4)
		{
			if (scout.IsLaserModeActive)
			{
				SetLaserMode(scout, laser: false);
			}
			if (!flag6)
			{
				SetBool(ForceEnableFireField, scout, value: false);
			}
		}
	}

	private static void SetLaserMode(ScoutLaserRifle scout, bool laser)
	{
		if (scout.IsLaserModeActive == laser)
		{
			return;
		}
		if (((Gun)scout).IsFiring)
		{
			try
			{
				StopFiringMethod?.Invoke(scout, null);
			}
			catch
			{
			}
		}
		scout.IsLaserModeActive = laser;
		if (!laser)
		{
			if (AmmoRefilledFromLaserField != null)
			{
				AmmoRefilledFromLaserField.SetValue(scout, 0f);
			}
			if (IsMovementLockedField != null && GetBool(IsMovementLockedField, scout))
			{
				IsMovementLockedField.SetValue(scout, false);
				if ((Object)(object)((Gun)scout).Player != (Object)null)
				{
					Player player = ((Gun)scout).Player;
					int movementControlLocks = player.MovementControlLocks;
					player.MovementControlLocks = movementControlLocks - 1;
				}
			}
		}
		try
		{
			if (OnModeChangedField?.GetValue(scout) is Action<bool> action)
			{
				action(laser);
			}
		}
		catch
		{
		}
	}

	[HarmonyPatch(typeof(Gun), "HandleAim")]
	[HarmonyPrefix]
	private static bool HandleAim_Prefix(Gun __instance)
	{
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance))
		{
			return true;
		}
		if (__instance.IsAiming)
		{
			try
			{
				IsAimingProperty?.SetValue(__instance, false);
				OnStopAimMethod?.Invoke(__instance, null);
			}
			catch
			{
			}
		}
		return false;
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "OverrideHoldReload")]
	[HarmonyPrefix]
	private static bool OverrideHoldReload_Prefix(ScoutLaserRifle __instance, ref bool __result)
	{
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance))
		{
			return true;
		}
		__result = false;
		return false;
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "AfterUpgradesEnabled")]
	[HarmonyPrefix]
	private static void AfterUpgradesEnabled_Prefix(ScoutLaserRifle __instance)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		if (SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) && UpgradeFlagsExtensions.IsEnabled(((Gun)__instance).UpgradeFlags, (DMLRUpgradeFlags)8) && !(ToggleLaserOnUpgradesEnabledField == null))
		{
			ToggleLaserOnUpgradesEnabledField.SetValue(__instance, false);
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "AfterUpgradesEnabled")]
	[HarmonyPostfix]
	private static void AfterUpgradesEnabled_Postfix(ScoutLaserRifle __instance)
	{
		if (SparrohPlugin.IsOurGear((IUpgradable)(object)__instance))
		{
			((Gun)__instance).IsAimEnabled = false;
			int num = 1;
			if (DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour) && behaviour.WeaponData.condensedMunitions)
			{
				num = 0;
			}
			if (DmrAutomaticField != null)
			{
				DmrAutomaticField.SetValue(__instance, num);
			}
			if (!__instance.IsLaserModeActive)
			{
				((Gun)__instance).GunData.automatic = num;
			}
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "OnUpgradesEnabled")]
	[HarmonyPrefix]
	private static void OnUpgradesEnabled_Prefix(ScoutLaserRifle __instance)
	{
		if (SparrohPlugin.IsOurGear((IUpgradable)(object)__instance))
		{
			((Gun)__instance).IsAimEnabled = false;
			if (!__instance.IsLaserModeActive)
			{
				((Gun)__instance).GunData.automatic = 1;
			}
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "ModifyBulletData")]
	[HarmonyPostfix]
	private static void ModifyBulletData_Postfix(ScoutLaserRifle __instance, ref BulletData data, BulletFlags flags)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Invalid comparison between Unknown and I4
		//IL_005c: 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_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Invalid comparison between Unknown and I4
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) || !DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return;
		}
		ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
		if (weaponData.reverseFalloff && weaponData.reverseFalloffMaxMult > 1f)
		{
			ApplyReverseFalloff(ref data.range, weaponData.reverseFalloffMaxMult);
		}
		if (__instance.IsLaserModeActive)
		{
			if (weaponData.elementalEmitter && (int)weaponData.elementalLaserEffect > 0)
			{
				data.damageEffect = weaponData.elementalLaserEffect;
				if (weaponData.elementalLaserAmount > 0f)
				{
					data.damageEffectAmount = Mathf.Max(data.damageEffectAmount, weaponData.elementalLaserAmount);
				}
			}
			return;
		}
		if (weaponData.demonstratorsTrick)
		{
			NotifyModeFired(behaviour, modeLaser: false);
		}
		if (weaponData.condensedMunitions)
		{
			ApplyCondensedMunitions(__instance, ref data, ref weaponData);
		}
		bool voltaicBattery = weaponData.voltaicBattery;
		bool flag = false;
		if (voltaicBattery)
		{
			behaviour.dmrShotCounter++;
			flag = behaviour.dmrShotCounter % 3 == 0;
		}
		if (weaponData.voltaicBattery && flag && weaponData.voltaicLaserDamageFraction > 0f)
		{
			float damage = __instance.LaserData.laserDamage.damage;
			if (damage > 0f)
			{
				data.damage += damage * weaponData.voltaicLaserDamageFraction;
			}
		}
		if (weaponData.tripleElement && (int)weaponData.tripleEffect > 0)
		{
			data.damageEffect = weaponData.tripleEffect;
			if (weaponData.tripleEffectAmount > 0f)
			{
				data.damageEffectAmount = Mathf.Max(data.damageEffectAmount, weaponData.tripleEffectAmount);
			}
		}
		if (weaponData.breachAmmoSystem && behaviour.breachAmmo >= weaponData.breachSlugCost)
		{
			behaviour.breachAmmo = Mathf.Max(0f, behaviour.breachAmmo - weaponData.breachSlugCost);
			behaviour.breachSlugArmed = true;
			float num = Mathf.Max(1f, weaponData.breachSlugDamageMult);
			data.damage *= num;
			data.damageEffectAmount *= num;
		}
		else
		{
			behaviour.breachSlugArmed = false;
		}
		if (weaponData.demonstratorsTrick && behaviour.demoBuffRemaining > 0f && weaponData.demoBuffDamageMult > 1f)
		{
			data.damage *= weaponData.demoBuffDamageMult;
		}
	}

	private static void ApplyReverseFalloff(ref RangeData range, float maxMult)
	{
		range.falloffStartDistance = 5f;
		range.falloffEndDistance = 55f;
		range.maxFalloffDamageMultiplier = maxMult;
		if (range.maxDamageRange < range.falloffEndDistance + 10f)
		{
			range.maxDamageRange = range.falloffEndDistance + 10f;
		}
	}

	private static void ApplyCondensedMunitions(ScoutLaserRifle scout, ref BulletData data, ref DmlrReworkBehaviour.Data wd)
	{
		if (DmlrReworkBehaviour.TryGet((IGear)(object)scout, out var behaviour))
		{
			float num = ((Gun)scout).RemainingAmmo;
			if (num < 1f)
			{
				num = 1f;
			}
			try
			{
				((Gun)scout).RemainingAmmo = 0f;
			}
			catch
			{
			}
			data.damage *= 1f + (num - 1f) * Mathf.Max(0.05f, wd.condensedDamagePerAmmo);
			int pendingCondensedPierces = 1 + Mathf.FloorToInt(num / 10f);
			behaviour.pendingCondensedPierces = pendingCondensedPierces;
			behaviour.pendingCondensedAmmoSpent = num;
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "OnFiredBullet")]
	[HarmonyPostfix]
	private static void OnFiredBullet_CondensedPierce(ScoutLaserRifle __instance, IBullet bullet, BulletFlags flags, int shotIndex, ref BulletData bulletData)
	{
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) || __instance.IsLaserModeActive || !DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour) || !behaviour.WeaponData.condensedMunitions)
		{
			return;
		}
		RailBullet val = (RailBullet)(object)((bullet is RailBullet) ? bullet : null);
		if (val != null)
		{
			int num = behaviour.pendingCondensedPierces;
			float num2 = behaviour.pendingCondensedAmmoSpent;
			behaviour.pendingCondensedPierces = 0;
			behaviour.pendingCondensedAmmoSpent = 0f;
			if (num < 1)
			{
				num = 1;
			}
			if (num2 < 1f)
			{
				num2 = 1f;
			}
			val.PierceTargets = true;
			CondensedPierceTracker condensedPierceTracker = ((Component)val).gameObject.GetComponent<CondensedPierceTracker>();
			if ((Object)(object)condensedPierceTracker == (Object)null)
			{
				condensedPierceTracker = ((Component)val).gameObject.AddComponent<CondensedPierceTracker>();
			}
			((Behaviour)condensedPierceTracker).enabled = true;
			condensedPierceTracker.maxPierces = num;
			condensedPierceTracker.piercedCount = 0;
			condensedPierceTracker.ammoSpent = num2;
			condensedPierceTracker.chargeGranted = false;
		}
	}

	[HarmonyPatch(typeof(RailBullet), "DamageTarget")]
	[HarmonyPrefix]
	private static bool RailBullet_DamageTarget_CondensedPierce(RailBullet __instance, ITarget target, DamageData damageData, Vector3 position, Collider collider, bool directHit, ref bool __result)
	{
		CondensedPierceTracker component = ((Component)__instance).GetComponent<CondensedPierceTracker>();
		if ((Object)(object)component == (Object)null || !((Behaviour)component).enabled || component.maxPierces <= 0)
		{
			return true;
		}
		if (!component.CanPierceMore)
		{
			__result = false;
			__instance.PierceTargets = false;
			return false;
		}
		component.RegisterHit();
		if (!component.CanPierceMore)
		{
			__instance.PierceTargets = false;
		}
		return true;
	}

	[HarmonyPatch(typeof(RailBullet), "Kill")]
	[HarmonyPrefix]
	private static void RailBullet_Kill_ClearTracker(RailBullet __instance)
	{
		CondensedPierceTracker component = ((Component)__instance).GetComponent<CondensedPierceTracker>();
		if (!((Object)(object)component == (Object)null))
		{
			component.ResetState();
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "OnTargetDamaged")]
	[HarmonyPostfix]
	private static void OnTargetDamaged_CondensedCharge(ScoutLaserRifle __instance, in DamageCallbackData data)
	{
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) || __instance.IsLaserModeActive || data.damageData.damage <= 0f)
		{
			return;
		}
		IDamageSource source = data.source;
		RailBullet val = (RailBullet)(object)((source is RailBullet) ? source : null);
		if (val == null)
		{
			return;
		}
		CondensedPierceTracker component = ((Component)val).GetComponent<CondensedPierceTracker>();
		if ((Object)(object)component == (Object)null || !((Behaviour)component).enabled || component.chargeGranted)
		{
			return;
		}
		if (component.ammoSpent <= 1.01f)
		{
			component.chargeGranted = true;
			return;
		}
		component.chargeGranted = true;
		float num = __instance.LaserData.laserChargeOnHit * (component.ammoSpent - 1f);
		if (num > 0f)
		{
			__instance.LaserCharge += num;
		}
	}

	private static void NotifyModeFired(DmlrReworkBehaviour b, bool modeLaser)
	{
		if (b.WeaponData.demonstratorsTrick)
		{
			int num = (modeLaser ? 1 : 0);
			if (b.lastFiredMode >= 0 && b.lastFiredMode != num)
			{
				b.demoBuffRemaining = b.WeaponData.demoBuffDuration;
			}
			b.lastFiredMode = num;
		}
	}

	[HarmonyPatch(typeof(Gun), "Update")]
	[HarmonyPostfix]
	private static void GunUpdate_Postfix_LaserEffects(Gun __instance)
	{
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		ScoutLaserRifle val = (ScoutLaserRifle)(object)((__instance is ScoutLaserRifle) ? __instance : null);
		if (val == null || !((NetworkBehaviour)val).IsOwner || !((Gun)val).Active || !SparrohPlugin.IsOurGear((IUpgradable)(object)val) || !DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour))
		{
			return;
		}
		ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
		float deltaTime = Time.deltaTime;
		if (behaviour.demoBuffRemaining > 0f)
		{
			behaviour.demoBuffRemaining = Mathf.Max(0f, behaviour.demoBuffRemaining - deltaTime);
		}
		bool flag = val.IsLaserModeActive && (((Gun)val).IsFiring || ((Gun)val).WantsToFire || behaviour.wantLaserMode || behaviour.forcingSecondaryFire || GetBool(IsFireInputHeldField, val));
		if (weaponData.overheatedCapacitor)
		{
			if (flag)
			{
				behaviour.laserBeamAirTime += deltaTime;
			}
			else
			{
				behaviour.laserBeamAirTime = 0f;
			}
		}
		else
		{
			behaviour.laserBeamAirTime = 0f;
		}
		if (weaponData.shredder && flag)
		{
			behaviour.shredderTimer += deltaTime;
			float num = Mathf.Max(0.4f, weaponData.shredderInterval);
			float num2 = behaviour.shredderTimer % num;
			behaviour.shredderDecayActive = num2 < num * 0.35f;
		}
		else
		{
			behaviour.shredderTimer = 0f;
			behaviour.shredderDecayActive = false;
		}
		if (weaponData.gravitationalCollapse && flag && UpgradeFlagsExtensions.IsEnabled(((Gun)val).UpgradeFlags, (DMLRUpgradeFlags)64))
		{
			TickGravitationalPull(val, ref weaponData);
		}
		if (weaponData.incendiaryWave && flag)
		{
			behaviour.incendiaryTimer += deltaTime;
			float num3 = Mathf.Max(0.35f, weaponData.incendiaryInterval);
			if (behaviour.incendiaryTimer >= num3)
			{
				behaviour.incendiaryTimer = 0f;
				FireIncendiaryWave(val, ref weaponData);
			}
		}
		else if (!flag)
		{
			behaviour.incendiaryTimer = 0f;
		}
		if (weaponData.severanceCycle)
		{
			TickSeveranceCycle(val, behaviour, ref weaponData, deltaTime);
		}
	}

	private static void TickSeveranceCycle(ScoutLaserRifle scout, DmlrReworkBehaviour b, ref DmlrReworkBehaviour.Data wd, float dt)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Max(1.5f, wd.cycleInterval);
		float num2 = Mathf.Clamp(wd.cycleLaserWindow, 0.5f, num - 0.25f);
		b.cycleTimer += dt;
		bool flag = b.cycleTimer % num < num2;
		if (flag != b.cycleLaserPhase)
		{
			if (b.dissectionStacks >= Mathf.Max(1, wd.dissectionStacksToPulse))
			{
				FireDissectionPulse(scout, b, ref wd);
			}
			b.cycleLaserPhase = flag;
		}
		bool flag2 = false;
		bool flag3 = false;
		try
		{
			if (PlayerInput.Controls != null)
			{
				PlayerActions player = PlayerInput.Controls.Player;
				flag2 = ((PlayerActions)(ref player)).Fire.IsPressed();
				player = PlayerInput.Controls.Player;
				flag3 = ((PlayerActions)(ref player)).Aim.IsPressed();
			}
		}
		catch
		{
		}
		if (!flag2 && !flag3 && scout.IsLaserModeActive != b.cycleLaserPhase && (!b.cycleLaserPhase || !(scout.LaserCharge <= 0f)))
		{
			SetLaserMode(scout, b.cycleLaserPhase);
		}
	}

	private unsafe static void FireDissectionPulse(ScoutLaserRifle scout, DmlrReworkBehaviour b, ref DmlrReworkBehaviour.Data wd)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_0123: Unknown result type (might be due to invalid IL or missing references)
		int num = Mathf.Max(1, wd.dissectionStacksToPulse);
		if (b.dissectionStacks < num)
		{
			return;
		}
		b.dissectionStacks = 0;
		if (b.lastLimbBrainId == 0)
		{
			return;
		}
		try
		{
			Vector3 val = b.lastLimbHitPos;
			if (val == Vector3.zero)
			{
				val = ((Component)scout).transform.position;
			}
			TargetEnumerator val2 = default(TargetEnumerator);
			try
			{
				if (!((TargetEnumerator)(ref val2)).GetTargetsInSphere(val, 12f, 345224, (TargetType)5))
				{
					return;
				}
				EnemyPart val3 = null;
				while (((TargetEnumerator)(ref val2)).MoveNext())
				{
					ITarget current = ((TargetEnumerator)(ref val2)).Current;
					EnemyPart val4 = (EnemyPart)(object)((current is EnemyPart) ? current : null);
					if (val4 != null && val4.IsAlive && !((Object)(object)val4.Brain == (Object)null) && ((Object)val4.Brain).GetInstanceID() == b.lastLimbBrainId)
					{
						val3 = val4;
						break;
					}
				}
				if ((Object)(object)val3 == (Object)null)
				{
					return;
				}
				float num2 = ((Gun)scout).GunData.damage * Mathf.Max(0.5f, wd.dissectionPulseDamageScale);
				float num3 = Mathf.Max(0.1f, wd.dissectionPulseTransferPercent);
				EnemyPart val5 = SeveranceSystem.FindTransferDestination(val3, b);
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = val3;
				}
				b.isApplyingTransfer = true;
				try
				{
					SeveranceSystem.DealTransferDamage((IDamageSource)(object)scout, val5, num2 * num3, (EffectType)0, 0f, val, val3);
				}
				finally
				{
					b.isApplyingTransfer = false;
				}
			}
			finally
			{
				((IDisposable)(*(TargetEnumerator*)(&val2))/*cast due to .constrained prefix*/).Dispose();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[Severance] DissectionPulse: " + ex.Message));
			}
		}
	}

	private unsafe static void TickGravitationalPull(ScoutLaserRifle scout, ref DmlrReworkBehaviour.Data wd)
	{
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: 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)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Invalid comparison between Unknown and I4
		//IL_00ae: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: 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_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!DmlrReworkBehaviour.TryGet((IGear)(object)scout, out var behaviour))
			{
				return;
			}
			float time = Time.time;
			if (time - behaviour.lastGravPullTime < 0.18f)
			{
				return;
			}
			behaviour.lastGravPullTime = time;
			Vector3 position = ((Component)scout).transform.position;
			Vector3 forward = ((Component)scout).transform.forward;
			try
			{
				if ((Object)(object)((Gun)scout).Player?.playerLook != (Object)null)
				{
					forward = ((Component)((Gun)scout).Player.playerLook).transform.forward;
					position = ((Component)((Gun)scout).Player.playerLook).transform.position;
				}
				else if ((Object)(object)((Gun)scout).GunData.firePoint != (Object)null)
				{
					position = ((Gun)scout).GunData.firePoint.position;
				}
			}
			catch
			{
			}
			float num = Mathf.Max(20f, scout.LaserData.laserRangeData.maxDamageRange);
			float num2 = Mathf.Max(1f, wd.gravPullRadius);
			Vector3 val = position + forward * Mathf.Min(num, 35f);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(position, forward, ref val2, num, -1, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val2)).point;
			}
			float num3 = Mathf.Max(1f, wd.gravPullForce);
			TargetEnumerator val3 = default(TargetEnumerator);
			try
			{
				HashSet<EnemyBrain> hashSet = CollectionPool<HashSet<EnemyBrain>, EnemyBrain>.Get();
				try
				{
					if (!((TargetEnumerator)(ref val3)).GetTargetsInSphere(val, num2, 345216, (TargetType)5))
					{
						return;
					}
					while (((TargetEnumerator)(ref val3)).MoveNext())
					{
						ITarget current = ((TargetEnumerator)(ref val3)).Current;
						if (current == null || current is Player)
						{
							continue;
						}
						IPullable val4 = null;
						EnemyPart val5 = (EnemyPart)(object)((current is EnemyPart) ? current : null);
						if (val5 != null)
						{
							EnemyBrain brain = val5.Brain;
							if ((Object)(object)brain != (Object)null)
							{
								if ((int)brain.EnemyType >= 2 || !hashSet.Add(brain))
								{
									continue;
								}
								val4 = (IPullable)(object)brain;
								goto IL_01b8;
							}
						}
						val4 = (IPullable)(object)((current is IPullable) ? current : null);
						goto IL_01b8;
						IL_01b8:
						if (val4 == null)
						{
							continue;
						}
						Vector3 position2 = val4.transform.position;
						Vector3 val6 = val - position2;
						float magnitude = ((Vector3)(ref val6)).magnitude;
						if (!(magnitude < 0.05f) && !(magnitude > num2))
						{
							float num4 = num3 * (1f - magnitude / num2);
							Vector3 val7 = ((Vector3)(ref val6)).normalized * num4;
							try
							{
								val4.AddImpulseForce_Client(val7);
							}
							catch
							{
							}
						}
					}
				}
				finally
				{
					CollectionPool<HashSet<EnemyBrain>, EnemyBrain>.Release(hashSet);
				}
			}
			finally
			{
				((IDisposable)(*(TargetEnumerator*)(&val3))/*cast due to .constrained prefix*/).Dispose();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[DMLRRework] Grav pull: " + ex.Message));
			}
		}
	}

	private static void FireIncendiaryWave(ScoutLaserRifle scout, ref DmlrReworkBehaviour.Data wd)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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_0017: 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_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Vector3 position = ((Component)scout).transform.position;
			Vector3 forward = ((Component)scout).transform.forward;
			try
			{
				if ((Object)(object)((Gun)scout).GunData.firePoint != (Object)null)
				{
					position = ((Gun)scout).GunData.firePoint.position;
				}
				if ((Object)(object)((Gun)scout).Player?.playerLook != (Object)null)
				{
					forward = ((Component)((Gun)scout).Player.playerLook).transform.forward;
				}
			}
			catch
			{
			}
			float num = Mathf.Max(15f, scout.LaserData.laserRangeData.maxDamageRange);
			float num2 = Mathf.Max(0.75f, wd.incendiaryRadius);
			float num3 = Mathf.Max(1f, num2 * 0.85f);
			float num4 = scout.LaserData.laserDamage.damage * Mathf.Max(0.1f, wd.incendiaryDamageScale);
			float num5 = Mathf.Max(1f, wd.incendiaryEffectAmount);
			DamageData val = default(DamageData);
			((DamageData)(ref val))..ctor(num4, (EffectType)1, num5, (DamageFlags)16);
			for (float num6 = num3; num6 <= num; num6 += num3)
			{
				Vector3 val2 = position + forward * num6;
				try
				{
					IDamageSource.DamageTargetsInSphere((IDamageSource)(object)scout, ref val2, num2, (TargetType)5, ref val, 0f, 1f);
				}
				catch
				{
					break;
				}
			}
			try
			{
				Vector3 val3 = position + forward * (num * 0.35f);
				GameManager instance = GameManager.Instance;
				if (instance != null)
				{
					instance.SpawnExplosionVisual_ServerRpc(val3, num2 * 1.5f, (EffectType)1);
				}
			}
			catch
			{
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[DMLRRework] Incendiary wave: " + ex.Message));
			}
		}
	}

	[HarmonyPatch(typeof(Gun), "ModifyContinuousBulletDamage")]
	[HarmonyPostfix]
	private static void ModifyContinuousBulletDamage_Postfix(Gun __instance, ref DamageData damage, float dpsMultiplier, Vector3 endPos)
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Invalid comparison between Unknown and I4
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		ScoutLaserRifle val = (ScoutLaserRifle)(object)((__instance is ScoutLaserRifle) ? __instance : null);
		if (val == null || !SparrohPlugin.IsOurGear((IUpgradable)(object)val) || !val.IsLaserModeActive || !DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour))
		{
			return;
		}
		ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
		if (weaponData.demonstratorsTrick)
		{
			NotifyModeFired(behaviour, modeLaser: true);
		}
		if (weaponData.overheatedCapacitor)
		{
			if (behaviour.wantLaserMode || behaviour.forcingSecondaryFire || ((Gun)val).WantsToFire || ((Gun)val).IsFiring)
			{
				behaviour.laserBeamAirTime += Time.deltaTime;
			}
			float num = Mathf.Min(weaponData.overheatMaxBonus, behaviour.laserBeamAirTime * weaponData.overheatDamagePerSecond);
			if (num > 0f)
			{
				float num2 = 1f + num;
				damage.damage *= num2;
				damage.effectAmount *= num2;
			}
		}
		if (weaponData.shredder && behaviour.shredderDecayActive)
		{
			damage.effect = (EffectType)4;
			if (damage.effectAmount < 8f)
			{
				damage.effectAmount = 8f;
			}
		}
		if (weaponData.elementalEmitter && (int)weaponData.elementalLaserEffect > 0)
		{
			damage.effect = weaponData.elementalLaserEffect;
			if (weaponData.elementalLaserAmount > 0f)
			{
				damage.effectAmount = Mathf.Max(damage.effectAmount, weaponData.elementalLaserAmount);
			}
		}
		if (weaponData.breachAmmoSystem && weaponData.breachAmmoPerLaserTick > 0f)
		{
			behaviour.breachAmmo = Mathf.Min(weaponData.breachAmmoMax, behaviour.breachAmmo + weaponData.breachAmmoPerLaserTick * Time.deltaTime * 8f);
		}
		if (weaponData.severanceCycle && behaviour.cycleLaserPhase)
		{
			try
			{
				val.LaserCharge += val.LaserData.laserChargeUsePerSecond * Time.deltaTime;
			}
			catch
			{
			}
		}
		if (weaponData.demonstratorsTrick && behaviour.demoBuffRemaining > 0f && weaponData.demoBuffDamageMult > 1f)
		{
			damage.damage *= weaponData.demoBuffDamageMult;
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "AfterUpgradesEnabled")]
	[HarmonyPostfix]
	private static void AfterUpgradesEnabled_SeveranceHooks(ScoutLaserRifle __instance)
	{
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Expected O, but got Unknown
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Expected O, but got Unknown
		//IL_01e9: 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_0134: Expected O, but got Unknown
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Expected O, but got Unknown
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Expected O, but got Unknown
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Expected O, but got Unknown
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Expected O, but got Unknown
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Expected O, but got Unknown
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) || !DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return;
		}
		bool flag = behaviour.WeaponData.dmrKillExplosion || behaviour.WeaponData.overkillConduit || behaviour.WeaponData.hardLightDesignator || behaviour.WeaponData.reactorTap || behaviour.WeaponData.phantomPain || behaviour.WeaponData.collapseWave;
		bool flag2 = behaviour.NeedsSeveranceHooks();
		if ((flag || flag2) && !behaviour.killHookSubscribed)
		{
			KillCallback onKillTarget = ((Gun)__instance).OnKillTarget;
			object obj = <>O.<0>__OnMlrKillTarget;
			if (obj == null)
			{
				KillCallback val = OnMlrKillTarget;
				<>O.<0>__OnMlrKillTarget = val;
				obj = (object)val;
			}
			((Gun)__instance).OnKillTarget = (KillCallback)Delegate.Combine((Delegate?)(object)onKillTarget, (Delegate?)obj);
			behaviour.killHookSubscribed = true;
		}
		else if (!flag && !flag2 && behaviour.killHookSubscribed)
		{
			KillCallback onKillTarget2 = ((Gun)__instance).OnKillTarget;
			object obj2 = <>O.<0>__OnMlrKillTarget;
			if (obj2 == null)
			{
				KillCallback val2 = OnMlrKillTarget;
				<>O.<0>__OnMlrKillTarget = val2;
				obj2 = (object)val2;
			}
			((Gun)__instance).OnKillTarget = (KillCallback)Delegate.Remove((Delegate?)(object)onKillTarget2, (Delegate?)obj2);
			behaviour.killHookSubscribed = false;
		}
		if (flag2 && !behaviour.severanceHooksSubscribed)
		{
			MutableDamageCallback onBeforeDamage = ((Gun)__instance).OnBeforeDamage;
			object obj3 = <>O.<1>__OnMlrBeforeDamage;
			if (obj3 == null)
			{
				MutableDamageCallback val3 = OnMlrBeforeDamage;
				<>O.<1>__OnMlrBeforeDamage = val3;
				obj3 = (object)val3;
			}
			((Gun)__instance).OnBeforeDamage = (MutableDamageCallback)Delegate.Combine((Delegate?)(object)onBeforeDamage, (Delegate?)obj3);
			DamageCallback onDamageTarget = ((Gun)__instance).OnDamageTarget;
			object obj4 = <>O.<2>__OnMlrDamageTarget;
			if (obj4 == null)
			{
				DamageCallback val4 = OnMlrDamageTarget;
				<>O.<2>__OnMlrDamageTarget = val4;
				obj4 = (object)val4;
			}
			((Gun)__instance).OnDamageTarget = (DamageCallback)Delegate.Combine((Delegate?)(object)onDamageTarget, (Delegate?)obj4);
			behaviour.severanceHooksSubscribed = true;
		}
		else if (!flag2 && behaviour.severanceHooksSubscribed)
		{
			MutableDamageCallback onBeforeDamage2 = ((Gun)__instance).OnBeforeDamage;
			object obj5 = <>O.<1>__OnMlrBeforeDamage;
			if (obj5 == null)
			{
				MutableDamageCallback val5 = OnMlrBeforeDamage;
				<>O.<1>__OnMlrBeforeDamage = val5;
				obj5 = (object)val5;
			}
			((Gun)__instance).OnBeforeDamage = (MutableDamageCallback)Delegate.Remove((Delegate?)(object)onBeforeDamage2, (Delegate?)obj5);
			DamageCallback onDamageTarget2 = ((Gun)__instance).OnDamageTarget;
			object obj6 = <>O.<2>__OnMlrDamageTarget;
			if (obj6 == null)
			{
				DamageCallback val6 = OnMlrDamageTarget;
				<>O.<2>__OnMlrDamageTarget = val6;
				obj6 = (object)val6;
			}
			((Gun)__instance).OnDamageTarget = (DamageCallback)Delegate.Remove((Delegate?)(object)onDamageTarget2, (Delegate?)obj6);
			behaviour.severanceHooksSubscribed = false;
		}
		behaviour.WeaponData.hotSwapRoles = UpgradeFlagsExtensions.IsEnabled(((Gun)__instance).UpgradeFlags, (DMLRUpgradeFlags)8);
		StampWeaponElements(__instance, ref behaviour.WeaponData);
	}

	private static void StampWeaponElements(ScoutLaserRifle scout, ref DmlrReworkBehaviour.Data wd)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Invalid comparison between Unknown and I4
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_0039: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (wd.tripleElement && (int)wd.tripleEffect > 0)
			{
				GunData gunData = ((Gun)scout).GunData;
				gunData.damageEffect = wd.tripleEffect;
				if (wd.tripleEffectAmount > 0f)
				{
					gunData.damageEffectAmount = Mathf.Max(gunData.damageEffectAmount, wd.tripleEffectAmount);
				}
				((Gun)scout).GunData = gunData;
			}
			if (wd.elementalEmitter && (int)wd.elementalLaserEffect > 0)
			{
				LaserGunData laserData = scout.LaserData;
				DamageData laserDamage = laserData.laserDamage;
				laserDamage.effect = wd.elementalLaserEffect;
				if (wd.elementalLaserAmount > 0f)
				{
					laserDamage.effectAmount = Mathf.Max(laserDamage.effectAmount, wd.elementalLaserAmount);
				}
				laserData.laserDamage = laserDamage;
				scout.LaserData = laserData;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[DMLRRework] StampWeaponElements: " + ex.Message));
			}
		}
	}

	[HarmonyPatch(typeof(ScoutLaserRifle), "OnUpgradesDisabled")]
	[HarmonyPrefix]
	private static void OnUpgradesDisabled_SeveranceHooks(ScoutLaserRifle __instance)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		//IL_0073: 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_007e: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//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_00af: Expected O, but got Unknown
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance) || !DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return;
		}
		if (behaviour.killHookSubscribed)
		{
			KillCallback onKillTarget = ((Gun)__instance).OnKillTarget;
			object obj = <>O.<0>__OnMlrKillTarget;
			if (obj == null)
			{
				KillCallback val = OnMlrKillTarget;
				<>O.<0>__OnMlrKillTarget = val;
				obj = (object)val;
			}
			((Gun)__instance).OnKillTarget = (KillCallback)Delegate.Remove((Delegate?)(object)onKillTarget, (Delegate?)obj);
			behaviour.killHookSubscribed = false;
		}
		if (behaviour.severanceHooksSubscribed)
		{
			MutableDamageCallback onBeforeDamage = ((Gun)__instance).OnBeforeDamage;
			object obj2 = <>O.<1>__OnMlrBeforeDamage;
			if (obj2 == null)
			{
				MutableDamageCallback val2 = OnMlrBeforeDamage;
				<>O.<1>__OnMlrBeforeDamage = val2;
				obj2 = (object)val2;
			}
			((Gun)__instance).OnBeforeDamage = (MutableDamageCallback)Delegate.Remove((Delegate?)(object)onBeforeDamage, (Delegate?)obj2);
			DamageCallback onDamageTarget = ((Gun)__instance).OnDamageTarget;
			object obj3 = <>O.<2>__OnMlrDamageTarget;
			if (obj3 == null)
			{
				DamageCallback val3 = OnMlrDamageTarget;
				<>O.<2>__OnMlrDamageTarget = val3;
				obj3 = (object)val3;
			}
			((Gun)__instance).OnDamageTarget = (DamageCallback)Delegate.Remove((Delegate?)(object)onDamageTarget, (Delegate?)obj3);
			behaviour.severanceHooksSubscribed = false;
		}
	}

	private static void OnMlrBeforeDamage(ref DamageCallbackData data)
	{
		try
		{
			if (SeveranceSystem.IsTransferHit(in data))
			{
				return;
			}
			ScoutLaserRifle val = ResolveScout(data.source);
			if ((Object)(object)val == (Object)null || !SparrohPlugin.IsOurGear((IUpgradable)(object)val) || !DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour) || behaviour.isApplyingTransfer)
			{
				return;
			}
			ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
			SeveranceSystem.PartKind partKind = SeveranceSystem.GetPartKind(data.target);
			if (partKind == SeveranceSystem.PartKind.Limb && !Mathf.Approximately(weaponData.limbDamageMult, 1f) && weaponData.limbDamageMult > 0f)
			{
				data.damageData.damage *= weaponData.limbDamageMult;
				data.damageData.effectAmount *= weaponData.limbDamageMult;
			}
			else if (partKind == SeveranceSystem.PartKind.Shell && !Mathf.Approximately(weaponData.shellDamageMult, 1f) && weaponData.shellDamageMult > 0f)
			{
				data.damageData.damage *= weaponData.shellDamageMult;
				data.damageData.effectAmount *= weaponData.shellDamageMult;
			}
			if (behaviour.breachSlugArmed && (partKind == SeveranceSystem.PartKind.Shell || partKind == SeveranceSystem.PartKind.Core) && weaponData.breachSlugShellMult > 1f)
			{
				data.damageData.damage *= weaponData.breachSlugShellMult;
				data.damageData.effectAmount *= weaponData.breachSlugShellMult;
			}
			if (partKind == SeveranceSystem.PartKind.Core && weaponData.exposeDamageMult > 1.001f && SeveranceSystem.IsTargetExposed(behaviour, data.target))
			{
				data.damageData.damage *= weaponData.exposeDamageMult;
				data.damageData.effectAmount *= weaponData.exposeDamageMult;
			}
			if (weaponData.overkillConduit && partKind == SeveranceSystem.PartKind.Limb)
			{
				ITarget target = data.target;
				EnemyPart val2 = (EnemyPart)(object)((target is EnemyPart) ? target : null);
				if (val2 != null)
				{
					SeveranceSystem.RecordPotentialOverkill(behaviour, val2, data.damageData.damage);
				}
			}
			if (weaponData.faultLine && !val.IsLaserModeActive && partKind == SeveranceSystem.PartKind.Shell)
			{
				ITarget target2 = data.target;
				EnemyPart val3 = (EnemyPart)(object)((target2 is EnemyPart) ? target2 : null);
				if (val3 != null)
				{
					int partId = SeveranceSystem.GetPartId(val3);
					float time = Time.time;
					if (behaviour.faultLinePartId != partId || time - behaviour.faultLineLastHitTime > weaponData.faultLineResetTime)
					{
						behaviour.faultLinePartId = partId;
						behaviour.faultLineStacks = 0;
					}
					float num = Mathf.Min(weaponData.faultLineMaxBonus, (float)behaviour.faultLineStacks * weaponData.faultLineBonusPerHit);
					if (num > 0f)
					{
						data.damageData.damage *= 1f + num;
						data.damageData.effectAmount *= 1f + num;
					}
					behaviour.faultLineStacks++;
					behaviour.faultLineLastHitTime = time;
				}
			}
			if (weaponData.phantomPain && partKind == SeveranceSystem.PartKind.Limb)
			{
				ITarget target3 = data.target;
				EnemyPart val4 = (EnemyPart)(object)((target3 is EnemyPart) ? target3 : null);
				if (val4 != null && behaviour.IsPhantomRegrownLimb(val4) && weaponData.phantomPainDamageMult > 1f)
				{
					data.damageData.damage *= weaponData.phantomPainDamageMult;
					data.damageData.effectAmount *= weaponData.phantomPainDamageMult;
				}
			}
			if (weaponData.demoTrickV2 && behaviour.demoPendingEmpower == 2 && !val.IsLaserModeActive && weaponData.demoHeavyMarkDamageMult > 1f)
			{
				data.damageData.damage *= weaponData.demoHeavyMarkDamageMult;
				data.damageData.effectAmount *= weaponData.demoHeavyMarkDamageMult;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[Severance] BeforeDamage: " + ex.Message));
			}
		}
	}

	private static void OnMlrDamageTarget(in DamageCallbackData data)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_044c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0463: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0539: Unknown result type (might be due to invalid IL or missing references)
		//IL_053b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (data.damageData.damage <= 0f || SeveranceSystem.IsTransferHit(in data))
			{
				return;
			}
			ScoutLaserRifle val = ResolveScout(data.source);
			if ((Object)(object)val == (Object)null || !SparrohPlugin.IsOurGear((IUpgradable)(object)val) || !DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour) || behaviour.isApplyingTransfer)
			{
				return;
			}
			ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
			EnemyPart val2 = SeveranceSystem.AsEnemyPart(data.target);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			SeveranceSystem.PartKind partKind = SeveranceSystem.GetPartKind((ITarget)(object)val2);
			bool isLaserModeActive = val.IsLaserModeActive;
			Vector3 position = data.position;
			if (weaponData.markOnDmrHit && !isLaserModeActive && weaponData.markDuration > 0f)
			{
				SeveranceSystem.ApplyMark(behaviour, val2, weaponData.markDuration);
			}
			if (weaponData.jointBreaker && !isLaserModeActive && partKind == SeveranceSystem.PartKind.Limb)
			{
				behaviour.limbHitCounter++;
				int num = Mathf.Max(2, weaponData.jointBreakerEveryN);
				if (behaviour.limbHitCounter % num == 0)
				{
					float num2 = Mathf.Max(1f, weaponData.jointBreakerDecayAmount);
					try
					{
						ITarget.ApplyStatusEffect((ITarget)(object)val2, (EffectType)4, num2, (IDamageSource)(object)val, (DamageFlags)0);
					}
					catch
					{
					}
				}
			}
			if (weaponData.rotThread && !isLaserModeActive && partKind == SeveranceSystem.PartKind.Shell)
			{
				behaviour.shellHitCounter++;
				int num3 = Mathf.Max(2, weaponData.rotThreadEveryN);
				if (behaviour.shellHitCounter % num3 == 0)
				{
					float num4 = Mathf.Max(1f, weaponData.rotThreadRotAmount);
					try
					{
						ITarget.ApplyStatusEffect((ITarget)(object)val2, (EffectType)7, num4, (IDamageSource)(object)val, (DamageFlags)0);
					}
					catch
					{
					}
				}
			}
			if (!isLaserModeActive)
			{
				if (weaponData.bleedCharge && partKind == SeveranceSystem.PartKind.Limb && weaponData.bleedChargeAmount > 0f)
				{
					val.LaserCharge += weaponData.bleedChargeAmount;
				}
				if (weaponData.breachCharge && partKind == SeveranceSystem.PartKind.Shell && weaponData.breachChargeAmount > 0f)
				{
					val.LaserCharge += weaponData.breachChargeAmount;
				}
			}
			if (weaponData.coreBrand)
			{
				EnemyBrain brain = val2.Brain;
				if ((Object)(object)brain != (Object)null)
				{
					int instanceID = ((Object)brain).GetInstanceID();
					Dictionary<int, int> dictionary = behaviour.EnsureBrandMap();
					int value2;
					if (!isLaserModeActive && partKind == SeveranceSystem.PartKind.Shell)
					{
						dictionary.TryGetValue(instanceID, out var value);
						value++;
						dictionary[instanceID] = value;
					}
					else if (isLaserModeActive && dictionary.TryGetValue(instanceID, out value2) && value2 >= Mathf.Max(1, weaponData.coreBrandMaxStacks))
					{
						float num5 = ((weaponData.coreBrandExposeDuration > 0f) ? weaponData.coreBrandExposeDuration : weaponData.exposeDuration);
						SeveranceSystem.ExposeBrain(behaviour, brain, Mathf.Max(1f, num5));
						dictionary[instanceID] = 0;
					}
				}
			}
			if (weaponData.phantomPain && partKind == SeveranceSystem.PartKind.Limb && behaviour.IsPhantomRegrownLimb(val2) && weaponData.phantomPainChargeRefund > 0f)
			{
				val.LaserCharge += weaponData.phantomPainChargeRefund;
			}
			if (weaponData.markedRecycling && isLaserModeActive && weaponData.markedRecyclingAmmoPerHit > 0f)
			{
				bool num6 = SeveranceSystem.IsMarked(behaviour, val2);
				bool flag = SeveranceSystem.IsTargetExposed(behaviour, (ITarget)(object)val2);
				if (num6 || flag)
				{
					try
					{
						((Gun)val).RemainingAmmo = ((Gun)val).RemainingAmmo + weaponData.markedRecyclingAmmoPerHit;
					}
					catch
					{
					}
				}
			}
			if (weaponData.arterialShred && partKind == SeveranceSystem.PartKind.Limb && !isLaserModeActive)
			{
				EnemyBrain brain2 = val2.Brain;
				if ((Object)(object)brain2 != (Object)null)
				{
					SeveranceSystem.ApplyOpenArtery(behaviour, brain2, weaponData.openArteryDuration);
				}
			}
			if (weaponData.transferFromLimbs && partKind == SeveranceSystem.PartKind.Limb)
			{
				float num7 = SeveranceSystem.GetTransferPercent(behaviour, isLaserModeActive);
				if (isLaserModeActive && SeveranceSystem.TryConsumeOpenArtery(behaviour, val2.Brain, out var bonusTransfer))
				{
					num7 += bonusTransfer;
				}
				if (num7 > 0.001f)
				{
					EnemyPart val3 = SeveranceSystem.FindTransferDestination(val2, behaviour);
					if ((Object)(object)val3 != (Object)null)
					{
						float damage = data.damageData.damage * num7;
						behaviour.isApplyingTransfer = true;
						try
						{
							SeveranceSystem.DealTransferDamage((IDamageSource)(object)val, val3, damage, data.damageData.effect, data.damageData.effectAmount * num7, position, val2);
						}
						finally
						{
							behaviour.isApplyingTransfer = false;
						}
					}
					else if (SeveranceSystem.DebugTransfer)
					{
						ManualLogSource logger = SparrohPlugin.Logger;
						if (logger != null)
						{
							logger.LogInfo((object)$"[Severance] Neural Feedback: no dest from {((Object)val2).name} (kind={partKind})");
						}
					}
				}
			}
			if (weaponData.shellInwardSplashPercent > 0.001f && partKind == SeveranceSystem.PartKind.Shell)
			{
				EnemyPart val4 = SeveranceSystem.FindTransferDestination(val2, behaviour);
				if ((Object)(object)val4 != (Object)null)
				{
					float damage2 = data.damageData.damage * weaponData.shellInwardSplashPercent;
					behaviour.isApplyingTransfer = true;
					try
					{
						SeveranceSystem.DealTransferDamage((IDamageSource)(object)val, val4, damage2, data.damageData.effect, data.damageData.effectAmount * weaponData.shellInwardSplashPercent, position, val2);
					}
					finally
					{
						behaviour.isApplyingTransfer = false;
					}
				}
			}
			if (weaponData.hardLightDesignator && isLaserModeActive && partKind == SeveranceSystem.PartKind.Core && weaponData.exposeChargeRefund > 0f && SeveranceSystem.IsTargetExposed(behaviour, (ITarget)(object)val2))
			{
				val.LaserCharge += weaponData.exposeChargeRefund;
			}
			TickConductorOnHit(val, behaviour, ref weaponData, val2, partKind, isLaserModeActive, in data);
			if (weaponData.breachAmmoSystem && isLaserModeActive && weaponData.breachAmmoPerLaserHit > 0f)
			{
				behaviour.breachAmmo = Mathf.Min(weaponData.breachAmmoMax, behaviour.breachAmmo + weaponData.breachAmmoPerLaserHit);
			}
			if (weaponData.severanceCycle && partKind == SeveranceSystem.PartKind.Limb)
			{
				behaviour.dissectionStacks += Mathf.Max(1, weaponData.dissectionStacksPerLimbHit);
				if ((Object)(object)val2.Brain != (Object)null)
				{
					behaviour.lastLimbBrainId = ((Object)val2.Brain).GetInstanceID();
					behaviour.lastLimbHitPos = position;
				}
			}
			if (behaviour.breachSlugArmed)
			{
				behaviour.breachSlugArmed = false;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger2 = SparrohPlugin.Logger;
			if (logger2 != null)
			{
				logger2.LogDebug((object)("[Severance] DamageTarget: " + ex.Message));
			}
		}
	}

	private static void TickConductorOnHit(ScoutLaserRifle scout, DmlrReworkBehaviour b, ref DmlrReworkBehaviour.Data wd, EnemyPart part, SeveranceSystem.PartKind kind, bool laser, in DamageCallbackData data)
	{
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		if (wd.demoTrickV2)
		{
			int num = (laser ? 1 : 0);
			if (b.lastFiredMode >= 0 && b.lastFiredMode != num)
			{
				b.demoPendingEmpower = ((num == 1) ? 1 : 2);
			}
			b.lastFiredMode = num;
			if (b.demoPendingEmpower == 1 && laser)
			{
				SpreadMarkOnBrain(b, part, wd.demoMarkSpreadRadius, wd.markDuration);
				b.demoPendingEmpower = 0;
			}
			else if (b.demoPendingEmpower == 2 && !laser)
			{
				SeveranceSystem.ApplyMark(b, part, Mathf.Max(wd.markDuration, wd.demoHeavyMarkDuration));
				b.demoPendingEmpower = 0;
			}
		}
		bool flag = SeveranceSystem.IsMarked(b, part);
		if (wd.sympatheticResonance && flag && wd.resonanceEchoScale > 0f)
		{
			ApplyResonanceEcho(scout, b, part, data.damageData.damage * wd.resonanceEchoScale);
		}
		if (wd.sympatheticArc && laser && flag && wd.arcDamageScale > 0f)
		{
			ApplySympatheticArcs(scout, b, ref wd, part, data.damageData.damage, data.position);
		}
	}

	private static void SpreadMarkOnBrain(DmlrReworkBehaviour b, EnemyPart from, float radius, float duration)
	{
		//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_0064: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)((from != null) ? from.Brain : null) == (Object)null || duration <= 0f)
		{
			return;
		}
		EnemyBrain brain = from.Brain;
		Vector3 position = ((Component)from).transform.position;
		float r = Mathf.Max(1f, radius) * Mathf.Max(1f, radius);
		try
		{
			EnemyCore core = SeveranceSystem.GetCore(brain);
			if ((Object)(object)core == (Object)null)
			{
				SeveranceSystem.ApplyMark(b, from, duration);
			}
			else
			{
				MarkPartsInTree(b, (EnemyPart)(object)core, position, r, duration, from);
			}
		}
		catch
		{
			SeveranceSystem.ApplyMark(b, from, duration);
		}
	}

	private static void MarkPartsInTree(DmlrReworkBehaviour b, EnemyPart root, Vector3 origin, float r2, float duration, EnemyPart always)
	{
		//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_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_0060: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null || !root.IsAlive)
		{
			return;
		}
		if (root != always)
		{
			Vector3 val = ((Component)root).transform.position - origin;
			if (!(((Vector3)(ref val)).sqrMagnitude <= r2))
			{
				goto IL_003c;
			}
		}
		SeveranceSystem.ApplyMark(b, root, duration);
		goto IL_003c;
		IL_003c:
		if (root.ChildComponents == null)
		{
			return;
		}
		for (int i = 0; i < root.ChildComponents.Count; i++)
		{
			IEnemyComponent obj = root.ChildComponents[i];
			EnemyPart val2 = (EnemyPart)(object)((obj is EnemyPart) ? obj : null);
			if (val2 != null)
			{
				MarkPartsInTree(b, val2, origin, r2, duration, always);
			}
		}
	}

	private static void ApplyResonanceEcho(ScoutLaserRifle scout, DmlrReworkBehaviour b, EnemyPart source, float echoDamage)
	{
		if (echoDamage <= 0.01f || (Object)(object)((source != null) ? source.Brain : null) == (Object)null)
		{
			return;
		}
		EnemyCore core = SeveranceSystem.GetCore(source.Brain);
		if ((Object)(object)core == (Object)null)
		{
			return;
		}
		b.isApplyingTransfer = true;
		try
		{
			EchoMarkedInTree(scout, b, (EnemyPart)(object)core, source, echoDamage);
		}
		finally
		{
			b.isApplyingTransfer = false;
		}
	}

	private static void EchoMarkedInTree(ScoutLaserRifle scout, DmlrReworkBehaviour b, EnemyPart root, EnemyPart exclude, float dmg)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)root == (Object)null || !root.IsAlive)
		{
			return;
		}
		if (root != exclude && SeveranceSystem.IsMarked(b, root))
		{
			try
			{
				DamageData val = default(DamageData);
				((DamageData)(ref val))..ctor(dmg, (EffectType)2, dmg * 0.25f, (DamageFlags)4);
				IDamageSource.DamageTarget((IDamageSource)(object)scout, (ITarget)(object)root, val, ((Component)root).transform.position, (Collider)null);
			}
			catch
			{
			}
		}
		if (root.ChildComponents == null)
		{
			return;
		}
		for (int i = 0; i < root.ChildComponents.Count; i++)
		{
			IEnemyComponent obj2 = root.ChildComponents[i];
			EnemyPart val2 = (EnemyPart)(object)((obj2 is EnemyPart) ? obj2 : null);
			if (val2 != null)
			{
				EchoMarkedInTree(scout, b, val2, exclude, dmg);
			}
		}
	}

	private unsafe static void ApplySympatheticArcs(ScoutLaserRifle scout, DmlrReworkBehaviour b, ref DmlrReworkBehaviour.Data wd, EnemyPart from, float sourceDamage, Vector3 hitPos)
	{
		//IL_003e: 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)
		float num = Mathf.Max(2f, wd.arcRadius);
		float num2 = sourceDamage * Mathf.Max(0.1f, wd.arcDamageScale);
		int maxJumps = Mathf.Max(1, wd.arcMaxJumps);
		if (num2 <= 0.01f)
		{
			return;
		}
		try
		{
			TargetEnumerator val = default(TargetEnumerator);
			try
			{
				if (!((TargetEnumerator)(ref val)).GetTargetsInSphere(hitPos, num, 345224, (TargetType)5))
				{
					return;
				}
				List<EnemyPart> list = new List<EnemyPart>(8);
				List<EnemyPart> list2 = new List<EnemyPart>(8);
				List<EnemyPart> list3 = new List<EnemyPart>(8);
				_ = from.Brain;
				while (((TargetEnumerator)(ref val)).MoveNext())
				{
					ITarget current = ((TargetEnumerator)(ref val)).Current;
					EnemyPart val2 = (EnemyPart)(object)((current is EnemyPart) ? current : null);
					if (val2 != null && val2.IsAlive && val2 != from)
					{
						if (SeveranceSystem.IsMarked(b, val2))
						{
							list.Add(val2);
						}
						else if (SeveranceSystem.GetPartKind((ITarget)(object)val2) == SeveranceSystem.PartKind.Limb)
						{
							list2.Add(val2);
						}
						else
						{
							list3.Add(val2);
						}
					}
				}
				bool transferFromLimbs = wd.transferFromLimbs;
				float arcTransferScale = wd.arcTransferScale;
				int jumps = 0;
				jumps = ArcList(scout, b, list, num2, maxJumps, jumps, transferFromLimbs, arcTransferScale);
				jumps = ArcList(scout, b, list2, num2, maxJumps, jumps, transferFromLimbs, arcTransferScale);
				ArcList(scout, b, list3, num2, maxJumps, jumps, transferFromLimbs, arcTransferScale);
			}
			finally
			{
				((IDisposable)(*(TargetEnumerator*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[Severance] Arc: " + ex.Message));
			}
		}
	}

	private static int ArcList(ScoutLaserRifle scout, DmlrReworkBehaviour b, List<EnemyPart> list, float dmg, int maxJumps, int jumps, bool canTransfer, float arcXferScale)
	{
		//IL_0023: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		DamageData val2 = default(DamageData);
		for (int i = 0; i < list.Count; i++)
		{
			if (jumps >= maxJumps)
			{
				break;
			}
			EnemyPart val = list[i];
			((DamageData)(ref val2))..ctor(dmg, (EffectType)2, dmg * 0.3f, (DamageFlags)20);
			try
			{
				IDamageSource.DamageTarget((IDamageSource)(object)scout, (ITarget)(object)val, val2, ((Component)val).transform.position, (Collider)null);
				jumps++;
				if (!canTransfer || SeveranceSystem.GetPartKind((ITarget)(object)val) != SeveranceSystem.PartKind.Limb || !(arcXferScale > 0f))
				{
					continue;
				}
				float num = SeveranceSystem.GetTransferPercent(b, laserMode: true) * arcXferScale;
				if (!(num > 0.001f))
				{
					continue;
				}
				EnemyPart val3 = SeveranceSystem.FindTransferDestination(val, b);
				if ((Object)(object)val3 != (Object)null)
				{
					b.isApplyingTransfer = true;
					try
					{
						SeveranceSystem.DealTransferDamage((IDamageSource)(object)scout, val3, dmg * num, (EffectType)2, 0f, ((Component)val).transform.position, val);
					}
					finally
					{
						b.isApplyingTransfer = false;
					}
				}
			}
			catch
			{
			}
		}
		return jumps;
	}

	[HarmonyPatch(typeof(Gun), "OnReload")]
	[HarmonyPostfix]
	private static void Gun_OnReload_VoltaicBattery(Gun __instance)
	{
		ScoutLaserRifle val = (ScoutLaserRifle)(object)((__instance is ScoutLaserRifle) ? __instance : null);
		if (val != null && SparrohPlugin.IsOurGear((IUpgradable)(object)val) && DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour) && behaviour.WeaponData.voltaicBatteryV2)
		{
			float num = 1f;
			try
			{
				num = Mathf.Max(1f, (float)((Gun)val).GunData.magazineSize);
				Mathf.Clamp(((Gun)val).RemainingAmmo, 0f, num);
			}
			catch
			{
				num = 20f;
			}
			float num2 = 1f;
			ThrowVoltaicBattery(power: behaviour.batteryPowerMult = 1f + (behaviour.WeaponData.batteryEmptyMagBonus - 1f) * num2, scout: val, b: behaviour);
		}
	}

	private static void ThrowVoltaicBattery(ScoutLaserRifle scout, DmlrReworkBehaviour b, float power)
	{
		//IL_00b4: 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_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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: 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_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_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: 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_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: 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)
		ref DmlrReworkBehaviour.Data weaponData = ref b.WeaponData;
		float time = Time.time;
		if (time - b.lastBatteryThrowTime < 0.4f)
		{
			return;
		}
		b.lastBatteryThrowTime = time;
		try
		{
			Vector3 position = ((Component)scout).transform.position;
			Vector3 forward = ((Component)scout).transform.forward;
			try
			{
				if ((Object)(object)((Gun)scout).Player?.playerLook != (Object)null)
				{
					position = ((Component)((Gun)scout).Player.playerLook).transform.position;
					forward = ((Component)((Gun)scout).Player.playerLook).transform.forward;
				}
				else if ((Object)(object)((Gun)scout).GunData.firePoint != (Object)null)
				{
					position = ((Gun)scout).GunData.firePoint.position;
				}
			}
			catch
			{
			}
			float num = 40f;
			Vector3 val = position + forward * num;
			EnemyPart val2 = null;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(position, forward, ref val3, num, -1, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val3)).point;
				val2 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<EnemyPart>() : null);
			}
			float num2 = weaponData.batteryBaseDamage * Mathf.Max(1f, power);
			float num3 = Mathf.Max(1.5f, weaponData.batteryRadius);
			DamageData val4 = default(DamageData);
			((DamageData)(ref val4))..ctor(num2, (EffectType)2, num2 * 0.35f, (DamageFlags)16);
			if ((Object)(object)val2 != (Object)null && val2.IsAlive)
			{
				try
				{
					IDamageSource.DamageTarget((IDamageSource)(object)scout, (ITarget)(object)val2, val4, val, (Collider)null);
				}
				catch
				{
				}
				if (weaponData.batteryTransferPercent > 0f)
				{
					EnemyPart val5 = SeveranceSystem.FindTransferDestination(val2, b);
					if ((Object)(object)val5 != (Object)null)
					{
						b.isApplyingTransfer = true;
						try
						{
							SeveranceSystem.DealTransferDamage((IDamageSource)(object)scout, val5, num2 * weaponData.batteryTransferPercent, (EffectType)2, 0f, val, val2);
						}
						finally
						{
							b.isApplyingTransfer = false;
						}
					}
				}
			}
			else
			{
				try
				{
					Vector3 val6 = val;
					IDamageSource.DamageTargetsInSphere((IDamageSource)(object)scout, ref val6, num3, (TargetType)5, ref val4, 0f, 1f);
				}
				catch
				{
				}
			}
			try
			{
				GameManager instance = GameManager.Instance;
				if (instance != null)
				{
					instance.SpawnExplosionVisual_ServerRpc(val, num3, (EffectType)2);
				}
			}
			catch
			{
			}
		}
		catch (Exception ex)
		{
			ManualLogSource logger = SparrohPlugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("[Severance] Battery: " + ex.Message));
			}
		}
	}

	private static void OnMlrKillTarget(in KillCallbackData data)
	{
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b8: Invalid comparison between Unknown and I4
		//IL_0514: Unknown result type (might be due to invalid IL or missing references)
		//IL_0518: Unknown result type (might be due to invalid IL or missing references)
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0400: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c7: Invalid comparison between Unknown and I4
		//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			ScoutLaserRifle val = ResolveScout(data.source);
			if ((Object)(object)val == (Object)null || !SparrohPlugin.IsOurGear((IUpgradable)(object)val) || !DmlrReworkBehaviour.TryGet((IGear)(object)val, out var behaviour))
			{
				return;
			}
			ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData;
			EnemyPart val2 = SeveranceSystem.AsEnemyPart(data.target);
			SeveranceSystem.PartKind partKind = SeveranceSystem.GetPartKind(data.target);
			ITarget target = data.target;
			Component val3 = (Component)(object)((target is Component) ? target : null);
			Vector3 val4 = ((val3 != null && (Object)(object)val3 != (Object)null) ? val3.transform.position : ((!((Object)(object)((Gun)val).GunData.firePoint != (Object)null)) ? ((Component)val).transform.position : ((Gun)val).GunData.firePoint.position));
			if (weaponData.overkillConduit && partKind == SeveranceSystem.PartKind.Limb && (Object)(object)val2 != (Object)null)
			{
				SeveranceSystem.TryTakeOverkill(behaviour, val2, out var overkill);
				if (overkill <= 0.01f && data.damageData.damage > 0f)
				{
					overkill = data.damageData.damage * 0.15f;
				}
				if (overkill > 0.01f)
				{
					float num = Mathf.Max(1f, weaponData.overkillTransferMult);
					if (SeveranceSystem.IsMarked(behaviour, val2) && weaponData.overkillMarkedBonusMult > 1f)
					{
						num *= weaponData.overkillMarkedBonusMult;
					}
					EnemyPart val5 = SeveranceSystem.FindTransferDestination(val2, behaviour);
					if ((Object)(object)val5 == (Object)null && (Object)(object)val2.Brain != (Object)null)
					{
						EnemyCore core = SeveranceSystem.GetCore(val2.Brain);
						if ((Object)(object)core != (Object)null && SeveranceSystem.CanCoreAcceptNormalDamage(core))
						{
							val5 = (EnemyPart)(object)core;
						}
					}
					if ((Object)(object)val5 != (Object)null && val5.IsAlive)
					{
						behaviour.isApplyingTransfer = true;
						try
						{
							SeveranceSystem.DealTransferDamage((IDamageSource)(object)val, val5, overkill * num, data.damageData.effect, 0f, val4, val2);
						}
						finally
						{
							behaviour.isApplyingTransfer = false;
						}
					}
					else if (SeveranceSystem.DebugTransfer)
					{
						ManualLogSource logger = SparrohPlugin.Logger;
						if (logger != null)
						{
							logger.LogInfo((object)("[Severance] Overkill Conduit: no dest for limb kill " + ((val2 != null) ? ((Object)val2).name : null)));
						}
					}
				}
			}
			if (weaponData.phantomPain && partKind == SeveranceSystem.PartKind.Limb && (Object)(object)val2 != (Object)null)
			{
				behaviour.RecordPhantomLimbKill(val2);
			}
			if (weaponData.reactorTap && partKind == SeveranceSystem.PartKind.Core)
			{
				if (weaponData.reactorTapCharge > 0f)
				{
					val.LaserCharge += weaponData.reactorTapCharge;
				}
				if (weaponData.reactorTapAmmoOnExposed > 0 && SeveranceSystem.IsTargetExposed(behaviour, data.target))
				{
					try
					{
						((Gun)val).RemainingAmmo = ((Gun)val).RemainingAmmo + (float)weaponData.reactorTapAmmoOnExposed;
					}
					catch
					{
					}
				}
			}
			if (weaponData.breachAmmoSystem && weaponData.breachBreakTransferBonus > 0f && (partKind == SeveranceSystem.PartKind.Shell || partKind == SeveranceSystem.PartKind.Limb) && (Object)(object)val2 != (Object)null)
			{
				EnemyPart val6 = SeveranceSystem.FindTransferDestination(val2, behaviour);
				if ((Object)(object)val6 == (Object)null && (Object)(object)val2.Brain != (Object)null)
				{
					EnemyCore core2 = SeveranceSystem.GetCore(val2.Brain);
					if ((Object)(object)core2 != (Object)null && SeveranceSystem.CanCoreAcceptNormalDamage(core2))
					{
						val6 = (EnemyPart)(object)core2;
					}
				}
				if ((Object)(object)val6 != (Object)null && val6.IsAlive)
				{
					float damage = data.damageData.damage * weaponData.breachBreakTransferBonus;
					behaviour.isApplyingTransfer = true;
					try
					{
						SeveranceSystem.DealTransferDamage((IDamageSource)(object)val, val6, damage, data.damageData.effect, 0f, val4, val2);
					}
					finally
					{
						behaviour.isApplyingTransfer = false;
					}
				}
			}
			if (weaponData.collapseWave && partKind == SeveranceSystem.PartKind.Shell && (Object)(object)val2 != (Object)null)
			{
				float num2 = 100f;
				try
				{
					num2 = Mathf.Max(10f, val2.MaxHealth);
				}
				catch
				{
					num2 = 100f;
				}
				float num3 = num2 * Mathf.Max(0.05f, weaponData.collapseHpScale);
				float num4 = Mathf.Max(1.5f, weaponData.collapseRadius);
				EffectType val7 = (EffectType)(((int)weaponData.collapseEffect <= 0) ? 2 : ((int)weaponData.collapseEffect));
				DamageData val8 = default(DamageData);
				((DamageData)(ref val8))..ctor(num3, val7, num3 * 0.2f, (DamageFlags)16);
				try
				{
					Vector3 val9 = val4;
					IDamageSource.DamageTargetsInSphere((IDamageSource)(object)val, ref val9, num4, (TargetType)5, ref val8, 0f, 1f);
					GameManager instance = GameManager.Instance;
					if (instance != null)
					{
						instance.SpawnExplosionVisual_ServerRpc(val4, num4, val7);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource logger2 = SparrohPlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogDebug((object)("[Severance] CollapseWave: " + ex.Message));
					}
				}
			}
			if (weaponData.hardLightDesignator && partKind == SeveranceSystem.PartKind.Shell)
			{
				EnemyBrain brain = SeveranceSystem.GetBrain(data.target);
				if ((Object)(object)brain != (Object)null)
				{
					SeveranceSystem.ExposeBrain(behaviour, brain, weaponData.exposeDuration);
				}
			}
			if (!weaponData.dmrKillExplosion || val.IsLaserModeActive)
			{
				return;
			}
			float dmrKillExplosionRadius = weaponData.dmrKillExplosionRadius;
			if (!(dmrKillExplosionRadius > 0.1f) || !((Object)(object)GameManager.Instance != (Object)null))
			{
				return;
			}
			float num5 = ((Gun)val).GunData.damage * Mathf.Max(0.1f, weaponData.dmrKillExplosionDamageScale);
			EffectType val10 = weaponData.dmrKillExplosionEffect;
			if ((int)val10 <= 0)
			{
				val10 = (EffectType)1;
			}
			DamageData val11 = default(DamageData);
			((DamageData)(ref val11))..ctor(num5, val10, 10f, (DamageFlags)16);
			try
			{
				GameManager.Instance.SpawnExplosionFirstPerson((IDamageSource)(object)val, val4, dmrKillExplosionRadius, (TargetType)5, val11, 2f);
			}
			catch
			{
				try
				{
					IDamageSource.DamageTargetsInSphere((IDamageSource)(object)val, ref val4, dmrKillExplosionRadius, (TargetType)5, ref val11, 0f, 1f);
					GameManager.Instance.SpawnExplosionVisual_ServerRpc(val4, dmrKillExplosionRadius, val10);
				}
				catch (Exception ex2)
				{
					ManualLogSource logger3 = SparrohPlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogDebug((object)("[DMLRRework] Kill explosion failed: " + ex2.Message));
					}
				}
			}
		}
		catch (Exception ex3)
		{
			ManualLogSource logger4 = SparrohPlugin.Logger;
			if (logger4 != null)
			{
				logger4.LogDebug((object)("[DMLRRework] OnMlrKillTarget: " + ex3.Message));
			}
		}
	}

	private static ScoutLaserRifle ResolveScout(IDamageSource source)
	{
		for (IDamageSource val = source; val != null; val = val.ParentSource)
		{
			ScoutLaserRifle val2 = (ScoutLaserRifle)(object)((val is ScoutLaserRifle) ? val : null);
			if (val2 != null)
			{
				return val2;
			}
		}
		return null;
	}

	[HarmonyPatch(typeof(Gun), "Disable")]
	[HarmonyPostfix]
	private static void GunDisable_Postfix(Gun __instance)
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		//IL_00bf: 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_00ca: Expected O, but got Unknown
		if (!SparrohPlugin.IsOurGear((IUpgradable)(object)__instance))
		{
			return;
		}
		SetBool(ForceEnableFireField, __instance, value: false);
		if (!DmlrReworkBehaviour.TryGet((IGear)(object)__instance, out var behaviour))
		{
			return;
		}
		ScoutLaserRifle val = (ScoutLaserRifle)(object)((__instance is ScoutLaserRifle) ? __instance : null);
		if (val != null)
		{
			if (behaviour.killHookSubscribed)
			{
				KillCallback onKillTarget = ((Gun)val).OnKillTarget;
				object obj = <>O.<0>__OnMlrKillTarget;
				if (obj == null)
				{
					KillCallback val2 = OnMlrKillTarget;
					<>O.<0>__OnMlrKillTarget = val2;
					obj = (object)val2;
				}
				((Gun)val).OnKillTarget = (KillCallback)Delegate.Remove((Delegate?)(object)onKillTarget, (Delegate?)obj);
				behaviour.killHookSubscribed = false;
			}
			if (behaviour.severanceHooksSubscribed)
			{
				MutableDamageCallback onBeforeDamage = ((Gun)val).OnBeforeDamage;
				object obj2 = <>O.<1>__OnMlrBeforeDamage;
				if (obj2 == null)
				{
					MutableDamageCallback val3 = OnMlrBeforeDamage;
					<>O.<1>__OnMlrBeforeDamage = val3;
					obj2 = (object)val3;
				}
				((Gun)val).OnBeforeDamage = (MutableDamageCallback)Delegate.Remove((Delegate?)(object)onBeforeDamage, (Delegate?)obj2);
				DamageCallback onDamageTarget = ((G