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 PickUpTames v1.0.0
PickUpTames.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("PickUpTames")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PickUpTames")] [assembly: AssemblyTitle("PickUpTames")] [assembly: AssemblyVersion("1.0.0.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 PickUpTames { [BepInPlugin("Iteravio.PickUpTames", "PickUpTames", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "Iteravio.PickUpTames"; public const string PluginName = "PickUpTames"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; private static ConfigEntry<float> holdSeconds; private static ConfigEntry<bool> logPickUps; internal static float HoldSeconds => holdSeconds.Value; internal static bool LogPickUps => logPickUps.Value; private void Awake() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; holdSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "HoldToPickUpSeconds", 0.3f, new ConfigDescription("How long you need to hold E (use/interact) to pick up a tame. [Not synced with Server]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), new object[1] { (object)new ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); logPickUps = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogPickUps", false, "Logs every pick-up and drop, with the reason. [Not synced with Server]"); CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "pickuptames_hold", "Hold" }, { "pickuptames_pickup", "Pick up" }, { "pickuptames_follow", "Follow" }, { "pickuptames_stay", "Stay" } }); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new StatusCommand()); new Harmony("Iteravio.PickUpTames").PatchAll(); } private void Update() { TameCarry.Update(); } } internal class StatusCommand : ConsoleCommand { public override string Name => "pickuptames"; public override string Help => "Show PickUpTames settings, what you're holding, and nearby tames with their size"; public override void Run(string[] args, Terminal context) { if ((Object)(object)context == (Object)null) { return; } context.AddString("PickUpTames 1.0.0"); context.AddString($"Hold time: {Plugin.HoldSeconds:0.##} s"); foreach (string item in TameCarry.DescribeNearby(20f)) { context.AddString(item); } } } internal static class TameCarry { private static readonly int HolderKey = StringExtensionMethods.GetStableHashCode("Iteravio.PickUpTames.Holder"); private static readonly int HeartbeatKey = StringExtensionMethods.GetStableHashCode("Iteravio.PickUpTames.Heartbeat"); private const float HeartbeatSeconds = 1f; private const float HeartbeatTimeoutSeconds = 3f; private static readonly FieldRef<Character, Rigidbody> BodyRef = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body"); private static readonly FieldRef<Character, ZSyncAnimation> AnimRef = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim"); private static readonly MethodInfo PlayerInteract = AccessTools.Method(typeof(Player), "Interact", (Type[])null, (Type[])null); private static readonly int ForwardSpeed = ZSyncAnimation.GetHash("forward_speed"); private static readonly int OnGround = ZSyncAnimation.GetHash("onGround"); private const float SpringFrequency = 9f; private const float SpringDamping = 0.35f; private const float MaxSpeed = 25f; private const float SwingDegreesPerSpeed = 9f; private const float MaxSwingDegrees = 30f; private const float TurnSharpness = 8f; private const float HoldGap = 0.35f; private const float MinClearance = 0.5f; private const float PaddleSpeedFactor = 0.7f; private const float SnagDistance = 3f; private const float SnagSeconds = 0.5f; private const float GrabReachSlack = 1.5f; private static GameObject pressHover; private static Character pressTame; private static float pressTime; private static Character held; private static ZNetView heldView; private static BaseAI heldAI; private static float yawOffset; private static float halfHeight; private static float snagTimer; private static float nextHeartbeat; private static Collider playerCollider; private static readonly List<Collider> ignoredColliders = new List<Collider>(); private static bool bypassInteract; private static bool suppressCombat; internal static bool IsHolding => (Object)(object)held != (Object)null; internal static bool IsHeldAI(BaseAI ai) { if (ai == heldAI) { return (Object)(object)ai != (Object)null; } return false; } internal static float GetSize(Character c) { //IL_001c: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) CapsuleCollider collider = c.GetCollider(); if ((Object)(object)collider == (Object)null) { return float.MaxValue; } Vector3 lossyScale = ((Component)collider).transform.lossyScale; return Mathf.Max(collider.height, collider.radius * 2f) * Mathf.Max(lossyScale.x, Mathf.Max(lossyScale.y, lossyScale.z)); } private static bool IsCarryable(Character c) { if ((Object)(object)c != (Object)null && !c.IsPlayer() && c.IsTamed()) { return !c.IsDead(); } return false; } private static string WhyNotGrabbable(Player player, Character c) { ZNetView component = ((Component)c).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return "not loaded"; } Tameable component2 = ((Component)c).GetComponent<Tameable>(); if ((Object)(object)component2 != (Object)null && component2.HaveRider()) { return "being ridden"; } if (IsHeldByOther(component.GetZDO())) { return "held by someone else"; } if (((Character)player).IsDead() || ((Character)player).InAttack() || ((Character)player).IsBlocking() || ((Character)player).IsAttached() || ((Character)player).IsTeleporting()) { return "you're busy"; } return null; } private static bool IsHeldByOther(ZDO zdo) { long num = zdo.GetLong(HolderKey, 0L); if (num == 0L || num == ZDOMan.GetSessionID() || zdo.GetOwner() != num) { return false; } return ZNet.instance.GetTime().Ticks - zdo.GetLong(HeartbeatKey, 0L) < TimeSpan.FromSeconds(3.0).Ticks; } internal static bool OnInteract(Player player, GameObject go, bool hold, bool alt) { if (bypassInteract || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return true; } if ((Object)(object)held != (Object)null) { return false; } if (alt) { return true; } Interactable componentInParent = go.GetComponentInParent<Interactable>(); Tameable val = (Tameable)(object)((componentInParent is Tameable) ? componentInParent : null); Character c = ((val != null) ? ((Component)val).GetComponent<Character>() : ((componentInParent == null) ? go.GetComponentInParent<Character>() : null)); if (!IsCarryable(c)) { return true; } if (!hold) { pressHover = go; pressTame = c; pressTime = Time.time; } return false; } internal static void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { if ((Object)(object)held != (Object)null) { Drop("player gone"); } pressTame = null; return; } bool useHeld = ZInput.GetButton("Use") || ZInput.GetButton("JoyUse"); if ((Object)(object)pressTame != (Object)null) { UpdatePress(localPlayer, useHeld); } if ((Object)(object)held != (Object)null) { UpdateHeld(localPlayer, useHeld); } } private static void UpdatePress(Player player, bool useHeld) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (InMenu()) { pressTame = null; } else if (!useHeld) { GameObject val = pressHover; pressTame = null; if (!((Object)(object)val == (Object)null)) { bypassInteract = true; try { PlayerInteract.Invoke(player, new object[3] { val, false, false }); } finally { bypassInteract = false; } } } else { if (Time.time - pressTime < Plugin.HoldSeconds) { return; } Character val2 = pressTame; pressTame = null; if (IsCarryable(val2)) { string text = WhyNotGrabbable(player, val2); float num = player.m_maxInteractDistance + GetSize(val2) * 0.5f + 1.5f; if (text == null && Vector3.Distance(((Character)player).GetEyePoint(), val2.GetCenterPoint()) > num) { text = "out of reach"; } if (text == null) { Grab(player, val2); } else if (Plugin.LogPickUps) { Plugin.Log.LogInfo((object)("Can't pick up " + NameOf(val2) + ": " + text)); } } } } private static void UpdateHeld(Player player, bool useHeld) { string text = null; if (!useHeld) { text = "released"; } else if ((Object)(object)held == (Object)null || (Object)(object)heldView == (Object)null || !heldView.IsValid() || held.IsDead()) { text = "tame gone"; } else if (!heldView.IsOwner()) { text = "lost ownership"; } else if (((Character)player).IsDead() || ((Character)player).IsTeleporting() || ((Character)player).IsAttached() || InMenu()) { text = "player busy"; } else if (snagTimer > 0.5f) { text = "snagged"; } if (text != null) { Drop(text); } else if (Time.time >= nextHeartbeat) { nextHeartbeat = Time.time + 1f; heldView.GetZDO().Set(HeartbeatKey, ZNet.instance.GetTime().Ticks); } } private static void Grab(Player player, Character c) { //IL_0070: 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_0092: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)c).GetComponent<ZNetView>(); component.ClaimOwnership(); ZDO zDO = component.GetZDO(); zDO.Set(HolderKey, ZDOMan.GetSessionID()); zDO.Set(HeartbeatKey, ZNet.instance.GetTime().Ticks); nextHeartbeat = Time.time + 1f; held = c; heldView = component; heldAI = c.GetBaseAI(); yawOffset = Mathf.DeltaAngle(LookYaw(player), ((Component)c).transform.eulerAngles.y); Bounds bounds = ((Collider)c.GetCollider()).bounds; halfHeight = ((Bounds)(ref bounds)).extents.y; snagTimer = 0f; playerCollider = (Collider)(object)((Character)player).GetCollider(); Collider[] componentsInChildren = ((Component)c).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { Physics.IgnoreCollision(val, playerCollider, true); ignoredColliders.Add(val); } BodyRef.Invoke(c).useGravity = false; if (Plugin.LogPickUps) { Plugin.Log.LogInfo((object)$"Picked up {NameOf(c)} (size {GetSize(c):0.##} m)"); } } internal static void Drop(string reason) { //IL_007b: 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_009f: Unknown result type (might be due to invalid IL or missing references) Character val = held; string text = (((Object)(object)val != (Object)null) ? NameOf(val) : "tame"); if ((Object)(object)val != (Object)null && (Object)(object)heldView != (Object)null && heldView.IsValid() && heldView.IsOwner()) { heldView.GetZDO().Set(HolderKey, 0L); Rigidbody obj = BodyRef.Invoke(val); obj.useGravity = true; obj.angularVelocity = Vector3.zero; obj.rotation = Quaternion.Euler(0f, ((Component)val).transform.eulerAngles.y, 0f); AnimRef.Invoke(val).SetFloat(ForwardSpeed, 0f); } foreach (Collider ignoredCollider in ignoredColliders) { if ((Object)(object)ignoredCollider != (Object)null && (Object)(object)playerCollider != (Object)null) { Physics.IgnoreCollision(ignoredCollider, playerCollider, false); } } ignoredColliders.Clear(); playerCollider = null; held = null; heldView = null; heldAI = null; if (Plugin.LogPickUps) { Plugin.Log.LogInfo((object)("Dropped " + text + ": " + reason)); } } internal static bool OnUpdateMotion(Character c, float dt) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) if (c != held) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } Transform transform = ((Component)GameCamera.instance).transform; Vector3 eyePoint = ((Character)localPlayer).GetEyePoint(); float num = ((Character)localPlayer).GetRadius() + GetSize(c) * 0.5f + 0.35f; Vector3 val = transform.position + transform.forward * (Vector3.Dot(eyePoint - transform.position, transform.forward) + num); val.y = Mathf.Max(val.y, ((Component)localPlayer).transform.position.y + halfHeight + 0.5f); Vector3 val2 = val - c.GetCenterPoint(); snagTimer = ((((Vector3)(ref val2)).magnitude > 3f) ? (snagTimer + dt) : 0f); Rigidbody obj = BodyRef.Invoke(c); Vector3 velocity = ((Character)localPlayer).GetVelocity(); Vector3 linearVelocity = obj.linearVelocity; float num2 = 9f; linearVelocity += (val2 * (num2 * num2) - (linearVelocity - velocity) * (0.7f * num2)) * dt; linearVelocity = (obj.linearVelocity = Vector3.ClampMagnitude(linearVelocity, 25f)); obj.angularVelocity = Vector3.zero; Vector3 val4 = linearVelocity - velocity; val4.y = 0f; float num3 = Mathf.Min(((Vector3)(ref val4)).magnitude * 9f, 30f); Quaternion val5 = ((num3 > 0.01f) ? Quaternion.AngleAxis(num3, Vector3.Cross(Vector3.up, ((Vector3)(ref val4)).normalized)) : Quaternion.identity) * Quaternion.Euler(0f, LookYaw(localPlayer) + yawOffset, 0f); obj.rotation = Quaternion.Slerp(obj.rotation, val5, 1f - Mathf.Exp(-8f * dt)); ZSyncAnimation obj2 = AnimRef.Invoke(c); obj2.SetFloat(ForwardSpeed, c.m_walkSpeed * 0.7f); obj2.SetBool(OnGround, true); return false; } internal static void FilterCombat(ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold) { bool flag = attack | attackHold | secondaryAttack | secondaryAttackHold | block | blockHold; if ((Object)(object)held != (Object)null && flag) { Drop("attack or block"); suppressCombat = true; } if (suppressCombat) { if (!flag) { suppressCombat = false; } else { attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = false))))); } } } internal static string AdjustHoverText(Character c, string text) { if (c == held && (Object)(object)c != (Object)null) { return ""; } if (!IsCarryable(c)) { return text; } ZNetView component = ((Component)c).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || IsHeldByOther(component.GetZDO())) { return text; } string text2 = Localization.instance.Localize("[<color=yellow><b>$pickuptames_hold $KEY_Use</b></color>] $pickuptames_pickup"); if (string.IsNullOrEmpty(text)) { return c.GetHoverName() + "\n" + text2; } List<string> list = new List<string>(text.Split(new char[1] { '\n' })); AddCommandToPetLine(c, list); list.Insert(Mathf.Min(2, list.Count), text2); return string.Join("\n", list.ToArray()); } private static void AddCommandToPetLine(Character c, List<string> lines) { Tameable component = ((Component)c).GetComponent<Tameable>(); if (!((Object)(object)component == (Object)null) && component.m_commandable && lines.Count >= 2 && lines[1].EndsWith(Localization.instance.Localize("$hud_pet"))) { bool flag = !string.IsNullOrEmpty(((Component)c).GetComponent<ZNetView>().GetZDO().GetString(ZDOVars.s_follow, "")); lines[1] += Localization.instance.Localize(flag ? " + $pickuptames_stay" : " + $pickuptames_follow"); } } internal static IEnumerable<string> DescribeNearby(float radius) { Player player = Player.m_localPlayer; if ((Object)(object)player == (Object)null) { yield return "Not in a world"; yield break; } yield return ((Object)(object)held != (Object)null) ? $"Holding: {NameOf(held)}, {Vector3.Distance(((Character)player).GetEyePoint(), held.GetCenterPoint()):0.##} m from your eyes" : "Holding: nothing"; GameObject hoverObject = ((Humanoid)player).GetHoverObject(); yield return "Looking at: " + (((Object)(object)hoverObject != (Object)null) ? ((Object)hoverObject).name : "nothing"); foreach (Character allCharacter in Character.GetAllCharacters()) { if (IsCarryable(allCharacter)) { float num = Vector3.Distance(((Component)player).transform.position, ((Component)allCharacter).transform.position); if (!(num > radius)) { float size = GetSize(allCharacter); string text = WhyNotGrabbable(player, allCharacter) ?? "can pick up"; BaseAI baseAI = allCharacter.GetBaseAI(); BaseAI obj = ((baseAI is MonsterAI) ? baseAI : null); string text2 = (((Object)(object)((obj != null) ? ((MonsterAI)obj).GetFollowTarget() : null) != (Object)null) ? "following" : "staying"); yield return $"{NameOf(allCharacter)} ({((Object)allCharacter).name}): size {size:0.##} m, {num:0.#} m away, {text2}, {text}"; } } } } private static string NameOf(Character c) { return Localization.instance.Localize(c.m_name); } private static float LookYaw(Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_002a: Unknown result type (might be due to invalid IL or missing references) Vector3 lookDir = ((Character)player).GetLookDir(); lookDir.y = 0f; if (!(((Vector3)(ref lookDir)).sqrMagnitude < 0.0001f)) { Quaternion val = Quaternion.LookRotation(lookDir); return ((Quaternion)(ref val)).eulerAngles.y; } return ((Component)player).transform.eulerAngles.y; } private static bool InMenu() { if (!InventoryGui.IsVisible() && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !Minimap.IsOpen()) { if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } return true; } } [HarmonyPatch(typeof(Player), "Interact")] internal static class PlayerInteractPatch { private static bool Prefix(Player __instance, GameObject go, bool hold, bool alt) { return TameCarry.OnInteract(__instance, go, hold, alt); } } [HarmonyPatch(typeof(BaseAI), "UpdateAI")] internal static class BaseAIUpdatePatch { private static bool Prefix(BaseAI __instance, ref bool __result) { if (!TameCarry.IsHeldAI(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Character), "UpdateMotion")] internal static class CharacterUpdateMotionPatch { private static bool Prefix(Character __instance, float dt) { return TameCarry.OnUpdateMotion(__instance, dt); } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class PlayerSetControlsPatch { [HarmonyPriority(200)] private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { TameCarry.FilterCombat(ref attack, ref attackHold, ref secondaryAttack, ref secondaryAttackHold, ref block, ref blockHold); } } } [HarmonyPatch(typeof(Player), "TeleportTo")] internal static class PlayerTeleportPatch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && TameCarry.IsHolding) { TameCarry.Drop("teleport"); } } } [HarmonyPatch(typeof(Character), "GetHoverText")] internal static class CharacterHoverTextPatch { private static void Postfix(Character __instance, ref string __result) { __result = TameCarry.AdjustHoverText(__instance, __result); } } }