Decompiled source of DeadPiece v0.4.1
Deadpiece.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using AudioImportLib; using BoneLib; using BoneLib.BoneMenu; using DeadPiece; using DeadPiece.Networking; using DeadPiece.Networking.Messages; using HarmonyLib; using Il2CppCysharp.Threading.Tasks; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VRMK; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LabFusion.Entities; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.Representation; using LabFusion.SDK.Modules; using LabFusion.Utilities; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: MelonColor(255, 139, 0, 0)] [assembly: MelonInfo(typeof(DeadPieceMod), "DeadPiece", "0.4.1", "VoidIndustries", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonPlatform(/*Could not decode attribute arguments.*/)] [assembly: AssemblyVersion("0.0.0.0")] [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; } } } namespace DeadPiece { public static class AvatarHealthResolver { public const float MinVitalityHealth = 25f; public const float MaxVitalityHealth = 200f; public const float MaxSanityHealth = 500f; public const float DefaultUnsetHealth = 100f; public static float Resolve(RigManager rm, float fallbackHp) { if ((Object)(object)rm == (Object)null) { return Mathf.Max(1f, fallbackHp); } float num = Mathf.Max(1f, fallbackHp); float num2 = ReadMarrowHealth(rm.health); float num3 = ReadVitalityHealth(rm.avatar); if (num2 > 0f) { if (num3 > 0f && LooksLikeStaleDefaultHealth(num2, num3)) { return ClampHealth(num3, num); } return ClampHealth(num2, num); } if (num3 > 0f) { return ClampHealth(num3, num); } return num; } public static float ReadVitalityHealth(Avatar avatar) { if ((Object)(object)avatar == (Object)null) { return -1f; } float vitality = avatar.vitality; if (vitality <= 0f || float.IsNaN(vitality) || float.IsInfinity(vitality)) { return -1f; } if (vitality > 2f) { return ClampHealth(vitality, 200f); } return Mathf.Lerp(25f, 200f, Mathf.Clamp01(vitality)); } private static float ReadMarrowHealth(Health health) { if ((Object)(object)health == (Object)null) { return -1f; } float max_Health = health.max_Health; if (max_Health <= 0f || float.IsNaN(max_Health) || float.IsInfinity(max_Health)) { return -1f; } return max_Health; } private static bool LooksLikeStaleDefaultHealth(float marrowHp, float vitalityHp) { if (Mathf.Abs(marrowHp - 100f) > 0.5f) { return false; } return Mathf.Abs(vitalityHp - marrowHp) > 12f; } private static float ClampHealth(float hp, float fallback) { if (hp <= 0f || float.IsNaN(hp) || float.IsInfinity(hp)) { return fallback; } if (hp > 500f) { hp = 500f; } return Mathf.Max(1f, hp); } } [HarmonyPatch(typeof(BaseController), "GetThumbStickAxis")] internal static class RightStickPatch { private static void Postfix(BaseController __instance, ref Vector2 __result) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (!((Object)(object)__instance == (Object)null) && (int)__instance.handedness == 2) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && DeadPieceMod.Instance != null && DeadPieceMod.Instance.ShouldApplyLocalNoLegEffects(rigManager) && !DeadPieceMod.Instance.IsAutoInjectorUseActiveOrRecent() && !DeadPieceMod.Instance.IsCrouchForcingSuppressed()) { __result.y = 0f; } } } } [HarmonyPatch(typeof(RemapRig), "CrouchHold")] internal static class CrouchHoldPostfixPatch { private static void Postfix(RemapRig __instance) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && DeadPieceMod.Instance != null && !((Object)(object)rigManager.remapHeptaRig != (Object)(object)__instance) && DeadPieceMod.Instance.ShouldApplyLocalNoLegEffects(rigManager) && !DeadPieceMod.Instance.IsAutoInjectorUseActiveOrRecent() && !DeadPieceMod.Instance.IsCrouchForcingSuppressed() && !DeadPieceMod.Instance.IsHoldingNimbusGun(rigManager)) { __instance._spineCrouchOff = 0.8f; __instance._crouchTarget = 0.8f; __instance.vertState = (VertState)3; } } } [HarmonyPatch(typeof(RemapRig), "OnAfterFixedUpdate")] internal static class ForceCrouchHeight { private const float TARGET_CROUCH = 0.8f; private const float LERP_SPEED = 8f; private static void Postfix(RemapRig __instance) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && DeadPieceMod.Instance != null && !((Object)(object)rigManager.remapHeptaRig != (Object)(object)__instance) && DeadPieceMod.Instance.ShouldApplyLocalNoLegEffects(rigManager) && !DeadPieceMod.Instance.IsAutoInjectorUseActiveOrRecent() && !DeadPieceMod.Instance.IsCrouchForcingSuppressed() && !DeadPieceMod.Instance.IsHoldingNimbusGun(rigManager)) { float num = Time.deltaTime * 8f; __instance._spineCrouchOff = Mathf.Lerp(__instance._spineCrouchOff, 0.8f, num); __instance._crouchTarget = Mathf.Lerp(__instance._crouchTarget, 0.8f, num); __instance.vertState = (VertState)3; } } } [HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")] [HarmonyPriority(800)] public static class DamageInterceptor { internal static void Prefix(PlayerDamageReceiver __instance, ref Attack attack, out bool __state) { __state = false; try { __state = DeadPieceMod.Instance != null && DeadPieceMod.Instance.TryConsumeNonFatalAttack(__instance, attack); if (__state) { attack.damage = 0.1f; } } catch (Exception ex) { MelonLogger.Error("[DeadPiece] Damage prefix failed: " + ex); } } internal static void Postfix(PlayerDamageReceiver __instance, Attack attack, bool __state) { if (__state) { return; } try { Health health = __instance.health; RigManager val = ((health != null) ? health._rigManager : null); bool flag = (Object)(object)val != (Object)null && DeadPieceMod.Instance != null && DeadPieceMod.Instance.IsBothLegsGone(val); DeadPieceMod.Instance?.OnAttackReceived(__instance, attack); bool flag2 = (Object)(object)val != (Object)null && DeadPieceMod.Instance != null && DeadPieceMod.Instance.IsBothLegsGone(val); if (!flag && flag2) { DeadPieceMod.Instance?.SyncLegState(val, 3); } } catch (Exception ex) { MelonLogger.Error("[DeadPiece] Damage postfix failed: " + ex); } } } public class DamageVolume : MonoBehaviour { private float _damagePerSecond; private float _lifetime; private float _spawnTime; private float _nextTickTime; private bool _initialized; public void Initialize(float damagePerSecond, float lifetime) { _damagePerSecond = damagePerSecond; _lifetime = lifetime; _spawnTime = Time.time; _nextTickTime = 0f; _initialized = true; } private void Update() { if (_initialized && Time.time - _spawnTime >= _lifetime) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnTriggerStay(Collider other) { if (!_initialized || (Object)(object)other == (Object)null || _damagePerSecond <= 0f || Time.time < _nextTickTime) { return; } _nextTickTime = Time.time + 0.25f; try { float num = _damagePerSecond * 0.25f; if (num <= 0f) { return; } Transform val = ((Component)other).transform; for (int i = 0; i < 6; i++) { if (!((Object)(object)val != (Object)null)) { break; } RigManager component = ((Component)val).GetComponent<RigManager>(); if ((Object)(object)component != (Object)null && (Object)(object)component.health != (Object)null && component.health.curr_Health > 0f) { component.health.Death(); break; } val = val.parent; } } catch { } } } public class DeadPieceMod : MelonMod { private struct PendingNetworkState { public ushort Sequence; public uint GoneBoneMask; public bool IsFallen; } [Flags] private enum LimbGoneMask : byte { None = 0, LeftArm = 1, RightArm = 2, LeftLeg = 4, RightLeg = 8, Spine = 0x10, Hips = 0x20 } private sealed class RigRuntimeCache { public int AvatarHash; public bool Initialized; public bool LimbDamageBlocked; public int LimbDamageBlockFrame; public bool HasMissingLimbs; public LimbGoneMask LimbGoneFlags; public Transform[] BoneTransforms; public VisualDamageController VisualDamage; } public static MelonPreferences_Category Category; public static MelonPreferences_Entry<float> MaxLimbHealth; public static MelonPreferences_Entry<float> DamageMultiplier; public static MelonPreferences_Entry<bool> EnableSoundEffects; public static MelonPreferences_Entry<bool> EnableDualStickDeathReset; public static MelonPreferences_Entry<float> SeveredLimbBleedDamagePerSecond; public static MelonPreferences_Entry<bool> EnableVrEyeBlindness; public static MelonPreferences_Entry<bool> EnableHeadSever; public static MelonPreferences_Entry<bool> EnableVisualCuts; public static MelonPreferences_Entry<bool> EnableVisualHitMarks; public static MelonPreferences_Entry<bool> EnableAttackTypeBalancing; public static MelonPreferences_Entry<float> PiercingDamageMultiplier; public static MelonPreferences_Entry<float> BluntDamageMultiplier; public static MelonPreferences_Entry<float> SlashDamageMultiplier; public static MelonPreferences_Entry<float> StabDamageMultiplier; public static MelonPreferences_Entry<float> FireDamageMultiplier; public static MelonPreferences_Entry<float> SharpSeverChance; public static MelonPreferences_Entry<float> ExplosionDamageThreshold; public static MelonPreferences_Entry<float> ExplosionRadius; public static MelonPreferences_Entry<bool> EnableBlastLimbDamage; public static MelonPreferences_Entry<bool> EnableExplosiveHarmonyHooks; public static MelonPreferences_Entry<bool> EnableImpactBlood; public static MelonPreferences_Entry<bool> EnableBloodEffects; public static MelonPreferences_Entry<bool> EnableGameBloodEffects; public static MelonPreferences_Entry<bool> EnableFallbackBloodEffects; public static MelonPreferences_Entry<string> BloodColorOverride; public static MelonPreferences_Entry<bool> EnableMovementPenalty; public static MelonPreferences_Entry<bool> EnableSecondLegRagdoll; public static DeadPieceMod Instance; private DataCardReference<SurfaceDataCard> _fleshSurfaceCard; private bool _fleshCardFound; private readonly List<string> _gameBloodSpawnableBarcodes = new List<string>(); private bool _bloodSpawnablesScanned; private ParticleSystem _gameBloodParticlePrefab; private float _lastGameBloodParticleSearchTime = -999f; private bool _loggedMissingGameBloodParticles; private bool _loggedVanillaBloodSpawnable; private bool _loggedVanillaBloodSpawnableFailure; private Spawnable _smallBloodSplatterSpawnable; private Spawnable _largeBloodSplatterSpawnable; private Spawnable _bloodBagBlasterSpawnable; private bool _vanillaBloodSpawnablesRegistered; public ParticleSystem BloodPrefab; private bool _limitsSaved; private const float DefaultLocomotionMaxVelocity = 4.5f; private float _savedLocomotionMaxVelocity = 4.5f; private float _savedLocomotionCurrentMaxVelocity = 4.5f; private bool _savedLocomotionJumpEnabled = true; private bool _locomotionStateSaved; private bool _deadpieceNoLegUsageApplied; private bool _deadpieceJumpBlocked; private bool _deadpieceFallenStateApplied; private float _suppressNoLegRagdollUntil = -999f; private float _suppressCrouchForcingUntil = -999f; private float _lastLocalRespawnTime = -999f; private float _lastLocalBothLegsSeveredTime = -999f; private Harmony _harmony = new Harmony("com.deadpiece.patches"); private const string MetadataKey = "DeadPieceLimbs"; private const float FusionStateResyncInterval = 5f; private const float StumpBloodEffectInterval = 0.45f; private const float StumpBloodVisualDamage = 3f; private const float VanillaBloodLifetimeSeconds = 10f; private const float AutoInjectorUseWindowSeconds = 0.8f; private const string Explosive_SmallBigDamage = "BaBaCorp.MiscExplosiveDevices.Spawnable.ExplosionSmallBigDamage"; private const string Explosive_MicroNuke = "BaBaCorp.MiscExplosiveDevices.Spawnable.MicroNukeGrenade"; private const string Explosive_TimedNuke = "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedNuke"; private const string Explosive_Dynamite = "BaBaCorp.MiscExplosiveDevices.Spawnable.Dynamite"; private const string Explosive_C4 = "BaBaCorp.MiscExplosiveDevices.Spawnable.CelebratoryC4"; private const string Explosive_Grenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.FragmentationGrenade"; private const string Explosive_TimedC4 = "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedC4"; private const string Explosive_ProxMine = "BaBaCorp.MiscExplosiveDevices.Spawnable.ProxMine"; private const string Explosive_GiftMine = "BaBaCorp.MiscExplosiveDevices.Spawnable.GiftMine"; private const string Explosive_FragGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.FragmentationGrenade"; private const string Explosive_GasGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.GasGrenade"; private const string Explosive_SmokeGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.SmokeGrenade"; private const string Explosive_Flare = "BaBaCorp.MiscExplosiveDevices.Spawnable.Flare"; private const string Explosive_PropaneTank = "BaBaCorp.MiscExplosiveDevices.Spawnable.PropaneTank"; private const string Explosive_FuelTank = "BaBaCorp.MiscExplosiveDevices.Spawnable.FuelTank"; private const string Explosive_Missile = "BaBaCorp.MiscExplosiveDevices.Spawnable.Missile"; private const string Explosive_MiniMissile = "BaBaCorp.MiscExplosiveDevices.Spawnable.MiniMissile"; private const string Explosive_DivinationGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.DivinationGrenade"; private const string Explosive_VoidTunneling = "BaBaCorp.MiscExplosiveDevices.Spawnable.KCB4VoidTunnelingDevice"; private const string Explosive_IncendiaryGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.IncendiaryGrenade"; private const string Explosive_FireworkPurple = "BaBaCorp.MiscExplosiveDevices.Spawnable.PurpleFireworkRocket"; private const string Explosive_FireworkGreen = "BaBaCorp.MiscExplosiveDevices.Spawnable.GreenFireworkRocket"; private const string Explosive_FireworkBlue = "BaBaCorp.MiscExplosiveDevices.Spawnable.BlueFireworkRocket"; private const string Explosive_FireworkRed = "BaBaCorp.MiscExplosiveDevices.Spawnable.RedFireworkRocket"; private const string Explosive_Lighter = "BaBaCorp.MiscExplosiveDevices.Spawnable.Lighter"; private const string Explosive_M72Law = "BaBaCorp.MiscExplosiveDevices.Spawnable.M72LAW"; private const string Explosive_M72LawInf = "BaBaCorp.MiscExplosiveDevices.Spawnable.M72LawINF"; private const string Explosive_Stielhandgranate = "BaBaCorp.MiscExplosiveDevices.Spawnable.Stielhandgranate"; private const string Explosive_SmallRocket = "BaBaCorp.MiscExplosiveDevices.Spawnable.SmallRocket"; private const string Explosive_Jarate = "BaBaCorp.MiscExplosiveDevices.Spawnable.Jarate"; private const string Explosive_JoyousGreenGrenade = "BaBaCorp.MiscExplosiveDevices.Spawnable.JoyousGreenGrenade"; private const string Explosive_BatteryAcidGlass = "BaBaCorp.MiscExplosiveDevices.Spawnable.BatteryAcidGlass"; private const string Explosive_CrateWithLid = "BaBaCorp.MiscExplosiveDevices.Spawnable.CrateWithLid"; private const string Explosive_RemoteIED = "BaBaCorp.MiscExplosiveDevices.Spawnable.RemoteIED"; private const string Explosive_ClassicBomb = "BaBaCorp.MiscExplosiveDevices.Spawnable.ClassicBomb"; private const string Explosive_Frank = "BaBaCorp.MiscExplosiveDevices.Spawnable.Frank"; private const string Explosive_BirthdayCake = "BaBaCorp.MiscExplosiveDevices.Spawnable.BirthdayCake"; private const string Explosive_IncinMissile = "BaBaCorp.MiscExplosiveDevices.Spawnable.IncinMissile"; private const string Explosive_TriggeredExplosive = "BaBaCorp.MiscExplosiveDevices.Spawnable.TriggeredExplosive"; private const string Explosive_TimedExplosive6s = "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedExplosive6sec"; private const string Explosive_ImpactExplosive = "BaBaCorp.MiscExplosiveDevices.Spawnable.ImpactExplosive"; private const string Explosive_Pliers = "BaBaCorp.MiscExplosiveDevices.Spawnable.Pliers"; private readonly Dictionary<RigManager, Dictionary<HumanBodyBones, float>> _playersHealth = new Dictionary<RigManager, Dictionary<HumanBodyBones, float>>(); private readonly Dictionary<RigManager, Dictionary<Collider, HumanBodyBones>> _colliderBoneMap = new Dictionary<RigManager, Dictionary<Collider, HumanBodyBones>>(); private readonly Dictionary<RigManager, Dictionary<Collider, float>> _colliderBoneDistanceMap = new Dictionary<RigManager, Dictionary<Collider, float>>(); private readonly Dictionary<RigManager, Dictionary<HumanBodyBones, Vector3>> _originalScales = new Dictionary<RigManager, Dictionary<HumanBodyBones, Vector3>>(); private readonly Dictionary<RigManager, Dictionary<HumanBodyBones, float>> _lastHitEffectTimes = new Dictionary<RigManager, Dictionary<HumanBodyBones, float>>(); private readonly Dictionary<RigManager, Dictionary<HumanBodyBones, float>> _lastStumpBloodEffectTimes = new Dictionary<RigManager, Dictionary<HumanBodyBones, float>>(); private readonly Dictionary<RigManager, Dictionary<HumanBodyBones, float>> _stumpBloodStartTimes = new Dictionary<RigManager, Dictionary<HumanBodyBones, float>>(); private readonly Dictionary<byte, PendingNetworkState> _pendingNetworkStates = new Dictionary<byte, PendingNetworkState>(); private readonly Dictionary<byte, uint> _appliedStateMasks = new Dictionary<byte, uint>(); private readonly HashSet<byte> _remoteFallenPlayers = new HashSet<byte>(); private bool _lastLeftArmUsable = true; private bool _lastRightArmUsable = true; private readonly Dictionary<byte, ushort> _lastAppliedNetworkSequence = new Dictionary<byte, ushort>(); private ushort _localStateSequence; private uint _lastSentStateMask = uint.MaxValue; private float _lastStateSyncTime = -999f; private float _lastRadialBlastDedupeTime = -999f; private Vector3 _lastRadialBlastDedupeOrigin; private readonly List<AudioClip> _dismemberSounds = new List<AudioClip>(); public AudioClip DismemberSound; private string _soundFolder; private readonly Dictionary<RigManager, int> _lastAvatarHashes = new Dictionary<RigManager, int>(); private readonly Dictionary<string, Color> _avatarBloodOverrides = new Dictionary<string, Color>(); private readonly Dictionary<RigManager, Color> _bloodColorOverrides = new Dictionary<RigManager, Color>(); private readonly Dictionary<RigManager, byte> _bloodColorIndexOverrides = new Dictionary<RigManager, byte>(); private string _lastBroadcastedBloodColor = "Auto"; private bool _boneMenuCreated; public static readonly HumanBodyBones[] DamageBones; private static readonly HashSet<HumanBodyBones> FatalBones; private static readonly HashSet<HumanBodyBones> TorsoBones; private static readonly HashSet<HumanBodyBones> CoreNearestExcludeBones; private const float NearestBoneMaxDistance = 0.75f; private const float NearestBoneTorsoBias = 0.35f; private const float TorsoBoneMaxHitDistance = 0.4f; private const float MaxColliderBoneWorldDistance = 0.55f; private const float MaxColliderHierarchyDepth = 5f; private const float InvincibleHealthThreshold = 9999f; private const int LimbDamageBlockRecheckFrames = 30; private const float SlowUpdateInterval = 0.5f; private const float AvatarSwapCheckInterval = 0.2f; private const float MinLimbHealthFloorAbsolute = 8f; private const float MinLimbHealthFloorRatio = 0.15f; private static readonly HumanBodyBones[] NetworkBones; public static readonly Dictionary<HumanBodyBones, int> BoneToIndexMap; private static readonly string[] GameBloodPositiveKeywords; private static readonly string[] GameBloodNegativeKeywords; private static readonly string[] VanillaBloodSpawnableBarcodes; private const string VanillaBloodBlasterBarcode = "c1534c5a-1ea0-4156-920b-f8a8426c6173"; private const float DualStickResetCooldown = 0.75f; private const float DualStickTapPairMaxGap = 0.25f; private const float DualStickTapWindowDuration = 1.75f; private const int DualStickResetTapCount = 2; private RigManager _cachedRm; private float _lastTrackedBodyHealth = -1f; private float _lastAutoInjectorUseTime = -999f; private float _lastExplosiveUseTime = -999f; private const float ExplosiveUseWindowSeconds = 1.5f; private int _dualStickResetTapCount; private float _dualStickResetTapWindowExpire; private float _lastLeftStickTapTime = -999f; private float _lastRightStickTapTime = -999f; private float _lastDualStickTapRegisteredTime = -999f; private float _lastDualStickResetTime = -999f; private readonly Dictionary<RigManager, bool> _rigWasDead = new Dictionary<RigManager, bool>(); private readonly Dictionary<RigManager, float> _avatarHealthBaseCache = new Dictionary<RigManager, float>(); private readonly Dictionary<RigManager, int> _avatarHealthHashCache = new Dictionary<RigManager, int>(); private readonly HashSet<RigManager> _trackedRigs = new HashSet<RigManager>(); private float _slowUpdateTimer; private float _avatarSwapTimer; private float _delayedDeathTime; private RigManager _delayedDeathRm; private RigManager _vrEyeCacheRig; private bool _vrEyeCamerasCached; private bool _lastAppliedLeftEyeBlind; private bool _lastAppliedRightEyeBlind; private readonly List<Camera> _vrLeftEyeCameras = new List<Camera>(); private readonly List<Camera> _vrRightEyeCameras = new List<Camera>(); private readonly Dictionary<Camera, bool> _vrCameraEnabledBackup = new Dictionary<Camera, bool>(); private readonly Dictionary<Camera, GameObject> _vrEyeBlackoutObjects = new Dictionary<Camera, GameObject>(); private int _updateFrame; private bool _localRigInitialized; private bool _startupScheduled; private bool _wasConnected; private readonly HashSet<RigManager> _pendingHealthRefresh = new HashSet<RigManager>(); private readonly Dictionary<RigManager, RigRuntimeCache> _rigCache = new Dictionary<RigManager, RigRuntimeCache>(); private Mesh _bloodQuadMesh; private bool _pluginCallbacksRegistered; private const float DamageVolumeLifetime = 8f; private const float DamageVolumeRadius = 0.12f; private const float DamageVolumeDps = 2f; private static Dictionary<HumanBodyBones, int> BuildBoneToIndexMap() { Dictionary<HumanBodyBones, int> dictionary = new Dictionary<HumanBodyBones, int>(DamageBones.Length); for (int i = 0; i < DamageBones.Length; i++) { dictionary[DamageBones[i]] = i; } return dictionary; } public override void OnUpdate() { //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) NetworkSync.ProcessMainThreadQueue(); _updateFrame++; RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } if ((Object)(object)_cachedRm == (Object)null || (Object)(object)_cachedRm != (Object)(object)rigManager) { RigManager cachedRm = _cachedRm; _cachedRm = rigManager; _localRigInitialized = false; _startupScheduled = false; if ((Object)(object)cachedRm != (Object)null) { MelonLogger.Msg(ConsoleColor.Gray, "Local player RigManager changed, performing respawn cleanup."); RemoveRigFromCaches(cachedRm); SuppressNoLegRagdollForRespawn(); ResetLocalNoLegRagdollPermission(); StabilizeRespawnLocomotion(rigManager); RestoreDeadpieceLegUsage(rigManager); ResetLimbStats(rigManager, restoreBody: true); StabilizeRespawnLocomotion(rigManager); _lastTrackedBodyHealth = -1f; UpdateLimbPenaltyFlag(rigManager); SyncFullState(); NetworkSync.SendRespawn(PlayerIDManager.LocalSmallID); } } if (!_localRigInitialized) { if (!_startupScheduled) { _startupScheduled = true; MelonCoroutines.Start(DeferredStartup(rigManager)); } return; } float deltaTime = Time.deltaTime; _avatarSwapTimer += deltaTime; if (_avatarSwapTimer >= 0.2f) { _avatarSwapTimer = 0f; HandleAvatarSwap(rigManager); } HandleRespawnRestore(rigManager); HandleStickInputs(deltaTime); UpdateAutoInjectorUseWindow(); UpdateExplosiveUseWindow(); ProcessPlayerHealing(rigManager); ProcessSeveredLimbBleed(rigManager, deltaTime); if ((Object)(object)rigManager == (Object)(object)Player.RigManager) { ApplyMovementConstraints(rigManager); EnforceBothLegsGoneState(rigManager); if (IsBothLegsGone(rigManager) && (Object)(object)rigManager.physicsRig != (Object)null) { float num = Mathf.Pow(0.01f, Time.deltaTime); Rigidbody rbKnee = rigManager.physicsRig.rbKnee; Rigidbody rbFeet = rigManager.physicsRig.rbFeet; if ((Object)(object)rbKnee != (Object)null) { rbKnee.velocity *= num; rbKnee.angularVelocity *= num; } if ((Object)(object)rbFeet != (Object)null) { rbFeet.velocity *= num; rbFeet.angularVelocity *= num; } } } _slowUpdateTimer += deltaTime; if (_slowUpdateTimer >= 0.5f) { _slowUpdateTimer = 0f; try { string text = BloodColorOverride?.Value ?? "Auto"; if (text != _lastBroadcastedBloodColor) { _lastBroadcastedBloodColor = text; BroadcastBloodColor(); } } catch { } bool hasServer = NetworkInfo.HasServer; if (hasServer && !_wasConnected) { _wasConnected = true; NetworkSync.RegisterHandlers(); try { SyncFullState(); BroadcastBloodColor(); } catch { } } else if (!hasServer && _wasConnected) { _wasConnected = false; NetworkSync.ResetSessionState(); } if (hasServer) { ResyncLocalStateIfNeeded(); HandleAllRigsRespawnRestore(); if (_pendingNetworkStates.Count > 0) { ApplyPendingNetworkStates(); } } EnforceInvincibleRigsForAllTracked(); ProcessRemoteRigsStumpBlood(deltaTime); PruneTrackedRigs(); if (EnableVrEyeBlindness.Value) { UpdateVrEyeBlindness(rigManager); } } if ((_updateFrame & 7) == 0 && NetworkInfo.HasServer) { EnforceDismemberedBones(); EnforceAppliedStates(); EnforceRemoteFallenState(); } if ((_updateFrame & 3) == 0 && EnableMovementPenalty.Value) { EnforceLocalHandUsability(); } if ((Object)(object)_delayedDeathRm != (Object)null && Time.time >= _delayedDeathTime) { RigManager delayedDeathRm = _delayedDeathRm; _delayedDeathRm = null; if ((Object)(object)delayedDeathRm != (Object)null && (Object)(object)delayedDeathRm.health != (Object)null) { delayedDeathRm.health.Death(); } } } public override void OnLateUpdate() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00b6: 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_00c5: 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) RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && EnableMovementPenalty.Value && IsBothLegsGone(rigManager) && !((Object)(object)rigManager.avatar == (Object)null) && !((Object)(object)rigManager.avatar.animator == (Object)null)) { Transform boneTransform = rigManager.avatar.animator.GetBoneTransform((HumanBodyBones)0); Transform boneTransform2 = rigManager.avatar.animator.GetBoneTransform((HumanBodyBones)10); if ((Object)(object)boneTransform != (Object)null && (Object)(object)boneTransform2 != (Object)null) { Vector3 position = boneTransform2.position; boneTransform.position += Vector3.down * 0.5f; boneTransform2.position = position; } } } private IEnumerator DeferredStartup(RigManager rigManager) { yield return null; if (!_fleshCardFound) { TryCacheFleshSurface(); } if ((Object)(object)rigManager != (Object)null) { EnsureRigInitialized(rigManager); TrackRig(rigManager); } if (NetworkInfo.HasServer) { SyncExistingRemoteMetadata(); ApplyPendingNetworkStates(); } _localRigInitialized = true; SetupBoneMenu(); } private void SetupBoneMenu() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_006f: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (_boneMenuCreated) { return; } _boneMenuCreated = true; try { Page val = Page.Root.CreatePage("Deadpiece", Color.red, 0, true); val.CreateFunction("Red", Color.red, (Action)delegate { SetBloodColor("Red"); }); val.CreateFunction("Green", Color.green, (Action)delegate { SetBloodColor("Green"); }); val.CreateFunction("Blue", Color.blue, (Action)delegate { SetBloodColor("Blue"); }); val.CreateFunction("Yellow", Color.yellow, (Action)delegate { SetBloodColor("Yellow"); }); val.CreateFunction("Black", Color.gray, (Action)delegate { SetBloodColor("Black"); }); val.CreateFunction("White", Color.white, (Action)delegate { SetBloodColor("White"); }); val.CreateFunction("Purple", new Color(0.5f, 0.02f, 0.6f), (Action)delegate { SetBloodColor("Purple"); }); val.CreateFunction("Orange", new Color(1f, 0.5f, 0f), (Action)delegate { SetBloodColor("Orange"); }); val.CreateFunction("Pink", new Color(1f, 0.4f, 0.7f), (Action)delegate { SetBloodColor("Pink"); }); val.CreateFunction("Auto", Color.white, (Action)delegate { SetBloodColor("Auto"); }); MelonLogger.Msg(ConsoleColor.Gray, "BoneMenu registered. Blood Color menu available."); } catch (Exception ex) { MelonLogger.Warning("Failed to setup BoneMenu: " + ex.Message); } } private void SetBloodColor(string color) { BloodColorOverride.Value = color; _lastBroadcastedBloodColor = color; BroadcastBloodColor(); } private void SyncExistingRemoteMetadata() { string value = default(string); RigRefs val = default(RigRefs); foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID != null && !playerID.IsMe) { PlayerMetadata metadata = playerID.Metadata; if (((metadata != null) ? metadata.Metadata : null) != null && playerID.Metadata.Metadata.TryGetMetadata("DeadPieceLimbs", ref value)) { ApplyNetworkState(playerID.SmallID, value); } if (PlayerRepUtilities.TryGetReferences(playerID.SmallID, ref val) && (Object)(object)((val != null) ? val.RigManager : null) != (Object)null) { TrackRig(val.RigManager); } } } } public override void OnInitializeMelon() { //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Expected O, but got Unknown //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Expected O, but got Unknown Instance = this; WarnAboutLegacyNetworkPlugin(); InitializeModules(); NetworkSync.Initialize(); _pluginCallbacksRegistered = NetworkSync.RegisterCallbacks(OnPluginLimbHit, OnPluginLimbSever, OnPluginRespawn, OnPluginBloodColor, OnPluginFullState, GetPluginStateMask); try { _harmony.PatchAll(); } catch (Exception ex) { MelonLogger.Warning("Harmony PatchAll failed: " + ex.Message); } Category = MelonPreferences.CreateCategory("DeadPiece", "DeadPiece Settings"); MaxLimbHealth = Category.CreateEntry<float>("MaxLimbHealth", 100f, "Fallback Avatar HP", "Fallback max health when the avatar does not expose player health (limb HP scales from avatar max health)", false, false, (ValueValidator)null, (string)null); DamageMultiplier = Category.CreateEntry<float>("DamageMultiplier", 1f, "Damage Multiplier", "Multiplier for damage dealt to limbs", false, false, (ValueValidator)null, (string)null); EnableImpactBlood = Category.CreateEntry<bool>("EnableImpactBlood", true, "Severed Limb Bleed", "Tiny damage ticks at severed bone tips (vanilla impact blood)", false, false, (ValueValidator)null, (string)null); EnableBloodEffects = Category.CreateEntry<bool>("EnableBloodEffects", true, "Blood Effects", "Enable blood particle effects on dismemberment", false, false, (ValueValidator)null, (string)null); EnableGameBloodEffects = Category.CreateEntry<bool>("EnableGameBloodEffects", true, "Game Blood", "Clone already-loaded BONELAB blood VFX instead of shipping custom particles", false, false, (ValueValidator)null, (string)null); EnableFallbackBloodEffects = Category.CreateEntry<bool>("EnableProceduralFallbackBlood", true, "Procedural Fallback", "Always keep a lightweight procedural blood fallback when native BONELAB blood VFX cannot be spawned", false, false, (ValueValidator)null, (string)null); BloodColorOverride = Category.CreateEntry<string>("BloodColorOverride", "Auto", "Blood Color Override", "Force a specific blood color for all avatars (Auto = use per-avatar rules)", false, false, (ValueValidator)null, (string)null); EnableMovementPenalty = Category.CreateEntry<bool>("EnableMovementPenalty", true, "Movement Penalty", "Apply movement restrictions and body lowering when legs are lost", false, false, (ValueValidator)null, (string)null); EnableSecondLegRagdoll = Category.CreateEntry<bool>("EnableSecondLegRagdoll", false, "Second Leg Ragdoll", "Deprecated; DeadPiece no longer changes player leg physics", false, false, (ValueValidator)null, (string)null); SeveredLimbBleedDamagePerSecond = Category.CreateEntry<float>("SeveredLimbBleedDamagePerSecond", 0.01f, "Bleed DPS", "Damage per second at each severed limb tip", false, false, (ValueValidator)null, (string)null); EnableDualStickDeathReset = Category.CreateEntry<bool>("EnableDualStickDeathReset", true, "Dual Stick Death Reset", "Double-tap both thumbsticks to die and respawn (full reset)", false, false, (ValueValidator)null, (string)null); EnableSoundEffects = Category.CreateEntry<bool>("EnableSoundEffects", true, "Sound Effects", "Enable sound effects on dismemberment", false, false, (ValueValidator)null, (string)null); EnableVrEyeBlindness = Category.CreateEntry<bool>("EnableVrEyeBlindness", true, "VR Eye Blindness", "When an eye is destroyed, blackout that eye in the VR headset (local player only)", false, false, (ValueValidator)null, (string)null); EnableHeadSever = Category.CreateEntry<bool>("EnableHeadSever", true, "Head Sever", "Make lethal head damage use stronger decapitation effects", false, false, (ValueValidator)null, (string)null); EnableVisualCuts = Category.CreateEntry<bool>("EnableAvatarCutMasks", false, "Visual Cuts", "Experimental Marrow cut masks; keep off if the avatar shows square artifacts", false, false, (ValueValidator)null, (string)null); EnableVisualHitMarks = Category.CreateEntry<bool>("EnableVisualHitMarks", true, "Visual Hit Marks", "Try to use Marrow's visual damage hit system on normal limb damage", false, false, (ValueValidator)null, (string)null); EnableAttackTypeBalancing = Category.CreateEntry<bool>("EnableAttackTypeBalancing", true, "Attack Type Balancing", "Use different limb damage rules for piercing, blunt, sharp, fire, and explosion-like attacks", false, false, (ValueValidator)null, (string)null); PiercingDamageMultiplier = Category.CreateEntry<float>("PiercingDamageMultiplier", 1.35f, "Piercing Damage", "Limb damage multiplier for piercing attacks", false, false, (ValueValidator)null, (string)null); BluntDamageMultiplier = Category.CreateEntry<float>("BluntDamageMultiplier", 0.65f, "Blunt Damage", "Limb damage multiplier for blunt attacks", false, false, (ValueValidator)null, (string)null); SlashDamageMultiplier = Category.CreateEntry<float>("SlashDamageMultiplier", 1.55f, "Slash Damage", "Limb damage multiplier for slicing attacks", false, false, (ValueValidator)null, (string)null); StabDamageMultiplier = Category.CreateEntry<float>("StabDamageMultiplier", 1.75f, "Stab Damage", "Limb damage multiplier for stabbing attacks", false, false, (ValueValidator)null, (string)null); FireDamageMultiplier = Category.CreateEntry<float>("FireDamageMultiplier", 0.25f, "Fire Damage", "Limb damage multiplier for fire attacks", false, false, (ValueValidator)null, (string)null); SharpSeverChance = Category.CreateEntry<float>("SharpSeverChance", 0.35f, "Sharp Sever Chance", "Chance for slicing or stabbing attacks to instantly sever a damaged limb", false, false, (ValueValidator)null, (string)null); ExplosionDamageThreshold = Category.CreateEntry<float>("ExplosionDamageThreshold", 35f, "Explosion Threshold", "Minimum raw damage for grenade/mine/blast attacks to count as radial limb damage", false, false, (ValueValidator)null, (string)null); ExplosionRadius = Category.CreateEntry<float>("ExplosionRadius", 2.25f, "Explosion Radius", "Default blast radius for limb damage when the weapon does not provide one", false, false, (ValueValidator)null, (string)null); EnableBlastLimbDamage = Category.CreateEntry<bool>("EnableBlastLimbDamage", true, "Grenade & Mine Limbs", "Radial limb damage from grenades, mines, and other explosions", false, false, (ValueValidator)null, (string)null); EnableExplosiveHarmonyHooks = Category.CreateEntry<bool>("EnableExplosiveHarmonyHooks", true, "Explosive Hooks", "Patch grenade (RigidbodyProjectile) and blast (SimpleExplosionForce) detonations", false, false, (ValueValidator)null, (string)null); if (EnableExplosiveHarmonyHooks.Value) { ExplosivePatches.TryRegister(_harmony); } FusionRigLoadingFix.TryRegister(_harmony); MultiplayerHooking.OnPlayerJoined += new PlayerUpdate(OnPlayerJoined); MultiplayerHooking.OnPlayerLeft += new PlayerUpdate(OnPlayerLeft); PlayerID.OnMetadataChangedEvent += OnMetadataChanged; NetworkPlayer.OnNetworkRigCreated += OnNetworkRigCreated; PropertyInfo property = typeof(MelonUtils).GetProperty("UserDataDirectory", BindingFlags.Static | BindingFlags.Public); _soundFolder = Path.Combine((string)property.GetValue(null), "DeadPiece", "Sounds"); try { if (!Directory.Exists(_soundFolder)) { Directory.CreateDirectory(_soundFolder); } } catch (Exception ex2) { MelonLogger.Warning("Sound folder setup failed: " + ex2.Message); } LoadBloodColorOverrides(); } private static void WarnAboutLegacyNetworkPlugin() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { string text = assemblies[i]?.GetName()?.Name ?? string.Empty; if (text.Equals("DeadPiecePlugin", StringComparison.OrdinalIgnoreCase)) { MelonLogger.Error("[DeadPiece] Legacy Plugins/DeadPiecePlugin.dll is loaded. Remove it from every client; it conflicts with the integrated Fusion transport and can break joins."); break; } } } catch (Exception ex) { MelonLogger.Warning("[DeadPiece] Could not check for the legacy network plugin: " + ex.Message); } } public override void OnLateInitializeMelon() { if (!NetworkSync.RegisterHandlers()) { MelonLogger.Error("[DeadPiece] Fusion network handlers are unavailable; multiplayer sync is disabled."); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { _playersHealth.Clear(); _colliderBoneMap.Clear(); _colliderBoneDistanceMap.Clear(); _originalScales.Clear(); _lastHitEffectTimes.Clear(); _lastStumpBloodEffectTimes.Clear(); _stumpBloodStartTimes.Clear(); _lastAvatarHashes.Clear(); _avatarHealthBaseCache.Clear(); _avatarHealthHashCache.Clear(); _trackedRigs.Clear(); _rigCache.Clear(); _localRigInitialized = false; _lastTrackedBodyHealth = -1f; _lastAutoInjectorUseTime = -999f; _startupScheduled = false; _pendingHealthRefresh.Clear(); _cachedRm = null; _rigWasDead.Clear(); _pendingNetworkStates.Clear(); _lastAppliedNetworkSequence.Clear(); _remoteFallenPlayers.Clear(); _lastLeftArmUsable = true; _lastRightArmUsable = true; _localStateSequence = 0; _lastSentStateMask = uint.MaxValue; _lastStateSyncTime = -999f; _dualStickResetTapCount = 0; _fleshCardFound = false; _gameBloodParticlePrefab = null; _lastGameBloodParticleSearchTime = -999f; _loggedMissingGameBloodParticles = false; _loggedVanillaBloodSpawnable = false; _loggedVanillaBloodSpawnableFailure = false; _smallBloodSplatterSpawnable = null; _largeBloodSplatterSpawnable = null; _bloodBagBlasterSpawnable = null; _vanillaBloodSpawnablesRegistered = false; _locomotionStateSaved = false; _deadpieceNoLegUsageApplied = false; _deadpieceJumpBlocked = false; _deadpieceFallenStateApplied = false; SuppressNoLegRagdollForRespawn(); ResetLocalNoLegRagdollPermission(); _savedLocomotionMaxVelocity = 4.5f; _savedLocomotionCurrentMaxVelocity = 4.5f; _savedLocomotionJumpEnabled = true; ClearVrEyeCameraCache(); ForceClearNoLegRagdollState(Player.RigManager); ResetLimbStats(Player.RigManager, restoreBody: true); if (_dismemberSounds.Count == 0) { MelonCoroutines.Start(LoadDismemberSounds()); } } private void HandleAvatarSwap(RigManager rm) { if (!((Object)(object)rm == (Object)null) && !((Object)(object)rm.avatar == (Object)null)) { int hashCode = ((Object)rm.avatar).GetHashCode(); if (!_lastAvatarHashes.TryGetValue(rm, out var value) || value != hashCode) { _lastAvatarHashes[rm] = hashCode; OnAvatarSwapped(rm); } } } private void OnAvatarSwapped(RigManager rm) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026d: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: 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) //IL_0208: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rm == (Object)null || (Object)(object)rm.avatar == (Object)null || (Object)(object)rm.avatar.animator == (Object)null) { return; } _colliderBoneMap.Remove(rm); InvalidateAvatarHealthCache(rm); InvalidateRigCache(rm); if ((Object)(object)rm == (Object)(object)Player.RigManager) { _locomotionStateSaved = false; } _colliderBoneDistanceMap.Remove(rm); if (IsRigLimbDamageBlocked(rm)) { ResetLimbStats(rm, restoreBody: true); if ((Object)(object)rm == (Object)(object)Player.RigManager) { UpdateLimbPenaltyFlag(rm); } return; } BuildColliderBoneMap(rm); RebuildBoneCache(rm); if (!_originalScales.ContainsKey(rm)) { _originalScales[rm] = new Dictionary<HumanBodyBones, Vector3>(); } HashSet<HumanBodyBones> hashSet = new HashSet<HumanBodyBones>(); HumanBodyBones[] damageBones = DamageBones; HumanBodyBones[] array = damageBones; foreach (HumanBodyBones val in array) { Transform cachedBoneTransform = GetCachedBoneTransform(rm, val); if ((Object)(object)cachedBoneTransform == (Object)null) { continue; } if (_playersHealth.TryGetValue(rm, out var value) && value.TryGetValue(val, out var value2) && value2 <= 0f) { hashSet.Add(val); if (cachedBoneTransform.localScale != Vector3.zero) { _originalScales[rm][val] = cachedBoneTransform.localScale; } cachedBoneTransform.localScale = Vector3.zero; } else if (!_originalScales[rm].ContainsKey(val) || _originalScales[rm][val] == Vector3.zero) { _originalScales[rm][val] = ((cachedBoneTransform.localScale == Vector3.zero) ? Vector3.one : cachedBoneTransform.localScale); } } RestoreRigMeshes(rm); ResetLimbStats(rm, restoreBody: false); if (_playersHealth.TryGetValue(rm, out var value3)) { foreach (HumanBodyBones item in hashSet) { value3[item] = 0f - GetMaxHealthForBone(rm, item); } } RefreshLimbMaxHealth(rm); ScheduleDelayedHealthRefresh(rm); if ((Object)(object)rm == (Object)(object)Player.RigManager) { UpdateLimbPenaltyFlag(rm); SetHandUsable(Player.LeftHand, !IsLeftArmGone(rm)); SetHandUsable(Player.RightHand, !IsRightArmGone(rm)); } } public void OnHealthAvatarSet(Health health, Avatar avatar) { RigManager rigFromHealth = GetRigFromHealth(health); if ((Object)(object)rigFromHealth == (Object)null) { return; } TrackRig(rigFromHealth); InvalidateAvatarHealthCache(rigFromHealth); if (IsRigLimbDamageBlocked(rigFromHealth)) { ResetLimbStats(rigFromHealth, restoreBody: true); if ((Object)(object)rigFromHealth == (Object)(object)Player.RigManager) { UpdateLimbPenaltyFlag(rigFromHealth); SetLocalMetadata(""); SyncFullState(); } } else { RefreshLimbMaxHealth(rigFromHealth); } } private RigManager GetRigFromHealth(Health health) { if ((Object)(object)health == (Object)null) { return null; } return ((Component)health).GetComponentInParent<RigManager>(); } private void ScheduleDelayedHealthRefresh(RigManager rm) { if (!((Object)(object)rm == (Object)null) && _pendingHealthRefresh.Add(rm)) { MelonCoroutines.Start(DelayedRefreshLimbHealth(rm)); } } private IEnumerator DelayedRefreshLimbHealth(RigManager rm) { yield return null; yield return null; _pendingHealthRefresh.Remove(rm); if (!((Object)(object)rm == (Object)null)) { InvalidateAvatarHealthCache(rm); if (!IsRigLimbDamageBlocked(rm)) { RefreshLimbMaxHealth(rm); } } } public void EnsureRigInitialized(RigManager rm) { RigRuntimeCache orCreateRigCache = GetOrCreateRigCache(rm); if (orCreateRigCache.Initialized && _playersHealth.ContainsKey(rm) && _colliderBoneMap.ContainsKey(rm)) { TrackRig(rm); return; } if (!_playersHealth.ContainsKey(rm)) { ResetLimbStats(rm, restoreBody: false); } if (!_colliderBoneMap.ContainsKey(rm)) { BuildColliderBoneMap(rm); } RebuildBoneCache(rm); orCreateRigCache.Initialized = true; TrackRig(rm); } private void ResetLimbStats(RigManager rm, bool restoreBody) { //IL_010e: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01be: 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_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rm == (Object)null || (Object)(object)rm.avatar == (Object)null || (Object)(object)rm.avatar.animator == (Object)null) { return; } if (restoreBody && TryGetPlayerIdForRig(rm, out var playerId)) { _appliedStateMasks.Remove(playerId); _remoteFallenPlayers.Remove(playerId); if ((Object)(object)rm == (Object)(object)Player.RigManager) { _lastLeftArmUsable = true; _lastRightArmUsable = true; } } if (!_playersHealth.ContainsKey(rm)) { _playersHealth[rm] = new Dictionary<HumanBodyBones, float>(); } if (!_originalScales.ContainsKey(rm)) { _originalScales[rm] = new Dictionary<HumanBodyBones, Vector3>(); } HumanBodyBones[] damageBones = DamageBones; RebuildBoneCache(rm); RigRuntimeCache orCreateRigCache = GetOrCreateRigCache(rm); ResetLimbDamageBlockCache(rm); Transform[] boneTransforms = orCreateRigCache.BoneTransforms; for (int i = 0; i < damageBones.Length; i++) { HumanBodyBones val = damageBones[i]; Transform val2 = ((boneTransforms != null && i < boneTransforms.Length) ? boneTransforms[i] : null); if (!((Object)(object)val2 == (Object)null)) { if (!_originalScales[rm].ContainsKey(val)) { _originalScales[rm][val] = ((val2.localScale == Vector3.zero) ? Vector3.one : val2.localScale); } _playersHealth[rm][val] = GetMaxHealthForBone(rm, val); if (restoreBody) { val2.localScale = (_originalScales[rm].TryGetValue(val, out var value) ? value : Vector3.one); } } } RebuildLimbGoneFlags(rm); if (restoreBody) { ClearStumpBloodState(rm); RestoreRigMeshes(rm); if ((Object)(object)rm == (Object)(object)Player.RigManager) { ClearVrEyeCameraCache(); _lastAppliedLeftEyeBlind = false; _lastAppliedRightEyeBlind = false; UpdateVrEyeBlindness(rm); RestoreLocomotion(); RestoreOriginalLimits(rm); ResetLegRagdoll(rm); RestoreDeadpieceLegUsage(rm); RestoreNoLegJump(rm); RestoreNoLegFallenState(rm); SuppressCrouchForcingForRestoration(); SetHandUsable(Player.LeftHand, usable: true); SetHandUsable(Player.RightHand, usable: true); } ResetVisualDamage(rm); if ((Object)(object)rm.avatar != (Object)null && (Object)(object)rm.avatar.animator != (Object)null) { ((Behaviour)rm.avatar.animator).enabled = true; } } if ((Object)(object)rm == (Object)(object)Player.RigManager) { _lastTrackedBodyHealth = -1f; UpdateRigMissingLimbsFlag(rm); SetLocalMetadata(""); } InvalidateAvatarHealthCache(rm); RebuildBoneCache(rm); UpdateRigMissingLimbsFlag(rm); BuildColliderBoneMap(rm); } private void TryCacheFleshSurface() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (_fleshCardFound) { return; } try { AssetWarehouse instance = AssetWarehouse.Instance; if (instance == null || !AssetWarehouse.ready) { return; } SurfaceDataCard val = default(SurfaceDataCard); if (instance.TryGetDataCard<SurfaceDataCard>(new Barcode("SLZ.Backlot.SurfaceDataCard.Blood"), ref val) && (Object)(object)val != (Object)null) { _fleshSurfaceCard = new DataCardReference<SurfaceDataCard>(((Scannable)val).Barcode); _fleshCardFound = true; MelonLogger.Msg(ConsoleColor.Gray, "Found vanilla Blood surface card: SLZ.Backlot.SurfaceDataCard.Blood"); return; } SurfaceDataCard val2 = default(SurfaceDataCard); if (instance.TryGetDataCard<SurfaceDataCard>(new Barcode("slz.marrow.surfacedata.Flesh"), ref val2) && (Object)(object)val2 != (Object)null) { _fleshSurfaceCard = new DataCardReference<SurfaceDataCard>(((Scannable)val2).Barcode); _fleshCardFound = true; MelonLogger.Msg(ConsoleColor.Gray, "Found Flesh surface card by barcode: slz.marrow.surfacedata.Flesh"); return; } List<DataCard> dataCards = instance.GetDataCards(); if (dataCards == null) { return; } Enumerator<DataCard> enumerator = dataCards.GetEnumerator(); while (enumerator.MoveNext()) { DataCard current = enumerator.Current; if ((Object)(object)current == (Object)null) { continue; } SurfaceDataCard val3 = ((Il2CppObjectBase)current).TryCast<SurfaceDataCard>(); if (!((Object)(object)val3 == (Object)null)) { string text = ((Scannable)val3).Title ?? string.Empty; string text2 = text.ToLowerInvariant(); if (text2.Contains("blood") || text2.Contains("flesh")) { _fleshSurfaceCard = new DataCardReference<SurfaceDataCard>(((Scannable)val3).Barcode); _fleshCardFound = true; MelonLogger.Msg($"Found Flesh surface card by title: {text} ({((Scannable)val3).Barcode})"); break; } } } } catch (Exception ex) { MelonLogger.Warning("Flesh surface scan failed: " + ex.Message); } } private void SetFleshImpactProperties(RigManager rm, HumanBodyBones bone) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!EnableImpactBlood.Value || !_fleshCardFound || (Object)(object)rm == (Object)null || !_colliderBoneMap.TryGetValue(rm, out var value)) { return; } try { foreach (KeyValuePair<Collider, HumanBodyBones> item in value) { if (item.Value != bone) { continue; } Collider key = item.Key; if (!((Object)(object)key == (Object)null)) { ImpactProperties val = ((Component)key).GetComponent<ImpactProperties>(); if ((Object)(object)val == (Object)null) { val = ((Component)key).gameObject.AddComponent<ImpactProperties>(); } if ((Object)(object)val != (Object)null) { val.SurfaceDataCard = _fleshSurfaceCard; } } } } catch (Exception ex) { MelonLogger.Warning($"SetFleshImpactProperties failed for {bone}: {ex.Message}"); } } private void ApplyBloodImpactProperties(RigManager rm) { if (!EnableImpactBlood.Value || (Object)(object)rm == (Object)null) { return; } if (!_fleshCardFound) { TryCacheFleshSurface(); } if (!_fleshCardFound || !_colliderBoneMap.TryGetValue(rm, out var value)) { return; } try { foreach (KeyValuePair<Collider, HumanBodyBones> item in value) { Collider key = item.Key; if (!((Object)(object)key == (Object)null)) { ImpactProperties val = ((Component)key).GetComponent<ImpactProperties>(); if ((Object)(object)val == (Object)null) { val = ((Component)key).gameObject.AddComponent<ImpactProperties>(); } if ((Object)(object)val != (Object)null) { val.SurfaceDataCard = _fleshSurfaceCard; } } } } catch (Exception ex) { MelonLogger.Warning("ApplyBloodImpactProperties failed: " + ex.Message); } } private static bool IsAvatarBodyCollider(Collider collider, Transform avatarRoot) { if ((Object)(object)collider == (Object)null || (Object)(object)avatarRoot == (Object)null) { return false; } Transform val = ((Component)collider).transform; if (!val.IsChildOf(avatarRoot)) { return false; } for (int i = 0; i < 14; i++) { if (!((Object)(object)val != (Object)null)) { break; } if (!((Object)(object)val != (Object)(object)avatarRoot)) { break; } string text = ((Object)val).name.ToLowerInvariant(); if (text.Contains("gun") || text.Contains("pistol") || text.Contains("rifle") || text.Contains("weapon") || text.Contains("magazine") || text.Contains("ammo") || text.Contains("slide") || text.Contains("barrel") || text.Contains("trigger") || text.Contains("holster")) { return false; } Type il2CppType = ((Object)val).GetIl2CppType(); if (il2CppType != (Type)null) { string text2 = il2CppType.FullName ?? string.Empty; if (text2.Contains("Gun") || text2.Contains("Weapon") || text2.Contains("Magazine") || text2.Contains("Ammo") || text2.Contains("Firearm") || text2.Contains("Cartridge") || text2.Contains("Projectile")) { return false; } } val = val.parent; } return true; } private void RegrowLimb(RigManager rm, HumanBodyBones bone) { //IL_003a: 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_008c: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00a9: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rm == (Object)null || (Object)(object)rm.avatar == (Object)null || (Object)(object)rm.avatar.animator == (Object)null) { return; } Transform cachedBoneTransform = GetCachedBoneTransform(rm, bone); if (!((Object)(object)cachedBoneTransform == (Object)null)) { if (!_originalScales.TryGetValue(rm, out var value)) { value = new Dictionary<HumanBodyBones, Vector3>(); _originalScales[rm] = value; } if (!value.TryGetValue(bone, out var value2) || value2 == Vector3.zero) { value2 = (value[bone] = Vector3.one); } cachedBoneTransform.localScale = value2; if (_playersHealth.TryGetValue(rm, out var value3)) { value3[bone] = GetMaxHealthForBone(rm, bone); } ClearStumpBloodState(rm, bone); } } private void ProcessPlayerHealing(RigManager rm) { if ((Object)(object)rm != (Object)(object)Player.RigManager || (Object)(object)((rm != null) ? rm.health : null) == (Object)null || !rm.health.alive) { return; } if (IsRigLimbDamageBlocked(rm) || !_playersHealth.ContainsKey(rm)) { _lastTrackedBodyHealth = rm.health.curr_Health; return; } float curr_Health = rm.health.curr_Health; if (_lastTrackedBodyHealth < 0f) { _lastTrackedBodyHealth = curr_Health; return; } if (curr_Health <= _lastTrackedBodyHealth) { _lastTrackedBodyHealth = curr_Health; return; } _lastTrackedBodyHealth = curr_Health; if (IsAutoInjectorUseActiveOrRecent()) { RestoreMissingLimbsFromHealing(rm); } } public void OnHealthSetFullHealth(Health health, float previousHealth) { RigManager rigFromHealth = GetRigFromHealth(health); if ((Object)(object)rigFromHealth == (Object)null) { return; } if ((Object)(object)rigFromHealth == (Object)(object)Player.RigManager) { if (IsAutoInjectorUseActiveOrRecent()) { RestoreMissingLimbsFromHealing(rigFromHealth); } } else if (IsRemotePlayerRig(rigFromHealth) && health.curr_Health > previousHealth) { RestoreMissingLimbsFromHealing(rigFromHealth); } } private void UpdateAutoInjectorUseWindow() { try { if (IsAutoInjectorUsePressed(Player.LeftHand, Player.LeftController) || IsAutoInjectorUsePressed(Player.RightHand, Player.RightController)) { _lastAutoInjectorUseTime = Time.unscaledTime; } } catch { } } public bool IsAutoInjectorUseActiveOrRecent() { if (Time.unscaledTime - _lastAutoInjectorUseTime <= 0.8f) { return true; } return IsAutoInjectorUsePressed(Player.LeftHand, Player.LeftController) || IsAutoInjectorUsePressed(Player.RightHand, Player.RightController); } private void UpdateExplosiveUseWindow() { try { if ((IsExplosiveHeld(Player.LeftHand) || IsExplosiveHeld(Player.RightHand)) && (IsExplosiveDetonatePressed(Player.LeftHand, Player.LeftController) || IsExplosiveDetonatePressed(Player.RightHand, Player.RightController))) { _lastExplosiveUseTime = Time.unscaledTime; TriggerSelfExplosion(); } } catch { } } public bool IsExplosiveUseActiveOrRecent() { if (Time.unscaledTime - _lastExplosiveUseTime <= 1.5f) { return true; } return false; } private bool IsExplosiveHeld(Hand hand) { if ((Object)(object)hand == (Object)null) { return false; } try { HandReciever attachedReceiver = hand.AttachedReceiver; if ((Object)(object)attachedReceiver == (Object)null) { return false; } if (IsExplosiveObject(((Component)attachedReceiver).gameObject)) { return true; } IGrippable host = attachedReceiver.Host; GameObject gameObject = ((host != null) ? host.GetHostGameObject() : null); return IsExplosiveObject(gameObject); } catch { } return false; } private bool IsExplosiveObject(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return false; } Transform val = gameObject.transform; for (int i = 0; i < 8; i++) { if (!((Object)(object)val != (Object)null)) { break; } if (LooksLikeExplosiveName(((Object)val).name)) { return true; } val = val.parent; } return false; } private bool LooksLikeExplosiveName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return false; } string text = objectName.ToLowerInvariant(); return text.Contains("explosive") || text.Contains("micro") || text.Contains("nuke") || text.Contains("dynamite") || text.Contains("c4") || text.Contains("grenade") || text.Contains("prox") || text.Contains("ied") || text.Contains("mine") || (text.Contains("timed") && (text.Contains("explos") || text.Contains("nuke"))); } private bool IsExplosiveDetonatePressed(Hand hand, BaseController controller) { if ((Object)(object)hand == (Object)null || (Object)(object)controller == (Object)null) { return false; } bool primaryInteractionButtonDown = controller.GetPrimaryInteractionButtonDown(); bool secondaryInteractionButtonDown = controller.GetSecondaryInteractionButtonDown(); return primaryInteractionButtonDown && secondaryInteractionButtonDown; } private void TriggerSelfExplosion() { RigManager rigManager = Player.RigManager; if ((Object)(object)rigManager == (Object)null) { return; } string[] array = new string[41] { "BaBaCorp.MiscExplosiveDevices.Spawnable.MicroNukeGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedNuke", "BaBaCorp.MiscExplosiveDevices.Spawnable.KCB4VoidTunnelingDevice", "BaBaCorp.MiscExplosiveDevices.Spawnable.IncinMissile", "BaBaCorp.MiscExplosiveDevices.Spawnable.Missile", "BaBaCorp.MiscExplosiveDevices.Spawnable.MiniMissile", "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedC4", "BaBaCorp.MiscExplosiveDevices.Spawnable.CelebratoryC4", "BaBaCorp.MiscExplosiveDevices.Spawnable.RemoteIED", "BaBaCorp.MiscExplosiveDevices.Spawnable.TriggeredExplosive", "BaBaCorp.MiscExplosiveDevices.Spawnable.ImpactExplosive", "BaBaCorp.MiscExplosiveDevices.Spawnable.TimedExplosive6sec", "BaBaCorp.MiscExplosiveDevices.Spawnable.M72LAW", "BaBaCorp.MiscExplosiveDevices.Spawnable.M72LawINF", "BaBaCorp.MiscExplosiveDevices.Spawnable.ClassicBomb", "BaBaCorp.MiscExplosiveDevices.Spawnable.Dynamite", "BaBaCorp.MiscExplosiveDevices.Spawnable.ProxMine", "BaBaCorp.MiscExplosiveDevices.Spawnable.GiftMine", "BaBaCorp.MiscExplosiveDevices.Spawnable.FragmentationGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.IncendiaryGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.DivinationGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.GasGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.JoyousGreenGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.Stielhandgranate", "BaBaCorp.MiscExplosiveDevices.Spawnable.SmallRocket", "BaBaCorp.MiscExplosiveDevices.Spawnable.PurpleFireworkRocket", "BaBaCorp.MiscExplosiveDevices.Spawnable.GreenFireworkRocket", "BaBaCorp.MiscExplosiveDevices.Spawnable.BlueFireworkRocket", "BaBaCorp.MiscExplosiveDevices.Spawnable.RedFireworkRocket", "BaBaCorp.MiscExplosiveDevices.Spawnable.BirthdayCake", "BaBaCorp.MiscExplosiveDevices.Spawnable.Frank", "BaBaCorp.MiscExplosiveDevices.Spawnable.BatteryAcidGlass", "BaBaCorp.MiscExplosiveDevices.Spawnable.CrateWithLid", "BaBaCorp.MiscExplosiveDevices.Spawnable.PropaneTank", "BaBaCorp.MiscExplosiveDevices.Spawnable.FuelTank", "BaBaCorp.MiscExplosiveDevices.Spawnable.SmokeGrenade", "BaBaCorp.MiscExplosiveDevices.Spawnable.Flare", "BaBaCorp.MiscExplosiveDevices.Spawnable.Jarate", "BaBaCorp.MiscExplosiveDevices.Spawnable.Lighter", "BaBaCorp.MiscExplosiveDevices.Spawnable.Pliers", "BaBaCorp.MiscExplosiveDevices.Spawnable.ExplosionSmallBigDamage" }; string[] array2 = array; foreach (string text in array2) { try { TriggerExplosion(rigManager, text); MelonLogger.Msg(ConsoleColor.Gray, "Self explosion triggered with: " + text); break; } catch (Exception ex) { MelonLogger.Warning("Explosion failed for " + text + ": " + ex.Message); } } } private void TriggerExplosion(RigManager rm, string explosiveBarcode) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00d2: Unknown result type (might be due to invalid IL or missing references) MelonLogger.Msg(ConsoleColor.Gray, "TriggerExplosion: attempting " + explosiveBarcode); if ((Object)(object)rm == (Object)null) { MelonLogger.Error("RigManager is null!"); return; } try { Spawnable val = new Spawnable { crateRef = new SpawnableCrateReference(explosiveBarcode), policyData = null }; if (!val.IsValid()) { MelonLogger.Error("Spawnable is not valid for " + explosiveBarcode); return; } MelonLogger.Msg(ConsoleColor.Gray, "Spawnable valid, spawning at position..."); Vector3 val2 = ((Component)rm).transform.position + ((Component)rm).transform.forward * 0.5f + ((Component)rm).transform.up * 0.5f; Action<GameObject> action = OnExplosiveSpawned; AssetSpawner.Spawn(val, val2, Quaternion.identity, new Nullable<Vector3>(Vector3.one), (Transform)null, false, (Nullable<int>)null, Action<GameObject>.op_Implicit(action), (Action<GameObject>)null); MelonLogger.Msg(ConsoleColor.Gray, "AssetSpawner.Spawn called for " + explosiveBarcode); } catch (Exception value) { MelonLogger.Error($"TriggerExplosion exception for {explosiveBarcode}: {value}"); } } private void OnExplosiveSpawned(GameObject spawned) { MelonLogger.Msg(ConsoleColor.Gray, $"OnExplosiveSpawned called, spawned: {(Object)(object)spawned != (Object)null}"); if ((Object)(object)spawned != (Object)null) { MelonLogger.Msg(ConsoleColor.Gray, $"Spawned object name: {((Object)spawned).name}, active: {spawned.activeInHierarchy}"); Il2CppArrayBase<MonoBehaviour> componentsInChildren = spawned.GetComponentsInChildren<MonoBehaviour>(true); MelonLogger.Msg(ConsoleColor.Gray, $"Found {componentsInChildren.Length} components"); foreach (MonoBehaviour item in componentsInChildren) { if ((Object)(object)item != (Object)null) { MelonLogger.Msg(ConsoleColor.Gray, "Component: " + ((object)item).GetType().Name); } } ForceDetonate(spawned); } else { MelonLogger.Error("Spawned object is null!"); } } private void ForceDetonate(GameObject spawned) { MelonLogger.Msg(ConsoleColor.Gray, "ForceDetonate called for " + ((Object)spawned).name); try { Il2CppArrayBase<MonoBehaviour> componentsInChildren = spawned.GetComponentsInChildren<MonoBehaviour>(true); MelonLogger.Msg(ConsoleColor.Gray, $"Checking {componentsInChildren.Length} components for Detonate/Explode methods"); foreach (MonoBehaviour item in componentsInChildren) { if (!((Object)(object)item == (Object)null)) { MethodInfo method = ((object)item).GetType().GetMethod("Detonate", BindingFlags.Instance | BindingFlags.Public); if (method != null) { MelonLogger.Msg(ConsoleColor.Gray, "Found Detonate() on " + ((object)item).GetType().Name + ", invoking..."); method.Invoke(item, null); MelonLogger.Msg(ConsoleColor.Gray, "Detonated via " + ((object)item).GetType().Name + ".Detonate()"); return; } } } Rigidbody component = spawned.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.useGravity = true; component.isKinematic = false; MelonLogger.Msg(ConsoleColor.Gray, "Set rigidbody for gravity detonation"); } else { MelonLogger.Warning("No Rigidbody found on spawned object"); } foreach (MonoBehaviour item2 in componentsInChildren) { if (!((Object)(object)item2 == (Object)null)) { MethodInfo method2 = ((object)item2).GetType().GetMethod("Explode", BindingFlags.Instance | BindingFlags.Public); if (method2 != null) { MelonLogger.Msg(ConsoleColor.Gray, "Found Explode() on " + ((object)item2).GetType().Name + ", invoking..."); method2.Invoke(item2, null); MelonLogger.Msg(ConsoleColor.Gray, "Detonated via " + ((object)item2).GetType().Name + ".Explode()"); return; } } } MelonLogger.Warning("No detonation method found, object spawned but may not explode automatically"); } catch (Exception value) { MelonLogger.Error($"ForceDetonate exception: {value}"); } } public bool IsHoldingNimbusGun(RigManager rm) { return IsNimbusGunHand(Player.LeftHand) || IsNimbusGunHand(Player.RightHand); } private bool IsNimbusGunHand(Hand hand) { if ((Object)(object)hand == (Object)null) { return false; } try { HandReciever attachedReceiver = hand.AttachedReceiver; if ((Object)(object)attachedReceiver == (Object)null) { return false; } IGrippable host = attachedReceiver.Host; GameObject val = ((host != null) ? host.GetHostGameObject() : null); if ((Object)(object)val == (Object)null) { return false; } SpawnableCrate componentInChildren = val.GetComponentInChildren<SpawnableCrate>(true); if ((Object)(object)componentInChildren != (Object)null && ((Scannable)componentInChildren).Barcode != (Barcode)null && ((Object)((Scannable)componentInChildren).Barcode).ToString().Contains("Nimbus")) { return true; } Transform val2 = val.transform; while ((Object)(object)val2 != (Object)null) { if (((Object)val2).name.Contains("Nimbus")) { return true; } val2 = val2.parent; } } catch { } return false; } private bool IsAutoInjectorUsePressed(Hand hand, BaseController controller) { if (!IsAutoInjectorHeldByHand(hand)) { return false; } bool flag = false; try { flag |= (Object)(object)hand != (Object)null && (hand.GetIndexButtonDown() || hand.GetIndexButton()); } catch { } try { flag |= (Object)(object)controller != (Object)null && (controller.GetPrimaryInteractionButtonDown() || controller.GetPrimaryInteractionButton()); flag |= (Object)(object)controller != (Object)null && (controller.GetSecondaryInteractionButtonDown() || controller.GetSecondaryInteractionButton()); flag |= (Object)(object)controller != (Object)null && (controller.GetAButtonDown() || controller.GetAButton()); flag |= (Object)(object)controller != (Object)null && (controller.GetBButtonDown() || controller.GetBButton()); } catch { } return flag; } private bool IsAutoInjectorHeldByHand(Hand hand) { if ((Object)(object)hand == (Object)null) { return false; } try { HandReciever attachedReceiver = hand.AttachedReceiver; if ((Object)(object)attachedReceiver == (Object)null) { return false; } if (IsAutoInjectorObject(((Component)attachedReceiver).gameObject)) { return true; } IGrippable host = attachedReceiver.Host; GameObject gameObject = ((host != null) ? host.GetHostGameObject() : null); return IsAutoInjectorObject(gameObject); } catch { return false; } } private bool IsAutoInjectorObject(GameObject gameObject) { Transform val = (((Object)(object)gameObject != (Object)null) ? gameObject.transform : null); for (int i = 0; i < 8; i++) { if (!((Object)(object)val != (Object)null)) { break; } if (LooksLikeAutoInjectorName(((Object)val).name)) { return true; } val = val.parent; } return false; } private bool LooksLikeAutoInjectorName(string objectName) { if (string.IsNullOrEmpty(objectName)) { return false; } string text = objectName.ToLowerInvariant(); string text2 = text.Replace(" ", string.Empty).Replace("_", string.Empty).Replace("-", string.Empty); return text2.Contains("autoinjector") || (text2.Contains("auto") && text2.Contains("inject")) || text2.Contains("signalisautoinjector"); } private bool RestoreMissingLimbsFromHealing(RigManager rm) { //IL_00b9: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rm == (Object)null || (Object)(object)rm.avatar == (Object)null || (Object)(object)rm.avatar.animator == (Object)null) { return false; } EnsureRigInitialized(rm); if (IsRigLimbDamageBlocked(rm)) { ResetLimbStats(rm, restoreBody: true); if ((Object)(object)rm != (Object)(object)Player.RigManager && TryGetPlayerIdForRig(rm, out var playerId)) { NetworkSync.SendFullState(playerId, 0u, 0, 0); } return true; } if (!_playersHealth.TryGetValue(rm, out var value)) { return false; } bool flag = false; for (int i = 0; i < DamageBones.Length; i++) { HumanBodyBones val = DamageBones[i]; float value2; bool flag2 = value.TryGetValue(val, out value2) && value2 < 0f; if (IsBoneGone(rm, val) || flag2) { RegrowLimb(rm, val); flag = true; } } if (!flag) { return false; } RebuildLimbGoneFlags(rm); UpdateRigMissingLimbsFlag(rm); ResetVisualDamage(rm); if ((Object)(object)rm == (Object)(object)Player.RigManager) { SetHandUsable(Player.LeftHand, !IsLeftArmGone(rm)); SetHandUsable(Player.RightHand, !IsRightArmGone(rm)); if (EnableVrEyeBlindness.Value) { UpdateVrEyeBlindness(rm); } RestoreLocomotion(); RestoreOriginalLimits(rm); ResetLegRagdoll(rm); RestoreDeadpieceLegUsage(rm); RestoreNoLegJump(rm); RestoreNoLegFallenState(rm); SuppressCrouchForcingForRestoration(); } byte playerId3; if (NetworkInfo.HasServer) { byte playerId2; if ((Object)(object)rm == (Object)(object)Player.RigManager) { SyncFullState(); } else if (TryGetPlayerIdForRig(rm, out playerId2)) { uint stateMask = GetStateMask(rm); NetworkSync.SendFullState(playerId2, stateMask, 0, 0); } } else if ((Object)(object)rm != (Object)(object)Player.RigManager && TryGetPlayerIdForRig(rm, out playerId3)) { uint stateMask2 = GetStateMask(rm); NetworkSync.SendFullState(playerId3, stateMask2, 0, 0); } return true; } private void ProcessSeveredLimbBleed(RigManager rm, float deltaTime) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (!EnableImpactBlood.Value || (Object)(object)rm == (Object)null || deltaTime <= 0f || !_playersHealth.ContainsKey(rm)) { return; } float num = Mathf.Max(0f, SeveredLimbBleedDamagePerSecond.Value) * deltaTime; if (num <= 0f && !EnableBloodEffects.Value) { return; } for (int i = 0; i < DamageBones.Length; i++) { HumanBodyBones bone = DamageBones[i]; if (!IsBoneGone(rm, bone)) { continue; } float remainingStumpBloodLifetime = GetRemainingStumpBloodLifetime(rm, bone, startIfMissing: true); if (!(remainingStumpBloodLifetime <= 0.05f)) { if (num > 0f) { TryApplyBleedAtBone(rm, bone, num); } TryPlayStumpBloodEffect(rm, bone, remainingStumpBloodLifetime); } } } private void ProcessRemoteRigsStumpBlood(float deltaTime) { if (!EnableImpactBlood.Value || _trackedRigs.Count == 0 || deltaTime <= 0f) { return; } RigManager[] array = _trackedRigs.ToArray(); foreach (RigManager val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)Player.RigManager) { ProcessSeveredLimbBleed(val, deltaTime); } } } private void TryPlayStumpBloodEffect(RigManager rm, HumanBodyBones bone, float remainingBloodLifetime) { //IL_0069: 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_009c: 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) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00c5: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ee: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if (!EnableBloodEffects.Value || !EnableGameBloodEffects.Value || (Object)(object)rm == (Object)null || (Object)(object)rm.avatar == (Object)null || (Object)(object)rm.avatar.animator == (Object)null || remainingBloodLifetime <= 0.05f || !ShouldPlayStumpBloodEffect(rm, bone)) { return; } Transform cachedBoneTransform = GetCachedBoneTransform(rm, bone); if (!((Object)(object)cachedBoneTransform == (Object)null)) { Vector3 val = GetBoneStreamDirection(rm, bone, cachedBoneTransform); if (val == Vector3.zero) { val = cachedBoneTransform.up; } val = ((Vector3)(ref val)).normalized; Vector3 val2 = cachedBoneTransform.position + val * 0.04f; Color bloodColor = GetBloodColor(rm); TryApplyBloodImpactAtBone(rm, bone, val2, 3f, bloodColor); if (!TrySpawnVanillaBloodSpawnable(val2, 0.72f, stream: true, Quaternion.LookRotation(val), bloodColor, remainingBloodLifetime)) { TrySpawnGameBlood(val2, 0.55f, bloodColor, remainingBloodLifetime); } } } private bool ShouldPlayStumpBloodEffect(RigManager rm, HumanBodyBones bone) { //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) if (!_lastStumpBloodEffectTimes.TryGetValue(rm, out var value)) { value = new Dictionary<HumanBodyBones, float>(); _lastStumpBloodEffectTimes[rm] = value; } if (value.TryGetValue(bone, out var value2) && Time.time - value2 < 0.45f) { return false; } value[bone] = Time.time; return true; } private void MarkStumpBloodStarted(RigManager rm, HumanBodyBones bone) { //IL_003b: 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 (!((Object)(object)rm == (Object)null)) { if (!_stumpBloodStartTimes.TryGetValue(rm, out var value)) { value = new Dictionary<HumanBodyBones, float>(); _stumpBloodStartTimes[rm] = value; } value[bone] = Time.time; if (_lastStumpBloodEffectTimes.TryGetValue(rm, out var value2)) { value2.Remove(bone); } } } private bool HasStumpBloodStart(RigManager rm, HumanBodyBones bone) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Dictionary<HumanBodyBones, float> value; return (Object)(object)rm != (Object)null && _stumpBloodStartTimes.TryGetValue(rm, out value) && value.ContainsKey(bone); } private float GetRemainingStumpBloodLifetime(RigManager rm, HumanBodyBones bone, bool startIfMissing) { //IL_0026: 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) if ((Object)(object)rm == (Object)null) { return 0f; } if (!_stumpBloodStartTimes.TryGetValue(rm, out var value) || !value.TryGetValue(bone, out var value2)) { if (!startIfMissing) { return 0f; } MarkStumpBloodStarted(rm, bone); value2 = Time.time; } return Mathf.Max(0f, 10f - (Time.time - value2)); } private void ClearStumpBloodState(RigManager rm) { if (!((Object)(object)rm == (Object)null)) { _stumpBloodStartTimes.Remove(rm); _lastStumpBloodEffectTimes.Remove(rm); } } private void ClearStumpBloodState(RigManager rm, HumanBodyBones bone) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rm == (Object)null) { return; } if (_stumpBloodStartTimes.TryGetValue(rm, out var value)) { value.Remove(bone); if (value.Count == 0) { _stumpBloodStartTimes.Remove(rm); } } if (_lastStumpBloodEffectTimes.TryGetValue(rm, out var value2)) { value2.Remove(bone); if (value2.Count == 0) { _lastStumpBloodEffectTimes.Remove(rm); } } } private void TryApplyBleedAtBone(RigManager rm, HumanBodyBones bone, float damage) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) TryApplyBloodImpactAtBone(rm, bone, Vector3.zero, damage); } private bool TryApplyBloodImpactAtBone(RigManager rm, HumanBodyBones bone, Vector3 origin, float damage) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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) return TryApplyBloodImpactAtBone(rm, bone, origin, damage, Color.white); } private bool TryApplyBloodImpactAtBone(RigManager rm, HumanBodyBones bone, Vector3 origin, float damage, Color color) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((rm != null) ? rm.avatar : null) == (Object)null || damage <= 0f || !_colliderBoneMap.TryGetValue(rm, out var value)) { return false; } Collider val = null; foreach (KeyValuePair<Collider, HumanBodyBones> item in value) { if (item.Value == bone) { val = item.Key; break; } } if ((Object)(object)val == (Object)null) { return false; } try { ImpactProperties val2 = ((Component)val).GetComponent<ImpactProperties>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).gameObject.AddComponent<ImpactProperties>(); } if ((Object)(object)val2 == (Object)null) { return false; } if (_fleshCardFound) { val2.SurfaceDataCard = _fleshSurfaceCard; } Vector3 val3; Bounds bounds; if (!(origin == Vector3.zero)) { val3 = origin; } else { bounds = val.bounds; val3 = ((Bounds)(ref bounds)).center; } Vector3 val4 = val3; bounds = val.bounds; Vector3 val5 = ((Bounds)(ref bounds)).center - val4; if (val5 == Vector3.zero) { val5 = Vector3.down; } ((Vector3)(ref val5)).Normalize(); Attack val6 = new Attack { damage = damage, normal = -val5, origin = val4, direction = val5, backFacing = false, OrderInPool = 0, collider = val, attackType = (AttackType)1, proxy = null }; val2.ReceiveAttack(val6); return true; } catch { } return false; } private void SpawnBloodPoolDecal(Vector3 origin, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_0111: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = origin; val.y += 2.5f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 5f, -1, (QueryTriggerInteraction)1) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null) { GameObject val3 = new GameObject("DeadPiece_BloodPool"); val3.transform.position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.005f; val3.transform.rotation = Quaternion.LookRotation(((RaycastHit)(ref val2)).normal); val3.transform.localScale = Vector3.one * Mathf.Lerp(0.08f, 0.35f, Random.value); val3.transform.Rotate(0f, 0f, Random.Range(0f, 360f)); MeshFilter val4 = val3.AddComponent<MeshFilter>(); val4.sharedMesh = BuildBloodQuadMesh(); MeshRenderer val5 = val3.AddComponent<MeshRenderer>(); ((Renderer)val5).material = new Material(Shader.Find("Sprites/Default")); ((Renderer)val5).material.color = color; ((Renderer)val5).material.mainTexture = null; Object.Destroy((Object)(object)val3, 10f); } } catch { } } private IEnumerator DelayedPoolClear(Poolee poolee, float delay) { yield return (object)new WaitForSeconds(delay); if ((Object)(object)poolee != (Object)null && (Object)(object)((Component)poolee).gameObject != (Object)null) { StopBloodEffectObject(((Component)poolee).gameObject); HideRenderers(((Component)poolee).gameObject); try { AssetSpawner.Clear(poolee); } catch { } if ((Object)(object)((Component)poolee).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)poolee).gameObject); } } } private IEnumerator RunAsyncSpawnBlood(Spawnable spawnable, Vector3 position, Quaternion rotation, Nullable<Vector3> scale, Color color, float clearDelay) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) Poolee result = null; bool done = false; UniTask<Poolee> task = AssetSpawner.SpawnAsync(spawnable, position, rotation, scale, (Transform)null, false, (Nullable<int>)null, (Action<GameObject>)null, (Action<GameObject>)null, (Action<GameObject>)null); Awaiter<Poolee> awaiter = task.GetAwaiter(); for (int i = 0; i < 60; i++) { if (done) { break; } yield return null; try { result = awaiter.GetResult(); done = true; } catch { } } if (!((Object)(object)result != (Object)null) || !((Object)(object)((Component)result).gameObject != (Object)null)) { yield break; } if (color != Color.white) { Renderer[] renderers = Il2CppArrayBase<Renderer>.op_Implicit(((Component)result).GetComponentsInChildren<Renderer>(true)); Renderer[] array = renderers; foreach (Renderer r in array) { Material mat = r.material; string[] colorProps = new string[5] { "_Color", "_BaseColor", "_TintColor", "_EmissiveColor", "_MainColor" }; string[] array2 = colorProps; foreach (string prop in array2) { if (mat.HasProperty(prop)) { mat.SetColor(prop, color); break; } } } ParticleSystem[] particles = Il2CppArrayBase<ParticleSystem>.op_Implicit(((Component)result).GetComponentsInChildren<ParticleSystem>(true)); ParticleSystem[] array3 = particles; foreach (ParticleSystem ps in array3) { MainModule main = ps.main; main.startColor = MinMaxGradient.op_Implicit(color); } } MelonCoroutines.Start(DelayedPoolClear(result, clearDelay)); } private IEnumerator RunAsyncSpawnVanillaBlood(Spawnable spawnable, Vector3 position, Quaternion rotation, Nullable<Vector3> scale, Nullable<int> groupId, Color color, float clearDelay) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Poolee result = null; bool done = false; UniTask<Poolee> spawnTask = AssetSpawner.SpawnAsync(spawnable, position, rotation, scale, (Transform)null, false, groupId, (Action<GameObject>)null, (Action<GameObject>)null, (Action<GameObject>)null); Awaiter<Poolee> awaiter = spawnTask.GetAwaiter(); for (int i = 0; i < 60; i++) { if (done) { break; } yield return null; try { result = awaiter.GetResult(); done = true; } catch { } } if ((Object)(object)result == (Object)null) { if (!_loggedVanillaBloodSpawnableFailure) { _loggedVanillaBloodSpawnableFailure = true; Melo