Decompiled source of SmartNPCOverhaul v1.0.0

SmartNPCOverhaul.dll

Decompiled 14 hours ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using SmartNPCOverhaul;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(SmartNPCOverhaulMod), "Smart NPC Overhaul", "1.0.0", "Community", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("SmartNPCOverhaul")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SmartNPCOverhaul")]
[assembly: AssemblyTitle("SmartNPCOverhaul")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SmartNPCOverhaul;

public sealed class SmartNPCOverhaulMod : MelonMod
{
	private const float BrainScanInterval = 0.5f;

	private const float DodgeCooldown = 1.1f;

	private const float DodgeHandSpeed = 3.5f;

	private const float DodgeDistance = 2f;

	private const float WeaponPickupDistance = 1.8f;

	private readonly Dictionary<int, float> _nextDodgeTime = new Dictionary<int, float>();

	private float _nextBrainScan;

	private Vector3 _lastLeftHandPosition;

	private Vector3 _lastRightHandPosition;

	private Vector3 _leftHandVelocity;

	private Vector3 _rightHandVelocity;

	private bool _haveHandPositions;

	public override void OnInitializeMelon()
	{
		((MelonBase)this).LoggerInstance.Msg("Loaded. BoneLib is required for player-hand tracking.");
	}

	public override void OnUpdate()
	{
		UpdatePlayerHandVelocities();
		if (!(Time.unscaledTime < _nextBrainScan))
		{
			_nextBrainScan = Time.unscaledTime + 0.5f;
			TuneNPCs();
		}
	}

	private void UpdatePlayerHandVelocities()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_006e: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		Hand leftHand = Player.LeftHand;
		Hand rightHand = Player.RightHand;
		if ((Object)(object)leftHand == (Object)null || (Object)(object)rightHand == (Object)null)
		{
			_haveHandPositions = false;
			return;
		}
		Vector3 position = ((Component)leftHand).transform.position;
		Vector3 position2 = ((Component)rightHand).transform.position;
		float deltaTime = Time.deltaTime;
		if (_haveHandPositions && deltaTime > 0f)
		{
			_leftHandVelocity = (position - _lastLeftHandPosition) / deltaTime;
			_rightHandVelocity = (position2 - _lastRightHandPosition) / deltaTime;
		}
		_lastLeftHandPosition = position;
		_lastRightHandPosition = position2;
		_haveHandPositions = true;
	}

	private void TuneNPCs()
	{
		Il2CppArrayBase<AIBrain> val = Object.FindObjectsOfType<AIBrain>();
		Il2CppArrayBase<Grip> grips = Object.FindObjectsOfType<Grip>();
		for (int i = 0; i < val.Length; i++)
		{
			AIBrain val2 = val[i];
			if (!((Object)(object)val2 == (Object)null) && !val2.isDead && !((Object)(object)val2.behaviour == (Object)null))
			{
				BehaviourBaseNav behaviour = val2.behaviour;
				ImproveCombatBehaviour(behaviour);
				ImproveRagdoll(val2);
				TryDodge(val2, behaviour);
				TryPickUpNearbyGun(val2, grips);
			}
		}
	}

	private static void ImproveCombatBehaviour(BehaviourBaseNav behaviour)
	{
		behaviour.roamSpeed = Mathf.Max(behaviour.roamSpeed, 1.5f);
		behaviour.roamAngSpeed = Mathf.Max(behaviour.roamAngSpeed, 150f);
		behaviour.agroedSpeed = Mathf.Max(behaviour.agroedSpeed, 3.2f);
		behaviour.agroedAngSpeed = Mathf.Max(behaviour.agroedAngSpeed, 210f);
		behaviour.aiTickFreq = Mathf.Min(behaviour.aiTickFreq, 0.15f);
		behaviour.enableThrowAttack = true;
		behaviour.throwMinRange = Mathf.Min(behaviour.throwMinRange, 1.5f);
		behaviour.throwMaxRange = Mathf.Max(behaviour.throwMaxRange, 8f);
		behaviour.throwVelocity = Mathf.Max(behaviour.throwVelocity, 5f);
		if (behaviour.throwCooldown > 0.05f)
		{
			behaviour.throwCooldown = Mathf.Min(behaviour.throwCooldown, 2.5f);
		}
		behaviour.gunRange = Mathf.Max(behaviour.gunRange, 16f);
		behaviour.accuracy = Mathf.Max(behaviour.accuracy, 0.65f);
		behaviour.burstSize = Mathf.Max(behaviour.burstSize, 2);
		NavMeshAgent navAgent = behaviour._navAgent;
		if ((Object)(object)navAgent != (Object)null)
		{
			navAgent.acceleration = Mathf.Max(navAgent.acceleration, 8f);
			navAgent.angularSpeed = Mathf.Max(navAgent.angularSpeed, 210f);
		}
	}

	private static void ImproveRagdoll(AIBrain brain)
	{
		BehaviourPuppet componentInChildren = ((Component)brain).GetComponentInChildren<BehaviourPuppet>();
		if (!((Object)(object)componentInChildren == (Object)null))
		{
			componentInChildren.unpinnedMuscleWeightMlp = Mathf.Min(componentInChildren.unpinnedMuscleWeightMlp, 0.75f);
			componentInChildren.regainPinSpeed = Mathf.Min(componentInChildren.regainPinSpeed, 2f);
			componentInChildren.getUpRegainPinSpeedMlp = Mathf.Min(componentInChildren.getUpRegainPinSpeedMlp, 0.8f);
		}
	}

	private void TryDodge(AIBrain brain, BehaviourBaseNav behaviour)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		NavMeshAgent navAgent = behaviour._navAgent;
		if (!((Object)(object)navAgent == (Object)null) && navAgent.isOnNavMesh && !(Time.unscaledTime < GetDodgeReadyTime(brain)) && (TryDodgeFromHand(brain, navAgent, Player.LeftHand, _leftHandVelocity) || TryDodgeFromHand(brain, navAgent, Player.RightHand, _rightHandVelocity)))
		{
			_nextDodgeTime[((Object)brain).GetInstanceID()] = Time.unscaledTime + 1.1f;
		}
	}

	private float GetDodgeReadyTime(AIBrain brain)
	{
		float value;
		return _nextDodgeTime.TryGetValue(((Object)brain).GetInstanceID(), out value) ? value : 0f;
	}

	private static bool TryDodgeFromHand(AIBrain brain, NavMeshAgent agent, Hand hand, Vector3 handVelocity)
	{
		//IL_002f: 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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hand == (Object)null || ((Vector3)(ref handVelocity)).sqrMagnitude < 12.25f)
		{
			return false;
		}
		Vector3 val = ((Component)brain).transform.position - ((Component)hand).transform.position;
		if (((Vector3)(ref val)).sqrMagnitude > 4f)
		{
			return false;
		}
		Vector3 val2 = Vector3.ProjectOnPlane(handVelocity, Vector3.up);
		Vector3 normalized = ((Vector3)(ref val2)).normalized;
		Vector3 val3 = Vector3.Cross(Vector3.up, normalized);
		if ((((Object)brain).GetInstanceID() & 1) != 0)
		{
			val3 = -val3;
		}
		Vector3 val4 = ((Component)brain).transform.position + val3 * 1.4f;
		NavMeshHit val5 = default(NavMeshHit);
		if (!NavMesh.SamplePosition(val4, ref val5, 1.5f, agent.areaMask))
		{
			return false;
		}
		return agent.SetDestination(((NavMeshHit)(ref val5)).position);
	}

	private static void TryPickUpNearbyGun(AIBrain brain, Il2CppArrayBase<Grip> grips)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		Il2CppArrayBase<Hand> componentsInChildren = ((Component)brain).GetComponentsInChildren<Hand>(true);
		if (componentsInChildren.Length == 0)
		{
			return;
		}
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Hand val = componentsInChildren[i];
			if ((Object)(object)val == (Object)null || val.HasAttachedObject())
			{
				continue;
			}
			Grip val2 = null;
			float num = 3.2399998f;
			for (int j = 0; j < grips.Length; j++)
			{
				Grip val3 = grips[j];
				if (!((Object)(object)val3 == (Object)null) && !val3.HasAttachedHands() && !((Object)(object)((Component)val3).GetComponentInParent<Gun>() == (Object)null))
				{
					Vector3 val4 = ((Component)val3).transform.position - ((Component)val).transform.position;
					float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						val2 = val3;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.OnGrabConfirm(val, true);
				break;
			}
		}
	}
}