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 Deathlink v0.11.2
plugins/Deathlink.dll
Decompiled 2 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.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using AlmanacClasses.API; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Deathlink.Common; using Deathlink.Death; using Deathlink.external; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using SimpleJson; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Deathlink")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Deathlink")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.1.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Backpacks { [PublicAPI] public static class API { public static EpicMMOSystem_API.API_State state; private static MethodInfo eCountItemsInBackpacks; private static MethodInfo eAddItemToBackpack; private static MethodInfo eDeleteItemsFromBackpacks; private static MethodInfo eGetEquippedBackpackInventory; private static MethodInfo eGetAllBackpackInventories; public static int CountItemsInBackpacks(Inventory inventory, string name, bool onlyRemoveable = true) { return (int)eCountItemsInBackpacks?.Invoke(null, new object[3] { inventory, name, onlyRemoveable }); } public static bool IsItemInBackpacks(Inventory inventory, string name) { return CountItemsInBackpacks(inventory, name) > 0; } public static bool AddItemToBackpack(ItemData backpack, ItemData item) { return (bool)eAddItemToBackpack?.Invoke(null, new object[2] { backpack, item }); } public static bool DeleteItemsFromBackpacks(Inventory inventory, string name, int count = 1) { return (bool)eDeleteItemsFromBackpacks?.Invoke(null, new object[3] { inventory, name, count }); } public static Inventory? GetEquippedBackpackInventory() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown return (Inventory)(eGetEquippedBackpackInventory?.Invoke(null, new object[0])); } public static List<Inventory> GetAllBackpackInventories(Inventory inventory) { return (List<Inventory>)(eGetAllBackpackInventories?.Invoke(null, new object[1] { inventory })); } public static void Init() { EpicMMOSystem_API.API_State aPI_State = state; if ((uint)(aPI_State - 1) > 1u) { if (Type.GetType("Backpacks.API, Backpacks") == null) { state = EpicMMOSystem_API.API_State.NotInstalled; return; } state = EpicMMOSystem_API.API_State.Ready; Type type = Type.GetType("Backpacks.API, Backpacks"); eCountItemsInBackpacks = type.GetMethod("CountItemsInBackpacks", BindingFlags.Static | BindingFlags.Public); eAddItemToBackpack = type.GetMethod("AddItemToBackpack", BindingFlags.Static | BindingFlags.Public); eDeleteItemsFromBackpacks = type.GetMethod("DeleteItemsFromBackpacks", BindingFlags.Static | BindingFlags.Public); eGetEquippedBackpackInventory = type.GetMethod("GetEquippedBackpackInventory", BindingFlags.Static | BindingFlags.Public); eGetAllBackpackInventories = type.GetMethod("GetAllBackpackInventories", BindingFlags.Static | BindingFlags.Public); } } } } namespace AzuExtendedPlayerInventory { [PublicAPI] public class API { public delegate void SlotAddedHandler(string slotName); public delegate void SlotRemovedHandler(string slotName); public static event Action<Hud>? OnHudAwake; public static event Action<Hud>? OnHudAwakeComplete; public static event Action<Hud>? OnHudUpdate; public static event Action<Hud>? OnHudUpdateComplete; public static event SlotAddedHandler? SlotAdded; public static event SlotRemovedHandler? SlotRemoved; public static bool IsLoaded() { return false; } public static bool AddSlot(string slotName, Func<Player, ItemData?> getItem, Func<ItemData, bool> isValid, int index = -1) { return false; } public static bool RemoveSlot(string slotName) { return false; } public static SlotInfo GetSlots() { return new SlotInfo(); } public static SlotInfo GetQuickSlots() { return new SlotInfo(); } public static List<ItemData> GetQuickSlotsItems() { return new List<ItemData>(); } public static int GetAddedRows(int width) { return 0; } } [PublicAPI] public class SlotInfo { public string[] SlotNames { get; set; } = new string[0]; public Vector2[] SlotPositions { get; set; } = (Vector2[])(object)new Vector2[0]; public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = new Func<Player, ItemData>[0]; public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = new Func<ItemData, bool>[0]; } } namespace AlmanacClasses.API { public static class ClassesAPI { private static readonly MethodInfo? API_AddExperience; private static readonly MethodInfo? API_GetLevel; private static readonly MethodInfo? API_GetCharacteristic; public static void AddEXP(int amount) { API_AddExperience?.Invoke(null, new object[1] { amount }); } public static int GetLevel() { return (int)(API_GetLevel?.Invoke(null, null) ?? ((object)0)); } public static int GetCharacteristic(string type) { return (int)(API_GetCharacteristic?.Invoke(null, new object[1] { type }) ?? ((object)0)); } public static int GetConstitution() { return GetCharacteristic("Constitution"); } public static int GetDexterity() { return GetCharacteristic("Dexterity"); } public static int GetStrength() { return GetCharacteristic("Strength"); } public static int GetIntelligence() { return GetCharacteristic("Intelligence"); } public static int GetWisdom() { return GetCharacteristic("Wisdom"); } static ClassesAPI() { Type type = Type.GetType("AlmanacClasses.API.API, AlmanacClasses"); if ((object)type != null) { API_AddExperience = type.GetMethod("AddExperience", BindingFlags.Static | BindingFlags.Public); API_GetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public); API_GetCharacteristic = type.GetMethod("GetCharacteristic", BindingFlags.Static | BindingFlags.Public); } } } } namespace Deathlink { internal class Logger { public static LogLevel Level = (LogLevel)16; public static void enableDebugLogging(object sender, EventArgs e) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (ValConfig.EnableDebugMode.Value) { Level = (LogLevel)32; } else { Level = (LogLevel)16; } } public static void CheckEnableDebugLogging() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (ValConfig.EnableDebugMode.Value) { Level = (LogLevel)32; } else { Level = (LogLevel)16; } } public static void LogDebug(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)Level >= 32) { Deathlink.Log.LogInfo((object)message); } } public static void LogInfo(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)Level >= 16) { Deathlink.Log.LogInfo((object)message); } } public static void LogWarning(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Level >= 4) { Deathlink.Log.LogWarning((object)message); } } public static void LogError(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Level >= 2) { Deathlink.Log.LogError((object)message); } } } [BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.11.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Deathlink : BaseUnityPlugin { public const string PluginGUID = "MidnightsFX.Deathlink"; public const string PluginName = "Deathlink"; public const string PluginVersion = "0.11.2"; public ValConfig cfg; internal static AssetBundle EmbeddedResourceBundle; internal static bool AzuEPILoaded = false; internal static bool RustyAlmanacClassesLoaded = false; internal static bool WackyMMOLoaded = false; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); public static ManualLogSource Log; public void Awake() { Log = ((BaseUnityPlugin)this).Logger; cfg = new ValConfig(((BaseUnityPlugin)this).Config); AddLocalizations(); EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Deathlink.AssetsEmbedded.deathless", typeof(Deathlink).Assembly); DeathProgressionSkill.SetupDeathSkill(); if (API.IsLoaded()) { AzuEPILoaded = true; } if (Enumerable.Contains(BepInExUtils.GetPlugins(false).Keys, "WackyMole.EpicMMOSystem")) { EpicMMOSystem_API.Init(); if (EpicMMOSystem_API.state == EpicMMOSystem_API.API_State.Ready) { WackyMMOLoaded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API loaded."); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API installed but API not ready."); } } if (Enumerable.Contains(BepInExUtils.GetPlugins(false).Keys, "RustyMods.AlmanacClasses")) { RustyAlmanacClassesLoaded = true; } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); YamlConfigManager.Init(); DeathChoiceEditor.Init(); LeaderboardData.Init(); ((MonoBehaviour)this).StartCoroutine(LeaderboardData.SyncLoop()); TerminalCommands.AddCommands(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Death is not the end."); } public static DataObjects.DeathChoiceLevel pcfg() { return DeathConfigurationData.playerDeathConfiguration; } private void AddLocalizations() { Localization = LocalizationManager.Instance.GetLocalization(); string text = Path.Combine(Paths.ConfigPath, "Deathlink", "localizations"); Directory.CreateDirectory(text); string[] manifestResourceNames = typeof(Deathlink).Assembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (!text2.Contains("Localizations")) { continue; } string input = ReadEmbeddedResourceFile(text2); string text3 = Regex.Replace(input, "\\/\\/.*", ""); Dictionary<string, string> internal_localization = SimpleJson.DeserializeObject<Dictionary<string, string>>(text3); string[] array = text2.Split(new char[1] { '.' }); if (File.Exists(text + "/" + array[2] + ".json")) { string text4 = File.ReadAllText(text + "/" + array[2] + ".json"); try { Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text4); UpdateLocalizationWithMissingKeys(internal_localization, dictionary); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text + "/" + array[2] + ".json")); File.WriteAllText(text + "/" + array[2] + ".json", SimpleJson.SerializeObject((object)dictionary)); string text5 = File.ReadAllText(text + "/" + array[2] + ".json"); Localization.AddJsonFile(array[2], text5); } catch { File.WriteAllText(text + "/" + array[2] + ".json", text3); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2)); Localization.AddJsonFile(array[2], text3); } } else { File.WriteAllText(text + "/" + array[2] + ".json", text3); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2)); Localization.AddJsonFile(array[2], text3); } ((BaseUnityPlugin)this).Logger.LogDebug((object)("Added localization: '" + array[2] + "'")); } } private void UpdateLocalizationWithMissingKeys(Dictionary<string, string> internal_localization, Dictionary<string, string> cached_localization) { if (internal_localization.Keys.Count == cached_localization.Keys.Count) { return; } ((BaseUnityPlugin)this).Logger.LogDebug((object)"Cached localization was missing some entries. They will be added."); foreach (KeyValuePair<string, string> item in internal_localization) { if (!cached_localization.ContainsKey(item.Key)) { cached_localization.Add(item.Key, item.Value); } } } private string ReadEmbeddedResourceFile(string filename) { using Stream stream = typeof(Deathlink).Assembly.GetManifestResourceStream(filename); using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } public static List<T> shuffleList<T>(List<T> inputList) { int i = 0; int count = inputList.Count; int num = 0; T val = default(T); List<T> list = new List<T>(); list.AddRange(inputList); for (; i < count; i++) { num = Random.Range(i, list.Count); val = list[i]; list[i] = list[num]; list[num] = val; } return list; } } } namespace Deathlink.external { public static class EpicMMOSystem_API { public enum API_State { NotReady, NotInstalled, Ready } public enum Attribut { Strength, Agility, Intellect, Body, Vigour, Special } public static API_State state; private static MethodInfo eGetLevel; private static MethodInfo eAddExp; private static MethodInfo eGetAttribute; private static MethodInfo eGetAttributeRusty; private static MethodInfo eSetSingleRate; public static int GetLevel() { int result = 0; Init(); if (eGetLevel != null) { result = (int)eGetLevel.Invoke(null, null); } return result; } public static int GetAttribute(Attribut attribute) { int result = 0; Init(); if (eGetAttribute != null) { result = (int)eGetAttribute.Invoke(null, new object[1] { attribute }); } return result; } public static int GetAttributeRusty(string attribute) { int result = 0; Init(); if (eGetAttributeRusty != null) { result = (int)eGetAttributeRusty.Invoke(null, new object[1] { attribute }); } return result; } public static void AddExp(int value) { Init(); eAddExp?.Invoke(null, new object[1] { value }); } public static void SetSingleRate(float rate) { Init(); eSetSingleRate?.Invoke(null, new object[1] { rate }); } public static void Init() { API_State aPI_State = state; if ((uint)(aPI_State - 1) > 1u) { if (Type.GetType("EpicMMOSystem.EpicMMOSystem, EpicMMOSystem") == null) { state = API_State.NotInstalled; return; } state = API_State.Ready; Type type = Type.GetType("API.EMMOS_API, EpicMMOSystem"); eGetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public); eAddExp = type.GetMethod("AddExp", BindingFlags.Static | BindingFlags.Public); eGetAttribute = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eGetAttributeRusty = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eSetSingleRate = type.GetMethod("SetSingleRate", BindingFlags.Static | BindingFlags.Public); } } } } namespace Deathlink.Death { public static class Compendium { [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] public static class TextsDialog_UpdateTextsList_Patch { public static void Postfix(TextsDialog __instance) { AddDeathLinkExplanationPage(__instance); } private static void AddDeathLinkExplanationPage(TextsDialog textsDialog) { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown DataObjects.DeathChoiceLevel playerDeathConfiguration = DeathConfigurationData.playerDeathConfiguration; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("<size=48>" + Localization.instance.Localize("$comp_header") + ": <color=" + specialColor + ">" + playerDeathConfiguration.DisplayName + "</color></size>"); stringBuilder.AppendLine(); stringBuilder.AppendLine("<size=30><b>Death Effects</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetDeathStyleDescription()); stringBuilder.AppendLine(); if (playerDeathConfiguration.DamageTakenModifier != 1f || playerDeathConfiguration.DamageDoneModifier != 1f) { stringBuilder.AppendLine("<size=30><b>Combat Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetDamageModifierDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.SkillModifiers != null && playerDeathConfiguration.SkillModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetSkillModiferDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.ResourceModifiers != null && playerDeathConfiguration.ResourceModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetResourceModiferDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.DeathLootModifiers != null && playerDeathConfiguration.DeathLootModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Loot Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetLootModifiersDescription()); stringBuilder.AppendLine(); } textsDialog.m_texts.Insert(0, new TextInfo(Localization.instance.Localize("$deathlink_settings"), Localization.instance.Localize(stringBuilder.ToString()))); } } [HarmonyPatch(typeof(TextsDialog), "ShowText", new Type[] { typeof(TextInfo) })] public static class TextsDialog_ShowText_Patch { public static void Postfix(TextsDialog __instance, TextInfo text) { bool flag = text != null && text.m_topic == Localization.instance.Localize("$deathlink_settings"); bool flag2 = flag && DeathConfigurationData.PlayerCanChangeChoice(Player.m_localPlayer); Logger.LogDebug($"TextsDialog.ShowText topic='{text?.m_topic}' isDeathlinkPage={flag} canChange={flag2}"); if (!flag2) { if ((Object)(object)changeChoiceButton != (Object)null) { changeChoiceButton.SetActive(false); } return; } EnsureChangeChoiceButton(__instance); if ((Object)(object)changeChoiceButton != (Object)null) { changeChoiceButton.SetActive(true); changeChoiceButton.transform.SetAsLastSibling(); } } private static void EnsureChangeChoiceButton(TextsDialog dialog) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown if ((Object)(object)changeChoiceButton != (Object)null) { return; } if (GUIManager.Instance == null) { Logger.LogWarning("GUIManager not setup, skipping death choice change button creation."); return; } Transform val = ((Component)dialog).transform.Find("Texts_frame/Closebutton"); changeChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$comp_change_choice"), val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(300f, 0f), 200f, 40f); ((UnityEvent)changeChoiceButton.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { dialog.OnClose(); DeathChoices.DeathChoiceUI.Instance.ShowForChange(); }); } private static RectTransform FindCloseButton(TextsDialog dialog) { Button val = null; Button[] componentsInChildren = ((Component)dialog).GetComponentsInChildren<Button>(true); foreach (Button val2 in componentsInChildren) { if ((Object)(object)((Component)val2).gameObject == (Object)(object)changeChoiceButton) { continue; } for (int j = 0; j < ((UnityEventBase)val2.onClick).GetPersistentEventCount(); j++) { if (((UnityEventBase)val2.onClick).GetPersistentMethodName(j) == "OnClose") { return ((Component)val2).GetComponent<RectTransform>(); } } if ((Object)(object)val == (Object)null && ((Object)val2).name.IndexOf("close", StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; } } if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<RectTransform>(); } } private static string specialColor = "#ffa64d"; private static GameObject changeChoiceButton; } public static class DamageModifiers { [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class DamageModifierPatch { private static void Prefix(Character __instance, HitData hit) { if (hit == null) { return; } if (__instance is Player) { float storedModifier = GetStoredModifier(__instance, DataObjects.DamageTakenModifierKey); if (storedModifier != 1f) { hit.ApplyModifier(storedModifier); } } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { float storedModifier2 = GetStoredModifier((Character)(object)val, DataObjects.DamageDoneModifierKey); if (storedModifier2 != 1f) { hit.ApplyModifier(storedModifier2); } } } private static float GetStoredModifier(Character character, string key) { if ((Object)(object)character == (Object)null) { return 1f; } ZNetView nview = character.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return 1f; } ZDO zDO = nview.GetZDO(); if (zDO == null) { return 1f; } return zDO.GetFloat(key, 1f); } } } internal static class DeathChoiceEditor { private const string EntryName = "Deathlink"; private const float PanelW = 1000f; private const float PanelH = 720f; private const float ListW = 250f; private const float DetailX = 280f; private const float DetailY = 96f; private const float LabelW = 230f; private const float MessagesH = 60f; private static GameObject panel; private static Transform body; private static GameObject detailRoot; private static Transform listContent; private static Text messages; private static DeathChoiceEditorModel model; private static int activeTab; private static bool awaitingServer; private static float sentAtTime; private static readonly string[] TabNames = new string[4] { "$dl_cfg_general", "$dl_cfg_deathstyle", "$dl_cfg_resources", "$dl_cfg_loot" }; internal static void Init() { ConfigUILauncher.Init(); ApplyRegistration(); ConfigNetwork.EditResult += OnEditResult; } internal static void ApplyRegistration() { if (ValConfig.ShowQuickConfigButton == null || ValConfig.ShowQuickConfigButton.Value) { ConfigUILauncher.Register("Deathlink", OpenPanel); } else { ConfigUILauncher.Unregister("Deathlink"); } } private static bool IsOwner() { if (!((Object)(object)ZNet.instance == (Object)null)) { return ZNet.instance.IsServer(); } return true; } internal static void OpenPanel() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown ClosePanel(); if (GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { model = DeathChoiceEditorModel.Snapshot(); awaitingServer = false; activeTab = 0; panel = ConfigUI.CreatePanel("$dl_cfg_title", 1000f, 720f, out body); ConfigUI.AddText(body, 280f, 54f, 700f, 24f, IsOwner() ? "$dl_cfg_banner_local" : "$dl_cfg_banner_remote", 13, (TextAnchor)3, GUIManager.Instance.ValheimBeige); BuildLevelList(); BuildTabs(); BuildDetail(); messages = ConfigUI.AddText(body, 20f, 608f, 960f, 60f, "", 13, (TextAnchor)0); ConfigUI.AddButton(body, 20f, 668f, 130f, "$dl_cfg_validate", new UnityAction(RunValidate), 36f); ConfigUI.AddButton(body, 670f, 668f, 140f, "$dl_cfg_cancel", new UnityAction(ClosePanel), 36f); ConfigUI.AddButton(body, 820f, 668f, 160f, "$dl_cfg_apply", new UnityAction(ApplyAndSave), 36f); } } private static void ClosePanel() { ConfigUIPicker.Close(); if ((Object)(object)panel != (Object)null) { Object.Destroy((Object)(object)panel); panel = null; } body = null; detailRoot = null; listContent = null; messages = null; awaitingServer = false; } private static void BuildLevelList() { //IL_0026: 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_0093: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown ConfigUI.AddText(body, 20f, 54f, 250f, 24f, "$dl_cfg_levels", 15, (TextAnchor)3, GUIManager.Instance.ValheimYellow); ConfigUI.CreateScroll(body, 20f, 82f, 250f, 480f, out listContent, out var contentWidth); RefreshLevelList(contentWidth); float y = 570f; ConfigUI.AddButton(body, 20f, y, 58f, "$dl_cfg_add", new UnityAction(OnAdd), 30f); ConfigUI.AddButton(body, 82f, y, 58f, "$dl_cfg_duplicate", new UnityAction(OnDuplicate), 30f); ConfigUI.AddButton(body, 144f, y, 58f, "$dl_cfg_rename", new UnityAction(OnRename), 30f); ConfigUI.AddButton(body, 206f, y, 58f, "$dl_cfg_delete", new UnityAction(OnDelete), 30f); } private static void RefreshLevelList(float contentW) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)listContent == (Object)null) { return; } foreach (Transform item in listContent) { Transform val = item; Object.Destroy((Object)(object)((Component)val).gameObject); } foreach (string item2 in model.Order) { string entry = item2; bool flag = string.Equals(entry, model.SelectedKey, StringComparison.Ordinal); GameObject val2 = ConfigUI.NewLayoutRow(listContent, contentW, 32f); GameObject val3 = ConfigUI.AddButton(val2.transform, 0f, 0f, contentW, entry, (UnityAction)delegate { model.SelectedKey = entry; RefreshLevelList(contentW); BuildDetail(); }, 30f); if (flag) { Text componentInChildren = val3.GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = GUIManager.Instance.ValheimOrange; } } } } private static void RebuildList() { RefreshLevelList(234f); BuildDetail(); } private static void OnAdd() { ConfigUIPrompt.Show("$dl_cfg_add_title", "$dl_cfg_add_label", "", null, delegate(string name) { if (!model.TryAdd(name, out var message)) { ShowError(message); } else { if (!string.IsNullOrEmpty(message)) { ShowWarning(message); } RebuildList(); } }); } private static void OnDuplicate() { if (!string.IsNullOrEmpty(model.SelectedKey) && model.Duplicate(model.SelectedKey) != null) { RebuildList(); } } private static void OnRename() { if (string.IsNullOrEmpty(model.SelectedKey)) { return; } string oldKey = model.SelectedKey; string text = ConfigUI.L("$dl_cfg_rename_warning").Replace("{0}", oldKey); if (ValConfig.DefaultDeathChoice != null && string.Equals(ValConfig.DefaultDeathChoice.Value, oldKey, StringComparison.Ordinal)) { text = text + "\n" + ConfigUI.L("$dl_cfg_rename_isdefault"); } ConfigUIPrompt.Show("$dl_cfg_rename_title", "$dl_cfg_rename_label", oldKey, text, delegate(string newKey) { if (!model.TryRename(oldKey, newKey, out var message)) { ShowError(message); } else { if (!string.IsNullOrEmpty(message)) { ShowWarning(message); } RebuildList(); } }); } private static void OnDelete() { if (string.IsNullOrEmpty(model.SelectedKey)) { return; } if (!model.TryDelete(model.SelectedKey, out var message)) { ShowError(message); return; } if (!string.IsNullOrEmpty(message)) { ShowWarning(message); } RebuildList(); } private static void BuildTabs() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown float num = 280f; for (int i = 0; i < TabNames.Length; i++) { int index = i; ConfigUI.AddButton(body, num, 78f, 170f, TabNames[index], (UnityAction)delegate { activeTab = index; BuildDetail(); }, 30f); num += 176f; } } private static void BuildDetail() { if ((Object)(object)detailRoot != (Object)null) { Object.Destroy((Object)(object)detailRoot); detailRoot = null; } if ((Object)(object)body == (Object)null) { return; } float num = 700f; float num2 = 494f; detailRoot = ConfigUI.NewRect("Detail", body, 280f, 116f, num, num2); if (string.IsNullOrEmpty(model.SelectedKey) || !model.Levels.TryGetValue(model.SelectedKey, out var value)) { ConfigUI.AddText(detailRoot.transform, 0f, 0f, num, 30f, "$dl_cfg_noselection", 15, (TextAnchor)3); return; } switch (activeTab) { case 1: BuildDeathStyleTab(value, num, num2); break; case 2: BuildResourcesTab(value, num, num2); break; case 3: BuildLootTab(value, num, num2); break; default: BuildGeneralTab(value, num); break; } } private static void BuildGeneralTab(DataObjects.DeathChoiceLevel level, float width) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); Transform transform = detailRoot.transform; list.Add(ConfigUI.AddTextRow(transform, width, 26f, ConfigUI.L("$dl_cfg_key") + ": " + model.SelectedKey, 14, GUIManager.Instance.ValheimOrange, (TextAnchor)0)); list.Add(ConfigUI.AddTextFieldRow(transform, width, 230f, 300f, "$dl_cfg_displayname", level.DisplayName, delegate(string s) { level.DisplayName = s; }, null, 64)); list.Add(ConfigUI.AddToggleRow(transform, width, 230f, "$dl_cfg_fallback", level.Fallback, delegate(bool on) { if (on) { model.SetFallback(model.SelectedKey); } else { level.Fallback = false; } BuildDetail(); })); list.Add(ConfigUI.AddSliderRow(transform, width, 230f, 230f, 60f, "$dl_cfg_deathskillrate", 0f, 10f, level.DeathSkillRate, wholeNumbers: false, delegate(float v) { level.DeathSkillRate = v; })); list.Add(ConfigUI.AddSliderRow(transform, width, 230f, 230f, 60f, "$dl_cfg_damagetaken", 0f, 3f, level.DamageTakenModifier, wholeNumbers: false, delegate(float v) { level.DamageTakenModifier = v; })); list.Add(ConfigUI.AddSliderRow(transform, width, 230f, 230f, 60f, "$dl_cfg_damagedone", 0f, 3f, level.DamageDoneModifier, wholeNumbers: false, delegate(float v) { level.DamageDoneModifier = v; })); ConfigUI.LayoutColumn(list, 0f, 0f); } private static void BuildDeathStyleTab(DataObjects.DeathChoiceLevel level, float width, float height) { if (level.DeathStyle == null) { level.DeathStyle = new DataObjects.DeathProgressionDetails(); } DataObjects.DeathProgressionDetails style = level.DeathStyle; ConfigUI.CreateScroll(detailRoot.transform, 0f, 0f, width, height, out var content, out var contentWidth); if ((Object)(object)content == (Object)null) { return; } AddScrollEnumCycle(content, contentWidth, "$dl_cfg_itemlossstyle", Enum.GetNames(typeof(DataObjects.ItemLossStyle)), (int)style.itemLossStyle, delegate(int i) { style.itemLossStyle = (DataObjects.ItemLossStyle)i; BuildDetail(); }); if (style.itemLossStyle != DataObjects.ItemLossStyle.DestroyAll) { AddScrollEnumCycle(content, contentWidth, "$dl_cfg_itemsavedstyle", Enum.GetNames(typeof(DataObjects.ItemSavedStyle)), (int)style.itemSavedStyle, delegate(int i) { style.itemSavedStyle = (DataObjects.ItemSavedStyle)i; }); AddScrollEnumCycle(content, contentWidth, "$dl_cfg_nonskillchecked", Enum.GetNames(typeof(DataObjects.NonSkillCheckedItemAction)), (int)style.nonSkillCheckedItemAction, delegate(int i) { style.nonSkillCheckedItemAction = (DataObjects.NonSkillCheckedItemAction)i; }); AddScrollToggle(content, contentWidth, "$dl_cfg_enablesavingchoices", style.EnableItemSavingChoices, delegate(bool v) { style.EnableItemSavingChoices = v; }); } if (style.itemLossStyle == DataObjects.ItemLossStyle.DeathlinkBased) { AddScrollHeader(content, contentWidth, "$dl_cfg_keepbudget"); AddScrollSlider(content, contentWidth, "$dl_cfg_minitems", 0f, 64f, style.minItemsKept, whole: true, delegate(float v) { style.minItemsKept = (int)v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_maxitems", 0f, 64f, style.maxItemsKept, whole: true, delegate(float v) { style.maxItemsKept = (int)v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_minequip", 0f, 16f, style.minEquipmentKept, whole: true, delegate(float v) { style.minEquipmentKept = (int)v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_maxequip", 0f, 16f, style.maxEquipmentKept, whole: true, delegate(float v) { style.maxEquipmentKept = (int)v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_minchoices", 0f, 16f, style.minItemsKeptChoices, whole: true, delegate(float v) { style.minItemsKeptChoices = (int)v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_maxchoices", 0f, 16f, style.maxItemsKeptChoices, whole: true, delegate(float v) { style.maxItemsKeptChoices = (int)v; }); } AddScrollHeader(content, contentWidth, "$dl_cfg_skillloss"); AddScrollToggle(content, contentWidth, "$dl_cfg_skilllossondeath", style.skillLossOnDeath, delegate(bool v) { style.skillLossOnDeath = v; }); if (style.skillLossOnDeath) { AddScrollSlider(content, contentWidth, "$dl_cfg_minskillloss", 0f, 1f, style.minSkillLossPercentage, whole: false, delegate(float v) { style.minSkillLossPercentage = v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_maxskillloss", 0f, 1f, style.maxSkillLossPercentage, whole: false, delegate(float v) { style.maxSkillLossPercentage = v; }); } AddScrollHeader(content, contentWidth, "$dl_cfg_food"); AddScrollToggle(content, contentWidth, "$dl_cfg_foodloss", style.foodLossOnDeath, delegate(bool v) { style.foodLossOnDeath = v; BuildDetail(); }); if (style.foodLossOnDeath) { AddScrollToggle(content, contentWidth, "$dl_cfg_fooddeathlink", style.foodLossUsesDeathlink, delegate(bool v) { style.foodLossUsesDeathlink = v; }); } } private static void BuildResourcesTab(DataObjects.DeathChoiceLevel level, float width, float height) { //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) ConfigUI.CreateScroll(detailRoot.transform, 0f, 0f, width, height, out var content, out var contentWidth); if ((Object)(object)content == (Object)null) { return; } if (level.ResourceModifiers == null) { level.ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>(); } if (level.SkillModifiers == null) { level.SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier>(); } AddScrollHeader(content, contentWidth, "$dl_cfg_resourcemods"); foreach (KeyValuePair<string, DataObjects.DeathResourceModifier> item in new List<KeyValuePair<string, DataObjects.DeathResourceModifier>>(level.ResourceModifiers)) { string entryKey = item.Key; DataObjects.DeathResourceModifier modifier = item.Value; if (modifier != null) { AddEntryHeader(content, contentWidth, entryKey, delegate { level.ResourceModifiers.Remove(entryKey); BuildDetail(); }); AddScrollSlider(content, contentWidth, "$dl_cfg_bonusmodifier", 0f, 5f, modifier.BonusModifier, whole: false, delegate(float v) { modifier.BonusModifier = v; }); AddScrollToggle(content, contentWidth, "$dl_cfg_skillinfluence", modifier.skillInfluence, delegate(bool v) { modifier.skillInfluence = v; }); AddBonusActions(content, contentWidth, modifier.bonusActions); if (modifier.prefabs == null) { modifier.prefabs = new List<string>(); } ConfigUI.AddStringListEditor(content, contentWidth, "$dl_cfg_prefabs", modifier.prefabs, BuildDetail, PrefabNames, IsKnownPrefab); } } AddAddButton(content, contentWidth, "$dl_cfg_addresource", delegate { level.ResourceModifiers[UniqueEntryKey(level.ResourceModifiers.Keys, "NewResource")] = new DataObjects.DeathResourceModifier { BonusModifier = 1f, prefabs = new List<string>() }; BuildDetail(); }); AddScrollHeader(content, contentWidth, "$dl_cfg_skillmods"); foreach (KeyValuePair<string, DataObjects.DeathSkillModifier> item2 in new List<KeyValuePair<string, DataObjects.DeathSkillModifier>>(level.SkillModifiers)) { string entryKey2 = item2.Key; DataObjects.DeathSkillModifier modifier2 = item2.Value; if (modifier2 == null) { continue; } AddEntryHeader(content, contentWidth, entryKey2, delegate { level.SkillModifiers.Remove(entryKey2); BuildDetail(); }); AddScrollPicker(content, contentWidth, "$dl_cfg_skill", ((object)modifier2.skill/*cast due to .constrained prefix*/).ToString(), SkillNames, delegate(string s) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (Enum.IsDefined(typeof(SkillType), s)) { modifier2.skill = (SkillType)Enum.Parse(typeof(SkillType), s, ignoreCase: true); } }, IsKnownSkill); AddScrollSlider(content, contentWidth, "$dl_cfg_bonusmodifier", 0f, 5f, modifier2.BonusModifier, whole: false, delegate(float v) { modifier2.BonusModifier = v; }); AddScrollToggle(content, contentWidth, "$dl_cfg_skillinfluence", modifier2.skillInfluence, delegate(bool v) { modifier2.skillInfluence = v; }); } AddAddButton(content, contentWidth, "$dl_cfg_addskill", delegate { level.SkillModifiers[UniqueEntryKey(level.SkillModifiers.Keys, "NewSkill")] = new DataObjects.DeathSkillModifier { BonusModifier = 1f, skill = (SkillType)999 }; BuildDetail(); }); } private static void BuildLootTab(DataObjects.DeathChoiceLevel level, float width, float height) { ConfigUI.CreateScroll(detailRoot.transform, 0f, 0f, width, height, out var content, out var contentWidth); if ((Object)(object)content == (Object)null) { return; } if (level.DeathLootModifiers == null) { level.DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(); } AddScrollHeader(content, contentWidth, "$dl_cfg_lootmods"); foreach (KeyValuePair<string, DataObjects.DeathLootModifier> item in new List<KeyValuePair<string, DataObjects.DeathLootModifier>>(level.DeathLootModifiers)) { string entryKey = item.Key; DataObjects.DeathLootModifier modifier = item.Value; if (modifier != null) { AddEntryHeader(content, contentWidth, entryKey, delegate { level.DeathLootModifiers.Remove(entryKey); BuildDetail(); }); AddScrollPicker(content, contentWidth, "$dl_cfg_prefab", modifier.prefab, PrefabNames, delegate(string s) { modifier.prefab = s; }, IsKnownPrefab); AddScrollSlider(content, contentWidth, "$dl_cfg_chance", 0f, 1f, modifier.chance, whole: false, delegate(float v) { modifier.chance = v; }); AddScrollSlider(content, contentWidth, "$dl_cfg_amount", 1f, 100f, modifier.amount, whole: true, delegate(float v) { modifier.amount = (int)v; }); AddBonusActions(content, contentWidth, modifier.bonusActions); } } AddAddButton(content, contentWidth, "$dl_cfg_addloot", delegate { level.DeathLootModifiers[UniqueEntryKey(level.DeathLootModifiers.Keys, "NewLoot")] = new DataObjects.DeathLootModifier { chance = 0.05f, amount = 1, bonusActions = new List<DataObjects.ResourceGainTypes>() }; BuildDetail(); }); } private static void AddScrollHeader(Transform content, float w, string label) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 0f, 0f, w, 34f, label, 16, (TextAnchor)3, GUIManager.Instance.ValheimYellow); } private static void AddEntryHeader(Transform content, float w, string entryKey, Action onDelete) { //IL_003f: 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_0081: Expected O, but got Unknown GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, w - 110f, 34f, entryKey, 15, (TextAnchor)3, GUIManager.Instance.ValheimOrange); ConfigUI.AddButton(val.transform, w - 96f, 2f, 92f, "$dl_cfg_deleteentry", (UnityAction)delegate { onDelete(); }, 28f); } private static void AddAddButton(Transform content, float w, string label, Action onAdd) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddButton(val.transform, 8f, 2f, 220f, label, (UnityAction)delegate { onAdd(); }, 28f); } private static void AddScrollToggle(Transform content, float w, string label, bool value, Action<bool> onChange) { GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, 230f, 34f, label, 15, (TextAnchor)3); ConfigUI.AddToggle(val.transform, 244f, 4f, 24f, value, onChange); } private static void AddScrollSlider(Transform content, float w, string label, float min, float max, float value, bool whole, Action<float> onChange) { GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, 230f, 34f, label, 15, (TextAnchor)3); Slider slider = ConfigUI.BuildSlider(val.transform, 244f, 7f, 220f, min, max, value, whole); float x = 474f; InputField box = ConfigUI.AddTextField(val.transform, x, 3f, 66f, ConfigUI.Fmt(value, whole), null, (ContentType)(whole ? 2 : 3)); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v) { if (whole) { v = Mathf.Round(v); } box.SetTextWithoutNotify(ConfigUI.Fmt(v, whole)); onChange(v); }); ((UnityEvent<string>)(object)box.onEndEdit).AddListener((UnityAction<string>)delegate(string str) { if (!float.TryParse(str, out var result)) { result = slider.value; } result = Mathf.Clamp(result, min, max); if (whole) { result = Mathf.Round(result); } box.SetTextWithoutNotify(ConfigUI.Fmt(result, whole)); if (slider.value != result) { slider.value = result; } else { onChange(result); } }); } private static void AddScrollEnumCycle(Transform content, float w, string label, string[] options, int current, Action<int> onChange) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, 230f, 34f, label, 15, (TextAnchor)3); int idx = Mathf.Clamp(current, 0, Math.Max(0, options.Length - 1)); GameObject val2 = ConfigUI.AddButton(val.transform, 244f, 2f, 210f, (options.Length != 0) ? options[idx] : "", null, 28f); Text caption = val2.GetComponentInChildren<Text>(); ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { if (options.Length != 0) { idx = (idx + 1) % options.Length; caption.text = options[idx]; onChange(idx); } }); } private static void AddScrollPicker(Transform content, float w, string label, string current, Func<IList<string>> options, Action<string> onPick, Func<string, bool> isKnown) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, 230f, 34f, label, 15, (TextAnchor)3); InputField field = ConfigUI.AddTextField(val.transform, 244f, 3f, 220f, current, onPick, (ContentType)0); Text marker = ConfigUI.AddText(val.transform, 508f, 0f, 20f, 34f, "", 15, (TextAnchor)3, (Color?)new Color(0.98f, 0.75f, 0.14f)); Action refresh = delegate { bool flag = !string.IsNullOrEmpty(field.text) && !isKnown(field.text); marker.text = (flag ? "!" : ""); }; refresh(); ((UnityEvent<string>)(object)field.onEndEdit).AddListener((UnityAction<string>)delegate { refresh(); }); ConfigUI.AddButton(val.transform, 470f, 3f, 34f, "...", (UnityAction)delegate { ConfigUIPicker.ShowPicker(label, options(), field.text, delegate(string picked) { field.SetTextWithoutNotify(picked); refresh(); onPick(picked); }); }, 28f); } private static void AddBonusActions(Transform content, float w, List<DataObjects.ResourceGainTypes> actions) { if (actions == null) { return; } GameObject val = ConfigUI.NewLayoutRow(content, w, 34f); ConfigUI.AddText(val.transform, 8f, 0f, 230f, 34f, "$dl_cfg_bonusactions", 15, (TextAnchor)3); string[] names = Enum.GetNames(typeof(DataObjects.ResourceGainTypes)); float num = 244f; for (int i = 0; i < names.Length; i++) { DataObjects.ResourceGainTypes value = (DataObjects.ResourceGainTypes)Enum.Parse(typeof(DataObjects.ResourceGainTypes), names[i]); ConfigUI.AddToggle(val.transform, num, 4f, 22f, actions.Contains(value), delegate(bool on) { if (on) { if (!actions.Contains(value)) { actions.Add(value); } } else { actions.Remove(value); } }); ConfigUI.AddText(val.transform, num + 26f, 0f, 100f, 34f, names[i], 13, (TextAnchor)3); num += 130f; } } private static void RunValidate() { if (model != null) { ValidationReport validationReport = model.Validate(); if (validationReport.Errors.Count == 0 && validationReport.Warnings.Count == 0) { messages.text = ConfigUI.L("$dl_cfg_looksgood"); } else { ConfigUI.SetMessages(messages, validationReport.Errors, validationReport.Warnings); } } } private static void ApplyAndSave() { if (model == null || awaitingServer) { return; } try { ValidationReport validationReport = model.Validate(); if (validationReport.HasErrors) { ConfigUI.SetMessages(messages, validationReport.Errors, validationReport.Warnings); return; } YamlConfigFile<Dictionary<string, DataObjects.DeathChoiceLevel>> deathChoices = YamlConfigManager.DeathChoices; if (deathChoices != null && deathChoices.LastLoadedUtc != model.BaseLoadedUtc) { model.BaseLoadedUtc = deathChoices.LastLoadedUtc; ShowWarning(ConfigUI.L("$dl_cfg_changedunderneath")); return; } string yaml = model.Serialize(); if (IsOwner()) { if (!YamlConfigManager.ApplyEdited(deathChoices, yaml, out var message)) { ShowError(message); return; } if (!string.IsNullOrEmpty(message)) { Logger.LogWarning(message); } ClosePanel(); return; } if (!ConfigNetwork.RequestEdit(deathChoices, yaml, out var refusal)) { ShowError(refusal); return; } awaitingServer = true; sentAtTime = Time.realtimeSinceStartup; messages.text = ConfigUI.L("$dl_cfg_sent"); ThreadingHelper instance = ThreadingHelper.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(AwaitServerReply()); } } catch (Exception ex) { Logger.LogError($"Death choice editor failed to apply: {ex}"); ShowError(ex.Message); } } private static IEnumerator AwaitServerReply() { while (awaitingServer && Time.realtimeSinceStartup - sentAtTime < 10f) { yield return null; } if (awaitingServer) { awaitingServer = false; ShowError(ConfigUI.L("$dl_cfg_noreply")); } } private static void OnEditResult(YamlConfigFile file, bool accepted, string message) { if (!awaitingServer || file != YamlConfigManager.DeathChoices) { return; } awaitingServer = false; if (!accepted) { ShowError(message); return; } if (!string.IsNullOrEmpty(message)) { Logger.LogWarning(message); } ClosePanel(); } private static void ShowError(string message) { ConfigUI.SetMessages(messages, new List<string> { message }, null); } private static void ShowWarning(string message) { ConfigUI.SetMessages(messages, null, new List<string> { message }); } private static IList<string> PrefabNames() { List<string> list = new List<string>(); if ((Object)(object)ZNetScene.instance == (Object)null) { return list; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab != (Object)null) { list.Add(((Object)prefab).name); } } return list; } private static bool IsKnownPrefab(string name) { if (!Utils.PrefabsAvailable()) { return true; } return (Object)(object)PrefabManager.Instance.GetPrefab(name) != (Object)null; } private static IList<string> SkillNames() { //IL_000b: 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) List<string> list = new List<string> { ((object)(SkillType)999/*cast due to .constrained prefix*/).ToString() }; string[] names = Enum.GetNames(typeof(SkillType)); foreach (string text in names) { if (!(text == ((object)(SkillType)999/*cast due to .constrained prefix*/).ToString())) { list.Add(text); } } return list; } private static bool IsKnownSkill(string name) { return Enum.IsDefined(typeof(SkillType), name); } private static string UniqueEntryKey(ICollection<string> existing, string candidate) { if (!existing.Contains(candidate)) { return candidate; } for (int i = 2; i < 1000; i++) { if (!existing.Contains(candidate + i)) { return candidate + i; } } return candidate + Guid.NewGuid().ToString("N").Substring(0, 4); } } internal sealed class DeathChoiceEditorModel { internal Dictionary<string, DataObjects.DeathChoiceLevel> Levels = new Dictionary<string, DataObjects.DeathChoiceLevel>(); internal List<string> Order = new List<string>(); internal string SelectedKey; internal DateTime BaseLoadedUtc; private static YamlFormat Format { get { YamlConfigFile<Dictionary<string, DataObjects.DeathChoiceLevel>> deathChoices = YamlConfigManager.DeathChoices; if (deathChoices == null) { return YamlFormat.Default; } return deathChoices.EffectiveFormat; } } internal static DeathChoiceEditorModel Snapshot() { DeathChoiceEditorModel deathChoiceEditorModel = new DeathChoiceEditorModel(); YamlConfigFile<Dictionary<string, DataObjects.DeathChoiceLevel>> deathChoices = YamlConfigManager.DeathChoices; Dictionary<string, DataObjects.DeathChoiceLevel> dictionary = null; if (deathChoices != null && deathChoices.Value != null) { try { YamlFormat effectiveFormat = deathChoices.EffectiveFormat; dictionary = effectiveFormat.Deserializer.Deserialize<Dictionary<string, DataObjects.DeathChoiceLevel>>(effectiveFormat.Serializer.Serialize((object)deathChoices.Value)); } catch (Exception ex) { Logger.LogError("Could not copy the death levels for editing: " + ex.Message); } } deathChoiceEditorModel.Levels = dictionary ?? new Dictionary<string, DataObjects.DeathChoiceLevel>(); deathChoiceEditorModel.Order = new List<string>(deathChoiceEditorModel.Levels.Keys); deathChoiceEditorModel.SelectedKey = ((deathChoiceEditorModel.Order.Count > 0) ? deathChoiceEditorModel.Order[0] : null); deathChoiceEditorModel.BaseLoadedUtc = deathChoices?.LastLoadedUtc ?? DateTime.MinValue; return deathChoiceEditorModel; } internal bool TryAdd(string key, out string message) { key = (key ?? "").Trim(); if (!IsUsableKey(key, out message)) { return false; } if (Levels.ContainsKey(key)) { message = "A level called '" + key + "' already exists."; return false; } Levels[key] = new DataObjects.DeathChoiceLevel { DisplayName = key, DeathStyle = new DataObjects.DeathProgressionDetails() }; Order.Add(key); SelectedKey = key; message = NearMatchWarning(key); return true; } internal bool TryRename(string oldKey, string newKey, out string message) { message = null; newKey = (newKey ?? "").Trim(); if (!Levels.ContainsKey(oldKey)) { message = "That level no longer exists."; return false; } if (!IsUsableKey(newKey, out message)) { return false; } if (string.Equals(oldKey, newKey, StringComparison.Ordinal)) { return true; } if (Levels.ContainsKey(newKey)) { message = "A level called '" + newKey + "' already exists."; return false; } DataObjects.DeathChoiceLevel value = Levels[oldKey]; Levels.Remove(oldKey); Levels[newKey] = value; int num = Order.IndexOf(oldKey); if (num >= 0) { Order[num] = newKey; } else { Order.Add(newKey); } if (string.Equals(SelectedKey, oldKey, StringComparison.Ordinal)) { SelectedKey = newKey; } message = NearMatchWarning(newKey); return true; } internal bool TryDelete(string key, out string message) { message = null; if (!Levels.ContainsKey(key)) { message = "That level no longer exists."; return false; } if (Levels.Count <= 1) { message = "There has to be at least one death level."; return false; } bool fallback = Levels[key].Fallback; Levels.Remove(key); Order.Remove(key); if (string.Equals(SelectedKey, key, StringComparison.Ordinal)) { SelectedKey = ((Order.Count > 0) ? Order[0] : null); } if (fallback && Order.Count > 0) { Levels[Order[0]].Fallback = true; message = "'" + key + "' was the fallback level, so '" + Order[0] + "' is now."; } return true; } internal string Duplicate(string key) { if (!Levels.ContainsKey(key)) { return null; } DataObjects.DeathChoiceLevel deathChoiceLevel; try { YamlFormat format = Format; deathChoiceLevel = format.Deserializer.Deserialize<DataObjects.DeathChoiceLevel>(format.Serializer.Serialize((object)Levels[key])); } catch (Exception ex) { Logger.LogError("Could not duplicate '" + key + "': " + ex.Message); return null; } if (deathChoiceLevel == null) { return null; } deathChoiceLevel.Fallback = false; string text = UniqueKey(key + "Copy"); Levels[text] = deathChoiceLevel; int num = Order.IndexOf(key); if (num >= 0) { Order.Insert(num + 1, text); } else { Order.Add(text); } SelectedKey = text; return text; } internal void SetFallback(string key) { foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> level in Levels) { if (level.Value != null) { level.Value.Fallback = string.Equals(level.Key, key, StringComparison.Ordinal); } } } internal string Serialize() { Dictionary<string, DataObjects.DeathChoiceLevel> dictionary = new Dictionary<string, DataObjects.DeathChoiceLevel>(); foreach (string item in Order) { if (Levels.TryGetValue(item, out var value)) { dictionary[item] = value; } } foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> level in Levels) { if (!dictionary.ContainsKey(level.Key)) { dictionary[level.Key] = level.Value; } } return YamlConfigManager.SerializeForEdit(YamlConfigManager.DeathChoices, dictionary); } internal ValidationReport Validate() { return DeathConfigurationData.ValidateDeathLevels(Levels, DeathConfigurationData.DeathLevels); } private static bool IsUsableKey(string key, out string message) { message = null; if (string.IsNullOrWhiteSpace(key)) { message = "A level needs a name."; return false; } if (key.IndexOf(':') >= 0 || key.IndexOf('#') >= 0 || key.StartsWith("-")) { message = "A level name cannot contain ':' or '#', or start with '-'."; return false; } return true; } private string NearMatchWarning(string key) { foreach (string item in Order) { if (!string.Equals(item, key, StringComparison.Ordinal) && string.Equals(item, key, StringComparison.OrdinalIgnoreCase)) { return "'" + key + "' differs from '" + item + "' only by capitalisation. They are two separate levels."; } } return null; } private string UniqueKey(string candidate) { if (!Levels.ContainsKey(candidate)) { return candidate; } for (int i = 2; i < 1000; i++) { string text = candidate + i; if (!Levels.ContainsKey(text)) { return text; } } return candidate + Guid.NewGuid().ToString("N").Substring(0, 4); } } public static class DeathChoiceEnable { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class ShowDeathChoiceUI { public static void Postfix(InventoryGui __instance) { if (ValConfig.UsePrivateKeysForDeathChoice.Value) { if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey)) { return; } } else if ((Object)(object)Player.m_localPlayer != (Object)null && DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID())) { return; } DeathChoices.DeathChoiceUI.Instance.Show(); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class HideDeathChoiceUI { public static void Postfix(InventoryGui __instance) { if (DeathChoices.DeathChoiceUI.IsInitialized) { DeathChoices.DeathChoiceUI.Instance.Hide(); } } } } public class DeathChoices { public class DeathChoiceUI : MonoBehaviour { private static DeathChoiceUI _instance; private static GameObject DeathChoicePanel; private static GameObject ChoicesScrollView; private static GameObject ChoicesContent; private static GameObject ChoicesContainer; private static GameObject manualCloseButton; private static GameObject selectChoiceButton; private static Text DeathPenaltyDescription; private static Text CombatModifiersDescription; private static Text XPModifiersDescription; private static Text LootModifersDescription; private static Text HarvestModifiersDescription; private static List<Toggle> difficultyToggles = new List<Toggle>(); private static ToggleGroup choiceGroup; private static string selectedDeathChoice = "none"; private static bool isChangeMode = false; public static DeathChoiceUI Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("DeathlinkDeathChoiceUI"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<DeathChoiceUI>(); } return _instance; } } public static bool IsInitialized => (Object)(object)_instance != (Object)null; public void Awake() { _instance = this; CreateStaticUIObjects(); SetChoiceList(); } public void Show() { if ((Object)(object)DeathChoicePanel == (Object)null) { CreateStaticUIObjects(); SetChoiceList(); } DeathChoicePanel.SetActive(true); } public void ShowForChange() { isChangeMode = true; Show(); } public void Hide() { if ((Object)(object)DeathChoicePanel != (Object)null) { DeathChoicePanel.SetActive(false); } isChangeMode = false; GUIManager.BlockInput(false); } internal void RebuildChoiceList() { if (!((Object)(object)ChoicesContent == (Object)null)) { SetChoiceList(); } } internal static void RefreshIfBuilt() { if (IsInitialized) { Instance.RebuildChoiceList(); } } public void MakePlayerDeathSelection() { if ((Object)(object)Player.m_localPlayer == (Object)null) { Logger.LogWarning("Player not set, ensure the local player is set."); return; } if (selectedDeathChoice == "none") { Logger.LogWarning("No death type selected"); return; } Logger.LogDebug("Player selected death type " + selectedDeathChoice); long playerID = Player.m_localPlayer.GetPlayerID(); if (DeathConfigurationData.playerSettings.ContainsKey(playerID)) { DeathConfigurationData.playerSettings[playerID].DeathChoiceLevel = selectedDeathChoice; } else { DeathConfigurationData.playerSettings.Add(playerID, new DataObjects.DeathConfiguration { DeathChoiceLevel = selectedDeathChoice }); } Player.m_localPlayer.PlayerRemoveUniqueKey(DataObjects.DeathChoiceKey); Player.m_localPlayer.AddUniqueKeyValue(DataObjects.DeathChoiceKey, selectedDeathChoice); if (isChangeMode) { DeathConfigurationData.IncrementPlayerChangesUsed(Player.m_localPlayer); } DeathConfigurationData.CheckAndSetPlayerDeathConfig(Player.m_localPlayer); DeathConfigurationData.WritePlayerChoices(); Hide(); } private void SetChoiceList() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in ChoicesContent.transform) { Transform val = item; Object.Destroy((Object)(object)((Component)val).gameObject); } difficultyToggles.Clear(); int num = -75; foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> entry in DeathConfigurationData.DeathLevels) { GameObject val2 = Object.Instantiate<GameObject>(ChoicesContainer, ChoicesContent.transform); Transform val3 = val2.transform.Find("selecter"); ((Component)val3.Find("Label")).GetComponent<Text>().text = entry.Key; ((Component)val2.transform.Find("ChoiceName")).GetComponent<Text>().text = entry.Value.DisplayName; Toggle component = ((Component)val3).GetComponent<Toggle>(); component.group = choiceGroup; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn) { if (isOn) { ((Component)DeathPenaltyDescription).GetComponent<Text>().text = entry.Value.GetDeathStyleDescription(); ((Component)CombatModifiersDescription).GetComponent<Text>().text = entry.Value.GetDamageModifierDescription(); ((Component)XPModifiersDescription).GetComponent<Text>().text = entry.Value.GetSkillModiferDescription(); ((Component)LootModifersDescription).GetComponent<Text>().text = entry.Value.GetLootModifiersDescription(); ((Component)HarvestModifiersDescription).GetComponent<Text>().text = entry.Value.GetResourceModiferDescription(); selectedDeathChoice = entry.Key; } }); val2.SetActive(true); val2.transform.localPosition = new Vector3 { x = 5f, y = num }; difficultyToggles.Add(component); num -= 50; } } private void CreateStaticUIObjects() { //IL_004f: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_0535: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_0553: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_056a: Unknown result type (might be due to invalid IL or missing references) //IL_05d8: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_065d: Unknown result type (might be due to invalid IL or missing references) //IL_066c: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_0700: Unknown result type (might be due to invalid IL or missing references) //IL_070f: Unknown result type (might be due to invalid IL or missing references) //IL_071e: Unknown result type (might be due to invalid IL or missing references) //IL_0734: Unknown result type (might be due to invalid IL or missing references) //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_0785: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_07a3: Unknown result type (might be due to invalid IL or missing references) //IL_07b4: Unknown result type (might be due to invalid IL or missing references) //IL_07ba: Unknown result type (might be due to invalid IL or missing references) //IL_0828: Unknown result type (might be due to invalid IL or missing references) //IL_0837: Unknown result type (might be due to invalid IL or missing references) //IL_0846: Unknown result type (might be due to invalid IL or missing references) //IL_0879: Unknown result type (might be due to invalid IL or missing references) //IL_0883: Expected O, but got Unknown //IL_08ad: Unknown result type (might be due to invalid IL or missing references) //IL_08b2: Unknown result type (might be due to invalid IL or missing references) //IL_08d7: Unknown result type (might be due to invalid IL or missing references) //IL_08f5: Unknown result type (might be due to invalid IL or missing references) //IL_08f7: Unknown result type (might be due to invalid IL or missing references) //IL_0947: Unknown result type (might be due to invalid IL or missing references) //IL_095b: Expected O, but got Unknown //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_09f0: Unknown result type (might be due to invalid IL or missing references) //IL_09f5: 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_0a61: Unknown result type (might be due to invalid IL or missing references) //IL_0a70: Unknown result type (might be due to invalid IL or missing references) //IL_0a86: 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) if (!((Object)(object)DeathChoicePanel != (Object)null)) { if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { Logger.LogWarning("GUIManager not setup, skipping static object creation."); return; } Logger.LogDebug("Creating static UI"); DeathChoicePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 960f, true); DeathChoicePanel.SetActive(false); GameObject val = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 430f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false); ((Object)val).name = "DLHeader"; GameObject val2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 380f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 560f, 60f, false); Text component = val2.GetComponent<Text>(); component.resizeTextForBestFit = true; component.resizeTextMaxSize = 20; component.alignment = (TextAnchor)4; manualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$close"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(360f, 430f), 60f, 60f); Button component2 = manualCloseButton.GetComponent<Button>(); ((Selectable)component2).interactable = true; ((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide)); manualCloseButton.SetActive(true); GameObject val3 = GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 330f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false); ((Object)val3).name = "DeathPenaltyTitle"; GameObject val4 = GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(147f, 240f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 490f, 160f, false); ((Object)val4).name = "DeathPenaltyDesc"; DeathPenaltyDescription = val4.GetComponent<Text>(); DeathPenaltyDescription.resizeTextForBestFit = true; DeathPenaltyDescription.resizeTextMaxSize = 18; GameObject val5 = GUIManager.Instance.CreateText(Localization.instance.Localize("$combat_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 150f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false); ((Object)val5).name = "combatModifiersTitle"; GameObject val6 = GUIManager.Instance.CreateText(Localization.instance.Localize("$combat_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, 80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 100f, false); ((Object)val6).name = "combatModifiersDesc"; CombatModifiersDescription = val6.GetComponent<Text>(); CombatModifiersDescription.resizeTextForBestFit = true; CombatModifiersDescription.resizeTextMaxSize = 18; GameObject val7 = GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 30f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false); ((Object)val7).name = "xpModifiersTitle"; GameObject val8 = GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_mod_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)val8).name = "xpModifiersDesc"; XPModifiersDescription = val8.GetComponent<Text>(); XPModifiersDescription.resizeTextForBestFit = true; XPModifiersDescription.resizeTextMaxSize = 18; GameObject val9 = GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -130f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false); ((Object)val9).name = "lootModifiersTitle"; GameObject val10 = GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -240f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)val10).name = "lootModifersDesc"; LootModifersDescription = val10.GetComponent<Text>(); LootModifersDescription.resizeTextForBestFit = true; LootModifersDescription.resizeTextMaxSize = 18; GameObject val11 = GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -260f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false); ((Object)val11).name = "harvestModifiersTitle"; GameObject val12 = GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -370f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)val12).name = "harvestModifersDesc"; HarvestModifiersDescription = val12.GetComponent<Text>(); HarvestModifiersDescription.resizeTextForBestFit = true; HarvestModifiersDescription.resizeTextMaxSize = 18; selectChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$deathchoice_select"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-240f, -290f), 200f, 80f); Button component3 = selectChoiceButton.GetComponent<Button>(); ((UnityEvent)component3.onClick).AddListener(new UnityAction(MakePlayerDeathSelection)); Logger.LogDebug("Setting up scroll entry"); ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 250f, 400f); ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2 { x = -260f, y = -30f }); ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject; ChoicesScrollView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f; choiceGroup = ChoicesContent.AddComponent<ToggleGroup>(); Logger.LogDebug("Setting up death choice template entry"); ChoicesContainer = Object.Instantiate<GameObject>(new GameObject("DeathChoice"), DeathChoicePanel.transform); RectTransform val13 = ChoicesContainer.AddComponent<RectTransform>(); val13.SetSizeWithCurrentAnchors((Axis)0, 100f); val13.SetSizeWithCurrentAnchors((Axis)1, 50f); ((Transform)val13).position = new Vector3(0f, 0f); LayoutElement val14 = ChoicesContainer.AddComponent<LayoutElement>(); val14.minHeight = 50f; ChoicesContainer.SetActive(false); GameObject val15 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f); val15.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f)); ((Object)val15).name = "selecter"; ((Component)val15.transform.Find("Label")).gameObject.SetActive(false); val15.GetComponent<Toggle>().isOn = false; GameObject val16 = GUIManager.Instance.CreateText("Name", ChoicesContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 0f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false); ((Object)val16).name = "ChoiceName"; } } } } public static class DeathProgressionSkill { [HarmonyPatch(typeof(Player), "RaiseSkill")] public class Deathskill_EXP_Patch { public static void Postfix(Player __instance) { //IL_0384: Unknown result type (might be due to invalid IL or missing references) timeSinceGameStart += Time.deltaTime; if (lastSkillIncreaseTickTime == 0f) { lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value; PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); Dictionary<PlayerStatType, float> stats = playerProfile.m_playerStats[0].m_stats; _bossKills = stats[(PlayerStatType)85]; _enemykills = stats[(PlayerStatType)6]; _piecesBuilt = stats[(PlayerStatType)2]; _treesChopped = stats[(PlayerStatType)27]; _mineAmount = stats[(PlayerStatType)38]; _craftAndUpgrades = stats[(PlayerStatType)1]; } if (timeSinceGameStart > lastSkillIncreaseTickTime) { lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value; PlayerProfile playerProfile2 = Game.instance.GetPlayerProfile(); Dictionary<PlayerStatType, float> stats2 = playerProfile2.m_playerStats[0].m_stats; float num = stats2[(PlayerStatType)85]; float num2 = stats2[(PlayerStatType)6]; float num3 = stats2[(PlayerStatType)2]; float num4 = stats2[(PlayerStatType)27]; float num5 = stats2[(PlayerStatType)38]; float num6 = stats2[(PlayerStatType)1]; float num7 = 0f; float num8 = 0f; float num9 = 0f; float num10 = 0f; float num11 = 0f; float num12 = 0f; if (num > _bossKills || num2 > _enemykills) { num12 = (num - _bossKills) * ValConfig.SkillGainOnBossKills.Value; num11 = (num2 - _enemykills) * ValConfig.SkillGainOnKills.Value; Logger.LogDebug($"DeathProgression kill skill bosskill: {num12} kill: {num11}"); _bossKills = num; _enemykills = num2; } if (num3 > _piecesBuilt) { num10 = (num3 - _piecesBuilt) * ValConfig.SkillGainOnBuilding.Value; Logger.LogDebug($"DeathProgression building skill: {num10}"); _piecesBuilt = num3; } if (num4 > _treesChopped || num5 > _mineAmount) { num9 = (num4 - _treesChopped) * ValConfig.SkillGainOnResourceGathering.Value; num8 = (num5 - _mineAmount) * ValConfig.SkillGainOnResourceGathering.Value; Logger.LogDebug($"DeathProgression harvesting skill tree_harvest: {num9} mining: {num8}"); _treesChopped = num4; _mineAmount = num5; } if (num6 > _craftAndUpgrades) { num7 = (num6 - _craftAndUpgrades) * ValConfig.SkillGainOnCrafts.Value; Logger.LogDebug($"DeathProgression crafting skill crafting: {num7}"); _craftAndUpgrades = num6; } float num13 = num12 + num11 + num10 + num9 + num8 + num7; float num14 = Mathf.Max(0f, (float)Math.Log(__instance.m_timeSinceDeath) / 5f * 0.5f); float num15 = num14 * num13; if (Deathlink.RustyAlmanacClassesLoaded) { int num16 = Mathf.RoundToInt(num15 * ValConfig.AlmanacClassesXPGainScale.Value); Logger.LogDebug($"Almanac XP Gain {num16}"); ClassesAPI.AddEXP(num16); } if (Deathlink.WackyMMOLoaded) { int num17 = Mathf.RoundToInt(num15 * ValConfig.WackyMMOXPGainScale.Value); Logger.LogDebug($"WackyMMO XP Gain {num17}"); EpicMMOSystem_API.AddExp(num17); } float deathSkillRate = Deathlink.pcfg().DeathSkillRate; Logger.LogDebug($"DeathProgression skill bonus from survival (survive time: {__instance.m_timeSinceDeath}) {num14} x {num13} = {num15}, death skill rate {deathSkillRate}"); ((Character)Player.m_localPlayer).RaiseSkill(DeathSkill, num15 * deathSkillRate); } } } public static SkillType DeathSkill; private static float lastSkillIncreaseTickTime; private static float timeSinceGameStart; private static float _bossKills; private static float _enemykills; private static float _piecesBuilt; private static float _mineAmount; private static float _treesChopped; private static float _craftAndUpgrades; public static void SetupDeathSkill() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0061: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) SkillConfig val = new SkillConfig(); val.Name = LocalizationManager.Instance.TryTranslate("$death_skill"); val.Description = LocalizationManager.Instance.TryTranslate("$death_skill_description"); val.Icon = Deathlink.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/death_skill.png"); val.Identifier = "midnightsfx.deathskill"; val.IncreaseStep = 0.1f; DeathSkill = SkillManager.Instance.AddSkill(val); if (!SkillsChanges.skills_to_avoid_standard_death_penalty.Contains(DeathSkill)) { SkillsChanges.skills_to_avoid_standard_death_penalty.Add(DeathSkill); } } public static float DeathSkillCalculatePercentWithBonus(float bonus = 0f, float min = 0.01f, float max = 1f) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if ((Object)(object)Player.m_localPlayer != (Object)null) { float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(DeathSkill); num += skillFactor; } num += bonus; if (num < min) { num = min; } if (num > max) { num = max; } return num; } } internal static class DeathSavingOptions { [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned_Patch { public static void Postfix(Player __instance) { if (pendingChoice && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ((Character)__instance).Message((MessageType)2, Localization.instance.Localize("$dso_spawn_message"), 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class ShowSaveChoiceUI { public static void Postfix() { if (pendingChoice) { SaveChoiceUI.Instance.Show(new List<ItemData>(deathItems), totalToSave, maxChoices); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class HideSaveChoiceUI { public static void Postfix() { if (SaveChoiceUI.IsInitialized) { SaveChoiceUI.Instance.Hide(); } } } public class SaveChoiceUI : MonoBehaviour { private static SaveChoiceUI _instance; private const int GridWidth = 8; private static GameObject panel; private static Text counterText; private static InventoryGrid grid; private static RectTransform gridRoot; private static Inventory tempInv; private static bool selectionWired; private static readonly HashSet<ItemData> selected = new HashSet<ItemData>(); private static int keepBudget = 0; private static int pickLimit = 0; public static SaveChoiceUI Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("DeathlinkSaveChoiceUI"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<SaveChoiceUI>(); } return _instance; } } public static bool IsInitialized => (Object)(object)_instance != (Object)null; public void Awake() { _instance = this; } public void Update() { if (!((Object)(object)panel == (Object)null) && panel.activeSelf && !((Object)(object)grid == (Object)null) && tempInv != null) { grid.UpdateInventory(tempInv, (Player)null, (ItemData)null); } } public void Show(List<ItemData> items, int totalKept, int choiceCount) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (EnsurePanel() && EnsureGrid()) { keepBudget = totalKept; pickLimit = choiceCount; selected.Clear(); BuildInventory(items); grid.UpdateInventory(tempInv, (Player)null, (ItemData)null); grid.ResetView(); string text = $"SaveChoiceUI grid: {tempInv.GetWidth()}x{tempInv.GetHeight()}, "; string text2 = $"slot elements={(((Object)(object)gridRoot != (Object)null) ? ((Transform)gridRoot).childCount : (-1))}, "; Rect rect = ((RectTransform)((Component)grid).transform).rect; Logger.LogDebug(text + text2 + $"gridRect={((Rect)(ref rect)).size}"); ClearHighlights(); UpdateCounter(); panel.SetActive(true); } } public void Hide() { if ((Object)(object)panel != (Object)null) { panel.SetActive(false); } } private void Confirm() { List<ItemData> picked = selected.ToList(); Hide(); selected.Clear(); ApplySelection(picked); } private bool EnsurePanel() { //IL_0047: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown if ((Object)(object)panel != (Object)null) { return true; } if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { Logger.LogWarning("GUIManager not setup, skipping death saving panel creation."); return false; } panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 700f, 640f, true); panel.SetActive(false); GUIManager.Instance.CreateText(Localization.instance.Localize("$dso_header"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 270f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 620f, 40f, false); GameObject val = GUIManager.Instance.CreateText(Localization.instance.Localize("$dso_description"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 225f), GUIManager.Instance.AveriaSerif, 18, Color.white, true, Color.black, 620f, 50f, false); val.GetComponent<Text>().alignment = (TextAnchor)4; counterText = GUIManager.Instance.CreateText("", panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 180f), GUIManager.Instance.AveriaSerifBold, 18, GUIManager.Instance.ValheimYellow, true, Color.black, 620f, 40f, false).GetComponent<Text>(); counterText.alignment = (TextAnchor)4; GameObject val2 = GUIManager.Instance.CreateButton(Localization.instance.Localize("$dso_confirm"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -270f), 250f, 60f); ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener(new UnityAction(Confirm)); return true; } private bool EnsureGrid() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown if ((Object)(object)grid != (Object)null) { return true; } if ((Object)(object)InventoryGui.instance == (Object)null || (Object)(object)InventoryGui.instance.ContainerGrid == (Object)null) { Logger.LogWarning("InventoryGui not ready, cannot build death saving grid."); return false; } GameObject val = new GameObject("DL_GridHolder", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(panel.transform, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(600f, 380f); val2.anchoredPosition = new Vector2(0f, -40f); GameObject gameObject = ((Component)InventoryGui.instance.ContainerGrid).gameObject; GameObject val3 = Object.Instantiate<GameObject>(gameObject, (Transform)(object)val2); ((Object)val3).name = "DL_SaveGrid"; val3.SetActive(true); RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).localScale = Vector3.one; ((Transform)val4).localRotation = Quaternion.identity; val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; grid = val3.GetComponent<InventoryGrid>(); gridRoot = grid.m_gridRoot; if ((Object)(object)gridRoot != (Object)null) { ((Component)gridRoot).gameObject.SetActive(true); } if ((Object)(object)gridRoot != (Object)null) { foreach (Transform item in (Transform)gridRoot) { Transform val5 = item; Object.Destroy((Object)(object)((Component)val5).gameObject); } } grid.m_width = 0; grid.m_height = 0; if (!selectionWired) { InventoryGrid obj = grid; obj.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Combine(obj.m_onSelected, (Action<InventoryGrid, ItemData, Vector2i, Modifier>)delegate(InventoryGrid g, ItemData item, Vector2i pos, Modifier mod) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) OnItemClicked(item, pos); }); InventoryGrid obj2 = grid; obj2.m_onRightClick = (Action<InventoryGrid, ItemData, Vector2i>)Delegate.Combine(obj2.m_onRightClick, (Action<InventoryGrid, ItemData, Vector2i>)delegate { }); selectionWired = true; } return true; } private void BuildInventory(List<ItemData> items) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_005e: 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) int num