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.8.6
plugins/Deathlink.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.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; 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.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValRougelike")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValRougelike")] [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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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); } } } public static class Extensions { private static readonly List<ItemType> EquipmentTypes = new List<ItemType> { (ItemType)7, (ItemType)12, (ItemType)6, (ItemType)11, (ItemType)4, (ItemType)5, (ItemType)19, (ItemType)17, (ItemType)18, (ItemType)3, (ItemType)14, (ItemType)22, (ItemType)20, (ItemType)24 }; public static List<ItemData> GetEquipment(this List<ItemData> list) { return list.Where((ItemData x) => EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList(); } public static List<ItemData> GetNotEquipment(this List<ItemData> list) { return list.Where((ItemData x) => !EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList(); } public static bool IsEquipment(this ItemData item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (EquipmentTypes.Contains(item.m_shared.m_itemType)) { return true; } return false; } } [BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.8.6")] [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.8.6"; 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 (BepInExUtils.GetPlugins(false).Keys.Contains("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 (BepInExUtils.GetPlugins(false).Keys.Contains("RustyMods.AlmanacClasses")) { RustyAlmanacClassesLoaded = true; } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); DeathConfigurationData.Init(); 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 text3 = Regex.Replace(ReadEmbeddedResourceFile(text2), "\\/\\/.*", ""); 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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.SkillModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetSkillModiferDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.ResourceModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetResourceModiferDescription()); stringBuilder.AppendLine(); } if (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()))); } } private static string specialColor = "#ffa64d"; } 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; } if ((Object)(object)((Component)__instance).gameObject.GetComponent<DeathChoices.DeathChoiceUI>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DeathChoices.DeathChoiceUI>(); } DeathChoices.DeathChoiceUI.Instance.Show(); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class HideDeathChoiceUI { public static void Postfix(InventoryGui __instance) { 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 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"; public static DeathChoiceUI Instance => _instance ?? (_instance = new DeathChoiceUI()); public void Awake() { CreateStaticUIObjects(); SetChoiceList(); } public void Show() { if ((Object)(object)DeathChoicePanel == (Object)null) { CreateStaticUIObjects(); } DeathChoicePanel.SetActive(true); } public void Hide() { if ((Object)(object)DeathChoicePanel != (Object)null) { DeathChoicePanel.SetActive(false); } GUIManager.BlockInput(false); } 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.Remove(playerID); } DeathConfigurationData.playerSettings.Add(playerID, new DataObjects.DeathConfiguration { DeathChoiceLevel = selectedDeathChoice }); Player.m_localPlayer.AddUniqueKeyValue(DataObjects.DeathChoiceKey, selectedDeathChoice); DeathConfigurationData.CheckAndSetPlayerDeathConfig(); DeathConfigurationData.WritePlayerChoices(); Hide(); } private void SetChoiceList() { //IL_00d9: 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) difficultyToggles.Clear(); int num = -75; foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> entry in DeathConfigurationData.DeathLevels) { GameObject obj = Object.Instantiate<GameObject>(ChoicesContainer, ChoicesContent.transform); Transform val = obj.transform.Find("selecter"); ((Component)val.Find("Label")).GetComponent<Text>().text = entry.Key; ((Component)obj.transform.Find("ChoiceName")).GetComponent<Text>().text = entry.Value.DisplayName; Toggle component = ((Component)val).GetComponent<Toggle>(); component.group = choiceGroup; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate { ((Component)DeathPenaltyDescription).GetComponent<Text>().text = entry.Value.GetDeathStyleDescription(); ((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; }); obj.SetActive(true); obj.transform.localPosition = new Vector3 { x = 5f, y = num }; difficultyToggles.Add(component); num -= 50; } } private void CreateStaticUIObjects() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_0657: 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_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_071d: Expected O, but got Unknown //IL_0747: Unknown result type (might be due to invalid IL or missing references) //IL_074c: Unknown result type (might be due to invalid IL or missing references) //IL_0771: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Unknown result type (might be due to invalid IL or missing references) //IL_07f4: Expected O, but got Unknown //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_087c: Unknown result type (might be due to invalid IL or missing references) //IL_0881: Unknown result type (might be due to invalid IL or missing references) //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e9: Unknown result type (might be due to invalid IL or missing references) //IL_08f8: Unknown result type (might be due to invalid IL or missing references) //IL_090e: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) 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, 800f, true); DeathChoicePanel.SetActive(false); ((Object)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, 360f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false)).name = "DLHeader"; Text component = 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, 315f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 560f, 60f, false).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, 360f), 60f, 60f); Button component2 = manualCloseButton.GetComponent<Button>(); ((Selectable)component2).interactable = true; ((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide)); manualCloseButton.SetActive(true); ((Object)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, 220f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "DeathPenaltyTitle"; GameObject obj = 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(150f, 110f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 500f, 200f, false); ((Object)obj).name = "DeathPenaltyDesc"; DeathPenaltyDescription = obj.GetComponent<Text>(); DeathPenaltyDescription.resizeTextForBestFit = true; DeathPenaltyDescription.resizeTextMaxSize = 18; ((Object)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)).name = "xpModifiersTitle"; GameObject obj2 = 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)obj2).name = "xpModifiersDesc"; XPModifiersDescription = obj2.GetComponent<Text>(); XPModifiersDescription.resizeTextForBestFit = true; XPModifiersDescription.resizeTextMaxSize = 18; ((Object)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)).name = "lootModifiersTitle"; GameObject obj3 = 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)obj3).name = "lootModifersDesc"; LootModifersDescription = obj3.GetComponent<Text>(); LootModifersDescription.resizeTextForBestFit = true; LootModifersDescription.resizeTextMaxSize = 18; ((Object)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)).name = "harvestModifiersTitle"; GameObject obj4 = 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)obj4).name = "harvestModifersDesc"; HarvestModifiersDescription = obj4.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); ((UnityEvent)selectChoiceButton.GetComponent<Button>().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 obj5 = ChoicesContainer.AddComponent<RectTransform>(); obj5.SetSizeWithCurrentAnchors((Axis)0, 100f); obj5.SetSizeWithCurrentAnchors((Axis)1, 50f); ((Transform)obj5).position = new Vector3(0f, 0f); ChoicesContainer.AddComponent<LayoutElement>().minHeight = 50f; ChoicesContainer.SetActive(false); GameObject obj6 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f); obj6.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f)); ((Object)obj6).name = "selecter"; ((Component)obj6.transform.Find("Label")).gameObject.SetActive(false); obj6.GetComponent<Toggle>().isOn = false; ((Object)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)).name = "ChoiceName"; } } } public static class DeathProgressionSkill { [HarmonyPatch(typeof(Player), "RaiseSkill")] public class Deathskill_EXP_Patch { public static void Postfix(Player __instance) { //IL_03b2: 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(); _bossKills = playerProfile.m_playerStats.m_stats[(PlayerStatType)85]; _enemykills = playerProfile.m_playerStats.m_stats[(PlayerStatType)6]; _piecesBuilt = playerProfile.m_playerStats.m_stats[(PlayerStatType)2]; _treesChopped = playerProfile.m_playerStats.m_stats[(PlayerStatType)27]; _mineAmount = playerProfile.m_playerStats.m_stats[(PlayerStatType)38]; _craftAndUpgrades = playerProfile.m_playerStats.m_stats[(PlayerStatType)1]; } if (timeSinceGameStart > lastSkillIncreaseTickTime) { lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value; PlayerProfile playerProfile2 = Game.instance.GetPlayerProfile(); float num = playerProfile2.m_playerStats.m_stats[(PlayerStatType)85]; float num2 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)6]; float num3 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)2]; float num4 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)27]; float num5 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)38]; float num6 = playerProfile2.m_playerStats.m_stats[(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 + num10 + num9 + num8 + num7; float num14 = (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); } Logger.LogDebug($"DeathProgression skill bonus from survival (survive time: {__instance.m_timeSinceDeath}) {num14} x {num13} = {num15}"); ((Character)Player.m_localPlayer).RaiseSkill(DeathSkill, num15); } } } 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; } } public static class HarvestModifiers { [HarmonyPatch(typeof(TreeLog), "Destroy")] public static class IncreaseDropsFromTree { private static void Postfix(TreeLog __instance, HitData hitData) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hitData != null && (Object)(object)Player.m_localPlayer != (Object)null && hitData.m_attacker == ((Character)Player.m_localPlayer).GetZDOID()) { IncreaseDrops(__instance.m_dropWhenDestroyed, ((Component)__instance).transform.position); } } } [HarmonyPatch(typeof(Pickable), "Drop")] public static class IncreaseDropsPickable { private static void Prefix(Pickable __instance, GameObject prefab, int offset) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers == null || Deathlink.pcfg().ResourceModifiers.Count <= 0 || !((Object)(object)Player.m_localPlayer != (Object)null)) { return; } float num = Deathlink.pcfg().GetResouceEarlyCache(prefab.gameObject) - 1f; int num2 = 0; while (num > 0f) { float value = Random.value; Logger.LogDebug($"Checking to increase drops {value} <= {num}"); if (value <= num) { num2++; } num -= 1f; } if (num2 > 0) { Vector2 val = Random.insideUnitCircle * 0.2f; Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset + new Vector3(val.x, 0.5f * (float)offset, val.y); Quaternion val3 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); for (int i = 0; i < num2; i++) { Object.Instantiate<GameObject>(prefab, val2, val3); } } } } [HarmonyPatch(typeof(MineRock5), "RPC_SetAreaHealth")] public static class Minerock5DestroyPatch { private static void Postfix(MineRock5 __instance, long sender, int index, float health) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && (Object)(object)Player.m_localPlayer != (Object)null && health <= 0f) { IncreaseDrops(__instance.m_dropItems, ((Component)__instance).gameObject.transform.position); } } } [HarmonyPatch(typeof(Destructible), "Destroy")] public static class IncreaseDropsFromDestructible { private static void Prefix(Destructible __instance, HitData hit) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID()) { IncreaseDestructibleDrops(__instance); } } public static void IncreaseDestructibleDrops(Destructible destructible) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)destructible.m_spawnWhenDestroyed != (Object)null)) { Vector3 position = ((Component)destructible).transform.position; DropOnDestroyed component = ((Component)destructible).GetComponent<DropOnDestroyed>(); if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null) { IncreaseDrops(component.m_dropWhenDestroyed, position); } } } } public static void IncreaseDrops(DropTable drops, Vector3 position) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollHarvestLoot(); if (list2.Count > 0) { list.AddRange(list2); } int num = Random.Range(drops.m_dropMin, drops.m_dropMax); int num2 = drops.m_drops.Count; if (num == 0) { num = 1; } if (num2 == 0) { num2 = 1; } int num3 = Mathf.RoundToInt((float)(num / num2)); foreach (DropData drop in drops.m_drops) { float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(drop.m_item); if (resouceEarlyCache != 1f) { int num4 = Mathf.RoundToInt((float)num3 * resouceEarlyCache); if (num4 > 0) { list.Add(new KeyValuePair<GameObject, int>(drop.m_item, num4)); } } } if (list.Count <= 0) { return; } Logger.LogDebug("Deathlink drop increase."); foreach (KeyValuePair<GameObject, int> item in list) { Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize; int num5 = item.Value; if (num5 > maxStackSize) { int num6 = num5 / maxStackSize; for (int i = 0; i < num6; i++) { Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize; Logger.LogDebug($"Dropping {maxStackSize} of {((Object)item.Key).name} to the world."); } num5 -= maxStackSize * num6; } Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num5; Logger.LogDebug($"Dropping {num5} of {((Object)item.Key).name} to the world."); } } } public static class LootModifiers { [HarmonyPatch(typeof(CharacterDrop))] public static class CalculateLootByModifiers { [HarmonyPostfix] [HarmonyPatch("GenerateDropList")] private static void Postfix(List<KeyValuePair<GameObject, int>> __result, CharacterDrop __instance) { //IL_00e9: 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) if (!__instance.m_character.m_localPlayerHasHit || Deathlink.pcfg().DeathLootModifiers == null || Deathlink.pcfg().DeathLootModifiers.Count == 0) { return; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, int> item in __result) { float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(((Object)item.Key).name); if (resouceEarlyCache == 1f) { list.Add(item); continue; } int num = Mathf.RoundToInt((float)item.Value * resouceEarlyCache); if (num >= 1) { list.Add(new KeyValuePair<GameObject, int>(item.Key, num)); } } List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollKillLoot(); if (list2.Count > 0) { foreach (KeyValuePair<GameObject, int> item2 in list2) { for (int i = 0; i < item2.Value; i++) { Object.Instantiate<GameObject>(item2.Key, ((Component)__instance).transform.position, Quaternion.identity); } } } __result = list; } } } public static class SkillsChanges { [HarmonyPatch(typeof(Skills), "OnDeath")] private static class OnDeath_Patch { private static bool Prefix(Skills __instance) { if (((Character)__instance.m_player).m_seman.HaveStatusEffect(SEMan.s_statusEffectSoftDeath)) { return false; } if (Deathlink.pcfg().DeathStyle.skillLossOnDeath) { float num = Mathf.Lerp(Deathlink.pcfg().DeathStyle.maxSkillLossPercentage, Deathlink.pcfg().DeathStyle.minSkillLossPercentage, DeathProgressionSkill.DeathSkillCalculatePercentWithBonus()); Logger.LogDebug($"{num}"); LowerConfigurableSkills(__instance, num); } return false; } private static void LowerConfigurableSkills(Skills skills, float factor) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<SkillType, Skill> skillDatum in skills.m_skillData) { if (skills_to_avoid_standard_death_penalty.Contains(skillDatum.Key)) { Logger.LogDebug($"Skipping lowering skill {skillDatum.Key} current level: {skillDatum.Value.m_level}"); continue; } float num = skillDatum.Value.m_level * factor; Skill value = skillDatum.Value; value.m_level -= num; skillDatum.Value.m_accumulator = 0f; } if (Deathlink.RustyAlmanacClassesLoaded && ValConfig.EnableAlmanacClassesXPLossOnDeath.Value) { int level = ClassesAPI.GetLevel(); int num2 = Mathf.RoundToInt((float)level * factor * 500f * ValConfig.AlmanacClassesXPLossScale.Value) * -1; Logger.LogDebug($"Almanac (lvl {level}) XP Loss: {num2}"); ClassesAPI.AddEXP(num2); } if (Deathlink.WackyMMOLoaded && ValConfig.EnableWackyMMOXPLossOnDeath.Value) { int level2 = EpicMMOSystem_API.GetLevel(); int num3 = Mathf.RoundToInt((float)level2 * factor * 500f * ValConfig.WackyMMOXPLossScale.Value) * -1; Logger.LogDebug($"WackyMMO (lvl {level2}) XP Loss: {num3}"); EpicMMOSystem_API.AddExp(num3); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null); } } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] private static class SkillRaisePatch { private static void Prefix(Skills __instance, SkillType skillType, float factor) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) float skillBonusLazyCache = Deathlink.pcfg().GetSkillBonusLazyCache(skillType); Logger.LogDebug($"{skillType} skillGain Modified {skillBonusLazyCache}"); if (skillBonusLazyCache != 0f) { factor *= skillBonusLazyCache; } } } public static List<SkillType> skills_to_avoid_standard_death_penalty = new List<SkillType>(); } public static class OnDeathChanges { [HarmonyPatch(typeof(Player))] public static class OnDeath_Tombstone_Patch { [HarmonyTranspiler] [HarmonyPatch("OnDeath")] private static IEnumerable<CodeInstruction> ConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Player), "CreateTombStone", (Type[])null, (Type[])null), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<Player>>((Action<Player>)ModifyDeath) }) .CreateLabelOffset(out var label, 4) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Br, (object)label) }) .ThrowIfNotMatch("Unable to patch Deathlink player death changes.", Array.Empty<CodeMatch>()); return val.Instructions(); } private static void ModifyDeath(Player __instance) { TombstoneOnDeath(__instance); FoodLossOnDeath(__instance); } public static void FoodLossOnDeath(Player instance) { if (!Deathlink.pcfg().DeathStyle.foodLossOnDeath) { return; } if (Deathlink.pcfg().DeathStyle.foodLossUsesDeathlink && instance.m_foods.Count > 0) { float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus(); if (num >= 0.9f) { return; } if (num >= 0.6f && num < 0.9f) { instance.m_foods.Remove(instance.m_foods[0]); } else if (num > 0.3f && num < 0.6f) { instance.m_foods.Remove(instance.m_foods[0]); if (instance.m_foods.Count > 0) { instance.m_foods.Remove(instance.m_foods[0]); } } else { instance.m_foods.Clear(); } } else { instance.m_foods.Clear(); } } public static void TombstoneOnDeath(Player instance) { //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0376: 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_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems(); List<ItemData> list = new List<ItemData>(); List<ItemData> list2 = new List<ItemData>(); Inventory inventory = ((Humanoid)instance).m_inventory; Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>(); string[] source = ValConfig.ItemsNotSkillChecked.Value.Split(new char[1] { ',' }); foreach (ItemData item in allItems) { if ((Object)(object)item.m_dropPrefab != (Object)null && source.Contains(((Object)item.m_dropPrefab).name)) { list2.Add(item); } else { list.Add(item); } } switch (Deathlink.pcfg().DeathStyle.itemLossStyle) { case DataObjects.ItemLossStyle.None: Logger.LogDebug("No items destroyed on death."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemSaved, list); break; case DataObjects.ItemLossStyle.DestroyNonWeaponArmor: Logger.LogDebug("Destroying non Equipment items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list.GetNotEquipment()); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, list.GetEquipment()); foreach (ItemData item2 in list.GetNotEquipment()) { ((Humanoid)instance).m_inventory.RemoveItem(item2); } if (!Deathlink.AzuEPILoaded) { break; } Logger.LogDebug("AzuEPI| Removing non-equipment items from quickslots."); foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems()) { if (!quickSlotsItem.IsEquipment()) { ((Humanoid)instance).m_inventory.RemoveItem(quickSlotsItem); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, quickSlotsItem); } else { dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, quickSlotsItem); } } break; case DataObjects.ItemLossStyle.DestroyAll: Logger.LogDebug("Destroying all non skill checked items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list); foreach (ItemData item3 in list) { ((Humanoid)instance).m_inventory.RemoveItem(item3); } if (Deathlink.AzuEPILoaded) { Logger.LogDebug("AzuEPI| Destroying quickslot items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, API.GetQuickSlotsItems()); API.GetQuickSlotsItems().ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } break; case DataObjects.ItemLossStyle.DeathlinkBased: Logger.LogDebug("Destroying random items based on deathlink skill"); dictionary = DetermineItemResultsByDeathlink(instance, list); dictionary[DataObjects.ItemResults.EquipmentLost].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); dictionary[DataObjects.ItemResults.ItemLost].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); break; } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Destroy) { Logger.LogDebug("Non skill checked being destroyed."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list2); } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Save) { Logger.LogDebug("Non skill checked items being left on player."); } if ((!dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) || dictionary[DataObjects.ItemResults.EquipmentSaved].Count <= 0) && (!dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) || dictionary[DataObjects.ItemResults.ItemSaved].Count <= 0) && (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction != DataObjects.NonSkillCheckedItemAction.Tombstone || list2.Count() <= 0)) { return; } Logger.LogDebug("Tombstone needed"); GameObject obj = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation); Inventory inventory2 = obj.GetComponent<Container>().GetInventory(); if (Deathlink.pcfg().DeathStyle.itemSavedStyle == DataObjects.ItemSavedStyle.Tombstone) { Logger.LogDebug("Adding saved items to tombstone."); if (dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) && dictionary[DataObjects.ItemResults.EquipmentSaved].Count > 0) { AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.EquipmentSaved]); dictionary[DataObjects.ItemResults.EquipmentSaved].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } if (dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) && dictionary[DataObjects.ItemResults.ItemSaved].Count > 0) { AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.ItemSaved]); dictionary[DataObjects.ItemResults.ItemSaved].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Tombstone) { Logger.LogDebug("Adding saved non-skill checked items to tombstone."); AddItemsToTombstone(inventory2, list2); list2.ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } TombStone component = obj.GetComponent<TombStone>(); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); string name = playerProfile.GetName(); long playerID = playerProfile.GetPlayerID(); component.Setup(name, playerID); inventory.Changed(); if (ValConfig.ShowDeathMapMarker.Value) { Minimap.instance.AddPin(((Component)instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, default(PlatformUserID)); } } public static void AddItemsToTombstone(Inventory tombstone, List<ItemData> transferItems) { int num = Mathf.RoundToInt(Mathf.Sqrt((float)transferItems.Count())) + 1; tombstone.m_width += num; tombstone.m_height += num; foreach (ItemData transferItem in transferItems) { tombstone.m_inventory.Add(transferItem); } tombstone.Changed(); } internal static Dictionary<DataObjects.ItemResults, List<ItemData>> DetermineItemResultsByDeathlink(Player player, List<ItemData> playerItemsWithoutNonSkillCheckedItems) { float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus(); int num2 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxItemsKept - Deathlink.pcfg().DeathStyle.minItemsKept) * num + (float)Deathlink.pcfg().DeathStyle.minItemsKept); int num3 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxEquipmentKept - Deathlink.pcfg().DeathStyle.minEquipmentKept) * num + (float)Deathlink.pcfg().DeathStyle.minEquipmentKept); int remainingsaves = num2 + num3; Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>> { { DataObjects.ItemResults.EquipmentSaved, new List<ItemData>() }, { DataObjects.ItemResults.EquipmentLost, new List<ItemData>() }, { DataObjects.ItemResults.ItemSaved, new List<ItemData>() }, { DataObjects.ItemResults.ItemLost, new List<ItemData>() } }; int equipment_saved_count = 0; foreach (ItemData item in Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetEquipment())) { if (remainingsaves > 0) { if (RemoveEquipmentByStyle(equipment_saved_count, num3, item, remainingsaves, out remainingsaves, out equipment_saved_count)) { Logger.LogDebug("Save: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentSaved].Add(item); } else { Logger.LogDebug("Remove by style: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentLost].Add(item); } } else { Logger.LogDebug("Save limit reached, removing: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentLost].Add(item); } } if (Deathlink.AzuEPILoaded) { foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems()) { if (quickSlotsItem.IsEquipment() && remainingsaves > 0) { remainingsaves--; num2--; dictionary[DataObjects.ItemResults.EquipmentSaved].Add(quickSlotsItem); } else if (remainingsaves > 0) { remainingsaves--; num2--; dictionary[DataObjects.ItemResults.ItemSaved].Add(quickSlotsItem); } else { dictionary[DataObjects.ItemResults.ItemLost].Add(quickSlotsItem); } } } List<ItemData> list = Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetNotEquipment()); if (remainingsaves > 0) { foreach (ItemData item2 in list) { if (remainingsaves > 0 && num2 > 0) { Logger.LogDebug("NonEq| Saving: " + item2.m_shared.m_name); dictionary[DataObjects.ItemResults.ItemSaved].Add(item2); remainingsaves--; num2--; } else { Logger.LogDebug("NonEq| Removing: " + item2.m_shared.m_name); dictionary[DataObjects.ItemResults.ItemLost].Add(item2); } } } else { Logger.LogDebug($"NonEq| Removing: {list.Count} due to no saves remaining."); foreach (ItemData item3 in list) { dictionary[DataObjects.ItemResults.ItemLost].Add(item3); } } return dictionary; } internal static bool RemoveEquipmentByStyle(int equipment_saved, int max_equipment_savable, ItemData equipment, int numberOfItemsSavable, out int remainingsaves, out int equipment_saved_count) { equipment_saved_count = 0; remainingsaves = 0; if (numberOfItemsSavable <= 0) { return false; } if (equipment_saved >= max_equipment_savable) { Logger.LogDebug($"Max equipment retained ({max_equipment_savable}) reached, removing {((Object)equipment.m_dropPrefab).name}"); return false; } Logger.LogDebug($"Saving equipment remaining savable?({numberOfItemsSavable}) {((Object)equipment.m_dropPrefab).name}"); equipment_saved_count = equipment_saved + 1; remainingsaves = numberOfItemsSavable - 1; return true; } } } } namespace Deathlink.Common { internal static class TerminalCommands { internal class ResetPlayerDeathChoice : ConsoleCommand { public override string Name => "DL-RESET-CHOICE"; public override bool IsNetwork => true; public override string Help => "Format: [steamID|playerName] resets the deathlink choice for the target player. Accepts a platform Steam ID or a case-insensitive player name."; public override void Run(string[] args) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown if (!SynchronizationManager.Instance.PlayerIsAdmin) { Logger.LogWarning("You are not an admin, and not allowed to run this command."); return; } if (args.Length < 1) { Logger.LogInfo("Player Steam ID or name required"); return; } string text = args[0]; foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { string text2 = player.m_userInfo.m_id.m_userID.ToString(); string displayName = player.m_userInfo.m_displayName; bool flag = text2 == text; bool flag2 = string.Equals(displayName, text, StringComparison.OrdinalIgnoreCase); bool flag3 = string.Equals(player.m_name, text, StringComparison.OrdinalIgnoreCase); Logger.LogDebug("Checking Player " + displayName + " (platformID: " + text2 + ", playerName: " + player.m_name + ") against '" + text + "'"); if (flag || flag2 || flag3) { Logger.LogInfo("Matched player " + displayName + " (platformID: " + text2 + ") for reset command."); ZPackage val = new ZPackage(); val.Write(text2); Logger.LogDebug("Requesting server reset of player saved Deathlink choice"); ValConfig.resetChoiceRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val); } } } } internal static void AddCommands() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ResetPlayerDeathChoice()); } } public class DataObjects { public enum ItemLossStyle { None, DestroyNonWeaponArmor, DeathlinkBased, DestroyAll } public enum ItemResults { EquipmentSaved, EquipmentLost, ItemSaved, ItemLost } public enum ItemSavedStyle { OnCharacter, Tombstone } public enum ResourceGainTypes { Kills, Harvesting } public enum NonSkillCheckedItemAction { Destroy, Tombstone, Save } public class DeathProgressionDetails { public bool foodLossOnDeath = true; public bool foodLossUsesDeathlink = true; public int minItemsKept; public int maxItemsKept; public int minEquipmentKept; public int maxEquipmentKept; public bool skillLossOnDeath = true; public float maxSkillLossPercentage; public float minSkillLossPercentage; public ItemLossStyle itemLossStyle; public ItemSavedStyle itemSavedStyle; public NonSkillCheckedItemAction nonSkillCheckedItemAction = NonSkillCheckedItemAction.Tombstone; } public class DeathResourceModifier { public bool skillInfluence { get; set; } = true; public List<string> prefabs { get; set; } public float bonusModifer { get; set; } public List<ResourceGainTypes> bonusActions { get; set; } } public class DeathSkillModifier { public bool skillInfluence { get; set; } = true; public SkillType skill { get; set; } public float bonusModifer { get; set; } } public class DeathLootModifier { private bool skillInfluence { get; set; } = true; public string prefab { get; set; } public float chance { get; set; } public int amount { get; set; } = 1; public List<ResourceGainTypes> bonusActions { get; set; } } public class DeathChoiceLevel { private Dictionary<SkillType, float> CalculatedSkillMods = new Dictionary<SkillType, float>(); private Dictionary<string, float> CalculatedResourceMods = new Dictionary<string, float>(); private bool CalculatedResourceModsCached; private Dictionary<GameObject, Tuple<float, int>> KillLootModifiers = new Dictionary<GameObject, Tuple<float, int>>(); private bool CalculatedKillLootModifiersCached; private Dictionary<GameObject, Tuple<float, int>> ResourceLootModifiers = new Dictionary<GameObject, Tuple<float, int>>(); private bool CalculatedHarvestLootModifiersCached; public string DisplayName { get; set; } public DeathProgressionDetails DeathStyle { get; set; } public float DeathSkillRate { get; set; } = 1f; public Dictionary<string, DeathResourceModifier> ResourceModifiers { get; set; } public Dictionary<string, DeathSkillModifier> SkillModifiers { get; set; } public Dictionary<string, DeathLootModifier> DeathLootModifiers { get; set; } public List<KeyValuePair<GameObject, int>> RollKillLoot() { if (!CalculatedKillLootModifiersCached) { if (DeathLootModifiers != null && DeathLootModifiers.Count > 0) { foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers) { if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Kills)) { GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building kill loot table, it will be skipped."); } else { KillLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount)); } } } } CalculatedKillLootModifiersCached = true; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, Tuple<float, int>> killLootModifier in KillLootModifiers) { float value = Random.value; Logger.LogDebug($"Rolling chance loot for: {((Object)killLootModifier.Key.gameObject).name} {value} < {killLootModifier.Value.Item1}"); if (value < killLootModifier.Value.Item1) { list.Add(new KeyValuePair<GameObject, int>(killLootModifier.Key, killLootModifier.Value.Item2)); } } return list; } public List<KeyValuePair<GameObject, int>> RollHarvestLoot() { if (!CalculatedHarvestLootModifiersCached) { if (DeathLootModifiers != null && DeathLootModifiers.Count > 0) { foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers) { if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Harvesting)) { GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building harvest loot table, it will be skipped."); } else { ResourceLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount)); } } } } CalculatedHarvestLootModifiersCached = true; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, Tuple<float, int>> resourceLootModifier in ResourceLootModifiers) { if (Random.value < resourceLootModifier.Value.Item1) { list.Add(new KeyValuePair<GameObject, int>(resourceLootModifier.Key, resourceLootModifier.Value.Item2)); } } return list; } public float GetResouceEarlyCache(string prefab) { if (!CalculatedResourceModsCached) { Logger.LogDebug("Building cache entry for " + prefab); if (ResourceModifiers != null) { foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers) { if (resourceModifier.Value.prefabs == null) { continue; } foreach (string prefab2 in resourceModifier.Value.prefabs) { Logger.LogDebug($"Building cache entry for {prefab2} - {resourceModifier.Value.bonusModifer}"); CalculatedResourceMods.Add(prefab2, resourceModifier.Value.bonusModifer); } } } CalculatedResourceModsCached = true; } if (CalculatedResourceMods.ContainsKey(prefab)) { return CalculatedResourceMods[prefab]; } return 1f; } public float GetResouceEarlyCache(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return 1f; } return GetResouceEarlyCache(((Object)prefab).name); } public float GetSkillBonusLazyCache(SkillType skilltype) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //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) if (CalculatedSkillMods.TryGetValue(skilltype, out var value)) { return value; } float num = 0f; if (SkillModifiers != null && SkillModifiers.Count > 0) { foreach (KeyValuePair<string, DeathSkillModifier> skillModifier in SkillModifiers) { if ((int)skillModifier.Value.skill == 999 || skillModifier.Value.skill == skilltype) { num += skillModifier.Value.bonusModifer; } } } CalculatedSkillMods.Add(skilltype, num); return num; } public string GetLootModifiersDescription() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers) { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("<color={0}>{1}%</color> $loot_desc_pt1 {2} $loot_desc_pt2 {3}", "#b9f2ff", deathLootModifier.Value.chance * 100f, deathLootModifier.Key, string.Join(",", deathLootModifier.Value.bonusActions)))); } return stringBuilder.ToString(); } public string GetSkillModiferDescription() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, DeathSkillModifier> skillModifier in SkillModifiers) { if (skillModifier.Value.bonusModifer > 1f) { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} +<color={1}>{2}%</color> $xp", skillModifier.Key, "#b9f2ff", Mathf.Round((skillModifier.Value.bonusModifer - 1f) * 100f)))); } else { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} -<color={1}>{2}%</color> $xp", skillModifier.Key, "#ff4040", Mathf.Round((1f - skillModifier.Value.bonusModifer) * 100f)))); } } return stringBuilder.ToString(); } public string GetResourceModiferDescription() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers) { if (resourceModifier.Value.bonusModifer > 1f) { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} $drops <color={1}>{2}%</color> $more {3}", resourceModifier.Key, "#b9f2ff", (resourceModifier.Value.bonusModifer - 1f) * 100f, string.Join(",", resourceModifier.Value.bonusActions)))); } else { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} $drops <color={1}{2}%</color> $less {3}", resourceModifier.Key, "#ff4040", (1f - resourceModifier.Value.bonusModifer) * 100f, string.Join(",", resourceModifier.Value.bonusActions)))); } } return stringBuilder.ToString(); } public string GetDeathStyleDescription() { StringBuilder stringBuilder = new StringBuilder(); switch (DeathStyle.itemLossStyle) { case ItemLossStyle.None: stringBuilder.AppendLine(Localization.instance.Localize("$no_item_loss")); break; case ItemLossStyle.DestroyNonWeaponArmor: stringBuilder.AppendLine(Localization.instance.Localize("$no_equipment_loss")); break; case ItemLossStyle.DestroyAll: stringBuilder.AppendLine(Localization.instance.Localize("$all_item_loss")); break; case ItemLossStyle.DeathlinkBased: stringBuilder.AppendLine(Localization.instance.Localize("$limited_saved_deathlink")); stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$equipment_kept <color={0}>{1}</color> - <color={2}>{3}</color>", "#b9f2ff", DeathStyle.minEquipmentKept, "#b9f2ff", DeathStyle.maxEquipmentKept))); stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$items_kept <color={0}>{1}</color> - <color={2}>{3}</color>", "#b9f2ff", DeathStyle.minItemsKept, "#b9f2ff", DeathStyle.maxItemsKept))); break; } if (DeathStyle.itemLossStyle != ItemLossStyle.DestroyAll) { if (DeathStyle.itemSavedStyle == ItemSavedStyle.OnCharacter) { stringBuilder.AppendLine(Localization.instance.Localize("$saved_to_character")); } else { stringBuilder.AppendLine(Localization.instance.Localize("$saved_to_tombstone")); } if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Tombstone) { stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_tombstone")); } if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Save) { stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_character")); } if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Destroy) { stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_destroy")); } } if (DeathStyle.foodLossOnDeath) { if (DeathStyle.foodLossUsesDeathlink) { stringBuilder.AppendLine(Localization.instance.Localize("$food_loss_deathlink")); } else { stringBuilder.AppendLine(Localization.instance.Localize("$food_loss")); } } if (DeathStyle.maxSkillLossPercentage == DeathStyle.minSkillLossPercentage) { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$skill_loss_desc <color={0}>{1}%</color>", "#ff4040", DeathStyle.maxSkillLossPercentage * 100f))); } else { stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$skill_loss_desc <color={0}>{1}%</color> - <color={2}>{3}%</color> $influenced_by_deathlink", "#ff4040", DeathStyle.maxSkillLossPercentage * 100f, "#ff4040", DeathStyle.minSkillLossPercentage * 100f))); } return stringBuilder.ToString(); } } public class DeathConfiguration { public string DeathChoiceLevel { get; set; } } public class PlayerDeathConfiguration { public Dictionary<long, DeathConfiguration> selectedDeathStyle { get; set; } } public abstract class ZNetProperty<T> { protected readonly ZNetView zNetView; public string Key { get; private set; } public T DefaultValue { get; private set; } protected ZNetProperty(string key, ZNetView zNetView, T defaultValue) { Key = key; DefaultValue = defaultValue; this.zNetView = zNetView; } private void ClaimOwnership() { if (!zNetView.IsOwner()) { zNetView.ClaimOwnership(); } } public void Set(T value) { SetValue(value); } public void ForceSet(T value) { ClaimOwnership(); Set(value); } public abstract T Get(); protected abstract void SetValue(T value); } public class BoolZNetProperty : ZNetProperty<bool> { public BoolZNetProperty(string key, ZNetView zNetView, bool defaultValue) : base(key, zNetView, defaultValue) { } public override bool Get() { return zNetView.GetZDO().GetBool(base.Key, base.DefaultValue); } protected override void SetValue(bool value) { zNetView.GetZDO().Set(base.Key, value); } } public class IntZNetProperty : ZNetProperty<int> { public IntZNetProperty(string key, ZNetView zNetView, int defaultValue) : base(key, zNetView, defaultValue) { } public override int Get() { return zNetView.GetZDO().GetInt(base.Key, base.DefaultValue); } protected override void SetValue(int value) { zNetView.GetZDO().Set(base.Key, value); } } public class StringZNetProperty : ZNetProperty<string> { public StringZNetProperty(string key, ZNetView zNetView, string defaultValue) : base(key, zNetView, defaultValue) { } public override string Get() { return zNetView.GetZDO().GetString(base.Key, base.DefaultValue); } protected override void SetValue(string value) { zNetView.GetZDO().Set(base.Key, value); } } public class Vector3ZNetProperty : ZNetProperty<Vector3> { public Vector3ZNetProperty(string key, ZNetView zNetView, Vector3 defaultValue) : base(key, zNetView, defaultValue) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) public override Vector3 Get() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) return zNetView.GetZDO().GetVec3(base.Key, base.DefaultValue); } protected override void SetValue(Vector3 value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) zNetView.GetZDO().Set(base.Key, value); } } public class DictionaryZNetProperty : ZNetProperty<Dictionary<SkillType, float>> { private BinaryFormatter binFormatter = new BinaryFormatter(); public DictionaryZNetProperty(string key, ZNetView zNetView, Dictionary<SkillType, float> defaultValue) : base(key, zNetView, defaultValue) { } public override Dictionary<SkillType, float> Get() { byte[] byteArray = zNetView.GetZDO().GetByteArray(base.Key, (byte[])null); if (byteArray == null) { return new Dictionary<SkillType, float>(); } MemoryStream serializationStream = new MemoryStream(byteArray); return (Dictionary<SkillType, float>)binFormatter.Deserialize(serializationStream); } protected override void SetValue(Dictionary<SkillType, float> value) { MemoryStream memoryStream = new MemoryStream(); binFormatter.Serialize(memoryStream, value); zNetView.GetZDO().Set(base.Key, memoryStream.ToArray()); } public void UpdateDictionary() { } } public class ZDOIDZNetProperty : ZNetProperty<ZDOID> { public ZDOIDZNetProperty(string key, ZNetView zNetView, ZDOID defaultValue) : base(key, zNetView, defaultValue) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) public override ZDOID Get() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return zNetView.GetZDO().GetZDOID(base.Key); } protected override void SetValue(ZDOID value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) zNetView.GetZDO().Set(base.Key, value); } } public static IDeserializer yamldeserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); public static ISerializer yamlserializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).DisableAliases().ConfigureDefaultValuesHandling((DefaultValuesHandling)2) .Build(); public static readonly string DeathChoiceKey = "DL_DeathChoice"; private const string color_good = "#b9f2ff"; private const string color_bad = "#ff4040"; } internal static class DeathConfigurationData { [HarmonyPatch(typeof(Player))] public static class SetupPlayerDeathlink { [HarmonyPostfix] [HarmonyPatch("OnSpawned")] private static void Postfix(Player __instance) { CheckAndSetPlayerDeathConfig(); } } public static readonly Dictionary<string, DataObjects.DeathChoiceLevel> defaultDeathLevels = new Dictionary<string, DataObjects.DeathChoiceLevel> { { "Vanilla", new DataObjects.DeathChoiceLevel { DisplayName = "Vanilla", DeathStyle = new DataObjects.DeathProgressionDetails { itemLossStyle = DataObjects.ItemLossStyle.None, foodLossOnDeath = true, itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone, minSkillLossPercentage = 0.05f, maxSkillLossPercentage = 0.05f }, DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(), ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>(), SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier>() } }, { "Rougelike1", new DataObjects.DeathChoiceLevel { DisplayName = "ShieldBearer", DeathStyle = new DataObjects.DeathProgressionDetails { itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased, foodLossUsesDeathlink = true, itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone, minEquipmentKept = 3, maxEquipmentKept = 9, minItemsKept = 3, maxItemsKept = 15, minSkillLossPercentage = 0.03f, maxSkillLossPercentage = 0.13f }, DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(), ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier> { { "Wood", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" }, bonusModifer = 1.1f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } } }, SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> { { "All", new DataObjects.DeathSkillModifier { bonusModifer = 1.05f, skill = (SkillType)999 } } } } }, { "Rougelike2", new DataObjects.DeathChoiceLevel { DisplayName = "Raider", DeathStyle = new DataObjects.DeathProgressionDetails { itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased, itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone, minEquipmentKept = 2, maxEquipmentKept = 6, minSkillLossPercentage = 0.02f, maxSkillLossPercentage = 0.14f }, DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(), ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier> { { "Wood", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" }, bonusModifer = 1.2f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } }, { "Ore", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" }, bonusModifer = 1.2f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } } }, SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> { { "All", new DataObjects.DeathSkillModifier { bonusModifer = 1.1f, skill = (SkillType)999 } } } } }, { "Rougelike3", new DataObjects.DeathChoiceLevel { DisplayName = "Berserker", DeathStyle = new DataObjects.DeathProgressionDetails { itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased, itemSavedStyle = DataObjects.ItemSavedStyle.OnCharacter, minEquipmentKept = 0, maxEquipmentKept = 3, minSkillLossPercentage = 0.05f, maxSkillLossPercentage = 0.2f }, DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier> { { "AmberPearl", new DataObjects.DeathLootModifier { chance = 0.05f, prefab = "AmberPearl", bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills } } } }, ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier> { { "Wood", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" }, bonusModifer = 1.5f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } }, { "Ore", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" }, bonusModifer = 1.5f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } } }, SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> { { "All", new DataObjects.DeathSkillModifier { bonusModifer = 1.2f, skill = (SkillType)999 } } } } }, { "Hardcore", new DataObjects.DeathChoiceLevel { DisplayName = "Deathbringer", DeathStyle = new DataObjects.DeathProgressionDetails { itemLossStyle = DataObjects.ItemLossStyle.DestroyAll, minSkillLossPercentage = 0.05f, maxSkillLossPercentage = 0.25f }, DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier> { { "AmberPearl", new DataObjects.DeathLootModifier { chance = 0.05f, prefab = "AmberPearl", bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills } } }, { "SmallHealthPotion", new DataObjects.DeathLootModifier { chance = 0.01f, prefab = "MeadHealthMinor", bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills } } } }, ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier> { { "Wood", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood", "ElderBark" }, bonusModifer = 2f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } }, { "Stone", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "Flint", "Stone", "BlackMarble", "Grausten" }, bonusModifer = 2f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } }, { "Ore", new DataObjects.DeathResourceModifier { prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" }, bonusModifer = 2f, bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting } } } }, SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> { { "All", new DataObjects.DeathSkillModifier { bonusModifer = 1.3f, skill = (SkillType)999 } } } } } }; public static Dictionary<long, DataObjects.DeathConfiguration> playerSettings = new Dictionary<long, DataObjects.DeathConfiguration>(); public static Dictionary<string, DataObjects.DeathChoiceLevel> DeathLevels = defaultDeathLevels; public static DataObjects.DeathChoiceLevel playerDeathConfiguration = new DataObjects.DeathChoiceLevel { DeathStyle = new DataObjects.DeathProgressionDetails { foodLossOnDeath = true, foodLossUsesDeathlink = false, itemLossStyle = DataObjects.ItemLossStyle.None, minItemsKept = 0, maxItemsKept = 0, minEquipmentKept = 0, maxEquipmentKept = 0, skillLossOnDeath = true, maxSkillLossPercentage = 0.05f, minSkillLossPercentage = 0.05f, itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone, nonSkillCheckedItemAction = DataObjects.NonSkillCheckedItemAction.Tombstone } }; internal static void Init() { try { UpdateDeathLevelsConfig(File.ReadAllText(ValConfig.deathChoicesPath)); } catch (Exception arg) { Logger.LogWarning((object)$"There was an error updating the Death choice Level values, defaults will be used. Exception: {arg}"); } try { UpdatePlayerConfigSettings(File.ReadAllText(ValConfig.playerSettingsPath)); } catch (Exception arg2) { Logger.LogWarning((object)$"There was an error updating the player choice configs, defaults will be used. Exception: {arg2}"); } } public static void CheckAndSetPlayerDeathConfig() { Player localPlayer = Player.m_localPlayer; if (ValConfig.UsePrivateKeysForDeathChoice.Value && (Object)(object)localPlayer != (Object)null) { Logger.LogDebug("Checking private keys configurations for Deathl