Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BeastsOfBurden v1.0.6
BeastsOfBurden.dll
Decompiled 2 weeks agousing 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); } } }