Decompiled source of BeastsOfBurden v1.0.6

BeastsOfBurden.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
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: AssemblyTitle("BeastsOfBurden")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BeastsOfBurden")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("fcb9af9d-f8cd-406f-9405-e10a8d59b395")]
[assembly: AssemblyFileVersion("1.0.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.6.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
namespace BeastsOfBurden
{
	[BepInPlugin("org.bepinex.plugins.beasts_of_burden", "BeastsOfBurden", "1.0.6")]
	public class BeastsOfBurden : BaseUnityPlugin
	{
		private delegate void VagonAttachToDelegate(Vagon instance, GameObject target);

		private delegate void VagonDetachDelegate(Vagon instance);

		private delegate bool BaseAIMoveToDelegate(BaseAI instance, float dt, Vector3 target, float stopDistance, bool run);

		public enum Beasts
		{
			lox,
			wolf,
			boar,
			player,
			other
		}

		[HarmonyPatch(typeof(Vagon), "LateUpdate")]
		private class LateUpdate_Vagon_Patch
		{
			private static void Prefix(Vagon __instance)
			{
				ConfigurableJoint val = VagonAttachJoin.Invoke(__instance);
				if ((Object)(object)val != (Object)null && (Object)(object)((Joint)val).connectedBody == (Object)null)
				{
					VagonDetach(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Vagon), "InUse")]
		private class InUse_Vagon_Patch
		{
			private static bool Prefix(ref bool __result, Vagon __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance.m_container) && __instance.m_container.IsInUse())
				{
					__result = true;
				}
				else if (__instance.IsAttached())
				{
					ConfigurableJoint val = VagonAttachJoin.Invoke(__instance);
					__result = (Object)(object)val != (Object)null && (Object)(object)((Joint)val).connectedBody != (Object)null && (Object)(object)((Component)((Joint)val).connectedBody).gameObject.GetComponent<Player>() != (Object)null;
				}
				else
				{
					__result = false;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Vagon), "CanAttach")]
		private class Vagon_CanAttach_Patch
		{
			private static bool Prefix(Vagon __instance, GameObject go, ref bool __result)
			{
				//IL_003c: 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_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_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				Character val = (((Object)(object)go != (Object)null) ? go.GetComponent<Character>() : null);
				if ((Object)(object)val == (Object)null || val.IsPlayer() || !val.IsTamed() || !IsAttachableCharacter(val))
				{
					return true;
				}
				if (((Component)__instance).transform.up.y < 0.1f || val.InDodge() || val.IsTeleporting())
				{
					__result = false;
					return false;
				}
				__instance.m_attachOffset = GetCartOffsetVectorForCharacter(val);
				__instance.m_detachDistance = GetCartDetachDistance(val);
				__result = Vector3.Distance(go.transform.position + __instance.m_attachOffset, __instance.m_attachPoint.position) < __instance.m_detachDistance;
				return false;
			}
		}

		[HarmonyPatch(typeof(Vagon), "Update")]
		private class Vagon_Update_Patch
		{
			private static void Prefix(Vagon __instance, ref Humanoid ___m_useRequester)
			{
				if (!__instance.IsAttached() && Object.op_Implicit((Object)(object)___m_useRequester))
				{
					Character val = FindClosestAttachableAnimal(__instance);
					if ((Object)(object)val != (Object)null)
					{
						AttachCartTo(val, __instance);
						___m_useRequester = null;
					}
				}
				Character val2 = AttachedCharacter(__instance);
				if ((Object)(object)val2 != (Object)null && !val2.IsPlayer())
				{
					__instance.m_detachDistance = GetCartDetachDistance(val2);
				}
			}
		}

		[HarmonyPatch(typeof(BaseAI), "UpdateAI")]
		private class BaseAI_UpdateAI_patch
		{
			private static bool Prefix(ref BaseAI __instance, Character ___m_character)
			{
				if ((Object)(object)___m_character != (Object)null && ___m_character.IsTamed() && preventTamedFearOfFire.Value)
				{
					__instance.m_afraidOfFire = false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(BaseAI), "Follow")]
		private class Tamed_Follow_patch
		{
			private static bool Prefix(GameObject go, float dt, ref BaseAI __instance, Character ___m_character)
			{
				//IL_004d: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)___m_character == (Object)null || !___m_character.IsTamed())
				{
					return true;
				}
				BaseAI obj = __instance;
				MonsterAI val = (MonsterAI)(object)((obj is MonsterAI) ? obj : null);
				GameObject val2 = (((Object)(object)val != (Object)null) ? val.GetFollowTarget() : null);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.GetComponent<Player>() == (Object)null)
				{
					return true;
				}
				float num = Vector3.Distance(go.transform.position, ((Component)__instance).transform.position);
				float value;
				switch (ParseCharacterType(___m_character))
				{
				case Beasts.lox:
					value = followDistanceLox.Value;
					break;
				case Beasts.wolf:
				case Beasts.boar:
					value = followDistanceMediumAnimal.Value;
					break;
				default:
					return true;
				}
				bool run = num > value * 3f;
				if (num < value)
				{
					__instance.StopMoving();
				}
				else
				{
					BaseAIMoveTo(__instance, dt, go.transform.position, 0f, run);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Tameable), "Interact")]
		private class Command_Patch
		{
			private static void Prefix(ref bool ___m_commandable, ref Character ___m_character)
			{
				switch (ParseCharacterType(___m_character))
				{
				case Beasts.lox:
					___m_commandable = commandLox.Value;
					break;
				case Beasts.wolf:
					___m_commandable = commandWolf.Value;
					break;
				case Beasts.boar:
					___m_commandable = commandBoar.Value;
					break;
				}
			}
		}

		private const string pluginGUID = "org.bepinex.plugins.beasts_of_burden";

		private const string pluginName = "BeastsOfBurden";

		public const string pluginVersion = "1.0.6";

		public static ManualLogSource logger;

		private readonly Harmony harmony = new Harmony("org.bepinex.plugins.beasts_of_burden");

		private static readonly FieldRef<Character, ZNetView> CharacterNView = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview");

		private static readonly FieldRef<Vagon, ConfigurableJoint> VagonAttachJoin = AccessTools.FieldRefAccess<Vagon, ConfigurableJoint>("m_attachJoin");

		private static readonly VagonAttachToDelegate VagonAttachTo = AccessTools.MethodDelegate<VagonAttachToDelegate>(AccessTools.Method(typeof(Vagon), "AttachTo", new Type[1] { typeof(GameObject) }, (Type[])null), (object)null, false);

		private static readonly VagonDetachDelegate VagonDetach = AccessTools.MethodDelegate<VagonDetachDelegate>(AccessTools.Method(typeof(Vagon), "Detach", (Type[])null, (Type[])null), (object)null, false);

		private static readonly BaseAIMoveToDelegate BaseAIMoveTo = AccessTools.MethodDelegate<BaseAIMoveToDelegate>(AccessTools.Method(typeof(BaseAI), "MoveTo", new Type[4]
		{
			typeof(float),
			typeof(Vector3),
			typeof(float),
			typeof(bool)
		}, (Type[])null), (object)null, false);

		private static ConfigEntry<bool> commandWolf;

		private static ConfigEntry<bool> commandBoar;

		private static ConfigEntry<bool> commandLox;

		private static ConfigEntry<bool> attachToWolf;

		private static ConfigEntry<bool> attachToBoar;

		private static ConfigEntry<bool> attachToLox;

		private static ConfigEntry<bool> attachToOtherTamed;

		private static ConfigEntry<float> detachDistanceFactor;

		private static ConfigEntry<float> detachDistancePlayer;

		private static ConfigEntry<float> followDistanceLox;

		private static ConfigEntry<float> followDistanceMediumAnimal;

		private static ConfigEntry<bool> preventTamedFearOfFire;

		private void Awake()
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading Beasts of Burden ");
			commandWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandWolf", true, "Makes Wolf Commandable (as it is in the normal game)");
			commandBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandBoar", true, "Makes Boar Commandable");
			commandLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "commandLox", true, "Makes Lox Commandable");
			attachToWolf = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToWolf", true, "Allow cart to attach to Wolf");
			attachToBoar = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToBoar", true, "Allow cart to attach to Boar");
			attachToLox = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToLox", true, "Allow cart to attach to Lox");
			attachToOtherTamed = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "attachToOtherTamed", true, "Experimental: Allow cart to attach to other types of tamed animals. ");
			detachDistancePlayer = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "detachDistancePlayer", 2f, new ConfigDescription("How far the player has to be from the cart.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			detachDistanceFactor = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "detachDistanceFactor", 3.5f, new ConfigDescription("How far something has to be from the cart to use it a multiple of their radius", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			followDistanceLox = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "followDistanceLox", 8f, new ConfigDescription("How close the lox will follow behind the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			followDistanceMediumAnimal = ((BaseUnityPlugin)this).Config.Bind<float>("BeastsOfBurden", "followDistanceMediumAnimal", 3f, new ConfigDescription("How close medium animals (wolf and boar) will follow behind the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			preventTamedFearOfFire = ((BaseUnityPlugin)this).Config.Bind<bool>("BeastsOfBurden", "preventTamedFearOfFire", false, new ConfigDescription("Prevent tamed animals from being afraid of fire.", (AcceptableValueBase)null, Array.Empty<object>()));
			harmony.PatchAll();
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}

		public static Beasts ParseCharacterType(Character c)
		{
			if (c.IsPlayer())
			{
				return Beasts.player;
			}
			ZNetView val = CharacterNView.Invoke(c);
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(val.GetZDO().GetPrefab());
				return (((Object)(object)prefab != (Object)null) ? ((Object)prefab).name : string.Empty) switch
				{
					"Lox" => Beasts.lox, 
					"Wolf" => Beasts.wolf, 
					"Boar" => Beasts.boar, 
					_ => Beasts.other, 
				};
			}
			logger.LogDebug((object)"Character has invalid m_nview.");
			return Beasts.other;
		}

		public static Vector3 GetCartOffsetVectorForCharacter(Character c)
		{
			//IL_0033: 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)
			if (Object.op_Implicit((Object)(object)c))
			{
				return new Vector3(0f, 0.8f, 0f - c.GetRadius());
			}
			return new Vector3(0f, 0.8f, 0f);
		}

		public static bool IsAttachableCharacter(Character c)
		{
			return ParseCharacterType(c) switch
			{
				Beasts.lox => attachToLox.Value, 
				Beasts.wolf => attachToWolf.Value, 
				Beasts.boar => attachToBoar.Value, 
				Beasts.player => true, 
				_ => attachToOtherTamed.Value, 
			};
		}

		public static float GetCartDetachDistance(Character c)
		{
			if (Object.op_Implicit((Object)(object)c))
			{
				if (c.IsPlayer())
				{
					return detachDistancePlayer.Value;
				}
				return c.GetRadius() * detachDistanceFactor.Value;
			}
			logger.LogError((object)"Character pass was null");
			return 0f;
		}

		private static Character FindClosestAttachableAnimal(Vagon cart)
		{
			//IL_0085: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)cart))
			{
				logger.LogError((object)"Cart pointer is null");
				return null;
			}
			Transform attachPoint = cart.m_attachPoint;
			Character val = null;
			float num = float.MaxValue;
			if (!Object.op_Implicit((Object)(object)cart.m_attachPoint))
			{
				logger.LogError((object)"cart.m_attachPoint is null.");
				return null;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (Object.op_Implicit((Object)(object)allCharacter))
				{
					if (!allCharacter.IsPlayer() && allCharacter.IsTamed() && IsAttachableCharacter(allCharacter))
					{
						Vector3 cartOffsetVectorForCharacter = GetCartOffsetVectorForCharacter(allCharacter);
						float num2 = Vector3.Distance(((Component)allCharacter).transform.position + cartOffsetVectorForCharacter, attachPoint.position);
						float cartDetachDistance = GetCartDetachDistance(allCharacter);
						if (num2 < cartDetachDistance && num2 < num)
						{
							val = allCharacter;
							num = num2;
						}
					}
				}
				else
				{
					logger.LogWarning((object)"null character returned by Character.GetAllCharacter() in method FindClosestTamedAnimal");
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				logger.LogDebug((object)$"Closest animal is {val.m_name} at a distance of {num}");
			}
			return val;
		}

		private static Character AttachedCharacter(Vagon cart)
		{
			if (!Object.op_Implicit((Object)(object)cart) || !cart.IsAttached())
			{
				return null;
			}
			ConfigurableJoint val = VagonAttachJoin.Invoke(cart);
			if ((Object)(object)val == (Object)null || (Object)(object)((Joint)val).connectedBody == (Object)null)
			{
				return null;
			}
			return ((Component)((Joint)val).connectedBody).gameObject.GetComponent<Character>();
		}

		private static void LogCartContents(Vagon cart)
		{
			Container container = cart.m_container;
			logger.LogDebug((object)"Cart contents:");
			foreach (ItemData allItem in container.GetInventory().GetAllItems())
			{
				logger.LogDebug((object)("\t * " + allItem.m_shared.m_name));
			}
		}

		private static void AttachCartTo(Character attachTarget, Vagon cart)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			cart.m_attachOffset = GetCartOffsetVectorForCharacter(attachTarget);
			cart.m_detachDistance = GetCartDetachDistance(attachTarget);
			VagonAttachTo(cart, ((Component)attachTarget).gameObject);
		}
	}
}