Decompiled source of Hastur of Carcosa Community Modpack v5.0.0

plugins/BeastsOfBurden.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
namespace BeastsOfBurden;

[BepInPlugin("org.bepinex.plugins.beasts_of_burden", "BeastsOfBurden", "1.0.4")]
public class BeastsOfBurden : BaseUnityPlugin
{
	public enum Beasts
	{
		lox,
		wolf,
		boar,
		player,
		other
	}

	[HarmonyPatch(typeof(Vagon), "LateUpdate")]
	private class LateUpdate_Vagon_Patch
	{
		private static void Prefix(ref Vagon __instance, ref ConfigurableJoint ___m_attachJoin, ref Rigidbody ___m_body)
		{
			if ((Object)(object)___m_attachJoin != (Object)null && (Object)(object)((Joint)___m_attachJoin).connectedBody == (Object)null)
			{
				__instance.Detach();
			}
		}
	}

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

	[HarmonyPatch(typeof(Vagon), "FixedUpdate")]
	private class Vagon_FixedUpdate_Patch
	{
		private static bool Prefix(Vagon __instance)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_nview.IsValid())
			{
				logger.LogDebug((object)"m_nview invalid");
				return false;
			}
			__instance.UpdateAudio(Time.fixedDeltaTime);
			if (__instance.m_nview.IsOwner())
			{
				if (Object.op_Implicit((Object)(object)__instance.m_useRequester))
				{
					if (__instance.IsAttached())
					{
						__instance.Detach();
					}
					else
					{
						Character val = FindClosestAttachableAnimal(__instance);
						if ((Object)(object)val != (Object)null)
						{
							AttachCartTo(val, __instance);
						}
						else if (__instance.CanAttach(((Component)__instance.m_useRequester).gameObject))
						{
							AttachCartTo((Character)(object)__instance.m_useRequester, __instance);
						}
						else
						{
							((Character)__instance.m_useRequester).Message((MessageType)2, "Not in the right position", 0, (Sprite)null);
						}
					}
					__instance.m_useRequester = null;
				}
				if (__instance.IsAttached())
				{
					__instance.m_detachDistance = GetCartDetachDistance(AttachedCharacter(__instance));
					if (!__instance.CanAttach(((Component)((Joint)__instance.m_attachJoin).connectedBody).gameObject))
					{
						__instance.Detach();
						logger.LogDebug((object)"Cart no longer attachable.");
					}
				}
			}
			else if (__instance.IsAttached())
			{
				__instance.Detach();
			}
			return false;
		}
	}

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

	public static ManualLogSource logger;

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

	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;
		}
		if (c.m_nview.IsValid())
		{
			return ((Object)ZNetScene.instance.GetPrefab(c.m_nview.GetZDO().GetPrefab())).name 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 ((Component)((Joint)cart.m_attachJoin).connectedBody).gameObject.GetComponent<Character>();
		}
		return null;
	}

	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)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		cart.m_attachOffset = GetCartOffsetVectorForCharacter(attachTarget);
		cart.m_attachJoin = ((Component)cart).gameObject.AddComponent<ConfigurableJoint>();
		((Joint)cart.m_attachJoin).autoConfigureConnectedAnchor = false;
		((Joint)cart.m_attachJoin).anchor = cart.m_attachPoint.localPosition;
		((Joint)cart.m_attachJoin).connectedAnchor = cart.m_attachOffset;
		((Joint)cart.m_attachJoin).breakForce = cart.m_breakForce;
		cart.m_attachJoin.xMotion = (ConfigurableJointMotion)1;
		cart.m_attachJoin.yMotion = (ConfigurableJointMotion)1;
		cart.m_attachJoin.zMotion = (ConfigurableJointMotion)1;
		SoftJointLimit linearLimit = default(SoftJointLimit);
		((SoftJointLimit)(ref linearLimit)).limit = 0.001f;
		cart.m_attachJoin.linearLimit = linearLimit;
		SoftJointLimitSpring linearLimitSpring = default(SoftJointLimitSpring);
		((SoftJointLimitSpring)(ref linearLimitSpring)).spring = cart.m_spring;
		((SoftJointLimitSpring)(ref linearLimitSpring)).damper = cart.m_springDamping;
		cart.m_attachJoin.linearLimitSpring = linearLimitSpring;
		cart.m_attachJoin.zMotion = (ConfigurableJointMotion)0;
		((Joint)cart.m_attachJoin).connectedBody = ((Component)attachTarget).gameObject.GetComponent<Rigidbody>();
	}
}