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 LeashMe v1.3.1
LeashMe.dll
Decompiled 17 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LeashMe")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LeashMe")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.3.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.1.0")] namespace LeashMe; internal static class EmbeddedSprite { public static Sprite Load(string fileName) { //IL_0080: 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) using Stream stream = typeof(EmbeddedSprite).Assembly.GetManifestResourceStream("LeashMe." + fileName); if (stream == null) { Logger.LogWarning((object)("Embedded icon " + fileName + " not found.")); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = AssetUtils.LoadImage(array); return Object.op_Implicit((Object)(object)val) ? Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)) : null; } } internal class HitchingPost : MonoBehaviour, Hoverable, Interactable { private const int MaxAnimals = 5; private static readonly int IdKey = StringExtensionMethods.GetStableHashCode("LeashMe_postId"); private static readonly List<HitchingPost> s_posts = new List<HitchingPost>(); private static readonly List<LeashLink> s_links = new List<LeashLink>(); private static readonly Random s_random = new Random(); private ZNetView m_nview; private Piece m_piece; private int m_level; private GameObject m_wrap; private bool m_hasRopePoint; private Vector3 m_ropePoint; public long Id { get { if (!Object.op_Implicit((Object)(object)m_nview) || !m_nview.IsValid()) { return 0L; } return m_nview.GetZDO().GetLong(IdKey, 0L); } } public Vector3 RopePoint { get { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!m_hasRopePoint) { m_hasRopePoint = true; m_ropePoint = ((Component)this).transform.TransformPoint(0f, HitchingPostPiece.GetRopeHeight(((Component)this).gameObject), 0f); } return m_ropePoint; } } public static HitchingPost Find(long id) { if (id == 0L) { return null; } foreach (HitchingPost s_post in s_posts) { if (Object.op_Implicit((Object)(object)s_post) && s_post.Id == id) { return s_post; } } return null; } private void Start() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_piece = ((Component)this).GetComponent<Piece>(); m_level = HitchingPostPiece.GetLevel(((Component)this).gameObject); Transform obj = ((Component)this).transform.Find("leatherwrap"); m_wrap = ((obj != null) ? ((Component)obj).gameObject : null); if (Object.op_Implicit((Object)(object)m_nview) && m_nview.IsValid()) { s_posts.Add(this); EnsureId(); } } private void OnDestroy() { s_posts.Remove(this); } private void Update() { EnsureId(); UpdateWrap(); } private void UpdateWrap() { if (Object.op_Implicit((Object)(object)m_wrap)) { bool flag = Id != 0L && CountTied() > 0; if (m_wrap.activeSelf != flag) { m_wrap.SetActive(flag); } } } private void EnsureId() { if (Object.op_Implicit((Object)(object)m_nview) && m_nview.IsValid() && m_nview.IsOwner() && Id == 0L) { long num; do { num = ((long)s_random.Next() << 32) ^ (uint)s_random.Next(); } while (num == 0L); m_nview.GetZDO().Set(IdKey, num); } } public string GetHoverText() { string text = GetHoverName(); if (!LocalHasLeash((Humanoid)(object)Player.m_localPlayer) || Id == 0L) { return text; } LocalLeash.GetLinks(s_links, confirmedOnly: true); if (s_links.Count > 0) { text = text + "\n" + ((CountMisfits(out var reason) < s_links.Count) ? Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $leashme_tie") : reason); } if (CountTied() > 0) { text += Localization.instance.Localize((ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive()) ? "\n[<color=yellow><b>$KEY_AltKeys + $KEY_Use</b></color>] $leashme_untie" : "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $leashme_untie"); } return text; } public string GetHoverName() { if (!Object.op_Implicit((Object)(object)m_piece)) { return ""; } return Localization.instance.Localize(m_piece.m_name); } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (hold || !LocalHasLeash(user) || Id == 0L) { return false; } Player player = (Player)user; if (alt) { Untie(player); } else { Tie(player); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private static bool LocalHasLeash(Humanoid user) { if (Object.op_Implicit((Object)(object)user) && (Object)(object)user == (Object)(object)Player.m_localPlayer) { return LeashItem.IsEquipped(user); } return false; } private int CountTied() { long id = Id; int num = 0; foreach (LeashLink item in LeashLink.All) { if (item.PostId == id) { num++; } } return num; } private bool Fits(LeashLink link) { if (link.IsInPostReach(this)) { return LeashItem.IsStrongEnough(m_level, link.Tameable); } return false; } private int CountMisfits(out string reason) { int num = 0; string text = ""; int num2 = 0; string text2 = ""; foreach (LeashLink s_link in s_links) { if (!s_link.IsInPostReach(this)) { num2++; text2 = s_link.Tameable.GetHoverName(); } else if (!Fits(s_link)) { num++; text = s_link.Tameable.GetHoverName(); } } reason = ((num == 1) ? Localization.instance.Localize("$leashme_post_too_weak", new string[1] { text }) : ((num > 1) ? Localization.instance.Localize("$leashme_post_too_weak_many", new string[1] { num.ToString() }) : ((num2 == 1) ? Localization.instance.Localize("$leashme_post_too_far", new string[1] { text2 }) : ((num2 > 1) ? Localization.instance.Localize("$leashme_post_too_far_many", new string[1] { num2.ToString() }) : "")))); return num + num2; } private void Tie(Player player) { long id = Id; int num = CountTied(); int num2 = 0; LocalLeash.GetLinks(s_links, confirmedOnly: true); foreach (LeashLink s_link in s_links) { if (Fits(s_link)) { if (num >= 5) { num2++; continue; } s_link.RequestTie(id); num++; } } if (CountMisfits(out var reason) > 0) { ((Character)player).Message((MessageType)2, reason, 0, (Sprite)null, false); } else if (num2 > 0) { ((Character)player).Message((MessageType)2, (num2 == 1) ? "$leashme_post_no_room" : Localization.instance.Localize("$leashme_post_no_room_many", new string[1] { num2.ToString() }), 0, (Sprite)null, false); } } private void Untie(Player player) { long id = Id; bool flag = false; bool flag2 = false; foreach (LeashLink item in LeashLink.All) { if (item.PostId == id && LeashLink.CanLeash(item.Tameable, player)) { if (!LeashItem.IsStrongEnough((Humanoid)(object)player, item.Tameable)) { flag2 = true; } else if (LocalLeash.IsAtLimit(item)) { flag = true; } else { LocalLeash.Leash(item, player); } } } if (flag) { ((Character)player).Message((MessageType)2, "$leashme_limit", 0, (Sprite)null, false); } else if (flag2) { ((Character)player).Message((MessageType)2, "$leashme_too_weak", 0, (Sprite)null, false); } } } internal static class HitchingPostPiece { private const string BasePrefabName = "wood_pole_log"; private const string BundleName = "leashme"; private const string SilverPrefabName = "piece_chest_treasure"; private const string SilverMaterialName = "BlackMetalChest_silver_mat"; private const float SilverMetalColor = 0.5f; public const string WrapName = "leatherwrap"; private const string WrapModelName = "HitchingPost_LeatherWrap"; private const string HandWrapName = "LeashMe_HandWrap"; private static readonly (string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources)[] Pieces = new(string, string, int, float, string, float, Vector3, float, (string, int)[])[3] { ("LeashMe_HitchingPost", "$leashme_post", 1, 1000f, "HitchingPost_Corewood", 0.674f, Vector3.one, 0f, new(string, int)[1] { ("RoundLog", 3) }), ("LeashMe_HitchingPostSilver", "$leashme_post_silver", 2, 2000f, "HitchingPost_Silver", 0.664f, new Vector3(1.228024f, 1.051184f, 1.22486f), -0.043301f, new(string, int)[2] { ("RoundLog", 3), ("Silver", 10) }), ("LeashMe_HitchingPostBlackMetal", "$leashme_post_blackmetal", 3, 4000f, "HitchingPost_BlackMetal", 0.649f, new Vector3(1.58542f, 1.157886f, 1.57565f), -0.126443f, new(string, int)[2] { ("RoundLog", 3), ("BlackMetal", 20) }) }; private static readonly Dictionary<string, int> Levels = Pieces.ToDictionary(((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => p.Prefab, ((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => p.Level); private static readonly Dictionary<string, float> RopeHeights = Pieces.ToDictionary(((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => p.Prefab, ((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => p.RopeHeight); public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += AddPieces; } public static int GetLevel(GameObject go) { if (!Levels.TryGetValue(Utils.GetPrefabName(go), out var value)) { return 0; } return value; } public static float GetRopeHeight(GameObject go) { if (!RopeHeights.TryGetValue(Utils.GetPrefabName(go), out var value)) { return 0f; } return value; } private static void AddPieces() { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= AddPieces; AssetBundle bundle = AssetUtils.LoadAssetBundleFromResources("leashme", typeof(HitchingPostPiece).Assembly); if (!Object.op_Implicit((Object)(object)bundle)) { Logger.LogError((object)"Asset bundle not found; hitching posts not added."); return; } Dictionary<string, GameObject> dictionary = Pieces.ToDictionary(((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => p.Model, ((string Prefab, string Name, int Level, float Health, string Model, float RopeHeight, Vector3 WrapScale, float WrapY, (string Item, int Amount)[] Resources) p) => bundle.LoadAsset<GameObject>(p.Model)); GameObject val = bundle.LoadAsset<GameObject>("HitchingPost_LeatherWrap"); GameObject obj = bundle.LoadAsset<GameObject>("LeashMe_HandWrap"); object obj2; if (obj == null) { obj2 = null; } else { MeshRenderer componentInChildren = obj.GetComponentInChildren<MeshRenderer>(true); obj2 = ((componentInChildren != null) ? ((Renderer)componentInChildren).sharedMaterial : null); } Material val2 = (Material)obj2; bundle.Unload(false); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { Logger.LogWarning((object)"Hitching post leather wrap not found; posts without wrap."); } Material val3 = VanillaMaterials.Find("piece_chest_treasure", "BlackMetalChest_silver_mat"); Material blackMetal = VanillaMaterials.BlackMetal; if (dictionary.Values.Any((GameObject m) => !Object.op_Implicit((Object)(object)m)) || !Object.op_Implicit((Object)(object)blackMetal) || !Object.op_Implicit((Object)(object)val3)) { Logger.LogError((object)"Hitching post models or materials not found; hitching posts not added."); return; } val3 = new Material(val3) { name = ((Object)val3).name }; val3.SetColor("_MetalColor", new Color(0.5f, 0.5f, 0.5f, 1f)); (string, string, int, float, string, float, Vector3, float, (string, int)[])[] pieces = Pieces; for (int num = 0; num < pieces.Length; num++) { (string, string, int, float, string, float, Vector3, float, (string, int)[]) tuple = pieces[num]; PieceConfig val4 = new PieceConfig { Name = tuple.Item2, Description = "$leashme_post_desc", PieceTable = PieceTables.Hammer, CraftingStation = "piece_workbench", Requirements = ((IEnumerable<(string, int)>)tuple.Rest.Item2).Select((Func<(string, int), RequirementConfig>)(((string Item, int Amount) r) => new RequirementConfig(r.Item, r.Amount, 0, true))).ToArray() }; Sprite val5 = EmbeddedSprite.Load($"buildmenu_icon_hitchingpost{tuple.Item3}_128.png"); if (Object.op_Implicit((Object)(object)val5)) { val4.Icon = val5; } CustomPiece val6 = new CustomPiece(tuple.Item1, "wood_pole_log", val4); if (!Object.op_Implicit((Object)(object)val6.PiecePrefab)) { Logger.LogError((object)"wood_pole_log not found; hitching posts not added."); break; } val6.Piece.m_category = (PieceCategory)0; val6.Piece.m_usage = (UsageTagFlags)1; val6.Piece.m_notOnWood = true; Material head = ((tuple.Item3 == 2) ? val3 : ((tuple.Item3 == 3) ? blackMetal : null)); if (!ReplaceModel(val6.PiecePrefab, dictionary[tuple.Item5], head)) { Logger.LogError((object)"wood_pole_log has no core wood material; hitching posts not added."); break; } if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { AddWrap(val6.PiecePrefab, val, val2, tuple.Item7, tuple.Rest.Item1); } WearNTear component = val6.PiecePrefab.GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_health = tuple.Item4; } val6.PiecePrefab.AddComponent<HitchingPost>(); PieceManager.Instance.AddPiece(val6); } } private static bool ReplaceModel(GameObject prefab, GameObject model, Material head) { //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_0060: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) Transform obj = prefab.transform.Find("New"); object obj2; if (obj == null) { obj2 = null; } else { MeshRenderer componentInChildren = ((Component)obj).GetComponentInChildren<MeshRenderer>(true); obj2 = ((componentInChildren != null) ? ((Renderer)componentInChildren).sharedMaterial : null); } Material val = (Material)obj2; Transform val2 = prefab.transform.Find("collider"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { return false; } val = new Material(val) { name = ((Object)val).name }; val.SetFloat("_RippleDistance", 0f); WearNTear component = prefab.GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_snow)) { Object.DestroyImmediate((Object)(object)((Component)component.m_snow).gameObject); } int layer = ((Component)val2).gameObject.layer; string tag = ((Component)val2).tag; string[] array = new string[3] { "New", "WornBroken", "collider" }; foreach (string text in array) { Transform val3 = prefab.transform.Find(text); if (Object.op_Implicit((Object)(object)val3)) { Object.DestroyImmediate((Object)(object)((Component)val3).gameObject); } } LODGroup component2 = prefab.GetComponent<LODGroup>(); if (Object.op_Implicit((Object)(object)component2)) { Object.DestroyImmediate((Object)(object)component2); } GameObject val4 = Object.Instantiate<GameObject>(model, prefab.transform, false); ((Object)val4).name = "model"; MeshRenderer componentInChildren2 = val4.GetComponentInChildren<MeshRenderer>(); Mesh sharedMesh = val4.GetComponentInChildren<MeshFilter>().sharedMesh; ((Renderer)componentInChildren2).sharedMaterials = (Material[])(object)((!Object.op_Implicit((Object)(object)head)) ? new Material[1] { val } : new Material[2] { val, head }); Transform[] componentsInChildren = val4.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = layer; } Bounds bounds = sharedMesh.bounds; float num = Mathf.Min(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z); GameObject val5 = new GameObject("collider") { layer = layer, tag = tag }; val5.transform.SetParent(prefab.transform, false); BoxCollider obj3 = val5.AddComponent<BoxCollider>(); obj3.center = ((Bounds)(ref bounds)).center; obj3.size = new Vector3(num, ((Bounds)(ref bounds)).size.y, num); if (Object.op_Implicit((Object)(object)component)) { component.m_new = val4; component.m_worn = val4; component.m_broken = val4; component.m_snow = null; } KeepBottomSnapPoint(prefab, ((Bounds)(ref bounds)).min.y); return true; } private static void AddWrap(GameObject prefab, GameObject model, Material leather, Vector3 scale, float offsetY) { //IL_002b: 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_004b: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(model, prefab.transform, false); ((Object)val).name = "leatherwrap"; val.transform.localPosition = new Vector3(0f, offsetY, 0f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = scale; int layer = ((Component)prefab.transform.Find("model")).gameObject.layer; Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = layer; } MeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Renderer)componentsInChildren2[i]).sharedMaterial = leather; } val.SetActive(false); } private static void KeepBottomSnapPoint(GameObject prefab, float footY) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) List<Transform> list = (from t in prefab.GetComponentsInChildren<Transform>(true) where ((Component)t).CompareTag("snappoint") orderby prefab.transform.InverseTransformPoint(t.position).y select t).ToList(); foreach (Transform item in list.Skip(1)) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } if (list.Count > 0) { list[0].localPosition = new Vector3(0f, footY, 0f); } } } internal static class LeashItem { public const string PrefabName = "LeashMe_Leash"; private const string BundleName = "leashme"; private const string HandWrapName = "LeashMe_HandWrap"; private const string GroundCoilName = "LeashMe_GroundCoil"; private const string StandObjectName = "attachobj"; private const string StandCoilName = "coil"; private const string StandHangingName = "hanging"; private const string WallStandName = "itemstand"; public static readonly int PrefabHash = StringExtensionMethods.GetStableHashCode("LeashMe_Leash"); private const int MaxLevel = 3; private static readonly string[] Resources = new string[3] { "LeatherScraps", "WolfHairBundle", "LinenThread" }; private static readonly int[][] AmountsPerLevel = new int[3][] { new int[3] { 10, 5, 5 }, new int[3] { 0, 5, 0 }, new int[3] { 0, 0, 5 } }; private static readonly Dictionary<string, int> RequiredLevels = new Dictionary<string, int> { { "Boar", 1 }, { "Hen", 1 }, { "Wolf", 2 } }; private static Recipe s_recipe; public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += AddItem; } public static bool IsEquipped(Humanoid humanoid) { return IsLeash(Object.op_Implicit((Object)(object)humanoid) ? humanoid.m_leftItem : null); } public static bool IsHeld(Humanoid humanoid) { if (!IsEquipped(humanoid)) { return IsLeash(Object.op_Implicit((Object)(object)humanoid) ? humanoid.m_hiddenLeftItem : null); } return true; } public static bool IsHeld(ZDO playerZdo) { if (playerZdo.GetInt(ZDOVars.s_leftItem, 0) != PrefabHash) { return playerZdo.GetInt(ZDOVars.s_leftBackItem, 0) == PrefabHash; } return true; } public static bool IsLeash(ItemData item) { if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)item.m_dropPrefab).name == "LeashMe_Leash"; } return false; } public static bool IsStrongEnough(Humanoid humanoid, Tameable tameable) { if (IsEquipped(humanoid)) { return IsStrongEnough(humanoid.m_leftItem.m_quality, tameable); } return false; } public static bool IsStrongEnough(int level, Tameable tameable) { if (!RequiredLevels.TryGetValue(Utils.GetPrefabName(((Component)tameable).gameObject), out var value)) { value = 3; } return level >= value; } public static bool TryGetAmount(Requirement requirement, int quality, out int amount) { amount = 0; Requirement[] array = (Object.op_Implicit((Object)(object)s_recipe) ? s_recipe.m_resources : null); if (array == null) { return false; } int num = Array.IndexOf(array, requirement); if (num < 0 || num >= AmountsPerLevel.Length) { return false; } amount = AmountsPerLevel[num][Mathf.Clamp(quality, 1, 3) - 1]; return true; } private static void AddItem() { //IL_0011: 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_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= AddItem; ItemConfig val = new ItemConfig { Name = "$leashme_leash", Description = "$leashme_leash_desc", CraftingStation = "piece_workbench", MinStationLevel = 3, Requirements = (RequirementConfig[])(object)new RequirementConfig[Resources.Length] }; for (int i = 0; i < Resources.Length; i++) { val.Requirements[i] = new RequirementConfig(Resources[i], AmountsPerLevel[i][0], 1, false); } Sprite val2 = EmbeddedSprite.Load("inventory_icon_leine_128.png"); if (Object.op_Implicit((Object)(object)val2)) { val.Icons = (Sprite[])(object)new Sprite[1] { val2 }; } CustomItem val3 = new CustomItem("LeashMe_Leash", "ShieldWood", val); if (!Object.op_Implicit((Object)(object)val3.ItemPrefab)) { Logger.LogError((object)"ShieldWood prefab not found; leash item not added."); return; } SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_maxQuality = 3; shared.m_variants = 1; shared.m_useDurability = false; shared.m_canBeReparied = false; shared.m_weight = 0.5f; shared.m_movementModifier = 0f; shared.m_eitrRegenModifier = 0f; shared.m_homeItemsStaminaModifier = 0f; shared.m_heatResistanceModifier = 0f; shared.m_jumpStaminaModifier = 0f; shared.m_attackStaminaModifier = 0f; shared.m_blockStaminaModifier = 0f; shared.m_dodgeStaminaModifier = 0f; shared.m_swimStaminaModifier = 0f; shared.m_sneakStaminaModifier = 0f; shared.m_runStaminaModifier = 0f; shared.m_damageModifiers.Clear(); shared.m_equipStatusEffect = null; shared.m_setName = ""; shared.m_setSize = 0; shared.m_setStatusEffect = null; shared.m_blockPower = 0f; shared.m_blockPowerPerLevel = 0f; shared.m_deflectionForce = 0f; shared.m_deflectionForcePerLevel = 0f; shared.m_timedBlockBonus = 0f; shared.m_blockAdrenaline = 0f; shared.m_perfectBlockAdrenaline = 0f; ReplaceModels(val3.ItemPrefab); ItemManager.Instance.AddItem(val3); CustomRecipe recipe = val3.Recipe; s_recipe = ((recipe != null) ? recipe.Recipe : null); if (!Object.op_Implicit((Object)(object)s_recipe) || s_recipe.m_resources == null || s_recipe.m_resources.Length != Resources.Length) { Logger.LogWarning((object)"Leash recipe resources not as expected; upgrade costs fall back to vanilla scaling."); } } public static void OnStandVisual(ItemStand stand, int itemHash) { if (itemHash == PrefabHash && Object.op_Implicit((Object)(object)stand.m_visualItem)) { stand.m_visualItem.SetActive(true); bool flag = IsWallStand(stand); Transform val = stand.m_visualItem.transform.Find("coil"); Transform val2 = stand.m_visualItem.transform.Find("hanging"); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { ((Component)val).gameObject.SetActive(!flag); ((Component)val2).gameObject.SetActive(flag); } } } public static bool IsWallStand(ItemStand stand) { return Utils.GetPrefabName(Object.op_Implicit((Object)(object)stand.m_nview) ? ((Component)stand.m_nview).gameObject : ((Component)stand).gameObject) == "itemstand"; } private static void ReplaceModels(GameObject itemPrefab) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: 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_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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) AssetBundle val = AssetUtils.LoadAssetBundleFromResources("leashme", typeof(LeashItem).Assembly); if (!Object.op_Implicit((Object)(object)val)) { return; } GameObject val2 = val.LoadAsset<GameObject>("LeashMe_HandWrap"); GameObject val3 = val.LoadAsset<GameObject>("LeashMe_GroundCoil"); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3)) { Logger.LogError((object)"Leash models not found in asset bundle; leash keeps the shield model."); val.Unload(false); return; } int layer = itemPrefab.layer; string[] array = new string[2] { "attach", "attach_back" }; foreach (string text in array) { Transform val4 = itemPrefab.transform.Find(text); if (Object.op_Implicit((Object)(object)val4)) { if (text == "attach") { layer = ((Component)val4).gameObject.layer; } Object.DestroyImmediate((Object)(object)((Component)val4).gameObject); } } GameObject val5 = new GameObject("attach_back"); val5.transform.SetParent(itemPrefab.transform, false); val5.transform.SetSiblingIndex(0); GameObject val6 = new GameObject("attach"); val6.transform.SetParent(itemPrefab.transform, false); Transform transform = new GameObject("LeashMe_HandWrap").transform; transform.SetParent(val6.transform, false); transform.localPosition = new Vector3(0.09f, 0.03f, -0.027f); transform.localEulerAngles = new Vector3(60f, 130f, 220f); transform.localScale = Vector3.one * 1.9f; GameObject val7 = Object.Instantiate<GameObject>(val2, transform, false); MeshFilter componentInChildren = val7.GetComponentInChildren<MeshFilter>(); if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.sharedMesh)) { Transform transform2 = ((Component)componentInChildren).transform; Bounds bounds = componentInChildren.sharedMesh.bounds; Vector3 val8 = transform2.TransformPoint(((Bounds)(ref bounds)).center); val7.transform.localPosition = -transform.InverseTransformPoint(val8); } Transform transform3 = new GameObject("attachobj").transform; ((Component)transform3).gameObject.SetActive(false); transform3.SetParent(val6.transform, false); GameObject obj = Object.Instantiate<GameObject>(val3, transform3, false); ((Object)obj).name = "coil"; obj.transform.localScale = Vector3.one * 2.5f; obj.transform.localEulerAngles = new Vector3(0f, 270f, 0f); obj.transform.localPosition = new Vector3(-0.14f, 0f, -0.125f); Transform transform4 = new GameObject("hanging").transform; transform4.SetParent(transform3, false); transform4.localScale = new Vector3(1f, 1f, 1.5f); GameObject obj2 = Object.Instantiate<GameObject>(val3, transform4, false); obj2.transform.localPosition = new Vector3(-0.05f, -0.11f, -0.242f); obj2.transform.localEulerAngles = new Vector3(0f, 250f, 0f); obj2.transform.localScale = Vector3.one * 1.9f; ((Component)transform4).gameObject.SetActive(false); GameObject val9 = Object.Instantiate<GameObject>(val3, itemPrefab.transform, false); ((Object)val9).name = "LeashMe_GroundCoil"; val9.transform.localScale = Vector3.one * 2.5f; MeshFilter[] componentsInChildren = val9.GetComponentsInChildren<MeshFilter>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.AddComponent<BoxCollider>(); } Transform[] componentsInChildren2 = val9.GetComponentsInChildren<Transform>(); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Component)componentsInChildren2[i]).gameObject.layer = layer; } val6.SetActive(false); val.Unload(false); } } internal class LeashLine : MonoBehaviour { private const int Points = 12; private const float MaxSag = 1f; private const float WidthScale = 0.4f; private const float TautDistance = 12f; private const string HeadBoneName = "DEF-head"; private static readonly Color LeatherBrown = new Color(0.578f, 0.282f, 0.119f); private static LineRenderer s_template; private static Material s_material; private static bool s_templateMissing; private Tameable m_tameable; private Transform m_head; private LineRenderer m_line; public static void Attach(Tameable tameable) { LeashLine leashLine = ((Component)tameable).gameObject.AddComponent<LeashLine>(); leashLine.m_tameable = tameable; leashLine.m_head = FindHead(tameable); } private static Transform FindHead(Tameable tameable) { Character character = tameable.m_character; if (!Object.op_Implicit((Object)(object)character) || Object.op_Implicit((Object)(object)character.m_head)) { if (!Object.op_Implicit((Object)(object)character)) { return null; } return character.m_head; } return ((IEnumerable<Transform>)((Component)tameable).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-head")); } private void LateUpdate() { //IL_005b: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0098: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) Character character = m_tameable.m_character; if (!Object.op_Implicit((Object)(object)character) || !TryGetStart(out var start) || !EnsureLine()) { if (Object.op_Implicit((Object)(object)m_line)) { ((Renderer)m_line).enabled = false; } return; } Vector3 val = (Object.op_Implicit((Object)(object)m_head) ? m_head.position : character.GetCenterPoint()); float num = 1f * Mathf.Clamp01(1f - Vector3.Distance(start, val) / 12f); for (int i = 0; i < 12; i++) { float num2 = (float)i / 11f; m_line.SetPosition(i, Vector3.Lerp(start, val, num2) + Vector3.down * (num * 4f * num2 * (1f - num2))); } ((Renderer)m_line).enabled = true; } private bool TryGetStart(out Vector3 start) { //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_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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) start = Vector3.zero; long post = LeashLink.GetPost(m_tameable.m_nview); if (post != 0L) { HitchingPost hitchingPost = HitchingPost.Find(post); if (!Object.op_Implicit((Object)(object)hitchingPost)) { return false; } start = hitchingPost.RopePoint; return true; } ZDOID holder = LeashLink.GetHolder(m_tameable); GameObject val = ((((ZDOID)(ref holder)).IsNone() || !Object.op_Implicit((Object)(object)ZNetScene.instance)) ? null : ZNetScene.instance.FindInstance(holder)); Player val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Player>() : null); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)((Humanoid)val2).m_visEquipment) || !Object.op_Implicit((Object)(object)((Humanoid)val2).m_visEquipment.m_leftHand)) { return false; } start = ((Humanoid)val2).m_visEquipment.m_leftHand.position; return true; } private bool EnsureLine() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)m_line)) { return true; } LineRenderer template = GetTemplate(); if (!Object.op_Implicit((Object)(object)template)) { return false; } GameObject val = new GameObject("LeashMe_Line"); val.transform.SetParent(((Component)this).transform, false); m_line = val.AddComponent<LineRenderer>(); m_line.useWorldSpace = true; m_line.positionCount = 12; ((Renderer)m_line).sharedMaterial = GetMaterial(template); m_line.widthCurve = template.widthCurve; m_line.widthMultiplier = template.widthMultiplier * 0.4f; m_line.textureMode = template.textureMode; m_line.generateLightingData = true; m_line.alignment = template.alignment; ((Renderer)m_line).shadowCastingMode = ((Renderer)template).shadowCastingMode; return true; } private static Material GetMaterial(LineRenderer template) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)s_material)) { return s_material; } s_material = new Material(((Renderer)template).sharedMaterial) { color = LeatherBrown, mainTexture = null }; s_material.SetTexture("_BumpMap", (Texture)null); s_material.SetFloat("_Metallic", 0f); s_material.SetFloat("_Glossiness", 0.1f); return s_material; } private static LineRenderer GetTemplate() { if (Object.op_Implicit((Object)(object)s_template) || s_templateMissing || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return s_template; } s_template = (from data in ObjectDB.instance.m_StatusEffects.OfType<SE_Harpooned>().SelectMany((SE_Harpooned effect) => ((StatusEffect)effect).m_startEffects.m_effectPrefabs) where Object.op_Implicit((Object)(object)data.m_prefab) select data.m_prefab.GetComponentInChildren<LineRenderer>(true)).FirstOrDefault((Func<LineRenderer, bool>)((LineRenderer line) => Object.op_Implicit((Object)(object)line))); if (!Object.op_Implicit((Object)(object)s_template)) { s_templateMissing = true; Logger.LogWarning((object)"Harpoon line not found; leash rope is not shown."); } return s_template; } } internal class LeashLink : MonoBehaviour { private static readonly KeyValuePair<int, int> HolderKey = ZDO.GetHashZDOID("LeashMe_holder"); private static readonly int PostKey = StringExtensionMethods.GetStableHashCode("LeashMe_post"); private static readonly int PostPosKey = StringExtensionMethods.GetStableHashCode("LeashMe_postPos"); private const string RpcLeash = "LeashMe_Leash"; private const string RpcRelease = "LeashMe_Release"; private const string RpcRequestOwnership = "LeashMe_RequestOwnership"; private const string RpcTie = "LeashMe_Tie"; private const float HardLimit = 18f; private const string SpiritCallerSuffix = "_spiritcaller"; private const float LoxHardLimit = 30f; private const float CheckInterval = 1f; private const float GraceSeconds = 3f; private const float MaxDropInFront = 2f; private static readonly List<LeashLink> s_links = new List<LeashLink>(); private Tameable m_tameable; private float m_hardLimit; private float m_nextCheck; private float m_invalidSince = -1f; public Tameable Tameable => m_tameable; public static IReadOnlyList<LeashLink> All => s_links; public long PostId => GetPost(m_tameable.m_nview); public static bool IsSpiritCaller(GameObject go) { return Utils.GetPrefabName(go).EndsWith("_spiritcaller"); } public static void Attach(Tameable tameable) { if (tameable.m_nview.IsValid() && !Object.op_Implicit((Object)(object)((Component)tameable).GetComponent<LeashLink>()) && !IsSpiritCaller(((Component)tameable).gameObject)) { LeashLink leashLink = ((Component)tameable).gameObject.AddComponent<LeashLink>(); leashLink.Init(tameable); LeashLine.Attach(tameable); LocalLeash.Adopt(leashLink); } } public static ZDOID GetHolder(Tameable tameable) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!tameable.m_nview.IsValid()) { return ZDOID.None; } return tameable.m_nview.GetZDO().GetZDOID(HolderKey); } public static bool IsLeashed(ZNetView nview) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (nview.IsValid()) { ZDOID zDOID = nview.GetZDO().GetZDOID(HolderKey); return !((ZDOID)(ref zDOID)).IsNone(); } return false; } public static long GetPost(ZNetView nview) { if (!nview.IsValid()) { return 0L; } return nview.GetZDO().GetLong(PostKey, 0L); } public static bool IsTied(ZNetView nview) { return GetPost(nview) != 0; } public static bool IsBound(ZNetView nview) { if (!IsLeashed(nview)) { return IsTied(nview); } return true; } public static bool CanLeash(Tameable tameable, Player player) { //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) if (tameable.IsTamed() && Object.op_Implicit((Object)(object)tameable.m_monsterAI)) { ZDOID holder = GetHolder(tameable); if (((ZDOID)(ref holder)).IsNone()) { string text = tameable.m_nview.GetZDO().GetString(ZDOVars.s_follow, ""); if (text.Length != 0) { return text == player.GetPlayerName(); } return true; } } return false; } public void RequestLeash(Player player) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) m_tameable.m_nview.InvokeRPC("LeashMe_Leash", new object[1] { ((Character)player).GetZDOID() }); } public void RequestRelease() { m_tameable.m_nview.InvokeRPC("LeashMe_Release", Array.Empty<object>()); } public void RequestOwnership() { m_tameable.m_nview.InvokeRPC("LeashMe_RequestOwnership", Array.Empty<object>()); } public void RequestTie(long postId) { m_tameable.m_nview.InvokeRPC("LeashMe_Tie", new object[1] { postId }); } public bool IsInPostReach(HitchingPost post) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(((Component)post).transform.position, ((Component)this).transform.position) <= 18f; } public void MoveTo(Vector3 targetPos, Quaternion targetRot) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = m_tameable.m_nview; ZDO zDO = nview.GetZDO(); Vector3 exitPosition = GetExitPosition(targetPos, targetRot); nview.ResetZDO(); Object.Destroy((Object)(object)((Component)this).gameObject); ZNetScene.instance.m_instances.Remove(zDO); zDO.SetPosition(exitPosition); zDO.SetRotation(targetRot); } public void PlaceAt(Vector3 holderPos, Quaternion holderRot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) Vector3 val = GetExitPosition(holderPos, holderRot); float num = default(float); if (!ZoneSystem.instance.FindFloor(val, ref num) || num < holderPos.y - 2f) { val = holderPos + Vector3.up; } ((Component)this).transform.SetPositionAndRotation(val, holderRot); Rigidbody val2 = (Object.op_Implicit((Object)(object)m_tameable.m_character) ? m_tameable.m_character.m_body : null); if (Object.op_Implicit((Object)(object)val2)) { val2.position = val; val2.linearVelocity = Vector3.zero; } } private Vector3 GetExitPosition(Vector3 pos, Quaternion rot) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_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_0042: 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) float num = (Object.op_Implicit((Object)(object)m_tameable.m_character) ? m_tameable.m_character.GetRadius() : 0f); return pos + rot * Vector3.forward * (1f + num) + Vector3.up; } private void Init(Tameable tameable) { m_tameable = tameable; m_hardLimit = ((Utils.GetPrefabName(((Component)this).gameObject) == "Lox") ? 30f : 18f); m_tameable.m_nview.Register<ZDOID>("LeashMe_Leash", (Action<long, ZDOID>)RPC_Leash); m_tameable.m_nview.Register("LeashMe_Release", (Action<long>)RPC_Release); m_tameable.m_nview.Register("LeashMe_RequestOwnership", (Action<long>)RPC_RequestOwnership); m_tameable.m_nview.Register<long>("LeashMe_Tie", (Action<long, long>)RPC_Tie); s_links.Add(this); } private void OnDestroy() { s_links.Remove(this); } private void RPC_Leash(long sender, ZDOID holder) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!m_tameable.m_nview.IsOwner() || ((ZDOID)(ref holder)).UserID != sender) { return; } Player val = FindPlayer(holder); if (Object.op_Implicit((Object)(object)val) && CanLeash(m_tameable, val)) { ZDO zDO = m_tameable.m_nview.GetZDO(); if (IsTied(m_tameable.m_nview)) { zDO.Set(PostKey, 0L); m_tameable.m_monsterAI.SetFollowTarget((GameObject)null); } zDO.Set(HolderKey, holder); if (m_tameable.m_nview.GetZDO().GetString(ZDOVars.s_follow, "").Length == 0) { m_tameable.Command((Humanoid)(object)val, false); } } } private void RPC_Release(long sender) { //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) if (m_tameable.m_nview.IsOwner()) { ZDOID holder = GetHolder(m_tameable); if (((ZDOID)(ref holder)).UserID == sender) { Release(); } } } private void RPC_Tie(long sender, long postId) { //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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) ZDOID holder = GetHolder(m_tameable); if (m_tameable.m_nview.IsOwner() && !((ZDOID)(ref holder)).IsNone() && ((ZDOID)(ref holder)).UserID == sender && Object.op_Implicit((Object)(object)m_tameable.m_monsterAI)) { HitchingPost hitchingPost = HitchingPost.Find(postId); if (Object.op_Implicit((Object)(object)hitchingPost) && IsInPostReach(hitchingPost)) { ZDO zDO = m_tameable.m_nview.GetZDO(); zDO.Set(HolderKey, ZDOID.None); zDO.Set(PostKey, postId); zDO.Set(PostPosKey, ((Component)hitchingPost).transform.position); zDO.Set(ZDOVars.s_follow, ""); m_tameable.m_monsterAI.SetFollowTarget(((Component)hitchingPost).gameObject); ((BaseAI)m_tameable.m_monsterAI).SetPatrolPoint(((Component)hitchingPost).transform.position); m_invalidSince = -1f; } } } private void RPC_RequestOwnership(long sender) { //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) if (m_tameable.m_nview.IsOwner()) { ZDOID holder = GetHolder(m_tameable); if (((ZDOID)(ref holder)).UserID == sender) { m_tameable.m_nview.GetZDO().SetOwner(sender); } } } private void Release() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = m_tameable.m_nview.GetZDO(); zDO.Set(HolderKey, ZDOID.None); zDO.Set(PostKey, 0L); m_tameable.m_monsterAI.SetFollowTarget((GameObject)null); ((BaseAI)m_tameable.m_monsterAI).SetPatrolPoint(); zDO.Set(ZDOVars.s_follow, ""); m_invalidSince = -1f; } private void Update() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (Time.time < m_nextCheck || !m_tameable.m_nview.IsValid() || !m_tameable.m_nview.IsOwner()) { return; } m_nextCheck = Time.time + 1f; long post = GetPost(m_tameable.m_nview); if (post != 0L) { CheckPost(post); return; } GameObject val = (Object.op_Implicit((Object)(object)m_tameable.m_monsterAI) ? m_tameable.m_monsterAI.GetFollowTarget() : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.GetComponent<HitchingPost>())) { m_tameable.m_monsterAI.SetFollowTarget((GameObject)null); } ZDOID holder = GetHolder(m_tameable); Player val2 = (((ZDOID)(ref holder)).IsNone() ? null : FindPlayer(holder)); if (Object.op_Implicit((Object)(object)val2) && !LeashPortal.IsLanding(val2) && Vector3.Distance(((Component)val2).transform.position, ((Component)this).transform.position) > m_hardLimit) { Release(); } else if (((ZDOID)(ref holder)).IsNone() || IsHolderValid(val2)) { m_invalidSince = -1f; } else { ReleaseAfterGrace(); } } private void CheckPost(long postId) { //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_0025: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) Vector3 vec = m_tameable.m_nview.GetZDO().GetVec3(PostPosKey, ((Component)this).transform.position); HitchingPost hitchingPost = HitchingPost.Find(postId); if (Object.op_Implicit((Object)(object)hitchingPost)) { if (!IsInPostReach(hitchingPost)) { Release(); return; } if (Object.op_Implicit((Object)(object)m_tameable.m_monsterAI) && (Object)(object)m_tameable.m_monsterAI.GetFollowTarget() != (Object)(object)((Component)hitchingPost).gameObject) { m_tameable.m_monsterAI.SetFollowTarget(((Component)hitchingPost).gameObject); } m_invalidSince = -1f; } else if (!ZNetScene.instance.IsAreaReady(vec)) { float num = (Object.op_Implicit((Object)(object)m_tameable.m_monsterAI) ? (2f * ((BaseAI)m_tameable.m_monsterAI).m_randomMoveRange) : 0f); if (Vector3.Distance(vec, ((Component)this).transform.position) > 18f + num) { Release(); } else { m_invalidSince = -1f; } } else { ReleaseAfterGrace(); } } private void ReleaseAfterGrace() { if (m_invalidSince < 0f) { m_invalidSince = Time.time; } else if (Time.time - m_invalidSince >= 3f) { Release(); } } private static bool IsHolderValid(Player player) { if (Object.op_Implicit((Object)(object)player) && !((Character)player).IsDead()) { return LeashItem.IsHeld(((Character)player).m_nview.GetZDO()); } return false; } private static Player FindPlayer(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) GameObject val = ZNetScene.instance.FindInstance(id); if (!Object.op_Implicit((Object)(object)val)) { return null; } return val.GetComponent<Player>(); } } [BepInPlugin("de.evabs.valheim.leashme", "LeashMe", "1.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class LeashMe : BaseUnityPlugin { public const string PluginGUID = "de.evabs.valheim.leashme"; public const string PluginName = "LeashMe"; public const string PluginVersion = "1.3.1"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) AddTranslations(); LeashItem.Register(); PackSaddleItem.Register(); PackSaddleCrate.Register(); HitchingPostPiece.Register(); new Harmony("de.evabs.valheim.leashme").PatchAll(typeof(LeashPatches).Assembly); } private void Update() { LocalLeash.Update(); TamePins.Update(); } private static void AddTranslations() { CustomLocalization localization = Localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "leashme_leash", "Leash" }, { "leashme_leash_desc", "Equip in the off-hand to lead tamed animals." }, { "leashme_attach", "Leash" }, { "leashme_detach", "Unleash" }, { "leashme_too_weak", "This animal needs a stronger leash" }, { "leashme_limit", "You can't lead more than 5 animals." }, { "leashme_lost", "$1 is no longer leashed." }, { "leashme_lost_many", "$1 animals are no longer leashed." }, { "leashme_portal_too_big", "A leashed animal is too big for this portal." }, { "leashme_packsaddle", "Pack saddle" }, { "leashme_packsaddle_desc", "Use on a Lox to transport cargo. The cargo can only be accessed by the person who put the saddle on." }, { "leashme_packsaddle_ready", "is ready to carry cargo." }, { "leashme_post", "Weak Hitching Post" }, { "leashme_post_silver", "Hitching Post" }, { "leashme_post_blackmetal", "Strong Hitching Post" }, { "leashme_post_desc", "Tie up leashed animals here." }, { "leashme_tie", "Tie up" }, { "leashme_untie", "Untie all" }, { "leashme_post_too_weak", "$1 needs a stronger hitching post" }, { "leashme_post_too_weak_many", "$1 animals need a stronger hitching post" }, { "leashme_post_too_far", "$1 is too far away to be hitched to the post" }, { "leashme_post_too_far_many", "$1 animals are too far away to be hitched to the post" }, { "leashme_post_no_room", "There was no room for 1 animal" }, { "leashme_post_no_room_many", "There was no room for $1 animals" } }); CustomLocalization localization2 = Localization; text = "German"; localization2.AddTranslation(ref text, new Dictionary<string, string> { { "leashme_leash", "Leine" }, { "leashme_leash_desc", "In der Nebenhand ausrüsten, um gezähmte Tiere zu führen." }, { "leashme_attach", "Anleinen" }, { "leashme_detach", "Ableinen" }, { "leashme_too_weak", "Dieses Tier braucht eine stärkere Leine" }, { "leashme_limit", "Du kannst nicht mehr als 5 Tiere führen." }, { "leashme_lost", "$1 ist nicht mehr angeleint." }, { "leashme_lost_many", "$1 Tiere sind nicht mehr angeleint." }, { "leashme_portal_too_big", "Ein angeleintes Tier ist zu groß für dieses Portal." }, { "leashme_packsaddle", "Packsattel" }, { "leashme_packsaddle_desc", "Auf einen Lox anwenden, um Fracht zu transportieren. Nur wer den Sattel angelegt hat, kommt an die Fracht." }, { "leashme_packsaddle_ready", "ist bereit, Fracht zu tragen." }, { "leashme_post", "Schwacher Anbindepfosten" }, { "leashme_post_silver", "Anbindepfosten" }, { "leashme_post_blackmetal", "Starker Anbindepfosten" }, { "leashme_post_desc", "Hier angeleinte Tiere anbinden." }, { "leashme_tie", "Anbinden" }, { "leashme_untie", "Alle losmachen" }, { "leashme_post_too_weak", "$1 braucht einen stärkeren Anbindepfosten" }, { "leashme_post_too_weak_many", "$1 Tiere brauchen einen stärkeren Anbindepfosten" }, { "leashme_post_too_far", "$1 ist zu weit weg, um am Pfosten angebunden zu werden" }, { "leashme_post_too_far_many", "$1 Tiere sind zu weit weg, um am Pfosten angebunden zu werden" }, { "leashme_post_no_room", "Für 1 Tier war kein Platz mehr" }, { "leashme_post_no_room_many", "Für $1 Tiere war kein Platz mehr" } }); } } internal static class LeashPatches { [HarmonyPatch(typeof(Tameable), "Awake")] private static class TameableAwake { private static void Postfix(Tameable __instance) { LeashLink.Attach(__instance); PackSaddle.Attach(__instance); } } [HarmonyPatch(typeof(Tameable), "UseItem")] private static class TameableUseItem { private static bool Prefix(Tameable __instance, Humanoid user, ItemData item, ref bool __result) { if (__instance.m_nview.IsValid()) { return !PackSaddle.TryUseItem(__instance, user, item, ref __result); } return true; } } [HarmonyPatch(typeof(Tameable), "RPC_AddSaddle")] private static class TameableRpcAddSaddle { private static bool Prefix(Tameable __instance) { return PackSaddle.GetOwner(__instance.m_nview) == 0; } } [HarmonyPatch(typeof(Container), "CheckAccess")] private static class ContainerCheckAccess { private static bool Prefix(Container __instance, long playerID, ref bool __result) { return !PackSaddle.TryCheckAccess(__instance, playerID, ref __result); } } [HarmonyPatch(typeof(Tameable), "Interact")] private static class TameableInteract { private static bool Prefix(Tameable __instance, Humanoid user, bool hold, ref bool __result) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0031: 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) LeashLink component = ((Component)__instance).GetComponent<LeashLink>(); if (!LocalHasLeash(user) || !__instance.IsTamed() || !Object.op_Implicit((Object)(object)component)) { return true; } __result = false; if (hold) { return false; } Player val = (Player)user; if (LeashLink.GetHolder(__instance) == ((Character)val).GetZDOID()) { LocalLeash.Release(component); __result = true; } else if (LeashLink.CanLeash(__instance, val) && LeashItem.IsStrongEnough((Humanoid)(object)val, __instance)) { if (LocalLeash.IsAtLimit(component)) { ((Character)val).Message((MessageType)2, "$leashme_limit", 0, (Sprite)null, false); return false; } LocalLeash.Leash(component, val); __result = true; } return false; } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] private static class TameableHoverText { private static bool Prefix(Tameable __instance, ref string __result) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!LocalHasLeash((Humanoid)(object)Player.m_localPlayer) || !__instance.IsTamed() || !__instance.m_nview.IsValid() || !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<LeashLink>())) { return true; } string text = __instance.GetName(); if (Object.op_Implicit((Object)(object)__instance.m_character)) { text += Localization.instance.Localize(" ( $hud_tame, " + __instance.GetStatusString() + " )"); } Player localPlayer = Player.m_localPlayer; if (LeashLink.GetHolder(__instance) == ((Character)localPlayer).GetZDOID()) { text += Localization.instance.Localize("\n[<color=yellow><b>$KEY_Use</b></color>] $leashme_detach"); } else if (LeashLink.CanLeash(__instance, localPlayer)) { text += Localization.instance.Localize(LeashItem.IsStrongEnough((Humanoid)(object)localPlayer, __instance) ? "\n[<color=yellow><b>$KEY_Use</b></color>] $leashme_attach" : "\n$leashme_too_weak"); } __result = text; return false; } } [HarmonyPatch(typeof(Sadle), "Interact")] private static class SadleInteract { private static bool Prefix(Sadle __instance, Humanoid character, bool repeat, bool alt, ref bool __result) { Tameable linkedTameable = GetLinkedTameable(__instance); if (!Object.op_Implicit((Object)(object)linkedTameable) || alt || (!LocalHasLeash(character) && !LeashLink.IsTied(linkedTameable.m_nview))) { return true; } __result = linkedTameable.Interact(character, repeat, alt); return false; } } [HarmonyPatch(typeof(Sadle), "GetHoverText")] private static class SadleHoverText { private static bool Prefix(Sadle __instance, ref string __result) { Tameable linkedTameable = GetLinkedTameable(__instance); if (!Object.op_Implicit((Object)(object)linkedTameable)) { return true; } bool flag = LocalHasLeash((Humanoid)(object)Player.m_localPlayer); if (!flag && (!LeashLink.IsTied(linkedTameable.m_nview) || !__instance.InUseDistance((Humanoid)(object)Player.m_localPlayer))) { return true; } string text = (flag ? linkedTameable.GetHoverText() : Localization.instance.Localize(__instance.m_hoverText + "\n[<color=yellow><b>$KEY_Use</b></color>] $hud_pet")); if (__instance.InUseDistance((Humanoid)(object)Player.m_localPlayer)) { text += Localization.instance.Localize((ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive()) ? "\n[<color=yellow><b>$KEY_AltKeys + $KEY_Use</b></color>] $hud_saddle_remove" : "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $hud_saddle_remove"); } __result = text; return false; } } [HarmonyPatch(typeof(Tameable), "RPC_Command")] private static class TameableRpcCommand { private static bool Prefix(Tameable __instance, ZDOID characterID) { //IL_0010: 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_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) if (LeashLink.IsTied(__instance.m_nview)) { return false; } ZDOID holder = LeashLink.GetHolder(__instance); if (!((ZDOID)(ref holder)).IsNone()) { if (holder == characterID) { return !Object.op_Implicit((Object)(object)__instance.m_monsterAI.GetFollowTarget()); } return false; } return true; } } [HarmonyPatch(typeof(Humanoid), "HideHandItems")] private static class HumanoidHideHandItems { private static void Prefix(Humanoid __instance, bool onlyRightHand) { if (!onlyRightHand && LocalHasLeash(__instance) && IsManualHideInput(__instance)) { LocalLeash.ReleaseAll(); } } private static bool IsManualHideInput(Humanoid player) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) bool flag = !Hud.InRadial() && ZInput.GetButtonUp("JoyHide") && ZInput.GetButtonLastPressedTimer("JoyHide") < 0.33f && !ZInput.GetButton("JoyAltKeys") && !((Character)player).InPlaceMode(); if ((int)ZInput.InputLayout != 0 && ZInput.IsGamepadActive()) { return flag; } return ZInput.GetButtonDown("Hide") || flag; } } [HarmonyPatch(typeof(Humanoid), "GetCurrentBlocker")] private static class HumanoidCurrentBlocker { private static bool Prefix(Humanoid __instance, ref ItemData __result) { if (!LeashItem.IsEquipped(__instance)) { return true; } __result = __instance.GetCurrentWeapon(); return false; } } [HarmonyPatch(typeof(Humanoid), "SetupAnimationState")] private static class HumanoidSetupAnimationState { private static bool Prefix(Humanoid __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!LeashItem.IsEquipped(__instance)) { return true; } ItemData val = __instance.m_rightItem ?? (Object.op_Implicit((Object)(object)__instance.m_unarmedWeapon) ? __instance.m_unarmedWeapon.m_itemData : null); if (val != null) { __instance.SetAnimationState(val.m_shared.m_animationState); } return false; } } [HarmonyPatch(typeof(Player), "SetControls")] private static class PlayerSetControls { private static Player s_player; private static Vector3 s_unlimited; private static void Prefix(Player __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)(object)s_player) { ((Character)__instance).m_moveDir = s_unlimited; } } private static void Postfix(Player __instance) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Vector3 moveDir = ((Character)__instance).m_moveDir; Vector3 val = LocalLeash.LimitMove(__instance, moveDir); s_player = ((val != moveDir) ? __instance : null); s_unlimited = moveDir; ((Character)__instance).m_moveDir = val; } } [HarmonyPatch(typeof(Player), "Dodge")] private static class PlayerDodge { private static bool Prefix(Player __instance, ref Vector3 dodgeDir) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) Vector3 val = LocalLeash.LimitMove(__instance, dodgeDir); if (val == dodgeDir) { return true; } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { return false; } dodgeDir = ((Vector3)(ref val)).normalized; return true; } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] private static class TeleportWorldTeleport { private static void Prefix(TeleportWorld __instance) { LeashPortal.CurrentPortal = __instance; } private static void Finalizer() { LeashPortal.CurrentPortal = null; } } [HarmonyPatch(typeof(Player), "TeleportTo")] private static class PlayerTeleportTo { private static bool Prefix(Player __instance, ref bool __result) { TeleportWorld currentPortal = LeashPortal.CurrentPortal; if (!Object.op_Implicit((Object)(object)currentPortal) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsTeleporting() || !LeashPortal.IsBlocked(currentPortal)) { return true; } ((Character)__instance).Message((MessageType)2, "$leashme_portal_too_big", 0, (Sprite)null, false); __result = false; return false; } private static void Postfix(Player __instance, bool __result) { if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { LeashPortal.OnTeleportStarted(Object.op_Implicit((Object)(object)LeashPortal.CurrentPortal)); } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] private static class PlayerUpdateTeleport { private static void Postfix(Player __instance) { LeashPortal.OnUpdateTeleport(__instance); } } [HarmonyPatch(typeof(ArmorStand), "CanAttach")] private static class ArmorStandCanAttach { private static bool Prefix(ItemData item, ref bool __result) { if (!LeashItem.IsLeash(item) && !PackSaddleItem.IsPackSaddle(item)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ItemStand), "CanAttach")] private static class ItemStandCanAttach { private static bool Prefix(ItemStand __instance, ItemData item, ref bool __result) { if (!PackSaddleItem.IsPackSaddle(item) || !LeashItem.IsWallStand(__instance)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ItemStand), "SetVisualItem")] private static class ItemStandSetVisualItem { private static void Prefix(ItemStand __instance, out GameObject __state) { __state = __instance.m_visualItem; } private static void Postfix(ItemStand __instance, int itemHash, GameObject __state) { if ((Object)(object)__instance.m_visualItem != (Object)(object)__state) { LeashItem.OnStandVisual(__instance, itemHash); } } } [HarmonyPatch(typeof(Requirement), "GetAmount")] private static class RequirementGetAmount { private static bool Prefix(Requirement __instance, int qualityLevel, ref int __result) { return !LeashItem.TryGetAmount(__instance, qualityLevel, out __result); } } [HarmonyPatch(typeof(Minimap), "Start")] private static class MinimapStart { private static void Postfix(Minimap __instance) { PawMarker.Register(__instance); PlayerMarkerOrder.Apply(__instance); } } [HarmonyPatch(typeof(Minimap), "GetSprite")] private static class MinimapGetSprite { private static bool Prefix(PinType type, ref Sprite __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (type != PawMarker.PawType) { return true; } __result = PawMarker.GetIcon(); return false; } } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] private static class MonsterAIUpdateTarget { private static void Postfix(MonsterAI __instance, ref bool canHearTarget, ref bool canSeeTarget) { if (LeashLink.IsBound(((BaseAI)__instance).m_nview)) { __instance.m_targetCreature = null; __instance.m_targetStatic = null; __instance.m_timeSinceAttacking = 0f; canHearTarget = false; canSeeTarget = false; } } } [HarmonyPatch(typeof(BaseAI), "Follow")] private static class BaseAIFollow { private const float VanillaStopDistance = 3f; private static bool Prefix(BaseAI __instance, GameObject go) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!LeashLink.IsBound(__instance.m_nview)) { return true; } float num = 3f + __instance.m_character.GetRadius(); if (Vector3.Distance(go.transform.position, ((Component)__instance).transform.position) >= num) { return true; } __instance.StopMoving(); return false; } } private static bool LocalHasLeash(Humanoid user) { if (Object.op_Implicit((Object)(object)user) && (Object)(object)user == (Object)(object)Player.m_localPlayer) { return LeashItem.IsEquipped(user); } return false; } private static Tameable GetLinkedTameable(Sadle sadle) { Tameable tameable = sadle.GetTameable(); if (!Object.op_Implicit((Object)(object)tameable) || !Object.op_Implicit((Object)(object)((Component)tameable).GetComponent<LeashLink>())) { return null; } return tameable; } } internal static class LeashPortal { private const string SmallPortal = "portal_wood"; private static readonly HashSet<string> LargeCreatures = new HashSet<string> { "Lox", "Asksvin", "Moose" }; private const float JumpTime = 2f; private static readonly List<LeashLink> s_links = new List<LeashLink>(); public static TeleportWorld CurrentPortal; private static bool s_transportPending; private static bool s_arrivalPending; public static bool IsBlocked(TeleportWorld portal) { if (Utils.GetPrefabName(((Component)portal).gameObject) != "portal_wood") { return false; } LocalLeash.GetLinks(s_links, confirmedOnly: false); foreach (LeashLink s_link in s_links) { if (LargeCreatures.Contains(Utils.GetPrefabName(((Component)s_link).gameObject))) { return true; } } return false; } public static void OnTeleportStarted(bool viaPortal) { s_transportPending = viaPortal; s_arrivalPending = false; if (!viaPortal) { return; } LocalLeash.GetLinks(s_links, confirmedOnly: true); foreach (LeashLink s_link in s_links) { s_link.RequestOwnership(); } } public static bool IsLanding(Player holder) { if (s_arrivalPending && (Object)(object)holder == (Object)(object)Player.m_localPlayer) { return holder.m_teleporting; } return false; } public static void OnUpdateTeleport(Player player) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } if (s_arrivalPending && !player.m_teleporting) { s_arrivalPending = false; LocalLeash.GetLinks(s_links, confirmedOnly: true); foreach (LeashLink s_link in s_links) { if (s_link.Tameable.m_nview.IsOwner()) { s_link.PlaceAt(((Component)player).transform.position, ((Component)player).transform.rotation); } } } if (!s_transportPending || !player.m_teleporting || player.m_teleportTimer <= 2f) { return; } s_transportPending = false; s_arrivalPending = true; LocalLeash.GetLinks(s_links, confirmedOnly: true); foreach (LeashLink s_link2 in s_links) { if (s_link2.Tameable.m_nview.IsOwner()) { s_link2.MoveTo(player.m_teleportTargetPos, player.m_teleportTargetRot); } else { LocalLeash.ReleaseLost(s_link2); } } } } internal static class LocalLeash { private class Handle { public LeashLink Link; public float RequestedAt; public bool Confirmed; } private const int MaxLinks = 5; private const float PendingTimeout = 5f; private const float SoftLimit = 12f; private const float LostMessageSeconds = 4f; private static readonly List<Handle> s_handles = new List<Handle>(); private static readonly List<Vector3> s_aways = new List<Vector3>(); private static int s_lostCount; private static float s_lostAt = float.MinValue; public static bool IsAtLimit(LeashLink link) { if (Find(link) == null) { return s_handles.Count >= 5; } return false; } public static Vector3 LimitMove(Player player, Vector3 dir) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)Player.m_localPlayer) { return dir; } List<Vector3> list = s_aways; list.Clear(); foreach (Handle s_handle in s_handles) { if (s_handle.Confirmed && Object.op_Implicit((Object)(object)s_handle.Link)) { Vector3 val = ((Component)player).transform.position - ((Component)s_handle.Link).transform.position; if (((Vector3)(ref val)).magnitude >= 12f) { val.y = 0f; list.Add(((Vector3)(ref val)).normalized); } } } if (list.Count == 0 || IsAllowed(dir, list)) { return dir; } Vector3 result = Vector3.zero; foreach (Vector3 item in list) { Vector3 val2 = dir - item * Vector3.Dot(dir, item); if (((Vector3)(ref val2)).sqrMagnitude > ((Vector3)(ref result)).sqrMagnitude && IsAllowed(val2, list)) { result = val2; } } return result; } private static bool IsAllowed(Vector3 dir, List<Vector3> aways) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) foreach (Vector3 away in aways) { if (Vector3.Dot(dir, away) > 0.001f) { return false; } } return true; } public static void Leash(LeashLink link, Player player) { Handle handle = Find(link); if (handle == null) { handle = new Handle { Link = link }; s_handles.Add(handle); } handle.RequestedAt = Time.time; handle.Confirmed = false; link.RequestLeash(player); } public static void Release(LeashLink link) { link.RequestRelease(); Handle handle = Find(link); if (handle != null) { if (handle.Confirmed) { PlaySound(Player.m_localPlayer); } s_handles.Remove(handle); } } public static void ReleaseAll() { for (int num = s_handles.Count - 1; num >= 0; num--) { LeashLink link = s_handles[num].Link; if (Object.op_Implicit((Object)(object)link)) { Release(link); } else { s_handles.RemoveAt(num); } } } public static void ReleaseLost(LeashLink link) { Release(link); if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ShowLost(Player.m_localPlayer, link.Tameable.GetHoverName()); } } public static void GetLinks(List<LeashLink> result, bool confirmedOnly) { result.Clear(); foreach (Handle s_handle in s_handles) { if (Object.op_Implicit((Object)(object)s_handle.Link) && s_handle.Link.Tameable.m_nview.IsValid() && (s_handle.Confirmed || !confirmedOnly)) { result.Add(s_handle.Link); } } } public static void Adopt(LeashLink link) { //IL_001c: 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) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Find(link) == null && !(LeashLink.GetHolder(link.Tameable) != ((Character)localPlayer).GetZDOID())) { s_handles.RemoveAll((Handle h) => !Object.op_Implicit((Object)(object)h.Link) || !h.Link.Tameable.m_nview.IsValid()); s_handles.Add(new Handle { Link = link, RequestedAt = Time.time, Confirmed = true }); } } private static Handle Find(LeashLink link) { foreach (Handle s_handle in s_handles) { if ((Object)(object)s_handle.Link == (Object)(object)link) { return s_handle; } } return null; } private static void ShowLost(Player player, string name) { s_lostCount = ((Time.time - s_lostAt > 4f) ? 1 : (s_lostCount + 1)); s_lostAt = Time.time; string text = ((s_lostCount == 1) ? Localization.instance.Localize("$leashme_lost", new string[1] { name }) : Localization.instance.Localize("$leashme_lost_many", new string[1] { s_lostCount.ToString() })); ((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false); } private static void PlaySound(Player player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)player)) { ((Humanoid)player).m_pickupEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID()); } } public static void Update() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (s_handles.Count == 0) { return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { s_handles.Clear(); return; } bool flag = false; for (int num = s_handles.Count - 1; num >= 0; num--) { Handle handle = s_handles[num]; if (!Object.op_Implicit((Object)(object)handle.Link) || !handle.Link.Tameable.m_nview.IsValid()) { s_handles.RemoveAt(num); } else if (LeashLink.GetHolder(handle.Link.Tameable) == ((Character)localPlayer).GetZDOID()) { if (!handle.Confirmed) { handle.Confirmed = true; PlaySound(localPlayer); } flag = true; } else if (handle.Confirmed) { s_handles.RemoveAt(num); if (!LeashLink.IsTied(handle.Link.Tameable.m_nview)) { ShowLost(localPlayer, handle.Link.Tameable.GetHoverName()); } PlaySound(localPlayer); } else if (Time.time - handle.RequestedAt > 5f) { Release(handle.Link); } } if (flag) { if (!LeashItem.IsHeld((Humanoid)(object)localPlayer) || ((Character)localPlayer).IsDead()) { ReleaseAll(); } else if (!LeashItem.IsEquipped((Humanoid)(object)localPlayer) && IsAutoHideOver(localPlayer)) { ((Humanoid)localPlayer).ShowHandItems(false, true); } } } private static bool IsAutoHideOver(Player player) { if (!((Character)player).IsSwimming() && !((Character)player).IsAttached() && !Object.op_Implicit((Object)(object)player.GetCurrentCraftingStation()) && ((Character)player).TakeInput() && !((Character)player).InAttack()) { return !((Character)player).InDodge(); } return false; } } internal class MaterialTestCommand : ConsoleCommand { private static readonly string[] Placeholders = new string[4] { "crate_wood", "linen", "linen_dark", "leash_leather" }; private static readonly Dictionary<Material, Material> Backups = new Dictionary<Material, Material>(); public override string Name => "leashme_mat"; public override string Help => "leashme_mat <placeholder> <prefab> [material] | <placeholder> reset"; public static void Register() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new MaterialTestCommand()); } public override void Run(string[] args) { //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_058f: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Expected O, but got Unknown if (args.Length == 0) { Print("Placeholders: " + string.Join(", ", Placeholders)); return; } if (args[0] == "find" && args.Length == 2) { List<string> list = (from m in Resources.FindObjectsOfTypeAll<Material>() where ((Object)m).name.IndexOf(args[1], StringComparison.OrdinalIgnoreCase) >= 0 group m by ((Object)m).name + " [" + ((Object)m.shader).name + "]" into g select $"{g.Key} x{g.Count()}").ToList(); Console instance = Console.instance; if (instance != null) { ((Terminal)instance).AddString($"find {args[1]}: {list.Count} materials, see BepInEx log."); } Logger.LogInfo((object)("find " + args[1] + ": " + string.Join(", ", list))); return; } List<Material> list2 = (from m in Resources.FindObjectsOfTypeAll<Material>() where ((Object)m).name == args[0] || ((Object)m).name.StartsWith(args[0] + " ") where !Backups.ContainsValue(m) select m).ToList(); if (list2.Count == 0) { Print("No loaded material '" + args[0] + "'."); return; } if (args.Length == 4 && args[1] == "set") { if (!float.TryParse(args[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { Print("Not a number: '" + args[3] + "'."); return; } foreach (Material item in list2) { item.SetFloat(args[2], result); } Print($"{args[0]}: {args[2]} = {result} ({list2.Count} materials, property known: {list2[0].HasProperty(args[2])})."); return; } if (args.Length == 5 && args[1] == "color") { float[] array = new float[3]; for (int num = 0; num < 3; num++) { if (!float.TryParse(args[2 + num], NumberStyles.Float, CultureInfo.InvariantCulture, out array[num])) { Print("Not a number: '" + args[2 + num] + "'."); return; } } foreach (Material item2 in list2) { item2.SetColor("_Color", new Color(array[0], array[1], array[2], 1f)); } Print($"{args[0]}: _Color = {array[0]} {array[1]} {array[2]} ({list2.Count} materials)."); return; } if (args.Length == 2 && args[1] == "reset") { foreach (Material item3 in list2.Where(Backups.ContainsKey)) { Copy(Backups[item3], item3); } Print($"{args[0]}: reset ({list2.Count} materials)."); return; } if (args.Length < 2) { Print(((ConsoleCommand)this).Help); return; } GameObject prefab = PrefabManager.Instance.GetPrefab(args[1]); if (!Object.op_Implicit((Object)(object)prefab)) { Print("No prefab '" + args[1] + "'."); return; } List<Material> source = (from m in prefab.GetComponentsInChildren<Renderer>(true).SelectMany((Renderer r) => r.sharedMaterials) where Object.op_Implicit((Object)(object)m) select m).Distinct().ToList(); if (args.Length == 2) { Print(args[1] + ": " + string.Join(", ", source.Select((Material m) => ((Object)m).name + " [" + ((Object)m.shader).name + "]"))); return; } Material val = ((IEnumerable<Material>)source).FirstOrDefault((Func<Material, bool>)((Material m) => ((Object)m).name == args[2])); if (!Object.op_Implicit((Object)(object)val)) { Print(args[1] + " has no material '" + args[2] + "'."); return; } foreach (Material item4 in list2) { if (!Backups.ContainsKey(item4)) { Backups[item4] = new Material(item4) { name = ((Object)item4).name + "_backup" }; } Copy(val, item4); } Print($"{args[0]}: {args[1]}/{args[2]} [{((Object)val.shader).name}] ({list2.Count} materials)."); } private static void Print(string text) { Console instance = Console.instance; if (instance != null) { ((Terminal)instance).AddString(text); } Logger.LogInfo((object)text); } private static void Copy(Material source, Material target) { string name = ((Object)target).name; target.shader = source.shader; target.CopyPropertiesFromMaterial(source); target.shaderKeywords = source.shaderKeywords; target.renderQueue = source.renderQueue; ((Object)target).name = name; } } internal class PackSaddle : MonoBehaviour { private const string LoxPrefabName = "Lox"; private const string BundleName = "leashme"; private const string VisualName = "LoxPackVisual"; private const string RpcAdd = "LeashMe_AddPack"; private const string RpcRemove = "LeashMe_RemovePack"; private const string MountBoneName = "Mount"; private const string ChestPrefabName = "piece_chest"; private const float SinkDepth = 0.1f; private const string LeftTop = "Cargo_Left_Top"; private const string RightTop = "Cargo_Right_Top"; private const string LeftBottom = "Cargo_Left_Bottom"; private const string RightBottom = "Cargo_Right_Bottom"; private const string Bedroll = "Cargo_Bedroll"; private static readonly int OwnerKey = StringExtensionMethods.GetStableHashCode("LeashMe_packOwner"); private static GameObject s_visualPrefab; private static bool s_visualMissing; private Tameable m_tameable; private Container m_container; private GameObject m_holder; private GameObject m_bottomLeft; private GameObject m_bottomRight; private GameObject m_bedroll; private bool m_shown; public Tameable Tameable => m_tameable; public static long LocalPlayerId { get { if (!Object.op_Implicit((Object)(object)Game.instance)) { return 0L; } return Game.instance.GetPlayerProfile().GetPlayerID(); } } public bool IsLocalOwner => GetOwner(m_tameable.m_nview) == LocalPlayerId; public bool IsCargoEmpty { get { if (Object.op_Implicit((Object)(object)m_container)) { return m_container.GetInventory().NrOfItems() == 0; } return true; } } public static void Attach(Tameable tameable) { if (tameable.m_nview.IsValid() && Utils.GetPrefabName(((Component)tameable).gameObject) == "Lox" && !Object.op_Implicit((Object)(object)((Component)tameable).GetComponent<PackSaddle>())) { ((Component)tameable).gameObject.AddComponent<PackSaddle>().Init(tameable); } } public static long GetOwner(ZNetView nview) { if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid()) { return 0L; } return nview.GetZDO().GetLong(OwnerKey, 0L); } public string GetCargoHoverText() { if (!Object.op_Implicit((Object)(object)m_container)) { return Localization.instance.Localize("$leashme_packsaddle"); } return m_container.GetHoverText(); } public bool OpenCargo(Humanoid user) { if (Object.op_Implicit((Object)(object)m_container)) { return m_container.Interact(user, false, false); } return false; } public static bool TryCheckAccess(Container container, long playerId, ref bool result) { PackSaddle packSaddle = (Object.op_Implicit((Object)(object)container.m_nview) ? ((Component)container.m_nview).GetComponent<PackSaddle>() : null); if (!Object.op_Implicit((Object)(object)packSaddle) || (Object)(object)packSaddle.m_container != (Object)(object)container) { return false; } result = playerId != 0L && GetOwner(container.m_nview) == playerId; return true; } public static bool TryUseItem(Tameable tameable, Humanoid user, ItemData item, ref bool result) { PackSaddle component = ((Component)tameable).GetComponent<PackSaddle>(); if (PackSaddleItem.IsPackSaddle(item)) { if (!Object.op_Implicit((Object)(object)component) || !tameable.IsTamed()) { return false; } result = true; if (tameable.HaveSaddle() || GetOwner(tameable.m_nview) != 0L) { ((Character)user).Message((MessageType)2, tameable.GetHoverName() + " $hud_saddle_already", 0, (Sprite)null, false); return true; } tameable.m_nview.InvokeRPC("LeashMe_AddPack", new object[1] { LocalPlayerId }); user.GetInventory().RemoveOneItem(item); ((Character)user).Message((MessageType)2, tameable.GetHoverName() + " $leashme_packsaddle_ready", 0, (Sprite)null, false); return true; } if (Object.op_Implicit((Object)(object)component) && IsVanillaSaddle(tameable, item) && GetOwner(tameable.m_nview) != 0L) { result = true; ((Character)user).Message((MessageType)2, tameable.GetHoverName() + " $hud_saddle_already", 0, (Sprite)null, false); return true; } return false; } public static bool IsVanillaSaddle(Tameable tameable, ItemData item) { if (item != null && Object.op_Implicit((Object)(object)tameable.m_saddleItem)) { return item.m_shared.m_name == tameable.m_saddleItem.m_itemData.m_shared.m_name; } return false; } public void RequestRemove(Humanoid user) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) m_tameable.m_nview.InvokeRPC("LeashMe_RemovePack", new object[2] { LocalPlayerId, ((Component)user).transform.position }); } private void Init(Tameable tameable) { m_tameable = tameable; m_tameable.m_nview.Register<long>("LeashMe_AddPack", (Action<long, long>)RPC_Add); m_tameable.m_nview.Register<long, Vector3>("LeashMe_RemovePack", (Action<long, long, Vector3>)RPC_Remove); Character component = ((Component)this).GetComponent<Character>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDeath = (Action)Delegate.Combine(component.m_onDeath, new Action(OnDeath)); } BuildVisual(); UpdateShown(); } private void RPC_Add(long sender, long playerId) { if (m_tameable.m_nview.IsOwner() && !m_tameable.HaveSaddle() && GetOwner(m_tameable.m_nview) == 0L) { m_tameable.m_nview.GetZDO().Set(OwnerKey, playerId); } } private void RPC_Remove(long sender, long playerId, Vector3 userPoint) { //IL_0074: 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_0080: Unknown result type (might be due to invalid IL or missing references) if (m_tameable.m_nview.IsOwner() && playerId != 0L && GetOwner(m_tameable.m_nview) == playerId && Object.op_Implicit((Object)(object)PackSaddleItem.Prefab)) { if (Object.op_Implicit((Object)(object)m_container)) { m_container.Load(); } if (IsCargoEmpty) { m_tameable.m_nview.GetZDO().Set(OwnerKey, 0L); SpawnItem(userPoint - ((Component)this).transform.position); } } } private void OnDeath() { //IL_005b: 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_00ac: Unknown result type (might be due to invalid IL or missing references) if (!m_tameable.m_nview.IsValid() || !m_tameable.m_nview.IsOwner() || GetOwner(m_tameable.m_nview) == 0L) { return; } if (Object.op_Implicit((Object)(object)m_container)) { ((Component)m_container).transform.position = ((Component)this).transform.TransformPoint(m_tameable.m_dropSaddleOffset); m_container.Load(); if (Object.op_Implicit((Object)(object)PackSaddleCrate.Prefab)) { m_container.DropAllItems(PackSaddleCrate.Prefab); } else { m_container.DropAllItems(); } } if (Object.op_Implicit((Object)(object)PackSaddleItem.Prefab)) { SpawnItem(Vector3.zero); } } private void SpawnItem(Vector3 flyDirection) { //IL_0011: 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_0033: Unknown