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.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+a39d7694ac5eecb28ea3582a1549fe932bc54223")]
[assembly: AssemblyProduct("LootCompanion")]
[assembly: AssemblyTitle("LootCompanion")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.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.2+a39d7694ac5eecb28ea3582a1549fe932bc54223")]
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.2+a39d7694ac5eecb28ea3582a1549fe932bc54223";
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)
//IL_002b: 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);
if (LootCompanionPlugin.h3mpEnabled)
{
LootNetwork.SendDestination(position, ownerTransform);
}
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_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
//IL_0486: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: 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;
continue;
}
break;
}
FVRFireArm val2 = null;
FVRFireArmMagazine val3 = null;
Speedloader val4 = null;
FVRGrenade val5 = null;
if ((Object)(object)val == (Object)null)
{
NavMeshHit val6 = default(NavMeshHit);
for (int k = 0; k < num; k++)
{
if ((Object)(object)colbuffer[k].attachedRigidbody != (Object)null && (Object)(object)val2 == (Object)null)
{
val2 = ((Component)colbuffer[k].attachedRigidbody).gameObject.GetComponent<FVRFireArm>();
if ((Object)(object)val2 != (Object)null && !((FVRInteractiveObject)val2).IsHeld && !((Object)(object)((FVRPhysicalObject)val2).QuickbeltSlot != (Object)null) && NavMesh.SamplePosition(((Component)val2).transform.position, ref val6, pickupDistance, -1))
{
val = (FVRPhysicalObject)(object)val2;
break;
}
}
}
if ((Object)(object)val == (Object)null)
{
for (int l = 0; l < num; l++)
{
if ((Object)(object)colbuffer[l].attachedRigidbody != (Object)null && (Object)(object)val3 == (Object)null)
{
val3 = ((Component)colbuffer[l].attachedRigidbody).gameObject.GetComponent<FVRFireArmMagazine>();
if ((Object)(object)val3 != (Object)null && val3.HasARound() && !((FVRInteractiveObject)val3).IsHeld && !((Object)(object)((FVRPhysicalObject)val3).QuickbeltSlot != (Object)null) && NavMesh.SamplePosition(((Component)val3).transform.position, ref val6, pickupDistance, -1))
{
val = (FVRPhysicalObject)(object)val3;
break;
}
}
}
}
if ((Object)(object)val == (Object)null)
{
for (int m = 0; m < num; m++)
{
if (!((Object)(object)colbuffer[m].attachedRigidbody != (Object)null) || !((Object)(object)val4 == (Object)null))
{
continue;
}
val4 = ((Component)colbuffer[m].attachedRigidbody).gameObject.GetComponent<Speedloader>();
if (!((Object)(object)val4 != (Object)null) || ((FVRInteractiveObject)val4).IsHeld || (Object)(object)((FVRPhysicalObject)val4).QuickbeltSlot != (Object)null)
{
continue;
}
bool flag2 = false;
for (int n = 0; n < val4.Chambers.Count; n++)
{
if (val4.Chambers[n].IsLoaded)
{
flag2 = true;
break;
}
}
if (flag2 && NavMesh.SamplePosition(((Component)val4).transform.position, ref val6, pickupDistance, -1))
{
val = (FVRPhysicalObject)(object)val4;
break;
}
}
}
if ((Object)(object)val == (Object)null)
{
for (int num2 = 0; num2 < num; num2++)
{
if ((Object)(object)colbuffer[num2].attachedRigidbody != (Object)null && (Object)(object)val5 == (Object)null)
{
val5 = ((Component)colbuffer[num2].attachedRigidbody).gameObject.GetComponent<FVRGrenade>();
if ((Object)(object)val5 != (Object)null && !val5.m_isPinPulled && !((FVRInteractiveObject)val5).IsHeld && !((Object)(object)((FVRPhysicalObject)val5).QuickbeltSlot != (Object)null) && NavMesh.SamplePosition(((Component)val5).transform.position, ref val6, pickupDistance, -1))
{
val = (FVRPhysicalObject)(object)val5;
break;
}
}
}
}
}
if (trollMode && (Object)(object)val != (Object)null && (Object)(object)val.QuickbeltSlot != (Object)(object)mouthSlot)
{
targetObject = val;
SetState(CompanionStateEnum.GettingItem);
}
else if ((Object)(object)val != (Object)null)
{
targetObject = val;
SetState(CompanionStateEnum.GettingItem);
}
else
{
pickupTimeNext = Time.time + pickupCooldown + Random.Range(-0.25f, 0.25f);
}
}
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;
}
public static void SendDestination(Vector3 position, Transform owner)
{
if (!((Object)(object)owner != (Object)(object)((Component)GM.CurrentPlayerBody).transform))
{
}
}
}
}