using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using GravControl;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using UnityEngine;
using UnityEngine.XR;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "GravControl", "1.1.0", "You", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyCompany("GravControl")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GravControl")]
[assembly: AssemblyTitle("GravControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace GravControl;
public class Main : MelonMod
{
private class Npc
{
public AIBrain Brain;
public PuppetMaster Puppet;
public List<Rigidbody> Bodies = new List<Rigidbody>();
public bool Ragdolled;
public float OrigPin;
public float OrigMuscle;
public bool OrigBrainEnabled;
}
private const float DefaultGravity = 1f;
private const bool DefaultRagdolls = false;
private const bool DefaultLauncher = false;
private const float DefaultVelocityMult = 1f;
private static float _npcGravity = 1f;
private static bool _ragdolls = false;
private static bool _launcher = false;
private static float _velocityMult = 1f;
private FloatElement _gravElement;
private BoolElement _ragdollElement;
private BoolElement _launcherElement;
private FloatElement _velElement;
private readonly Dictionary<int, Npc> _npcs = new Dictionary<int, Npc>();
private float _refreshTimer;
private const float RefreshInterval = 0.75f;
private const float BaseLaunchSpeed = 12f;
private const float ShotCooldown = 0.25f;
private const float ShotRange = 100f;
private float _lastShot;
private bool _triggerWasDown;
public override void OnInitializeMelon()
{
SetupMenu();
((MelonBase)this).LoggerInstance.Msg("GravControl loaded.");
}
private void SetupMenu()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_008a: 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_0108: Unknown result type (might be due to invalid IL or missing references)
Page val = Page.Root.CreatePage("GravControl", Color.cyan, 0, true);
_gravElement = val.CreateFloat("Global NPC Gravity", Color.white, 1f, 0.25f, -3f, 5f, (Action<float>)delegate(float v)
{
_npcGravity = v;
});
_ragdollElement = val.CreateBool("Ragdolls", Color.yellow, false, (Action<bool>)delegate(bool v)
{
SetRagdolls(v);
});
_launcherElement = val.CreateBool("NPC Launcher (Hand Gun)", Color.green, false, (Action<bool>)delegate(bool v)
{
_launcher = v;
});
_velElement = val.CreateFloat("NPC Velocity Multiplier", Color.white, 1f, 0.5f, 0.5f, 10f, (Action<float>)delegate(float v)
{
_velocityMult = v;
});
val.CreateFunction("Reset", Color.red, (Action)ResetAll);
}
private void ResetAll()
{
_npcGravity = 1f;
_velocityMult = 1f;
_launcher = false;
SetRagdolls(on: false);
_gravElement.Value = 1f;
_velElement.Value = 1f;
_launcherElement.Value = false;
_ragdollElement.Value = false;
((MelonBase)this).LoggerInstance.Msg("GravControl settings reset to defaults.");
}
public override void OnSceneWasInitialized(int buildIndex, string sceneName)
{
_npcs.Clear();
_refreshTimer = 0f;
}
public override void OnFixedUpdate()
{
//IL_0056: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
if (!_ragdolls && !_launcher && Mathf.Approximately(_npcGravity, 1f))
{
return;
}
_refreshTimer -= Time.fixedDeltaTime;
if (_refreshTimer <= 0f)
{
_refreshTimer = 0.75f;
RefreshNpcs();
}
Vector3 val = Physics.gravity * (_npcGravity - 1f);
bool flag = !Mathf.Approximately(_npcGravity, 1f);
foreach (Npc value in _npcs.Values)
{
if ((Object)(object)value.Brain == (Object)null)
{
continue;
}
if (_ragdolls)
{
Ragdoll(value, on: true);
}
if (!flag)
{
continue;
}
foreach (Rigidbody body in value.Bodies)
{
if ((Object)(object)body != (Object)null && !body.isKinematic)
{
body.AddForce(val, (ForceMode)5);
}
}
}
}
public override void OnUpdate()
{
//IL_0010: 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)
if (!_launcher)
{
_triggerWasDown = false;
return;
}
InputDevice deviceAtXRNode = InputDevices.GetDeviceAtXRNode((XRNode)5);
bool flag = false;
if (((InputDevice)(ref deviceAtXRNode)).isValid)
{
((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.triggerButton, ref flag);
}
bool num = flag && !_triggerWasDown;
_triggerWasDown = flag;
if (num && Time.time - _lastShot >= 0.25f)
{
_lastShot = Time.time;
FireAtNpc();
}
}
private void FireAtNpc()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//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_00df: Unknown result type (might be due to invalid IL or missing references)
Hand rightHand = Player.RightHand;
if ((Object)(object)rightHand == (Object)null)
{
return;
}
Transform transform = ((Component)rightHand).transform;
RaycastHit[] array = Il2CppArrayBase<RaycastHit>.op_Implicit((Il2CppArrayBase<RaycastHit>)(object)Physics.RaycastAll(transform.position, transform.forward, 100f));
AIBrain val = null;
float num = float.MaxValue;
RaycastHit[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
RaycastHit val2 = array2[i];
AIBrain componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<AIBrain>();
if ((Object)(object)componentInParent != (Object)null && ((RaycastHit)(ref val2)).distance < num)
{
num = ((RaycastHit)(ref val2)).distance;
val = componentInParent;
}
}
if ((Object)(object)val == (Object)null)
{
return;
}
Vector3 velocity = Vector3.up * (12f * _velocityMult);
foreach (Rigidbody componentsInChild in ((Component)((Component)val).transform.root).GetComponentsInChildren<Rigidbody>())
{
if ((Object)(object)componentsInChild != (Object)null && !componentsInChild.isKinematic)
{
componentsInChild.velocity = velocity;
}
}
}
private void SetRagdolls(bool on)
{
_ragdolls = on;
foreach (Npc value in _npcs.Values)
{
if ((Object)(object)value.Brain != (Object)null)
{
Ragdoll(value, on);
}
}
}
private static void Ragdoll(Npc npc, bool on)
{
if (on && !npc.Ragdolled)
{
if ((Object)(object)npc.Puppet != (Object)null)
{
npc.OrigMuscle = npc.Puppet.muscleWeight;
}
npc.OrigBrainEnabled = ((Behaviour)npc.Brain).enabled;
npc.Ragdolled = true;
}
else if (!on && npc.Ragdolled)
{
if ((Object)(object)npc.Puppet != (Object)null)
{
npc.Puppet.muscleWeight = npc.OrigMuscle;
}
((Behaviour)npc.Brain).enabled = npc.OrigBrainEnabled;
npc.Ragdolled = false;
return;
}
if (on && npc.Ragdolled)
{
if ((Object)(object)npc.Puppet != (Object)null)
{
npc.Puppet.muscleWeight = 0f;
}
((Behaviour)npc.Brain).enabled = false;
}
}
private void RefreshNpcs()
{
HashSet<int> hashSet = new HashSet<int>();
foreach (AIBrain item in Object.FindObjectsOfType<AIBrain>())
{
if ((Object)(object)item == (Object)null)
{
continue;
}
int instanceID = ((Object)item).GetInstanceID();
hashSet.Add(instanceID);
Transform root = ((Component)item).transform.root;
if (!_npcs.TryGetValue(instanceID, out var value))
{
value = new Npc
{
Brain = item,
Puppet = ((Component)root).GetComponentInChildren<PuppetMaster>()
};
_npcs[instanceID] = value;
}
value.Bodies.Clear();
foreach (Rigidbody componentsInChild in ((Component)root).GetComponentsInChildren<Rigidbody>())
{
if ((Object)(object)componentsInChild != (Object)null)
{
value.Bodies.Add(componentsInChild);
}
}
}
List<int> list = new List<int>();
foreach (int key in _npcs.Keys)
{
if (!hashSet.Contains(key))
{
list.Add(key);
}
}
foreach (int item2 in list)
{
_npcs.Remove(item2);
}
}
}