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 Carturs Feeding Trough v1.0.0
plugins/CarturFeedingTrough/CarturFeedingTrough.dll
Decompiled 12 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CarturFeedingTrough")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b2d0d9427f966cbdbec853bc8585dee492058655")] [assembly: AssemblyProduct("CarturFeedingTrough")] [assembly: AssemblyTitle("CarturFeedingTrough")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CarturFeedingTrough { internal static class MeshBlob { private static string AssetDir => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "assets"); internal static Mesh LoadMesh(string fileName) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown string text = Path.Combine(AssetDir, fileName); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("missing " + text)); return null; } using BinaryReader binaryReader = new BinaryReader(File.OpenRead(text)); if (new string(binaryReader.ReadChars(4)) != "CTM1") { Plugin.Log.LogWarning((object)(fileName + " is not a CTM1 blob")); return null; } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); Vector3[] array = (Vector3[])(object)new Vector3[num]; for (int i = 0; i < num; i++) { array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; for (int j = 0; j < num; j++) { array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } Vector2[] array3 = (Vector2[])(object)new Vector2[num]; for (int k = 0; k < num; k++) { array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); } int[] array4 = new int[num2]; for (int l = 0; l < num2; l++) { array4[l] = binaryReader.ReadInt32(); } Mesh val = new Mesh { name = Path.GetFileNameWithoutExtension(fileName), vertices = array, normals = array2, uv = array3, triangles = array4 }; val.RecalculateTangents(); val.RecalculateBounds(); return val; } internal static Texture2D LoadTexture(string fileName, bool linear) { //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) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown string text = Path.Combine(AssetDir, fileName); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("missing " + text)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear) { name = Path.GetFileNameWithoutExtension(fileName), wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; if (LoadImageViaReflection(val, File.ReadAllBytes(text))) { return val; } Plugin.Log.LogWarning((object)("ImageConversion.LoadImage failed for " + text)); return null; } private static bool LoadImageViaReflection(Texture2D tex, byte[] data) { Type type = AccessTools.TypeByName("UnityEngine.ImageConversion"); if (type == null) { return false; } MethodInfo methodInfo = null; MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo2 in methods) { if (!(methodInfo2.Name != "LoadImage")) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 3 && parameters[1].ParameterType == typeof(byte[])) { methodInfo = methodInfo2; break; } } } if (methodInfo == null) { return false; } object obj = methodInfo.Invoke(null, new object[3] { tex, data, false }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } [BepInPlugin("cartur.feedingtrough", "Cartur's Feeding Trough", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "cartur.feedingtrough"; public const string PluginName = "Cartur's Feeding Trough"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { _harmony = new Harmony("cartur.feedingtrough"); _harmony.PatchAll(typeof(Plugin).Assembly); TroughPiece.Register(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"loaded"); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"failed to load, game continues without it: {arg}"); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] internal static class TameTimer { private static void Postfix(Tameable __instance, ref string __result) { if (string.IsNullOrEmpty(__result) || __instance.IsTamed()) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO != null) { float num = zDO.GetFloat(ZDOVars.s_tameTimeLeft, __instance.m_tamingTime); if (!(num <= 0f) && !(num >= __instance.m_tamingTime)) { __result = __result + "\n" + Format(num) + " left"; } } } private static string Format(float seconds) { int num = Mathf.CeilToInt(seconds); int num2 = num / 60; int num3 = num % 60; if (num2 <= 0) { return $"{num3}s"; } return $"{num2}m {num3}s"; } } [HarmonyPatch(typeof(EnemyHud), "ShowHud")] internal static class TamingBarPatch { private static readonly FieldInfo HudsField = AccessTools.Field(typeof(EnemyHud), "m_huds"); private static readonly FieldInfo GuiField = AccessTools.Field(AccessTools.Inner(typeof(EnemyHud), "HudData"), "m_gui"); internal static readonly FieldInfo HoverTimerField = AccessTools.Field(AccessTools.Inner(typeof(EnemyHud), "HudData"), "m_hoverTimer"); private static bool s_reported; private static void Postfix(EnemyHud __instance, Character c) { if ((Object)(object)c == (Object)null) { return; } if (HudsField == null || GuiField == null) { Report($"cannot reach EnemyHud internals (m_huds={HudsField != null}, " + $"HudData.m_gui={GuiField != null}) - no taming bar this session"); return; } Tameable component = ((Component)c).GetComponent<Tameable>(); if ((Object)(object)component == (Object)null) { return; } try { object obj = (HudsField.GetValue(__instance) as IDictionary)?[c]; object? value = GuiField.GetValue(obj); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { Report("no hud object for " + ((Object)c).name + " - taming bar not added"); } else if (!((Object)(object)val.GetComponent<TamingBar>() != (Object)null)) { val.AddComponent<TamingBar>().Bind(component, obj); Report("taming bar attached to " + ((Object)c).name + "'s hud"); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"could not add the taming bar, health bar is unaffected: {arg}"); } } private static void Report(string message) { if (!s_reported) { s_reported = true; Plugin.Log.LogInfo((object)message); } } } internal class TamingBar : MonoBehaviour { private const float Gap = 2f; private static readonly Color Yellow = new Color(0.95f, 0.82f, 0.25f, 1f); private static bool s_said; private static bool s_saidHidden; private Tameable _tameable; private GuiBar _bar; private GameObject _root; private bool _built; private object _hudData; private static void Say(string message) { if (!s_said) { s_said = true; Plugin.Log.LogInfo((object)message); } } internal void Bind(Tameable tameable, object hudData) { _tameable = tameable; _hudData = hudData; } private void HoldHudOpen() { if (_hudData != null && !(TamingBarPatch.HoverTimerField == null)) { TamingBarPatch.HoverTimerField.SetValue(_hudData, 0f); } } private void Build() { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_0278: 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_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) _built = true; Transform obj = ((Component)this).transform.Find("Health"); RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null); if ((Object)(object)val == (Object)null) { Say("hud has no 'Health' child - EnemyHud layout changed, no taming bar"); return; } _root = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Transform)val).parent); ((Object)_root).name = "CarturTaming"; Transform transform = _root.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val2 == (Object)null) { return; } Transform val3 = ((Transform)val2).Find("health_fast"); Transform val4 = ((Transform)val2).Find("health_fast_friendly"); Transform val5 = PickBar(val3) ?? PickBar(val4); _bar = (((Object)(object)val5 == (Object)null) ? null : ((Component)val5).GetComponent<GuiBar>()); if ((Object)(object)_bar == (Object)null) { Say("cloned hud has no usable GuiBar - no taming bar"); Object.Destroy((Object)(object)_root); return; } ((Component)val5).gameObject.SetActive(true); Strip((Transform)(object)val2, "health_slow"); Strip((Transform)(object)val2, "HealthText"); if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val5) { Object.Destroy((Object)(object)((Component)val3).gameObject); } if ((Object)(object)val4 != (Object)null && (Object)(object)val4 != (Object)(object)val5) { Object.Destroy((Object)(object)((Component)val4).gameObject); } Rect rect = val.rect; float height = ((Rect)(ref rect)).height; rect = ((RectTransform)val3).rect; float num = Mathf.Max(height, ((Rect)(ref rect)).height); if (num <= 0f) { num = 10f; } val2.anchoredPosition = val.anchoredPosition - new Vector2(0f, num + 2f); StringBuilder stringBuilder = new StringBuilder(); rect = val.rect; stringBuilder.Append($"taming bar built: Health rect={((Rect)(ref rect)).size} anchored={val.anchoredPosition} " + $"drop={num + 2f} -> taming anchored={val2.anchoredPosition}\n"); stringBuilder.Append(" hud root children: "); for (int i = 0; i < ((Component)this).transform.childCount; i++) { stringBuilder.Append(((Object)((Component)this).transform.GetChild(i)).name).Append(" "); } stringBuilder.Append("\n taming bar contents:\n"); RectTransform[] componentsInChildren = _root.GetComponentsInChildren<RectTransform>(true); foreach (RectTransform val6 in componentsInChildren) { string name = ((Object)val6).name; rect = val6.rect; stringBuilder.Append($" {name} size={((Rect)(ref rect)).size} pos={val6.anchoredPosition} " + $"active={((Component)val6).gameObject.activeSelf} img={(Object)(object)((Component)val6).GetComponent<Image>() != (Object)null}\n"); } Say(stringBuilder.ToString()); _bar.SetMaxValue(1f); _bar.SetColor(Yellow); _root.SetActive(false); } private static Transform PickBar(Transform t) { if (!((Object)(object)t != (Object)null) || !((Object)(object)((Component)t).GetComponent<GuiBar>() != (Object)null)) { return null; } return t; } private static void Strip(Transform parent, string childName) { Transform val = parent.Find(childName); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } private void Update() { if (!_built) { Build(); } if ((Object)(object)_root == (Object)null || (Object)(object)_bar == (Object)null) { return; } float num = Progress(); if (num < 0f) { if (_root.activeSelf) { _root.SetActive(false); } return; } if (!_root.activeSelf) { _root.SetActive(true); } _bar.SetValue(num); HoldHudOpen(); } private float Progress() { if ((Object)(object)_tameable == (Object)null || _tameable.IsTamed()) { return -1f; } ZNetView component = ((Component)_tameable).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null || _tameable.m_tamingTime <= 0f) { return -1f; } float num = val.GetFloat(ZDOVars.s_tameTimeLeft, _tameable.m_tamingTime); if (num >= _tameable.m_tamingTime) { return -1f; } float num2 = Mathf.Clamp01(1f - num / _tameable.m_tamingTime); if (!s_saidHidden) { s_saidHidden = true; Plugin.Log.LogInfo((object)($"taming bar for {((Object)_tameable).name}: timeLeft={num} " + $"of {_tameable.m_tamingTime} -> {num2:P0}")); } return num2; } } internal class Trough : MonoBehaviour { private const float FloorY = 0.209f; internal static readonly Vector3 BaitLocalPosition = new Vector3(0f, 0.269f, 0f); private const float BaitSearchRadius = 0.3f; private static readonly int ItemMask = LayerMask.GetMask(new string[1] { "item" }); private const float InnerHalfX = 0.85f; private const float InnerHalfZ = 0.24f; private const int MaxVisuals = 14; private const int ItemsPerVisual = 4; internal static readonly List<Trough> All = new List<Trough>(); private Container _container; private Inventory _inventory; private Transform _holder; private readonly List<GameObject> _spawned = new List<GameObject>(); private void Awake() { All.Add(this); } private void Start() { _container = ((Component)this).GetComponent<Container>(); if (!((Object)(object)_container == (Object)null)) { _inventory = _container.GetInventory(); if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(Rebuild)); Rebuild(); } } } private void OnDestroy() { All.Remove(this); if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(Rebuild)); } } internal ItemDrop FindBait() { //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) Collider[] array = Physics.OverlapSphere(((Component)this).transform.TransformPoint(BaitLocalPosition), 0.3f, ItemMask); for (int i = 0; i < array.Length; i++) { Rigidbody attachedRigidbody = array[i].attachedRigidbody; ItemDrop val = (((Object)(object)attachedRigidbody == (Object)null) ? null : ((Component)attachedRigidbody).GetComponent<ItemDrop>()); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void Rebuild() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject item in _spawned) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)item); } } _spawned.Clear(); List<ItemData> allItems = _inventory.GetAllItems(); if (allItems.Count == 0) { return; } if ((Object)(object)_holder == (Object)null) { _holder = new GameObject("TroughFill").transform; _holder.SetParent(((Component)this).transform, false); } Random rng = new Random(((Object)this).GetInstanceID()); int num = 0; foreach (ItemData item2 in allItems) { num += item2.m_stack; } int num2 = Mathf.Clamp(Mathf.CeilToInt((float)num / 4f), 1, 14); int num3 = 0; foreach (ItemData item3 in allItems) { if (!((Object)(object)item3.m_dropPrefab == (Object)null)) { int num4 = Mathf.Max(1, Mathf.RoundToInt((float)num2 * ((float)item3.m_stack / (float)num))); int num5 = 0; while (num5 < num4 && num3 < num2) { Place(item3.m_dropPrefab, num3, num2, rng); num5++; num3++; } } } } private void Place(GameObject dropPrefab, int index, int slots, Random rng) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) bool forceDisableInit = ZNetView.m_forceDisableInit; ZNetView.m_forceDisableInit = true; GameObject val; try { val = Object.Instantiate<GameObject>(dropPrefab, _holder); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } Strip(val); float num = ((slots == 1) ? 0.5f : ((float)index / (float)(slots - 1))); float num2 = Mathf.Lerp(-0.85f, 0.85f, num) + (float)(rng.NextDouble() - 0.5) * 0.08f; float num3 = (float)(rng.NextDouble() - 0.5) * 2f * 0.24f; float num4 = 0.209f + ((index >= slots / 2) ? 0.05f : 0f) + (float)rng.NextDouble() * 0.02f; val.transform.localPosition = new Vector3(num2, num4, num3); val.transform.localRotation = Quaternion.Euler((float)rng.NextDouble() * 30f, (float)rng.NextDouble() * 360f, (float)rng.NextDouble() * 30f); _spawned.Add(val); } private static void Strip(GameObject go) { ZNetView[] componentsInChildren = go.GetComponentsInChildren<ZNetView>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } ItemDrop[] componentsInChildren2 = go.GetComponentsInChildren<ItemDrop>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Rigidbody[] componentsInChildren3 = go.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Collider[] componentsInChildren4 = go.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } Floating[] componentsInChildren5 = go.GetComponentsInChildren<Floating>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren5[i]); } Transform[] componentsInChildren6 = go.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren6.Length; i++) { ((Component)componentsInChildren6[i]).gameObject.layer = LayerMask.NameToLayer("piece_nonsolid"); } } } [HarmonyPatch(typeof(MonsterAI), "FindClosestConsumableItem")] internal static class TroughFeeding { private static readonly MethodInfo CanConsumeMethod = AccessTools.Method(typeof(MonsterAI), "CanConsume", new Type[1] { typeof(ItemData) }, (Type[])null); private static bool s_loggedFirstFeed; private static bool s_loggedPathing; private static bool s_loggedNoTrough; private static void Postfix(MonsterAI __instance, float maxRange, ref ItemDrop __result) { if ((Object)(object)__result != (Object)null || CanConsumeMethod == null) { return; } try { ItemDrop val = FindBait(__instance, maxRange); if ((Object)(object)val != (Object)null) { __result = val; } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"trough feeding failed, animal falls back to vanilla: {arg}"); } } private static ItemDrop FindBait(MonsterAI ai, float maxRange) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Trough trough = null; float num = float.MaxValue; foreach (Trough item in Trough.All) { if ((Object)(object)item == (Object)null) { continue; } ZNetView component = ((Component)item).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { float num2 = Vector3.Distance(((Component)ai).transform.position, ((Component)item).transform.position); if (num2 <= maxRange && num2 < num) { trough = item; num = num2; } } } if ((Object)(object)trough == (Object)null) { if (!s_loggedNoTrough) { s_loggedNoTrough = true; Plugin.Log.LogInfo((object)($"no trough within {maxRange} of {((Object)ai).name} " + $"(troughs loaded: {Trough.All.Count}) - said once")); } return null; } ItemDrop val = trough.FindBait(); if ((Object)(object)val != (Object)null) { if (!CanConsume(ai, val.m_itemData)) { return null; } if (!Reachable(ai, trough)) { return null; } return val; } Container component2 = ((Component)trough).GetComponent<Container>(); if ((Object)(object)component2 == (Object)null || component2.IsInUse()) { return null; } Inventory inventory = component2.GetInventory(); if (inventory == null) { return null; } ItemData val2 = null; foreach (ItemData allItem in inventory.GetAllItems()) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && CanConsume(ai, allItem)) { val2 = allItem; break; } } if (val2 == null) { return null; } if (!Reachable(ai, trough)) { return null; } return TakeBait(trough, component2, inventory, val2); } private static ItemDrop TakeBait(Trough trough, Container container, Inventory inventory, ItemData food) { //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_004a: 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) ZNetView component = ((Component)container).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return null; } if (!component.IsOwner()) { return null; } ItemData val = food.Clone(); if (!inventory.RemoveItem(food, 1)) { return null; } Vector3 val2 = ((Component)trough).transform.TransformPoint(Trough.BaitLocalPosition); ItemDrop val3 = ItemDrop.DropItem(val, 1, val2, Random.rotation); if ((Object)(object)val3 == (Object)null) { return null; } val3.m_autoPickup = false; Rigidbody component2 = ((Component)val3).GetComponent<Rigidbody>(); if ((Object)(object)component2 != (Object)null) { component2.isKinematic = true; } if (!s_loggedFirstFeed) { s_loggedFirstFeed = true; Plugin.Log.LogInfo((object)("first trough feed: " + val.m_shared.m_name + " offered to " + ((Object)trough).name)); } return val3; } private static bool Reachable(MonsterAI ai, Trough trough) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) Pathfinding instance = Pathfinding.instance; if ((Object)(object)instance == (Object)null) { return true; } Vector3 position = ((Component)ai).transform.position; Vector3 position2 = ((Component)trough).transform.position; float num = Utils.DistanceXZ(position, position2); bool flag = num <= ai.m_consumeRange + 1f; Vector3 val = default(Vector3); bool flag2 = instance.FindValidPoint(ref val, position2, 4f, ((BaseAI)ai).m_pathAgentType); bool flag3 = flag2 && instance.HavePath(position, val, ((BaseAI)ai).m_pathAgentType); bool flag4 = instance.HavePath(position, position2, ((BaseAI)ai).m_pathAgentType); bool flag5 = flag || flag3 || flag4; if (!s_loggedPathing) { s_loggedPathing = true; Plugin.Log.LogInfo((object)($"trough pathing for {((Object)ai).name}: d={num:0.00} " + $"near={flag} snapped={flag2} viaPoint={flag3} direct={flag4} " + $"agent={((BaseAI)ai).m_pathAgentType} -> reachable={flag5}")); } return flag5; } private static bool CanConsume(MonsterAI ai, ItemData item) { return (bool)CanConsumeMethod.Invoke(ai, new object[1] { item }); } } internal static class TroughPiece { internal const string PrefabName = "piece_cartur_trough"; internal const string NameToken = "$piece_cartur_trough"; internal const string DescriptionToken = "$piece_cartur_trough_description"; internal static Bounds BowlBounds { get; private set; } internal static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Build; } private static void Build() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Build; try { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; string text2 = "$piece_cartur_trough".Substring(1); localization.AddTranslation(ref text, ref text2, "Feeding Trough"); text = "English"; text2 = "$piece_cartur_trough_description".Substring(1); localization.AddTranslation(ref text, ref text2, "Fill it with food and your animals will come and eat from it."); PieceConfig val = new PieceConfig(); val.Name = "$piece_cartur_trough"; val.Description = "$piece_cartur_trough_description"; val.PieceTable = "Hammer"; val.Category = "Furniture"; val.CraftingStation = "piece_workbench"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig("Wood", 10, 0, true) }; CustomPiece val2 = new CustomPiece("piece_cartur_trough", "piece_chest_wood", val); if ((Object)(object)val2.PiecePrefab == (Object)null) { Plugin.Log.LogWarning((object)"piece_chest_wood did not resolve - no trough this session"); } else if (Reskin(val2.PiecePrefab)) { val2.Piece.m_icon = RenderManager.Instance.Render(val2.PiecePrefab); PieceManager.Instance.AddPiece(val2); ManualLogSource log = Plugin.Log; Bounds bowlBounds = BowlBounds; log.LogInfo((object)("registered piece_cartur_trough (clone of piece_chest_wood, " + $"bowl bounds {((Bounds)(ref bowlBounds)).size})")); } } catch (Exception arg) { Plugin.Log.LogWarning((object)$"could not build the trough piece: {arg}"); } } private static bool Reskin(GameObject prefab) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) Mesh val = MeshBlob.LoadMesh("trough.mesh"); if ((Object)(object)val == (Object)null) { return false; } Transform val2 = prefab.transform.Find("New/woodchest"); MeshRenderer val3 = (((Object)(object)val2 == (Object)null) ? null : ((Component)val2).GetComponent<MeshRenderer>()); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"chest prefab has no New/woodchest renderer - layout changed"); return false; } Material val4 = new Material(((Renderer)val3).sharedMaterial) { name = "cartur_trough" }; Texture2D val5 = MeshBlob.LoadTexture("trough_albedo.jpg", linear: false); Texture2D val6 = MeshBlob.LoadTexture("trough_normal.png", linear: true); if ((Object)(object)val5 != (Object)null) { val4.SetTexture("_MainTex", (Texture)(object)val5); } if ((Object)(object)val6 != (Object)null) { val4.SetTexture("_BumpMap", (Texture)(object)val6); } val4.SetFloat("_BumpScale", 1f); val4.SetFloat("_Metallic", 0f); val4.SetFloat("_Glossiness", 0.3f); DestroyChild(prefab, "New"); DestroyChild(prefab, "floor_2x2_snow"); GameObject val7 = new GameObject("TroughVisual") { layer = prefab.layer }; val7.transform.SetParent(prefab.transform, false); val7.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val7.AddComponent<MeshRenderer>()).sharedMaterial = val4; Bounds bounds = val.bounds; BoxCollider obj = prefab.AddComponent<BoxCollider>(); obj.center = ((Bounds)(ref bounds)).center; obj.size = ((Bounds)(ref bounds)).size; ((Collider)obj).isTrigger = false; BowlBounds = bounds; Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { ((StaticTarget)component).m_primaryTarget = false; } Container component2 = prefab.GetComponent<Container>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "$piece_cartur_trough"; component2.m_width = 4; component2.m_height = 2; } prefab.AddComponent<Trough>(); return true; } private static void DestroyChild(GameObject prefab, string name) { Transform val = prefab.transform.Find(name); if ((Object)(object)val != (Object)null) { Object.DestroyImmediate((Object)(object)((Component)val).gameObject); } } } }