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 PotatoFarmer v1.2.0
plugins/PotatoFarmer.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace PotatoFarmer; internal static class Assets { internal static string Dir; internal static Mesh LoadMesh(string name, float size = 1f) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_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_0167: Expected O, but got Unknown string text = Path.Combine(Dir, name + ".mesh"); if (!File.Exists(text)) { Plugin.Log.LogError((object)("Missing " + text)); return null; } using BinaryReader binaryReader = new BinaryReader(File.OpenRead(text)); if (new string(binaryReader.ReadChars(4)) != "PTM1") { Plugin.Log.LogError((object)(text + " isn't a model file from convert.py.")); return null; } int num = binaryReader.ReadInt32(); int num2 = binaryReader.ReadInt32(); Vector3[] array = (Vector3[])(object)new Vector3[num]; Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector2[] array3 = (Vector2[])(object)new Vector2[num]; int[] array4 = new int[num2]; for (int i = 0; i < num; i++) { array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()) * size; } for (int j = 0; j < num; j++) { array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); } for (int k = 0; k < num; k++) { array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); } for (int l = 0; l < num2; l++) { array4[l] = binaryReader.ReadInt32(); } Mesh val = new Mesh { name = "potato_" + name }; if (num > 65535) { val.indexFormat = (IndexFormat)1; } val.vertices = array; val.normals = array2; val.uv = array3; val.triangles = array4; val.RecalculateTangents(); val.RecalculateBounds(); return val; } } internal sealed class PieceLook { internal readonly Material Material; internal PieceLook(string name, float brightness, float shine, string templateName = "ironchest", Color? metalColor = null, float valueNoise = -1f) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_002f: 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) //IL_0175: Unknown result type (might be due to invalid IL or missing references) Material prefab = Cache.GetPrefab<Material>(templateName); Material = (Object.op_Implicit((Object)(object)prefab) ? new Material(prefab) : new Material(Shader.Find("Custom/Piece") ?? Shader.Find("Standard"))); if (!Object.op_Implicit((Object)(object)prefab)) { Plugin.Log.LogWarning((object)("The material " + templateName + " wasn't found; using a plain one.")); } ((Object)Material).name = "potato_" + name; if (Material.HasProperty("_Metallic")) { Material.SetFloat("_Metallic", 1f); } if (Material.HasProperty("_BumpScale")) { Material.SetFloat("_BumpScale", 1f); } if (Material.HasProperty("_Color")) { Material.SetColor("_Color", new Color(brightness, brightness, brightness, 1f)); } if (shine >= 0f && Material.HasProperty("_MetallicAlphaGloss")) { Material.SetFloat("_MetallicAlphaGloss", shine); } if (shine >= 0f && Material.HasProperty("_GlossMapScale")) { Material.SetFloat("_GlossMapScale", shine); } if (metalColor.HasValue && Material.HasProperty("_MetalColor")) { Material.SetColor("_MetalColor", metalColor.Value); } if (valueNoise >= 0f && Material.HasProperty("_ValueNoise")) { Material.SetFloat("_ValueNoise", valueNoise); } if (valueNoise >= 0f && Material.HasProperty("_ValueNoiseVertex")) { Material.SetFloat("_ValueNoiseVertex", 0f); } if (!GUIManager.IsHeadless()) { SetTexture("_MainTex", name + "_d.png", linear: false); SetTexture("_BumpMap", name + "_n.png", linear: true); Texture2D val = SetTexture("_MetallicTex", name + "_m.png", linear: true); if (Object.op_Implicit((Object)(object)val) && Material.HasProperty("_MetallicGlossMap")) { Material.SetTexture("_MetallicGlossMap", (Texture)(object)val); } } } private Texture2D SetTexture(string property, string file, bool linear) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (!Material.HasProperty(property)) { return null; } string text = Path.Combine(Assets.Dir, file); 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(file), wrapMode = (TextureWrapMode)0 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), true)) { Plugin.Log.LogWarning((object)("Couldn't read " + text)); return null; } ((Texture)val).filterMode = (FilterMode)0; Material.SetTexture(property, (Texture)(object)val); return val; } } public class Cask : MonoBehaviour, Hoverable, Interactable { private struct Batch { public string Prefab; public long Start; } private const string BatchesKey = "PotatoCask.Batches"; private const float TapDelay = 1.5f; private const float CoverEvery = 10f; internal const float Size = 1.5f; private static readonly Vector3 OutputPoint = new Vector3(-1.05f, 0.58f, 0f); private static readonly Vector3 RoofCheck = new Vector3(0f, 2.15f, 0f); private static Fermenter fermenter; private ZNetView view; private float nextCover; private float nextCheck; private bool exposed; private bool hasRoof = true; private bool Valid { get { if (Object.op_Implicit((Object)(object)view)) { return view.IsValid(); } return false; } } private void Awake() { view = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)view) && view.GetZDO() != null) { view.Register<string, int>("PotatoCask_Add", (Action<long, string, int>)RPC_Add); view.Register("PotatoCask_Tap", (Action<long>)RPC_Tap); view.Register<string, int>("PotatoCask_Give", (Action<long, string, int>)RPC_Give); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } } } private static Fermenter Fermenter() { if (Object.op_Implicit((Object)(object)fermenter)) { return fermenter; } GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("fermenter") : null); fermenter = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Fermenter>() : null); return fermenter; } private static ItemConversion Recipe(string prefab) { return Fermenter()?.m_conversion?.FirstOrDefault((Func<ItemConversion, bool>)((ItemConversion c) => c != null && Object.op_Implicit((Object)(object)c.m_from) && ((Object)((Component)c.m_from).gameObject).name == prefab)); } private static float TweaksSetting(string key) { try { ConfigEntry<float> val = default(ConfigEntry<float>); if (Chainloader.PluginInfos.TryGetValue("potato.tweaks", out var value) && Object.op_Implicit((Object)(object)value.Instance) && value.Instance.Config.TryGetEntry<float>("13 - Fermenters", key, ref val)) { return Mathf.Max(0.1f, val.Value); } } catch (Exception) { } return 1f; } private static float Duration() { return (Object.op_Implicit((Object)(object)Fermenter()) ? Fermenter().m_fermentationDuration : 2400f) / TweaksSetting("Speed"); } private static int Yield(ItemConversion recipe) { return Math.Max(1, Mathf.RoundToInt((float)recipe.m_producedItems * TweaksSetting("Output"))); } private List<Batch> Read() { List<Batch> list = new List<Batch>(); if (!Valid) { return list; } string[] array = view.GetZDO().GetString("PotatoCask.Batches", "").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { int num = text.LastIndexOf('@'); if (num > 0 && long.TryParse(text.Substring(num + 1), out var result)) { list.Add(new Batch { Prefab = text.Substring(0, num), Start = result }); } } return list; } private void Write(List<Batch> batches) { view.GetZDO().Set("PotatoCask.Batches", string.Join(";", batches.Select((Batch b) => b.Prefab + "@" + b.Start).ToArray())); } private static string Brewing(List<Batch> batches) { if (!Plugin.CaskMix.Value && batches.Count != 0) { return batches[0].Prefab; } return null; } private static double Age(Batch batch) { return (ZNet.instance.GetTime() - new DateTime(batch.Start)).TotalSeconds; } private static bool Ready(Batch batch) { return Age(batch) >= (double)Duration(); } private void Update() { if (Valid && !(Time.time < nextCheck)) { nextCheck = Time.time + 2f; UpdateCover(now: false); } } private void UpdateCover(bool now) { //IL_0028: 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_0037: Unknown result type (might be due to invalid IL or missing references) if (!now && Time.time < nextCover) { return; } nextCover = Time.time + 10f; float num = default(float); bool flag = default(bool); Cover.GetCoverForPoint(((Component)this).transform.TransformPoint(RoofCheck * 1.5f), ref num, ref flag, 0.5f); exposed = num < 0.7f; hasRoof = flag; if ((!exposed && hasRoof) || !view.IsOwner()) { return; } List<Batch> list = Read(); bool flag2 = false; long ticks = ZNet.instance.GetTime().Ticks; for (int i = 0; i < list.Count; i++) { if (!Ready(list[i])) { list[i] = new Batch { Prefab = list[i].Prefab, Start = ticks }; flag2 = true; } } if (flag2) { Write(list); } } public float GetHoverOffset() { return 0f; } public string GetHoverName() { return Localization.instance.Localize("$piece_potato_cask"); } public string GetHoverText() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return ""; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize("$piece_potato_cask\n$piece_noaccess"); } List<Batch> list = Read(); StringBuilder stringBuilder = new StringBuilder("$piece_potato_cask" + $" ({list.Count}/{Plugin.CaskBatches.Value})"); if (list.Count == 0) { stringBuilder.Append("\n$piece_container_empty"); } float num = Duration(); foreach (Batch item in list) { ItemConversion val = Recipe(item.Prefab); string text = ((val != null && Object.op_Implicit((Object)(object)val.m_from)) ? val.m_from.m_itemData.m_shared.m_name : item.Prefab); if (Ready(item)) { stringBuilder.Append("\n" + text + ": <color=yellow>$piece_fermenter_ready</color>"); } else if (!hasRoof) { stringBuilder.Append("\n" + text + ": $piece_fermenter_needroof"); } else if (exposed) { stringBuilder.Append("\n" + text + ": $piece_fermenter_exposed"); } else { stringBuilder.Append($"\n{text}: {Mathf.CeilToInt((float)((double)num - Age(item)) / 60f)} min left"); } } if (list.Any(Ready)) { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $piece_fermenter_tap"); } else if (list.Count < Plugin.CaskBatches.Value) { stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $piece_fermenter_add"); } if (list.Count < Plugin.CaskBatches.Value) { stringBuilder.Append("\n[<color=yellow><b>1-8</b></color>] Add mead bases from your hotbar"); } return Localization.instance.Localize(stringBuilder.ToString()); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (hold || !Valid) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (Read().Any(Ready)) { view.InvokeRPC("PotatoCask_Tap", Array.Empty<object>()); return true; } string brewing = Brewing(Read()); ItemData val = (from c in Fermenter()?.m_conversion?.Where((ItemConversion c) => c != null && Object.op_Implicit((Object)(object)c.m_from) && (brewing == null || ((Object)((Component)c.m_from).gameObject).name == brewing)) select user.GetInventory().GetItem(c.m_from.m_itemData.m_shared.m_name, -1, false)).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i != null)); if (val == null) { ((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null, false); return true; } Add(user, val, 1); return true; } public bool UseItem(Humanoid user, ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!Valid || item == null) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (!Object.op_Implicit((Object)(object)item.m_dropPrefab) || Recipe(((Object)item.m_dropPrefab).name) == null) { ((Character)user).Message((MessageType)2, "That doesn't brew", 0, (Sprite)null, false); return true; } Add(user, item, item.m_stack); return true; } private void Add(Humanoid user, ItemData item, int wanted) { UpdateCover(now: true); if (!hasRoof) { ((Character)user).Message((MessageType)2, "$piece_fermenter_needroof", 0, (Sprite)null, false); return; } if (exposed) { ((Character)user).Message((MessageType)2, "$piece_fermenter_exposed", 0, (Sprite)null, false); return; } List<Batch> list = Read(); string text = Brewing(list); if (text != null && text != ((Object)item.m_dropPrefab).name) { ((Character)user).Message((MessageType)2, "The cask is brewing " + (Recipe(text)?.m_from?.m_itemData.m_shared.m_name ?? text), 0, (Sprite)null, false); return; } int num = Plugin.CaskBatches.Value - list.Count; if (num <= 0) { ((Character)user).Message((MessageType)2, "The cask is full", 0, (Sprite)null, false); return; } int num2 = Math.Min(num, Math.Min(wanted, item.m_stack)); string name = ((Object)item.m_dropPrefab).name; string name2 = item.m_shared.m_name; if (user.GetInventory().RemoveItem(item, num2)) { view.InvokeRPC("PotatoCask_Add", new object[2] { name, num2 }); ((Character)user).Message((MessageType)2, $"$msg_added {name2} x{num2}", 0, (Sprite)null, false); } } private void RPC_Add(long sender, string prefab, int count) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !view.IsOwner() || count <= 0 || Recipe(prefab) == null) { return; } List<Batch> list = Read(); string text = Brewing(list); int num = ((text == null || !(text != prefab)) ? Math.Min(count, Math.Max(0, Plugin.CaskBatches.Value - list.Count)) : 0); long ticks = ZNet.instance.GetTime().Ticks; for (int i = 0; i < num; i++) { list.Add(new Batch { Prefab = prefab, Start = ticks }); } if (num > 0) { Write(list); Fermenter obj = Fermenter(); if (obj != null) { obj.m_addedEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } if (count > num) { view.InvokeRPC(sender, "PotatoCask_Give", new object[2] { prefab, count - num }); } } private void RPC_Tap(long sender) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !view.IsOwner()) { return; } List<Batch> source = Read(); List<Batch> list = source.Where(Ready).ToList(); if (list.Count != 0) { Write(source.Where((Batch b) => !Ready(b)).ToList()); Fermenter obj = Fermenter(); if (obj != null) { obj.m_tapEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } ((MonoBehaviour)this).StartCoroutine(Pour(list.Select((Batch b) => b.Prefab).ToList())); } } private IEnumerator Pour(List<string> prefabs) { yield return (object)new WaitForSeconds(1.5f); Vector3 val = ((Component)this).transform.TransformPoint(OutputPoint * 1.5f); Fermenter obj = Fermenter(); if (obj != null) { obj.m_spawnEffects.Create(val, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } float num = 0.3f; foreach (string prefab in prefabs) { ItemConversion val2 = Recipe(prefab); if (val2 != null && Object.op_Implicit((Object)(object)val2.m_to)) { for (int i = 0; i < Yield(val2); i++) { ItemDrop.OnCreateNew(Object.Instantiate<ItemDrop>(val2.m_to, val + Vector3.up * num, Quaternion.identity), false); num += 0.05f; } } } } private void RPC_Give(long sender, string prefab, int count) { //IL_007d: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); if (!Object.op_Implicit((Object)(object)val) || count <= 0) { return; } Inventory val2 = (Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetInventory() : null); if (val2 == null || !val2.CanAddItem(val, count) || !val2.AddItem(val, count)) { Vector3 val3 = (Object.op_Implicit((Object)(object)localPlayer) ? (((Component)localPlayer).transform.position + Vector3.up) : (((Component)this).transform.position + Vector3.up)); for (int i = 0; i < count; i++) { ItemDrop.OnCreateNew(Object.Instantiate<GameObject>(val, val3, Quaternion.identity), false); } } } private void OnDestroyed() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !view.IsOwner()) { return; } List<Batch> list = Read(); Write(new List<Batch>()); foreach (Batch item in list) { ItemConversion val = Recipe(item.Prefab); if (val != null) { bool num = Ready(item); ItemDrop val2 = (num ? val.m_to : val.m_from); int num2 = ((!num) ? 1 : Yield(val)); for (int i = 0; i < num2; i++) { Vector3 val3 = ((Component)this).transform.position + Vector3.up + Random.insideUnitSphere * 0.4f; ItemDrop.OnCreateNew(Object.Instantiate<GameObject>(((Component)val2).gameObject, val3, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)), false); } } } } } internal static class Feeding { [HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")] private static class Watch { private static void Prefix(MonsterAI __instance) { } } [HarmonyPatch(typeof(MonsterAI), "FindClosestConsumableItem")] private static class FromTrough { private static void Postfix(MonsterAI __instance, float maxRange, ref ItemDrop __result) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (Trough.All.Count == 0 || CanConsume == null) { return; } maxRange = Mathf.Max(maxRange, Plugin.TroughReach.Value); if (Object.op_Implicit((Object)(object)__result)) { Note(__instance, "found food on the ground: " + ((Object)__result).name.Replace("(Clone)", "")); return; } try { Vector3 at = ((Component)__instance).transform.position; foreach (Trough item in from trough in Trough.All where Object.op_Implicit((Object)(object)trough) orderby Vector3.Distance(at, ((Component)trough).transform.position) select trough) { float num = Vector3.Distance(at, ((Component)item).transform.position); if (num > maxRange) { Note(__instance, $"hungry, but the nearest trough is {num:0.0} m away (reach {maxRange:0} m)"); break; } string text = item.FoodFor(__instance); if (text == null) { Note(__instance, string.Format("hungry, trough {0:0.0} m away has nothing it eats (it eats: {1})", num, string.Join(", ", (from item in __instance.m_consumeItems where Object.op_Implicit((Object)(object)item) select ((Object)item).name).ToArray()))); continue; } if (!Reachable(__instance, item)) { Note(__instance, $"hungry, trough {num:0.0} m away has {text}, but its route doesn't get close enough"); continue; } ItemDrop val = item.Dispense(text); Note(__instance, Object.op_Implicit((Object)(object)val) ? $"hungry, took {text} from the trough {num:0.0} m away and is walking to it" : $"hungry, asked the trough {num:0.0} m away for {text} (waiting for a bite, or the bowl is busy)"); if (Object.op_Implicit((Object)(object)val)) { __result = val; } else { SearchTimer.Invoke(__instance) = Mathf.Max(SearchTimer.Invoke(__instance), __instance.m_consumeSearchInterval - 2f); } break; } } catch (Exception ex) { if (!warned) { warned = true; Plugin.Log.LogWarning((object)("Trough feeding failed; animals eat off the ground as usual: " + ex)); } } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class BaitStaysPut { private static void Postfix(ItemDrop __instance) { if (IsBait(__instance)) { __instance.m_autoPickup = false; } } } private const string BaitKey = "PotatoTrough.Bait"; private static readonly Func<MonsterAI, ItemData, bool> CanConsume = AccessTools.MethodDelegate<Func<MonsterAI, ItemData, bool>>(AccessTools.Method(typeof(MonsterAI), "CanConsume", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef<MonsterAI, float> SearchTimer = AccessTools.FieldRefAccess<MonsterAI, float>("m_consumeSearchTimer"); private static HashSet<string> animalFood; private static ZNetScene foodFrom; private static bool warned; private static readonly List<Vector3> route = new List<Vector3>(); internal const bool Diagnostics = false; private static readonly Dictionary<int, float> lastNote = new Dictionary<int, float>(); internal static bool IsAnimalFood(ItemData item) { ZNetScene instance = ZNetScene.instance; if (!Object.op_Implicit((Object)(object)instance)) { return false; } if (animalFood == null || (Object)(object)foodFrom != (Object)(object)instance) { foodFrom = instance; animalFood = new HashSet<string>(); foreach (GameObject prefab in instance.m_prefabs) { MonsterAI val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<MonsterAI>() : null); if (!Object.op_Implicit((Object)(object)val) || val.m_consumeItems == null || (!Object.op_Implicit((Object)(object)prefab.GetComponent<Tameable>()) && !Object.op_Implicit((Object)(object)prefab.GetComponent<Procreation>()))) { continue; } foreach (ItemDrop consumeItem in val.m_consumeItems) { if (Object.op_Implicit((Object)(object)consumeItem) && consumeItem.m_itemData?.m_shared != null) { animalFood.Add(consumeItem.m_itemData.m_shared.m_name); } } } } if (item?.m_shared != null) { return animalFood.Contains(item.m_shared.m_name); } return false; } internal static bool CanEat(MonsterAI animal, string prefab) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (Object.op_Implicit((Object)(object)val2)) { return CanConsume(animal, val2.m_itemData); } return false; } internal static void MarkBait(ItemDrop bite) { if (Object.op_Implicit((Object)(object)bite)) { bite.m_autoPickup = false; ZNetView component = ((Component)bite).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.GetZDO() != null) { component.GetZDO().Set("PotatoTrough.Bait", true); } } } internal static bool IsBait(ItemDrop drop) { ZNetView component = ((Component)drop).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.GetZDO() != null) { return component.GetZDO().GetBool("PotatoTrough.Bait", false); } return false; } private static bool Reachable(MonsterAI animal, Trough trough) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0026: 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_0043: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)animal).transform.position; Vector3 position2 = ((Component)trough).transform.position; float num = animal.m_consumeRange + 2.42f; if (Utils.DistanceXZ(position, position2) <= num) { return true; } Pathfinding instance = Pathfinding.instance; if (!Object.op_Implicit((Object)(object)instance)) { return true; } if (!instance.GetPath(position, position2, route, ((BaseAI)animal).m_pathAgentType, false, false, false) || route.Count == 0) { return false; } return Utils.DistanceXZ(route[route.Count - 1], position2) <= num; } internal static void Note(MonsterAI animal, string text) { } private static Trough Nearest(MonsterAI animal, out float distance) { //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) distance = float.MaxValue; Trough result = null; foreach (Trough item in Trough.All) { if (Object.op_Implicit((Object)(object)item)) { float num = Vector3.Distance(((Component)animal).transform.position, ((Component)item).transform.position); if (num < distance) { distance = num; result = item; } } } return result; } } [BepInPlugin("potato.farmer", "PotatoFarmer", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Id = "potato.farmer"; public const string Version = "1.2.0"; public const string TroughPiece = "piece_potato_trough"; public const string TroughName = "$piece_potato_trough"; private const string TroughDescription = "$piece_potato_trough_description"; private const string TroughSection = "1 - Trough"; public const string RoostPiece = "piece_potato_roost"; public const string RoostName = "$piece_potato_roost"; private const string RoostDescription = "$piece_potato_roost_description"; private const string RoostSection = "2 - Roost"; public const string CaskPiece = "piece_potato_cask"; public const string CaskName = "$piece_potato_cask"; private const string CaskDescription = "$piece_potato_cask_description"; private const string CaskSection = "3 - Cask"; internal static ManualLogSource Log; internal static ConfigEntry<int> TroughCapacity; internal static ConfigEntry<int> RoostCapacity; internal static ConfigEntry<int> RoostFlock; internal static ConfigEntry<int> CaskBatches; internal static ConfigEntry<bool> TroughEnabled; internal static ConfigEntry<bool> TroughShowFood; internal static ConfigEntry<bool> RoostEnabled; internal static ConfigEntry<bool> CaskEnabled; internal static ConfigEntry<bool> CaskMix; internal static ConfigEntry<float> TroughReach; internal static ConfigEntry<float> RoostReach; private static Piece troughPiece; private static Piece roostPiece; private static Piece caskPiece; private void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Expected O, but got Unknown //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Expected O, but got Unknown //IL_0308: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Assets.Dir = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? "", "assets"); ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; TroughEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Trough", "Enabled", true, new ConfigDescription("Show the feeding trough on the hammer. Troughs already built stay and keep working. Set by the server.", (AcceptableValueBase)null, new object[1] { val })); TroughCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Trough", "Capacity", 100, new ConfigDescription("How many food items one trough holds. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), new object[1] { val })); TroughReach = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Trough", "Reach", 25f, new ConfigDescription("How far away (metres) hungry animals notice the trough and walk over to eat. 25 covers a big farm pen; animals on their own only look about 10 m for food. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), new object[1] { val })); TroughShowFood = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Trough", "Show food in the bowl", true, "Show what is in the trough as food models in the bowl (only on your screen)."); TroughEnabled.SettingChanged += delegate { if (Object.op_Implicit((Object)(object)troughPiece)) { troughPiece.m_enabled = TroughEnabled.Value; } }; RoostEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Roost", "Enabled", true, new ConfigDescription("Show the roost on the hammer. Roosts already built stay and keep working. Set by the server.", (AcceptableValueBase)null, new object[1] { val })); RoostCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Roost", "Capacity", 60, new ConfigDescription("How many eggs one roost holds. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), new object[1] { val })); RoostReach = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Roost", "Reach", 10f, new ConfigDescription("How far away (metres) the roost gathers eggs. Hens only breed with others within 10 m, so 10 covers a coop. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), new object[1] { val })); RoostFlock = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Roost", "Flock size", 6, new ConfigDescription("With a fire near the roost, it hatches its eggs one at a time while there are fewer hens (and chicks) than this within its reach. 0 = never hatch. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), new object[1] { val })); RoostEnabled.SettingChanged += delegate { if (Object.op_Implicit((Object)(object)roostPiece)) { roostPiece.m_enabled = RoostEnabled.Value; } }; CaskEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Cask", "Enabled", true, new ConfigDescription("Show the cask on the hammer. Casks already built stay and keep working. Set by the server.", (AcceptableValueBase)null, new object[1] { val })); CaskBatches = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Cask", "Batches", 4, new ConfigDescription("How many mead bases one cask brews at once, each like a fermenter of its own. Set by the server.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), new object[1] { val })); CaskMix = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Cask", "Mix mead bases", false, new ConfigDescription("Let one cask brew different mead bases at once. Off: a cask brews one kind at a time, until it's emptied. Set by the server.", (AcceptableValueBase)null, new object[1] { val })); CaskEnabled.SettingChanged += delegate { if (Object.op_Implicit((Object)(object)caskPiece)) { caskPiece.m_enabled = CaskEnabled.Value; } }; new Harmony("potato.farmer").PatchAll(typeof(Plugin).Assembly); PrefabManager.OnVanillaPrefabsAvailable += AddPieces; } private static void AddPieces() { PrefabManager.OnVanillaPrefabsAvailable -= AddPieces; CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "$piece_potato_trough".Substring(1), "Gullinbursti's Trough" }, { "$piece_potato_trough_description".Substring(1), "A feeding trough blessed by Freyr's golden boar. Fill it with food and hungry animals nearby come to eat: taming, breeding and feeding all count." }, { "$piece_potato_roost".Substring(1), "Gullinkambi's Roost" }, { "$piece_potato_roost_description".Substring(1), "A nesting box watched over by Gullinkambi, the golden-combed rooster of Valhalla. Gathers the eggs your hens lay nearby, so they keep laying." }, { "$piece_potato_cask".Substring(1), "Heiðrún's Cask" }, { "$piece_potato_cask_description".Substring(1), "A great mead cask blessed by Heiðrún, the goat whose udder runs with mead in Valhalla. Brews several mead bases at once, each like a fermenter of its own. Needs a roof." } }); try { AddTrough(); } catch (Exception ex) { Log.LogError((object)("Couldn't add the feeding trough: " + ex)); } try { AddRoost(); } catch (Exception ex2) { Log.LogError((object)("Couldn't add the roost: " + ex2)); } try { AddCask(); } catch (Exception ex3) { Log.LogError((object)("Couldn't add the cask: " + ex3)); } } private static void AddTrough() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_010c: 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_0144: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) PieceConfig val = new PieceConfig(); val.Name = "$piece_potato_trough"; val.Description = "$piece_potato_trough_description"; val.PieceTable = "Hammer"; val.Category = "Furniture"; val.CraftingStation = "forge"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("Wood", 10, 0, true), new RequirementConfig("Bronze", 2, 0, true) }; CustomPiece val2 = new CustomPiece("piece_potato_trough", "piece_table", val); if (!Object.op_Implicit((Object)(object)val2.PiecePrefab)) { Log.LogWarning((object)"The wooden table to build the trough from wasn't found; no trough this session."); return; } Mesh val3 = Assets.LoadMesh("trough", 1.21f); if (Object.op_Implicit((Object)(object)val3)) { PieceLook pieceLook = new PieceLook("trough", 1f, 0.6f); GameObject piecePrefab = val2.PiecePrefab; Rebuild(piecePrefab, val3, pieceLook.Material); AddBox(piecePrefab, "Floor", new Vector3(0f, 0.11f, 0f), new Vector3(1.52f, 0.215f, 0.52f), 1.21f); AddBox(piecePrefab, "Side", new Vector3(0f, 0.28f, 0.25f), new Vector3(1.52f, 0.14f, 0.06f), 1.21f); AddBox(piecePrefab, "Side", new Vector3(0f, 0.28f, -0.25f), new Vector3(1.52f, 0.14f, 0.06f), 1.21f); AddBox(piecePrefab, "End", new Vector3(0.88f, 0.25f, 0f), new Vector3(0.24f, 0.5f, 0.42f), 1.21f); AddBox(piecePrefab, "End", new Vector3(-0.88f, 0.25f, 0f), new Vector3(0.24f, 0.5f, 0.42f), 1.21f); piecePrefab.GetComponent<WearNTear>().m_materialType = (MaterialType)0; piecePrefab.AddComponent<Trough>(); troughPiece = val2.Piece; troughPiece.m_enabled = TroughEnabled.Value; if (!GUIManager.IsHeadless()) { troughPiece.m_icon = RenderManager.Instance.Render(piecePrefab, Quaternion.Euler(20f, 200f, 0f)); } PieceManager.Instance.AddPiece(val2); Log.LogInfo((object)"Feeding trough added to the hammer."); } } private static void AddRoost() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_010c: 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_0144: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) PieceConfig val = new PieceConfig(); val.Name = "$piece_potato_roost"; val.Description = "$piece_potato_roost_description"; val.PieceTable = "Hammer"; val.Category = "Furniture"; val.CraftingStation = "forge"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("FineWood", 10, 0, true), new RequirementConfig("BlackMetal", 2, 0, true) }; CustomPiece val2 = new CustomPiece("piece_potato_roost", "piece_table", val); if (!Object.op_Implicit((Object)(object)val2.PiecePrefab)) { Log.LogWarning((object)"The wooden table to build the roost from wasn't found; no roost this session."); return; } Mesh val3 = Assets.LoadMesh("roost", 1.3f); if (Object.op_Implicit((Object)(object)val3)) { PieceLook pieceLook = new PieceLook("roost", 1f, -1f, "BlackMetalChest_mat", null, 0f); GameObject piecePrefab = val2.PiecePrefab; Rebuild(piecePrefab, val3, pieceLook.Material); AddBox(piecePrefab, "Base", new Vector3(0f, 0.12f, 0f), new Vector3(1.5f, 0.245f, 0.5f), 1.3f); AddBox(piecePrefab, "Lid", new Vector3(0f, 0.52f, 0f), new Vector3(1.6f, 0.19f, 0.64f), 1.3f); AddBox(piecePrefab, "Back", new Vector3(0f, 0.335f, -0.19f), new Vector3(1.5f, 0.19f, 0.09f), 1.3f); AddBox(piecePrefab, "Side", new Vector3(0.715f, 0.335f, 0f), new Vector3(0.07f, 0.19f, 0.45f), 1.3f); AddBox(piecePrefab, "Side", new Vector3(-0.715f, 0.335f, 0f), new Vector3(0.07f, 0.19f, 0.45f), 1.3f); AddBox(piecePrefab, "End", new Vector3(0.85f, 0.42f, 0f), new Vector3(0.2f, 0.84f, 0.22f), 1.3f); AddBox(piecePrefab, "End", new Vector3(-0.85f, 0.42f, 0f), new Vector3(0.2f, 0.84f, 0.22f), 1.3f); piecePrefab.GetComponent<WearNTear>().m_materialType = (MaterialType)0; piecePrefab.AddComponent<Roost>(); roostPiece = val2.Piece; roostPiece.m_enabled = RoostEnabled.Value; if (!GUIManager.IsHeadless()) { roostPiece.m_icon = RenderManager.Instance.Render(piecePrefab, Quaternion.Euler(20f, 200f, 0f)); } PieceManager.Instance.AddPiece(val2); Log.LogInfo((object)"Roost added to the hammer."); } } private static void AddCask() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_01b5: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) PieceConfig val = new PieceConfig(); val.Name = "$piece_potato_cask"; val.Description = "$piece_potato_cask_description"; val.PieceTable = "Hammer"; val.Category = "Crafting"; val.CraftingStation = "forge"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig("FineWood", 30, 0, true), new RequirementConfig("BlackMetal", 6, 0, true), new RequirementConfig("Tar", 4, 0, true), new RequirementConfig("IronNails", 20, 0, true) }; CustomPiece val2 = new CustomPiece("piece_potato_cask", "piece_table", val); if (!Object.op_Implicit((Object)(object)val2.PiecePrefab)) { Log.LogWarning((object)"The wooden table to build the cask from wasn't found; no cask this session."); return; } Mesh val3 = Assets.LoadMesh("cask", 1.5f); if (Object.op_Implicit((Object)(object)val3)) { PieceLook pieceLook = new PieceLook("cask", 1f, -1f, "BlackMetalChest_mat", null, 0f); GameObject piecePrefab = val2.PiecePrefab; GameObject val4 = Rebuild(piecePrefab, val3, pieceLook.Material); Mesh val5 = Assets.LoadMesh("caskhoops", 1.5f); if (Object.op_Implicit((Object)(object)val5)) { GameObject val6 = new GameObject("Hoops") { layer = piecePrefab.layer }; val6.transform.SetParent(val4.transform, false); val6.AddComponent<MeshFilter>().sharedMesh = val5; ((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterial = new PieceLook("caskhoops", 1f, -1f, "BlackMetalChest_mat", null, 0f).Material; } AddBox(piecePrefab, "Barrel", new Vector3(0.055f, 1.19f, 0f), new Vector3(1.71f, 1.78f, 1.81f), 1.5f); AddBox(piecePrefab, "Cradle", new Vector3(0.064f, 0.2f, 0f), new Vector3(1.87f, 0.4f, 1.64f), 1.5f); piecePrefab.GetComponent<WearNTear>().m_materialType = (MaterialType)0; piecePrefab.AddComponent<Cask>(); caskPiece = val2.Piece; caskPiece.m_enabled = CaskEnabled.Value; if (!GUIManager.IsHeadless()) { caskPiece.m_icon = RenderManager.Instance.Render(piecePrefab, Quaternion.Euler(20f, 230f, 0f)); } PieceManager.Instance.AddPiece(val2); Log.LogInfo((object)"Cask added to the hammer."); } } private static GameObject Rebuild(GameObject prefab, Mesh mesh, Material material) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in ((IEnumerable)prefab.transform).Cast<Transform>().ToList()) { Object.DestroyImmediate((Object)(object)((Component)item).gameObject); } Component[] components = prefab.GetComponents<Component>(); foreach (Component val in components) { if (!(val is Transform) && !(val is ZNetView) && !(val is Piece) && !(val is WearNTear)) { Log.LogDebug((object)("Removing the base piece's " + ((object)val).GetType().Name)); Object.DestroyImmediate((Object)(object)val); } } GameObject val2 = new GameObject("Model"); val2.layer = prefab.layer; val2.transform.SetParent(prefab.transform, false); val2.AddComponent<MeshFilter>().sharedMesh = mesh; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = material; Piece component = prefab.GetComponent<Piece>(); component.m_comfort = 0; component.m_comfortGroup = (ComfortGroup)0; ((StaticTarget)component).m_primaryTarget = false; WearNTear component2 = prefab.GetComponent<WearNTear>(); component2.m_new = (component2.m_worn = (component2.m_broken = val2)); component2.m_fragmentRoots = null; component2.m_autoCreateFragments = false; return val2; } private static void AddBox(GameObject prefab, string name, Vector3 center, Vector3 size, float scale) { //IL_0000: 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_000a: 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_0012: 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_0026: 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_0044: Unknown result type (might be due to invalid IL or missing references) center *= scale; size *= scale; GameObject val = new GameObject(name) { layer = prefab.layer }; val.transform.SetParent(prefab.transform, false); BoxCollider obj = val.AddComponent<BoxCollider>(); obj.center = center; obj.size = size; } } public class Roost : MonoBehaviour, Hoverable, Interactable { private const string EggsKey = "PotatoRoost.Eggs"; private const string OffKey = "PotatoRoost.Off"; private const string WarmKey = "PotatoRoost.Warming"; private const float GatherEvery = 3f; internal const float Size = 1.3f; private static readonly float[] CubbyX = new float[3] { -0.466f, -0.017f, 0.447f }; private const float CubbyFloor = 0.25f; private const float CubbyZ = 0.05f; private const float MaxShownPerCubby = 4f; private const float EggLength = 0.12f; private static bool eggSizeLogged; private static readonly Vector3[] Clutch = (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, 0f, 0f), new Vector3(0.5f, 0f, 0f), new Vector3(0f, 0f, 0.85f), new Vector3(0f, 0f, -0.85f) }; private static int itemMask; private ZNetView view; private string shown; private GameObject eggModels; private float nextCheck; private float nextGather; private const float Stagger = 300f; private bool Valid { get { if (Object.op_Implicit((Object)(object)view)) { return view.IsValid(); } return false; } } private bool Gathering { get { if (Valid) { return !view.GetZDO().GetBool("PotatoRoost.Off", false); } return false; } } private void Awake() { view = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)view) && view.GetZDO() != null) { view.Register("PotatoRoost_Toggle", (Action<long>)RPC_Toggle); view.Register("PotatoRoost_Take", (Action<long>)RPC_Take); view.Register<string>("PotatoRoost_Give", (Action<long, string>)RPC_Give); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } nextGather = Time.time + Random.Range(0f, 3f); } } private Stock Read() { return Stock.Parse(Valid ? view.GetZDO().GetString("PotatoRoost.Eggs", "") : ""); } private void Write(Stock stock) { view.GetZDO().Set("PotatoRoost.Eggs", stock.Format()); } private void Update() { if (!Valid) { return; } if (Time.time >= nextGather) { nextGather = Time.time + 3f; if (view.IsOwner()) { if (Gathering) { Gather(); } Hatch(); } } if (!(Time.time < nextCheck)) { nextCheck = Time.time + 0.5f; string text = view.GetZDO().GetString("PotatoRoost.Eggs", ""); if (!(text == shown)) { shown = text; ShowEggs(Stock.Parse(text)); } } } private void Gather() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) Stock stock = Read(); int num = Plugin.RoostCapacity.Value - stock.Total; if (num <= 0) { return; } if (itemMask == 0) { itemMask = LayerMask.GetMask(new string[1] { "item" }); } bool flag = false; HashSet<ItemDrop> hashSet = new HashSet<ItemDrop>(); Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, Plugin.RoostReach.Value, itemMask); foreach (Collider val in array) { ItemDrop val2 = (Object.op_Implicit((Object)(object)val.attachedRigidbody) ? ((Component)val.attachedRigidbody).GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2) || !hashSet.Add(val2) || !Object.op_Implicit((Object)(object)((Component)val2).GetComponent<EggGrow>())) { continue; } ZNetView component = ((Component)val2).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || component.GetZDO().GetFloat(ZDOVars.s_growStart, 0f) > 0f) { continue; } if (!component.IsOwner()) { val2.RequestOwn(); continue; } int stack = val2.m_itemData.m_stack; int num2 = Math.Min(stack, num); stock.Add(Key(((Component)val2).gameObject, val2.m_itemData.m_quality), num2); num -= num2; flag = true; if (num2 >= stack) { component.Destroy(); } else { val2.SetStack(stack - num2); } if (num <= 0) { break; } } if (flag) { Write(stock); } } private static string Key(GameObject prefab, int quality) { return Utils.GetPrefabName(prefab) + "@" + Math.Max(1, quality); } private static bool Split(string key, out string prefab, out int quality) { int num = key.LastIndexOf('@'); prefab = ((num > 0) ? key.Substring(0, num) : key); quality = ((num <= 0 || !int.TryParse(key.Substring(num + 1), out var result)) ? 1 : Math.Max(1, result)); return prefab.Length > 0; } private void Hatch() { //IL_0039: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = view.GetZDO(); Stock stock = Read(); string key; int quality; EggGrow val = NextEgg(stock, out key, out quality); int num = ((Object.op_Implicit((Object)(object)val) && Plugin.RoostFlock.Value > 0 && Object.op_Implicit((Object)(object)EffectArea.IsPointInsideArea(((Component)this).transform.position + Vector3.up * 0.4f, (Type)1, 0.5f))) ? Mathf.Min(Plugin.RoostFlock.Value - Flock(val), Hatchable(stock)) : 0); List<float> list = Starts(); int count = list.Count; if (num <= 0) { if (count > 0) { zDO.Set("PotatoRoost.Warming", ""); } return; } float num2 = (float)ZNet.instance.GetTimeSeconds(); if (count > 0 && num2 - list[0] >= val.m_growTime) { list.RemoveAt(0); zDO.Set("PotatoRoost.Warming", Join(list)); if (stock.Remove(key, 1)) { Write(stock); Vector3 val2 = ((Component)this).transform.TransformPoint(new Vector3(0f, 0f, 0.9f) * 1.3f); Character component = Object.Instantiate<GameObject>(val.m_grownPrefab, val2, ((Component)this).transform.rotation).GetComponent<Character>(); val.m_hatchEffect.Create(val2, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); if (Object.op_Implicit((Object)(object)component)) { component.SetTamed(val.m_tamed); component.SetLevel(quality); } } } else { while (list.Count > num) { list.RemoveAt(list.Count - 1); } while (list.Count < num) { list.Add((list.Count == 0) ? num2 : Mathf.Max(num2, list[list.Count - 1] + 300f)); } if (list.Count != count) { zDO.Set("PotatoRoost.Warming", Join(list)); } } } private List<float> Starts() { List<float> list = new List<float>(); string[] array = view.GetZDO().GetString("PotatoRoost.Warming", "").Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { if (float.TryParse(array[i], NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { list.Add(result); } } return list; } private static string Join(List<float> starts) { return string.Join(";", starts.Select((float t) => t.ToString("R", CultureInfo.InvariantCulture))); } private static int Hatchable(Stock stock) { int num = 0; foreach (KeyValuePair<string, int> entry in stock.Entries) { if (Split(entry.Key, out var prefab, out var _)) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); EggGrow val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<EggGrow>() : null); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.m_grownPrefab)) { num += entry.Value; } } } return num; } private static EggGrow NextEgg(Stock stock, out string key, out int quality) { key = null; quality = 1; foreach (KeyValuePair<string, int> entry in stock.Entries) { if (Split(entry.Key, out var prefab, out var quality2)) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); EggGrow val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<EggGrow>() : null); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.m_grownPrefab)) { key = entry.Key; quality = quality2; return val2; } } } return null; } private int Flock(EggGrow egg) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) string name = ((Object)egg.m_grownPrefab).name; Growup component = egg.m_grownPrefab.GetComponent<Growup>(); string text = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_grownPrefab)) ? ((Object)component.m_grownPrefab).name : null); float value = Plugin.RoostReach.Value; int num = 0; foreach (Character allCharacter in Character.GetAllCharacters()) { if (Object.op_Implicit((Object)(object)allCharacter) && !allCharacter.IsDead() && !(Vector3.Distance(((Component)allCharacter).transform.position, ((Component)this).transform.position) > value)) { string prefabName = Utils.GetPrefabName(((Component)allCharacter).gameObject); if (prefabName == name || prefabName == text) { num++; } } } return num; } private string Warming() { List<float> list = Starts(); if (list.Count == 0) { return null; } string key; int quality; EggGrow val = NextEgg(Read(), out key, out quality); if (!Object.op_Implicit((Object)(object)val)) { return null; } float num = Mathf.Max(0f, val.m_growTime - (float)(ZNet.instance.GetTimeSeconds() - (double)list[0])); string arg = ((list.Count == 1) ? "an egg" : (list.Count + " eggs")); return $"Warming {arg}: next chick in {Mathf.CeilToInt(num / 60f)} min"; } public float GetHoverOffset() { return 0f; } public string GetHoverName() { return Localization.instance.Localize("$piece_potato_roost"); } public string GetHoverText() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return ""; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize("$piece_potato_roost\n$piece_noaccess"); } Stock stock = Read(); List<string> list = new List<string>(); foreach (KeyValuePair<string, int> entry in stock.Entries) { if (Split(entry.Key, out var prefab, out var quality)) { list.Add(entry.Value + " " + ItemName(prefab) + ((quality > 1) ? (" " + new string('★', quality - 1)) : "")); } } string text = ((list.Count == 0) ? "No eggs" : string.Join(", ", list.ToArray())); string text2 = Warming(); if (text2 != null) { text = text + "\n" + text2; } string text3 = "$piece_potato_roost" + $" ({stock.Total}/{Plugin.RoostCapacity.Value})\n" + text + "\n[<color=yellow><b>$KEY_Use</b></color>] Gather eggs: " + (Gathering ? "On" : "Off"); if (stock.Total > 0) { text3 += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Take the eggs"; } return Localization.instance.Localize(text3); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (hold || !Valid) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (alt) { if (Read().Total > 0) { view.InvokeRPC("PotatoRoost_Take", Array.Empty<object>()); } } else { bool gathering = Gathering; view.InvokeRPC("PotatoRoost_Toggle", Array.Empty<object>()); ((Character)user).Message((MessageType)2, gathering ? "The roost stops gathering eggs" : "The roost gathers eggs again", 0, (Sprite)null, false); } return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private static string ItemName(string prefab) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { return prefab; } return val2.m_itemData.m_shared.m_name; } private void RPC_Toggle(long sender) { if (Valid && view.IsOwner()) { view.GetZDO().Set("PotatoRoost.Off", Gathering); } } private void RPC_Take(long sender) { if (Valid && view.IsOwner()) { Stock stock = Read(); if (stock.Total != 0) { Write(new Stock()); view.InvokeRPC(sender, "PotatoRoost_Give", new object[1] { stock.Format() }); } } } private void RPC_Give(long sender, string packed) { //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) //IL_0035: 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_0019: 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_003a: 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) Player localPlayer = Player.m_localPlayer; Vector3 at = (Object.op_Implicit((Object)(object)localPlayer) ? (((Component)localPlayer).transform.position + Vector3.up) : (((Component)this).transform.position + Vector3.up)); foreach (KeyValuePair<string, int> entry in Stock.Parse(packed).Entries) { Hand(entry.Key, entry.Value, Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetInventory() : null, at); } if (Object.op_Implicit((Object)(object)localPlayer)) { ((Character)localPlayer).Message((MessageType)2, "You take the eggs", 0, (Sprite)null, false); } } private static void Hand(string key, int count, Inventory inventory, Vector3 at) { //IL_00b8: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (!Split(key, out var prefab, out var quality)) { return; } GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { return; } int num = count; int val3 = Math.Max(1, val2.m_itemData.m_shared.m_maxStackSize); while (num > 0) { int num2 = Math.Min(num, val3); num -= num2; ItemData val4 = val2.m_itemData.Clone(); val4.m_dropPrefab = val; val4.m_stack = num2; val4.m_quality = quality; if (inventory == null || !inventory.CanAddItem(val4, num2) || !inventory.AddItem(val4)) { ItemDrop.DropItem(val4, num2, at + Random.insideUnitSphere * 0.3f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); } } } private void OnDestroyed() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) if (!Valid || !view.IsOwner()) { return; } Stock stock = Read(); Write(new Stock()); foreach (KeyValuePair<string, int> entry in stock.Entries) { Hand(entry.Key, entry.Value, null, ((Component)this).transform.position + Vector3.up * 0.5f); } } private void ShowEggs(Stock stock) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)eggModels)) { Object.Destroy((Object)(object)eggModels); } eggModels = null; if (stock.Total == 0 || GUIManager.IsHeadless() || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } eggModels = new GameObject("Eggs"); eggModels.SetActive(false); eggModels.transform.SetParent(((Component)this).transform, false); ZDOID uid = view.GetZDO().m_uid; float num = 0f; Random random = new Random((int)(((ZDOID)(ref uid)).ID * 31) + ((ZDOID)(ref uid)).UserID.GetHashCode()); List<string> list = stock.Entries.SelectMany((KeyValuePair<string, int> entry) => Enumerable.Repeat(entry.Key, entry.Value)).Take(CubbyX.Length * 4).ToList(); for (int num2 = 0; num2 < list.Count; num2++) { if (!Split(list[num2], out var prefab, out var _)) { continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if (!Object.op_Implicit((Object)(object)itemPrefab)) { continue; } GameObject val = Object.Instantiate<GameObject>(itemPrefab, eggModels.transform, false); Trough.Strip(val); int num3 = num2 / 4; int num4 = num2 % 4; Quaternion rotation = Quaternion.Euler(0f, (float)random.NextDouble() * 360f, 0f) * Quaternion.Euler(90f, 0f, 0f); val.transform.localRotation = rotation; float num5 = 0f; float num6 = 0.096f; if (Trough.LocalBounds(val, out var bounds)) { Vector3 val2 = Vector3.Scale(((Bounds)(ref bounds)).size, val.transform.localScale); float num7 = Mathf.Max(val2.x, Mathf.Max(val2.y, val2.z)); float num8 = Mathf.Min(val2.x, Mathf.Min(val2.y, val2.z)); if (num7 > 0.001f) { float num9 = 0.12f / num7; Transform transform = val.transform; transform.localScale *= num9; num6 = (num7 + num8) / 2f * num9; if (!eggSizeLogged) { eggSizeLogged = true; Plugin.Log.LogInfo((object)$"Roost: {prefab} model is {num7:0.###} m long, shown at {0.12f} m."); } } Vector3 scale = val.transform.localScale; num5 = (from k in Enumerable.Range(0, 8) select (rotation * Vector3.Scale(new Vector3(((k & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((k & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((k & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z), scale)).y).Min(); } if (num4 == 0) { num = (float)random.NextDouble() * 360f; } Vector3 val3 = Quaternion.Euler(0f, num, 0f) * (Clutch[num4] * num6 * 0.9f); float num10 = num6 * 0.08f; float num11 = CubbyX[num3] * 1.3f + val3.x + (float)(random.NextDouble() - 0.5) * num10; float num12 = 0.065f + val3.z + (float)(random.NextDouble() - 0.5) * num10; val.transform.localPosition = new Vector3(num11, 0.325f - num5, num12); } eggModels.SetActive(true); } } internal sealed class Stock { private readonly List<KeyValuePair<string, int>> entries = new List<KeyValuePair<string, int>>(); public IEnumerable<KeyValuePair<string, int>> Entries => entries; public int Total => entries.Sum((KeyValuePair<string, int> entry) => entry.Value); public static Stock Parse(string text) { Stock stock = new Stock(); if (string.IsNullOrEmpty(text)) { return stock; } string[] array = text.Split(';'); foreach (string text2 in array) { int num = text2.LastIndexOf(':'); if (num > 0 && int.TryParse(text2.Substring(num + 1), out var result)) { stock.Add(text2.Substring(0, num), result); } } return stock; } public string Format() { return string.Join(";", entries.Select((KeyValuePair<string, int> entry) => entry.Key + ":" + entry.Value).ToArray()); } public int Count(string item) { int num = entries.FindIndex((KeyValuePair<string, int> entry) => entry.Key == item); if (num >= 0) { return entries[num].Value; } return 0; } public void Add(string item, int count) { if (!string.IsNullOrEmpty(item) && count > 0 && item.IndexOf(';') < 0 && item.IndexOf(':') < 0) { int num = entries.FindIndex((KeyValuePair<string, int> entry) => entry.Key == item); if (num < 0) { entries.Add(new KeyValuePair<string, int>(item, count)); } else { entries[num] = new KeyValuePair<string, int>(item, (int)Math.Min((long)entries[num].Value + (long)count, 2147483647L)); } } } public bool Remove(string item, int count) { int num = entries.FindIndex((KeyValuePair<string, int> entry) => entry.Key == item); if (num < 0 || count <= 0 || entries[num].Value < count) { return false; } int num2 = entries[num].Value - count; if (num2 == 0) { entries.RemoveAt(num); } else { entries[num] = new KeyValuePair<string, int>(item, num2); } return true; } } public class Trough : MonoBehaviour, Hoverable, Interactable { private const string FoodKey = "PotatoTrough.Food"; private const int MaxBaitInBowl = 4; private const int MaxFoodModels = 20; private const float DispenseDelay = 3f; internal const float Size = 1.21f; internal static readonly Vector3 BowlFloor = new Vector3(0f, 0.215f, 0f) * 1.21f; private static readonly Vector3 BowlCenter = new Vector3(0f, 0.3f, 0f) * 1.21f; private static readonly Vector3 BowlHalfSize = new Vector3(0.75f, 0.15f, 0.22f) * 1.21f; private static int itemMask; internal static readonly List<Trough> All = new List<Trough>(); private ZNetView view; private string shown; private GameObject foodModels; private float nextCheck; private float lastDispense = -100f; private const float InnerHalfLength = 0.847f; private const float InnerHalfWidth = 0.2299f; private const float FloorTop = 0.26862f; private const float MaxFoodHeight = 0.24200001f; private const float SinkIn = 0.35f; private bool Valid { get { if (Object.op_Implicit((Object)(object)view)) { return view.IsValid(); } return false; } } private void Awake() { view = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)view) && view.GetZDO() != null) { All.Add(this); view.Register<string, int>("PotatoTrough_Add", (Action<long, string, int>)RPC_Add); view.Register("PotatoTrough_Take", (Action<long>)RPC_Take); view.Register<string>("PotatoTrough_Give", (Action<long, string>)RPC_Give); view.Register<string>("PotatoTrough_Feed", (Action<long, string>)RPC_Feed); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } } } private void OnDestroy() { All.Remove(this); } internal Stock Read() { return Stock.Parse(Valid ? view.GetZDO().GetString("PotatoTrough.Food", "") : ""); } private void Write(Stock stock) { view.GetZDO().Set("PotatoTrough.Food", stock.Format()); } private void Update() { if (!(Time.time < nextCheck) && Valid) { nextCheck = Time.time + 0.5f; string text = (Plugin.TroughShowFood.Value ? view.GetZDO().GetString("PotatoTrough.Food", "") : ""); if (!(text == shown)) { shown = text; ShowFood(Stock.Parse(text)); } } } public float GetHoverOffset() { return 0f; } public string GetHoverName() { return Localization.instance.Localize("$piece_potato_trough"); } public string GetHoverText() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!Valid) { return ""; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize("$piece_potato_trough\n$piece_noaccess"); } Stock stock = Read(); string text = ((stock.Total == 0) ? "Empty" : string.Join(", ", stock.Entries.Select((KeyValuePair<string, int> entry) => entry.Value + " " + ItemName(entry.Key)).ToArray())); string text2 = "$piece_potato_trough" + $" ({stock.Total}/{Plugin.TroughCapacity.Value})\n" + text + "\n[<color=yellow><b>1-8</b></color>] Add food from your hotbar"; if (stock.Total > 0) { text2 += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Take the food back"; } return Localization.instance.Localize(text2); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (hold || !alt || !Valid) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (Read().Total > 0) { view.InvokeRPC("PotatoTrough_Take", Array.Empty<object>()); } return true; } public bool UseItem(Humanoid user, ItemData item) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!Valid || item == null) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (!Object.op_Implicit((Object)(object)item.m_dropPrefab) || !Feeding.IsAnimalFood(item)) { ((Character)user).Message((MessageType)2, "No animal eats that", 0, (Sprite)null, false); return true; } return Add(user, item); } private bool Add(Humanoid user, ItemData item) { int num = Plugin.TroughCapacity.Value - Read().Total; if (num <= 0) { ((Character)user).Message((MessageType)2, "The trough is full", 0, (Sprite)null, false); return true; } int num2 = Math.Min(num, item.m_stack); string name = ((Object)item.m_dropPrefab).name; string name2 = item.m_shared.m_name; if (!user.GetInventory().RemoveItem(item, num2)) { return true; } view.InvokeRPC("PotatoTrough_Add", new object[2] { name, num2 }); ((Character)user).Message((MessageType)2, $"$msg_added {name2} x{num2}", 0, (Sprite)null, false); return true; } private static string ItemName(string prefab) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { return prefab; } return val2.m_itemData.m_shared.m_name; } private void RPC_Add(long sender, string prefab, int count) { if (Valid && view.IsOwner() && count > 0 && Object.op_Implicit((Object)(object)ObjectDB.instance) && Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(prefab))) { Stock stock = Read(); stock.Add(prefab, count); Write(stock); } } private void RPC_Take(long sender) { if (Valid && view.IsOwner()) { Stock stock = Read(); if (stock.Total != 0) { Write(new Stock()); view.InvokeRPC(sender, "PotatoTrough_Give", new object[1] { stock.Format() }); } } } private void RPC_Give(long sender, string packed) { //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_003f: 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_0019: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Vector3 val = (Object.op_Implicit((Object)(object)localPlayer) ? (((Component)localPlayer).transform.position + Vector3.up) : (((Component)this).transform.position + Vector3.up * 0.6f)); foreach (KeyValuePair<string, int> entry in Stock.Parse(packed).Entries) { GameObject val2 = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(entry.Key) : null); ItemDrop val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val3)) { continue; } int num = entry.Value; int val4 = Math.Max(1, val3.m_itemData.m_shared.m_maxStackSize); while (num > 0) { int num2 = Math.Min(num, val4); num -= num2; Inventory val5 = (Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetInventory() : null); if (val5 == null || !val5.CanAddItem(val2, num2) || !val5.AddItem(val2, num2)) { ItemDrop.DropItem(Item(val2, num2), num2, val, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); } } } if (Object.op_Implicit((Object)(object)localPlayer)) { ((Character)localPlayer).Message((MessageType)2, "You take the food back", 0, (Sprite)null, false); } } private static ItemData Item(GameObject prefab, int count) { ItemData obj = prefab.GetComponent<ItemDrop>().m_itemData.Clone(); obj.m_dropPrefab = prefab; obj.m_stack = count; return obj; } private void OnDestroyed() { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (!Valid || !view.IsOwner()) { return; } Stock stock = Read(); Write(new Stock()); foreach (KeyValuePair<string, int> entry in stock.Entries) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(entry.Key) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (Object.op_Implicit((Object)(object)val2)) { int num = entry.Value; int val3 = Math.Max(1, val2.m_itemData.m_shared.m_maxStackSize); while (num > 0) { int num2 = Math.Min(num, val3); num -= num2; Vector3 val4 = ((Component)this).transform.position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.3f; ItemDrop.DropItem(Item(val, num2), num2, val4, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); } } } } internal string FoodFor(MonsterAI animal) { return Read().Entries.Select((KeyValuePair<string, int> entry) => entry.Key).FirstOrDefault((string prefab) => Feeding.CanEat(animal, prefab)); } internal ItemDrop Dispense(string prefab) { if (Time.time - lastDispense < 3f || BaitInBowl() >= 4) { return null; } lastDispense = Time.time; if (view.IsOwner()) { return DropBait(prefab); } view.InvokeRPC("PotatoTrough_Feed", new object[1] { prefab }); return null; } private void RPC_Feed(long sender, string prefab) { if (Valid && view.IsOwner() && BaitInBowl() < 4) { DropBait(prefab); } } private ItemDrop DropBait(string prefab) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) //IL_0090: 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_009e: 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) GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.GetComponent<ItemDrop>())) { return null; } Stock stock = Read(); if (!stock.Remove(prefab, 1)) { return null; } Write(stock); Vector3 val2 = ((Component)this).transform.TransformPoint(BowlFloor + new Vector3(Random.Range(-0.45f, 0.45f) * 1.21f, 0.12f, Random.Range(-0.08f, 0.08f) * 1.21f)); ItemDrop obj = ItemDrop.DropItem(Item(val, 1), 1, val2, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); Feeding.MarkBait(obj); return obj; } private int BaitInBowl() { //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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (itemMask == 0) { itemMask = LayerMask.GetMask(new string[1] { "item" }); } HashSet<ItemDrop> hashSet = new HashSet<ItemDrop>(); Collider[] array = Physics.OverlapBox(((Component)this).transform.TransformPoint(BowlCenter), BowlHalfSize, ((Component)this).transform.rotation, itemMask); foreach (Collider val in array) { ItemDrop val2 = (Object.op_Implicit((Object)(object)val.attachedRigidbody) ? ((Component)val.attachedRigidbody).GetComponent<ItemDrop>() : null); if (Object.op_Implicit((Object)(object)val2) && Feeding.IsBait(val2)) { hashSet.Add(val2); } } return hashSet.Count; } private void ShowFood(Stock stock) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)foodModels)) { Object.Destroy((Object)(object)foodModels); } foodModels = null; int total = stock.Total; if (total == 0 || GUIManager.IsHeadless() || !Object.op_Implicit((Object)(object)ObjectDB.instance) || !Valid) { return; } foodModels = new GameObject("Food"); foodModels.SetActive(false); foodModels.transform.SetParent(((Component)this).transform, false); int num = Mathf.Clamp(Mathf.CeilToInt((float)total / 3f), 1, 20); int i = 0; ZDOID uid = view.GetZDO().m_uid; Random random = new Random((int)(((ZDOID)(ref uid)).ID * 31) + ((ZDOID)(ref uid)).UserID.GetHashCode()); List<GameObject> list = new List<GameObject>(); foreach (KeyValuePair<string, int> entry in stock.Entries) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(entry.Key); if (!Object.op_Implicit((Object)(object)itemPrefab)) { continue; } int num2 = Mathf.Max(1, Mathf.RoundToInt((float)num * (float)entry.Value / (float)total)); for (int j = 0; j < num2; j++) { if (list.Count >= num) { break; } list.Add(itemPrefab); } } for (int num3 = list.Count - 1; num3 > 0; num3--) { int num4 = random.Next(num3 + 1); List<GameObject> list2 = list; int index = num3; int index2 = num4; GameObject value = list[num4]; GameObject value2 = list[num3]; list2[index] = value; list[index2] = value2; } for (; i < list.Count; i++) { GameObject copy = Object.Instantiate<GameObject>(list[i], foodModels.transform, false); Strip(copy); float num5 = ((list.Count == 1) ? 0f : Mathf.Lerp(-0.66550004f, 0.66550004f, (float)i / (float)(list.Count - 1))); Place(copy, num5 + (float)(random.NextDouble() - 0.5) * 0.12f, (float)random.NextDouble(), random); } foodModels.SetActive(true); } private static void Place(GameObject copy, float wantX, float sideways, Random random) { //IL_000c: 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_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_006e: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) Vector3 localScale = copy.transform.localScale; if (!LocalBounds(copy, out var bounds)) { copy.transform.localPosition = new Vector3(Mathf.Clamp(wantX, -0.7260001f, 0.7260001f), 0.29862002f, 0f); return; } Vector3 size = Vector3.Scale(((Bounds)(ref bounds)).size, localScale); Vector3[] array = (Vector3[])(object)new Vector3[3] { Vector3.right, Vector3.up, Vector3.forward }; int[] array2 = new int[3] { 0, 1, 2 }.OrderByDescending((int axis) => ((Vector3)(ref size))[axis]).ToArray(); Quaternion val = Quaternion.Inverse(Quaternion.LookRotation(array[array2[1]], array[array2[2]])); Quaternion val2 = Quaternion.Euler(0f, (float)random.Next(2) * 180f + (float)(random.NextDouble() - 0.5) * 24f, 0f) * val; Vector3[] array3 = (Vector3[])(object)new Vector3[8]; Vector3 val3 = default(Vector3); for (int num = 0; num < 8; num++) { ((Vector3)(ref val3))..ctor(((num & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((num & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((num & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z); array3[num] = val2 * Vector3.Scale(val3, localScale); } Vector3 val4 = ((IEnumerable<Vector3>)array3).Aggregate((Func<Vector3, Vector3, Vector3>)Vector3.Min); Vector3 val5 = ((IEnumerable<Vector3>)array3).Aggregate((Func<Vector3, Vector3, Vector3>)Vector3.Max); Vector3 val6 = val5 - val4; float num2 = Mathf.Min(new float[4] { 1f, 1.694f / Mathf.Max(val6.x, 0.001f), 0.4598f / Mathf.Max(val6.z, 0.001f), 0.24200001f / Mathf.Max(val6.y, 0.001f) }); val4 *= num2; val5 *= num2; float num3 = -0.847f - val4.x; float num4 = 0.847f - val5.x; float num5 = -0.2299f - val4.z; float num6 = 0.2299f - val5.z; float num7 = ((num3 <= num4) ? Mathf.Clamp(wantX, num3, num4) : ((num3 + num4) / 2f)); float num8 = ((num5 <= num6) ? Mathf.Lerp(num5, num6, sideways) : ((num5 + num6) / 2f)); copy.transform.localScale = localScale * num2; copy.transform.localRotation = val2; copy.transform.localPosition = new Vector3(num7, 0.26862f - val4.y - (val5.y - val4.y) * 0.35f, num8); } private static bool Shown(Transform part, Transform root) { while (Object.op_Implicit((Object)(object)part) && (Object)(object)part != (Object)(object)root) { if (!((Component)part).gameObject.activeSelf) { return false; } part = part.parent; } return true; } internal static bool LocalBounds(GameObject copy, out Bounds bounds) { //IL_0001: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00ec: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or mi