Decompiled source of FeralLoot v1.0.0

FeralLoot.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Adir")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FeralLoot")]
[assembly: AssemblyTitle("FeralLoot")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute(string assemblyName) : Attribute()
	{
		public string AssemblyName { get; } = assemblyName;
	}
}
namespace FeralLoot
{
	internal class FeralBrain : MonoBehaviour
	{
		private enum Temperament
		{
			Lazy,
			Skittish,
			Wild
		}

		private readonly struct Traits
		{
			public readonly float HopSpeed;

			public readonly float HopHeight;

			public readonly int Stamina;

			public readonly float RadiusScale;

			public readonly float SlipScale;

			public Traits(float hopSpeed, float hopHeight, int stamina, float radiusScale, float slipScale)
			{
				HopSpeed = hopSpeed;
				HopHeight = hopHeight;
				Stamina = stamina;
				RadiusScale = radiusScale;
				SlipScale = slipScale;
			}
		}

		private static readonly Traits lazy = new Traits(2.4f, 3.2f, 3, 0.8f, 0f);

		private static readonly Traits skittish = new Traits(3.6f, 4f, 5, 1f, 0.4f);

		private static readonly Traits wild = new Traits(5.2f, 5f, 8, 1.5f, 1f);

		private const float SenseInterval = 0.2f;

		private const float MaxVerticalNotice = 2.5f;

		private const float RestSpeed = 0.7f;

		private ValuableObject valuable;

		private PhysGrabObject physGrabObject;

		private PhysGrabObjectImpactDetector? impactDetector;

		private RoomVolumeCheck? roomVolumeCheck;

		private Rigidbody rb;

		private Temperament temperament;

		private Traits traits;

		private bool temperamentSet;

		private float wakeTimer = 6f;

		private float senseTimer;

		private float hopTimer;

		private float wriggleTimer;

		private float fidgetTimer;

		private float restTimer;

		private int stamina;

		private PlayerAvatar? threat;

		private float threatDistance;

		private void Awake()
		{
			valuable = ((Component)this).GetComponent<ValuableObject>();
			physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
			impactDetector = ((Component)this).GetComponent<PhysGrabObjectImpactDetector>();
			roomVolumeCheck = ((Component)this).GetComponent<RoomVolumeCheck>();
			rb = (Object.op_Implicit((Object)(object)physGrabObject.rb) ? physGrabObject.rb : ((Component)this).GetComponent<Rigidbody>());
			fidgetTimer = Random.Range(8f, 25f);
			senseTimer = Random.Range(0f, 0.2f);
		}

		private void Update()
		{
			if (!FeralLoot.modEnabled.Value || !Object.op_Implicit((Object)(object)rb) || rb.isKinematic || !physGrabObject.spawned)
			{
				return;
			}
			if (wakeTimer > 0f)
			{
				if (SemiFunc.LevelGenDone())
				{
					wakeTimer -= Time.deltaTime;
				}
				return;
			}
			if (!temperamentSet)
			{
				SetTemperament();
			}
			if (IsTamed())
			{
				stamina = traits.Stamina;
				return;
			}
			if (physGrabObject.grabbed)
			{
				Struggle();
				return;
			}
			if (restTimer > 0f)
			{
				restTimer -= Time.deltaTime;
				if (restTimer <= 0f)
				{
					stamina = traits.Stamina;
				}
				return;
			}
			if (hopTimer > 0f)
			{
				hopTimer -= Time.deltaTime;
			}
			senseTimer -= Time.deltaTime;
			if (senseTimer <= 0f)
			{
				senseTimer = 0.2f;
				Sense();
			}
			if (Object.op_Implicit((Object)(object)threat))
			{
				if (hopTimer <= 0f && IsSettled())
				{
					Flee();
				}
			}
			else
			{
				if (!FeralLoot.fidget.Value)
				{
					return;
				}
				fidgetTimer -= Time.deltaTime;
				if (fidgetTimer <= 0f)
				{
					fidgetTimer = Random.Range(10f, 30f);
					if (IsSettled())
					{
						Fidget();
					}
				}
			}
		}

		private void SetTemperament()
		{
			temperamentSet = true;
			float dollarValueCurrent = valuable.dollarValueCurrent;
			temperament = ((dollarValueCurrent >= FeralLoot.wildValue.Value) ? Temperament.Wild : ((dollarValueCurrent >= FeralLoot.skittishValue.Value) ? Temperament.Skittish : Temperament.Lazy));
			traits = temperament switch
			{
				Temperament.Wild => wild, 
				Temperament.Skittish => skittish, 
				_ => lazy, 
			};
			stamina = traits.Stamina;
		}

		private bool IsTamed()
		{
			if (!Object.op_Implicit((Object)(object)impactDetector) || !impactDetector.inCart)
			{
				if (Object.op_Implicit((Object)(object)roomVolumeCheck))
				{
					if (!roomVolumeCheck.inTruck)
					{
						return roomVolumeCheck.inExtractionPoint;
					}
					return true;
				}
				return false;
			}
			return true;
		}

		private bool IsSettled()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = rb.velocity;
			return ((Vector3)(ref velocity)).sqrMagnitude < 0.48999998f;
		}

		private void Sense()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_007e: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			threat = null;
			threatDistance = float.MaxValue;
			Vector3 worldCenterOfMass = rb.worldCenterOfMass;
			float num = FeralLoot.spookRadius.Value * traits.RadiusScale;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!Object.op_Implicit((Object)(object)player) || player.isDisabled || player.deadSet)
				{
					continue;
				}
				Vector3 val = ((Component)player).transform.position - worldCenterOfMass;
				if (!(Mathf.Abs(val.y) > 2.5f))
				{
					float num2 = ((player.isCrouching || player.isCrawling) ? (num * FeralLoot.sneakMultiplier.Value) : num);
					if (player.isSprinting)
					{
						num2 *= 1.3f;
					}
					float magnitude = ((Vector3)(ref val)).magnitude;
					if (magnitude < num2 && magnitude < threatDistance)
					{
						threat = player;
						threatDistance = magnitude;
					}
				}
			}
		}

		private void Flee()
		{
			//IL_0006: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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)
			Vector3 val = rb.worldCenterOfMass - ((Component)threat).transform.position;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				val = Random.insideUnitSphere;
			}
			val.y = 0f;
			Hop(PickEscapeDirection(((Vector3)(ref val)).normalized), 1f);
			hopTimer = Random.Range(0.45f, 1.1f);
			if (--stamina <= 0)
			{
				restTimer = FeralLoot.restTime.Value * Random.Range(0.8f, 1.25f);
			}
		}

		private Vector3 PickEscapeDirection(Vector3 away)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//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_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = rb.worldCenterOfMass + Vector3.up * 0.2f;
			Vector3 result = away;
			float num = float.MinValue;
			RaycastHit val3 = default(RaycastHit);
			for (int i = 0; i < 7; i++)
			{
				float num2 = Random.Range(-75f, 75f);
				Vector3 val2 = Quaternion.Euler(0f, num2, 0f) * away;
				float num3 = (Physics.Raycast(val, val2, ref val3, 4f, -5, (QueryTriggerInteraction)1) ? ((RaycastHit)(ref val3)).distance : 4f) - Mathf.Abs(num2) / 60f;
				if (num3 > num)
				{
					num = num3;
					result = val2;
				}
			}
			return result;
		}

		private void Fidget()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			Vector3 insideUnitSphere = Random.insideUnitSphere;
			insideUnitSphere.y = 0f;
			Hop(((Vector3)(ref insideUnitSphere)).normalized, 0.3f);
		}

		private void Hop(Vector3 direction, float strength)
		{
			//IL_0029: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0071: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			float num = FeralLoot.hopPower.Value * strength;
			if (FeralLoot.safeHops.Value)
			{
				physGrabObject.OverrideIndestructible(2f);
			}
			Vector3 val = direction * (traits.HopSpeed * num) + Vector3.up * (traits.HopHeight * Mathf.Sqrt(num));
			rb.AddForce(val, (ForceMode)2);
			rb.AddTorque(Random.insideUnitSphere * 4f * num, (ForceMode)2);
		}

		private void Struggle()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			//IL_008f: 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_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)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			float value = FeralLoot.wriggleStrength.Value;
			wriggleTimer -= Time.deltaTime;
			if (wriggleTimer <= 0f && value > 0f)
			{
				wriggleTimer = Random.Range(0.2f, 0.5f);
				float num = value * (0.6f + 0.4f * (float)temperament);
				rb.AddTorque(Random.insideUnitSphere * 5f * num, (ForceMode)2);
				rb.AddForce((Random.insideUnitSphere + Vector3.up * 0.3f) * 1.5f * num, (ForceMode)2);
			}
			if (physGrabObject.playerGrabbing.Count == 1)
			{
				float num2 = FeralLoot.slipChance.Value * traits.SlipScale;
				if (num2 > 0f && Random.value < num2 * Time.deltaTime)
				{
					SlipFree();
				}
			}
		}

		private void SlipFree()
		{
			//IL_003c: 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_004c: 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_0092: 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)
			PhysGrabber val = physGrabObject.playerGrabbing[0];
			if (Object.op_Implicit((Object)(object)val))
			{
				val.OverrideGrabRelease(physGrabObject.photonView.ViewID, 1f);
				Vector3 val2 = rb.worldCenterOfMass - ((Component)val).transform.position;
				val2.y = 0f;
				if (FeralLoot.safeHops.Value)
				{
					physGrabObject.OverrideIndestructible(2.5f);
				}
				Hop((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val2)).normalized : Random.onUnitSphere, 1.2f);
				hopTimer = 0.3f;
				FeralLoot.Logger.LogInfo((object)(((Object)valuable).name + " slipped out of " + val.playerAvatar?.playerName + "'s hands!"));
			}
		}
	}
	[BepInPlugin("Adir.FeralLoot", "FeralLoot", "1.0.0")]
	public class FeralLoot : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> modEnabled;

		internal static ConfigEntry<float> spookRadius;

		internal static ConfigEntry<float> sneakMultiplier;

		internal static ConfigEntry<float> hopPower;

		internal static ConfigEntry<float> restTime;

		internal static ConfigEntry<float> wriggleStrength;

		internal static ConfigEntry<float> slipChance;

		internal static ConfigEntry<bool> safeHops;

		internal static ConfigEntry<bool> fidget;

		internal static ConfigEntry<float> skittishValue;

		internal static ConfigEntry<float> wildValue;

		internal static FeralLoot Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01c9: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Valuables come alive and run from players");
			safeHops = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SafeHops", true, "Valuables can't break from their own hops and landings (you still break them the normal way)");
			fidget = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Fidget", true, "Unwatched valuables occasionally twitch and hop in place. Makes noise, may attract monsters.");
			spookRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Senses", "SpookRadius", 6f, "How close (meters) a player can get before loot runs. Wild loot notices you from 50% further.");
			sneakMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Senses", "SneakMultiplier", 0.45f, "Spook radius multiplier for crouching/crawling players. Sneak up on them!");
			hopPower = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "HopPower", 1f, "Multiplier for how far and high loot hops");
			restTime = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RestTime", 4f, "Seconds a valuable lies still, exhausted, after running out of stamina");
			wriggleStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Grabbed", "WriggleStrength", 1f, "How hard loot squirms while being carried (0 = off)");
			slipChance = ((BaseUnityPlugin)this).Config.Bind<float>("Grabbed", "SlipChance", 0.07f, "Chance per second that wild loot slips out of a SINGLE player's grip. Carry it with a friend to hold it securely.");
			skittishValue = ((BaseUnityPlugin)this).Config.Bind<float>("Temperament", "SkittishValue", 1000f, "Loot worth at least this much is skittish (faster, more stamina). Below it, loot is lazy.");
			wildValue = ((BaseUnityPlugin)this).Config.Bind<float>("Temperament", "WildValue", 5000f, "Loot worth at least this much is wild (fastest, notices you from further, can slip out of your hands).");
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded! The loot is restless...");
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "Start")]
	internal static class ValuableObjectStartPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ValuableObject __instance)
		{
			if (FeralLoot.modEnabled.Value && SemiFunc.RunIsLevel() && SemiFunc.IsMasterClientOrSingleplayer() && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PhysGrabObject>()) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<FeralBrain>()))
			{
				((Component)__instance).gameObject.AddComponent<FeralBrain>();
			}
		}
	}
}