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 brandStacks; [NonSerialized] public HashSet phantomKilledLimbIds; [NonSerialized] public HashSet 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 markExpiries; [NonSerialized] public Dictionary 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 EnsureMarkMap() { return markExpiries ?? (markExpiries = new Dictionary(16)); } public Dictionary EnsureExposeMap() { return exposeExpiries ?? (exposeExpiries = new Dictionary(8)); } public Dictionary EnsureBrandMap() { return brandStacks ?? (brandStacks = new Dictionary(8)); } public HashSet EnsurePhantomLimbIds() { return phantomKilledLimbIds ?? (phantomKilledLimbIds = new HashSet()); } public HashSet EnsurePhantomLimbKeys() { return phantomKilledLimbKeys ?? (phantomKilledLimbKeys = new HashSet()); } 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(); 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(); } 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(); 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 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(); if ((Object)(object)condensedPierceTracker == (Object)null) { condensedPierceTracker = ((Component)val).gameObject.AddComponent(); } ((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(); 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(); 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(); 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 hashSet = CollectionPool, 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, 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 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 list = new List(8); List list2 = new List(8); List list3 = new List(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 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() : 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 = ((Gun)val).OnDamageTarget; object obj3 = <>O.<2>__OnMlrDamageTarget; if (obj3 == null) { DamageCallback val4 = OnMlrDamageTarget; <>O.<2>__OnMlrDamageTarget = val4; obj3 = (object)val4; } ((Gun)val).OnDamageTarget = (DamageCallback)Delegate.Remove((Delegate?)(object)onDamageTarget, (Delegate?)obj3); behaviour.severanceHooksSubscribed = false; } } behaviour.ResetRuntimeState(); } private static bool GetBool(FieldInfo field, object target) { if (field == null || target == null) { return false; } try { return (bool)field.GetValue(target); } catch { return false; } } private static void SetBool(FieldInfo field, object target, bool value) { if (field == null || target == null) { return; } try { field.SetValue(target, value); } catch { } } } internal static class DmlrUpgradePort { public const int UpgradeIdOffset = 50000; private static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static bool _registered; private static int _portedCount; private static int _skippedCount; public static bool IsRegistered => _registered; public static int PortedCount => _portedCount; public static void TryRegister(ManualLogSource log) { if (_registered) { return; } if (PlayerData.Instance == null) { if (log != null) { log.LogDebug((object)"[DmlrUpgradePort] PlayerData.Instance null — defer."); } return; } IUpgradable val = SparrohPlugin.ResolveRegisteredGear(); if (val == null) { if (log != null) { log.LogDebug((object)"[DmlrUpgradePort] Target gear not ready — defer."); } return; } WeaponRegistration.EnsureGearData(val, autoUnlock: true, log); GearData val2 = null; try { val2 = PlayerData.GetGearData(val); } catch (Exception ex) { if (log != null) { log.LogDebug((object)("[DmlrUpgradePort] GetGearData threw — defer: " + ex.Message)); } return; } if (val2 == null) { if (log != null) { log.LogDebug((object)"[DmlrUpgradePort] GearData missing after EnsureGearData — defer."); } return; } ScoutLaserRifle val3 = FindVanillaScout(); if ((Object)(object)((val3 != null) ? ((Gun)val3).Info : null) == (Object)null) { if (log != null) { log.LogWarning((object)"[DmlrUpgradePort] Vanilla ScoutLaserRifle not found in AllGear."); } return; } List upgrades = ((Gun)val3).Info.Upgrades; if (upgrades == null || upgrades.Count == 0) { if (log != null) { log.LogWarning((object)"[DmlrUpgradePort] Scout has no upgrades to port."); } return; } _portedCount = 0; _skippedCount = 0; int num = 0; for (int i = 0; i < upgrades.Count; i++) { Upgrade val4 = upgrades[i]; if ((Object)(object)val4 == (Object)null) { _skippedCount++; continue; } if (val4 is SkinUpgrade) { _skippedCount++; continue; } try { if (TryPortOne(val, val4, log)) { _portedCount++; } else { _skippedCount++; } } catch (Exception arg) { num++; _skippedCount++; if (log != null) { log.LogError((object)$"[DmlrUpgradePort] Failed porting '{SafeApiName(val4)}' (id={val4.NumberID}): {arg}"); } } } if (_portedCount > 0 || num == 0) { _registered = true; } if (log != null) { string text = $"[DmlrUpgradePort] Done: ported={_portedCount} skipped={_skippedCount} failed={num} "; object arg2 = _registered; object arg3 = PlayerData.HasUpgrades(val); GearInfo info = val.Info; log.LogInfo((object)(text + $"locked={arg2} HasUpgrades={arg3} grid={((info != null) ? new bool?(info.HasUpgradeGrid) : ((bool?)null))}.")); } } private static string SafeApiName(Upgrade src) { try { return src.APIName ?? src.Name ?? "?"; } catch { return "?"; } } private static ScoutLaserRifle FindVanillaScout() { Gun baseGunPrefab = WeaponRegistration.BaseGunPrefab; ScoutLaserRifle val = (ScoutLaserRifle)(object)((baseGunPrefab is ScoutLaserRifle) ? baseGunPrefab : null); if (val != null) { return val; } if (Global.Instance?.AllGear == null) { return null; } for (int i = 0; i < Global.Instance.AllGear.Length; i++) { IUpgradable obj = Global.Instance.AllGear[i]; ScoutLaserRifle val2 = (ScoutLaserRifle)(object)((obj is ScoutLaserRifle) ? obj : null); if (val2 != null && !SparrohPlugin.IsOurGear((IUpgradable)(object)val2)) { return val2; } } return null; } private static bool TryPortOne(IUpgradable targetGear, Upgrade src, ManualLogSource log) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) int num = src.NumberID + 50000; if (num <= 0) { num = 91000 + Math.Abs(src.NumberID % 1000); } string text = SafeApiName(src); UpgradeFlags val = src.Flags; if (TryGetRewrite(text, out var props, out var displayName, out var description, out var flags)) { if (flags.HasValue) { val = flags.Value; } if (log != null) { log.LogInfo((object)$"[DmlrUpgradePort] Rewriting '{text}' → '{displayName}' (id={num})."); } } else { props = CloneProperties(src); if (props == null || props.Length == 0) { if (log != null) { log.LogWarning((object)("[DmlrUpgradePort] No properties on '" + text + "' — skip.")); } return false; } displayName = SafeName(src); description = SafeDescription(src); } HexMap val2 = ClonePattern(src); CustomUpgradeParams val3 = CustomUpgradeParams.Create(targetGear, num, displayName, description, src.Rarity, src.Icon); val3.flags = val; val3.priority = src.Priority; val3.collectionSource = (CollectionSource)0; val3.upgradeType = src.UpgradeType; val3.useDefaultUnlockCost = true; if (val2 != null) { val3.pattern = val2; } Upgrade val4 = PlayerData.CreateUpgrade("sparroh.dmlrrework", val3, props); if ((Object)(object)val4 == (Object)null) { if (log != null) { log.LogError((object)("[DmlrUpgradePort] CreateUpgrade returned null for '" + displayName + "'.")); } return false; } if (val2 != null) { val4.SetPattern(val2); } if (log != null) { log.LogDebug((object)($"[DmlrUpgradePort] Ported '{displayName}' vanillaId={src.NumberID} → id={num} " + $"props={props.Length} rarity={src.Rarity} flags={val}.")); } return true; } private static bool TryGetRewrite(string api, out UpgradeProperty[] props, out string displayName, out string description, out UpgradeFlags? flags) { props = null; displayName = null; description = null; flags = null; if (string.IsNullOrEmpty(api)) { return false; } string a = api.Trim(); if (string.Equals(a, "Tosser", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_VoltaicBatteryV2() }; displayName = "Voltaic Battery"; description = "On reload, throw a voltaic battery along your aim. It blasts the stuck part and transfers a portion of damage inward. Stronger when the mag was empty."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Pulverizer", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_Pulverizer() }; displayName = "Pulverizer"; description = "Deal more damage to shells but less to limbs. Shell hits splash a portion of damage inward toward the core."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Shredder", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_ArterialShred() }; displayName = "Arterial Shred"; description = "Deal more damage to limbs but less to shells. Limb hits apply Open Artery: your next laser hit on that enemy gains bonus damage transfer."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Autocycler", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_NeuralFeedback() }; displayName = "Neural Feedback"; description = "Damage dealt to limbs transfers a percentage to the core. Laser transfer is much stronger than DMR transfer."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Energy Regeneration", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "EnergyRegeneration", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_OverkillConduit() }; displayName = "Overkill Conduit"; description = "When you kill a limb, overkill damage is multiplied and transferred inward to the core."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "ArcLightning", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Arc Lightning", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_SympatheticArc() }; displayName = "Sympathetic Arc"; description = "Laser hits on Marked parts arc lightning to nearby enemies. Priority: other Marked parts, then limbs."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Shield Piercing", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "ShieldPiercing", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_HardLightDesignator() }; displayName = "Hard-Light Designator"; description = "Shell kills Expose the core. Exposed cores take bonus damage; laser hits on Exposed cores refund laser charge."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Elemental Recycling", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "ElementalRecycling", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_SympatheticResonance() }; displayName = "Sympathetic Resonance"; description = "When you damage a Marked part, other Marked parts on that enemy take an echo hit."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Hot Exhaust", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "HotExhaust", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_CollapseWave() }; displayName = "Collapse Wave"; description = "When you kill a shell, emit a concussive pulse scaled by that shell's max health."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "PowerDMR", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Heavy Hitting", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_JointBreaker() }; displayName = "Joint Breaker"; description = "Every 3rd DMR hit on a limb applies Decay."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Burst", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Trifecta", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_RotThread() }; displayName = "Rot Thread"; description = "Every 3rd DMR hit on a shell applies Rot."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "LaserBurst", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Concussive Wave", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_FaultLine() }; displayName = "Fault Line"; description = "Repeated DMR hits on the same shell escalate damage to that shell."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Power Core", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "PowerCore", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_ReactorTap() }; displayName = "Reactor Tap"; description = "Core kills refund laser charge. If the core was Exposed, also refund DMR ammo."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Overcharge Cycling", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "OverchargeCycling", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_CoreBrand() }; displayName = "Core Brand"; description = "DMR hits on shells build Brand stacks. At max stacks, your next laser hit on that enemy Exposes the core."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Laser Repair", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "LaserRepair", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Engineering Nanites", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_PhantomPain() }; displayName = "Phantom Pain"; description = "Hitting a regrown limb deals bonus damage and refunds laser charge."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "MoreCharge", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Feedback Amplifier", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_BleedCharge() }; displayName = "Bleed Charge"; description = "Limb hits generate bonus laser charge."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Rapid Charge", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "RapidCharge", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_BreachCharge() }; displayName = "Breach Charge"; description = "Shell hits generate bonus laser charge."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Reorganized Reserves", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "ReorganizedReserves", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_MarkedRecycling() }; displayName = "Marked Recycling"; description = "Laser damage refunds DMR ammo only when hitting Marked or Exposed parts."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Triple", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_TripleFeed() }; displayName = "Triple Feed"; description = "Your DMR applies Shock or Acid (rolled per magazine) on every shot."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Long Scope", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "LongScope", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_ReverseFalloff() }; displayName = "Long Scope"; description = "DMR damage falloff is reversed — damage increases with distance."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "LasDmg", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Beam Amplifier", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_OverheatedCapacitor() }; displayName = "Overheated Capacitor"; description = "Laser damage increases the longer the beam has been active."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "TosserTwo", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_DemonstratorsTrickV2() }; displayName = "Demonstrator's Trick"; description = "DMR→Laser: next laser hit spreads Mark nearby. Laser→DMR: next DMR hit applies a heavy Mark and bonus damage."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Sturdy", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_GravitationalCollapse() }; displayName = "Gravitational Collapse"; description = "While under Kinetic Impossibility (Laser Hover), your laser pulls enemies toward your aim point."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "DmrDmg", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Kinetic Amplifier", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_CondensedMunitions() }; displayName = "Condensed Munitions"; description = "DMR fires the entire magazine in one shot. Damage scales with ammo spent; +1 pierce per 10 ammo."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Incendiary Laser", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "IncendiaryLaser", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_IncendiaryWave() }; displayName = "Incendiary Laser"; description = "Your laser periodically launches a fire damage wave along the aim path."; flags = (UpgradeFlags)0; return true; } if (string.Equals(a, "Shocking Laser", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "ShockingLaser", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "Corrosive Laser", StringComparison.OrdinalIgnoreCase) || string.Equals(a, "CorrosiveLaser", StringComparison.OrdinalIgnoreCase)) { props = (UpgradeProperty[])(object)new UpgradeProperty[1] { new UpgradeProperty_MLR_ElementalEmitter() }; displayName = "Elemental Emitter"; description = "Your laser applies Shock or Acid (rolled once when this upgrade is installed)."; flags = (UpgradeFlags)0; return true; } return false; } private static string SafeName(Upgrade src) { try { string name = src.Name; if (!string.IsNullOrEmpty(name)) { return name; } } catch { } if (!string.IsNullOrEmpty(src.APIName)) { return src.APIName; } return $"Upgrade_{src.NumberID}"; } private static string SafeDescription(Upgrade src) { try { string description = src.Description; if (!string.IsNullOrEmpty(description) && description != src.Name) { return description; } } catch { } return string.Empty; } private static UpgradeProperty[] CloneProperties(Upgrade src) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) UpgradePropertyList properties = src.Properties; if (!((UpgradePropertyList)(ref properties)).HasProperties || ((UpgradePropertyList)(ref properties)).Count == 0) { return Array.Empty(); } List list = new List(((UpgradePropertyList)(ref properties)).Count); for (int i = 0; i < ((UpgradePropertyList)(ref properties)).Count; i++) { UpgradeProperty val = ((UpgradePropertyList)(ref properties))[i]; if (val != null) { object obj = DeepCloneObject(val); UpgradeProperty val2 = (UpgradeProperty)((obj is UpgradeProperty) ? obj : null); if (val2 != null) { list.Add(val2); } } } return list.ToArray(); } private static HexMap ClonePattern(Upgrade src) { try { object obj = GetMember(src, "Pattern") ?? GetMember(src, "pattern"); HexMap val = (HexMap)((obj is HexMap) ? obj : null); if (val == null) { return null; } return DeepCloneHexMap(val); } catch { return null; } } private static HexMap DeepCloneHexMap(HexMap src) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (src == null) { return null; } try { int width = src.Width; int height = src.Height; HexMap val = new HexMap(width, height); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { ref Node reference = ref src[j, i]; ref Node reference2 = ref val[j, i]; reference2.enabled = reference.enabled; reference2.connections = reference.connections; reference2.upgrade = null; } } return val; } catch { object obj2 = DeepCloneObject(src); return (HexMap)((obj2 is HexMap) ? obj2 : null); } } private static object DeepCloneObject(object source) { if (source == null) { return null; } Type type = source.GetType(); if (type.IsPrimitive || type.IsEnum || type == typeof(string) || type == typeof(decimal)) { return source; } Object val = (Object)((source is Object) ? source : null); if (val != null) { return val; } if (type.IsArray) { Array array = (Array)source; Array array2 = Array.CreateInstance(type.GetElementType(), array.Length); for (int i = 0; i < array.Length; i++) { array2.SetValue(DeepCloneObject(array.GetValue(i)), i); } return array2; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) { object obj = Activator.CreateInstance(type); MethodInfo method = type.GetMethod("Add"); { foreach (object item in (IEnumerable)source) { method?.Invoke(obj, new object[1] { DeepCloneObject(item) }); } return obj; } } object obj2; try { obj2 = Activator.CreateInstance(type); } catch { obj2 = FormatterServices.GetUninitializedObject(type); } Type type2 = type; while (type2 != null && type2 != typeof(object)) { FieldInfo[] fields = type2.GetFields(InstanceFlags | BindingFlags.DeclaredOnly); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsStatic) { object value = fieldInfo.GetValue(source); fieldInfo.SetValue(obj2, DeepCloneObject(value)); } } type2 = type2.BaseType; } return obj2; } private static object GetMember(object target, string name) { if (target == null) { return null; } Type type = target.GetType(); while (type != null) { FieldInfo field = type.GetField(name, InstanceFlags); if (field != null) { return field.GetValue(target); } PropertyInfo property = type.GetProperty(name, InstanceFlags); if (property != null && property.CanRead) { return property.GetValue(target); } type = type.BaseType; } return null; } } [Serializable] public class UpgradeProperty_MLR_TaintedExhaust : UpgradeProperty { public Range radius = new Range(3f, 5f); public Range damageScale = new Range(0.75f, 1f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create("Kill explosion size:", radius, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Explosion dmg (× DMR):", damageScale, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); EffectType val = (EffectType)(sbyte)((Random)(ref rand)).Next(1, 4); yield return new StatData("Applies", Global.GetEffect(val).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_002e: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.dmrKillExplosion = true; behaviour.WeaponData.dmrKillExplosionRadius += radius.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.dmrKillExplosionDamageScale = Mathf.Max(behaviour.WeaponData.dmrKillExplosionDamageScale, damageScale.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.dmrKillExplosionEffect = (EffectType)(sbyte)((Random)(ref rand)).Next(1, 4); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_Shredder : UpgradeProperty { public Range interval = new Range(1.2f, 1.8f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Laser periodically", Global.GetEffect((EffectType)4).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Interval:", interval, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.shredder = true; behaviour.WeaponData.shredderInterval = interval.GetValue(ref rand, upgrade, default(BoostParams)); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_DemonstratorsTrick : UpgradeProperty { public Range duration = new Range(2.5f, 3.5f); public Range damageMult = new Range(1.2f, 1.35f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create("Mode-switch buff:", damageMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Duration:", duration, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.demonstratorsTrick = true; behaviour.WeaponData.demoBuffDuration = duration.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.demoBuffDamageMult = Mathf.Max(behaviour.WeaponData.demoBuffDamageMult, damageMult.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_GravitationalCollapse : UpgradeProperty { public Range pullForce = new Range(14f, 22f); public Range pullRadius = new Range(6f, 10f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("With Kinetic Impossibility", "laser pulls enemies", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Pull force:", pullForce, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Pull radius:", pullRadius, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.gravitationalCollapse = true; behaviour.WeaponData.gravPullForce = Mathf.Max(behaviour.WeaponData.gravPullForce, pullForce.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.gravPullRadius = Mathf.Max(behaviour.WeaponData.gravPullRadius, pullRadius.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_CondensedMunitions : UpgradeProperty { public Range damagePerAmmo = new Range(0.3f, 0.4f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("DMR", "fires full magazine in one shot", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Dmg / ammo:", damagePerAmmo, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return new StatData("Pierce targets", "+1 per 10 ammo spent", (OverrideType)3, (LabelType)0, default(BoostParams)); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.condensedMunitions = true; behaviour.WeaponData.condensedDamagePerAmmo = Mathf.Max(behaviour.WeaponData.condensedDamagePerAmmo, damagePerAmmo.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_IncendiaryWave : UpgradeProperty { public Range interval = new Range(1f, 1.5f); public Range radius = new Range(2f, 3f); public Range damageScale = new Range(0.5f, 0.75f); public Range effectAmount = new Range(8f, 12f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Laser wave", Global.GetEffect((EffectType)1).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Interval:", interval, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Wave size:", radius, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00bb: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.incendiaryWave = true; behaviour.WeaponData.incendiaryInterval = interval.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.incendiaryRadius = Mathf.Max(behaviour.WeaponData.incendiaryRadius, radius.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.incendiaryDamageScale = Mathf.Max(behaviour.WeaponData.incendiaryDamageScale, damageScale.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.incendiaryEffectAmount = Mathf.Max(behaviour.WeaponData.incendiaryEffectAmount, effectAmount.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_Triple : UpgradeProperty { public Range effectAmount = new Range(8f, 12f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) EffectType val = (EffectType)((((Random)(ref rand)).NextFloat() < 0.5f) ? 2 : 3); yield return new StatData("DMR element", Global.GetEffect(val).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Effect amount:", effectAmount, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0028: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (!DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { return; } behaviour.WeaponData.tripleElement = true; EffectType val = (EffectType)((((Random)(ref rand)).NextFloat() < 0.5f) ? 2 : 3); behaviour.WeaponData.tripleEffect = val; float value = effectAmount.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.tripleEffectAmount = Mathf.Max(behaviour.WeaponData.tripleEffectAmount, value); Gun val2 = (Gun)(object)((gear is Gun) ? gear : null); if (val2 == null) { return; } try { GunData gunData = val2.GunData; gunData.damageEffect = val; if (value > 0f) { gunData.damageEffectAmount = Mathf.Max(gunData.damageEffectAmount, value); } val2.GunData = gunData; } catch { } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_ElementalEmitter : UpgradeProperty { public Range effectAmount = new Range(8f, 14f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) EffectType val = (EffectType)((((Random)(ref rand)).NextFloat() < 0.5f) ? 2 : 3); yield return new StatData("Laser element", Global.GetEffect(val).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Effect amount:", effectAmount, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0048: 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_0080: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) if (!DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { return; } EffectType val = (EffectType)((((Random)(ref rand)).NextFloat() < 0.5f) ? 2 : 3); float value = effectAmount.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.elementalEmitter = true; behaviour.WeaponData.elementalLaserEffect = val; behaviour.WeaponData.elementalLaserAmount = Mathf.Max(behaviour.WeaponData.elementalLaserAmount, value); ScoutLaserRifle val2 = (ScoutLaserRifle)(object)((gear is ScoutLaserRifle) ? gear : null); if (val2 == null) { return; } try { LaserGunData laserData = val2.LaserData; DamageData laserDamage = laserData.laserDamage; laserDamage.effect = val; if (value > 0f) { laserDamage.effectAmount = Mathf.Max(laserDamage.effectAmount, value); } laserData.laserDamage = laserDamage; val2.LaserData = laserData; } catch { } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_ReverseFalloff : UpgradeProperty { public Range maxDistanceMult = new Range(1.35f, 1.55f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create("Far damage:", maxDistanceMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.reverseFalloff = true; behaviour.WeaponData.reverseFalloffMaxMult = Mathf.Max(behaviour.WeaponData.reverseFalloffMaxMult, maxDistanceMult.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_OverheatedCapacitor : UpgradeProperty { public Range bonusPerSecond = new Range(0.08f, 0.12f); public Range maxBonus = new Range(0.75f, 1f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create("Laser dmg / sec:", bonusPerSecond, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Max bonus:", maxBonus, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_002e: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.overheatedCapacitor = true; behaviour.WeaponData.overheatDamagePerSecond += bonusPerSecond.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.overheatMaxBonus = Mathf.Max(behaviour.WeaponData.overheatMaxBonus, maxBonus.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_JointBreaker : UpgradeProperty { public Range everyN = new Range(3f, 3f); public Range decayAmount = new Range(8f, 12f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Every Nth limb hit", Global.GetEffect((EffectType)4).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Every N limb hits:", everyN, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Decay amount:", decayAmount, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0028: 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_005e: 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 (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.jointBreaker = true; behaviour.WeaponData.jointBreakerEveryN = Mathf.Max(2, Mathf.RoundToInt(everyN.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.jointBreakerDecayAmount = Mathf.Max(behaviour.WeaponData.jointBreakerDecayAmount, decayAmount.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_RotThread : UpgradeProperty { public Range everyN = new Range(3f, 3f); public Range rotAmount = new Range(8f, 12f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Every Nth shell hit", Global.GetEffect((EffectType)7).ColoredEffectName, (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Every N shell hits:", everyN, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Rot amount:", rotAmount, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0028: 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_005e: 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 (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.rotThread = true; behaviour.WeaponData.rotThreadEveryN = Mathf.Max(2, Mathf.RoundToInt(everyN.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.rotThreadRotAmount = Mathf.Max(behaviour.WeaponData.rotThreadRotAmount, rotAmount.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_FaultLine : UpgradeProperty { public Range bonusPerHit = new Range(0.06f, 0.1f); public Range maxBonus = new Range(0.4f, 0.6f); public Range resetTime = new Range(2f, 3f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Same-shell DMR hits", "escalate damage", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Bonus / hit:", bonusPerHit, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Max bonus:", maxBonus, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.faultLine = true; behaviour.WeaponData.faultLineBonusPerHit = Mathf.Max(behaviour.WeaponData.faultLineBonusPerHit, bonusPerHit.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.faultLineMaxBonus = Mathf.Max(behaviour.WeaponData.faultLineMaxBonus, maxBonus.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.faultLineResetTime = Mathf.Max(behaviour.WeaponData.faultLineResetTime, resetTime.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_ReactorTap : UpgradeProperty { public Range charge = new Range(3.5f, 6f); public Range ammoOnExposed = new Range(2f, 3f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Core kill", "refunds laser charge", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Charge refund:", charge, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Exposed core ammo:", ammoOnExposed, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.reactorTap = true; behaviour.WeaponData.reactorTapCharge = Mathf.Max(behaviour.WeaponData.reactorTapCharge, charge.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.reactorTapAmmoOnExposed = Mathf.Max(behaviour.WeaponData.reactorTapAmmoOnExposed, Mathf.RoundToInt(ammoOnExposed.GetValue(ref rand, upgrade, default(BoostParams)))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_CoreBrand : UpgradeProperty { public Range maxStacks = new Range(4f, 6f); public Range exposeDuration = new Range(3f, 4.5f); public Range markDuration = new Range(3.5f, 5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("DMR shell hits", "build Brand", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Stacks to Expose:", maxStacks, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Expose duration:", exposeDuration, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.coreBrand = true; behaviour.WeaponData.markOnDmrHit = true; behaviour.WeaponData.markDuration = Mathf.Max(behaviour.WeaponData.markDuration, markDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.coreBrandMaxStacks = Mathf.Max(behaviour.WeaponData.coreBrandMaxStacks, Mathf.RoundToInt(maxStacks.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.coreBrandExposeDuration = Mathf.Max(behaviour.WeaponData.coreBrandExposeDuration, exposeDuration.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_PhantomPain : UpgradeProperty { public Range damageMult = new Range(1.25f, 1.45f); public Range chargeRefund = new Range(1.5f, 3f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Regrown limb hits", "bonus damage + charge", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Damage:", damageMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Charge refund:", chargeRefund, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.phantomPain = true; behaviour.WeaponData.phantomPainDamageMult = Mathf.Max(behaviour.WeaponData.phantomPainDamageMult, damageMult.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.phantomPainChargeRefund = Mathf.Max(behaviour.WeaponData.phantomPainChargeRefund, chargeRefund.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_BleedCharge : UpgradeProperty { public Range charge = new Range(0.75f, 1.25f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Limb hits", "bonus laser charge", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Charge / limb hit:", charge, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_002e: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.bleedCharge = true; behaviour.WeaponData.bleedChargeAmount += charge.GetValue(ref rand, upgrade, default(BoostParams)); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_BreachCharge : UpgradeProperty { public Range charge = new Range(0.75f, 1.25f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Shell hits", "bonus laser charge", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Charge / shell hit:", charge, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_002e: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.breachCharge = true; behaviour.WeaponData.breachChargeAmount += charge.GetValue(ref rand, upgrade, default(BoostParams)); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_MarkedRecycling : UpgradeProperty { public Range ammoPerHit = new Range(0.25f, 0.45f); public Range markDuration = new Range(3.5f, 5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Laser on Marked/Exposed", "refunds DMR ammo", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Ammo / hit:", ammoPerHit, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.markedRecycling = true; behaviour.WeaponData.markOnDmrHit = true; behaviour.WeaponData.markDuration = Mathf.Max(behaviour.WeaponData.markDuration, markDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.markedRecyclingAmmoPerHit = Mathf.Max(behaviour.WeaponData.markedRecyclingAmmoPerHit, ammoPerHit.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_TripleFeed : UpgradeProperty_MLR_Triple { } [Serializable] public class UpgradeProperty_MLR_SympatheticArc : UpgradeProperty { public Range radius = new Range(6f, 10f); public Range damageScale = new Range(0.35f, 0.55f); public Range maxJumps = new Range(2f, 4f); public Range transferScale = new Range(0.25f, 0.4f); public Range markDuration = new Range(3.5f, 5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Laser on Marked", "arcs to nearby enemies", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Arc radius:", radius, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Arc damage:", damageScale, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.sympatheticArc = true; behaviour.WeaponData.markOnDmrHit = true; behaviour.WeaponData.markDuration = Mathf.Max(behaviour.WeaponData.markDuration, markDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.arcRadius = Mathf.Max(behaviour.WeaponData.arcRadius, radius.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.arcDamageScale = Mathf.Max(behaviour.WeaponData.arcDamageScale, damageScale.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.arcMaxJumps = Mathf.Max(behaviour.WeaponData.arcMaxJumps, Mathf.RoundToInt(maxJumps.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.arcTransferScale = Mathf.Max(behaviour.WeaponData.arcTransferScale, transferScale.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_SympatheticResonance : UpgradeProperty { public Range echoScale = new Range(0.15f, 0.28f); public Range markDuration = new Range(3.5f, 5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Marked damage", "echoes to other marks", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Echo:", echoScale, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.sympatheticResonance = true; behaviour.WeaponData.markOnDmrHit = true; behaviour.WeaponData.markDuration = Mathf.Max(behaviour.WeaponData.markDuration, markDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.resonanceEchoScale = Mathf.Max(behaviour.WeaponData.resonanceEchoScale, echoScale.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_CollapseWave : UpgradeProperty { public Range radius = new Range(4f, 6.5f); public Range hpScale = new Range(0.12f, 0.2f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Shell kill", "concussive pulse", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Pulse radius:", radius, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("× shell max HP:", hpScale, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.collapseWave = true; behaviour.WeaponData.collapseRadius = Mathf.Max(behaviour.WeaponData.collapseRadius, radius.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.collapseHpScale = Mathf.Max(behaviour.WeaponData.collapseHpScale, hpScale.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.collapseEffect = (EffectType)((!(((Random)(ref rand)).NextFloat() < 0.5f)) ? 1 : 2); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_VoltaicBatteryV2 : UpgradeProperty { public Range baseDamage = new Range(30f, 55f); public Range emptyMagBonus = new Range(1.25f, 1.75f); public Range transferPercent = new Range(0.25f, 0.45f); public Range radius = new Range(2.5f, 4.5f); public Range fuseTime = new Range(1.8f, 3f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("On reload", "throw voltaic battery", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Base damage:", baseDamage, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Empty-mag power:", emptyMagBonus, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Inward transfer:", transferPercent, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.voltaicBattery = false; behaviour.WeaponData.voltaicBatteryV2 = true; behaviour.WeaponData.batteryBaseDamage = Mathf.Max(behaviour.WeaponData.batteryBaseDamage, baseDamage.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.batteryEmptyMagBonus = Mathf.Max(behaviour.WeaponData.batteryEmptyMagBonus, emptyMagBonus.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.batteryTransferPercent = Mathf.Max(behaviour.WeaponData.batteryTransferPercent, transferPercent.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.batteryRadius = Mathf.Max(behaviour.WeaponData.batteryRadius, radius.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.batteryFuseTime = Mathf.Max(behaviour.WeaponData.batteryFuseTime, fuseTime.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_DemonstratorsTrickV2 : UpgradeProperty { public Range markSpreadRadius = new Range(5f, 8f); public Range heavyMarkDuration = new Range(4f, 6f); public Range heavyMarkDamageMult = new Range(1.25f, 1.45f); public Range markDuration = new Range(3.5f, 5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("DMR→Laser", "next laser spreads Mark", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return new StatData("Laser→DMR", "next DMR heavy Mark + dmg", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Heavy Mark dmg:", heavyMarkDamageMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.demonstratorsTrick = false; behaviour.WeaponData.demoTrickV2 = true; behaviour.WeaponData.markOnDmrHit = true; behaviour.WeaponData.markDuration = Mathf.Max(behaviour.WeaponData.markDuration, markDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.demoMarkSpreadRadius = Mathf.Max(behaviour.WeaponData.demoMarkSpreadRadius, markSpreadRadius.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.demoHeavyMarkDuration = Mathf.Max(behaviour.WeaponData.demoHeavyMarkDuration, heavyMarkDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.demoHeavyMarkDamageMult = Mathf.Max(behaviour.WeaponData.demoHeavyMarkDamageMult, heavyMarkDamageMult.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_BreachAmmo : UpgradeProperty { public Range maxAmmo = new Range(80f, 120f); public Range perLaserHit = new Range(3f, 5.5f); public Range perLaserTick = new Range(1.5f, 3.5f); public Range slugCost = new Range(15f, 25f); public Range slugDamageMult = new Range(1.5f, 2f); public Range slugShellMult = new Range(1.2f, 1.5f); public Range breakTransferBonus = new Range(0.15f, 0.35f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Laser builds", "Breach Ammo", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return new StatData("DMR spends Breach Ammo", "for heavy slugs", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Slug damage:", slugDamageMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Max Breach Ammo:", maxAmmo, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.breachAmmoSystem = true; behaviour.WeaponData.breachAmmoMax = Mathf.Max(behaviour.WeaponData.breachAmmoMax, maxAmmo.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachAmmoPerLaserHit = Mathf.Max(behaviour.WeaponData.breachAmmoPerLaserHit, perLaserHit.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachAmmoPerLaserTick = Mathf.Max(behaviour.WeaponData.breachAmmoPerLaserTick, perLaserTick.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachSlugCost = Mathf.Max(5f, slugCost.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachSlugDamageMult = Mathf.Max(behaviour.WeaponData.breachSlugDamageMult, slugDamageMult.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachSlugShellMult = Mathf.Max(behaviour.WeaponData.breachSlugShellMult, slugShellMult.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.breachBreakTransferBonus = Mathf.Max(behaviour.WeaponData.breachBreakTransferBonus, breakTransferBonus.GetValue(ref rand, upgrade, default(BoostParams))); ScoutLaserRifle val = (ScoutLaserRifle)(object)((gear is ScoutLaserRifle) ? gear : null); if (val != null && UpgradeFlagsExtensions.IsEnabled(((Gun)val).UpgradeFlags, (DMLRUpgradeFlags)8)) { behaviour.WeaponData.hotSwapRoles = true; } } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_SeveranceCycle : UpgradeProperty { public Range interval = new Range(3.5f, 5f); public Range laserWindow = new Range(1.5f, 2.5f); public Range stacksPerLimb = new Range(1f, 2f); public Range stacksToPulse = new Range(3f, 5f); public Range pulseTransfer = new Range(0.25f, 0.45f); public Range pulseDamageScale = new Range(0.8f, 1.2f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Auto-cycles", "DMR ↔ Laser", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return new StatData("Limb hits build", "Dissection stacks", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Cycle interval:", interval, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Pulse transfer:", pulseTransfer, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.severanceCycle = true; behaviour.WeaponData.cycleInterval = Mathf.Max(2f, interval.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.cycleLaserWindow = Mathf.Max(0.75f, laserWindow.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.dissectionStacksPerLimbHit = Mathf.Max(1, Mathf.RoundToInt(stacksPerLimb.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.dissectionStacksToPulse = Mathf.Max(2, Mathf.RoundToInt(stacksToPulse.GetValue(ref rand, upgrade, default(BoostParams)))); behaviour.WeaponData.dissectionPulseTransferPercent = Mathf.Max(behaviour.WeaponData.dissectionPulseTransferPercent, pulseTransfer.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.dissectionPulseDamageScale = Mathf.Max(behaviour.WeaponData.dissectionPulseDamageScale, pulseDamageScale.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [BepInPlugin("sparroh.dmlrrework", "DMLRRework", "1.0.0")] [MycoMod(/*Could not decode attribute arguments.*/)] public class SparrohPlugin : BaseUnityPlugin { public const string PluginGUID = "sparroh.dmlrrework"; public const string PluginName = "DMLRRework"; public const string PluginVersion = "1.0.0"; public const int ExampleGearId = 91000; public const string ExampleGearApiName = "dmlr_rework"; public const string ExampleGearDisplayName = "Marksman Laser Rifle"; public const string ExampleGearDescription = "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."; public const string ExampleBaseTypeName = "ScoutLaserRifle"; public const float LaserChargeHitsToFull = 20f; internal static ManualLogSource Logger; internal static SparrohPlugin Instance; public static IUpgradable CustomWeaponPrefab; private Harmony _harmony; private bool _gearRegistered; private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("sparroh.dmlrrework"); _harmony.PatchAll(typeof(GlobalLoadHook)); _harmony.PatchAll(typeof(PlayerDataPersistenceHooks)); _harmony.PatchAll(typeof(DmlrReworkPatches)); _harmony.PatchAll(typeof(GearSelectionWindowHooks)); SpawnGearHooks.Apply(_harmony); PlayerData.AddRegisterUpgradesCallback((Action)TryRegisterUpgrades); TryRegisterGear("Awake"); TryRegisterUpgrades(); Logger.LogInfo((object)"DMLRRework v1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Instance = null; } internal void TryRegisterGear(string reason) { if (_gearRegistered) { return; } if ((Object)(object)Global.Instance == (Object)null || Global.Instance.AllGear == null || Global.Instance.AllGear.Length == 0) { Logger.LogDebug((object)("[DMLRRework] Global.AllGear not ready yet (" + reason + ").")); return; } try { if (WeaponRegistration.TryCreateAndRegister("sparroh.dmlrrework", 91000, "dmlr_rework", "Marksman Laser Rifle", "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.", "ScoutLaserRifle", autoUnlock: true, Logger, out CustomWeaponPrefab)) { _gearRegistered = true; Logger.LogInfo((object)("[DMLRRework] Registered gear 'Marksman Laser Rifle' " + string.Format("(api={0}, id={1}) via {2}.", "dmlr_rework", 91000, reason))); } } catch (Exception arg) { Logger.LogError((object)$"[DMLRRework] Gear registration failed: {arg}"); } } internal void TryRegisterUpgrades() { if (!_gearRegistered) { return; } if (PlayerData.Instance == null) { Logger.LogDebug((object)"[DMLRRework] Defer upgrades — PlayerData.Instance null."); return; } try { DmlrUpgradePort.TryRegister(Logger); } catch (Exception arg) { Logger.LogError((object)$"[DMLRRework] Upgrade port failed: {arg}"); } } internal static IUpgradable ResolveRegisteredGear() { if (CustomWeaponPrefab != null) { return CustomWeaponPrefab; } if (WeaponRegistration.CatalogGear != null) { return WeaponRegistration.CatalogGear; } return WeaponRegistration.FindGearSafe("dmlr_rework", 91000); } internal static bool IsOurGear(IUpgradable gear) { if (gear == null) { return false; } if (gear == CustomWeaponPrefab || gear == WeaponRegistration.CatalogGear) { return true; } if ((Object)(object)gear.Info != (Object)null) { if (gear.Info.APIName == "dmlr_rework") { return true; } if (gear.Info.ID == 91000) { return true; } } IGear val = (IGear)(object)((gear is IGear) ? gear : null); if (val != null && ((IUpgradable)val).Prefab != null) { if (((IUpgradable)val).Prefab == CustomWeaponPrefab || ((IUpgradable)val).Prefab == WeaponRegistration.CatalogGear) { return true; } if ((Object)(object)((IUpgradable)val).Prefab.Info != (Object)null && (((IUpgradable)val).Prefab.Info.APIName == "dmlr_rework" || ((IUpgradable)val).Prefab.Info.ID == 91000)) { return true; } } return false; } } [HarmonyPatch(typeof(Global), "LoadInstance")] internal static class GlobalLoadHook { [HarmonyPostfix] private static void Postfix() { SparrohPlugin.Instance?.TryRegisterGear("Global.LoadInstance"); } } [HarmonyPatch(typeof(PlayerData), "OnAwake")] internal static class PlayerDataPersistenceHooks { [HarmonyPrefix] private static void Prefix() { SparrohPlugin.Instance?.TryRegisterGear("PlayerData.OnAwake.Prefix"); } [HarmonyPostfix] private static void Postfix() { try { SparrohPlugin.Instance?.TryRegisterGear("PlayerData.OnAwake.Postfix"); IUpgradable val = SparrohPlugin.ResolveRegisteredGear(); if (val == null) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogWarning((object)"[DMLRRework] Persistence: gear missing after OnAwake."); } return; } GearData gearData = PlayerData.GetGearData(val); if (gearData == null) { WeaponRegistration.EnsureGearData(val, autoUnlock: true, SparrohPlugin.Logger); gearData = PlayerData.GetGearData(val); } else { gearData.Gear = val; } SparrohPlugin.Instance?.TryRegisterUpgrades(); if (gearData != null) { if (!gearData.IsUnlocked) { gearData.Unlock(); } ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { string text = $"[DMLRRework] Persistence OK: level={gearData.Level} unlocked={gearData.IsUnlocked} "; string text2 = $"equipped={gearData.EquippedUpgradeCount} xp={gearData.LevelXP} "; object arg = PlayerData.HasUpgrades(val); GearInfo info = val.Info; logger2.LogInfo((object)(text + text2 + $"HasUpgrades={arg} HasGrid={((info != null) ? new bool?(info.HasUpgradeGrid) : ((bool?)null))} " + $"ported={DmlrUpgradePort.PortedCount}.")); } } } catch (Exception arg2) { ManualLogSource logger3 = SparrohPlugin.Logger; if (logger3 != null) { logger3.LogError((object)$"[DMLRRework] Persistence postfix failed: {arg2}"); } } } } [Serializable] public class UpgradeProperty_MLR_NeuralFeedback : UpgradeProperty { public Range dmrTransfer = new Range(0.08f, 0.12f); public Range laserTransfer = new Range(0.2f, 0.3f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Limb damage", "transfers to Core", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("DMR transfer:", dmrTransfer, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Laser transfer:", laserTransfer, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0015: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { float value = dmrTransfer.GetValue(ref rand, upgrade, default(BoostParams)); float value2 = laserTransfer.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.transferDmrPercent = Mathf.Max(behaviour.WeaponData.transferDmrPercent, value); behaviour.WeaponData.transferLaserPercent = Mathf.Max(behaviour.WeaponData.transferLaserPercent, value2); behaviour.WeaponData.transferFromLimbs = true; } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_ArterialShred : UpgradeProperty { public Range limbDamage = new Range(1.35f, 1.65f); public Range shellDamage = new Range(0.75f, 0.85f); public Range arteryDuration = new Range(2.5f, 3.5f); public Range arteryTransferBonus = new Range(0.12f, 0.2f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create(TextBlocks.GetString("limb_d"), limbDamage, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create(TextBlocks.GetString("shell_d"), shellDamage, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return new StatData("Limb hits", "Open Artery (bonus laser transfer)", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Artery bonus transfer:", arteryTransferBonus, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0015: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0088: 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_00b9: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { float value = limbDamage.GetValue(ref rand, upgrade, default(BoostParams)); float value2 = shellDamage.GetValue(ref rand, upgrade, default(BoostParams)); CombineMult(ref behaviour.WeaponData.limbDamageMult, value); CombineMult(ref behaviour.WeaponData.shellDamageMult, value2); behaviour.WeaponData.arterialShred = true; behaviour.WeaponData.openArteryDuration = Mathf.Max(behaviour.WeaponData.openArteryDuration, arteryDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.openArteryTransferBonus = Mathf.Max(behaviour.WeaponData.openArteryTransferBonus, arteryTransferBonus.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } private static void CombineMult(ref float current, float incoming) { if (Mathf.Approximately(current, 1f) || current <= 0f) { current = incoming; } else { current += incoming - 1f; } } } [Serializable] public class UpgradeProperty_MLR_Pulverizer : UpgradeProperty { public Range limbDamage = new Range(0.73f, 0.82f); public Range shellDamage = new Range(1.22f, 1.31f); public Range inwardSplash = new Range(0.1f, 0.16f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create(TextBlocks.GetString("limb_d"), limbDamage, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create(TextBlocks.GetString("shell_d"), shellDamage, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Inward splash:", inwardSplash, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0015: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { float value = limbDamage.GetValue(ref rand, upgrade, default(BoostParams)); float value2 = shellDamage.GetValue(ref rand, upgrade, default(BoostParams)); float value3 = inwardSplash.GetValue(ref rand, upgrade, default(BoostParams)); if (Mathf.Approximately(behaviour.WeaponData.limbDamageMult, 1f) || behaviour.WeaponData.limbDamageMult <= 0f) { behaviour.WeaponData.limbDamageMult = value; } else { behaviour.WeaponData.limbDamageMult += value - 1f; } if (Mathf.Approximately(behaviour.WeaponData.shellDamageMult, 1f) || behaviour.WeaponData.shellDamageMult <= 0f) { behaviour.WeaponData.shellDamageMult = value2; } else { behaviour.WeaponData.shellDamageMult += value2 - 1f; } behaviour.WeaponData.pulverizer = true; behaviour.WeaponData.shellInwardSplashPercent = Mathf.Max(behaviour.WeaponData.shellInwardSplashPercent, value3); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_OverkillConduit : UpgradeProperty { public Range overkillMult = new Range(1.5f, 2.25f); public Range markedBonus = new Range(1.25f, 1.5f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Limb kill overkill", "transfers inward", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Overkill mult:", overkillMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("If Marked:", markedBonus, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.overkillConduit = true; behaviour.WeaponData.overkillTransferMult = Mathf.Max(behaviour.WeaponData.overkillTransferMult, overkillMult.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.overkillMarkedBonusMult = Mathf.Max(behaviour.WeaponData.overkillMarkedBonusMult, markedBonus.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } [Serializable] public class UpgradeProperty_MLR_HardLightDesignator : UpgradeProperty { public Range exposeDuration = new Range(3.5f, 5f); public Range exposeDamageMult = new Range(1.25f, 1.4f); public Range chargeRefund = new Range(2f, 4f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return new StatData("Shell kills", "Expose Core", (OverrideType)3, (LabelType)0, default(BoostParams)); yield return StatData.Create("Expose duration:", exposeDuration, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Exposed core dmg:", exposeDamageMult, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); yield return StatData.Create("Laser charge on Exposed:", chargeRefund, upgrade, ref rand, (OverrideType)1, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0032: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.WeaponData.hardLightDesignator = true; behaviour.WeaponData.exposeDuration = Mathf.Max(behaviour.WeaponData.exposeDuration, exposeDuration.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.exposeDamageMult = Mathf.Max(behaviour.WeaponData.exposeDamageMult, exposeDamageMult.GetValue(ref rand, upgrade, default(BoostParams))); behaviour.WeaponData.exposeChargeRefund = Mathf.Max(behaviour.WeaponData.exposeChargeRefund, chargeRefund.GetValue(ref rand, upgrade, default(BoostParams))); } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } internal static class SeveranceSystem { public enum PartKind : byte { None, Limb, Shell, Core, Other } public static bool DebugTransfer = true; private static readonly Color DebugTransferTextColor = new Color(0.45f, 0.95f, 1f, 1f); public const DamageFlags TransferFlag = (DamageFlags)4; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsTransferHit(in DamageData data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 return (data.damageFlags & 4) > 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsTransferHit(in DamageCallbackData data) { return IsTransferHit(in data.damageData); } public static PartKind GetPartKind(ITarget target) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (target == null) { return PartKind.None; } if (target is EnemyLimbPart) { return PartKind.Limb; } if (target is EnemyShell) { return PartKind.Shell; } if (target is EnemyCore) { return PartKind.Core; } EnemyPart val = (EnemyPart)(object)((target is EnemyPart) ? target : null); if (val != null) { EnemyComponentType componentType = val.ComponentType; if ((componentType & 0x18) != 0) { return PartKind.Limb; } if ((componentType & 4) != 0) { return PartKind.Shell; } if ((componentType & 2) != 0) { return PartKind.Core; } return PartKind.Other; } return PartKind.None; } public static EnemyPart AsEnemyPart(ITarget target) { return (EnemyPart)(object)((target is EnemyPart) ? target : null); } public static EnemyBrain GetBrain(ITarget target) { EnemyPart val = (EnemyPart)(object)((target is EnemyPart) ? target : null); if (val != null) { return val.Brain; } return null; } public static EnemyCore GetCore(ITarget target) { return GetCore(GetBrain(target)); } public static EnemyCore GetCore(EnemyBrain brain) { if ((Object)(object)brain == (Object)null) { return null; } try { EnemyCore core = brain.Core; return (core is EnemyCore) ? core : null; } catch { return null; } } public static bool CanCoreAcceptNormalDamage(EnemyCore core) { if ((Object)(object)core == (Object)null || !((EnemyPart)core).IsAlive) { return false; } try { if (core.canTakeDamageWhileAllChildrenLive) { return true; } return core.currentChildCount < core.initialChildCount; } catch { return !HasLivingShellChild((EnemyPart)(object)core); } } public static bool HasLivingShellChild(EnemyPart part) { if (((part != null) ? part.ChildComponents : null) == null) { return false; } List childComponents = part.ChildComponents; for (int i = 0; i < childComponents.Count; i++) { IEnemyComponent obj = childComponents[i]; EnemyShell val = (EnemyShell)(object)((obj is EnemyShell) ? obj : null); if (val != null && ((EnemyPart)val).IsAlive) { return true; } } return false; } public static bool IsLimbPart(ITarget target) { return GetPartKind(target) == PartKind.Limb; } public static EnemyPart FindTransferDestination(EnemyPart from) { return FindTransferDestination(from, null); } public static EnemyPart FindTransferDestination(EnemyPart from, DmlrReworkBehaviour behaviour) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)from == (Object)null) { return null; } EnemyBrain brain = from.Brain; EnemyCore val = (((Object)(object)brain != (Object)null) ? GetCore(brain) : null); if ((Object)(object)brain == (Object)null && (Object)(object)val == (Object)null) { return null; } int num = (((Object)(object)brain != (Object)null) ? ((Object)brain).GetInstanceID() : 0); List list = new List(16); if ((Object)(object)val != (Object)null) { CollectLivingShells((EnemyPart)(object)val, list); } else if ((Object)(object)brain != (Object)null) { CollectLivingShellsFromBrain(brain, list); } if (list.Count == 0) { ClearDrillFocus(behaviour, num); if ((Object)(object)val != (Object)null && ((EnemyPart)val).IsAlive && (object)val != from && CanCoreAcceptNormalDamage(val)) { return (EnemyPart)(object)val; } return null; } if ((Object)(object)behaviour != (Object)null && behaviour.drillFocusBrainId == num && behaviour.drillFocusPartId != 0) { EnemyPart val2 = FindShellById(list, behaviour.drillFocusPartId); if ((Object)(object)val2 != (Object)null && val2.IsAlive) { behaviour.drillFocusLastPos = ((Component)val2).transform.position; return val2; } EnemyPart val3 = PickInwardAfterFocusDeath(list, behaviour.drillFocusLastPos, behaviour.drillFocusDepth); if ((Object)(object)val3 != (Object)null) { SetDrillFocus(behaviour, num, val3); return val3; } if ((Object)(object)val != (Object)null && ((EnemyPart)val).IsAlive && CanCoreAcceptNormalDamage(val) && (object)val != from) { ClearDrillFocus(behaviour, num); return (EnemyPart)(object)val; } ClearDrillFocus(behaviour, num); } if ((Object)(object)val != (Object)null && ((EnemyPart)val).IsAlive && (object)val != from && CanCoreAcceptNormalDamage(val) && !HasLivingShellChild((EnemyPart)(object)val)) { ClearDrillFocus(behaviour, num); return (EnemyPart)(object)val; } EnemyPart val4 = PickWeakestOutermost(list); if ((Object)(object)val4 != (Object)null) { SetDrillFocus(behaviour, num, val4); return val4; } if ((Object)(object)val != (Object)null && ((EnemyPart)val).IsAlive && CanCoreAcceptNormalDamage(val) && (object)val != from) { return (EnemyPart)(object)val; } return null; } public static int GetShellDepthFromCore(EnemyPart shell) { if ((Object)(object)shell == (Object)null) { return -1; } int num = 0; IEnemyComponent parent = shell.Parent; int num2 = 0; while (parent != null && num2++ < 16) { if (parent is EnemyCore) { return num; } if (parent is EnemyShell) { num++; } parent = parent.Parent; } return num; } private static void CollectLivingShells(EnemyPart root, List into) { if (((root != null) ? root.ChildComponents : null) == null) { return; } List childComponents = root.ChildComponents; for (int i = 0; i < childComponents.Count; i++) { IEnemyComponent obj = childComponents[i]; EnemyPart val = (EnemyPart)(object)((obj is EnemyPart) ? obj : null); if (val != null && val.IsAlive) { EnemyShell val2 = (EnemyShell)(object)((val is EnemyShell) ? val : null); if (val2 != null) { into.Add(val2); } CollectLivingShells(val, into); } } } private static void CollectLivingShellsFromBrain(EnemyBrain brain, List into) { EnemyCore core = GetCore(brain); if ((Object)(object)core != (Object)null) { CollectLivingShells((EnemyPart)(object)core, into); } } private static EnemyPart FindShellById(List shells, int partId) { for (int i = 0; i < shells.Count; i++) { if (GetPartId((EnemyPart)(object)shells[i]) == partId) { return (EnemyPart)(object)shells[i]; } } return null; } private static EnemyPart PickWeakestOutermost(List shells) { if (shells == null || shells.Count == 0) { return null; } int num = int.MinValue; for (int i = 0; i < shells.Count; i++) { int shellDepthFromCore = GetShellDepthFromCore((EnemyPart)(object)shells[i]); if (shellDepthFromCore > num) { num = shellDepthFromCore; } } EnemyShell val = null; float num2 = float.MaxValue; for (int j = 0; j < shells.Count; j++) { EnemyShell val2 = shells[j]; if (GetShellDepthFromCore((EnemyPart)(object)val2) == num) { float health = ((EnemyPart)val2).Health; if ((Object)(object)val == (Object)null || health < num2 - 0.01f || (Mathf.Abs(health - num2) <= 0.01f && GetPartId((EnemyPart)(object)val2) < GetPartId((EnemyPart)(object)val))) { val = val2; num2 = health; } } } return (EnemyPart)(object)val; } private static EnemyPart PickInwardAfterFocusDeath(List shells, Vector3 holePos, int deadFocusDepth) { //IL_006e: 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_0074: 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_00f4: 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_00ff: Unknown result type (might be due to invalid IL or missing references) if (shells == null || shells.Count == 0) { return null; } EnemyShell val = null; float num = float.MaxValue; Vector3 val3; for (int i = 0; i < shells.Count; i++) { EnemyShell val2 = shells[i]; int shellDepthFromCore = GetShellDepthFromCore((EnemyPart)(object)val2); float num2 = ((deadFocusDepth >= 0 && shellDepthFromCore > deadFocusDepth) ? (1000f + (float)shellDepthFromCore) : ((deadFocusDepth < 0 || shellDepthFromCore != deadFocusDepth) ? ((float)((deadFocusDepth >= 0) ? (deadFocusDepth - shellDepthFromCore) : 0) * 0.01f) : 500f)); val3 = ((Component)val2).transform.position - holePos; float num3 = ((Vector3)(ref val3)).sqrMagnitude + num2 + ((EnemyPart)val2).Health * 0.05f; if (num3 < num) { num = num3; val = val2; } } if ((Object)(object)val != (Object)null && deadFocusDepth >= 0 && GetShellDepthFromCore((EnemyPart)(object)val) >= deadFocusDepth) { EnemyShell val4 = null; float num4 = float.MaxValue; for (int j = 0; j < shells.Count; j++) { EnemyShell val5 = shells[j]; if (GetShellDepthFromCore((EnemyPart)(object)val5) < deadFocusDepth) { val3 = ((Component)val5).transform.position - holePos; float num5 = ((Vector3)(ref val3)).sqrMagnitude + ((EnemyPart)val5).Health * 0.05f; if (num5 < num4) { num4 = num5; val4 = val5; } } } if ((Object)(object)val4 != (Object)null) { return (EnemyPart)(object)val4; } return null; } return (EnemyPart)(object)val; } private static void SetDrillFocus(DmlrReworkBehaviour b, int brainId, EnemyPart shell) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)b == (Object)null) && !((Object)(object)shell == (Object)null)) { b.drillFocusBrainId = brainId; b.drillFocusPartId = GetPartId(shell); b.drillFocusLastPos = ((Component)shell).transform.position; b.drillFocusDepth = GetShellDepthFromCore(shell); } } private static void ClearDrillFocus(DmlrReworkBehaviour b, int brainId) { if (!((Object)(object)b == (Object)null) && (b.drillFocusBrainId == 0 || b.drillFocusBrainId == brainId)) { b.drillFocusBrainId = 0; b.drillFocusPartId = 0; b.drillFocusDepth = 0; } } public static EnemyPart FindLivingShell(EnemyPart root, EnemyPart exclude) { if (((root != null) ? root.ChildComponents : null) == null) { return null; } List childComponents = root.ChildComponents; for (int i = 0; i < childComponents.Count; i++) { IEnemyComponent obj = childComponents[i]; EnemyPart val = (EnemyPart)(object)((obj is EnemyPart) ? obj : null); if (val != null && val.IsAlive && val != exclude) { if (val is EnemyShell) { return val; } EnemyPart val2 = FindLivingShell(val, exclude); if ((Object)(object)val2 != (Object)null) { return val2; } } } return null; } public static bool DealTransferDamage(IDamageSource source, EnemyPart destination, float damage, EffectType effect, float effectAmount, Vector3 hitPoint) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return DealTransferDamage(source, destination, damage, effect, effectAmount, hitPoint, null); } public static bool DealTransferDamage(IDamageSource source, EnemyPart destination, float damage, EffectType effect, float effectAmount, Vector3 hitPoint, EnemyPart fromPart) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00d0: Unknown result type (might be due to invalid IL or missing references) if (source == null || (Object)(object)destination == (Object)null || !destination.IsAlive) { if (DebugTransfer) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogInfo((object)("[Severance] Transfer SKIP dest=" + (((Object)(object)destination == (Object)null) ? "null" : PartLabel(destination)) + " " + $"alive={(Object)(object)destination != (Object)null && destination.IsAlive} dmg={damage:F1}")); } } return false; } if (damage <= 0.01f) { return false; } DamageData val = default(DamageData); ((DamageData)(ref val))..ctor(damage, (EffectType)(((int)effect > 0) ? ((int)effect) : 0), effectAmount, (DamageFlags)132); Vector3 position = (((Object)(object)((Component)destination).transform != (Object)null) ? ((Component)destination).transform.position : hitPoint); try { bool flag = IDamageSource.DamageTarget(source, (ITarget)(object)destination, val, hitPoint, (Collider)null); if (DebugTransfer) { NotifyTransferDebug(fromPart, destination, damage, flag, position); } return flag; } catch (Exception ex) { ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)("[Severance] Transfer failed: " + ex.Message)); } return false; } } private static void NotifyTransferDebug(EnemyPart from, EnemyPart dest, float damage, bool applied, Vector3 position) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) string text = PartLabel(from); string text2 = PartLabel(dest); string text3 = (applied ? "OK" : "BLOCKED"); ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogInfo((object)$"[Severance] Transfer {text3}: {text} → {text2} dmg={damage:F1}"); } try { Highlighter instance = default(Highlighter); if (!Highlighter.TryGetInstance(ref instance) && (Highlighter.Instance == null || !((Object)(object)(instance = Highlighter.Instance) != (Object)null))) { return; } string text4 = (applied ? $"XFER {damage:F0}→{ShortKind(dest)}" : ("XFER blocked→" + ShortKind(dest))); instance.ShowDamageText((ITarget)(object)dest, position, text4, DebugTransferTextColor); if (applied) { if (dest != null) { instance.ActivateHealthDisplay((ISelectable)(object)dest, instance.HighlightMaterial, false, 4f); } } } catch (Exception ex) { ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { logger2.LogDebug((object)("[Severance] debug VFX: " + ex.Message)); } } } private static string PartLabel(EnemyPart part) { if ((Object)(object)part == (Object)null) { return "null"; } string name = ((Object)part).name; if (string.IsNullOrEmpty(name)) { name = ((object)part).GetType().Name; } return ShortKind(part) + ":" + name; } private static string ShortKind(EnemyPart part) { return GetPartKind((ITarget)(object)part) switch { PartKind.Limb => "Limb", PartKind.Shell => "Shell", PartKind.Core => "Core", PartKind.Other => "Other", _ => "?", }; } public static float GetTransferPercent(DmlrReworkBehaviour behaviour, bool laserMode) { if ((Object)(object)behaviour == (Object)null) { return 0f; } ref DmlrReworkBehaviour.Data weaponData = ref behaviour.WeaponData; float num = (laserMode ? weaponData.transferLaserPercent : weaponData.transferDmrPercent); if (weaponData.hotSwapRoles) { num = (laserMode ? weaponData.transferDmrPercent : weaponData.transferLaserPercent); } return Mathf.Max(0f, num); } public static void ApplyMark(DmlrReworkBehaviour b, EnemyPart part, float duration) { if (!((Object)(object)b == (Object)null) && !((Object)(object)part == (Object)null) && !(duration <= 0f)) { int partId = GetPartId(part); if (partId != 0) { float value = Time.time + duration; b.EnsureMarkMap()[partId] = value; } } } public static bool IsMarked(DmlrReworkBehaviour b, EnemyPart part) { if (b?.markExpiries == null || (Object)(object)part == (Object)null) { return false; } int partId = GetPartId(part); if (partId == 0) { return false; } if (!b.markExpiries.TryGetValue(partId, out var value)) { return false; } if (Time.time > value) { b.markExpiries.Remove(partId); return false; } return true; } public static void ExposeBrain(DmlrReworkBehaviour b, EnemyBrain brain, float duration) { if (!((Object)(object)b == (Object)null) && !((Object)(object)brain == (Object)null) && !(duration <= 0f)) { int instanceID = ((Object)brain).GetInstanceID(); float num = Time.time + duration; Dictionary dictionary = b.EnsureExposeMap(); if (!dictionary.TryGetValue(instanceID, out var value) || !(value > num)) { dictionary[instanceID] = num; } } } public static bool IsBrainExposed(DmlrReworkBehaviour b, EnemyBrain brain) { if (b?.exposeExpiries == null || (Object)(object)brain == (Object)null) { return false; } int instanceID = ((Object)brain).GetInstanceID(); if (!b.exposeExpiries.TryGetValue(instanceID, out var value)) { return false; } if (Time.time > value) { b.exposeExpiries.Remove(instanceID); return false; } return true; } public static bool IsTargetExposed(DmlrReworkBehaviour b, ITarget target) { EnemyBrain brain = GetBrain(target); return IsBrainExposed(b, brain); } public static void ApplyOpenArtery(DmlrReworkBehaviour b, EnemyBrain brain, float duration) { if (!((Object)(object)b == (Object)null) && !((Object)(object)brain == (Object)null) && !(duration <= 0f)) { b.openArteryBrainId = ((Object)brain).GetInstanceID(); b.openArteryExpiry = Time.time + duration; } } public static bool TryConsumeOpenArtery(DmlrReworkBehaviour b, EnemyBrain brain, out float bonusTransfer) { bonusTransfer = 0f; if ((Object)(object)b == (Object)null || (Object)(object)brain == (Object)null) { return false; } if (b.openArteryBrainId == 0 || Time.time > b.openArteryExpiry) { b.openArteryBrainId = 0; return false; } if (((Object)brain).GetInstanceID() != b.openArteryBrainId) { return false; } bonusTransfer = Mathf.Max(0f, b.WeaponData.openArteryTransferBonus); b.openArteryBrainId = 0; b.openArteryExpiry = 0f; return bonusTransfer > 0f; } public static void RecordPotentialOverkill(DmlrReworkBehaviour b, EnemyPart part, float rawDamage) { if (!((Object)(object)b == (Object)null) && !((Object)(object)part == (Object)null) && !(rawDamage <= 0f)) { float health = part.Health; float num = rawDamage - health; if (num <= 0.01f && num < 0f) { num = 0f; } b.pendingOverkillPartId = GetPartId(part); b.pendingOverkillAmount = Mathf.Max(0f, num); b.pendingOverkillTime = Time.time; } } public static bool TryTakeOverkill(DmlrReworkBehaviour b, EnemyPart killed, out float overkill) { overkill = 0f; if ((Object)(object)b == (Object)null || (Object)(object)killed == (Object)null) { return false; } if (b.pendingOverkillPartId == 0) { return false; } if (Time.time - b.pendingOverkillTime > 0.35f) { ClearOverkill(b); return false; } if (GetPartId(killed) != b.pendingOverkillPartId) { return false; } overkill = b.pendingOverkillAmount; ClearOverkill(b); return true; } public static void ClearOverkill(DmlrReworkBehaviour b) { if (!((Object)(object)b == (Object)null)) { b.pendingOverkillPartId = 0; b.pendingOverkillAmount = 0f; b.pendingOverkillTime = 0f; } } public static int GetPartId(EnemyPart part) { if ((Object)(object)part == (Object)null) { return 0; } try { if (((NetworkBehaviour)part).IsSpawned) { return (int)((NetworkBehaviour)part).NetworkObjectId; } } catch { } return ((Object)part).GetInstanceID(); } public static void PruneExpired(DmlrReworkBehaviour b) { if (!((Object)(object)b == (Object)null)) { float time = Time.time; PruneMap(b.markExpiries, time); PruneMap(b.exposeExpiries, time); if (b.openArteryBrainId != 0 && time > b.openArteryExpiry) { b.openArteryBrainId = 0; b.openArteryExpiry = 0f; } } } private static void PruneMap(Dictionary map, float now) { if (map == null || map.Count == 0) { return; } List list = null; foreach (KeyValuePair item in map) { if (now > item.Value) { if (list == null) { list = new List(4); } list.Add(item.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { map.Remove(list[i]); } } } } internal static class SpawnGearHooks { [ThreadStatic] private static bool RemappingCustomSpawn; [ThreadStatic] private static int RemappedSlot; public static void Apply(Harmony harmony) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_018c: Expected O, but got Unknown Type typeFromHandle = typeof(Player); MethodInfo methodInfo = AccessTools.Method(typeFromHandle, "SpawnGear_Server", new Type[6] { typeof(int), typeof(int), typeof(bool), typeof(bool), typeof(int), typeof(int) }, (Type[])null); if (methodInfo == null) { methodInfo = AccessTools.Method(typeFromHandle, "SpawnGear_Server", new Type[4] { typeof(int), typeof(int), typeof(bool), typeof(bool) }, (Type[])null); } if (methodInfo == null) { foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeFromHandle)) { if (declaredMethod.Name == "SpawnGear_Server") { methodInfo = declaredMethod; break; } } } if (methodInfo == null) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)"[DMLRRework] Could not find Player.SpawnGear_Server to patch."); } return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(SpawnGearHooks), "SpawnGearServerPrefix_6", (Type[])null, (Type[])null); ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 4) { methodInfo2 = AccessTools.Method(typeof(SpawnGearHooks), "SpawnGearServerPrefix_4", (Type[])null, (Type[])null); } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), new HarmonyMethod(typeof(SpawnGearHooks), "SpawnGearServerPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)("[DMLRRework] Patched " + methodInfo.DeclaringType.FullName + "." + methodInfo.Name + " " + $"({parameters.Length} params) with {methodInfo2.Name}.")); } } private static void SpawnGearServerPrefix_6(Player __instance, int slot, ref int allGearIndex, bool equip, bool despawn, int skinID, int skinSeed) { TryRemap(slot, ref allGearIndex); } private static void SpawnGearServerPrefix_4(Player __instance, int slot, ref int allGearIndex, bool equip, bool despawn) { TryRemap(slot, ref allGearIndex); } private static void TryRemap(int slot, ref int allGearIndex) { RemappingCustomSpawn = false; if (Global.Instance?.AllGear == null || allGearIndex < 0 || allGearIndex >= Global.Instance.AllGear.Length) { return; } IUpgradable val = Global.Instance.AllGear[allGearIndex]; if (!IsOurCatalogGear(val)) { return; } int num = ResolveBaseIndex(); if (num < 0) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)"[DMLRRework] Cannot remap spawn — base gun AllGear index unknown. Aborting custom equip to avoid NRE."); } return; } ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { string text = $"[DMLRRework] Remap SpawnGear slot={slot} index {allGearIndex} → base {num} "; GearInfo info = val.Info; logger2.LogInfo((object)(text + "(api=" + ((info != null) ? info.APIName : null) + ").")); } allGearIndex = num; RemappingCustomSpawn = true; RemappedSlot = slot; } private static int ResolveBaseIndex() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) if (Global.Instance?.AllGear == null) { return -1; } int baseAllGearIndex = WeaponRegistration.BaseAllGearIndex; if (baseAllGearIndex >= 0 && baseAllGearIndex < Global.Instance.AllGear.Length) { IUpgradable val = Global.Instance.AllGear[baseAllGearIndex]; if (val != null && !IsOurCatalogGear(val)) { return baseAllGearIndex; } } if ((Object)(object)WeaponRegistration.BaseGunPrefab != (Object)null) { int num = Array.IndexOf(Global.Instance.AllGear, (IUpgradable)(object)WeaponRegistration.BaseGunPrefab); if (num >= 0) { WeaponRegistration.SetBaseAllGearIndex(num); return num; } } if ((Object)(object)WeaponRegistration.BaseNetworkPrefab != (Object)null) { for (int i = 0; i < Global.Instance.AllGear.Length; i++) { IUpgradable obj = Global.Instance.AllGear[i]; Component val2 = (Component)(object)((obj is Component) ? obj : null); if (val2 != null && (Object)(object)val2.gameObject == (Object)(object)WeaponRegistration.BaseNetworkPrefab && !IsOurCatalogGear(Global.Instance.AllGear[i])) { WeaponRegistration.SetBaseAllGearIndex(i); return i; } } } for (int j = 0; j < Global.Instance.AllGear.Length; j++) { IUpgradable obj2 = Global.Instance.AllGear[j]; Gun val3 = (Gun)(object)((obj2 is Gun) ? obj2 : null); if (val3 != null && (int)val3.GearType == 0 && !IsOurCatalogGear(Global.Instance.AllGear[j])) { WeaponRegistration.SetBaseAllGearIndex(j); return j; } } return -1; } private static void SpawnGearServerPostfix(Player __instance) { if (!RemappingCustomSpawn) { return; } RemappingCustomSpawn = false; int remappedSlot = RemappedSlot; try { StampCustomIdentityOnSlot(__instance, remappedSlot); } catch (Exception arg) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)$"[DMLRRework] Post-spawn stamp failed: {arg}"); } } } private static void StampCustomIdentityOnSlot(Player player, int slot) { if (((player != null) ? player.Gear : null) == null || slot < 0 || slot >= player.Gear.Length) { return; } IGear val = player.Gear[slot]; if (val == null) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogWarning((object)$"[DMLRRework] Post-spawn Gear[{slot}] is null — base spawn may have failed."); } return; } IUpgradable val2 = SparrohPlugin.CustomWeaponPrefab ?? WeaponRegistration.CatalogGear ?? WeaponRegistration.FindGearSafe("dmlr_rework", 91000); if (val2 == null) { ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)"[DMLRRework] Catalog gear missing during stamp."); } } else { RebindLiveGear(val, val2, slot); } } internal static void RebindLiveGear(IGear live, IUpgradable catalog, int slot = -1) { if (live == null || catalog == null) { return; } ((IUpgradable)live).Prefab = catalog; if ((Object)(object)catalog.Info != (Object)null) { TryAssignInfo(live, catalog.Info); } if ((Object)(object)live.gameObject != (Object)null) { DmlrReworkBehaviour dmlrReworkBehaviour = live.gameObject.GetComponent(); if ((Object)(object)dmlrReworkBehaviour == (Object)null) { dmlrReworkBehaviour = live.gameObject.AddComponent(); } DmlrReworkBehaviour dmlrReworkBehaviour2 = null; Component val = (Component)(object)((catalog is Component) ? catalog : null); if (val != null) { dmlrReworkBehaviour2 = val.GetComponent(); } dmlrReworkBehaviour.InitializeAsPrefab(((Object)(object)dmlrReworkBehaviour2 != (Object)null) ? dmlrReworkBehaviour2.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."); if ((Object)(object)dmlrReworkBehaviour2 != (Object)null) { dmlrReworkBehaviour.CopySnapshotFrom(dmlrReworkBehaviour2); } } try { live.ApplyUpgrades(); } catch (Exception arg) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)$"[DMLRRework] ApplyUpgrades after rebind failed (slot={slot}): {arg}"); } } Gun val2 = (Gun)(object)((live is Gun) ? live : null); if (val2 != null) { val2.IsAimEnabled = false; ScoutLaserRifle val3 = (ScoutLaserRifle)(object)((live is ScoutLaserRifle) ? live : null); if (val3 == null || !val3.IsLaserModeActive) { val2.GunData.automatic = 1; } } ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { string[] obj = new string[6] { string.Format("[DMLRRework] Rebound Gear[{0}] → {1} ", slot, "dmlr_rework"), "(Info=", null, null, null, null }; GearInfo info = ((IUpgradable)live).Info; obj[2] = ((info != null) ? info.APIName : null); obj[3] = ", Prefab="; IUpgradable prefab = ((IUpgradable)live).Prefab; IUpgradable obj2 = ((prefab is Component) ? prefab : null); obj[4] = ((obj2 != null) ? ((Object)obj2).name : null); obj[5] = ")."; logger2.LogInfo((object)string.Concat(obj)); } } internal static bool IsOurCatalogGear(IUpgradable gear) { return SparrohPlugin.IsOurGear(gear); } private static void TryAssignInfo(IGear live, GearInfo info) { Type type = ((object)live).GetType(); while (type != null) { FieldInfo fieldInfo = type.GetField("k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("Info", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo != null) { fieldInfo.SetValue(live, info); break; } PropertyInfo property = type.GetProperty("Info", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(live, info); break; } type = type.BaseType; } } } [HarmonyPatch(typeof(GearSelectionWindow))] internal static class GearSelectionWindowHooks { [HarmonyPatch("OnOpen")] [HarmonyPrefix] private static void OnOpenPrefix(GearSelectionWindow __instance) { } [HarmonyPatch("OnOpen")] [HarmonyFinalizer] private static Exception OnOpenFinalizer(Exception __exception) { if (__exception is NullReferenceException) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)("[DMLRRework] GearSelectionWindow.OnOpen NRE (null Gear slot after failed spawn).\n" + __exception)); } return null; } return __exception; } [HarmonyPatch("OnCloseCallback")] [HarmonyPrefix] private static bool OnCloseCallbackPrefix(GearSelectionWindow __instance) { try { return SafeOnCloseCallback(__instance); } catch (Exception arg) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)$"[DMLRRework] Safe OnCloseCallback failed: {arg}"); } return true; } } [HarmonyPatch("OnCloseCallback")] [HarmonyFinalizer] private static Exception OnCloseFinalizer(Exception __exception) { if (__exception is NullReferenceException) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)("[DMLRRework] GearSelectionWindow.OnCloseCallback NRE (null Gear[i] after failed spawn).\n" + __exception)); } return null; } return __exception; } private static bool SafeOnCloseCallback(GearSelectionWindow window) { //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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) GearSlot[] value = Traverse.Create((object)window).Field("gearEquipSlots").GetValue(); if (value == null) { return true; } if (Traverse.Create(typeof(GearSelectionWindow)).Field("DisableGearSwitching").GetValue()) { return true; } Player localPlayer = Player.LocalPlayer; if (((localPlayer != null) ? localPlayer.Gear : null) == null || Global.Instance?.AllGear == null) { return true; } for (int i = 0; i < value.Length; i++) { GearSlot val = value[i]; if ((Object)(object)val == (Object)null) { continue; } GearType val2 = (GearType)0; IUpgradable val3 = null; try { val2 = val.GearType; val3 = val.Gear; } catch { val3 = Traverse.Create((object)val).Property("Gear", (object[])null).GetValue() ?? Traverse.Create((object)val).Field("gear").GetValue(); val2 = Traverse.Create((object)val).Property("GearType", (object[])null).GetValue(); } if ((int)val2 == 6 || i == 2 || i >= localPlayer.Gear.Length || val3 == null) { continue; } IGear obj2 = localPlayer.Gear[i]; if (((obj2 != null) ? ((IUpgradable)obj2).Prefab : null) == val3 || !SpawnGearHooks.IsOurCatalogGear(val3)) { continue; } int num = WeaponRegistration.BaseAllGearIndex; if (num < 0) { for (int j = 0; j < Global.Instance.AllGear.Length; j++) { IUpgradable obj3 = Global.Instance.AllGear[j]; Gun val4 = (Gun)(object)((obj3 is Gun) ? obj3 : null); if (val4 != null && (int)val4.GearType == 0 && !SpawnGearHooks.IsOurCatalogGear(Global.Instance.AllGear[j])) { num = j; WeaponRegistration.SetBaseAllGearIndex(j); break; } } } if (num < 0) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogError((object)$"[DMLRRework] OnClose: no base index for custom equip slot {i}."); } continue; } ManualLogSource logger2 = SparrohPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)$"[DMLRRework] OnClose equip slot {i} custom → SpawnGear baseIndex={num}."); } bool flag = i == 0; localPlayer.SpawnGear_ServerRpc(i, num, flag, true); try { StampAfterClose(localPlayer, i); } catch (Exception ex) { ManualLogSource logger3 = SparrohPlugin.Logger; if (logger3 != null) { logger3.LogWarning((object)("[DMLRRework] OnClose stamp: " + ex.Message)); } } } return true; } private static void StampAfterClose(Player player, int slot) { if (((player != null) ? player.Gear : null) == null || slot < 0 || slot >= player.Gear.Length) { return; } IGear val = player.Gear[slot]; if (val != null) { IUpgradable val2 = SparrohPlugin.CustomWeaponPrefab ?? WeaponRegistration.CatalogGear ?? WeaponRegistration.FindGearSafe("dmlr_rework", 91000); if (val2 != null) { SpawnGearHooks.RebindLiveGear(val, val2, slot); } } } } [Serializable] public class UpgradeProperty_MLR_VoltaicBattery : UpgradeProperty { public Range laserDamageFraction = new Range(0.45f, 0.55f); public override IEnumerator GetStatData(Random rand, IUpgradable gear, UpgradeInstance upgrade) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return StatData.Create("Every 3rd DMR shot (laser dmg):", laserDamageFraction, upgrade, ref rand, (OverrideType)2, (LabelType)1, default(BoostParams), (Range?)null); } public override void Apply(IGear gear, UpgradeInstance upgrade, ref Random rand) { //IL_0015: 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) if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { float value = laserDamageFraction.GetValue(ref rand, upgrade, default(BoostParams)); behaviour.WeaponData.voltaicLaserDamageFraction = Mathf.Max(behaviour.WeaponData.voltaicLaserDamageFraction, value); behaviour.WeaponData.voltaicBattery = true; } } public override void Remove(IGear gear, IGear prefab, UpgradeInstance upgrade, ref Random rand) { if (DmlrReworkBehaviour.TryGet(gear, out var behaviour)) { behaviour.RestoreFromPrefab(); } } } public static class WeaponRegistration { public static IUpgradable CatalogGear { get; private set; } public static Gun BaseGunPrefab { get; private set; } public static GameObject BaseNetworkPrefab { get; private set; } public static int BaseAllGearIndex { get; private set; } = -1; public static void SetBaseAllGearIndex(int index) { BaseAllGearIndex = index; } public static IUpgradable FindGearSafe(string apiName, int gearId = -1) { if (CatalogGear != null && (Object)(object)CatalogGear.Info != (Object)null && (CatalogGear.Info.APIName == apiName || (gearId >= 0 && CatalogGear.Info.ID == gearId))) { return CatalogGear; } if (Global.Instance?.AllGear != null) { IUpgradable[] allGear = Global.Instance.AllGear; foreach (IUpgradable val in allGear) { if (!((Object)(object)((val != null) ? val.Info : null) == (Object)null)) { if (!string.IsNullOrEmpty(apiName) && val.Info.APIName == apiName) { return val; } if (gearId >= 0 && val.Info.ID == gearId) { return val; } } } } try { if (PlayerData.Instance != null && !string.IsNullOrEmpty(apiName)) { IUpgradable val2 = PlayerData.FindGear(apiName); if (val2 != null) { return val2; } } } catch { } return null; } public static bool TryCreateAndRegister(string modGuid, int gearId, string apiName, string displayName, string description, string baseTypeName, bool autoUnlock, ManualLogSource log, out IUpgradable registeredGear) { registeredGear = null; if (string.IsNullOrEmpty(modGuid) || string.IsNullOrEmpty(apiName)) { if (log != null) { log.LogError((object)"[WeaponRegistration] modGuid / apiName required."); } return false; } if ((Object)(object)Global.Instance == (Object)null || Global.Instance.AllGear == null) { if (log != null) { log.LogError((object)"[WeaponRegistration] Global.Instance.AllGear is null."); } return false; } IUpgradable val = FindGearSafe(apiName, gearId); if (val != null) { CatalogGear = val; registeredGear = val; TryRefreshBaseIndex(baseTypeName, log); RegisterGearTextBlocks(apiName, displayName, "Primary Weapon", description, log); if ((Object)(object)val.Info != (Object)null) { TrySetMember(val.Info, "_localizedName", displayName); } Gun val2 = (Gun)(object)((val is Gun) ? val : null); if (val2 != null) { ApplyMarksmanBaseline(val2, log); } EnsureGearData(val, autoUnlock, log); if (log != null) { log.LogInfo((object)("[WeaponRegistration] Gear '" + apiName + "' already present — reusing.")); } return true; } if (!TryFindBaseGun(baseTypeName, log, out var gear, out var go, out var allGearIndex)) { return false; } BaseGunPrefab = gear; BaseNetworkPrefab = go; BaseAllGearIndex = allGearIndex; if (log != null) { log.LogInfo((object)$"[WeaponRegistration] Base spawn prefab index={allGearIndex} type={((object)gear).GetType().Name}."); } GameObject val3 = Object.Instantiate(go); ((Object)val3).name = "[" + modGuid + "] " + displayName; val3.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val3); NetworkObject val4 = default(NetworkObject); if (val3.TryGetComponent(ref val4)) { Object.DestroyImmediate((Object)(object)val4); if (log != null) { log.LogDebug((object)"[WeaponRegistration] Stripped NetworkObject from catalog clone (spawn uses base prefab)."); } } Gun component = val3.GetComponent(); if ((Object)(object)component == (Object)null) { if (log != null) { log.LogError((object)"[WeaponRegistration] Clone lost Gun component."); } Object.Destroy((Object)(object)val3); return false; } GearInfo val5 = CreateGearInfo(gearId, apiName, displayName, description, gear.Info, autoUnlock, log); if ((Object)(object)val5 == (Object)null) { Object.Destroy((Object)(object)val3); return false; } if (!TryAssignGearInfo(component, val5, log)) { Object.Destroy((Object)(object)val3); return false; } if ((Object)(object)component.Info == (Object)null || component.Info.ID != gearId || component.Info.APIName != apiName) { if (log != null) { log.LogError((object)("[WeaponRegistration] GearInfo verification failed (Info=" + (((Object)(object)component.Info == (Object)null) ? "null" : (component.Info.APIName + "/" + component.Info.ID)) + ").")); } Object.Destroy((Object)(object)val3); return false; } DmlrReworkBehaviour dmlrReworkBehaviour = val3.GetComponent(); if ((Object)(object)dmlrReworkBehaviour == (Object)null) { dmlrReworkBehaviour = val3.AddComponent(); } dmlrReworkBehaviour.InitializeAsPrefab(description); ApplyMarksmanBaseline(component, log); if (!InjectIntoAllGear((IUpgradable)(object)component, log)) { Object.Destroy((Object)(object)val3); return false; } InjectIntoPlayerData((IUpgradable)(object)component, autoUnlock, log); ModelImportHooks.ApplyPlaceholderHooks(val3, log); CatalogGear = (IUpgradable)(object)component; registeredGear = (IUpgradable)(object)component; return true; } private static void ApplyMarksmanBaseline(Gun cloneGun, ManualLogSource log) { cloneGun.GunData.automatic = 1; cloneGun.IsAimEnabled = false; ScoutLaserRifle val = (ScoutLaserRifle)(object)((cloneGun is ScoutLaserRifle) ? cloneGun : null); if (val != null) { ref LaserGunData laserData = ref val.LaserData; float num = laserData.laserChargeCapacity; if (num <= 0f) { num = 100f; } float num2 = Mathf.Max(1f, 20f); laserData.laserChargeOnHit = num / num2; laserData.minLaserCharge = 0f; if (log != null) { log.LogInfo((object)("[WeaponRegistration] Marksman baseline: automatic=1, canAim=false, " + $"laserChargeCapacity={num}, laserChargeOnHit={laserData.laserChargeOnHit} " + $"({num2} hits to full), minLaserCharge=0.")); } } else if (log != null) { log.LogWarning((object)"[WeaponRegistration] Clone is not ScoutLaserRifle — laser charge retune skipped."); } } private static void TryRefreshBaseIndex(string preferredTypeName, ManualLogSource log) { if (Global.Instance?.AllGear == null) { return; } if ((Object)(object)BaseGunPrefab != (Object)null) { int num = Array.IndexOf(Global.Instance.AllGear, (IUpgradable)(object)BaseGunPrefab); if (num >= 0) { BaseAllGearIndex = num; return; } } if (TryFindBaseGun(preferredTypeName, log, out var gear, out var go, out var allGearIndex)) { BaseGunPrefab = gear; BaseNetworkPrefab = go; BaseAllGearIndex = allGearIndex; } } private static bool TryFindBaseGun(string preferredTypeName, ManualLogSource log, out Gun gear, out GameObject go, out int allGearIndex) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) gear = null; go = null; allGearIndex = -1; Gun val = null; GameObject val2 = null; int num = -1; IUpgradable[] allGear = Global.Instance.AllGear; for (int i = 0; i < allGear.Length; i++) { IUpgradable obj = allGear[i]; Gun val3 = (Gun)(object)((obj is Gun) ? obj : null); if (val3 == null) { continue; } if ((int)val3.GearType != 0 && (int)val3.GearType != -1) { if ((Object)(object)val == (Object)null) { val = val3; val2 = ((Component)val3).gameObject; num = i; } continue; } GameObject gameObject = ((Component)val3).gameObject; string name = ((object)val3).GetType().Name; if (!string.IsNullOrEmpty(preferredTypeName) && string.Equals(name, preferredTypeName, StringComparison.Ordinal)) { gear = val3; go = gameObject; allGearIndex = i; if (log != null) { log.LogInfo((object)$"[WeaponRegistration] Base gun: {name} ({((Object)gameObject).name}) index={i}."); } return true; } if ((Object)(object)val == (Object)null || (int)val.GearType != 0) { val = val3; val2 = gameObject; num = i; } } if ((Object)(object)val != (Object)null) { gear = val; go = val2; allGearIndex = num; if (log != null) { log.LogWarning((object)("[WeaponRegistration] '" + preferredTypeName + "' not found — " + $"falling back to {((object)val).GetType().Name} ({((Object)val2).name}) index={num}.")); } return true; } if (log != null) { log.LogError((object)"[WeaponRegistration] No Gun found in Global.AllGear."); } return false; } private static GearInfo CreateGearInfo(int gearId, string apiName, string displayName, string description, GearInfo template, bool autoUnlock, ManualLogSource log) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) GearInfo val = ScriptableObject.CreateInstance(); ((Object)val).name = apiName; TrySetMember(val, "ID", gearId); TrySetMember(val, "k__BackingField", gearId); TrySetMember(val, "_name", apiName); TrySetMember(val, "id", gearId); RegisterGearTextBlocks(apiName, displayName, "Primary Weapon", description, log); TrySetMember(val, "_localizedName", displayName); if ((Object)(object)template != (Object)null) { object member = GetMember(template, "grid"); if (member != null) { TrySetMember(val, "grid", member); } if ((Object)(object)template.Icon != (Object)null) { TrySetMember(val, "k__BackingField", template.Icon); } if (template.UnlockCost != null) { val.UnlockCost = template.UnlockCost; } val.CanGainXP = template.CanGainXP; val.XPGainMultilier = template.XPGainMultilier; val.MaxLevel = template.MaxLevel; val.MinUnlockLevel = 0; val.HideWhenNotCollected = false; } else if ((Object)(object)Global.Instance != (Object)null && (Object)(object)Global.Instance.WarningIcon != (Object)null) { TrySetMember(val, "k__BackingField", Global.Instance.WarningIcon); } val.UnlockAutomatically = autoUnlock; val.UnlockState = (UnlockState)(autoUnlock ? 2 : 0); TrySetMember(val, "upgrades", Array.Empty()); TrySetMember(val, "skins", Array.Empty()); TrySetMember(val, "combinedUpgradeList", new List()); TrySetMember(val, "defaultSkin", null); TrySetMember(val, "k__BackingField", null); _ = val.Upgrades; if (!val.HasUpgradeGrid && log != null) { log.LogWarning((object)"[WeaponRegistration] GearInfo has no upgrade grid — UI may hide hex inventory."); } if (log != null) { log.LogDebug((object)$"[WeaponRegistration] GearInfo created id={gearId} api={apiName} name={displayName}"); } return val; } private static void RegisterGearTextBlocks(string apiName, string displayName, string typeName, string description, ManualLogSource log) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (string.IsNullOrEmpty(apiName)) { return; } try { TextBlockGroup val = new TextBlockGroup(0); val.blocks = (TextBlock[])(object)new TextBlock[3] { new TextBlock(displayName ?? apiName, apiName), new TextBlock(typeName ?? "Primary Weapon", apiName), new TextBlock(description ?? string.Empty, apiName) }; TextBlockGroup value = val; TextBlocks.strings[apiName] = value; if (log != null) { log.LogDebug((object)("[WeaponRegistration] Registered TextBlocks for '" + apiName + "' → '" + displayName + "'.")); } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("[WeaponRegistration] TextBlocks registration failed: " + ex.Message)); } } } private static bool TryAssignGearInfo(Gun gear, GearInfo info, ManualLogSource log) { if (TrySetMember(gear, "k__BackingField", info) || TrySetMember(gear, "Info", info)) { return true; } if (log != null) { log.LogError((object)"[WeaponRegistration] Failed to assign GearInfo onto clone (reflection)."); } return false; } private static bool InjectIntoAllGear(IUpgradable gear, ManualLogSource log) { IUpgradable[] allGear = Global.Instance.AllGear; for (int i = 0; i < allGear.Length; i++) { if (allGear[i] != null && (Object)(object)allGear[i].Info != (Object)null && allGear[i].Info.ID == gear.Info.ID) { if (log != null) { log.LogWarning((object)$"[WeaponRegistration] AllGear already contains id={gear.Info.ID}."); } return true; } } IUpgradable[] array = (IUpgradable[])(object)new IUpgradable[allGear.Length + 1]; Array.Copy(allGear, array, allGear.Length); array[allGear.Length] = gear; Global.Instance.AllGear = array; Component val = (Component)(object)((gear is Component) ? gear : null); if (val != null) { TryAppendObjectArray(Global.Instance, "_allGear", (Object)(object)val.gameObject); } if (log != null) { log.LogInfo((object)$"[WeaponRegistration] Injected into AllGear (count={array.Length})."); } return true; } private static void InjectIntoPlayerData(IUpgradable gear, bool autoUnlock, ManualLogSource log) { EnsureGearData(gear, autoUnlock, log); } public static void EnsureGearData(IUpgradable gear, bool autoUnlock, ManualLogSource log) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown if ((Object)(object)((gear != null) ? gear.Info : null) == (Object)null) { return; } if (PlayerData.Instance == null) { if (log != null) { log.LogWarning((object)"[WeaponRegistration] PlayerData.Instance null — gear may appear on next InitializeCollectedGear."); } return; } GearData gearData = PlayerData.GetGearData(gear); if (gearData != null) { gearData.Gear = gear; if (autoUnlock && !gearData.IsUnlocked) { gearData.Unlock(); } if (log != null) { log.LogDebug((object)"[WeaponRegistration] Bound existing GearData entry."); } return; } gearData = PlayerData.GetGearData(gear.Info.ID); if (gearData != null) { gearData.Gear = gear; if (autoUnlock && !gearData.IsUnlocked) { gearData.Unlock(); } if (log != null) { log.LogInfo((object)"[WeaponRegistration] Re-bound GearData by id after load."); } } else if (typeof(PlayerData).GetField("collectedGear", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(PlayerData.Instance) is IDictionary dictionary) { GearData val = new GearData(gear, (UnlockState)(autoUnlock ? 2 : 0)); dictionary[gear.Info.ID] = val; if (autoUnlock) { val.Unlock(); } if (log != null) { log.LogInfo((object)"[WeaponRegistration] Added GearData to collectedGear."); } } else if (log != null) { log.LogWarning((object)"[WeaponRegistration] Could not inject GearData directly. If gear is missing in UI, ensure registration runs before/during PlayerData.OnAwake."); } } private static void TryRegisterNetworkPrefab(GameObject prefab, ManualLogSource log) { try { NetworkManager val = NetworkManager.Singleton; if ((Object)(object)val == (Object)null && (Object)(object)Global.Instance != (Object)null) { val = Global.Instance.NetworkManager; } if ((Object)(object)val == (Object)null) { if (log != null) { log.LogDebug((object)"[WeaponRegistration] NetworkManager not ready — skip AddNetworkPrefab (ok at boot)."); } return; } MethodInfo method = ((object)val).GetType().GetMethod("AddNetworkPrefab", new Type[1] { typeof(GameObject) }); if (method != null) { method.Invoke(val, new object[1] { prefab }); if (log != null) { log.LogInfo((object)"[WeaponRegistration] AddNetworkPrefab succeeded."); } return; } object obj = ((object)val).GetType().GetProperty("NetworkConfig")?.GetValue(val); if (obj != null) { object obj2 = obj.GetType().GetProperty("Prefabs")?.GetValue(obj); MethodInfo methodInfo = obj2?.GetType().GetMethod("Add", new Type[1] { typeof(GameObject) }) ?? obj2?.GetType().GetMethod("Add", new Type[1] { typeof(NetworkPrefab) }); if (methodInfo != null) { if (methodInfo.GetParameters()[0].ParameterType == typeof(GameObject)) { methodInfo.Invoke(obj2, new object[1] { prefab }); } else { object obj3 = Activator.CreateInstance(methodInfo.GetParameters()[0].ParameterType); TrySetMember(obj3, "Prefab", prefab); methodInfo.Invoke(obj2, new object[1] { obj3 }); } if (log != null) { log.LogInfo((object)"[WeaponRegistration] NetworkConfig.Prefabs add succeeded."); } return; } } if (log != null) { log.LogDebug((object)"[WeaponRegistration] No network prefab API found — multiplayer may need a real AssetBundle prefab."); } } catch (Exception ex) { if (log != null) { log.LogWarning((object)("[WeaponRegistration] Network prefab registration failed: " + ex.Message)); } } } private static bool TrySetMember(object target, string name, object value) { if (target == null) { return false; } Type type = target.GetType(); PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(target, value); return true; } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(target, value); return true; } Type baseType = type.BaseType; while (baseType != null) { field = baseType.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(target, value); return true; } property = baseType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(target, value); return true; } baseType = baseType.BaseType; } return false; } private static object GetMember(object target, string name) { if (target == null) { return null; } Type type = target.GetType(); object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(target); if (obj == null) { PropertyInfo? property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property == null) { return null; } obj = property.GetValue(target); } return obj; } private static void TryAppendObjectArray(object host, string fieldName, Object item) { FieldInfo field = host.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && field.GetValue(host) is Array array) { Type elementType = array.GetType().GetElementType(); if (!(elementType == null) && elementType.IsInstanceOfType(item)) { Array array2 = Array.CreateInstance(elementType, array.Length + 1); Array.Copy(array, array2, array.Length); array2.SetValue(item, array.Length); field.SetValue(host, array2); } } } } public static class ModelImportHooks { public static void ApplyPlaceholderHooks(GameObject gearRoot, ManualLogSource log) { if (log != null) { log.LogDebug((object)"[ModelImportHooks] Placeholder only — using vanilla ScoutLaserRifle visuals."); } } public static bool ApplyMesh(GameObject root, Mesh mesh, Material material = null) { if ((Object)(object)root == (Object)null || (Object)(object)mesh == (Object)null) { return false; } MeshFilter componentInChildren = root.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return false; } componentInChildren.sharedMesh = mesh; MeshRenderer val = default(MeshRenderer); if ((Object)(object)material != (Object)null && ((Component)componentInChildren).TryGetComponent(ref val)) { ((Renderer)val).sharedMaterial = material; } return true; } public static bool TrySetBulletPrefab(Gun gun, GameObject bulletPrefab) { if ((Object)(object)gun == (Object)null || (Object)(object)bulletPrefab == (Object)null) { return false; } FieldInfo fieldInfo = typeof(Gun).GetField("_bulletPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(Gun).GetField("bulletPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo == null) { return false; } fieldInfo.SetValue(gun, bulletPrefab); return true; } } namespace DMLRRework { public static class MyPluginInfo { public const string PLUGIN_GUID = "DMLRRework"; public const string PLUGIN_NAME = "DMLRRework"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }