using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.SDK.Modules;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using PhysicsRemover;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(MainMod), "PhysicsRemover", "1.2.0", "dimastv", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "BoneLib", "LabFusion" })]
[assembly: MelonColor(255, 30, 200, 255)]
[assembly: MelonAuthorColor(255, 100, 220, 255)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PhysicsRemover")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PhysicsRemover")]
[assembly: AssemblyTitle("PhysicsRemover")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 PhysicsRemover
{
internal static class BoneMenuIntegration
{
private static Page? _mainPage;
private static Page? _laserPage;
private static Page? _modesPage;
private static Page? _statusPage;
private static FunctionElement? _modeSelectorBtn;
private static FunctionElement? _scopeSelectorBtn;
private static FunctionElement? _aimSourceBtn;
private static FunctionElement? _vrShootBtn;
private static FunctionElement? _statusInfoBtn;
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void SetupMenu()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: 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)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Unknown result type (might be due to invalid IL or missing references)
//IL_037b: Unknown result type (might be due to invalid IL or missing references)
//IL_03be: Unknown result type (might be due to invalid IL or missing references)
//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0426: Unknown result type (might be due to invalid IL or missing references)
//IL_046d: Unknown result type (might be due to invalid IL or missing references)
//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
//IL_0516: Unknown result type (might be due to invalid IL or missing references)
//IL_054a: Unknown result type (might be due to invalid IL or missing references)
_mainPage = Page.Root.CreatePage("Physics Remover", new Color(0.2f, 0.85f, 1f), 0, true);
_mainPage.CreateBool("Mod Enabled", Color.white, ModConfig.Enabled.Value, (Action<bool>)delegate(bool val)
{
ModConfig.Enabled.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
if (!val)
{
LaserVisualizer.Hide();
}
RefreshUI();
});
_mainPage.CreateBool("Laser Pointer", Color.cyan, ModConfig.LaserAimingEnabled.Value, (Action<bool>)delegate(bool val)
{
ModConfig.LaserAimingEnabled.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
if (!val)
{
LaserVisualizer.Hide();
}
NotificationHelper.Show("Laser Pointer", val ? "Laser: ENABLED" : "Laser: DISABLED", (NotificationType)0);
RefreshUI();
});
_mainPage.CreateBool("Show Notifications", Color.yellow, ModConfig.ShowNotifications.Value, (Action<bool>)delegate(bool val)
{
ModConfig.ShowNotifications.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
if (val)
{
NotificationHelper.ShowSuccess("Notifications", "Notifications: ENABLED");
}
RefreshUI();
});
_mainPage.CreateFunction("❄\ufe0f Freeze / Unfreeze at Aim", new Color(0.15f, 0.9f, 1f), (Action)delegate
{
PhysicsManager.RemovePhysicsAtAim();
RefreshUI();
});
_mainPage.CreateFunction("↩\ufe0f Undo Last", Color.yellow, (Action)delegate
{
PhysicsManager.UndoLast();
RefreshUI();
});
_mainPage.CreateFunction("\ud83d\udd25 Unfreeze All in Scene", new Color(1f, 0.5f, 0.2f), (Action)delegate
{
PhysicsManager.RestoreAllInScene();
RefreshUI();
});
_modesPage = _mainPage.CreatePage("Modes & Settings", new Color(0.3f, 0.7f, 1f), 0, true);
_modeSelectorBtn = _modesPage.CreateFunction("Mode: " + GetModeDisplayName(ModConfig.RemoverMode.Value), Color.white, (Action)delegate
{
CycleRemoverMode();
RefreshUI();
});
_scopeSelectorBtn = _modesPage.CreateFunction("Scope: " + GetScopeDisplayName(ModConfig.TargetScope.Value), Color.yellow, (Action)delegate
{
CycleTargetScope();
RefreshUI();
});
_modesPage.CreateBool("Notifications", Color.white, ModConfig.ShowNotifications.Value, (Action<bool>)delegate(bool val)
{
ModConfig.ShowNotifications.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
RefreshUI();
});
_modesPage.CreateBool("Protect Floor Under Player", Color.green, ModConfig.ProtectFloorUnderPlayer.Value, (Action<bool>)delegate(bool val)
{
ModConfig.ProtectFloorUnderPlayer.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.ShowSuccess("Floor Guard", val ? "Floor protection: ON" : "Floor protection: OFF");
RefreshUI();
});
_modesPage.CreateFunction("\ud83d\udca5 Freeze in 3m Radius", new Color(0.3f, 0.9f, 1f), (Action)delegate
{
PhysicsManager.FreezeInRadius(3f);
RefreshUI();
});
_modesPage.CreateFunction("\ud83d\udca5 Freeze in 5m Radius", new Color(0.2f, 0.8f, 1f), (Action)delegate
{
PhysicsManager.FreezeInRadius(5f);
RefreshUI();
});
_modesPage.CreateFunction("\ud83d\udca5 Freeze in 10m Radius", new Color(0.1f, 0.7f, 1f), (Action)delegate
{
PhysicsManager.FreezeInRadius(10f);
RefreshUI();
});
_laserPage = _mainPage.CreatePage("Laser & Controls", new Color(0.3f, 0.8f, 1f), 0, true);
_laserPage.CreateBool("Laser Beam & Dot", Color.cyan, ModConfig.LaserAimingEnabled.Value, (Action<bool>)delegate(bool val)
{
ModConfig.LaserAimingEnabled.Value = val;
ModConfig.PrefCategory.SaveToFile(false);
if (!val)
{
LaserVisualizer.Hide();
}
RefreshUI();
});
_aimSourceBtn = _laserPage.CreateFunction("Aim From: " + ModConfig.AimSource.Value, Color.white, (Action)delegate
{
CycleAimSource();
RefreshUI();
});
_vrShootBtn = _laserPage.CreateFunction("VR Shoot Button: " + ModConfig.VRShootTrigger.Value, Color.yellow, (Action)delegate
{
CycleVRShootButton();
RefreshUI();
});
_statusPage = _mainPage.CreatePage("Status & Info", new Color(0.7f, 0.7f, 0.7f), 0, true);
_statusInfoBtn = _statusPage.CreateFunction("Status: Ready", Color.white, (Action)delegate
{
RefreshUI();
});
_statusPage.CreateFunction("PhysicsRemover v1.1.0 by dimastv", new Color(0.4f, 0.8f, 1f), (Action)delegate
{
});
_statusPage.CreateFunction("Freezes physics with 100% SOLID collisions", Color.gray, (Action)delegate
{
});
RefreshUI();
}
private static string GetModeDisplayName(string mode)
{
return mode switch
{
"FreezeInPlace" => "Freeze Solid (Collisions Active) [Default]",
"DisablePhysics" => "Ghost / No-Collision (Pass-Through)",
"DestroyObject" => "Destroy Object (Permanent Delete)",
_ => mode,
};
}
private static string GetScopeDisplayName(string scope)
{
if (!(scope == "ObjectAndChildren"))
{
if (scope == "SingleColliderOnly")
{
return "Single Hit Collider Only";
}
return scope;
}
return "Object & Children (Whole Structure)";
}
private static void CycleRemoverMode()
{
string value = ModConfig.RemoverMode.Value;
string text = ((value == "FreezeInPlace") ? "DisablePhysics" : ((!(value == "DisablePhysics")) ? "FreezeInPlace" : "DestroyObject"));
string text2 = text;
ModConfig.RemoverMode.Value = text2;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.Show("Physics Remover", "Mode: " + GetModeDisplayName(text2), (NotificationType)0);
}
private static void CycleTargetScope()
{
string text = ((ModConfig.TargetScope.Value == "ObjectAndChildren") ? "SingleColliderOnly" : "ObjectAndChildren");
ModConfig.TargetScope.Value = text;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.Show("Physics Remover", "Scope: " + GetScopeDisplayName(text), (NotificationType)0);
}
private static void CycleAimSource()
{
string value = ModConfig.AimSource.Value;
string text = ((value == "RightHand") ? "LeftHand" : ((!(value == "LeftHand")) ? "RightHand" : "HeadCrosshair"));
string text2 = text;
ModConfig.AimSource.Value = text2;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.Show("Physics Remover", "Aim Source: " + text2, (NotificationType)0);
}
private static void CycleVRShootButton()
{
string text = ModConfig.VRShootTrigger.Value switch
{
"Disabled" => "RightSecondary",
"RightSecondary" => "RightPrimary",
"RightPrimary" => "LeftSecondary",
"LeftSecondary" => "LeftPrimary",
"LeftPrimary" => "LeftStickClick",
"LeftStickClick" => "Disabled",
_ => "Disabled",
};
ModConfig.VRShootTrigger.Value = text;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.Show("Physics Remover", "VR Shoot: " + text, (NotificationType)0);
}
public static void RefreshUI()
{
if (_modeSelectorBtn != null)
{
((Element)_modeSelectorBtn).ElementName = "Mode: " + GetModeDisplayName(ModConfig.RemoverMode.Value);
}
if (_scopeSelectorBtn != null)
{
((Element)_scopeSelectorBtn).ElementName = "Scope: " + GetScopeDisplayName(ModConfig.TargetScope.Value);
}
if (_aimSourceBtn != null)
{
((Element)_aimSourceBtn).ElementName = "Aim From: " + ModConfig.AimSource.Value;
}
if (_vrShootBtn != null)
{
((Element)_vrShootBtn).ElementName = "VR Shoot Button: " + ModConfig.VRShootTrigger.Value;
}
if (_statusInfoBtn != null)
{
((Element)_statusInfoBtn).ElementName = $"Active Frozen: {PhysicsManager.ActiveFrozenCount} | Total: {PhysicsManager.TotalModifiedCount}";
}
}
}
public class PhysicsRemoverFusionModule : Module
{
public override string Name => "PhysicsRemover";
public override string Author => "dimastv";
public override Version Version => new Version(1, 2, 0);
public override ConsoleColor Color => ConsoleColor.Cyan;
}
public class PhysicsFreezeData : INetSerializable
{
public bool IsFreeze = true;
public ushort EntityId;
public string TargetPath = string.Empty;
public float PosX;
public float PosY;
public float PosZ;
public float RotX;
public float RotY;
public float RotZ;
public float RotW = 1f;
public void Serialize(INetSerializer serializer)
{
serializer.SerializeValue(ref IsFreeze);
serializer.SerializeValue(ref EntityId);
serializer.SerializeValue(ref TargetPath);
serializer.SerializeValue(ref PosX);
serializer.SerializeValue(ref PosY);
serializer.SerializeValue(ref PosZ);
serializer.SerializeValue(ref RotX);
serializer.SerializeValue(ref RotY);
serializer.SerializeValue(ref RotZ);
serializer.SerializeValue(ref RotW);
}
public int? GetSize()
{
return null;
}
}
public class PhysicsFreezeMessage : ModuleMessageHandler
{
protected override void OnHandleMessage(ReceivedMessage received)
{
try
{
PhysicsFreezeData physicsFreezeData = ((ReceivedMessage)(ref received)).ReadData<PhysicsFreezeData>();
if (physicsFreezeData != null)
{
PhysicsFusionIntegration.ApplyRemoteFreeze(physicsFreezeData);
}
}
catch (Exception ex)
{
MelonLogger.Warning("[PhysicsRemover] Failed to handle received network freeze: " + ex.Message);
}
}
}
public static class PhysicsFusionIntegration
{
public static bool IsFusionAvailable { get; private set; }
public static void Initialize()
{
try
{
if (IsLabFusionPresent())
{
ModuleManager.RegisterModule<PhysicsRemoverFusionModule>();
ModuleMessageManager.RegisterHandler<PhysicsFreezeMessage>();
IsFusionAvailable = true;
MelonLogger.Msg("[PhysicsRemover] LabFusion Network Module registered! Full multiplayer sync ACTIVE.");
}
}
catch (Exception ex)
{
IsFusionAvailable = false;
MelonLogger.Warning("[PhysicsRemover] LabFusion registration skipped: " + ex.Message);
}
}
private static bool IsLabFusionPresent()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
if (assemblies[i].GetName().Name == "LabFusion")
{
return true;
}
}
return false;
}
public static void BroadcastFreeze(GameObject targetGo, bool isFreeze)
{
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: 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_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
if (!IsFusionAvailable || !NetworkInfo.HasServer || (Object)(object)targetGo == (Object)null)
{
return;
}
try
{
ushort num = 0;
Dictionary<ushort, NetworkEntity> dictionary = NetworkEntityManager.IDManager?.RegisteredEntities?.IDEntityLookup;
if (dictionary != null)
{
foreach (KeyValuePair<ushort, NetworkEntity> item in dictionary)
{
NetworkEntity value = item.Value;
if (value != null && !value.IsDestroyed)
{
NetworkProp extender = value.GetExtender<NetworkProp>();
if (extender != null && (Object)(object)extender.MarrowEntity != (Object)null && (Object)(object)((Component)extender.MarrowEntity).gameObject == (Object)(object)targetGo)
{
num = item.Key;
break;
}
}
}
}
Vector3 position = targetGo.transform.position;
Quaternion rotation = targetGo.transform.rotation;
string transformPath = GetTransformPath(targetGo.transform);
MessageRelay.RelayModule<PhysicsFreezeMessage, PhysicsFreezeData>(new PhysicsFreezeData
{
IsFreeze = isFreeze,
EntityId = num,
TargetPath = transformPath,
PosX = position.x,
PosY = position.y,
PosZ = position.z,
RotX = rotation.x,
RotY = rotation.y,
RotZ = rotation.z,
RotW = rotation.w
}, CommonMessageRoutes.ReliableToOtherClients);
MelonLogger.Msg($"[PhysicsRemover] Network sync sent: '{(isFreeze ? "FREEZE" : "UNFREEZE")}' on '{((Object)targetGo).name}' (EntityId: {num})");
}
catch (Exception ex)
{
MelonLogger.Warning("[PhysicsRemover] Failed to broadcast network freeze: " + ex.Message);
}
}
public static void ApplyRemoteFreeze(PhysicsFreezeData data)
{
//IL_0161: 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_01b2: 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)
try
{
GameObject val = null;
if (data.EntityId > 0)
{
Dictionary<ushort, NetworkEntity> dictionary = NetworkEntityManager.IDManager?.RegisteredEntities?.IDEntityLookup;
if (dictionary != null && dictionary.TryGetValue(data.EntityId, out var value) && value != null)
{
NetworkProp extender = value.GetExtender<NetworkProp>();
if (extender != null && (Object)(object)extender.MarrowEntity != (Object)null)
{
val = ((Component)extender.MarrowEntity).gameObject;
}
}
}
if ((Object)(object)val == (Object)null && !string.IsNullOrEmpty(data.TargetPath))
{
val = FindByTransformPath(data.TargetPath);
}
if ((Object)(object)val == (Object)null)
{
MelonLogger.Warning($"[PhysicsRemover] Remote target not found: {data.TargetPath} (ID: {data.EntityId})");
return;
}
Il2CppArrayBase<Rigidbody> componentsInChildren = val.GetComponentsInChildren<Rigidbody>(true);
foreach (Collider componentsInChild in val.GetComponentsInChildren<Collider>(true))
{
if ((Object)(object)componentsInChild != (Object)null && !PhysicsManager.IsPartOfPlayer(componentsInChild))
{
componentsInChild.enabled = true;
}
}
if (data.IsFreeze)
{
val.transform.position = new Vector3(data.PosX, data.PosY, data.PosZ);
val.transform.rotation = new Quaternion(data.RotX, data.RotY, data.RotZ, data.RotW);
foreach (Rigidbody item in componentsInChildren)
{
if (!((Object)(object)item == (Object)null))
{
item.velocity = Vector3.zero;
item.angularVelocity = Vector3.zero;
item.isKinematic = true;
item.useGravity = false;
item.constraints = (RigidbodyConstraints)126;
item.detectCollisions = true;
item.Sleep();
}
}
MelonLogger.Msg("[PhysicsRemover] [FUSION SYNC] Applied remote FREEZE on '" + ((Object)val).name + "'");
return;
}
foreach (Rigidbody item2 in componentsInChildren)
{
if (!((Object)(object)item2 == (Object)null))
{
item2.isKinematic = false;
item2.useGravity = true;
item2.constraints = (RigidbodyConstraints)0;
item2.WakeUp();
}
}
MelonLogger.Msg("[PhysicsRemover] [FUSION SYNC] Applied remote UNFREEZE on '" + ((Object)val).name + "'");
}
catch (Exception ex)
{
MelonLogger.Warning("[PhysicsRemover] Error applying remote freeze: " + ex.Message);
}
}
public static string GetTransformPath(Transform transform)
{
if ((Object)(object)transform == (Object)null)
{
return string.Empty;
}
string text = ((Object)transform).name;
Transform parent = transform.parent;
while ((Object)(object)parent != (Object)null)
{
text = ((Object)parent).name + "/" + text;
parent = parent.parent;
}
return text;
}
public static GameObject? FindByTransformPath(string path)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(path))
{
return null;
}
GameObject val = GameObject.Find(path);
if ((Object)(object)val != (Object)null)
{
return val;
}
string[] array = path.Split('/');
if (array.Length == 0)
{
return null;
}
Scene activeScene = SceneManager.GetActiveScene();
foreach (GameObject item in (Il2CppArrayBase<GameObject>)(object)((Scene)(ref activeScene)).GetRootGameObjects())
{
if (!(((Object)item).name == array[0]))
{
continue;
}
Transform val2 = item.transform;
bool flag = true;
for (int i = 1; i < array.Length; i++)
{
Transform val3 = val2.Find(array[i]);
if ((Object)(object)val3 == (Object)null)
{
flag = false;
break;
}
val2 = val3;
}
if (flag)
{
return ((Component)val2).gameObject;
}
}
return null;
}
}
public static class LaserVisualizer
{
private static GameObject? _laserRoot;
private static LineRenderer? _lineRenderer;
private static GameObject? _targetDot;
private static MeshRenderer? _dotRenderer;
private static Material? _dotMaterial;
public static void Initialize()
{
EnsureObjects();
}
private static void EnsureObjects()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_006c: 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_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_laserRoot == (Object)null)
{
_laserRoot = new GameObject("PhysicsRemover_LaserRoot");
Object.DontDestroyOnLoad((Object)(object)_laserRoot);
_lineRenderer = _laserRoot.AddComponent<LineRenderer>();
_lineRenderer.startWidth = 0.005f;
_lineRenderer.endWidth = 0.002f;
_lineRenderer.positionCount = 2;
_lineRenderer.useWorldSpace = true;
Material material = ShaderHelper.CreateMaterial(Color.cyan, isEmissive: true, 2.5f);
((Renderer)_lineRenderer).material = material;
_targetDot = GameObject.CreatePrimitive((PrimitiveType)0);
((Object)_targetDot).name = "PhysicsRemover_TargetDot";
_targetDot.transform.SetParent(_laserRoot.transform);
Collider component = _targetDot.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
_dotRenderer = _targetDot.GetComponent<MeshRenderer>();
_dotMaterial = ShaderHelper.CreateMaterial(Color.cyan, isEmissive: true, 3f);
((Renderer)_dotRenderer).material = _dotMaterial;
_targetDot.transform.localScale = Vector3.one * 0.045f;
_targetDot.SetActive(false);
((Renderer)_lineRenderer).enabled = false;
}
}
public static void UpdateLaser(Vector3 origin, Vector3 direction, bool hasHit, RaycastHit hit, bool isFloorProtected, bool isMapObject, bool isAlreadyFrozen)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: 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)
//IL_0114: 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_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
if (!ModConfig.LaserAimingEnabled.Value || !ModConfig.Enabled.Value)
{
Hide();
return;
}
EnsureObjects();
if ((Object)(object)_lineRenderer == (Object)null || (Object)(object)_targetDot == (Object)null)
{
return;
}
Color red = default(Color);
if (!hasHit)
{
((Color)(ref red))..ctor(0.2f, 0.5f, 1f, 0.4f);
}
else if (isFloorProtected)
{
red = Color.red;
}
else if (isAlreadyFrozen)
{
((Color)(ref red))..ctor(1f, 0.85f, 0.2f);
}
else if (isMapObject)
{
((Color)(ref red))..ctor(0.35f, 0.7f, 1f);
}
else
{
((Color)(ref red))..ctor(0.15f, 0.95f, 1f);
}
((Renderer)_lineRenderer).enabled = true;
_lineRenderer.startColor = red;
_lineRenderer.endColor = red;
_lineRenderer.SetPosition(0, origin);
if (hasHit)
{
_lineRenderer.SetPosition(1, ((RaycastHit)(ref hit)).point);
_targetDot.SetActive(true);
_targetDot.transform.position = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.02f;
if ((Object)(object)_dotMaterial != (Object)null)
{
if (_dotMaterial.HasProperty("_Color"))
{
_dotMaterial.SetColor("_Color", red);
}
if (_dotMaterial.HasProperty("_BaseColor"))
{
_dotMaterial.SetColor("_BaseColor", red);
}
if (_dotMaterial.HasProperty("_EmissionColor"))
{
_dotMaterial.SetColor("_EmissionColor", red * 3f);
}
}
}
else
{
_lineRenderer.SetPosition(1, origin + direction * 35f);
_targetDot.SetActive(false);
}
}
public static void Hide()
{
if ((Object)(object)_lineRenderer != (Object)null)
{
((Renderer)_lineRenderer).enabled = false;
}
if ((Object)(object)_targetDot != (Object)null)
{
_targetDot.SetActive(false);
}
}
public static void Destroy()
{
if ((Object)(object)_laserRoot != (Object)null)
{
Object.Destroy((Object)(object)_laserRoot);
_laserRoot = null;
_lineRenderer = null;
_targetDot = null;
_dotRenderer = null;
_dotMaterial = null;
}
}
}
public class MainMod : MelonMod
{
private static bool _boneLibLoaded;
public override void OnInitializeMelon()
{
ModConfig.Initialize();
MelonLogger.Msg("PhysicsRemover initialized successfully!");
}
public override void OnLateInitializeMelon()
{
TryInitBoneLib();
LaserVisualizer.Initialize();
PhysicsFusionIntegration.Initialize();
}
private void TryInitBoneLib()
{
try
{
_boneLibLoaded = true;
BoneMenuIntegration.SetupMenu();
MelonLogger.Msg("[PhysicsRemover] BoneLib BoneMenu initialized!");
}
catch (Exception ex)
{
_boneLibLoaded = false;
MelonLogger.Warning("[PhysicsRemover] BoneLib menu setup skipped or failed: " + ex.Message);
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
PhysicsManager.ClearSceneHistory();
LaserVisualizer.Hide();
if (_boneLibLoaded)
{
BoneMenuIntegration.RefreshUI();
}
}
public override void OnUpdate()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (!ModConfig.Enabled.Value)
{
LaserVisualizer.Hide();
return;
}
if (PhysicsManager.GetAimRay(out var origin, out var direction))
{
RaycastHit hit;
bool isMapObject;
bool isFloorProtected;
bool isAlreadyFrozen;
bool hasHit = PhysicsManager.PerformRaycast(out hit, out isMapObject, out isFloorProtected, out isAlreadyFrozen);
LaserVisualizer.UpdateLaser(origin, direction, hasHit, hit, isFloorProtected, isMapObject, isAlreadyFrozen);
}
else
{
LaserVisualizer.Hide();
}
CheckVRControllerInput();
CheckKeyboardInput();
}
private static void CheckVRControllerInput()
{
string value = ModConfig.VRShootTrigger.Value;
if (string.Equals(value, "Disabled", StringComparison.OrdinalIgnoreCase))
{
return;
}
try
{
BaseController leftController = Player.LeftController;
BaseController rightController = Player.RightController;
bool flag = false;
switch (value)
{
case "RightSecondary":
if ((Object)(object)rightController != (Object)null && rightController.GetSecondaryInteractionButtonDown())
{
flag = true;
}
break;
case "RightPrimary":
if ((Object)(object)rightController != (Object)null && rightController.GetPrimaryInteractionButtonDown())
{
flag = true;
}
break;
case "LeftSecondary":
if ((Object)(object)leftController != (Object)null && leftController.GetSecondaryInteractionButtonDown())
{
flag = true;
}
break;
case "LeftPrimary":
if ((Object)(object)leftController != (Object)null && leftController.GetPrimaryInteractionButtonDown())
{
flag = true;
}
break;
case "LeftStickClick":
if ((Object)(object)leftController != (Object)null && leftController.GetThumbStickDown())
{
flag = true;
}
break;
}
if (flag)
{
PhysicsManager.RemovePhysicsAtAim();
BoneMenuIntegration.RefreshUI();
}
}
catch
{
}
}
private static void CheckKeyboardInput()
{
try
{
if (Input.GetKeyDown((KeyCode)112) || Input.GetKeyDown((KeyCode)102))
{
PhysicsManager.RemovePhysicsAtAim();
BoneMenuIntegration.RefreshUI();
}
else if (Input.GetKeyDown((KeyCode)117))
{
PhysicsManager.UndoLast();
BoneMenuIntegration.RefreshUI();
}
else if (Input.GetKeyDown((KeyCode)108))
{
ModConfig.LaserAimingEnabled.Value = !ModConfig.LaserAimingEnabled.Value;
ModConfig.PrefCategory.SaveToFile(false);
NotificationHelper.Show("Laser Aim", ModConfig.LaserAimingEnabled.Value ? "Laser: ON" : "Laser: OFF", (NotificationType)0);
BoneMenuIntegration.RefreshUI();
}
else if (Input.GetKeyDown((KeyCode)110))
{
ModConfig.ShowNotifications.Value = !ModConfig.ShowNotifications.Value;
ModConfig.PrefCategory.SaveToFile(false);
if (ModConfig.ShowNotifications.Value)
{
NotificationHelper.ShowSuccess("Notifications", "Notifications: ENABLED");
}
BoneMenuIntegration.RefreshUI();
}
}
catch
{
}
}
public override void OnApplicationQuit()
{
LaserVisualizer.Destroy();
}
}
public static class ModConfig
{
public static MelonPreferences_Category PrefCategory { get; private set; }
public static MelonPreferences_Entry<bool> Enabled { get; private set; }
public static MelonPreferences_Entry<bool> ShowNotifications { get; private set; }
public static MelonPreferences_Entry<bool> LaserAimingEnabled { get; private set; }
public static MelonPreferences_Entry<string> AimSource { get; private set; }
public static MelonPreferences_Entry<string> VRShootTrigger { get; private set; }
public static MelonPreferences_Entry<bool> ProtectFloorUnderPlayer { get; private set; }
public static MelonPreferences_Entry<string> RemoverMode { get; private set; }
public static MelonPreferences_Entry<string> TargetScope { get; private set; }
public static MelonPreferences_Entry<float> MaxRaycastDistance { get; private set; }
public static void Initialize()
{
PrefCategory = MelonPreferences.CreateCategory("PhysicsRemover", "Physics Remover Settings");
Enabled = PrefCategory.CreateEntry<bool>("Enabled", true, "Mod Enabled", "Master toggle for the Physics Remover mod.", false, false, (ValueValidator)null, (string)null);
ShowNotifications = PrefCategory.CreateEntry<bool>("ShowNotifications", true, "Show Notifications", "Show BoneLib UI pop-up notifications when physics is frozen or restored.", false, false, (ValueValidator)null, (string)null);
LaserAimingEnabled = PrefCategory.CreateEntry<bool>("LaserAimingEnabled", false, "Laser Aiming Beam", "Draw a visible laser beam and targeting reticle showing the targeted object.", false, false, (ValueValidator)null, (string)null);
AimSource = PrefCategory.CreateEntry<string>("AimSource", "RightHand", "Aim Source", "Origin of the aiming raycast (RightHand, LeftHand, HeadCrosshair).", false, false, (ValueValidator)null, (string)null);
VRShootTrigger = PrefCategory.CreateEntry<string>("VRShootTrigger", "Disabled", "VR Quick Button", "Controller button to freeze/unfreeze target (Disabled, RightSecondary [B], RightPrimary [A], LeftSecondary [Y], LeftPrimary [X]).", false, false, (ValueValidator)null, (string)null);
ProtectFloorUnderPlayer = PrefCategory.CreateEntry<bool>("ProtectFloorUnderPlayer", true, "Protect Floor Under Player", "Prevents accidentally modifying the floor directly underneath the player's feet.", false, false, (ValueValidator)null, (string)null);
RemoverMode = PrefCategory.CreateEntry<string>("RemoverMode", "FreezeInPlace", "Removal Mode", "FreezeInPlace (Freeze solid, keep collisions), DisablePhysics (Ghost / No-Collision), DestroyObject (Permanent Delete).", false, false, (ValueValidator)null, (string)null);
TargetScope = PrefCategory.CreateEntry<string>("TargetScope", "ObjectAndChildren", "Target Scope", "ObjectAndChildren (Freezes all rigidbodies on target GameObject & children), SingleColliderOnly (Only the specific collider/RB hit).", false, false, (ValueValidator)null, (string)null);
MaxRaycastDistance = PrefCategory.CreateEntry<float>("MaxRaycastDistance", 75f, "Max Distance", "Maximum raycast distance for targeting objects.", false, false, (ValueValidator)null, (string)null);
if (VRShootTrigger.Value == "RightStickClick")
{
VRShootTrigger.Value = "Disabled";
}
if (RemoverMode.Value == "DisablePhysics")
{
RemoverMode.Value = "FreezeInPlace";
}
PrefCategory.SaveToFile(false);
}
}
public static class NotificationHelper
{
public static void Show(string title, string message, NotificationType type = (NotificationType)0, float duration = 2.5f)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
if (!ModConfig.ShowNotifications.Value)
{
return;
}
try
{
Notifier.Send(new Notification
{
Title = new NotificationText(title, new Color(1f, 0.35f, 0.35f), false),
Message = new NotificationText(message, Color.white, false),
Type = type,
PopupLength = duration,
ShowTitleOnPopup = true
});
}
catch (Exception ex)
{
MelonLogger.Warning("[PhysicsRemover] Could not send BoneLib notification: " + ex.Message);
}
}
public static void ShowSuccess(string title, string message, float duration = 2.5f)
{
Show(title, message, (NotificationType)3, duration);
}
public static void ShowWarning(string title, string message, float duration = 3f)
{
Show(title, message, (NotificationType)1, duration);
}
public static void ShowError(string title, string message, float duration = 3.5f)
{
Show(title, message, (NotificationType)2, duration);
}
}
public class DisabledRigidbodyRecord
{
public Rigidbody Rigidbody { get; set; }
public bool WasKinematic { get; set; }
public bool WasDetectCollisions { get; set; }
public bool WasUseGravity { get; set; }
public RigidbodyConstraints PreviousConstraints { get; set; }
public Vector3 PreviousVelocity { get; set; }
public Vector3 PreviousAngularVelocity { get; set; }
}
public class PhysicsActionRecord
{
public string ObjectName { get; set; } = string.Empty;
public bool IsMapObject { get; set; }
public string ActionType { get; set; } = "Freeze";
public GameObject? TargetGameObject { get; set; }
public List<DisabledRigidbodyRecord> Rigidbodies { get; set; } = new List<DisabledRigidbodyRecord>();
}
public static class PhysicsManager
{
private static readonly Dictionary<int, PhysicsActionRecord> _activeFrozenObjects = new Dictionary<int, PhysicsActionRecord>();
private static readonly Stack<PhysicsActionRecord> _undoStack = new Stack<PhysicsActionRecord>();
private static readonly List<PhysicsActionRecord> _allModifiedRecords = new List<PhysicsActionRecord>();
public static int UndoCount => _undoStack.Count;
public static int ActiveFrozenCount => _activeFrozenObjects.Count;
public static int TotalModifiedCount => _allModifiedRecords.Count;
public static void ClearSceneHistory()
{
_activeFrozenObjects.Clear();
_undoStack.Clear();
_allModifiedRecords.Clear();
}
public static bool IsObjectFrozen(GameObject go)
{
if ((Object)(object)go == (Object)null)
{
return false;
}
return _activeFrozenObjects.ContainsKey(((Object)go).GetInstanceID());
}
public static int GetSafeRaycastMask()
{
int num = LayerMask.NameToLayer("Player");
int num2 = LayerMask.NameToLayer("NoCollide");
int num3 = -1;
if (num != -1)
{
num3 &= ~(1 << num);
}
if (num2 != -1)
{
num3 &= ~(1 << num2);
}
return num3;
}
public static bool GetAimRay(out Vector3 origin, out Vector3 direction)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: 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)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: 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_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_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
origin = Vector3.zero;
direction = Vector3.forward;
string value = ModConfig.AimSource.Value;
try
{
if (value == "RightHand")
{
Hand rightHand = Player.RightHand;
if ((Object)(object)rightHand != (Object)null && (Object)(object)((Component)rightHand).transform != (Object)null)
{
origin = ((Component)rightHand).transform.position;
direction = ((Component)rightHand).transform.forward;
return true;
}
}
else if (value == "LeftHand")
{
Hand leftHand = Player.LeftHand;
if ((Object)(object)leftHand != (Object)null && (Object)(object)((Component)leftHand).transform != (Object)null)
{
origin = ((Component)leftHand).transform.position;
direction = ((Component)leftHand).transform.forward;
return true;
}
}
}
catch
{
}
try
{
Transform head = Player.Head;
if ((Object)(object)head != (Object)null)
{
origin = head.position;
direction = head.forward;
return true;
}
}
catch
{
}
return false;
}
public static bool IsStaticMapObject(Collider col)
{
if ((Object)(object)col == (Object)null)
{
return false;
}
if ((Object)(object)((Component)col).GetComponentInParent<Rigidbody>() != (Object)null)
{
return false;
}
if ((Object)(object)((Component)col).GetComponentInParent<InteractableHost>() != (Object)null)
{
return false;
}
return true;
}
public static bool IsPartOfPlayer(Collider col)
{
if ((Object)(object)col == (Object)null)
{
return false;
}
try
{
RigManager rigManager = Player.RigManager;
if ((Object)(object)rigManager != (Object)null && ((Component)col).transform.IsChildOf(((Component)rigManager).transform))
{
return true;
}
}
catch
{
}
return false;
}
public static bool IsFloorDirectlyUnderPlayer(RaycastHit hit)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
try
{
RigManager rigManager = Player.RigManager;
Vector3 val = (((Object)(object)rigManager != (Object)null) ? ((Component)rigManager).transform.position : (((Object)(object)Player.Head != (Object)null) ? (Player.Head.position - Vector3.up * 1.5f) : Vector3.zero));
if (((RaycastHit)(ref hit)).normal.y > 0.55f && Vector2.Distance(new Vector2(((RaycastHit)(ref hit)).point.x, ((RaycastHit)(ref hit)).point.z), new Vector2(val.x, val.z)) < 1.1f && ((RaycastHit)(ref hit)).point.y <= val.y + 0.6f)
{
return true;
}
}
catch
{
}
return false;
}
public static bool PerformRaycast(out RaycastHit hit, out bool isMapObject, out bool isFloorProtected, out bool isAlreadyFrozen)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
hit = default(RaycastHit);
isMapObject = false;
isFloorProtected = false;
isAlreadyFrozen = false;
if (!GetAimRay(out var origin, out var direction))
{
return false;
}
int safeRaycastMask = GetSafeRaycastMask();
float value = ModConfig.MaxRaycastDistance.Value;
if (Physics.Raycast(origin + direction * 0.15f, direction, ref hit, value, safeRaycastMask, (QueryTriggerInteraction)1))
{
if (IsPartOfPlayer(((RaycastHit)(ref hit)).collider))
{
return false;
}
isMapObject = IsStaticMapObject(((RaycastHit)(ref hit)).collider);
isFloorProtected = ModConfig.ProtectFloorUnderPlayer.Value && IsFloorDirectlyUnderPlayer(hit);
Rigidbody componentInParent = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Rigidbody>();
GameObject go = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)((RaycastHit)(ref hit)).collider).gameObject);
isAlreadyFrozen = IsObjectFrozen(go);
return true;
}
return false;
}
public static bool RemovePhysicsAtAim()
{
if (!PerformRaycast(out var hit, out var isMapObject, out var isFloorProtected, out var _))
{
NotificationHelper.ShowWarning("Physics Remover", "No target object in sight!");
return false;
}
if (isFloorProtected)
{
NotificationHelper.ShowWarning("Floor Protected", "Cannot modify floor directly under player!\n(Disable 'Protect Floor' in BoneMenu if intended)");
return false;
}
return ProcessTarget(((RaycastHit)(ref hit)).collider, isMapObject);
}
public static bool ProcessTarget(Collider hitCollider, bool isMapObject)
{
//IL_031d: Unknown result type (might be due to invalid IL or missing references)
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
//IL_0337: Unknown result type (might be due to invalid IL or missing references)
//IL_0348: Unknown result type (might be due to invalid IL or missing references)
//IL_0354: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)hitCollider == (Object)null)
{
return false;
}
string text = ModConfig.RemoverMode.Value;
if (text != "DestroyObject")
{
text = "FreezeInPlace";
}
InteractableHost componentInParent = ((Component)hitCollider).GetComponentInParent<InteractableHost>();
Rigidbody componentInParent2 = ((Component)hitCollider).GetComponentInParent<Rigidbody>();
GameObject val = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((!((Object)(object)componentInParent2 != (Object)null)) ? ((Component)hitCollider).gameObject : ((Component)componentInParent2).gameObject));
string name = ((Object)val).name;
int instanceID = ((Object)val).GetInstanceID();
if (text == "DestroyObject")
{
try
{
Object.Destroy((Object)(object)val);
NotificationHelper.ShowSuccess("Destroyed Object", $"[DELETED] {name}\n({(isMapObject ? "MAP OBJECT" : "PROP")})");
MelonLogger.Msg("[PhysicsRemover] Destroyed GameObject: '" + name + "'");
return true;
}
catch (Exception ex)
{
NotificationHelper.ShowError("Error", "Failed to destroy object: " + ex.Message);
return false;
}
}
if (_activeFrozenObjects.TryGetValue(instanceID, out PhysicsActionRecord value))
{
RestoreRecord(value);
_activeFrozenObjects.Remove(instanceID);
PhysicsFusionIntegration.BroadcastFreeze(val, isFreeze: false);
NotificationHelper.ShowSuccess("Unfrozen", "\ud83d\udd25 Unfrozen: " + name + "\n(Physics motion restored)");
MelonLogger.Msg("[PhysicsRemover] Unfrozen: '" + name + "'");
return true;
}
List<Rigidbody> list = new List<Rigidbody>();
foreach (Rigidbody componentsInChild in val.GetComponentsInChildren<Rigidbody>(true))
{
if ((Object)(object)componentsInChild != (Object)null && !list.Contains(componentsInChild))
{
list.Add(componentsInChild);
}
}
if ((Object)(object)componentInParent2 != (Object)null && !list.Contains(componentInParent2))
{
list.Add(componentInParent2);
}
foreach (Collider componentsInChild2 in val.GetComponentsInChildren<Collider>(true))
{
if ((Object)(object)componentsInChild2 != (Object)null && !IsPartOfPlayer(componentsInChild2))
{
componentsInChild2.enabled = true;
}
}
if (list.Count == 0)
{
NotificationHelper.ShowSuccess("Already Static & Solid", "❄\ufe0f '" + name + "' is static map geometry!\n(Collision is SOLID)");
MelonLogger.Msg("[PhysicsRemover] '" + name + "' is already static map geometry with solid collision.");
return true;
}
PhysicsActionRecord physicsActionRecord = new PhysicsActionRecord
{
ObjectName = name,
IsMapObject = isMapObject,
ActionType = "Freeze",
TargetGameObject = val
};
foreach (Rigidbody item in list)
{
if (!((Object)(object)item == (Object)null))
{
physicsActionRecord.Rigidbodies.Add(new DisabledRigidbodyRecord
{
Rigidbody = item,
WasKinematic = item.isKinematic,
WasDetectCollisions = item.detectCollisions,
WasUseGravity = item.useGravity,
PreviousConstraints = item.constraints,
PreviousVelocity = item.velocity,
PreviousAngularVelocity = item.angularVelocity
});
item.velocity = Vector3.zero;
item.angularVelocity = Vector3.zero;
item.isKinematic = true;
item.useGravity = false;
item.constraints = (RigidbodyConstraints)126;
item.detectCollisions = true;
item.Sleep();
}
}
try
{
Hand rightHand = Player.RightHand;
if ((Object)(object)rightHand != (Object)null)
{
rightHand.DetachJoint(false, (Grip)null);
}
Hand leftHand = Player.LeftHand;
if ((Object)(object)leftHand != (Object)null)
{
leftHand.DetachJoint(false, (Grip)null);
}
}
catch
{
}
_activeFrozenObjects[instanceID] = physicsActionRecord;
_undoStack.Push(physicsActionRecord);
_allModifiedRecords.Add(physicsActionRecord);
PhysicsFusionIntegration.BroadcastFreeze(val, isFreeze: true);
NotificationHelper.ShowSuccess("Frozen in Place", "❄\ufe0f Frozen: " + name + "\n(Collisions remain 100% SOLID!)");
MelonLogger.Msg($"[PhysicsRemover] Frozen in place: '{name}' ({list.Count} RBs frozen, collisions solid)");
return true;
}
public static bool UndoLast()
{
if (_undoStack.Count == 0)
{
NotificationHelper.ShowWarning("Undo", "No actions to undo!");
return false;
}
PhysicsActionRecord physicsActionRecord = _undoStack.Pop();
if ((Object)(object)physicsActionRecord.TargetGameObject != (Object)null)
{
_activeFrozenObjects.Remove(((Object)physicsActionRecord.TargetGameObject).GetInstanceID());
}
RestoreRecord(physicsActionRecord);
if ((Object)(object)physicsActionRecord.TargetGameObject != (Object)null)
{
PhysicsFusionIntegration.BroadcastFreeze(physicsActionRecord.TargetGameObject, isFreeze: false);
}
NotificationHelper.ShowSuccess("Unfrozen", "\ud83d\udd25 Unfrozen: " + physicsActionRecord.ObjectName);
MelonLogger.Msg("[PhysicsRemover] Undone freeze on '" + physicsActionRecord.ObjectName + "'");
return true;
}
public static void RestoreAllInScene()
{
if (_allModifiedRecords.Count == 0 && _activeFrozenObjects.Count == 0)
{
NotificationHelper.ShowWarning("Unfreeze All", "No frozen objects in current scene.");
return;
}
int num = 0;
for (int num2 = _allModifiedRecords.Count - 1; num2 >= 0; num2--)
{
PhysicsActionRecord physicsActionRecord = _allModifiedRecords[num2];
if (RestoreRecord(physicsActionRecord))
{
if ((Object)(object)physicsActionRecord.TargetGameObject != (Object)null)
{
PhysicsFusionIntegration.BroadcastFreeze(physicsActionRecord.TargetGameObject, isFreeze: false);
}
num++;
}
}
_activeFrozenObjects.Clear();
_undoStack.Clear();
_allModifiedRecords.Clear();
NotificationHelper.ShowSuccess("Unfrozen All", $"\ud83d\udd25 Unfrozen all {num} objects in scene!");
MelonLogger.Msg($"[PhysicsRemover] Unfrozen all {num} objects.");
}
private static bool RestoreRecord(PhysicsActionRecord action)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
if (action == null)
{
return false;
}
bool result = false;
foreach (DisabledRigidbodyRecord rigidbody in action.Rigidbodies)
{
if ((Object)(object)rigidbody.Rigidbody != (Object)null)
{
rigidbody.Rigidbody.isKinematic = rigidbody.WasKinematic;
rigidbody.Rigidbody.detectCollisions = rigidbody.WasDetectCollisions;
rigidbody.Rigidbody.useGravity = rigidbody.WasUseGravity;
rigidbody.Rigidbody.constraints = rigidbody.PreviousConstraints;
rigidbody.Rigidbody.velocity = rigidbody.PreviousVelocity;
rigidbody.Rigidbody.angularVelocity = rigidbody.PreviousAngularVelocity;
rigidbody.Rigidbody.WakeUp();
result = true;
}
}
return result;
}
public static void FreezeInRadius(float radius)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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_00e5: 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_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_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_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
RigManager rigManager = Player.RigManager;
Vector3 val = (((Object)(object)rigManager != (Object)null) ? ((Component)rigManager).transform.position : (((Object)(object)Player.Head != (Object)null) ? Player.Head.position : Vector3.zero));
int safeRaycastMask = GetSafeRaycastMask();
Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(val, radius, safeRaycastMask, (QueryTriggerInteraction)1));
if (array == null || array.Length == 0)
{
NotificationHelper.ShowWarning("Radius Freeze", $"No objects found within {radius:0}m!");
return;
}
int num = 0;
HashSet<GameObject> hashSet = new HashSet<GameObject>();
Collider[] array2 = array;
foreach (Collider val2 in array2)
{
if ((Object)(object)val2 == (Object)null || IsPartOfPlayer(val2))
{
continue;
}
if (ModConfig.ProtectFloorUnderPlayer.Value && Vector2.Distance(new Vector2(((Component)val2).transform.position.x, ((Component)val2).transform.position.z), new Vector2(val.x, val.z)) < 1f)
{
Bounds bounds = val2.bounds;
if (((Bounds)(ref bounds)).max.y <= val.y + 0.3f)
{
continue;
}
}
Rigidbody componentInParent = ((Component)val2).GetComponentInParent<Rigidbody>();
GameObject item = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)val2).gameObject);
if (hashSet.Add(item))
{
bool isMapObject = IsStaticMapObject(val2);
if (ProcessTarget(val2, isMapObject))
{
num++;
}
}
}
NotificationHelper.ShowSuccess("Radius Freeze", $"❄\ufe0f Frozen {num} objects within {radius:0}m!");
MelonLogger.Msg($"[PhysicsRemover] Radius freeze: {num} objects frozen within {radius}m");
}
}
public static class ShaderHelper
{
private static Shader? _cachedShader;
public static Shader GetSafeShader()
{
if ((Object)(object)_cachedShader != (Object)null)
{
return _cachedShader;
}
string[] array = new string[8] { "SLZ/Marrow/Universal/Lit", "SLZ/Marrow/Lit", "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "Universal Render Pipeline/Unlit", "URP/Lit", "Sprites/Default", "Unlit/Color" };
for (int i = 0; i < array.Length; i++)
{
Shader val = Shader.Find(array[i]);
if ((Object)(object)val != (Object)null)
{
_cachedShader = val;
return _cachedShader;
}
}
try
{
Il2CppArrayBase<MeshRenderer> val2 = Object.FindObjectsOfType<MeshRenderer>();
if (val2 != null)
{
foreach (MeshRenderer item in val2)
{
if ((Object)(object)item != (Object)null && (Object)(object)((Renderer)item).sharedMaterial != (Object)null && (Object)(object)((Renderer)item).sharedMaterial.shader != (Object)null)
{
string name = ((Object)((Renderer)item).sharedMaterial.shader).name;
if (!string.IsNullOrEmpty(name) && !name.Contains("Fluorescence") && !name.Contains("Transparent") && !name.Contains("Decal") && !name.Contains("Internal") && !name.Contains("Error"))
{
_cachedShader = ((Renderer)item).sharedMaterial.shader;
return _cachedShader;
}
}
}
}
}
catch
{
}
_cachedShader = Shader.Find("Hidden/Internal-Colored") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Sprites/Default");
return _cachedShader;
}
public static Material CreateMaterial(Color color, bool isEmissive = false, float emissionIntensity = 2f)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
Material val = new Material(GetSafeShader());
if (val.HasProperty("_Color"))
{
val.SetColor("_Color", color);
}
if (val.HasProperty("_BaseColor"))
{
val.SetColor("_BaseColor", color);
}
if (isEmissive)
{
Color val2 = color * emissionIntensity;
val.EnableKeyword("_EMISSION");
if (val.HasProperty("_EmissionColor"))
{
val.SetColor("_EmissionColor", val2);
}
}
return val;
}
}
}