Decompiled source of LootCompanion v1.1.0

LootCompanion.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using FistVR;
using H3MP;
using H3MP.Scripts;
using Microsoft.CodeAnalysis;
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: AssemblyCompany("Packer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Script Library for Loot Companions")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+fa23c3c27f6b5d967147722319997801bb9ffa9c")]
[assembly: AssemblyProduct("LootCompanion")]
[assembly: AssemblyTitle("LootCompanion")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace Packer
{
	[BepInProcess("h3vr.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("LootCompanion", "LootCompanion", "1.1.0+fa23c3c27f6b5d967147722319997801bb9ffa9c")]
	public class LootCompanionPlugin : BaseUnityPlugin
	{
		public static bool h3mpEnabled;

		public const string Id = "LootCompanion";

		internal static ManualLogSource Logger { get; private set; }

		public static string Name => "LootCompanion";

		public static string Version => "1.1.0+fa23c3c27f6b5d967147722319997801bb9ffa9c";

		private void Awake()
		{
			h3mpEnabled = Chainloader.PluginInfos.ContainsKey("VIP.TommySoucy.H3MP");
		}
	}
}
namespace Packer.LootCompanion
{
	[RequireComponent(typeof(NavMeshAgent), typeof(Rigidbody), typeof(FVRPhysicalObject))]
	public class LootCompanion : MonoBehaviour
	{
		public enum CompanionStateEnum
		{
			PhysicsIdle,
			Follower,
			GettingItem
		}

		private FVRPhysicalObject selfObject;

		private Rigidbody rb;

		private NavMeshAgent agent;

		public CompanionStateEnum state = CompanionStateEnum.PhysicsIdle;

		private bool hasNavMesh = false;

		[Header("Brain")]
		[Tooltip("How often the companion will decide to do something")]
		public float updateTick = 1f;

		private float nextUpdate = 0f;

		[Header("Distance from player")]
		public float playerDistanceMin = 3f;

		public float playerDistanceMax = 30f;

		private float heldTimer = 3f;

		[Header("Item Pickup")]
		public Transform scanVolume;

		public LayerMask ScanningLM;

		[Tooltip("Time from last item pickup until the companion will try to look for an item")]
		public float pickupCooldown = 10f;

		[Tooltip("How far the companion can reach an item from its root position, default 3 units")]
		public float pickupDistance = 3f;

		private float pickupTimeNext = 0f;

		private Collider[] colbuffer = (Collider[])(object)new Collider[150];

		private FVRPhysicalObject targetObject;

		[Header("Slots")]
		public FVRQuickBeltSlot mouthSlot;

		public FVRQuickBeltSlot[] backpack;

		public string[] specialPickup;

		[Header("Animation")]
		public GameObject[] taskObjects;

		public Animator animator;

		public string animIdle = "Idle";

		public string animWait = "Wait";

		public string animRun = "Run";

		private bool isHeld = false;

		private float happy = 0f;

		[Header("Meme")]
		[Tooltip("Ignores if objects are being held or in a quick slot")]
		public bool trollMode = false;

		[Tooltip("If holding a grenade, pull the pin in player range")]
		public bool pullPin = false;

		private string currentAnimation = "";

		[Header("Network")]
		private bool pickupChecked = false;

		private Transform ownerTransform;

		private float exhauted = 0f;

		private float lookWeight = 0f;

		private LayerMask handMask;

		private bool petted = false;

		private void Start()
		{
			//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)
			handMask = LayerMask.op_Implicit(LayerMask.NameToLayer("HandTrigger"));
			colbuffer = (Collider[])(object)new Collider[200];
			if ((Object)(object)agent == (Object)null)
			{
				agent = ((Component)this).GetComponent<NavMeshAgent>();
			}
			if ((Object)(object)rb == (Object)null)
			{
				rb = ((Component)this).GetComponent<Rigidbody>();
			}
			if ((Object)(object)selfObject == (Object)null)
			{
				selfObject = ((Component)this).GetComponent<FVRPhysicalObject>();
			}
			((Behaviour)agent).enabled = false;
			rb.isKinematic = false;
			SetAnimation(animIdle);
		}

		private void Update()
		{
			//IL_0061: 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_0104: 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_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: 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_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			SetTaskObject();
			UpdateHappy();
			isHeld = Held();
			UpdateAgentState();
			UpdatePhysicsState();
			if (isHeld || !hasNavMesh)
			{
				if (LootCompanionPlugin.h3mpEnabled && !pickupChecked)
				{
					ownerTransform = LootNetwork.GetClosestPlayer(((Component)this).transform.position);
					pickupChecked = true;
				}
				return;
			}
			if (pickupChecked)
			{
				pickupChecked = false;
			}
			if (!(Time.time >= nextUpdate))
			{
				return;
			}
			nextUpdate = Time.time + Random.Range(0f, updateTick);
			if (state == CompanionStateEnum.GettingItem)
			{
				if ((Object)(object)targetObject != (Object)null)
				{
					bool flag = true;
					if (((Component)targetObject).transform.position != agent.destination)
					{
						flag = SetDestination(((Component)targetObject).transform.position);
					}
					if (!flag || ((FVRInteractiveObject)targetObject).IsHeld)
					{
						SetAnimation(animRun);
						SetState(CompanionStateEnum.Follower);
						targetObject = null;
						return;
					}
					float num = Distance2D(((Component)this).transform.position, ((Component)targetObject).transform.position);
					if (num <= pickupDistance)
					{
						PickupItem();
						pickupTimeNext = Time.time + pickupCooldown;
						if ((Object)(object)targetObject != (Object)null)
						{
							SetDestination(((Component)targetObject).transform.position);
						}
					}
					if (state == CompanionStateEnum.GettingItem)
					{
						return;
					}
				}
				else if ((Object)(object)targetObject == (Object)null || ((FVRInteractiveObject)targetObject).IsHeld)
				{
					SetAnimation(animRun);
					SetState(CompanionStateEnum.Follower);
				}
			}
			if ((Object)(object)mouthSlot != (Object)null && (Object)(object)mouthSlot.HeldObject == (Object)null && (Object)(object)targetObject == (Object)null && state == CompanionStateEnum.Follower && Time.time >= pickupTimeNext)
			{
				ScanForItem();
				if ((Object)(object)targetObject != (Object)null)
				{
					SetDestination(((Component)targetObject).transform.position);
				}
				if (state == CompanionStateEnum.GettingItem)
				{
					return;
				}
			}
			float num2 = Distance2D(((Component)this).transform.position, GetOwnerPosition());
			if (num2 >= playerDistanceMax)
			{
				Teleport(GetOwnerPosition());
				SetAnimation(animRun);
				SetState(CompanionStateEnum.Follower);
			}
			else if (num2 >= playerDistanceMin)
			{
				SetDestination(GetOwnerPosition());
				SetAnimation(animRun);
				SetState(CompanionStateEnum.Follower);
			}
			else
			{
				SetAnimation(animWait);
			}
		}

		private bool Held()
		{
			if (((FVRInteractiveObject)selfObject).IsHeld || (Object)(object)selfObject.QuickbeltSlot != (Object)null)
			{
				heldTimer = 3f;
				if (state != 0)
				{
					SetState(CompanionStateEnum.PhysicsIdle);
					((Behaviour)agent).enabled = false;
				}
			}
			else
			{
				if (!(heldTimer > 0f))
				{
					if (!hasNavMesh && HasNavMesh())
					{
						hasNavMesh = true;
					}
					return false;
				}
				heldTimer -= Time.deltaTime;
			}
			return true;
		}

		private Vector3 GetOwnerPosition()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (LootCompanionPlugin.h3mpEnabled && (Object)(object)ownerTransform == (Object)null)
			{
				ownerTransform = LootNetwork.GetClosestPlayer(((Component)this).transform.position);
			}
			if ((Object)(object)ownerTransform == (Object)null)
			{
				ownerTransform = ((Component)GM.CurrentPlayerBody).transform;
			}
			return ownerTransform.position + ownerTransform.forward;
		}

		private bool SetDestination(Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, pickupDistance, -1))
			{
				agent.SetDestination(position);
				return true;
			}
			return false;
		}

		private void ScanForItem()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapBoxNonAlloc(scanVolume.position, scanVolume.localScale * 0.5f, colbuffer, ((Component)this).transform.rotation, LayerMask.op_Implicit(ScanningLM), (QueryTriggerInteraction)2);
			FVRPhysicalObject val = null;
			for (int i = 0; i < num; i++)
			{
				if (!((Object)(object)colbuffer[i].attachedRigidbody != (Object)null))
				{
					continue;
				}
				val = ((Component)colbuffer[i].attachedRigidbody).gameObject.GetComponent<FVRPhysicalObject>();
				if (!((Object)(object)val != (Object)null))
				{
					continue;
				}
				bool flag = true;
				for (int j = 0; j < specialPickup.Length; j++)
				{
					if ((Object)(object)val.ObjectWrapper != (Object)null && val.ObjectWrapper.ItemID == specialPickup[j])
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					val = null;
				}
			}
			NavMeshHit val2 = default(NavMeshHit);
			for (int k = 0; k < num; k++)
			{
				if (!((Object)(object)colbuffer[k].attachedRigidbody != (Object)null))
				{
					continue;
				}
				if ((Object)(object)val != (Object)null)
				{
					val = (FVRPhysicalObject)(object)((Component)colbuffer[k].attachedRigidbody).gameObject.GetComponent<FVRFireArm>();
				}
				FVRFireArmMagazine component = ((Component)colbuffer[k].attachedRigidbody).gameObject.GetComponent<FVRFireArmMagazine>();
				Speedloader component2 = ((Component)colbuffer[k].attachedRigidbody).gameObject.GetComponent<Speedloader>();
				if ((Object)(object)val == (Object)null && (Object)(object)component != (Object)null && component.HasARound())
				{
					val = (FVRPhysicalObject)(object)component;
				}
				if ((Object)(object)val == (Object)null && (Object)(object)component2 != (Object)null)
				{
					val = (FVRPhysicalObject)(object)component2;
				}
				if ((Object)(object)val == (Object)null)
				{
					val = (FVRPhysicalObject)(object)((Component)colbuffer[k].attachedRigidbody).gameObject.GetComponent<FVRGrenade>();
				}
				if ((Object)(object)val != (Object)null)
				{
					if (!NavMesh.SamplePosition(((Component)val).transform.position, ref val2, pickupDistance, -1))
					{
						continue;
					}
					if (trollMode && (Object)(object)val.QuickbeltSlot != (Object)(object)mouthSlot)
					{
						targetObject = val;
						SetState(CompanionStateEnum.GettingItem);
						return;
					}
					if (!((FVRInteractiveObject)val).IsHeld && (Object)(object)val.QuickbeltSlot == (Object)null)
					{
						targetObject = val;
						SetState(CompanionStateEnum.GettingItem);
						return;
					}
				}
				val = null;
			}
			pickupTimeNext = Time.time + pickupCooldown;
		}

		private void PickupItem()
		{
			if ((Object)(object)targetObject == (Object)null || ((FVRInteractiveObject)targetObject).IsHeld)
			{
				targetObject = null;
				return;
			}
			if ((Object)(object)mouthSlot != (Object)null)
			{
				targetObject.SetQuickBeltSlot(mouthSlot);
			}
			targetObject = null;
			SetAnimation(animRun);
			SetState(CompanionStateEnum.Follower);
		}

		private void Teleport(Vector3 position)
		{
			//IL_0001: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, 50f, -1))
			{
				agent.Warp(((NavMeshHit)(ref val)).position);
				SetDestination(((NavMeshHit)(ref val)).position);
			}
		}

		private float Distance2D(Vector3 a, Vector3 b)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0027: 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)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(a.x, a.z);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(b.x, b.z);
			return Vector2.Distance(val, val2);
		}

		private bool HasNavMesh()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(((Component)this).transform.position, ref val, 100f, -1))
			{
				return true;
			}
			return false;
		}

		public void SetTaskObject()
		{
			for (int i = 0; i < taskObjects.Length; i++)
			{
				if ((Object)(object)taskObjects[i] != (Object)null)
				{
					taskObjects[i].SetActive(false);
				}
			}
			if ((int)state < taskObjects.Length && (Object)(object)taskObjects[(int)state] != (Object)null)
			{
				taskObjects[(int)state].SetActive(true);
			}
		}

		private void UpdateAgentState()
		{
			if (!hasNavMesh || isHeld || ((FVRInteractiveObject)selfObject).IsHeld)
			{
				if (((Behaviour)agent).enabled)
				{
					((Behaviour)agent).enabled = false;
				}
			}
			else if (!((Behaviour)agent).enabled)
			{
				((Behaviour)agent).enabled = true;
			}
		}

		private void UpdatePhysicsState()
		{
			if (!((Behaviour)agent).enabled || !hasNavMesh || state == CompanionStateEnum.PhysicsIdle)
			{
				if (rb.isKinematic)
				{
					rb.isKinematic = false;
				}
			}
			else if (!rb.isKinematic)
			{
				rb.isKinematic = true;
			}
		}

		private void SetState(CompanionStateEnum newState)
		{
			state = newState;
			switch (state)
			{
			case CompanionStateEnum.PhysicsIdle:
				SetAnimation(animIdle);
				break;
			case CompanionStateEnum.GettingItem:
				SetAnimation(animRun);
				break;
			}
		}

		private void OnAnimatorIK()
		{
			//IL_0061: 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)
			if (!Object.op_Implicit((Object)(object)animator))
			{
				return;
			}
			lookWeight = 1f;
			animator.SetLookAtWeight(lookWeight, 0f, 1f, 1f, 1f);
			switch (state)
			{
			case CompanionStateEnum.PhysicsIdle:
			case CompanionStateEnum.Follower:
				animator.SetLookAtPosition(GetOwnerPosition());
				break;
			case CompanionStateEnum.GettingItem:
				if ((Object)(object)targetObject != (Object)null)
				{
					animator.SetLookAtPosition(((Component)targetObject).transform.position);
				}
				break;
			}
		}

		private void UpdateHappy()
		{
			if (petted && happy < 1f)
			{
				happy = Mathf.Clamp01(happy += Time.deltaTime * 0.1f);
			}
			else if (happy > 0f)
			{
				happy = Mathf.Clamp01(happy -= Time.deltaTime * 0.02f);
			}
			animator.SetLayerWeight(1, happy);
		}

		private void UpdateExhuation()
		{
			if (currentAnimation == animRun && exhauted < 1f)
			{
				exhauted = Mathf.Clamp01(exhauted += Time.deltaTime * 0.1f);
			}
			else if (exhauted > 0f)
			{
				exhauted = Mathf.Clamp01(exhauted -= Time.deltaTime * 0.02f);
			}
			animator.SetLayerWeight(2, exhauted);
		}

		private void SetAnimation(string newAnimation)
		{
			if (!((Object)(object)animator == (Object)null) && !(newAnimation == "") && !(newAnimation == currentAnimation))
			{
				animator.Play(newAnimation);
				currentAnimation = newAnimation;
			}
		}

		private void OnDrawGizmos()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)scanVolume != (Object)null)
			{
				Gizmos.color = Color.yellow;
				Gizmos.DrawWireCube(scanVolume.position, scanVolume.localScale * 0.5f);
			}
		}

		private void OnTriggerEnter(Collider collider)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)collider).gameObject.layer == LayerMask.op_Implicit(handMask))
			{
				petted = true;
			}
		}

		private void OnTriggerExit(Collider collider)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (((Component)collider).gameObject.layer == LayerMask.op_Implicit(handMask))
			{
				petted = false;
			}
		}

		private void Awake()
		{
		}

		private void OnDestroy()
		{
		}
	}
	public class LootNetwork
	{
		public static Transform GetClosestPlayer(Vector3 position)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			float num = 99f;
			foreach (KeyValuePair<int, PlayerManager> player in GameManager.players)
			{
				float num2 = Vector3.Distance(position, ((Component)player.Value.playerBody).transform.position);
				if ((Object)(object)val == (Object)null || num2 <= num)
				{
					val = ((Component)player.Value.playerBody).transform;
					num = num2;
				}
			}
			return val;
		}
	}
}