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 Hugin What The Hel Is That v1.0.0
Hugin.dll
Decompiled 8 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.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Hugin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b2d1831e78047b263c4f86bf4960531bae2d7afb")] [assembly: AssemblyProduct("Hugin")] [assembly: AssemblyTitle("Hugin")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Hugin { internal class BossBar : MonoBehaviour { private const float IconSize = 20f; private static readonly FieldRef<EnemyHud, IDictionary> Huds = AccessTools.FieldRefAccess<EnemyHud, IDictionary>(AccessTools.Field(typeof(EnemyHud), "m_huds")); private static int _frame = -1; private static bool _showing; private static Rect _bar; private static Character _boss; private static Character _groupsFor; private static List<Weakness.Group> _groups; internal static bool Find(out Rect bar, out Character boss) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (_frame != Time.frameCount) { _frame = Time.frameCount; _showing = Locate(out _bar, out _boss); } bar = _bar; boss = _boss; return _showing; } private static bool Locate(out Rect bar, out Character boss) { //IL_0001: 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_00cd: Unknown result type (might be due to invalid IL or missing references) bar = default(Rect); boss = null; EnemyHud instance = EnemyHud.instance; if ((Object)(object)instance == (Object)null || Huds == null) { return false; } IDictionary dictionary = Huds.Invoke(instance); if (dictionary == null) { return false; } foreach (DictionaryEntry item in dictionary) { object key = item.Key; Character val = (Character)((key is Character) ? key : null); if (!((Object)(object)val == (Object)null) && val.IsBoss()) { GameObject value = Traverse.Create(item.Value).Field("m_gui").GetValue<GameObject>(); RectTransform val2 = (RectTransform)(((Object)(object)value != (Object)null && value.activeInHierarchy) ? /*isinst with value type is only supported in some contexts*/: null); if (!((Object)(object)val2 == (Object)null)) { bar = ToGui(val2); boss = val; return ((Rect)(ref bar)).width > 0f; } } } return false; } private static Rect ToGui(RectTransform rt) { //IL_001f: 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) //IL_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); Canvas componentInParent = ((Component)rt).GetComponentInParent<Canvas>(); Camera obj = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null); Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, array[0]); Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[2]); float num = (float)Screen.height / 1080f * Plugin.UiScale.Value; return new Rect(val.x / num, ((float)Screen.height - val2.y) / num, (val2.x - val.x) / num, (val2.y - val.y) / num); } internal static float Bottom() { if (!Find(out var bar, out var _)) { return 0f; } return ((Rect)(ref bar)).yMax + ((Plugin.BossBar.Value && Plugin.ShowWeaknesses.Value) ? 26f : 0f) + 8f; } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0106: 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_0075: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((int)Event.current.type != 7 || !Plugin.BossBar.Value || !Plugin.ShowWeaknesses.Value || Panel.ScreenHidden() || !Find(out var bar, out var boss)) { return; } if ((Object)(object)boss != (Object)(object)_groupsFor) { _groupsFor = boss; _groups = Weakness.Groups(boss.m_damageModifiers); } GUISkin skin = GUI.skin; GUI.skin = Ui.Skin; float width; float height; Matrix4x4 matrix = Ui.BeginScaled(out width, out height); try { if (_groups.Count == 0) { Ui.Label(new Rect(((Rect)(ref bar)).center.x - 150f, ((Rect)(ref bar)).yMax + 6f, 300f, 20f), "<color=#b9ad98>No weaknesses or resistances</color>", Ui.SmallCenter); } else { Weakness.Draw(_groups, Mathf.Round(((Rect)(ref bar)).center.x - Weakness.Width(_groups, 20f) * 0.5f), ((Rect)(ref bar)).yMax + 6f, 20f); } } finally { GUI.matrix = matrix; GUI.skin = skin; } } } internal static class Details { private static readonly Color WorkColor = new Color(0.95f, 0.75f, 0.3f); private static readonly MethodInfo GetSlot = AccessTools.Method(typeof(CookingStation), "GetSlot", (Type[])null, (Type[])null); private static readonly MethodInfo GetConversion = AccessTools.Method(typeof(CookingStation), "GetItemConversion", (Type[])null, (Type[])null); private static readonly Dictionary<string, MethodInfo> Methods = new Dictionary<string, MethodInfo>(); private static readonly Dictionary<string, FieldInfo> Fields = new Dictionary<string, FieldInfo>(); internal static void Production(GameObject go, ZDO zdo, Info info) { Smelter component = go.GetComponent<Smelter>(); if ((Object)(object)component != (Object)null) { Smelter(component, info); } Fermenter component2 = go.GetComponent<Fermenter>(); if ((Object)(object)component2 != (Object)null) { Fermenter(component2, info); } Beehive component3 = go.GetComponent<Beehive>(); if ((Object)(object)component3 != (Object)null) { Beehive(component3, info); } CookingStation component4 = go.GetComponent<CookingStation>(); if ((Object)(object)component4 != (Object)null) { Cooking(component4, info); } } internal static void Base(GameObject go, ZDO zdo, Info info) { if (zdo == null) { return; } PrivateArea component = go.GetComponent<PrivateArea>(); if ((Object)(object)component != (Object)null) { string text = Call<string>(component, "GetCreatorName") ?? ""; bool flag = Call<bool>(component, "IsEnabled"); info.Lines.Add((flag ? "<color=#9be07a>Active</color>" : "Off") + ((text.Length > 0) ? (", " + text + "'s") : "")); } Bed component2 = go.GetComponent<Bed>(); if ((Object)(object)component2 != (Object)null) { string text2 = Call<string>(component2, "GetOwnerName") ?? ""; info.Lines.Add((text2.Length > 0) ? (text2 + "'s bed") : "No owner"); } TombStone component3 = go.GetComponent<TombStone>(); if ((Object)(object)component3 != (Object)null) { string ownerName = component3.GetOwnerName(); if (!string.IsNullOrEmpty(ownerName)) { info.Title = ownerName + "'s grave"; } } TeleportWorld component4 = go.GetComponent<TeleportWorld>(); if ((Object)(object)component4 != (Object)null) { string text3 = component4.GetText(); info.Lines.Add(string.IsNullOrEmpty(text3) ? "No tag" : ("Tag: " + text3)); } ItemStand component5 = go.GetComponent<ItemStand>(); if ((Object)(object)component5 != (Object)null) { string text4 = (component5.HaveAttachment() ? ItemName(component5.GetAttachedItem()) : null); info.Lines.Add((text4 != null) ? ("Holds " + text4) : "Empty"); } ArmorStand component6 = go.GetComponent<ArmorStand>(); if (!((Object)(object)component6 != (Object)null) || component6.m_slots == null) { return; } int num = 0; for (int i = 0; i < component6.m_slots.Count; i++) { if (component6.HaveAttachment(i)) { num++; } } info.Lines.Add((num == 0) ? "Empty" : $"{num} / {component6.m_slots.Count} slots used"); } internal static void Creature(Character c, Info info) { if (!c.IsTamed()) { string text = Temper(c); if (text.Contains("Hostile")) { info.More.Add(text); } else if (text.Length > 0) { info.Lines.Add(text); } } Tameable component = ((Component)c).GetComponent<Tameable>(); if ((Object)(object)component != (Object)null && c.IsTamed()) { string text2 = component.GetText(); if (!string.IsNullOrEmpty(text2)) { info.Title = text2 + " <color=#b9ad98>(" + info.Title + ")</color>"; } if (Call<bool>(component, "HaveSaddle")) { info.Lines.Add("Saddled"); } } Procreation component2 = ((Component)c).GetComponent<Procreation>(); ZNetView component3 = ((Component)c).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && c.IsTamed() && (Object)(object)component3 != (Object)null && component3.IsValid() && (Object)(object)ZNet.instance != (Object)null) { long num = component3.GetZDO().GetLong(ZDOVars.s_pregnant, 0L); if (num != 0L) { double totalSeconds = (ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds; double num2 = (double)component2.m_pregnancyDuration - totalSeconds; info.Lines.Add((num2 > 0.0) ? ("Expecting, due in " + Time(num2)) : "Expecting, any moment now"); } else if (component2.ReadyForProcreation()) { info.Lines.Add("Ready to breed"); } } } private static string Temper(Character c) { BaseAI baseAI = c.GetBaseAI(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)baseAI == (Object)null || (Object)(object)localPlayer == (Object)null) { return ""; } if (baseAI is AnimalAI) { return "Runs away"; } if (!BaseAI.IsEnemy(c, (Character)(object)localPlayer)) { return "<color=#9be07a>Friendly</color>"; } if (baseAI.IsAggravatable() && !baseAI.IsAggravated()) { return "Neutral until provoked"; } if (baseAI.m_passiveAggresive) { return "Attacks if attacked"; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)30)) { return "Passive (world setting)"; } return "<color=#ff6f55>Hostile</color>"; } private static void Smelter(Smelter s, Info info) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) int num = Call<int>(s, "GetQueueSize"); int num2 = Call<int>(s, "GetProcessedQueueSize"); float num3 = Call<float>(s, "GetFuel"); float num4 = Call<float>(s, "GetBakeTimer"); string text = Call<string>(s, "GetQueuedOre"); if (s.m_maxOre > 0) { info.Lines.Add((num > 0) ? $"{L(ItemNameByPrefab(text) ?? text)}: {num} / {s.m_maxOre}" : "Nothing to smelt"); } if (s.m_maxFuel > 0) { info.Bar = Mathf.Clamp01(num3 / (float)s.m_maxFuel); info.BarColor = new Color(0.95f, 0.6f, 0.2f); info.BarText = string.Format("{0} {1} / {2}", L(((Object)(object)s.m_fuelItem != (Object)null) ? s.m_fuelItem.m_itemData.m_shared.m_name : "Fuel"), Mathf.CeilToInt(num3), s.m_maxFuel); } if (num > 0 && s.m_secPerProduct > 0f && (s.m_maxFuel == 0 || num3 > 0f)) { string text2 = ((s.m_requiresRoof && !Field<bool>(s, "m_haveRoof")) ? "needs a roof" : (Field<bool>(s, "m_blockedSmoke") ? "smoke is blocked" : (((Object)(object)s.m_windmill != (Object)null && s.m_windmill.GetPowerOutput() <= 0f) ? "no wind" : null))); info.Lines.Add((text2 != null) ? ("<color=#ff6f55>Stopped: " + text2 + "</color>") : ("Next in " + Time(Mathf.Max(0f, s.m_secPerProduct - num4)))); } if (num2 > 0) { info.Lines.Add(string.Format("<color={0}>{1} ready to take</color>", "#9be07a", num2)); } } private static void Fermenter(Fermenter f, Info info) { //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) string text = CallObject(f, "GetStatus")?.ToString(); string text2 = Call<string>(f, "GetContentName"); if (text == "Empty" || string.IsNullOrEmpty(text2)) { info.Lines.Add("Empty"); return; } info.Lines.Add(L(text2)); bool flag = Field<bool>(f, "m_hasRoof"); bool flag2 = Field<bool>(f, "m_exposed"); if (text == "Ready") { info.Lines.Add("<color=#9be07a>Ready to tap</color>"); return; } if (!flag) { info.Lines.Add("<color=#ff6f55>Won't ferment: needs a roof</color>"); return; } if (flag2) { info.Lines.Add("<color=#ff6f55>Won't ferment: too exposed, needs walls</color>"); return; } double num = Call<double>(f, "GetFermentationTime"); float bar = ((f.m_fermentationDuration > 0f) ? Mathf.Clamp01((float)(num / (double)f.m_fermentationDuration)) : 0f); info.Bar = bar; info.BarColor = WorkColor; info.BarText = "Ready in " + Time((double)f.m_fermentationDuration - num); } private static void Beehive(Beehive b, Info info) { //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) int num = Call<int>(b, "GetHoneyLevel"); info.Bar = ((b.m_maxHoney > 0) ? Mathf.Clamp01((float)num / (float)b.m_maxHoney) : 0f); info.BarColor = WorkColor; info.BarText = $"Honey {num} / {b.m_maxHoney}"; } private static void Cooking(CookingStation station, Info info) { if (GetSlot == null || GetConversion == null || station.m_slots == null) { return; } int num = 0; int num2 = 0; int num3 = 0; float num4 = float.MaxValue; float num5 = float.MaxValue; for (int i = 0; i < station.m_slots.Length; i++) { object[] array = new object[5] { i, null, 0f, null, false }; try { GetSlot.Invoke(station, array); } catch (Exception) { return; } string text = array[1] as string; if (string.IsNullOrEmpty(text)) { continue; } float num6 = (float)array[2]; int num7 = Convert.ToInt32(array[3]); object? obj = GetConversion.Invoke(station, new object[1] { text }); ItemConversion val = (ItemConversion)((obj is ItemConversion) ? obj : null); switch (num7) { case 2: num3++; break; case 1: num2++; if (val != null && station.m_canOvercookItems) { num5 = Mathf.Min(num5, val.m_cookTime * 2f - num6); } break; default: num++; if (val != null) { num4 = Mathf.Min(num4, val.m_cookTime - num6); } break; } } if (num + num2 + num3 == 0) { info.Lines.Add("Nothing cooking"); return; } bool flag = station.m_useFuel && Call<float>(station, "GetFuel") > 0f && (station.m_useFueldWhileEmpty || Call<bool>(station, "HaveUncookedItem")); bool flag2 = (station.m_requireFire && Call<bool>(station, "IsFireLit")) || flag; if (!flag2 && num + num2 > 0) { info.Lines.Add("<color=#ff6f55>Stopped: " + (station.m_useFuel ? "no fuel" : "no fire under it") + "</color>"); } if (num > 0) { info.Lines.Add($"{num} cooking" + ((flag2 && num4 < float.MaxValue) ? (", first done in " + Time(Mathf.Max(0f, num4))) : "")); } if (num2 > 0) { info.Lines.Add(string.Format("<color={0}>{1} done</color>", "#9be07a", num2) + ((flag2 && num5 < float.MaxValue) ? ("<color=#f0b04a>, burns in " + Time(Mathf.Max(0f, num5)) + "</color>") : "")); } if (num3 > 0) { info.Lines.Add(string.Format("<color={0}>{1} burnt</color>", "#ff6f55", num3)); } } private static object CallObject(object target, string method) { string key = target.GetType().FullName + "." + method; if (!Methods.TryGetValue(key, out var value)) { value = AccessTools.Method(target.GetType(), method, Type.EmptyTypes, (Type[])null); Methods[key] = value; } if (value == null) { return null; } try { return value.Invoke(target, null); } catch (Exception) { return null; } } private static T Call<T>(object target, string method) { object obj = CallObject(target, method); if (obj is T) { return (T)obj; } return default(T); } private static T Field<T>(object target, string field) { string key = target.GetType().FullName + "." + field; if (!Fields.TryGetValue(key, out var value)) { value = (Fields[key] = AccessTools.Field(target.GetType(), field)); } if (value != null) { object value2 = value.GetValue(target); if (value2 is T) { return (T)value2; } } return default(T); } private static string ItemName(int hash) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(hash) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 != (Object)null)) { return null; } return L(val2.m_itemData.m_shared.m_name); } private static string ItemNameByPrefab(string prefab) { if (string.IsNullOrEmpty(prefab) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if (!((Object)(object)itemPrefab != (Object)null)) { return null; } return itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_name; } private static string L(string token) { return Looking.L(token); } internal static string Time(double seconds) { if (seconds < 60.0) { return $"{Mathf.CeilToInt((float)seconds)} s"; } int num = Mathf.CeilToInt((float)(seconds / 60.0)); if (num < 60) { return $"{num} min"; } return $"{num / 60} h {num % 60} min"; } } internal static class Extended { private enum Tool { None, Pickaxe, Axe } private static readonly Dictionary<string, string> ToolNames = new Dictionary<string, string>(); internal static void Resistances(List<Weakness.Group> groups, Info info) { foreach (Weakness.Group group in groups) { List<string> list = new List<string>(); foreach (Weakness.Icon icon in group.Icons) { list.Add((icon.Amount != null) ? (icon.Name + " (" + icon.Amount + ")") : icon.Name); } info.More.Add(group.Text + " " + string.Join(", ", list.ToArray())); } } internal static void Drops(GameObject go, Info info) { HashSet<Sprite> seen = new HashSet<Sprite>(); CharacterDrop component = go.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null) { foreach (Drop drop in component.m_drops) { Add(drop.m_prefab, info, seen); } } AddTable(go.GetComponent<TreeBase>()?.m_dropWhenDestroyed, info, seen); AddTable(go.GetComponent<TreeLog>()?.m_dropWhenDestroyed, info, seen); AddTable(go.GetComponent<MineRock>()?.m_dropItems, info, seen); AddTable(go.GetComponent<MineRock5>()?.m_dropItems, info, seen); AddTable(go.GetComponent<DropOnDestroyed>()?.m_dropWhenDestroyed, info, seen); Pickable component2 = go.GetComponent<Pickable>(); if ((Object)(object)component2 != (Object)null) { Add(component2.m_itemPrefab, info, seen); AddTable(component2.m_extraDrops, info, seen); } } private static void AddTable(DropTable table, Info info, HashSet<Sprite> seen) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (table?.m_drops == null) { return; } foreach (DropData drop in table.m_drops) { Add(drop.m_item, info, seen); } } private static void Add(GameObject prefab, Info info, HashSet<Sprite> seen) { object obj; if (!((Object)(object)prefab != (Object)null)) { obj = null; } else { ItemDrop component = prefab.GetComponent<ItemDrop>(); obj = ((component != null) ? component.m_itemData.GetIcon() : null); } Sprite val = (Sprite)obj; if ((Object)(object)val != (Object)null && seen.Add(val)) { info.Drops.Add(val); } } internal static void Item(ItemData data, Info info) { SharedData shared = data.m_shared; if (!shared.m_teleportable) { info.Lines.Add("<color=#ff6f55>Can't go through portals</color>"); } info.More.Add($"Weight {data.GetWeight(-1):0.#}" + ((data.m_stack > 1) ? $" ({shared.m_weight:0.#} each)" : "")); if (shared.m_value > 0) { info.More.Add($"Sells for {shared.m_value * data.m_stack} coins"); } if (shared.m_maxStackSize > 1) { info.More.Add($"Stacks to {shared.m_maxStackSize}"); } } internal static void ToolNeed(GameObject go, Info info) { if (!Requirement(go, out var tool, out var tier) || tool == Tool.None) { return; } string text = Weakest(tool, tier); if (text != null) { if (!Carrying(tool, tier)) { info.Lines.Add("<color=#ff6f55>Needs " + text + "</color>"); } else if (tier > 0) { info.More.Add("Needs " + text); } } } private static bool Requirement(GameObject go, out Tool tool, out int tier) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) tool = Tool.None; tier = 0; MineRock component = go.GetComponent<MineRock>(); MineRock5 component2 = go.GetComponent<MineRock5>(); TreeBase component3 = go.GetComponent<TreeBase>(); TreeLog component4 = go.GetComponent<TreeLog>(); Destructible component5 = go.GetComponent<Destructible>(); if ((Object)(object)component != (Object)null) { Set(component.m_damageModifiers, component.m_minToolTier, out tool, out tier); } else if ((Object)(object)component2 != (Object)null) { Set(component2.m_damageModifiers, component2.m_minToolTier, out tool, out tier); } else if ((Object)(object)component3 != (Object)null) { Set(component3.m_damageModifiers, component3.m_minToolTier, out tool, out tier); } else if ((Object)(object)component4 != (Object)null) { Set(component4.m_damages, component4.m_minToolTier, out tool, out tier); } else { if (!((Object)(object)component5 != (Object)null)) { return false; } Set(component5.m_damages, component5.m_minToolTier, out tool, out tier); } return true; } private static void Set(DamageModifiers m, int minTier, out Tool tool, out int tier) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0050: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) tier = minTier; bool flag = Immune(m.m_blunt) && Immune(m.m_slash) && Immune(m.m_pierce); if (flag && !Immune(m.m_pickaxe) && Immune(m.m_chop)) { tool = Tool.Pickaxe; } else if (flag && !Immune(m.m_chop) && Immune(m.m_pickaxe)) { tool = Tool.Axe; } else { tool = Tool.None; } } private static bool Immune(DamageModifier m) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)m != 3) { return (int)m == 4; } return true; } private static bool Fits(SharedData shared, Tool tool, int tier) { if (shared.m_toolTier >= tier) { if (tool != Tool.Pickaxe) { return shared.m_damages.m_chop > 0f; } return shared.m_damages.m_pickaxe > 0f; } return false; } private static bool Carrying(Tool tool, int tier) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { if (Fits(allItem.m_shared, tool, tier)) { return true; } } return false; } private static string Weakest(Tool tool, int tier) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) string key = tool.ToString() + "/" + tier; if (ToolNames.TryGetValue(key, out var value)) { return value; } SharedData val = null; if ((Object)(object)ObjectDB.instance != (Object)null) { foreach (GameObject item in ObjectDB.instance.m_items) { SharedData val2 = ((!((Object)(object)item != (Object)null)) ? null : item.GetComponent<ItemDrop>()?.m_itemData.m_shared); if (val2 != null && Fits(val2, tool, tier) && (int)val2.m_itemType != 0 && (val == null || val2.m_toolTier < val.m_toolTier)) { val = val2; } } } if (val == null || Localization.instance == null) { return null; } string text = Looking.L(val.m_name); if (tier == 0) { text = ((tool == Tool.Pickaxe) ? "a pickaxe" : "an axe"); } else { text = text.ToLowerInvariant(); text = (("aeiou".IndexOf(text[0]) >= 0) ? "an " : "a ") + text + " or better"; } ToolNames[key] = text; return text; } } internal static class GameArt { private static Dictionary<string, Sprite> _sprites; private static readonly Dictionary<Sprite, Rect> UvCache = new Dictionary<Sprite, Rect>(); internal static Sprite Find(string name) { if (_sprites == null) { _sprites = new Dictionary<string, Sprite>(); Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val in array) { if ((Object)(object)val != (Object)null && !_sprites.ContainsKey(((Object)val).name)) { _sprites[((Object)val).name] = val; } } } if (!_sprites.TryGetValue(name, out var value) || !((Object)(object)value != (Object)null)) { return null; } return value; } internal static bool UvRect(Sprite sprite, out Rect uv) { //IL_0001: 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_005c: 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) uv = default(Rect); if ((Object)(object)sprite == (Object)null) { return false; } if (UvCache.TryGetValue(sprite, out uv)) { return ((Rect)(ref uv)).width > 0f; } bool flag = ComputeUvRect(sprite, out uv); if (UvCache.Count > 512) { UvCache.Clear(); } UvCache[sprite] = (Rect)(flag ? uv : default(Rect)); return flag; } private static bool ComputeUvRect(Sprite sprite, out Rect uv) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) uv = default(Rect); if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null) { return false; } if (sprite.packed && (int)sprite.packingRotation != 0) { return false; } Vector2[] uv2 = sprite.uv; if (uv2 == null || uv2.Length == 0) { return false; } Vector2 val = uv2[0]; Vector2 val2 = uv2[0]; Vector2[] array = uv2; foreach (Vector2 val3 in array) { val = Vector2.Min(val, val3); val2 = Vector2.Max(val2, val3); } uv = Rect.MinMaxRect(val.x, val.y, val2.x, val2.y); if (((Rect)(ref uv)).width > 0f) { return ((Rect)(ref uv)).height > 0f; } return false; } private static bool CoversRect(Sprite sprite) { //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0094: Unknown result type (might be due to invalid IL or missing references) Vector2[] vertices = sprite.vertices; if (vertices == null || vertices.Length == 0) { return false; } Vector2 val = vertices[0]; Vector2 val2 = vertices[0]; Vector2[] array = vertices; foreach (Vector2 val3 in array) { val = Vector2.Min(val, val3); val2 = Vector2.Max(val2, val3); } Vector2 val4 = (val2 - val) * sprite.pixelsPerUnit; float x = val4.x; Rect rect = sprite.rect; if (Mathf.Abs(x - ((Rect)(ref rect)).width) <= 1.5f) { float y = val4.y; rect = sprite.rect; return Mathf.Abs(y - ((Rect)(ref rect)).height) <= 1.5f; } return false; } internal static Texture2D Copy(string name, out RectOffset border) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_00a8: 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_00c0: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_010a: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_012a: Expected O, but got Unknown border = null; Sprite val = Find(name); if ((Object)(object)val == (Object)null || !UvRect(val, out var uv) || !CoversRect(val)) { return null; } Rect rect = val.rect; int num = Mathf.RoundToInt(((Rect)(ref rect)).width); rect = val.rect; int num2 = Mathf.RoundToInt(((Rect)(ref rect)).height); RenderTexture active = RenderTexture.active; RenderTexture temporary = RenderTexture.GetTemporary(num, num2, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); try { Graphics.Blit((Texture)(object)val.texture, temporary, new Vector2(((Rect)(ref uv)).width, ((Rect)(ref uv)).height), new Vector2(((Rect)(ref uv)).x, ((Rect)(ref uv)).y)); RenderTexture.active = temporary; Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false, false) { name = "Hugin_" + name, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; val2.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0); val2.Apply(); Vector4 border2 = val.border; border = new RectOffset(Mathf.RoundToInt(border2.x), Mathf.RoundToInt(border2.z), Mathf.RoundToInt(border2.w), Mathf.RoundToInt(border2.y)); return val2; } catch (Exception ex) { Debug.LogWarning((object)("[Hugin] Couldn't copy UI sprite " + name + ": " + ex.Message)); return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } internal static Texture2D Composite(Texture2D bottom, Texture2D top) { //IL_00c0: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown if ((Object)(object)bottom == (Object)null || (Object)(object)top == (Object)null || ((Texture)bottom).width != ((Texture)top).width || ((Texture)bottom).height != ((Texture)top).height) { return null; } Color[] pixels = bottom.GetPixels(); Color[] pixels2 = top.GetPixels(); for (int i = 0; i < pixels.Length; i++) { float a = pixels2[i].a; pixels[i] = new Color(Mathf.Lerp(pixels[i].r, pixels2[i].r, a), Mathf.Lerp(pixels[i].g, pixels2[i].g, a), Mathf.Lerp(pixels[i].b, pixels2[i].b, a), Mathf.Max(pixels[i].a, a)); } Texture2D val = new Texture2D(((Texture)bottom).width, ((Texture)bottom).height, (TextureFormat)4, false, false) { wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; val.SetPixels(pixels); val.Apply(); return val; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class ItemTooltipPatch { private static readonly Dictionary<string, GameObject> ByName = new Dictionary<string, GameObject>(); private static ObjectDB _builtFor; private static void Postfix(ItemData item, bool appending, ref string __result) { if (appending || item == null || !Plugin.ItemTooltips.Value) { return; } GameObject val = (((Object)(object)item.m_dropPrefab != (Object)null) ? item.m_dropPrefab : Find(item.m_shared.m_name)); if (!((Object)(object)val == (Object)null)) { string text = ModSource.Of(((Object)val).name, val); if (text != null && (!(text == "Valheim") || Plugin.ShowVanilla.Value)) { string text2 = ((text == "a mod") ? "Added by a mod" : text); __result = __result.TrimEnd(new char[1] { '\n' }) + "\n\n<color=#8ab4f8><i>" + text2 + "</i></color>"; } } } private static GameObject Find(string sharedName) { ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || string.IsNullOrEmpty(sharedName)) { return null; } if ((Object)(object)instance != (Object)(object)_builtFor) { _builtFor = instance; ByName.Clear(); foreach (GameObject item in instance.m_items) { ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { string name = val.m_itemData.m_shared.m_name; ByName[name] = (ByName.ContainsKey(name) ? null : item); } } } if (!ByName.TryGetValue(sharedName, out var value)) { return null; } return value; } } internal class Info { internal string Title; internal string Source; internal string Prefab; internal int Id; internal Sprite Icon; internal readonly List<string> Lines = new List<string>(); internal readonly List<string> More = new List<string>(); internal readonly List<Sprite> Drops = new List<Sprite>(); internal float Bar = -1f; internal Color BarColor; internal string BarText; internal List<Weakness.Group> Weaknesses; } internal static class Looking { private static readonly Color HealthColor = new Color(0.78f, 0.2f, 0.15f); private static readonly Color GrowColor = new Color(0.45f, 0.75f, 0.3f); private static readonly Color FuelColor = new Color(0.95f, 0.6f, 0.2f); private static readonly FieldRef<Plant, Status> PlantStatus = AccessTools.FieldRefAccess<Plant, Status>("m_status"); private static readonly Func<Plant, double> SincePlanted = AccessTools.MethodDelegate<Func<Plant, double>>(AccessTools.Method(typeof(Plant), "TimeSincePlanted", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<Plant, float> GrowTime = AccessTools.MethodDelegate<Func<Plant, float>>(AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<Tameable, int> Tameness = AccessTools.MethodDelegate<Func<Tameable, int>>(AccessTools.Method(typeof(Tameable), "GetTameness", (Type[])null, (Type[])null), (object)null, true); private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>(); internal static GameObject Find(out Vector3 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; Player localPlayer = Player.m_localPlayer; Transform val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform : null); if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null) { return null; } GameObject val2 = null; float num = float.MaxValue; float num2 = Mathf.Max(Plugin.CreatureRange.Value, Plugin.ObjectRange.Value); RaycastHit[] array = Physics.RaycastAll(val.position, val.forward, num2 + 8f, -1, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val3 = array[i]; if (((RaycastHit)(ref val3)).distance >= num || ((Component)((RaycastHit)(ref val3)).collider).transform.IsChildOf(((Component)localPlayer).transform)) { continue; } num = ((RaycastHit)(ref val3)).distance; point = ((RaycastHit)(ref val3)).point; ZNetView val4 = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<ZNetView>(); if ((Object)(object)val4 != (Object)null && IsStructure(((Component)val4).gameObject)) { val4 = null; } Heightmap val5 = (((Object)(object)val4 == (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Heightmap>() : null); object obj; if (!((Object)(object)val4 != (Object)null)) { if (!((Object)(object)val5 != (Object)null)) { Hoverable componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Hoverable>(); Component val6 = (Component)(object)((componentInParent is Component) ? componentInParent : null); obj = ((val6 != null) ? val6.gameObject : null); } else { obj = ((Component)val5).gameObject; } } else { obj = ((Component)val4).gameObject; } val2 = (GameObject)obj; } if ((Object)(object)val2 != (Object)null) { float num3 = (((Object)(object)val2.GetComponent<Character>() != (Object)null) ? Plugin.CreatureRange.Value : Plugin.ObjectRange.Value); if (Vector3.Distance(((Component)localPlayer).transform.position, point) > num3) { val2 = null; } } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); if ((Object)(object)hoverObject != (Object)null) { ZNetView componentInParent2 = hoverObject.GetComponentInParent<ZNetView>(); if (!((Object)(object)componentInParent2 != (Object)null) || IsStructure(((Component)componentInParent2).gameObject)) { return hoverObject; } return ((Component)componentInParent2).gameObject; } return val2; } private static bool IsStructure(GameObject go) { if (!((Object)(object)go.GetComponent<LocationProxy>() != (Object)null) && !((Object)(object)go.GetComponent<Location>() != (Object)null)) { return (Object)(object)go.GetComponent<DungeonGenerator>() != (Object)null; } return true; } internal unsafe static Info Describe(GameObject go, Vector3 point) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return null; } if ((Object)(object)go.GetComponent<Ragdoll>() != (Object)null) { return null; } Info info = new Info { Prefab = PrefabName(go), Id = ((Object)go).GetInstanceID() }; if ((Object)(object)go.GetComponent<Heightmap>() != (Object)null) { if (!Plugin.ShowTerrain.Value) { return null; } info.Title = "Ground"; Biome val = Heightmap.FindBiome(point); string text = L("$biome_" + ((object)(*(Biome*)(&val))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant()); info.Lines.Add((string.IsNullOrEmpty(text) || text.StartsWith("$") || text.StartsWith("[")) ? Pretty(((object)(*(Biome*)(&val))/*cast due to .constrained prefix*/).ToString()) : text); return info; } Character component = go.GetComponent<Character>(); ItemDrop component2 = go.GetComponent<ItemDrop>(); Piece component3 = go.GetComponent<Piece>(); if ((Object)(object)component != (Object)null && component.IsBoss() && Plugin.BossBar.Value) { return null; } if ((Object)(object)component != (Object)null) { DescribeCharacter(component, info); } else if ((Object)(object)component2 != (Object)null) { DescribeItem(component2, info); } else { info.Title = HoverName(go, component3); if ((Object)(object)component3 != (Object)null) { info.Icon = component3.m_icon; } DescribeParts(go, info); } if (string.IsNullOrEmpty(info.Title)) { info.Title = Pretty(info.Prefab); } if ((Object)(object)info.Icon == (Object)null) { info.Icon = DropIcon(go, info.Prefab); } if ((Object)(object)component2 == (Object)null && !(component is Player) && Plugin.ShowDrops.Value) { Extended.Drops(go, info); } info.Source = ModSource.Of(info.Prefab, go); return info; } private static void DescribeCharacter(Character c, Info info) { //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_00d0: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((c is Player) ? c : null); info.Title = (((Object)(object)val != (Object)null) ? val.GetPlayerName() : L(c.m_name)); int num = c.GetLevel() - 1; if (num > 0) { info.Title = info.Title + " <color=#e8c77e>" + new string('*', num) + "</color>"; } info.Bar = c.GetHealthPercentage(); info.BarColor = HealthColor; info.BarText = $"{Mathf.CeilToInt(c.GetHealth())} / {Mathf.CeilToInt(c.GetMaxHealth())}"; if ((Object)(object)val != (Object)null) { return; } if (c.IsBoss()) { info.Lines.Add("<color=#ff6f55>Boss</color>"); } if (Plugin.ShowWeaknesses.Value) { info.Weaknesses = Weakness.Groups(c.m_damageModifiers); Extended.Resistances(info.Weaknesses, info); } if (!Plugin.ShowCreatures.Value) { return; } Tameable component = ((Component)c).GetComponent<Tameable>(); if (c.IsTamed()) { string text = "<color=#9be07a>Tamed</color>"; if ((Object)(object)component != (Object)null) { text += (component.IsHungry() ? ", hungry" : ", fed"); } info.Lines.Add(text); } else if ((Object)(object)component != (Object)null && Tameness != null) { int num2 = Tameness(component); info.Lines.Add((num2 > 0) ? ($"Taming: {num2}%" + (component.IsHungry() ? ", hungry" : ", fed")) : "Can be tamed"); } BaseAI baseAI = c.GetBaseAI(); if ((Object)(object)baseAI != (Object)null && !c.IsTamed() && baseAI.IsAlerted()) { info.Lines.Add("<color=#f0b04a>Alerted</color>"); } Details.Creature(c, info); } private static void DescribeItem(ItemDrop drop, Info info) { ItemData itemData = drop.m_itemData; info.Title = L(itemData.m_shared.m_name) + ((itemData.m_stack > 1) ? $" x{itemData.m_stack}" : ""); info.Icon = itemData.GetIcon(); if (itemData.m_shared.m_maxQuality > 1) { info.Lines.Add($"Quality {itemData.m_quality}"); } if (Plugin.ShowItems.Value) { Extended.Item(itemData, info); } } private static void DescribeParts(GameObject go, Info info) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) ZNetView component = go.GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); WearNTear component2 = go.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { float num = (info.Bar = component2.GetHealthPercentage()); info.BarColor = Color.Lerp(HealthColor, GrowColor, num); info.BarText = $"{num * 100f:0}%"; } bool value = Plugin.ShowPlants.Value; bool value2 = Plugin.ShowProduction.Value; bool value3 = Plugin.ShowBase.Value; Plant component3 = go.GetComponent<Plant>(); if (value && (Object)(object)component3 != (Object)null && SincePlanted != null && GrowTime != null) { float num2 = GrowTime(component3); double num3 = SincePlanted(component3); float num4 = (info.Bar = ((num2 > 0f) ? Mathf.Clamp01((float)(num3 / (double)num2)) : 0f)); info.BarColor = GrowColor; info.BarText = $"{num4 * 100f:0}% grown"; Status val2 = PlantStatus.Invoke(component3); if ((int)val2 != 0) { info.Lines.Add("<color=#ff6f55>Won't grow: " + PlantProblem(val2) + "</color>"); } else if (num4 < 1f) { info.Lines.Add("Ready in " + Details.Time((double)num2 - num3)); } } Pickable component4 = go.GetComponent<Pickable>(); if ((Object)(object)component4 != (Object)null && (Object)(object)component4.m_itemPrefab != (Object)null) { ItemDrop component5 = component4.m_itemPrefab.GetComponent<ItemDrop>(); info.Icon = ((component5 != null) ? component5.m_itemData.GetIcon() : null); } if (value && (Object)(object)component4 != (Object)null) { if (component4.CanBePicked()) { info.Lines.Add("<color=#9be07a>Ready to pick</color>"); } else { info.Lines.Add(Regrows(component4, val)); } } Fireplace component6 = go.GetComponent<Fireplace>(); if (value2 && (Object)(object)component6 != (Object)null && component6.m_infiniteFuel) { info.Lines.Add("Burns forever"); } else if (value2 && (Object)(object)component6 != (Object)null && val != null) { float num5 = val.GetFloat(ZDOVars.s_fuel, 0f); info.Bar = ((component6.m_maxFuel > 0f) ? Mathf.Clamp01(num5 / component6.m_maxFuel) : 0f); info.BarColor = FuelColor; info.BarText = $"Fuel {Mathf.CeilToInt(num5)} / {component6.m_maxFuel:0}"; } Container component7 = go.GetComponent<Container>(); if (value3 && (Object)(object)component7 != (Object)null && component7.GetInventory() != null) { Inventory inventory = component7.GetInventory(); int count = inventory.GetAllItems().Count; int num6 = inventory.GetWidth() * inventory.GetHeight(); info.Lines.Add((count == 0) ? "Empty" : $"{count} / {num6} slots used"); } CraftingStation component8 = go.GetComponent<CraftingStation>(); if (value3 && (Object)(object)component8 != (Object)null) { info.Lines.Add($"Level {component8.GetLevel(true)}"); } if (value2) { Details.Production(go, val, info); } if (value3) { Details.Base(go, val, info); } if (Plugin.ShowTool.Value) { Extended.ToolNeed(go, info); } if (!((Object)(object)component2 == (Object)null) || val == null) { return; } float num7 = MaxHealth(go); if (num7 > 0f) { float num8 = val.GetFloat(ZDOVars.s_health, num7); if (num8 < num7) { info.Bar = Mathf.Clamp01(num8 / num7); info.BarColor = HealthColor; info.BarText = $"{Mathf.CeilToInt(num8)} / {num7:0}"; } } } private static string Regrows(Pickable pickable, ZDO zdo) { if (pickable.m_respawnTimeMinutes <= 0f || zdo == null || (Object)(object)ZNet.instance == (Object)null) { return "Picked"; } long num = zdo.GetLong(ZDOVars.s_pickedTime, 0L); if (num <= 1) { return "Picked"; } double num2 = (double)pickable.m_respawnTimeMinutes * 60.0 - (ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds; if (!(num2 > 0.0)) { return "Regrowing any moment"; } return "Regrows in " + Details.Time(num2); } private static float MaxHealth(GameObject go) { TreeBase component = go.GetComponent<TreeBase>(); if ((Object)(object)component != (Object)null) { return component.m_health; } TreeLog component2 = go.GetComponent<TreeLog>(); if ((Object)(object)component2 != (Object)null) { return component2.m_health; } MineRock component3 = go.GetComponent<MineRock>(); if ((Object)(object)component3 != (Object)null) { return component3.m_health; } Destructible component4 = go.GetComponent<Destructible>(); if ((Object)(object)component4 != (Object)null) { return component4.m_health; } return 0f; } private unsafe static string PlantProblem(Status status) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown return (status - 1) switch { 0 => "needs sun", 1 => "not enough space", 2 => "wrong biome", 3 => "needs cultivated ground", 4 => "nothing to grow on", 5 => "too hot", 6 => "too cold", _ => ((object)(*(Status*)(&status))/*cast due to .constrained prefix*/).ToString(), }; } private static string HoverName(GameObject go, Piece piece) { string text = NameOf(go.GetComponent<Hoverable>()); if (text != null) { return text; } string text2 = (((Object)(object)piece != (Object)null) ? L(piece.m_name) : null); if (!string.IsNullOrEmpty(text2) && !text2.StartsWith("$")) { return text2; } Hoverable[] componentsInChildren = go.GetComponentsInChildren<Hoverable>(); for (int i = 0; i < componentsInChildren.Length; i++) { string text3 = NameOf(componentsInChildren[i]); if (text3 != null) { return text3; } } return null; } private static string NameOf(Hoverable hoverable) { if (hoverable == null) { return null; } string text; try { text = L(hoverable.GetHoverName()); } catch (Exception) { return null; } if (string.IsNullOrEmpty(text) || text.StartsWith("$")) { return null; } return Ui.StripColor(text); } private static string PrefabName(GameObject go) { ZNetView component = go.GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); GameObject val2 = ((val != null && (Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(val.GetPrefab()) : null); if (!((Object)(object)val2 != (Object)null)) { return Utils.GetPrefabName(go); } return ((Object)val2).name; } private static Sprite DropIcon(GameObject go, string prefab) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 if (Icons.TryGetValue(prefab, out var value)) { return value; } Sprite val = null; CharacterDrop component = go.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null) { foreach (Drop drop in component.m_drops) { ItemData val2 = ((!((Object)(object)drop.m_prefab != (Object)null)) ? null : drop.m_prefab.GetComponent<ItemDrop>()?.m_itemData); if (val2 != null) { if ((Object)(object)val == (Object)null || (int)val2.m_shared.m_itemType == 13) { val = val2.GetIcon(); } if ((int)val2.m_shared.m_itemType == 13) { break; } } } } if ((Object)(object)val == (Object)null) { val = FirstDrop(go.GetComponent<TreeBase>()?.m_dropWhenDestroyed) ?? FirstDrop(go.GetComponent<TreeLog>()?.m_dropWhenDestroyed) ?? FirstDrop(go.GetComponent<MineRock>()?.m_dropItems) ?? FirstDrop(go.GetComponent<MineRock5>()?.m_dropItems) ?? FirstDrop(go.GetComponent<DropOnDestroyed>()?.m_dropWhenDestroyed); } Icons[prefab] = val; return val; } private static Sprite FirstDrop(DropTable table) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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 (table?.m_drops == null) { return null; } foreach (DropData drop in table.m_drops) { ItemData val = ((!((Object)(object)drop.m_item != (Object)null)) ? null : drop.m_item.GetComponent<ItemDrop>()?.m_itemData); if (val != null) { return val.GetIcon(); } } return null; } internal static string L(string token) { if (!string.IsNullOrEmpty(token) && Localization.instance != null) { return Localization.instance.Localize(token); } return token; } private static string Pretty(string prefab) { if (string.IsNullOrEmpty(prefab)) { return "?"; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < prefab.Length; i++) { char c = prefab[i]; if (c == '_') { c = ' '; } else if (i > 0 && char.IsUpper(c) && char.IsLower(prefab[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append((i > 0 && char.IsUpper(c)) ? char.ToLowerInvariant(c) : c); } string text = stringBuilder.ToString().Replace(" ", " ").Trim(); if (text.Length <= 0) { return "?"; } return char.ToUpperInvariant(text[0]) + text.Substring(1); } } internal static class ModSource { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class VanillaSnapshotPatch { [HarmonyPriority(int.MaxValue)] private static void Prefix(ZNetScene __instance) { _scene = __instance; VanillaPrefabs.Clear(); Cache.Clear(); foreach (GameObject prefab in __instance.m_prefabs) { if ((Object)(object)prefab != (Object)null) { VanillaPrefabs.Add(((Object)prefab).name); } } foreach (GameObject nonNetViewPrefab in __instance.m_nonNetViewPrefabs) { if ((Object)(object)nonNetViewPrefab != (Object)null) { VanillaPrefabs.Add(((Object)nonNetViewPrefab).name); } } _snapshotTaken = true; } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDBFirstPatch { [HarmonyPriority(int.MaxValue)] private static void Prefix(ObjectDB __instance) { _objectDB = __instance; } } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class WrapPatchesPatch { private static bool _done; private static void Postfix() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0075: Expected O, but got Unknown if (!_done && !HasJotunn) { _done = true; Harmony val = new Harmony("Hugin.ModSource"); Wrap(val, AccessTools.Method(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), scene: true); Wrap(val, AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), scene: false); Wrap(val, AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null), scene: false); } } } [HarmonyPatch] private static class BundlePatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(AssetBundle).GetMethods(BindingFlags.Static | BindingFlags.Public) where (m.Name == "LoadFromFile" || m.Name == "LoadFromMemory" || m.Name == "LoadFromStream") && m.ReturnType == typeof(AssetBundle) && m.GetMethodBody() != null select m; } private static void Postfix(AssetBundle __result) { if ((Object)(object)__result == (Object)null) { return; } try { string text = Caller(); if (text == null) { return; } string[] allAssetNames = __result.GetAllAssetNames(); for (int i = 0; i < allAssetNames.Length; i++) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(allAssetNames[i]); if (!BundleAsset.ContainsKey(fileNameWithoutExtension)) { BundleAsset[fileNameWithoutExtension] = text; } } } catch (Exception) { } } private static string Caller() { StackFrame[] array = new StackTrace(2, fNeedFileInfo: false).GetFrames() ?? new StackFrame[0]; for (int i = 0; i < array.Length; i++) { Assembly assembly = array[i].GetMethod()?.DeclaringType?.Assembly; if (!(assembly == null) && !(assembly == typeof(ModSource).Assembly)) { string text = PluginOf(assembly); if (text != null) { return text; } } } return null; } } internal const string JotunnGuid = "com.jotunn.jotunn"; internal const string Vanilla = "Valheim"; internal const string UnknownMod = "a mod"; private static readonly HashSet<string> VanillaPrefabs = new HashSet<string>(); private static readonly Dictionary<string, string> AddedBy = new Dictionary<string, string>(); private static readonly Dictionary<string, string> BundleAsset = new Dictionary<string, string>(); private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>(); private static Dictionary<Assembly, string> _plugins; private static int _pluginCount = -1; private static MethodInfo _jotunnGetPrefab; private static PropertyInfo _jotunnSourceMod; private static bool _snapshotTaken; private static ZNetScene _scene; private static ObjectDB _objectDB; private static readonly Stack<int> Counts = new Stack<int>(); internal static bool HasJotunn => _jotunnGetPrefab != null; internal static void Init() { try { Type type = Type.GetType("Jotunn.Utils.ModQuery, Jotunn"); if (!(type == null)) { type.GetMethod("Enable", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null); _jotunnGetPrefab = type.GetMethod("GetPrefab", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); _jotunnSourceMod = Type.GetType("Jotunn.Utils.IModPrefab, Jotunn")?.GetProperty("SourceMod"); Plugin.Log.LogInfo((object)"Jötunn found: using its ModQuery to name the mods things come from."); } } catch (Exception ex) { _jotunnGetPrefab = null; Plugin.Log.LogWarning((object)("Couldn't use Jötunn's ModQuery: " + ex.Message)); } } internal static string Of(string prefab, GameObject target) { if (string.IsNullOrEmpty(prefab)) { return null; } if (Cache.TryGetValue(prefab, out var value)) { return value; } string text = Find(prefab, target); if (_snapshotTaken) { Cache[prefab] = text; } return text; } private static string Find(string prefab, GameObject target) { if (!_snapshotTaken) { return null; } if (VanillaPrefabs.Contains(prefab)) { return "Valheim"; } string text = FromJotunn(prefab); if (text != null) { return text; } if (AddedBy.TryGetValue(prefab, out var value)) { return value; } if (BundleAsset.TryGetValue(prefab.ToLowerInvariant(), out var value2)) { return value2; } string text2 = FromScripts(target); if (text2 != null) { return text2; } if ((Object)(object)target != (Object)null && !Registered(target)) { return null; } return "a mod"; } private static bool Registered(GameObject target) { ZNetView componentInParent = target.GetComponentInParent<ZNetView>(); ZDO val = (((Object)(object)componentInParent != (Object)null) ? componentInParent.GetZDO() : null); if (val == null) { return (Object)(object)componentInParent != (Object)null; } if (!((Object)(object)ZNetScene.instance == (Object)null)) { return (Object)(object)ZNetScene.instance.GetPrefab(val.GetPrefab()) != (Object)null; } return true; } private static string FromJotunn(string prefab) { if (_jotunnGetPrefab == null) { return null; } try { object obj = _jotunnGetPrefab.Invoke(null, new object[1] { prefab }); object obj2 = (object)((obj != null) ? /*isinst with value type is only supported in some contexts*/: null); return (obj2 != null) ? ((BepInPlugin)obj2).Name : null; } catch (Exception) { return null; } } private static string FromScripts(GameObject target) { if ((Object)(object)target == (Object)null) { return null; } MonoBehaviour[] componentsInChildren = target.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string text = PluginOf(((object)val).GetType().Assembly); if (text != null && text != "Hugin") { return text; } } } return null; } internal static string PluginOf(Assembly assembly) { if (_plugins == null || _pluginCount != Chainloader.PluginInfos.Count) { _pluginCount = Chainloader.PluginInfos.Count; _plugins = new Dictionary<Assembly, string>(); Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); foreach (PluginInfo value3 in Chainloader.PluginInfos.Values) { if (!string.IsNullOrEmpty(value3.Location) && !dictionary.ContainsKey(value3.Location)) { dictionary[value3.Location] = value3.Metadata.Name; } } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { string text; try { text = (assembly2.IsDynamic ? null : assembly2.Location); } catch (Exception) { text = null; } if (!string.IsNullOrEmpty(text) && dictionary.TryGetValue(text, out var value)) { _plugins[assembly2] = value; } } } if (!(assembly != null) || !_plugins.TryGetValue(assembly, out var value2)) { return null; } return value2; } private static void Wrap(Harmony harmony, MethodBase target, bool scene) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown Patches val = ((target != null) ? Harmony.GetPatchInfo(target) : null); if (val == null) { return; } HarmonyMethod val2 = new HarmonyMethod(AccessTools.Method(typeof(ModSource), scene ? "BeforeScene" : "BeforeDB", (Type[])null, (Type[])null)); HarmonyMethod val3 = new HarmonyMethod(AccessTools.Method(typeof(ModSource), scene ? "AfterScene" : "AfterDB", (Type[])null, (Type[])null)); foreach (Patch item in val.Prefixes.Concat(val.Postfixes)) { MethodInfo patchMethod = item.PatchMethod; if (!(patchMethod == null) && !(patchMethod.DeclaringType?.Assembly == typeof(ModSource).Assembly) && PluginOf(patchMethod.DeclaringType?.Assembly) != null) { try { harmony.Patch((MethodBase)patchMethod, val2, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Couldn't watch " + patchMethod.DeclaringType?.Name + "." + patchMethod.Name + ": " + ex.Message)); } } } } private static void BeforeScene() { Counts.Push(((Object)(object)_scene != (Object)null) ? _scene.m_prefabs.Count : 0); } private static void AfterScene(MethodBase __originalMethod) { int num = ((Counts.Count > 0) ? Counts.Pop() : 0); if (!((Object)(object)_scene == (Object)null)) { Claim(_scene.m_prefabs, num, __originalMethod); } } private static void BeforeDB() { Counts.Push(((Object)(object)_objectDB != (Object)null) ? _objectDB.m_items.Count : 0); } private static void AfterDB(MethodBase __originalMethod) { int num = ((Counts.Count > 0) ? Counts.Pop() : 0); if (!((Object)(object)_objectDB == (Object)null)) { Claim(_objectDB.m_items, num, __originalMethod); } } private static void Claim(List<GameObject> list, int from, MethodBase patch) { string text = PluginOf(patch?.DeclaringType?.Assembly); if (text == null) { return; } for (int i = from; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null && !AddedBy.ContainsKey(((Object)list[i]).name)) { AddedBy[((Object)list[i]).name] = text; } } } } internal class Panel : MonoBehaviour { private const float Pad = 10f; private const float IconSize = 40f; private const float MinW = 220f; private const float MaxW = 480f; private const float TitleH = 24f; private const float LineH = 19f; private const float BarH = 14f; private const float DropSize = 24f; private const float Edge = 24f; private const float Interval = 0.1f; private const float Linger = 0.3f; private const float FadeSpeed = 7f; private const float SizeSpeed = 14f; private const float ContentFade = 9f; private const float BarSpeed = 6f; private const float Slide = 10f; internal const string SourceColor = "#8ab4f8"; private Info _info; private float _nextUpdate; private float _lostAt; private float _alpha; private float _w; private float _h; private float _contentAlpha; private float _bar = -1f; private int _shownId; private GUIStyle _source; private GUIStyle _title; private static readonly List<string> NoLines = new List<string>(); private GUIStyle SourceStyle { get { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0023: Expected O, but got Unknown GUIStyle obj = _source; if (obj == null) { GUIStyle val = new GUIStyle(Ui.Small) { fontStyle = (FontStyle)2 }; GUIStyle val2 = val; _source = val; obj = val2; } return obj; } } private GUIStyle TitleStyle { get { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0023: Expected O, but got Unknown GUIStyle obj = _title; if (obj == null) { GUIStyle val = new GUIStyle(Ui.Text) { fontStyle = (FontStyle)1 }; GUIStyle val2 = val; _title = val; obj = val2; } return obj; } } private void Update() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!(Time.unscaledTime < _nextUpdate)) { _nextUpdate = Time.unscaledTime + 0.1f; Vector3 point; Info info = (Hidden() ? null : Looking.Describe(Looking.Find(out point), point)); if (info != null) { _info = info; _lostAt = -1f; } else if (_info != null && _lostAt < 0f) { _lostAt = Time.unscaledTime; } } } private static bool Hidden() { if (!ScreenHidden()) { if (Plugin.HideWhileBuilding.Value) { return ((Character)Player.m_localPlayer).InPlaceMode(); } return false; } return true; } internal static bool ScreenHidden() { Player localPlayer = Player.m_localPlayer; if (!Plugin.ShowPanel.Value || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Hud.IsUserHidden()) { return true; } if (InventoryGui.IsVisible() || Minimap.IsOpen() || Menu.IsVisible() || StoreGui.IsVisible() || TextInput.IsVisible()) { return true; } if (!Console.IsVisible()) { return GameCamera.InFreeFly(); } return true; } private void OnGUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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) if ((int)Event.current.type != 7 || _info == null) { return; } float unscaledDeltaTime = Time.unscaledDeltaTime; bool flag = _lostAt < 0f || Time.unscaledTime - _lostAt < 0.3f; _alpha = Mathf.MoveTowards(_alpha, flag ? 1f : 0f, unscaledDeltaTime * 7f); if (_alpha <= 0f) { _info = null; _w = (_h = 0f); return; } if (_info.Id != _shownId) { _shownId = _info.Id; Raven.Curious(); _contentAlpha = 0f; _bar = _info.Bar; } _contentAlpha = Mathf.MoveTowards(_contentAlpha, 1f, unscaledDeltaTime * 9f); _bar = ((_info.Bar < 0f || _bar < 0f) ? _info.Bar : Mathf.Lerp(_bar, _info.Bar, 1f - Mathf.Exp(-6f * unscaledDeltaTime))); GUISkin skin = GUI.skin; Color color = GUI.color; GUI.skin = Ui.Skin; float width; float height; Matrix4x4 matrix = Ui.BeginScaled(out width, out height); try { GUI.color = new Color(1f, 1f, 1f, _alpha); Draw(width); } finally { GUI.matrix = matrix; GUI.skin = skin; GUI.color = color; } } private void Draw(float screenW) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063c: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_0658: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_07b1: Unknown result type (might be due to invalid IL or missing references) //IL_07fb: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Unknown result type (might be due to invalid IL or missing references) //IL_0763: Unknown result type (might be due to invalid IL or missing references) //IL_0843: Unknown result type (might be due to invalid IL or missing references) //IL_08d8: Unknown result type (might be due to invalid IL or missing references) //IL_0a20: Unknown result type (might be due to invalid IL or missing references) //IL_0a52: Unknown result type (might be due to invalid IL or missing references) //IL_0950: Unknown result type (might be due to invalid IL or missing references) //IL_0a99: Unknown result type (might be due to invalid IL or missing references) //IL_0a8c: Unknown result type (might be due to invalid IL or missing references) //IL_09a8: Unknown result type (might be due to invalid IL or missing references) //IL_09cc: Unknown result type (might be due to invalid IL or missing references) //IL_0aab: Unknown result type (might be due to invalid IL or missing references) //IL_0ad1: Unknown result type (might be due to invalid IL or missing references) Info info = _info; bool value = Plugin.Compact.Value; int num; if (!value) { KeyboardShortcut value2 = Plugin.MoreKey.Value; if ((int)((KeyboardShortcut)(ref value2)).MainKey != 0) { value2 = Plugin.MoreKey.Value; num = (((KeyboardShortcut)(ref value2)).IsPressed() ? 1 : 0); goto IL_0040; } } num = 0; goto IL_0040; IL_0040: bool flag = (byte)num != 0; bool num2 = !value && (info.More.Count > 0 || info.Drops.Count > 0); string text = SourceLine(info); string text2 = ((!value && (Plugin.ShowPrefab.Value || flag)) ? ("<color=#b9ad98>" + info.Prefab + "</color>") : null); List<string> list = (value ? NoLines : info.Lines); List<string> list2 = (flag ? info.More : NoLines); bool flag2 = flag && info.Drops.Count > 0; bool flag3 = info.Bar >= 0f && !value; List<Weakness.Group> list3 = ((!value && info.Weaknesses != null && info.Weaknesses.Count > 0 && (flag || Plugin.WeaknessIconsAlways.Value)) ? info.Weaknesses : null); string text3 = ((num2 && !flag && Plugin.ShowHint.Value) ? Ui.KeyName(Plugin.MoreKey.Value) : null); float num3 = ((text3 != null) ? (Ui.KeycapWidth(text3) + 8f) : 0f); bool flag4 = Plugin.ShowRaven.Value && Raven.Available; float num4 = (value ? 72f : 96f); float num5 = num4 * 0.625f; float num6 = num5 * 0.64f; float num7 = (flag4 ? Mathf.Max(0f, num5 * 0.32f - 10f + 4f) : 0f); float num8 = (value ? 28f : 40f); float num9 = (((Object)(object)info.Icon != (Object)null) ? (10f + num8 + 12f) : 12f); float num10 = Ui.LineWidth(info.Title, TitleStyle) + 4f; foreach (string item in list) { num10 = Mathf.Max(num10, Ui.LineWidth(item, Ui.Small)); } foreach (string item2 in list2) { num10 = Mathf.Max(num10, Ui.LineWidth(item2, Ui.Small)); } if (text != null || text3 != null) { num10 = Mathf.Max(num10, ((text != null) ? Ui.LineWidth(text, SourceStyle) : 0f) + num3); } if (text2 != null) { num10 = Mathf.Max(num10, Ui.LineWidth(text2, Ui.Small)); } if (flag3) { num10 = Mathf.Max(num10, 170f); } List<List<Weakness.Group>> list4 = ((list3 != null) ? Weakness.Rows(list3, 16f, Mathf.Max(num10, 200f)) : null); if (list4 != null) { foreach (List<Weakness.Group> item3 in list4) { num10 = Mathf.Max(num10, Weakness.Width(item3, 16f)); } } if (flag2) { num10 = Mathf.Max(num10, (float)Mathf.Min(info.Drops.Count, 8) * 28f); } float num11 = Mathf.Clamp(Mathf.Ceil((num9 + num10 + 10f + 4f) / 16f) * 16f, value ? 140f : 220f, 480f); float num12 = num7 + 10f + 24f + (flag3 ? 20f : 0f) + ((list4 != null) ? ((float)list4.Count * 19f + 2f) : 0f) + (float)list.Count * 19f + ((list2.Count > 0) ? (4f + (float)list2.Count * 19f) : 0f) + (flag2 ? 30f : 0f) + ((text2 != null) ? 19f : 0f) + ((text != null || text3 != null) ? 21f : 0f) + 10f; num12 = Mathf.Max(num12, ((Object)(object)info.Icon != (Object)null) ? (num7 + num8 + 20f) : 0f); float num13 = 1f - Mathf.Exp(-14f * Time.unscaledDeltaTime); _w = ((_w <= 0f) ? num11 : Mathf.Lerp(_w, num11, num13)); _h = ((_h <= 0f) ? num12 : Mathf.Lerp(_h, num12, num13)); if (Mathf.Abs(_w - num11) < 0.5f) { _w = num11; } if (Mathf.Abs(_h - num12) < 0.5f) { _h = num12; } Anchor value3 = Plugin.Position.Value; float num14 = (flag4 ? num6 : 0f); float num15 = Mathf.Clamp(value3 switch { Anchor.Right => screenW - 24f - _w, Anchor.Left => 24f, _ => (screenW - _w) * 0.5f, } + Plugin.OffsetX.Value, 0f, Mathf.Max(0f, screenW - _w)); float num16 = Plugin.OffsetY.Value + num14; if (BossBar.Find(out var bar, out var _) && num15 < ((Rect)(ref bar)).xMax + 8f && num15 + _w > ((Rect)(ref bar)).x - 8f) { num16 = Mathf.Max(num16, BossBar.Bottom() + num14); } num16 -= (1f - Mathf.SmoothStep(0f, 1f, _alpha)) * 10f; Rect val = default(Rect); ((Rect)(ref val))..ctor(Mathf.Round(num15), num16, _w, _h); Ui.Panel(val); GUI.BeginGroup(val); Color color = GUI.color; GUI.color = new Color(color.r, color.g, color.b, color.a * _contentAlpha); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(value3 switch { Anchor.Right => _w - num11, Anchor.Left => 0f, _ => (_w - num11) * 0.5f, }, num7, num11, num12 - num7); if ((Object)(object)info.Icon != (Object)null) { Rect r = default(Rect); ((Rect)(ref r))..ctor(((Rect)(ref val2)).x + 10f, ((Rect)(ref val2)).y + 10f, num8 + 4f, num8 + 4f); if (!value) { ((Rect)(ref r)).y = ((Rect)(ref val2)).y + Mathf.Min(10f, (((Rect)(ref val2)).height - ((Rect)(ref r)).height) * 0.5f); } Ui.Slot(r); Ui.Icon(new Rect(((Rect)(ref r)).x + 3f, ((Rect)(ref r)).y + 3f, ((Rect)(ref r)).width - 6f, ((Rect)(ref r)).height - 6f), info.Icon); } float num17 = ((Rect)(ref val2)).x + num9; float num18 = ((Rect)(ref val2)).xMax - 10f - num17; float num19 = ((Rect)(ref val2)).y + 10f - 2f; Ui.Label(new Rect(num17, num19, num18, 24f), "<b>" + info.Title + "</b>", Ui.Text); num19 += 24f; if (flag3) { Rect r2 = default(Rect); ((Rect)(ref r2))..ctor(num17, num19 + 2f, num18, 14f); Ui.Bar(r2, _bar, info.BarColor); if (!string.IsNullOrEmpty(info.BarText)) { Ui.Label(new Rect(((Rect)(ref r2)).x, ((Rect)(ref r2)).y - 3f, ((Rect)(ref r2)).width, ((Rect)(ref r2)).height + 6f), info.BarText, Ui.SmallCenter); } num19 += 20f; } if (list4 != null) { foreach (List<Weakness.Group> item4 in list4) { Weakness.Draw(item4, num17, num19 + 1f, 16f); num19 += 19f; } num19 += 2f; } foreach (string item5 in list) { Ui.Label(new Rect(num17, num19, num18, 19f), item5, Ui.Small); num19 += 19f; } if (list2.Count > 0) { Ui.Divider(num17, num19 + 1f, num18); num19 += 4f; foreach (string item6 in list2) { Ui.Label(new Rect(num17, num19, num18, 19f), item6, Ui.Small); num19 += 19f; } } if (flag2) { float num20 = num17; for (int i = 0; i < info.Drops.Count && i < 8; i++) { Ui.Slot(new Rect(num20, num19 + 2f, 24f, 24f)); Ui.Icon(new Rect(num20 + 3f, num19 + 5f, 18f, 18f), info.Drops[i]); num20 += 28f; } num19 += 30f; } if (text2 != null) { Ui.Label(new Rect(num17, num19, num18, 19f), text2, Ui.Small); num19 += 19f; } if (text != null) { Ui.Label(new Rect(num17, num19 + 2f, num18 - num3, 19f), text, SourceStyle); } if (text3 != null) { Ui.Keycap(new Rect(((Rect)(ref val2)).xMax - 10f - num3 + 8f, num19 + 2f, num3, 18f), text3); } GUI.color = color; GUI.EndGroup(); if (flag4) { Raven.Draw(new Rect(Mathf.Round(((Rect)(ref val)).center.x - num4 * 0.5f), ((Rect)(ref val)).y - num6, num4, num5)); } } private static string SourceLine(Info info) { if (string.IsNullOrEmpty(info.Source)) { return null; } if (info.Source == "Valheim") { if (!Plugin.ShowVanilla.Value) { return null; } return "<color=#8ab4f8>Valheim</color>"; } if (info.Source == "a mod") { return "<color=#8ab4f8>Added by a mod</color>"; } return "<color=#8ab4f8>" + info.Source + "</color>"; } } internal enum Anchor { Left, Centre, Right } [BepInPlugin("Hugin", "Hugin, What the Hel Is That?", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public class Plugin : BaseUnityPlugin { private const string Guid = "Hugin"; internal static ConfigEntry<bool> ShowPanel; internal static ConfigEntry<bool> ShowVanilla; internal static ConfigEntry<bool> ShowPrefab; internal static ConfigEntry<bool> ShowTerrain; internal static ConfigEntry<bool> HideWhileBuilding; internal static ConfigEntry<bool> Compact; internal static ConfigEntry<bool> ShowHint; internal static ConfigEntry<bool> ItemTooltips; internal static ConfigEntry<bool> BossBar; internal static ConfigEntry<bool> ShowRaven; internal static ConfigEntry<KeyboardShortcut> ToggleKey; internal static ConfigEntry<KeyboardShortcut> MoreKey; internal static ConfigEntry<float> UiScale; internal static ConfigEntry<float> CreatureRange; internal static ConfigEntry<float> ObjectRange; internal static ConfigEntry<float> OffsetY; internal static ConfigEntry<float> OffsetX; internal static ConfigEntry<Anchor> Position; internal static ConfigEntry<bool> ShowCreatures; internal static ConfigEntry<bool> ShowPlants; internal static ConfigEntry<bool> ShowProduction; internal static ConfigEntry<bool> ShowBase; internal static ConfigEntry<bool> ShowTool; internal static ConfigEntry<bool> ShowItems; internal static ConfigEntry<bool> ShowWeaknesses; internal static ConfigEntry<bool> ShowDrops; internal static ConfigEntry<bool> WeaknessIconsAlways; internal static ManualLogSource Log; private Harmony _harmony; private GameObject _panelObject; private void Awake() { //IL_0045: 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_0091: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Expected O, but got Unknown //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ShowPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show panel", true, "Show the panel for what you're looking at."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Toggle key", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Shows or hides the panel."); UiScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "UI scale", 1f, new ConfigDescription("Size of the panel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); Position = ((BaseUnityPlugin)this).Config.Bind<Anchor>("General", "Position", Anchor.Centre, "Which side of the top of the screen the panel sits on."); OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Sideways offset", 0f, new ConfigDescription("Moves the panel left (negative) or right (positive) from its position, e.g. to make room for a compass.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1200f, 1200f), Array.Empty<object>())); OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Distance from the top", 12f, new ConfigDescription("How far below the top of the screen the panel sits.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), Array.Empty<object>())); CreatureRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range for creatures", 20f, new ConfigDescription("How far away creatures and players are still shown, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), Array.Empty<object>())); ObjectRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range for objects", 6f, new ConfigDescription("How far away everything else (rocks, trees, pieces, plants...) is still shown, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), Array.Empty<object>())); MoreKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "More details key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to see more: weaknesses, drops, an item's weight and value, the prefab name."); ShowHint = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show the key hint", true, "Show the \"more details\" key in the corner of the panel when there's more to see."); ShowRaven = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Hugin", true, "Hugin the raven peeks over the top of the panel, as if he's the one telling you."); Compact = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Compact", false, "Only the icon, the name and the mod it comes from: no bars or details."); ShowVanilla = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Name the game for vanilla things", true, "Show \"Valheim\" as the source of the game's own things. Off: only modded things get a source line."); WeaknessIconsAlways = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Weakness icons always shown", true, "Show a creature's weakness icons all the time. Off: only while holding the more key, for the smallest panel."); BossBar = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Bosses use the boss bar", true, "No panel for bosses, since the game's boss bar is in the same spot; their weaknesses go under that bar as small icons instead."); ItemTooltips = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Mod name on item tooltips", true, "Add the mod an item comes from to the end of its tooltip, in the inventory, chests and crafting."); ShowCreatures = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Creatures", true, "Behaviour, alerted, taming, tame names, saddles and breeding."); ShowPlants = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Plants and pickables", true, "Growth, why a plant won't grow, ready to pick, when bushes grow back."); ShowProduction = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Production", true, "Fires' fuel, smelters, kilns, fermenters, cooking stations and beehives."); ShowBase = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Base", true, "Chests, crafting station levels, wards, beds, graves, portal tags and stands."); ShowTool = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Tool needed", true, "Which tool a rock or tree needs (in red when you carry nothing that can break it)."); ShowItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Item details", true, "Items on the ground: can't go through portals, weight, value and stack size."); ShowWeaknesses = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Weaknesses", true, "What a creature is weak to, resists or is immune to: a row of icons, and how much with the more key."); ShowDrops = ((BaseUnityPlugin)this).Config.Bind<bool>("Sections", "Drops", true, "With the more key: what something drops, as icons."); ShowPrefab = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Show prefab name", false, "Show the internal prefab name, handy for console commands and mod configs."); ShowTerrain = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Show the ground", false, "Show a panel for the ground too (biome)."); HideWhileBuilding = ((BaseUnityPlugin)this).Config.Bind<bool>("Details", "Hide while building", true, "Hide the panel while a building piece is selected."); ModSource.Init(); _panelObject = new GameObject("Hugin_Panel"); Object.DontDestroyOnLoad((Object)(object)_panelObject); _panelObject.AddComponent<Panel>(); _panelObject.AddComponent<BossBar>(); _harmony = new Harmony("Hugin"); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Hugin is watching."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)_panelObject != (Object)null) { Object.Destroy((Object)(object)_panelObject); } } private void Update() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Player.m_localPlayer == (Object)null)) { Ui.PrepareArt(); KeyboardShortcut value = ToggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !IsTyping()) { ShowPanel.Value = !ShowPanel.Value; } } } private static bool IsTyping() { if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible()) { return TextInput.IsVisible(); } return true; } } internal static class Raven { private const float TiltTime = 0.45f; private const float TiltAngle = 9f; internal const float Aspect = 0.625f; internal const float EdgeAt = 0.64f; internal const float BeakTip = 0.96f; private static Texture2D _texture; private static bool _loaded; private static float _tiltStart = -10f; private static Texture2D Texture { get { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown if (_loaded) { return _texture; } _loaded = true; try { using Stream stream = typeof(Raven).Assembly.GetManifestResourceStream("Hugin.raven.png"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; if (LoadImage(val, array)) { _texture = val; } } catch (IOException ex) { Plugin.Log.LogWarning((object)("Couldn't load Hugin's picture: " + ex.Message)); } return _texture; } } internal static bool Available => (Object)(object)Texture != (Object)null; private static bool LoadImage(Texture2D tex, byte[] bytes) { MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); bool flag = default(bool); int num; if (methodInfo != null) { object obj = methodInfo.Invoke(null, new object[2] { tex, bytes }); if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } internal static void Curious() { _tiltStart = Time.unscaledTime; } internal static void Draw(Rect r) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0059: 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_008b: 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_0098: Unknown res