Decompiled source of Deathlink v0.10.2

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 Deathlink.external;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SimpleJson;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValRougelike")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValRougelike")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Backpacks
{
	[PublicAPI]
	public static class API
	{
		public static EpicMMOSystem_API.API_State state;

		private static MethodInfo eCountItemsInBackpacks;

		private static MethodInfo eAddItemToBackpack;

		private static MethodInfo eDeleteItemsFromBackpacks;

		private static MethodInfo eGetEquippedBackpackInventory;

		private static MethodInfo eGetAllBackpackInventories;

		public static int CountItemsInBackpacks(Inventory inventory, string name, bool onlyRemoveable = true)
		{
			return (int)eCountItemsInBackpacks?.Invoke(null, new object[3] { inventory, name, onlyRemoveable });
		}

		public static bool IsItemInBackpacks(Inventory inventory, string name)
		{
			return CountItemsInBackpacks(inventory, name) > 0;
		}

		public static bool AddItemToBackpack(ItemData backpack, ItemData item)
		{
			return (bool)eAddItemToBackpack?.Invoke(null, new object[2] { backpack, item });
		}

		public static bool DeleteItemsFromBackpacks(Inventory inventory, string name, int count = 1)
		{
			return (bool)eDeleteItemsFromBackpacks?.Invoke(null, new object[3] { inventory, name, count });
		}

		public static Inventory? GetEquippedBackpackInventory()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return (Inventory)(eGetEquippedBackpackInventory?.Invoke(null, new object[0]));
		}

		public static List<Inventory> GetAllBackpackInventories(Inventory inventory)
		{
			return (List<Inventory>)(eGetAllBackpackInventories?.Invoke(null, new object[1] { inventory }));
		}

		public static void Init()
		{
			EpicMMOSystem_API.API_State aPI_State = state;
			if ((uint)(aPI_State - 1) > 1u)
			{
				if (Type.GetType("Backpacks.API, Backpacks") == null)
				{
					state = EpicMMOSystem_API.API_State.NotInstalled;
					return;
				}
				state = EpicMMOSystem_API.API_State.Ready;
				Type? type = Type.GetType("Backpacks.API, Backpacks");
				eCountItemsInBackpacks = type.GetMethod("CountItemsInBackpacks", BindingFlags.Static | BindingFlags.Public);
				eAddItemToBackpack = type.GetMethod("AddItemToBackpack", BindingFlags.Static | BindingFlags.Public);
				eDeleteItemsFromBackpacks = type.GetMethod("DeleteItemsFromBackpacks", BindingFlags.Static | BindingFlags.Public);
				eGetEquippedBackpackInventory = type.GetMethod("GetEquippedBackpackInventory", BindingFlags.Static | BindingFlags.Public);
				eGetAllBackpackInventories = type.GetMethod("GetAllBackpackInventories", BindingFlags.Static | BindingFlags.Public);
			}
		}
	}
}
namespace AzuExtendedPlayerInventory
{
	[PublicAPI]
	public class API
	{
		public delegate void SlotAddedHandler(string slotName);

		public delegate void SlotRemovedHandler(string slotName);

		public static event Action<Hud>? OnHudAwake;

		public static event Action<Hud>? OnHudAwakeComplete;

		public static event Action<Hud>? OnHudUpdate;

		public static event Action<Hud>? OnHudUpdateComplete;

		public static event SlotAddedHandler? SlotAdded;

		public static event SlotRemovedHandler? SlotRemoved;

		public static bool IsLoaded()
		{
			return false;
		}

		public static bool AddSlot(string slotName, Func<Player, ItemData?> getItem, Func<ItemData, bool> isValid, int index = -1)
		{
			return false;
		}

		public static bool RemoveSlot(string slotName)
		{
			return false;
		}

		public static SlotInfo GetSlots()
		{
			return new SlotInfo();
		}

		public static SlotInfo GetQuickSlots()
		{
			return new SlotInfo();
		}

		public static List<ItemData> GetQuickSlotsItems()
		{
			return new List<ItemData>();
		}

		public static int GetAddedRows(int width)
		{
			return 0;
		}
	}
	[PublicAPI]
	public class SlotInfo
	{
		public string[] SlotNames { get; set; } = new string[0];

		public Vector2[] SlotPositions { get; set; } = (Vector2[])(object)new Vector2[0];

		public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = new Func<Player, ItemData>[0];

		public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = new Func<ItemData, bool>[0];
	}
}
namespace AlmanacClasses.API
{
	public static class ClassesAPI
	{
		private static readonly MethodInfo? API_AddExperience;

		private static readonly MethodInfo? API_GetLevel;

		private static readonly MethodInfo? API_GetCharacteristic;

		public static void AddEXP(int amount)
		{
			API_AddExperience?.Invoke(null, new object[1] { amount });
		}

		public static int GetLevel()
		{
			return (int)(API_GetLevel?.Invoke(null, null) ?? ((object)0));
		}

		public static int GetCharacteristic(string type)
		{
			return (int)(API_GetCharacteristic?.Invoke(null, new object[1] { type }) ?? ((object)0));
		}

		public static int GetConstitution()
		{
			return GetCharacteristic("Constitution");
		}

		public static int GetDexterity()
		{
			return GetCharacteristic("Dexterity");
		}

		public static int GetStrength()
		{
			return GetCharacteristic("Strength");
		}

		public static int GetIntelligence()
		{
			return GetCharacteristic("Intelligence");
		}

		public static int GetWisdom()
		{
			return GetCharacteristic("Wisdom");
		}

		static ClassesAPI()
		{
			Type type = Type.GetType("AlmanacClasses.API.API, AlmanacClasses");
			if ((object)type != null)
			{
				API_AddExperience = type.GetMethod("AddExperience", BindingFlags.Static | BindingFlags.Public);
				API_GetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public);
				API_GetCharacteristic = type.GetMethod("GetCharacteristic", BindingFlags.Static | BindingFlags.Public);
			}
		}
	}
}
namespace Deathlink
{
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				Deathlink.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				Deathlink.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				Deathlink.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				Deathlink.Log.LogError((object)message);
			}
		}
	}
	public static class Extensions
	{
		private static readonly List<ItemType> EquipmentTypes = new List<ItemType>
		{
			(ItemType)7,
			(ItemType)12,
			(ItemType)6,
			(ItemType)11,
			(ItemType)4,
			(ItemType)5,
			(ItemType)19,
			(ItemType)17,
			(ItemType)18,
			(ItemType)3,
			(ItemType)14,
			(ItemType)22,
			(ItemType)20,
			(ItemType)24
		};

		public static List<ItemData> GetEquipment(this List<ItemData> list)
		{
			return list.Where((ItemData x) => EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList();
		}

		public static List<ItemData> GetNotEquipment(this List<ItemData> list)
		{
			return list.Where((ItemData x) => !EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList();
		}

		public static bool IsEquipment(this ItemData item)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (EquipmentTypes.Contains(item.m_shared.m_itemType))
			{
				return true;
			}
			return false;
		}
	}
	[BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.10.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Deathlink : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.Deathlink";

		public const string PluginName = "Deathlink";

		public const string PluginVersion = "0.10.2";

		public ValConfig cfg;

		internal static AssetBundle EmbeddedResourceBundle;

		internal static bool AzuEPILoaded = false;

		internal static bool RustyAlmanacClassesLoaded = false;

		internal static bool WackyMMOLoaded = false;

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		public static ManualLogSource Log;

		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			AddLocalizations();
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Deathlink.AssetsEmbedded.deathless", typeof(Deathlink).Assembly);
			DeathProgressionSkill.SetupDeathSkill();
			if (API.IsLoaded())
			{
				AzuEPILoaded = true;
			}
			if (Enumerable.Contains(BepInExUtils.GetPlugins(false).Keys, "WackyMole.EpicMMOSystem"))
			{
				EpicMMOSystem_API.Init();
				if (EpicMMOSystem_API.state == EpicMMOSystem_API.API_State.Ready)
				{
					WackyMMOLoaded = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API loaded.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API installed but API not ready.");
				}
			}
			if (Enumerable.Contains(BepInExUtils.GetPlugins(false).Keys, "RustyMods.AlmanacClasses"))
			{
				RustyAlmanacClassesLoaded = true;
			}
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			DeathConfigurationData.Init();
			LeaderboardData.Init();
			((MonoBehaviour)this).StartCoroutine(LeaderboardData.SyncLoop());
			TerminalCommands.AddCommands();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Death is not the end.");
		}

		public static DataObjects.DeathChoiceLevel pcfg()
		{
			return DeathConfigurationData.playerDeathConfiguration;
		}

		private void AddLocalizations()
		{
			Localization = LocalizationManager.Instance.GetLocalization();
			string text = Path.Combine(Paths.ConfigPath, "Deathlink", "localizations");
			Directory.CreateDirectory(text);
			string[] manifestResourceNames = typeof(Deathlink).Assembly.GetManifestResourceNames();
			foreach (string text2 in manifestResourceNames)
			{
				if (!text2.Contains("Localizations"))
				{
					continue;
				}
				string text3 = Regex.Replace(ReadEmbeddedResourceFile(text2), "\\/\\/.*", "");
				Dictionary<string, string> internal_localization = SimpleJson.DeserializeObject<Dictionary<string, string>>(text3);
				string[] array = text2.Split(new char[1] { '.' });
				if (File.Exists(text + "/" + array[2] + ".json"))
				{
					string text4 = File.ReadAllText(text + "/" + array[2] + ".json");
					try
					{
						Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text4);
						UpdateLocalizationWithMissingKeys(internal_localization, dictionary);
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text + "/" + array[2] + ".json"));
						File.WriteAllText(text + "/" + array[2] + ".json", SimpleJson.SerializeObject((object)dictionary));
						string text5 = File.ReadAllText(text + "/" + array[2] + ".json");
						Localization.AddJsonFile(array[2], text5);
					}
					catch
					{
						File.WriteAllText(text + "/" + array[2] + ".json", text3);
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
						Localization.AddJsonFile(array[2], text3);
					}
				}
				else
				{
					File.WriteAllText(text + "/" + array[2] + ".json", text3);
					((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
					Localization.AddJsonFile(array[2], text3);
				}
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Added localization: '" + array[2] + "'"));
			}
		}

		private void UpdateLocalizationWithMissingKeys(Dictionary<string, string> internal_localization, Dictionary<string, string> cached_localization)
		{
			if (internal_localization.Keys.Count == cached_localization.Keys.Count)
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogDebug((object)"Cached localization was missing some entries. They will be added.");
			foreach (KeyValuePair<string, string> item in internal_localization)
			{
				if (!cached_localization.ContainsKey(item.Key))
				{
					cached_localization.Add(item.Key, item.Value);
				}
			}
		}

		private string ReadEmbeddedResourceFile(string filename)
		{
			using Stream stream = typeof(Deathlink).Assembly.GetManifestResourceStream(filename);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		public static List<T> shuffleList<T>(List<T> inputList)
		{
			int i = 0;
			int count = inputList.Count;
			int num = 0;
			T val = default(T);
			List<T> list = new List<T>();
			list.AddRange(inputList);
			for (; i < count; i++)
			{
				num = Random.Range(i, list.Count);
				val = list[i];
				list[i] = list[num];
				list[num] = val;
			}
			return list;
		}
	}
}
namespace Deathlink.external
{
	public static class EpicMMOSystem_API
	{
		public enum API_State
		{
			NotReady,
			NotInstalled,
			Ready
		}

		public enum Attribut
		{
			Strength,
			Agility,
			Intellect,
			Body,
			Vigour,
			Special
		}

		public static API_State state;

		private static MethodInfo eGetLevel;

		private static MethodInfo eAddExp;

		private static MethodInfo eGetAttribute;

		private static MethodInfo eGetAttributeRusty;

		private static MethodInfo eSetSingleRate;

		public static int GetLevel()
		{
			int result = 0;
			Init();
			if (eGetLevel != null)
			{
				result = (int)eGetLevel.Invoke(null, null);
			}
			return result;
		}

		public static int GetAttribute(Attribut attribute)
		{
			int result = 0;
			Init();
			if (eGetAttribute != null)
			{
				result = (int)eGetAttribute.Invoke(null, new object[1] { attribute });
			}
			return result;
		}

		public static int GetAttributeRusty(string attribute)
		{
			int result = 0;
			Init();
			if (eGetAttributeRusty != null)
			{
				result = (int)eGetAttributeRusty.Invoke(null, new object[1] { attribute });
			}
			return result;
		}

		public static void AddExp(int value)
		{
			Init();
			eAddExp?.Invoke(null, new object[1] { value });
		}

		public static void SetSingleRate(float rate)
		{
			Init();
			eSetSingleRate?.Invoke(null, new object[1] { rate });
		}

		public static void Init()
		{
			API_State aPI_State = state;
			if ((uint)(aPI_State - 1) > 1u)
			{
				if (Type.GetType("EpicMMOSystem.EpicMMOSystem, EpicMMOSystem") == null)
				{
					state = API_State.NotInstalled;
					return;
				}
				state = API_State.Ready;
				Type? type = Type.GetType("API.EMMOS_API, EpicMMOSystem");
				eGetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public);
				eAddExp = type.GetMethod("AddExp", BindingFlags.Static | BindingFlags.Public);
				eGetAttribute = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public);
				eGetAttributeRusty = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public);
				eSetSingleRate = type.GetMethod("SetSingleRate", BindingFlags.Static | BindingFlags.Public);
			}
		}
	}
}
namespace Deathlink.Death
{
	public static class Compendium
	{
		[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
		public static class TextsDialog_UpdateTextsList_Patch
		{
			public static void Postfix(TextsDialog __instance)
			{
				AddDeathLinkExplanationPage(__instance);
			}

			private static void AddDeathLinkExplanationPage(TextsDialog textsDialog)
			{
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Expected O, but got Unknown
				DataObjects.DeathChoiceLevel playerDeathConfiguration = DeathConfigurationData.playerDeathConfiguration;
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("<size=48>" + Localization.instance.Localize("$comp_header") + ": <color=" + specialColor + ">" + playerDeathConfiguration.DisplayName + "</color></size>");
				stringBuilder.AppendLine();
				stringBuilder.AppendLine("<size=30><b>Death Effects</b></size>");
				stringBuilder.AppendLine(playerDeathConfiguration.GetDeathStyleDescription());
				stringBuilder.AppendLine();
				if (playerDeathConfiguration.DamageTakenModifier != 1f || playerDeathConfiguration.DamageDoneModifier != 1f)
				{
					stringBuilder.AppendLine("<size=30><b>Combat Modifiers</b></size>");
					stringBuilder.AppendLine(playerDeathConfiguration.GetDamageModifierDescription());
					stringBuilder.AppendLine();
				}
				if (playerDeathConfiguration.SkillModifiers != null && playerDeathConfiguration.SkillModifiers.Count > 0)
				{
					stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>");
					stringBuilder.AppendLine(playerDeathConfiguration.GetSkillModiferDescription());
					stringBuilder.AppendLine();
				}
				if (playerDeathConfiguration.ResourceModifiers != null && playerDeathConfiguration.ResourceModifiers.Count > 0)
				{
					stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>");
					stringBuilder.AppendLine(playerDeathConfiguration.GetResourceModiferDescription());
					stringBuilder.AppendLine();
				}
				if (playerDeathConfiguration.DeathLootModifiers != null && playerDeathConfiguration.DeathLootModifiers.Count > 0)
				{
					stringBuilder.AppendLine("<size=30><b>Loot Modifiers</b></size>");
					stringBuilder.AppendLine(playerDeathConfiguration.GetLootModifiersDescription());
					stringBuilder.AppendLine();
				}
				textsDialog.m_texts.Insert(0, new TextInfo(Localization.instance.Localize("$deathlink_settings"), Localization.instance.Localize(stringBuilder.ToString())));
			}
		}

		[HarmonyPatch(typeof(TextsDialog), "ShowText", new Type[] { typeof(TextInfo) })]
		public static class TextsDialog_ShowText_Patch
		{
			public static void Postfix(TextsDialog __instance, TextInfo text)
			{
				bool flag = text != null && text.m_topic == Localization.instance.Localize("$deathlink_settings");
				bool flag2 = flag && DeathConfigurationData.PlayerCanChangeChoice(Player.m_localPlayer);
				Logger.LogDebug($"TextsDialog.ShowText topic='{text?.m_topic}' isDeathlinkPage={flag} canChange={flag2}");
				if (!flag2)
				{
					if ((Object)(object)changeChoiceButton != (Object)null)
					{
						changeChoiceButton.SetActive(false);
					}
					return;
				}
				EnsureChangeChoiceButton(__instance);
				if ((Object)(object)changeChoiceButton != (Object)null)
				{
					changeChoiceButton.SetActive(true);
					changeChoiceButton.transform.SetAsLastSibling();
				}
			}

			private static void EnsureChangeChoiceButton(TextsDialog dialog)
			{
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Expected O, but got Unknown
				if ((Object)(object)changeChoiceButton != (Object)null)
				{
					return;
				}
				if (GUIManager.Instance == null)
				{
					Logger.LogWarning("GUIManager not setup, skipping death choice change button creation.");
					return;
				}
				Transform val = ((Component)dialog).transform.Find("Texts_frame/Closebutton");
				changeChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$comp_change_choice"), val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(300f, 0f), 200f, 40f);
				((UnityEvent)changeChoiceButton.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					dialog.OnClose();
					DeathChoices.DeathChoiceUI.Instance.ShowForChange();
				});
			}

			private static RectTransform FindCloseButton(TextsDialog dialog)
			{
				Button val = null;
				Button[] componentsInChildren = ((Component)dialog).GetComponentsInChildren<Button>(true);
				foreach (Button val2 in componentsInChildren)
				{
					if ((Object)(object)((Component)val2).gameObject == (Object)(object)changeChoiceButton)
					{
						continue;
					}
					for (int j = 0; j < ((UnityEventBase)val2.onClick).GetPersistentEventCount(); j++)
					{
						if (((UnityEventBase)val2.onClick).GetPersistentMethodName(j) == "OnClose")
						{
							return ((Component)val2).GetComponent<RectTransform>();
						}
					}
					if ((Object)(object)val == (Object)null && ((Object)val2).name.IndexOf("close", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						val = val2;
					}
				}
				if (!((Object)(object)val != (Object)null))
				{
					return null;
				}
				return ((Component)val).GetComponent<RectTransform>();
			}
		}

		private static string specialColor = "#ffa64d";

		private static GameObject changeChoiceButton;
	}
	public static class DamageModifiers
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public static class DamageModifierPatch
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				if (hit == null)
				{
					return;
				}
				if (__instance is Player)
				{
					float storedModifier = GetStoredModifier(__instance, DataObjects.DamageTakenModifierKey);
					if (storedModifier != 1f)
					{
						hit.ApplyModifier(storedModifier);
					}
				}
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (val != null)
				{
					float storedModifier2 = GetStoredModifier((Character)(object)val, DataObjects.DamageDoneModifierKey);
					if (storedModifier2 != 1f)
					{
						hit.ApplyModifier(storedModifier2);
					}
				}
			}

			private static float GetStoredModifier(Character character, string key)
			{
				if ((Object)(object)character == (Object)null)
				{
					return 1f;
				}
				ZNetView nview = character.m_nview;
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					return 1f;
				}
				ZDO zDO = nview.GetZDO();
				if (zDO == null)
				{
					return 1f;
				}
				return zDO.GetFloat(key, 1f);
			}
		}
	}
	public static class DeathChoiceEnable
	{
		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class ShowDeathChoiceUI
		{
			public static void Postfix(InventoryGui __instance)
			{
				if (ValConfig.UsePrivateKeysForDeathChoice.Value)
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey))
					{
						return;
					}
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null && DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID()))
				{
					return;
				}
				DeathChoices.DeathChoiceUI.Instance.Show();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class HideDeathChoiceUI
		{
			public static void Postfix(InventoryGui __instance)
			{
				if (DeathChoices.DeathChoiceUI.IsInitialized)
				{
					DeathChoices.DeathChoiceUI.Instance.Hide();
				}
			}
		}
	}
	public class DeathChoices
	{
		public class DeathChoiceUI : MonoBehaviour
		{
			private static DeathChoiceUI _instance;

			private static GameObject DeathChoicePanel;

			private static GameObject ChoicesScrollView;

			private static GameObject ChoicesContent;

			private static GameObject ChoicesContainer;

			private static GameObject manualCloseButton;

			private static GameObject selectChoiceButton;

			private static Text DeathPenaltyDescription;

			private static Text CombatModifiersDescription;

			private static Text XPModifiersDescription;

			private static Text LootModifersDescription;

			private static Text HarvestModifiersDescription;

			private static List<Toggle> difficultyToggles = new List<Toggle>();

			private static ToggleGroup choiceGroup;

			private static string selectedDeathChoice = "none";

			private static bool isChangeMode = false;

			public static DeathChoiceUI Instance
			{
				get
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Expected O, but got Unknown
					if ((Object)(object)_instance == (Object)null)
					{
						GameObject val = new GameObject("DeathlinkDeathChoiceUI");
						Object.DontDestroyOnLoad((Object)val);
						_instance = val.AddComponent<DeathChoiceUI>();
					}
					return _instance;
				}
			}

			public static bool IsInitialized => (Object)(object)_instance != (Object)null;

			public void Awake()
			{
				_instance = this;
				CreateStaticUIObjects();
				SetChoiceList();
			}

			public void Show()
			{
				if ((Object)(object)DeathChoicePanel == (Object)null)
				{
					CreateStaticUIObjects();
					SetChoiceList();
				}
				DeathChoicePanel.SetActive(true);
			}

			public void ShowForChange()
			{
				isChangeMode = true;
				Show();
			}

			public void Hide()
			{
				if ((Object)(object)DeathChoicePanel != (Object)null)
				{
					DeathChoicePanel.SetActive(false);
				}
				isChangeMode = false;
				GUIManager.BlockInput(false);
			}

			public void MakePlayerDeathSelection()
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					Logger.LogWarning("Player not set, ensure the local player is set.");
					return;
				}
				if (selectedDeathChoice == "none")
				{
					Logger.LogWarning("No death type selected");
					return;
				}
				Logger.LogDebug("Player selected death type " + selectedDeathChoice);
				long playerID = Player.m_localPlayer.GetPlayerID();
				if (DeathConfigurationData.playerSettings.ContainsKey(playerID))
				{
					DeathConfigurationData.playerSettings[playerID].DeathChoiceLevel = selectedDeathChoice;
				}
				else
				{
					DeathConfigurationData.playerSettings.Add(playerID, new DataObjects.DeathConfiguration
					{
						DeathChoiceLevel = selectedDeathChoice
					});
				}
				Player.m_localPlayer.PlayerRemoveUniqueKey(DataObjects.DeathChoiceKey);
				Player.m_localPlayer.AddUniqueKeyValue(DataObjects.DeathChoiceKey, selectedDeathChoice);
				if (isChangeMode)
				{
					DeathConfigurationData.IncrementPlayerChangesUsed(Player.m_localPlayer);
				}
				DeathConfigurationData.CheckAndSetPlayerDeathConfig(Player.m_localPlayer);
				DeathConfigurationData.WritePlayerChoices();
				Hide();
			}

			private void SetChoiceList()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				foreach (Transform item in ChoicesContent.transform)
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
				difficultyToggles.Clear();
				int num = -75;
				foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> entry in DeathConfigurationData.DeathLevels)
				{
					GameObject obj = Object.Instantiate<GameObject>(ChoicesContainer, ChoicesContent.transform);
					Transform val = obj.transform.Find("selecter");
					((Component)val.Find("Label")).GetComponent<Text>().text = entry.Key;
					((Component)obj.transform.Find("ChoiceName")).GetComponent<Text>().text = entry.Value.DisplayName;
					Toggle component = ((Component)val).GetComponent<Toggle>();
					component.group = choiceGroup;
					((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool isOn)
					{
						if (isOn)
						{
							((Component)DeathPenaltyDescription).GetComponent<Text>().text = entry.Value.GetDeathStyleDescription();
							((Component)CombatModifiersDescription).GetComponent<Text>().text = entry.Value.GetDamageModifierDescription();
							((Component)XPModifiersDescription).GetComponent<Text>().text = entry.Value.GetSkillModiferDescription();
							((Component)LootModifersDescription).GetComponent<Text>().text = entry.Value.GetLootModifiersDescription();
							((Component)HarvestModifiersDescription).GetComponent<Text>().text = entry.Value.GetResourceModiferDescription();
							selectedDeathChoice = entry.Key;
						}
					});
					obj.SetActive(true);
					obj.transform.localPosition = new Vector3
					{
						x = 5f,
						y = num
					};
					difficultyToggles.Add(component);
					num -= 50;
				}
			}

			private void CreateStaticUIObjects()
			{
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_021b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0225: Expected O, but got Unknown
				//IL_0258: Unknown result type (might be due to invalid IL or missing references)
				//IL_0267: Unknown result type (might be due to invalid IL or missing references)
				//IL_0276: Unknown result type (might be due to invalid IL or missing references)
				//IL_028c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0292: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0308: Unknown result type (might be due to invalid IL or missing references)
				//IL_030e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0377: Unknown result type (might be due to invalid IL or missing references)
				//IL_0386: Unknown result type (might be due to invalid IL or missing references)
				//IL_0395: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0407: Unknown result type (might be due to invalid IL or missing references)
				//IL_0416: Unknown result type (might be due to invalid IL or missing references)
				//IL_0427: Unknown result type (might be due to invalid IL or missing references)
				//IL_042d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0496: 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_04b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0517: Unknown result type (might be due to invalid IL or missing references)
				//IL_0526: Unknown result type (might be due to invalid IL or missing references)
				//IL_0535: Unknown result type (might be due to invalid IL or missing references)
				//IL_0546: Unknown result type (might be due to invalid IL or missing references)
				//IL_054c: Unknown result type (might be due to invalid IL or missing references)
				//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_0636: Unknown result type (might be due to invalid IL or missing references)
				//IL_0645: Unknown result type (might be due to invalid IL or missing references)
				//IL_0654: Unknown result type (might be due to invalid IL or missing references)
				//IL_0665: Unknown result type (might be due to invalid IL or missing references)
				//IL_066b: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0708: Unknown result type (might be due to invalid IL or missing references)
				//IL_070e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0755: Unknown result type (might be due to invalid IL or missing references)
				//IL_0764: Unknown result type (might be due to invalid IL or missing references)
				//IL_0773: Unknown result type (might be due to invalid IL or missing references)
				//IL_0784: Unknown result type (might be due to invalid IL or missing references)
				//IL_078a: Unknown result type (might be due to invalid IL or missing references)
				//IL_07f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0802: Unknown result type (might be due to invalid IL or missing references)
				//IL_0811: Unknown result type (might be due to invalid IL or missing references)
				//IL_0840: Unknown result type (might be due to invalid IL or missing references)
				//IL_084a: Expected O, but got Unknown
				//IL_0874: Unknown result type (might be due to invalid IL or missing references)
				//IL_0879: Unknown result type (might be due to invalid IL or missing references)
				//IL_089e: Unknown result type (might be due to invalid IL or missing references)
				//IL_08bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_08bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_090d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0921: Expected O, but got Unknown
				//IL_0952: Unknown result type (might be due to invalid IL or missing references)
				//IL_09a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_09ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a07: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a16: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a25: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a3b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a41: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)DeathChoicePanel != (Object)null))
				{
					if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
					{
						Logger.LogWarning("GUIManager not setup, skipping static object creation.");
						return;
					}
					Logger.LogDebug("Creating static UI");
					DeathChoicePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 960f, true);
					DeathChoicePanel.SetActive(false);
					((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, 430f), 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, 380f), 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, 430f), 60f, 60f);
					Button component2 = manualCloseButton.GetComponent<Button>();
					((Selectable)component2).interactable = true;
					((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide));
					manualCloseButton.SetActive(true);
					((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 330f), 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(147f, 240f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 490f, 160f, false);
					((Object)obj).name = "DeathPenaltyDesc";
					DeathPenaltyDescription = obj.GetComponent<Text>();
					DeathPenaltyDescription.resizeTextForBestFit = true;
					DeathPenaltyDescription.resizeTextMaxSize = 18;
					((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$combat_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 150f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "combatModifiersTitle";
					GameObject obj2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$combat_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, 80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 100f, false);
					((Object)obj2).name = "combatModifiersDesc";
					CombatModifiersDescription = obj2.GetComponent<Text>();
					CombatModifiersDescription.resizeTextForBestFit = true;
					CombatModifiersDescription.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 obj3 = 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)obj3).name = "xpModifiersDesc";
					XPModifiersDescription = obj3.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 obj4 = 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)obj4).name = "lootModifersDesc";
					LootModifersDescription = obj4.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 obj5 = 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)obj5).name = "harvestModifersDesc";
					HarvestModifiersDescription = obj5.GetComponent<Text>();
					HarvestModifiersDescription.resizeTextForBestFit = true;
					HarvestModifiersDescription.resizeTextMaxSize = 18;
					selectChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$deathchoice_select"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-240f, -290f), 200f, 80f);
					((UnityEvent)selectChoiceButton.GetComponent<Button>().onClick).AddListener(new UnityAction(MakePlayerDeathSelection));
					Logger.LogDebug("Setting up scroll entry");
					ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 250f, 400f);
					ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2
					{
						x = -260f,
						y = -30f
					});
					ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject;
					ChoicesScrollView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f;
					choiceGroup = ChoicesContent.AddComponent<ToggleGroup>();
					Logger.LogDebug("Setting up death choice template entry");
					ChoicesContainer = Object.Instantiate<GameObject>(new GameObject("DeathChoice"), DeathChoicePanel.transform);
					RectTransform obj6 = ChoicesContainer.AddComponent<RectTransform>();
					obj6.SetSizeWithCurrentAnchors((Axis)0, 100f);
					obj6.SetSizeWithCurrentAnchors((Axis)1, 50f);
					((Transform)obj6).position = new Vector3(0f, 0f);
					ChoicesContainer.AddComponent<LayoutElement>().minHeight = 50f;
					ChoicesContainer.SetActive(false);
					GameObject obj7 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f);
					obj7.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f));
					((Object)obj7).name = "selecter";
					((Component)obj7.transform.Find("Label")).gameObject.SetActive(false);
					obj7.GetComponent<Toggle>().isOn = false;
					((Object)GUIManager.Instance.CreateText("Name", ChoicesContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 0f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false)).name = "ChoiceName";
				}
			}
		}
	}
	public static class DeathProgressionSkill
	{
		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		public class Deathskill_EXP_Patch
		{
			public static void Postfix(Player __instance)
			{
				//IL_03b9: 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 + num9 + num8 + num7;
					float num14 = Mathf.Max(0f, (float)Math.Log(__instance.m_timeSinceDeath) / 5f * 0.5f);
					float num15 = num14 * num13;
					if (Deathlink.RustyAlmanacClassesLoaded)
					{
						int num16 = Mathf.RoundToInt(num15 * ValConfig.AlmanacClassesXPGainScale.Value);
						Logger.LogDebug($"Almanac XP Gain {num16}");
						ClassesAPI.AddEXP(num16);
					}
					if (Deathlink.WackyMMOLoaded)
					{
						int num17 = Mathf.RoundToInt(num15 * ValConfig.WackyMMOXPGainScale.Value);
						Logger.LogDebug($"WackyMMO XP Gain {num17}");
						EpicMMOSystem_API.AddExp(num17);
					}
					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;
		}
	}
	internal static class DeathSavingOptions
	{
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public static class Player_OnSpawned_Patch
		{
			public static void Postfix(Player __instance)
			{
				if (pendingChoice && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					((Character)__instance).Message((MessageType)2, Localization.instance.Localize("$dso_spawn_message"), 0, (Sprite)null);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class ShowSaveChoiceUI
		{
			public static void Postfix()
			{
				if (pendingChoice)
				{
					SaveChoiceUI.Instance.Show(new List<ItemData>(deathItems), totalToSave, maxChoices);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class HideSaveChoiceUI
		{
			public static void Postfix()
			{
				if (SaveChoiceUI.IsInitialized)
				{
					SaveChoiceUI.Instance.Hide();
				}
			}
		}

		public class SaveChoiceUI : MonoBehaviour
		{
			private static SaveChoiceUI _instance;

			private const int GridWidth = 8;

			private static GameObject panel;

			private static Text counterText;

			private static InventoryGrid grid;

			private static RectTransform gridRoot;

			private static Inventory tempInv;

			private static bool selectionWired;

			private static readonly HashSet<ItemData> selected = new HashSet<ItemData>();

			private static int keepBudget = 0;

			private static int pickLimit = 0;

			public static SaveChoiceUI Instance
			{
				get
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Expected O, but got Unknown
					if ((Object)(object)_instance == (Object)null)
					{
						GameObject val = new GameObject("DeathlinkSaveChoiceUI");
						Object.DontDestroyOnLoad((Object)val);
						_instance = val.AddComponent<SaveChoiceUI>();
					}
					return _instance;
				}
			}

			public static bool IsInitialized => (Object)(object)_instance != (Object)null;

			public void Awake()
			{
				_instance = this;
			}

			public void Update()
			{
				if (!((Object)(object)panel == (Object)null) && panel.activeSelf && !((Object)(object)grid == (Object)null) && tempInv != null)
				{
					grid.UpdateInventory(tempInv, (Player)null, (ItemData)null);
				}
			}

			public void Show(List<ItemData> items, int totalKept, int choiceCount)
			{
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				if (EnsurePanel() && EnsureGrid())
				{
					keepBudget = totalKept;
					pickLimit = choiceCount;
					selected.Clear();
					BuildInventory(items);
					grid.UpdateInventory(tempInv, (Player)null, (ItemData)null);
					grid.ResetView();
					string text = $"SaveChoiceUI grid: {tempInv.GetWidth()}x{tempInv.GetHeight()}, ";
					string text2 = $"slot elements={(((Object)(object)gridRoot != (Object)null) ? ((Transform)gridRoot).childCount : (-1))}, ";
					Rect rect = ((RectTransform)((Component)grid).transform).rect;
					Logger.LogDebug(text + text2 + $"gridRect={((Rect)(ref rect)).size}");
					ClearHighlights();
					UpdateCounter();
					panel.SetActive(true);
				}
			}

			public void Hide()
			{
				if ((Object)(object)panel != (Object)null)
				{
					panel.SetActive(false);
				}
			}

			private void Confirm()
			{
				List<ItemData> picked = selected.ToList();
				Hide();
				selected.Clear();
				ApplySelection(picked);
			}

			private bool EnsurePanel()
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0229: Unknown result type (might be due to invalid IL or missing references)
				//IL_0238: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: Unknown result type (might be due to invalid IL or missing references)
				//IL_026c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0276: Expected O, but got Unknown
				if ((Object)(object)panel != (Object)null)
				{
					return true;
				}
				if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
				{
					Logger.LogWarning("GUIManager not setup, skipping death saving panel creation.");
					return false;
				}
				panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 700f, 640f, true);
				panel.SetActive(false);
				GUIManager.Instance.CreateText(Localization.instance.Localize("$dso_header"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 270f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 620f, 40f, false);
				GUIManager.Instance.CreateText(Localization.instance.Localize("$dso_description"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 225f), GUIManager.Instance.AveriaSerif, 18, Color.white, true, Color.black, 620f, 50f, false).GetComponent<Text>().alignment = (TextAnchor)4;
				counterText = GUIManager.Instance.CreateText("", panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 180f), GUIManager.Instance.AveriaSerifBold, 18, GUIManager.Instance.ValheimYellow, true, Color.black, 620f, 40f, false).GetComponent<Text>();
				counterText.alignment = (TextAnchor)4;
				((UnityEvent)GUIManager.Instance.CreateButton(Localization.instance.Localize("$dso_confirm"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -270f), 250f, 60f).GetComponent<Button>().onClick).AddListener(new UnityAction(Confirm));
				return true;
			}

			private bool EnsureGrid()
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Expected O, but got Unknown
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)grid != (Object)null)
				{
					return true;
				}
				if ((Object)(object)InventoryGui.instance == (Object)null || (Object)(object)InventoryGui.instance.ContainerGrid == (Object)null)
				{
					Logger.LogWarning("InventoryGui not ready, cannot build death saving grid.");
					return false;
				}
				GameObject val = new GameObject("DL_GridHolder", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(panel.transform, false);
				RectTransform val2 = (RectTransform)val.transform;
				val2.anchorMin = new Vector2(0.5f, 0.5f);
				val2.anchorMax = new Vector2(0.5f, 0.5f);
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.sizeDelta = new Vector2(600f, 380f);
				val2.anchoredPosition = new Vector2(0f, -40f);
				GameObject obj = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.ContainerGrid).gameObject, (Transform)(object)val2);
				((Object)obj).name = "DL_SaveGrid";
				obj.SetActive(true);
				RectTransform val3 = (RectTransform)obj.transform;
				((Transform)val3).localScale = Vector3.one;
				((Transform)val3).localRotation = Quaternion.identity;
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				val3.offsetMin = Vector2.zero;
				val3.offsetMax = Vector2.zero;
				grid = obj.GetComponent<InventoryGrid>();
				gridRoot = grid.m_gridRoot;
				if ((Object)(object)gridRoot != (Object)null)
				{
					((Component)gridRoot).gameObject.SetActive(true);
				}
				if ((Object)(object)gridRoot != (Object)null)
				{
					foreach (Transform item in (Transform)gridRoot)
					{
						Object.Destroy((Object)(object)((Component)item).gameObject);
					}
				}
				grid.m_width = 0;
				grid.m_height = 0;
				if (!selectionWired)
				{
					InventoryGrid obj2 = grid;
					obj2.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Combine(obj2.m_onSelected, (Action<InventoryGrid, ItemData, Vector2i, Modifier>)delegate(InventoryGrid g, ItemData item, Vector2i pos, Modifier mod)
					{
						//IL_0002: Unknown result type (might be due to invalid IL or missing references)
						OnItemClicked(item, pos);
					});
					InventoryGrid obj3 = grid;
					obj3.m_onRightClick = (Action<InventoryGrid, ItemData, Vector2i>)Delegate.Combine(obj3.m_onRightClick, (Action<InventoryGrid, ItemData, Vector2i>)delegate
					{
					});
					selectionWired = true;
				}
				return true;
			}

			private void BuildInventory(List<ItemData> items)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				int num = Mathf.Max(1, items.Count);
				int num2 = Mathf.Max(1, Mathf.CeilToInt((float)num / 8f));
				tempInv = new Inventory("DL_SaveChoice", (Sprite)null, 8, num2);
				tempInv.m_inventory.Clear();
				int num3 = 0;
				foreach (ItemData item in items)
				{
					item.m_gridPos = new Vector2i(num3 % 8, num3 / 8);
					tempInv.m_inventory.Add(item);
					num3++;
				}
				tempInv.Changed();
			}

			private void OnItemClicked(ItemData item, Vector2i pos)
			{
				//IL_001e: 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)
				if (item == null)
				{
					return;
				}
				if (selected.Contains(item))
				{
					selected.Remove(item);
					SetHighlight(pos, on: false);
				}
				else
				{
					if (selected.Count >= pickLimit)
					{
						return;
					}
					selected.Add(item);
					SetHighlight(pos, on: true);
				}
				UpdateCounter();
			}

			private void SetHighlight(Vector2i pos, bool on)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: 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)
				if ((Object)(object)gridRoot == (Object)null)
				{
					return;
				}
				int num = pos.y * 8 + pos.x;
				if (num >= 0 && num < ((Transform)gridRoot).childCount)
				{
					Transform child = ((Transform)gridRoot).GetChild(num);
					Transform val = child.Find("dl_highlight");
					if ((Object)(object)val == (Object)null)
					{
						GameObject val2 = new GameObject("dl_highlight", new Type[2]
						{
							typeof(RectTransform),
							typeof(Image)
						});
						val2.transform.SetParent(child, false);
						RectTransform val3 = (RectTransform)val2.transform;
						val3.anchorMin = Vector2.zero;
						val3.anchorMax = Vector2.one;
						val3.offsetMin = Vector2.zero;
						val3.offsetMax = Vector2.zero;
						Image component = val2.GetComponent<Image>();
						((Graphic)component).color = new Color(1f, 0.82f, 0.2f, 0.4f);
						((Graphic)component).raycastTarget = false;
						val = val2.transform;
					}
					((Component)val).gameObject.SetActive(on);
				}
			}

			private void ClearHighlights()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)gridRoot == (Object)null)
				{
					return;
				}
				foreach (Transform item in (Transform)gridRoot)
				{
					Transform val = item.Find("dl_highlight");
					if ((Object)(object)val != (Object)null)
					{
						((Component)val).gameObject.SetActive(false);
					}
				}
			}

			private void UpdateCounter()
			{
				if (!((Object)(object)counterText == (Object)null))
				{
					string text = string.Format(Localization.instance.Localize("$dso_selected"), selected.Count, pickLimit);
					int num = Mathf.Max(0, keepBudget - selected.Count);
					if (num > 0)
					{
						text = text + "  -  " + string.Format(Localization.instance.Localize("$dso_random_note"), num);
					}
					counterText.text = text;
				}
			}
		}

		private static readonly List<ItemData> deathItems = new List<ItemData>();

		private static int totalToSave = 0;

		private static int maxChoices = 0;

		private static bool pendingChoice = false;

		public static void CaptureDeathChoice(List<ItemData> candidateItems, int totalKept, int choiceCount)
		{
			deathItems.Clear();
			deathItems.AddRange(candidateItems);
			totalToSave = Mathf.Max(0, totalKept);
			maxChoices = Mathf.Clamp(choiceCount, 0, totalToSave);
			pendingChoice = true;
			Logger.LogDebug($"Captured {deathItems.Count} death items for choice, keep {totalToSave}, pick up to {maxChoices}.");
		}

		private static void ApplySelection(List<ItemData> picked)
		{
			Player localPlayer = Player.m_localPlayer;
			List<ItemData> saved = new List<ItemData>();
			if (picked != null)
			{
				foreach (ItemData item in picked)
				{
					if (deathItems.Contains(item) && !saved.Contains(item))
					{
						saved.Add(item);
					}
				}
			}
			if (saved.Count < totalToSave)
			{
				foreach (ItemData item2 in Deathlink.shuffleList(deathItems.Where((ItemData i) => !saved.Contains(i)).ToList()))
				{
					if (saved.Count >= totalToSave)
					{
						break;
					}
					saved.Add(item2);
				}
			}
			if ((Object)(object)localPlayer != (Object)null)
			{
				foreach (ItemData item3 in saved)
				{
					item3.m_equipped = false;
					((Humanoid)localPlayer).m_inventory.AddItem(item3);
				}
				Logger.LogDebug($"Returned {saved.Count} items to the player after death choice.");
			}
			else
			{
				Logger.LogWarning("Local player missing while applying death choice, saved items were lost.");
			}
			deathItems.Clear();
			totalToSave = 0;
			maxChoices = 0;
			pendingChoice = false;
		}
	}
	public static class HarvestModifiers
	{
		[HarmonyPatch(typeof(DropTable), "GetDropList", new Type[] { })]
		public static class ScaleHarvestDropList
		{
			private static void Postfix(List<GameObject> __result)
			{
				if (ScalingActive && HasResourceModifiers())
				{
					ScaleDropListInPlace(__result);
				}
			}
		}

		[HarmonyPatch(typeof(TreeLog), "Destroy")]
		public static class TreeLogHarvestScale
		{
			private static void Prefix(HitData hitData, out bool __state)
			{
				__state = false;
				if (!ScalingActive && ShouldScaleHarvest(hitData))
				{
					ScalingActive = true;
					__state = true;
				}
			}

			private static void Finalizer(TreeLog __instance, bool __state)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if (__state)
				{
					ScalingActive = false;
					SpawnHarvestBonusLoot(((Component)__instance).transform.position);
				}
			}
		}

		[HarmonyPatch(typeof(Destructible), "Destroy")]
		public static class DestructibleHarvestScale
		{
			private static void Prefix(Destructible __instance, HitData hit, out bool __state)
			{
				__state = false;
				if (!((Object)(object)__instance.m_spawnWhenDestroyed != (Object)null))
				{
					DropOnDestroyed component = ((Component)__instance).GetComponent<DropOnDestroyed>();
					if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null && !component.m_dropWhenDestroyed.IsEmpty() && !ScalingActive && ShouldScaleHarvest(hit))
					{
						ScalingActive = true;
						__state = true;
					}
				}
			}

			private static void Finalizer(Destructible __instance, bool __state)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if (__state)
				{
					ScalingActive = false;
					SpawnHarvestBonusLoot(((Component)__instance).transform.position);
				}
			}
		}

		[HarmonyPatch(typeof(MineRock5), "DamageArea")]
		public static class MineRockHarvestScale
		{
			private static void Prefix(HitData hit, out bool __state)
			{
				__state = false;
				if (!ScalingActive && ShouldScaleHarvest(hit))
				{
					ScalingActive = true;
					__state = true;
				}
			}

			private static void Finalizer(MineRock5 __instance, bool __state, bool __result)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				if (__state)
				{
					ScalingActive = false;
					if (__result)
					{
						SpawnHarvestBonusLoot(((Component)__instance).transform.position);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Pickable), "Drop")]
		public static class ScalePickableDrop
		{
			private static bool Prefix(GameObject prefab, ref int stack)
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null || !HasResourceModifiers() || (Object)(object)prefab == (Object)null)
				{
					return true;
				}
				float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(prefab);
				if (resouceEarlyCache == 1f)
				{
					return true;
				}
				int num = ScaleCount(stack, resouceEarlyCache);
				if (num <= 0)
				{
					return false;
				}
				stack = num;
				return true;
			}
		}

		internal static bool ScalingActive;

		private static bool HasResourceModifiers()
		{
			DataObjects.DeathChoiceLevel deathChoiceLevel = Deathlink.pcfg();
			if (deathChoiceLevel.ResourceModifiers != null)
			{
				return deathChoiceLevel.ResourceModifiers.Count > 0;
			}
			return false;
		}

		private static bool ShouldScaleHarvest(HitData hit)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if (!HasResourceModifiers())
			{
				return false;
			}
			if (hit == null)
			{
				return false;
			}
			return hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID();
		}

		public static int ScaleCount(int baseCount, float m)
		{
			if (baseCount <= 0)
			{
				return 0;
			}
			float num = (float)baseCount * m;
			int num2 = Mathf.FloorToInt(num);
			float num3 = num - (float)num2;
			if (num3 > 0f && Random.value < num3)
			{
				num2++;
			}
			return num2;
		}

		public static void ScaleDropListInPlace(List<GameObject> drops)
		{
			if (drops == null || drops.Count == 0)
			{
				return;
			}
			Dictionary<GameObject, int> dictionary = new Dictionary<GameObject, int>();
			List<GameObject> list = new List<GameObject>();
			foreach (GameObject drop in drops)
			{
				if (!((Object)(object)drop == (Object)null))
				{
					if (dictionary.TryGetValue(drop, out var value))
					{
						dictionary[drop] = value + 1;
						continue;
					}
					dictionary[drop] = 1;
					list.Add(drop);
				}
			}
			drops.Clear();
			foreach (GameObject item in list)
			{
				float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(item);
				int num = ((resouceEarlyCache == 1f) ? dictionary[item] : ScaleCount(dictionary[item], resouceEarlyCache));
				if (num != dictionary[item])
				{
					Logger.LogDebug($"Scaling harvest drop {((Object)item).name}: {dictionary[item]} -> {num} (x{resouceEarlyCache})");
				}
				for (int i = 0; i < num; i++)
				{
					drops.Add(item);
				}
			}
		}

		private static void SpawnHarvestBonusLoot(Vector3 position)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<GameObject, int>> list = Deathlink.pcfg().RollHarvestLoot();
			if (list.Count == 0)
			{
				return;
			}
			foreach (KeyValuePair<GameObject, int> item in list)
			{
				for (int i = 0; i < item.Value; i++)
				{
					Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
					Object.Instantiate<GameObject>(item.Key, position, val);
				}
			}
		}
	}
	internal static class LeaderboardData
	{
		[HarmonyPatch(typeof(Player), "OnDeath")]
		public static class Leaderboard_OnDeath_Patch
		{
			[HarmonyPrefix]
			public static void Prefix(Player __instance)
			{
				if (ValConfig.EnableLeaderboard.Value && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					long num = (long)Mathf.Max(0f, __instance.m_timeSinceDeath);
					long longKey = GetLongKey(__instance, DataObjects.LeaderboardDeathCountKey);
					long longKey2 = GetLongKey(__instance, DataObjects.LeaderboardTotalLifeKey);
					long longKey3 = GetLongKey(__instance, DataObjects.LeaderboardLongestLifeKey);
					if (longKey == 0L)
					{
						SetLongKey(__instance, DataObjects.LeaderboardFirstLifeKey, num);
					}
					SetLongKey(__instance, DataObjects.LeaderboardDeathCountKey, longKey + 1);
					SetLongKey(__instance, DataObjects.LeaderboardTotalLifeKey, longKey2 + num);
					if (num > longKey3)
					{
						SetLongKey(__instance, DataObjects.LeaderboardLongestLifeKey, num);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		public static class Leaderboard_Damage_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(Character __instance, HitData hit)
			{
				if (ValConfig.EnableLeaderboard.Value && hit != null && !((Object)(object)Player.m_localPlayer == (Object)null) && !(__instance is Player) && !((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer))
				{
					long num = (long)Mathf.Max(0f, hit.GetTotalDamage());
					if (num > 0)
					{
						sessionDamage += num;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public static class Leaderboard_OnSpawned_Patch
		{
			[HarmonyPostfix]
			public static void Postfix(Player __instance)
			{
				if (!ValConfig.EnableLeaderboard.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || initialReportSent)
				{
					return;
				}
				initialReportSent = true;
				try
				{
					SendLocalSnapshotToServer();
				}
				catch (Exception arg)
				{
					Logger.LogWarning($"Initial leaderboard report failed: {arg}");
				}
			}
		}

		[HarmonyPatch(typeof(Game), "Shutdown")]
		public static class Leaderboard_Shutdown_Patch
		{
			[HarmonyPrefix]
			public static void Prefix()
			{
				if (ValConfig.EnableLeaderboard.Value)
				{
					try
					{
						FlushLocalSnapshotToServer();
					}
					catch (Exception arg)
					{
						Logger.LogWarning($"Leaderboard disconnect flush failed: {arg}");
					}
				}
				initialReportSent = false;
				sessionDamage = 0L;
			}
		}

		public static Dictionary<long, DataObjects.LeaderboardEntry> leaderboard = new Dictionary<long, DataObjects.LeaderboardEntry>();

		private static CustomRPC leaderboardRPC;

		private static long sessionDamage = 0L;

		private static bool initialReportSent = false;

		internal static void Init()
		{
			try
			{
				if (File.Exists(ValConfig.leaderboardPath))
				{
					UpdateLeaderboardFromYaml(File.ReadAllText(ValConfig.leaderboardPath));
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Failed to load leaderboard data, starting empty. Exception: {arg}");
			}
		}

		public static void Write()
		{
			try
			{
				File.WriteAllText(ValConfig.leaderboardPath, DataObjects.yamlserializer.Serialize((object)leaderboard));
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Failed to write leaderboard data. Exception: {arg}");
			}
		}

		public static void UpdateLeaderboardFromYaml(string rawyaml)
		{
			if (!string.IsNullOrWhiteSpace(rawyaml))
			{
				Dictionary<long, DataObjects.LeaderboardEntry> dictionary = DataObjects.leaderboardDeserializer.Deserialize<Dictionary<long, DataObjects.LeaderboardEntry>>(rawyaml);
				if (dictionary != null)
				{
					leaderboard = dictionary;
				}
			}
		}

		public static void MergeSnapshot(DataObjects.LeaderboardEntry entry)
		{
			if (entry != null && entry.PlayerID != 0L)
			{
				leaderboard[entry.PlayerID] = entry;
				Write();
			}
		}

		public static void SetupRPC()
		{
			//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
			leaderboardRPC = NetworkManager.Instance.AddRPC("DEATHLK_LB", new CoroutineHandler(OnServerReceiveSnapshot), new CoroutineHandler(OnClientReceiveBoard));
			SynchronizationManager.Instance.AddInitialSynchronization(leaderboardRPC, (Func<ZPackage>)SendFullBoardPackage);
		}

		private static IEnumerator OnServerReceiveSnapshot(long sender, ZPackage package)
		{
			try
			{
				bool num = package.ReadBool();
				string text = package.ReadString();
				MergeSnapshot(DataObjects.leaderboardDeserializer.Deserialize<DataObjects.LeaderboardEntry>(text));
				if (num && leaderboardRPC != null)
				{
					leaderboardRPC.SendPackage(sender, SendFullBoardPackage());
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Failed to parse leaderboard snapshot from {sender}. Exception: {arg}");
			}
			yield return null;
		}

		private static IEnumerator OnClientReceiveBoard(long sender, ZPackage package)
		{
			string rawyaml = package.ReadString();
			try
			{
				UpdateLeaderboardFromYaml(rawyaml);
				LeaderboardUI.RefreshIfVisible();
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Failed to parse leaderboard board. Exception: {arg}");
			}
			yield return null;
		}

		private static ZPackage SendFullBoardPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(DataObjects.yamlserializer.Serialize((object)leaderboard));
			return val;
		}

		public static void BroadcastFullBoard()
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && leaderboardRPC != null)
			{
				leaderboardRPC.SendPackage(ZNet.instance.m_peers, SendFullBoardPackage());
			}
		}

		public static void SendLocalSnapshotToServer(bool requestBoard = false)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			DataObjects.LeaderboardEntry leaderboardEntry = BuildLocalSnapshot();
			if (leaderboardEntry == null)
			{
				return;
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				MergeSnapshot(leaderboardEntry);
				if (requestBoard)
				{
					LeaderboardUI.RefreshIfVisible();
				}
			}
			else if (leaderboardRPC != null && ZRoutedRpc.instance != null)
			{
				ZPackage val = new ZPackage();
				val.Write(requestBoard);
				val.Write(DataObjects.yamlserializer.Serialize((object)leaderboardEntry));
				leaderboardRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val);
			}
		}

		public static void RequestDashboardSync()
		{
			if (!ValConfig.EnableLeaderboard.Value || (Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			try
			{
				SendLocalSnapshotToServer(requestBoard: true);
			}
			catch (Exception arg)
			{
				Logger.LogWarning($"Leaderboard dashboard sync failed: {arg}");
			}
		}

		public static void FlushLocalSnapshotToServer()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return;
			}
			if (ZNet.instance.IsServer())
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					DataObjects.LeaderboardEntry leaderboardEntry = BuildLocalSnapshot();
					if (leaderboardEntry != null)
					{
						MergeSnapshot(leaderboardEntry);
					}
				}
			}
			else
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null || leaderboardRPC == null)
				{
					return;
				}
				ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
				if (serverPeer == null)
				{
					return;
				}
				DataObjects.LeaderboardEntry leaderboardEntry2 = BuildLocalSnapshot();
				if (leaderboardEntry2 != null)
				{
					ZPackage val = new ZPackage();
					val.Write(false);
					val.Write(DataObjects.yamlserializer.Serialize((object)leaderboardEntry2));
					IEnumerator enumerator = leaderboardRPC.SendPackageRoutine(new List<ZNetPeer> { serverPeer }, val);
					while (enumerator.MoveNext())
					{
					}
				}
			}
		}

		public static DataObjects.LeaderboardEntry BuildLocalSnapshot()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return null;
			}
			PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null);
			if (val == null || val.m_playerStats == null)
			{
				return null;
			}
			Dictionary<PlayerStatType, float> stats = val.m_playerStats.m_stats;
			long num = GetLongKey(localPlayer, DataObjects.LeaderboardDamageKey);
			if (sessionDamage > 0)
			{
				num += sessionDamage;
				SetLongKey(localPlayer, DataObjects.LeaderboardDamageKey, num);
				sessionDamage = 0L;
			}
			return new DataObjects.LeaderboardEntry
			{
				PlayerID = localPlayer.GetPlayerID(),
				PlayerName = val.GetName(),
				DeathChoice = (DeathConfigurationData.playerDeathConfiguration?.DisplayName ?? ""),
				FirstLifeSeconds = GetLongKey(localPlayer, DataObjects.LeaderboardFirstLifeKey),
				LongestLifeSeconds = GetLongKey(localPlayer, DataObjects.LeaderboardLongestLifeKey),
				TotalLifeSeconds = GetLongKey(localPlayer, DataObjects.LeaderboardTotalLifeKey),
				DeathCount = (int)GetLongKey(localPlayer, DataObjects.LeaderboardDeathCountKey),
				TotalDamage = num,
				BossKills = (int)stats[(PlayerStatType)85],
				TreeChops = (int)stats[(PlayerStatType)27],
				Mines = (int)stats[(PlayerStatType)38],
				CraftsAndBuilds = (int)(stats[(PlayerStatType)1] + stats[(PlayerStatType)2])
			};
		}

		public static IEnumerator SyncLoop()
		{
			yield return (object)new WaitForSeconds(60f);
			while (true)
			{
				float num = Mathf.Max(60f, ValConfig.LeaderboardSyncInterval.Value * 60f);
				if (ValConfig.EnableLeaderboard.Value && (Object)(object)ZNet.instance != (Object)null)
				{
					try
					{
						if (ZNet.instance.IsServer())
						{
							if ((Object)(object)Player.m_localPlayer != (Object)null)
							{
								SendLocalSnapshotToServer();
							}
							BroadcastFullBoard();
						}
						else if ((Object)(object)Player.m_localPlayer != (Object)null)
						{
							SendLocalSnapshotToServer();
						}
					}
					catch (Exception arg)
					{
						Logger.LogWarning($"Leaderboard sync tick failed: {arg}");
					}
				}
				yield return (object)new WaitForSeconds(num);
			}
		}

		private static long GetLongKey(Player player, string key)
		{
			string s = default(string);
			if (player.TryGetUniqueKeyValue(key, ref s) && long.TryParse(s, out var result))
			{
				return result;
			}
			return 0L;
		}

		private static void SetLongKey(Player player, string key, long value)
		{
			player.PlayerRemoveUniqueKey(key);
			player.AddUniqueKeyValue(key, value.ToString());
		}
	}
	public static class LeaderboardUI
	{
		[HarmonyPatch(typeof(TextsDialog), "ShowText", new Type[] { typeof(TextInfo) })]
		public static class TextsDialog_ShowText_Leaderboard_Patch
		{
			public static void Postfix(TextsDialog __instance, TextInfo text)
			{
				bool flag = text != null && text.m_topic == DeathlinkSettingsTopic;
				if (!ValConfig.EnableLeaderboard.Value || !flag)
				{
					if ((Object)(object)leaderboardButton != (Object)null)
					{
						leaderboardButton.SetActive(false);
					}
					return;
				}
				EnsureLeaderboardButton(__instance);
				if ((Object)(object)leaderboardButton != (Object)null)
				{
					leaderboardButton.SetActive(true);
					leaderboardButton.transform.SetAsLastSibling();
				}
			}

			private static void EnsureLeaderboardButton(TextsDialog dialog)
			{
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Expected O, but got Unknown
				if ((Object)(object)leaderboardButton != (Object)null)
				{
					return;
				}
				if (GUIManager.Instance == null)
				{
					Logger.LogWarning("GUIManager not setup, skipping leaderboard button creation.");
					return;
				}
				Transform val = ((Component)dialog).transform.Find("Texts_frame/Closebutton");
				if (!((Object)(object)val == (Object)null))
				{
					leaderboardButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$leaderboard"), val, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-250f, 0f), 200f, 40f);
					((UnityEvent)leaderboardButton.GetComponent<Button>().onClick).AddListener(new UnityAction(Show));
				}
			}
		}

		[HarmonyPatch(typeof(TextsDialog), "OnClose")]
		public static class TextsDialog_OnClose_Leaderboard_Patch
		{
			public static void Postfix()
			{
				Hide();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class InventoryGui_Hide_Leaderboard_Patch
		{
			public static void Postfix()
			{
				Hide();
			}
		}

		private const int ViewSurvival = 0;

		private const int ViewCombat = 1;

		private const int ViewGathering = 2;

		private static GameObject panel;

		private static GameObject content;

		private static readonly List<GameObject> rows = new List<GameObject>();

		private static readonly Text[] headerCols = (Text[])(object)new Text[5];

		private static int currentView = 0;

		private const float RowWidth = 820f;

		private const float RowHeight = 30f;

		private static readonly (float x, float w)[] columns = new(float, float)[5]
		{
			(-310f, 200f),
			(-135f, 150f),
			(25f, 150f),
			(185f, 150f),
			(340f, 140f)
		};

		private static GameObject leaderboardButton;

		public static bool IsVisible
		{
			get
			{
				if ((Object)(object)panel != (Object)null)
				{
					return panel.activeSelf;
				}
				return false;
			}
		}

		private static string DeathlinkSettingsTopic => Localization.instance.Localize("$deathlink_settings");

		public static void Show()
		{
			if (EnsurePanel())
			{
				panel.SetActive(true);
				PopulateView(currentView);
				LeaderboardData.RequestDashboardSync();
			}
		}

		public static void Hide()
		{
			if ((Object)(object)panel != (Object)null)
			{
				panel.SetActive(false);
			}
		}

		public static void RefreshIfVisible()
		{
			if (IsVisible)
			{
				PopulateView(currentView);
			}
		}

		private static bool EnsurePanel()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)panel != (Object)null)
			{
				return true;
			}
			if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				Logger.LogWarning("GUIManager not setup, skipping leaderboard panel creation.");
				return false;
			}
			panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 900f, 680f, true);
			panel.SetActive(false);
			GUIManager.Instance.CreateText(Localization.instance.Localize("$leaderboard"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 290f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 500f, 40f, false);
			((UnityEvent)GUIManager.Instance.CreateButton(Localization.instance.Localize("$close"), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(420f, 300f), 50f, 50f).GetComponent<Button>().onClick).AddListener(new UnityAction(Hide));
			CreateViewButton("$leaderboard_survival", -230f, 0);
			CreateViewButton("$leaderboard_combat", 0f, 1);
			CreateViewButton("$leaderboard_gathering", 230f, 2);
			for (int i = 0; i < headerCols.Length; i++)
			{
				headerCols[i] = CreateText(panel, new Vector2(columns[i].x, 200f), columns[i].w, "", GUIManager.Instance.ValheimOrange, 18);
			}
			GameObject obj = GUIManager.Instance.CreateScrollView(panel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 860f, 440f);
			obj.transform.localPosition = Vector2.op_Implicit(new Vector2(0f, -70f));
			obj.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f;
			content = ((Component)obj.GetComponentInChildren<ContentSizeFitter>()).gameObject;
			VerticalLayoutGroup val = content.GetComponent<VerticalLayoutGroup>();
			if ((Object)(object)val == (Object)null)
			{
				val = content.AddComponent<VerticalLayoutGroup>();
			}
			((LayoutGroup)val).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)val).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val).spacing = 2f;
			return true;
		}

		private static void CreateViewButton(string locKey, float x, int view)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			((UnityEvent)GUIManager.Instance.CreateButton(Localization.instance.Localize(locKey), panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(x, 240f), 200f, 44f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				PopulateView(view);
			});
		}

		public static void PopulateView(int view)
		{
			currentView = view;
			if (!EnsurePanel())
			{
				return;
			}
			foreach (GameObject row in rows)
			{
				if ((Object)(object)row != (Object)null)
				{
					Object.Destroy((Object)(object)row);
				}
			}
			rows.Clear();
			SetHeaderLabels(view);
			foreach (DataObjects.LeaderboardEntry item in view switch
			{
				1 => from e in LeaderboardData.leaderboard.Values
					orderby e.BossKills descending, e.TotalDamage descending
					select e, 
				2 => LeaderboardData.leaderboard.Values.OrderByDescending((DataObjects.LeaderboardEntry e) => e.TreeChops + e.Mines + e.CraftsAndBuilds), 
				_ => LeaderboardData.leaderboard.Values.OrderByDescending((DataObjects.LeaderboardEntry e) => e.LongestLifeSeconds), 
			})
			{
				rows.Add(CreateRow(item, view));
			}
		}

		private static void SetHeaderLabels(int view)
		{
			string[] array = view switch
			{
				1 => new string[5] { "$lb_col_player", "$lb_col_choice", "$lb_damage", "$lb_bosses", "" }, 
				2 => new string[5] { "$lb_col_player", "$lb_col_choice", "$lb_trees", "$lb_mining", "$lb_crafts" }, 
				_ => new string[5] { "$lb_col_player", "$lb_col_choice", "$lb_first", "$lb_longest", "$lb_average" }, 
			};
			for (int i = 0; i < headerCols.Length; i++)
			{
				headerCols[i].text = (string.IsNullOrEmpty(array[i]) ? "" : Localization.instance.Localize(array[i]));
			}
		}

		private static GameObject CreateRow(DataObjects.LeaderboardEntry entry, int view)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LBRow", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val.transform.SetParent(content.transform, false);
			((RectTransform)val.transform).sizeDelta = new Vector2(820f, 30f);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.preferredHeight = 30f;
			component.minHeight = 30f;
			component.preferredWidth = 820f;
			CreateText(val, new Vector2(columns[0].x, 0f), columns[0].w, entry.PlayerName ?? "", GUIManager.Instance.ValheimYellow, 16);
			CreateText(val, new Vector2(columns[1].x, 0f), columns[1].w, entry.DeathChoice ?? "", Color.white, 16);
			switch (view)
			{
			case 1:
				CreateText(val, new Vector2(columns[2].x, 0f), columns[2].w, Mathf.RoundToInt(entry.TotalDamage).ToString("N0"), Color.white, 16);
				CreateText(val, new Vector2(columns[3].x, 0f), columns[3].w, entry.BossKills.ToString(), Color.white, 16);
				break;
			case 2:
				CreateText(val, new Vector2(columns[2].x, 0f), columns[2].w, entry.TreeChops.ToString(), Color.white, 16);
				CreateText(val, new Vector2(columns[3].x, 0f), columns[3].w, entry.Mines.ToString(), Color.white, 16);
				CreateText(val, new Vector2(columns[4].x, 0f), columns[4].w, entry.CraftsAndBuilds.ToString(), Color.white, 16);
				break;
			default:
				CreateText(val, new Vector2(columns[2].x, 0f), columns[2].w, FormatMinutes(entry.FirstLifeSeconds), Color.white, 16);
				CreateText(val, new Vector2(columns[3].x, 0f), columns[3].w, FormatMinutes(entry.LongestLif