Decompiled source of Deathlink v0.8.0
plugins/Deathlink.dll
Decompiled 3 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 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.0")] [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.0"; 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(); ((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; } 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 = -50; 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 = 260f, y = num }; difficultyToggles.Add(component); num -= 50; } } private void CreateStaticUIObjects() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05bb: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_063c: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_06cb: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_071a: Expected O, but got Unknown //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_0749: Unknown result type (might be due to invalid IL or missing references) //IL_076e: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_07c9: Unknown result type (might be due to invalid IL or missing references) //IL_07d3: Expected O, but got Unknown //IL_0800: Unknown result type (might be due to invalid IL or missing references) //IL_0843: Unknown result type (might be due to invalid IL or missing references) //IL_0848: Unknown result type (might be due to invalid IL or missing references) //IL_08a1: Unknown result type (might be due to invalid IL or missing references) //IL_08b0: Unknown result type (might be due to invalid IL or missing references) //IL_08bf: Unknown result type (might be due to invalid IL or missing references) //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08db: 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; } 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(false); ((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); Button component3 = selectChoiceButton.GetComponent<Button>(); ((Selectable)component3).interactable = true; ((UnityEvent)component3.onClick).AddListener(new UnityAction(MakePlayerDeathSelection)); Logger.LogDebug("Setting up scroll entry"); ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 200f, 400f); ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2 { x = -260f, y = -30f }); ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject; choiceGroup = ChoicesContent.AddComponent<ToggleGroup>(); Logger.LogDebug("Setting up death choice template entry"); ChoicesContainer = new GameObject("DeathChoice"); ChoicesContainer.transform.SetParent(DeathChoicePanel.transform); ChoicesContainer.transform.position = DeathChoicePanel.transform.position; ChoicesContainer.SetActive(false); GameObject obj5 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f); obj5.transform.localPosition = Vector2.op_Implicit(new Vector2(-220f, 0f)); ((Object)obj5).name = "selecter"; ((Component)obj5.transform.Find("Label")).gameObject.SetActive(false); obj5.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(-20f, 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 { 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" }, 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 Deathlink"); if (localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey)) { string text = default(string); localPlayer.TryGetUniqueKeyValue(DataObjects.DeathChoiceKey, ref text); if (DeathLevels.ContainsKey(text)) { Logger.LogDebug("Player deathlink configurations set " + text); playerDeathConfiguration = DeathLevels[text]; } else { Logger.LogDebug("Player preference setting is not an available config, removing player choice."); localPlayer.PlayerRemoveUniqueKey(DataObjects.DeathChoiceKey); CheckAndSetPlayerDeathConfig(); } } else { Logger.LogDebug("No private key set for deathlink configuration, checking yaml config fallback"); CheckYamlConfig(); } } else { CheckYamlConfig(); } } internal static void CheckYamlConfig() { if ((Object)(object)Player.m_localPlayer == (Object)null) { Logger.LogWarning("Local player not defined, skipping setup."); Logger.LogDebug("Player preference setting is not an available config, using fallback " + DeathLevels.First().Key); playerDeathConfiguration = DeathLevels.First().Value; return; } long playerID = Player.m_localPlayer.GetPlayerID(); Logger.LogDebug($"Setting up Deathlink player configuration with id {playerID}"); Logger.LogDebug(string.Format("Checking stored configurations for {0} {1}", playerID, string.Join(",", playerSettings.Keys))); if (playerSettings.ContainsKey(playerID)) { string deathChoiceLevel = playerSettings[playerID].DeathChoiceLevel; if (DeathLevels.ContainsKey(deathChoiceLevel)) { Logger.LogDebug("Player deathlink configurations set " + deathChoiceLevel); playerDeathConfiguration = DeathLevels[deathChoiceLevel]; } else { Logger.LogDebug("Player preference setting is not an available config, using fallback"); playerDeathConfiguration = DeathLevels.First().Value; } } } public static string PlayerSettingsDefaultConfig() { return DataObjects.yamlserializer.Serialize((object)playerSettings); } public static string DeathLevelsYamlDefaultConfig() { return DataObjects.yamlserializer.Serialize((object)DeathLevels); } public static void WriteDeathChoices() { File.WriteAllText(ValConfig.deathChoicesPath, DataObjects.yamlserializer.Serialize((object)DeathLevels)); } public static void WritePlayerChoices() { File.WriteAllText(ValConfig.playerSettingsPath, DataObjects.yamlserializer.Serialize((object)playerSettings)); } public static void UpdateDeathLevelsConfig(string rawyaml) { DeathLevels = DataObjects.yamldeserializer.Deserialize<Dictionary<string, DataObjects.DeathChoiceLevel>>(rawyaml); } public static void UpdatePlayerConfigSettings(string rawyaml) { foreach (KeyValuePair<long, DataObjects.DeathConfiguration> item in DataObjects.yamldeserializer.Deserialize<Dictionary<long, DataObjects.DeathConfiguration>>(rawyaml)) { if (!playerSettings.ContainsKey(item.Key)) { playerSettings.Add(item.Key, item.Value); } } } } internal static class Utils { public static CodeMatcher CreateLabelOffset(this CodeMatcher matcher, out Label label, int offset = 0) { return matcher.CreateLabelAt(matcher.Pos + offset, ref label); } public static bool PlayerHasUniqueKey(this Player player, string key) { foreach (string uniqueKey in player.GetUniqueKeys()) { if (uniqueKey.StartsWith(key)) { return true; } } return false; } public static bool PlayerRemoveUniqueKey(this Player player, string key) { foreach (string uniqueKey in player.GetUniqueKeys()) { if (uniqueKey.StartsWith(key)) { ((Humanoid)player).RemoveUniqueKey(uniqueKey); return true; } } return false; } public static void SafeInsertOrAppend(this Dictionary<DataObjects.ItemResults, List<ItemData>> dict, DataObjects.ItemResults key, List<ItemData> value) { if (!dict.ContainsKey(key)) { dict.Add(key, value); } else { dict[key].AddRange(value); } } public static void SafeInsertOrAppend(this Dictionary<DataObjects.ItemResults, List<ItemData>> dict, DataObjects.ItemResults key, ItemData value) { if (!dict.ContainsKey(key)) { dict.Add(key, new List<ItemData> { value }); } else { dict[key].Add(value); } } } public class ValConfig { [CompilerGenerated] private sealed class <OnClientReceiveDeathChoiceConfigs>d__31 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientReceiveDeathChoiceConfigs>d__31(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; DeathConfigurationData.UpdateDeathLevelsConfig(package.ReadString()); DeathConfigurationData.WriteDeathChoices(); DeathConfigurationData.CheckAndSetPlayerDeathConfig(); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnClientReceivePlayerSettingsConfigs>d__34 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientReceivePlayerSettingsConfigs>d__34(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; DeathConfigurationData.UpdatePlayerConfigSettings(package.ReadString()); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed