Decompiled source of Deathlink v0.7.5

plugins/Deathlink.dll

Decompiled 2 weeks ago
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 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
		};

		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.7.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*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.7.5";

		public ValConfig cfg;

		internal static AssetBundle EmbeddedResourceBundle;

		internal static bool AzuEPILoaded = false;

		internal static bool RustyAlmanacClassesLoaded = 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("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.Death
{
	public static class Compendium
	{
		[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
		public static class TextsDialog_UpdateTextsList_Patch
		{
			public static void Postfix(TextsDialog __instance)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					AddDeathLinkExplanationPage(__instance, localPlayer);
				}
			}

			private static void AddDeathLinkExplanationPage(TextsDialog textsDialog, Player player)
			{
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Expected O, but got Unknown
				long playerID = Player.m_localPlayer.GetPlayerID();
				if (DeathConfigurationData.playerSettings.ContainsKey(playerID))
				{
					string deathChoiceLevel = DeathConfigurationData.playerSettings[playerID].DeathChoiceLevel;
					DataObjects.DeathChoiceLevel deathChoiceLevel2 = DeathConfigurationData.DeathLevels[deathChoiceLevel];
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.AppendLine("<size=48>" + Localization.instance.Localize("$comp_header") + ": <color=" + specialColor + ">" + deathChoiceLevel2.DisplayName + "</color></size>");
					stringBuilder.AppendLine();
					stringBuilder.AppendLine("<size=30><b>Death Effects</b></size>");
					stringBuilder.AppendLine(deathChoiceLevel2.GetDeathStyleDescription());
					stringBuilder.AppendLine();
					if (deathChoiceLevel2.SkillModifiers.Count > 0)
					{
						stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>");
						stringBuilder.AppendLine(deathChoiceLevel2.GetSkillModiferDescription());
						stringBuilder.AppendLine();
					}
					if (deathChoiceLevel2.ResourceModifiers.Count > 0)
					{
						stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>");
						stringBuilder.AppendLine(deathChoiceLevel2.GetResourceModiferDescription());
						stringBuilder.AppendLine();
					}
					if (deathChoiceLevel2.DeathLootModifiers.Count > 0)
					{
						stringBuilder.AppendLine("<size=30><b>Loot Modifiers</b></size>");
						stringBuilder.AppendLine(deathChoiceLevel2.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 (!((Object)(object)Player.m_localPlayer != (Object)null) || !DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID()))
				{
					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()
			{
				GameObject deathChoicePanel = DeathChoicePanel;
				if (deathChoicePanel != 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;
				}
				DeathConfigurationData.playerSettings.Add(Player.m_localPlayer.GetPlayerID(), new DataObjects.DeathConfiguration
				{
					DeathChoiceLevel = 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_037a: 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);
					}
					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);
				}
				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_049a: Unknown result type (might be due to invalid IL or missing references)
				//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0549: Unknown result type (might be due to invalid IL or missing references)
				//IL_0578: Unknown result type (might be due to invalid IL or missing references)
				//IL_057e: Unknown result type (might be due to invalid IL or missing references)
				List<ItemData> list = new List<ItemData>();
				new List<ItemData>();
				List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems();
				List<ItemData> list2 = new List<ItemData>();
				List<ItemData> list3 = new List<ItemData>();
				Inventory inventory = ((Humanoid)instance).m_inventory;
				List<ItemData> list4 = new List<ItemData>();
				List<ItemData> list5 = new List<ItemData>();
				GameObject val = null;
				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
					{
						list3.Add(item);
					}
				}
				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;
				List<ItemData> list6 = Deathlink.shuffleList(list3.GetEquipment());
				if (Deathlink.AzuEPILoaded)
				{
					foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems())
					{
						if (source.Contains(quickSlotsItem.m_shared.m_name))
						{
							list2.Add(quickSlotsItem);
						}
						else
						{
							list3.Add(quickSlotsItem);
						}
					}
				}
				int equipment_saved_count = 0;
				foreach (ItemData item2 in list6)
				{
					if (remainingsaves > 0)
					{
						if (RemoveEquipmentByStyle(equipment_saved_count, num3, instance, item2, list, remainingsaves, out remainingsaves, out equipment_saved_count))
						{
							list.Add(item2);
						}
						else
						{
							list4.Add(item2);
						}
					}
					else
					{
						list4.Add(item2);
					}
				}
				List<ItemData> list7 = Deathlink.shuffleList(list3.GetNotEquipment());
				if (remainingsaves > 0)
				{
					foreach (ItemData item3 in list7)
					{
						if (remainingsaves > 0 && num2 > 0)
						{
							Logger.LogDebug("Saving " + item3.m_shared.m_name);
							list.Add(item3);
							remainingsaves--;
							num2--;
						}
						else
						{
							list4.Add(item3);
						}
					}
				}
				else
				{
					list4.AddRange(list7);
				}
				if (Deathlink.AzuEPILoaded)
				{
					Logger.LogDebug($"Quickslot items found {API.GetQuickSlotsItems().Count}");
					foreach (ItemData quickSlotsItem2 in API.GetQuickSlotsItems())
					{
						if (!list.Contains(quickSlotsItem2))
						{
							Logger.LogDebug("Removing quickslot item that was not saved " + quickSlotsItem2.m_shared.m_name);
							list4.Add(quickSlotsItem2);
						}
					}
				}
				switch (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction)
				{
				case DataObjects.NonSkillCheckedItemAction.Tombstone:
					Logger.LogDebug($"Dropping non-skill-checked items on death ({list2.Count()})");
					list5.AddRange(list2);
					break;
				case DataObjects.NonSkillCheckedItemAction.Destroy:
					Logger.LogDebug($"Destroying non-skill-checked items on death ({list2.Count()})");
					list4.AddRange(list2);
					break;
				case DataObjects.NonSkillCheckedItemAction.Save:
					Logger.LogDebug($"Saving non-skill-checked items on death ({list2.Count()})");
					list.AddRange(list2);
					break;
				}
				bool flag = false;
				if (Deathlink.pcfg().DeathStyle.itemLossStyle == DataObjects.ItemLossStyle.None && list4.Count > 0)
				{
					Logger.LogDebug($"Items failed skillcheck {list4.Count} items on death, dropping to tombestone.");
					list5.AddRange(list4);
				}
				foreach (ItemData item4 in list4)
				{
					((Humanoid)instance).m_inventory.RemoveItem(item4);
				}
				if (Deathlink.pcfg().DeathStyle.itemSavedStyle == DataObjects.ItemSavedStyle.Tombstone && list.Count > 0)
				{
					Logger.LogDebug($"Saving {list.Count} Items to tombstone");
					list5.AddRange(list);
				}
				if (list5.Count > 0)
				{
					Logger.LogDebug("Saving droppable items to tombstone");
					flag = true;
					val = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation);
					AddItemsToTombstone(val.GetComponent<Container>().GetInventory(), list5);
					foreach (ItemData item5 in list5)
					{
						((Humanoid)instance).m_inventory.RemoveItem(item5);
					}
					TombStone component = val.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 && flag)
				{
					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)
			{
				tombstone.m_height = (tombstone.m_width = Mathf.RoundToInt(Mathf.Sqrt((float)transferItems.Count())) + 1);
				foreach (ItemData transferItem in transferItems)
				{
					tombstone.m_inventory.Add(transferItem);
				}
				tombstone.Changed();
			}

			internal static bool RemoveEquipmentByStyle(int equipment_saved, int max_equipment_savable, Player instance, ItemData equipment, List<ItemData> saved_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 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();

		private const string color_good = "#b9f2ff";

		private const string color_bad = "#ff4040";
	}
	internal static class DeathConfigurationData
	{
		[HarmonyPatch(typeof(Player))]
		public static class SetupDeathLinkPlayerSpecificConfigPatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("SetPlayerID")]
			private static void Postfix()
			{
				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()
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				CheckAndSetPlayerDeathConfig(Player.m_localPlayer.GetPlayerID());
			}
		}

		public static void CheckAndSetPlayerDeathConfig(long 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 class ValConfig
	{
		[CompilerGenerated]
		private sealed class <OnClientReceiveDeathChoiceConfigs>d__27 : 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__27(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();
					<>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__30 : 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__30(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());
					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 <OnServerRecieveConfigs>d__28 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnServerRecieveConfigs>d__28(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;
					<>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 <OnServerRecievePlayerSettingsConfig>d__29 : 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 <OnServerRecievePlayerSettingsConfig>d__29(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());
					DeathConfigurationData.WritePlayerChoices();
					<>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();
			}
		}

		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<string> ItemsNotSkillChecked;

		public static ConfigEntry<float> SkillGainOnKills;

		public static ConfigEntry<float> SkillGainOnBossKills;

		public static ConfigEntry<float> SkillGainOnCrafts;

		public static ConfigEntry<float> SkillGainOnResourceGathering;

		public static ConfigEntry<float> SkillGainOnBuilding;

		public static ConfigEntry<bool> ShowDeathMapMarker;

		public static ConfigEntry<bool> EnableAlmanacClassesXPLossOnDeath;

		public static ConfigEntry<float> AlmanacClassesXPLossScale;

		public static ConfigEntry<float> AlmanacClassesXPGainScale;

		private const string cfgFolder = "Deathlink";

		private const string deathChoicesCfg = "DeathChoices.yaml";

		private const string deathSettingsCfg = "CharacterSettings.yaml";

		internal static string deathChoicesPath = Path.Combine(Paths.ConfigPath, "Deathlink", "DeathChoices.yaml");

		internal static string playerSettingsPath = Path.Combine(Paths.ConfigPath, "Deathlink", "CharacterSettings.yaml");

		private static CustomRPC deathChoiceRPC;

		private static CustomRPC characterSettingRPC;

		public static ConfigEntry<float> SkillProgressUpdateCheckInterval;

		public ValConfig(ConfigFile Config)
		{
			cfg = Config;
			cfg.SaveOnConfigSet = true;
			CreateConfigValues(Config);
			SetupConfigRPCs();
			LoadYamlConfigs();
		}

		public static string GetSecondaryConfigDirectoryPath()
		{
			return Directory.CreateDirectory(Path.Combine(Paths.ConfigPath, "Deathlink")).FullName;
		}

		public void SetupConfigRPCs()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0027: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0053: Expected O, but got Unknown
			deathChoiceRPC = NetworkManager.Instance.AddRPC("DEATHLK_CH", new CoroutineHandler(OnServerRecieveConfigs), new CoroutineHandler(OnClientReceiveDeathChoiceConfigs));
			characterSettingRPC = NetworkManager.Instance.AddRPC("DEATHLK_PSET", new CoroutineHandler(OnServerRecievePlayerSettingsConfig), new CoroutineHandler(OnClientReceivePlayerSettingsConfigs));
			SynchronizationManager.Instance.AddInitialSynchronization(deathChoiceRPC, (Func<ZPackage>)SendDeathChoices);
			SynchronizationManager.Instance.AddInitialSynchronization(characterSettingRPC, (Func<ZPackage>)SendCharSettings);
		}

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			ItemsNotSkillChecked = BindServerConfig("DeathProgression", "ItemsNotSkillChecked", "Tin,TinOre,Copper,CopperOre,CopperScrap,Bronze,Iron,IronScrap,Silver,SilverOre,DragonEgg,chest_hildir1,chest_hildir2,chest_hildir3,BlackMetal,BlackMetalScrap,DvergrNeedle,MechanicalSpring,FlametalNew,FlametalOreNew", "List of items that are not rolled to be saved through death progression.");
			SkillGainOnKills = BindServerConfig("DeathSkillGain", "SkillGainOnKills", 5f, "Skill Gain from killing non-boss creatures.");
			SkillGainOnBossKills = BindServerConfig("DeathSkillGain", "SkillGainOnBossKills", 20f, "Skill Gain from killing boss creatures.");
			SkillGainOnCrafts = BindServerConfig("DeathSkillGain", "SkillGainOnCrafts", 0.8f, "Skill Gain from crafting.");
			SkillGainOnResourceGathering = BindServerConfig("DeathSkillGain", "SkillGainOnResourceGathering", 0.1f, "Skill Gain from resource gathering.");
			SkillGainOnBuilding = BindServerConfig("DeathSkillGain", "SkillGainOnBuilding", 0.5f, "Skill Gain from building.");
			SkillProgressUpdateCheckInterval = BindServerConfig("DeathSkillGain", "SkillProgressUpdateCheckInterval", 1f, "How frequently skill gains are computed and added. More frequently means smaller xp gains more often.", advanced: true, 0.1f, 5f);
			ShowDeathMapMarker = BindServerConfig("DeathTweaks", "ShowDeathMapMarker", value: true, "Whether or not a map marker is placed on your death location.");
			EnableAlmanacClassesXPLossOnDeath = BindServerConfig("ModIntegrations", "EnableAlmanacClassesXPLossOnDeath", value: true, "If true, XP loss also happens for characters Alamanc Class level.");
			AlmanacClassesXPLossScale = BindServerConfig("ModIntegrations", "AlmanacClassesXPLossScale", 1f, "How strong the XP loss for Almanac is, lower = less XP loss, higher = more XP loss.");
			AlmanacClassesXPGainScale = BindServerConfig("ModIntegrations", "AlmanacClassesXPGainScale", 20f, "How much Almanac Classes XP is gained based on Deathlink actions. This is gained at an inregular interval based on deathlink skill gains.");
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
			EnableDebugMode.SettingChanged += Logger.enableDebugLogging;
			Logger.CheckEnableDebugLogging();
		}

		internal void LoadYamlConfigs()
		{
			string[] files = Directory.GetFiles(GetSecondaryConfigDirectoryPath());
			bool flag = false;
			bool flag2 = false;
			string[] array = files;
			foreach (string text in array)
			{
				if (text.Contains("DeathChoices.yaml"))
				{
					Logger.LogDebug("Found Deathchoice configuration: " + text);
					deathChoicesPath = text;
					flag = true;
				}
				if (text.Contains("CharacterSettings.yaml"))
				{
					Logger.LogDebug("Found Character configuration: " + text);
					playerSettingsPath = text;
					flag2 = true;
				}
			}
			if (!flag)
			{
				Logger.LogDebug("Death Choices missing, recreating.");
				using StreamWriter streamWriter = new StreamWriter(deathChoicesPath);
				string value = "#################################################\n# Deathlink - Death Choice Configuration\n#################################################\n";
				streamWriter.WriteLine(value);
				streamWriter.WriteLine(DeathConfigurationData.DeathLevelsYamlDefaultConfig());
			}
			if (!flag2)
			{
				Logger.LogDebug("Character Settings missing, recreating.");
				using StreamWriter streamWriter2 = new StreamWriter(playerSettingsPath);
				string value2 = "#################################################\n# Deathlink - Character settings\n#################################################\n";
				streamWriter2.WriteLine(value2);
				streamWriter2.WriteLine(DeathConfigurationData.PlayerSettingsDefaultConfig());
			}
			SetupFileWatcher("DeathChoices.yaml");
			SetupFileWatcher("CharacterSettings.yaml");
		}

		private void SetupFileWatcher(string filtername)
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
			fileSystemWatcher.Path = GetSecondaryConfigDirectoryPath();
			fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
			fileSystemWatcher.Filter = filtername;
			fileSystemWatcher.Changed += UpdateConfigFileOnChange;
			fileSystemWatcher.Created += UpdateConfigFileOnChange;
			fileSystemWatcher.Renamed += UpdateConfigFileOnChange;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private static void UpdateConfigFileOnChange(object sender, FileSystemEventArgs e)
		{
			if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Logger.LogInfo("Player is not an admin, and not allowed to change local configuration. Ignoring.");
			}
			else if