Decompiled source of Deathlink v0.8.3

plugins/Deathlink.dll

Decompiled 36 minutes 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 AzuEPI;
using AzuEPI.Core.Slots;
using AzuExtendedPlayerInventory;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Deathlink.Common;
using Deathlink.Death;
using Deathlink.external;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SimpleJson;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

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

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

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

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

		private static MethodInfo eCountItemsInBackpacks;

		private static MethodInfo eAddItemToBackpack;

		private static MethodInfo eDeleteItemsFromBackpacks;

		private static MethodInfo eGetEquippedBackpackInventory;

		private static MethodInfo eGetAllBackpackInventories;

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

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

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

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

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

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

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

		public delegate void SlotRemovedHandler(string slotName);

		[CompilerGenerated]
		private sealed class <EnumerateSlots>d__55 : IEnumerable<SlotDescriptor>, IEnumerable, IEnumerator<SlotDescriptor>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private SlotDescriptor <>2__current;

			private int <>l__initialThreadId;

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

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

			[DebuggerHidden]
			public <EnumerateSlots>d__55(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<SlotDescriptor> IEnumerable<SlotDescriptor>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <EnumerateSlots>d__55(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<SlotDescriptor>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetAllSlotSnapshots>d__56 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private SlotSnapshot <>2__current;

			private int <>l__initialThreadId;

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

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

			[DebuggerHidden]
			public <GetAllSlotSnapshots>d__56(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetAllSlotSnapshots>d__56(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<SlotSnapshot>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetEquipmentSlotSnapshots>d__58 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private SlotSnapshot <>2__current;

			private int <>l__initialThreadId;

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

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

			[DebuggerHidden]
			public <GetEquipmentSlotSnapshots>d__58(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetEquipmentSlotSnapshots>d__58(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<SlotSnapshot>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetQuickSlotSnapshots>d__57 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private SlotSnapshot <>2__current;

			private int <>l__initialThreadId;

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

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

			[DebuggerHidden]
			public <GetQuickSlotSnapshots>d__57(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetQuickSlotSnapshots>d__57(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<SlotSnapshot>)this).GetEnumerator();
			}
		}

		internal static HashSet<Model.EquipmentSlot?> CustomSlots { get; } = new HashSet<Model.EquipmentSlot>();


		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 Action? OnBeforeQuickSlotsAdded;

		public static event Action? OnQuickSlotsAdded;

		public static event SlotAddedHandler? SlotAdded;

		public static event SlotRemovedHandler? SlotRemoved;

		public static event Action<string>? OnRegisterVisualPrefab;

		public static bool IsLoaded()
		{
			return false;
		}

		public static ItemType GetFakeItemType()
		{
			return (ItemType)0;
		}

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

		public static bool AddSlot(string slotName, string prefabName, int index = -1)
		{
			return false;
		}

		public static bool AddSlot(string slotName, IEnumerable<string> prefabNames, int index = -1)
		{
			return false;
		}

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

		public static bool AddQuickSlot(string slotName, bool showName = false, int index = -1)
		{
			return false;
		}

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

		public static SlotInfo GetSlots()
		{
			return BuildSlotInfo((Model.Slot _) => true);
		}

		public static SlotInfo GetQuickSlots()
		{
			return BuildSlotInfo((Model.Slot s) => s.IsQuickSlot);
		}

		public static SlotInfo GetEquipmentSlots()
		{
			return BuildSlotInfo((Model.Slot s) => !s.IsQuickSlot && s.EquipmentSlot != null);
		}

		private static SlotInfo BuildSlotInfo(Func<Model.Slot, bool> filter)
		{
			return new SlotInfo();
		}

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

		public static int GetAddedRows(int width)
		{
			return 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetFullHeight(int width)
		{
			return 0;
		}

		public static void RegisterVisualPrefabs(string slotName, params (string prefabName, string visualName)[] pairs)
		{
		}

		public static int GetSlotCount()
		{
			return 0;
		}

		public static bool TryGetSlotIndexByName(string slotName, out int index, bool allowLocalized = true)
		{
			index = -1;
			return false;
		}

		public static bool TryGetSlotDescriptor(int index, out SlotDescriptor desc)
		{
			desc = default(SlotDescriptor);
			return false;
		}

		public static int GetSlotGridLinearIndex(Inventory inv, int slotIndex)
		{
			return -1;
		}

		public static Vector2i GetSlotGridPos(Inventory inv, int slotIndex)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2i(-1, -1);
		}

		public static bool TryGetSlotIndexAtGridPos(Inventory inv, Vector2i gridPos, out int slotIndex)
		{
			slotIndex = -1;
			return false;
		}

		public static bool IsEquipmentCell(Inventory inv, int x, int y, out int slotIndex)
		{
			slotIndex = -1;
			return false;
		}

		public static bool IsQuickCell(Inventory inv, int x, int y, out int slotIndex)
		{
			slotIndex = -1;
			return false;
		}

		public static bool TryGetSlotSnapshot(Inventory inv, int slotIndex, out SlotSnapshot snapshot)
		{
			snapshot = default(SlotSnapshot);
			return false;
		}

		[IteratorStateMachine(typeof(<EnumerateSlots>d__55))]
		public static IEnumerable<SlotDescriptor> EnumerateSlots()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnumerateSlots>d__55(-2);
		}

		[IteratorStateMachine(typeof(<GetAllSlotSnapshots>d__56))]
		public static IEnumerable<SlotSnapshot> GetAllSlotSnapshots(Inventory inv)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllSlotSnapshots>d__56(-2);
		}

		[IteratorStateMachine(typeof(<GetQuickSlotSnapshots>d__57))]
		public static IEnumerable<SlotSnapshot> GetQuickSlotSnapshots(Inventory inv)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetQuickSlotSnapshots>d__57(-2);
		}

		[IteratorStateMachine(typeof(<GetEquipmentSlotSnapshots>d__58))]
		public static IEnumerable<SlotSnapshot> GetEquipmentSlotSnapshots(Inventory inv)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetEquipmentSlotSnapshots>d__58(-2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool TryGetSlotIndexByItem(Player player, ItemData item, out int slotIndex)
		{
			slotIndex = -1;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool TryGetSlotIndexByItem(ItemData item, out int slotIndex)
		{
			slotIndex = -1;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool TryGetSlotDescriptorByItem(Player player, ItemData item, out SlotDescriptor desc)
		{
			desc = default(SlotDescriptor);
			return false;
		}

		public static bool SlotValidates(int slotIndex, ItemData item)
		{
			return false;
		}

		public static bool TryGetEquippedItem(int slotIndex, out ItemData? item)
		{
			item = null;
			return false;
		}

		public static bool TryGetSlotDescriptorByName(string slotName, out SlotDescriptor desc, bool allowLocalized = true)
		{
			desc = default(SlotDescriptor);
			if (TryGetSlotIndexByName(slotName, out var index, allowLocalized))
			{
				return TryGetSlotDescriptor(index, out desc);
			}
			return false;
		}
	}
	[PublicAPI]
	public struct SlotDescriptor
	{
		public int Index { get; }

		public string Name { get; }

		public string OriginalName { get; }

		public bool IsQuickSlot { get; }

		public bool IsEquipmentSlot { get; }

		public bool IsCustom { get; }

		public Vector2 UiPosition { get; }

		public SlotDescriptor(int index, string name, string originalName, bool isQuickSlot, bool isEquipmentSlot, bool isCustom, Vector2 uiPosition)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Index = index;
			Name = name ?? string.Empty;
			OriginalName = originalName ?? string.Empty;
			IsQuickSlot = isQuickSlot;
			IsEquipmentSlot = isEquipmentSlot;
			IsCustom = isCustom;
			UiPosition = uiPosition;
		}
	}
	[PublicAPI]
	public class SlotInfo
	{
		public string[] SlotNames { get; set; } = Array.Empty<string>();


		public string[] OriginalSlotNames { get; set; } = Array.Empty<string>();


		public Vector2[] SlotPositions { get; set; } = Array.Empty<Vector2>();


		public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = Array.Empty<Func<Player, ItemData>>();


		public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = Array.Empty<Func<ItemData, bool>>();

	}
	[PublicAPI]
	public struct SlotSnapshot
	{
		public SlotDescriptor Descriptor { get; }

		public bool Occupied { get; }

		public Vector2i GridPos { get; }

		public int LinearGridIndex { get; }

		public SlotSnapshot(SlotDescriptor descriptor, bool occupied, Vector2i gridPos, int linearGridIndex)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Descriptor = descriptor;
			Occupied = occupied;
			GridPos = gridPos;
			LinearGridIndex = linearGridIndex;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool Validates(ItemData item)
		{
			return API.SlotValidates(Descriptor.Index, item);
		}
	}
}
namespace AzuEPI.Core.Slots
{
	public class Model
	{
		internal class Slot
		{
			public string Name;

			public string OriginalName;

			public Vector2 Position;

			public bool IsQuickSlot;

			public bool IsAPIAdded;

			public bool Occupied;

			public EquipmentSlot? EquipmentSlot => this as EquipmentSlot;
		}

		internal class EquipmentSlot : Slot
		{
			public Func<Player, ItemData?>? Get;

			public Func<ItemData, bool>? Valid;
		}
	}
}
namespace AzuExtendedPlayerInventory
{
	[PublicAPI]
	public class API
	{
		public delegate void SlotAddedHandler(string slotName);

		public delegate void SlotRemovedHandler(string slotName);

		private static readonly Dictionary<SlotAddedHandler, AzuEPI.API.SlotAddedHandler> _slotAddedMap = new Dictionary<SlotAddedHandler, AzuEPI.API.SlotAddedHandler>();

		private static readonly Dictionary<SlotRemovedHandler, AzuEPI.API.SlotRemovedHandler> _slotRemovedMap = new Dictionary<SlotRemovedHandler, AzuEPI.API.SlotRemovedHandler>();

		private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudAwakeMap = new Dictionary<Action<Hud>, Action<Hud>>();

		private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudAwakeCompleteMap = new Dictionary<Action<Hud>, Action<Hud>>();

		private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudUpdateMap = new Dictionary<Action<Hud>, Action<Hud>>();

		private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudUpdateCompleteMap = new Dictionary<Action<Hud>, Action<Hud>>();

		public static event SlotAddedHandler? SlotAdded
		{
			add
			{
				SlotAddedHandler value2 = value;
				if (value2 == null || _slotAddedMap.ContainsKey(value2))
				{
					return;
				}
				AzuEPI.API.SlotAddedHandler value3 = delegate(string s)
				{
					try
					{
						value2(s);
					}
					catch
					{
					}
				};
				_slotAddedMap[value2] = value3;
				AzuEPI.API.SlotAdded += value3;
			}
			remove
			{
				if (value != null && _slotAddedMap.TryGetValue(value, out AzuEPI.API.SlotAddedHandler value2))
				{
					AzuEPI.API.SlotAdded -= value2;
					_slotAddedMap.Remove(value);
				}
			}
		}

		public static event SlotRemovedHandler? SlotRemoved
		{
			add
			{
				SlotRemovedHandler value2 = value;
				if (value2 == null || _slotRemovedMap.ContainsKey(value2))
				{
					return;
				}
				AzuEPI.API.SlotRemovedHandler value3 = delegate(string s)
				{
					try
					{
						value2(s);
					}
					catch
					{
					}
				};
				_slotRemovedMap[value2] = value3;
				AzuEPI.API.SlotRemoved += value3;
			}
			remove
			{
				if (value != null && _slotRemovedMap.TryGetValue(value, out AzuEPI.API.SlotRemovedHandler value2))
				{
					AzuEPI.API.SlotRemoved -= value2;
					_slotRemovedMap.Remove(value);
				}
			}
		}

		public static event Action<Hud>? OnHudAwake
		{
			add
			{
				AddHudEvent(value, _hudAwakeMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudAwake += h;
				});
			}
			remove
			{
				RemoveHudEvent(value, _hudAwakeMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudAwake -= h;
				});
			}
		}

		public static event Action<Hud>? OnHudAwakeComplete
		{
			add
			{
				AddHudEvent(value, _hudAwakeCompleteMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudAwakeComplete += h;
				});
			}
			remove
			{
				RemoveHudEvent(value, _hudAwakeCompleteMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudAwakeComplete -= h;
				});
			}
		}

		public static event Action<Hud>? OnHudUpdate
		{
			add
			{
				AddHudEvent(value, _hudUpdateMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudUpdate += h;
				});
			}
			remove
			{
				RemoveHudEvent(value, _hudUpdateMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudUpdate -= h;
				});
			}
		}

		public static event Action<Hud>? OnHudUpdateComplete
		{
			add
			{
				AddHudEvent(value, _hudUpdateCompleteMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudUpdateComplete += h;
				});
			}
			remove
			{
				RemoveHudEvent(value, _hudUpdateCompleteMap, delegate(Action<Hud> h)
				{
					AzuEPI.API.OnHudUpdateComplete -= h;
				});
			}
		}

		private static void AddHudEvent(Action<Hud>? handler, Dictionary<Action<Hud>, Action<Hud>> map, Action<Action<Hud>> subscribe)
		{
			Action<Hud> handler2 = handler;
			if (handler2 == null || map.ContainsKey(handler2))
			{
				return;
			}
			Action<Hud> value = delegate(Hud h)
			{
				try
				{
					handler2(h);
				}
				catch
				{
				}
			};
			map[handler2] = value;
		}

		private static void RemoveHudEvent(Action<Hud>? handler, Dictionary<Action<Hud>, Action<Hud>> map, Action<Action<Hud>> unsubscribe)
		{
			if (handler != null && map.TryGetValue(handler, out Action<Hud> _))
			{
				map.Remove(handler);
			}
		}

		public static bool IsLoaded()
		{
			return AzuEPI.API.IsLoaded();
		}

		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 AzuEPI.API.RemoveSlot(slotName);
		}

		public static SlotInfo GetSlots()
		{
			AzuEPI.SlotInfo slots = AzuEPI.API.GetSlots();
			return new SlotInfo
			{
				SlotNames = (slots.SlotNames ?? Array.Empty<string>()),
				SlotPositions = (slots.SlotPositions ?? Array.Empty<Vector2>()),
				GetItemFuncs = (slots.GetItemFuncs ?? Array.Empty<Func<Player, ItemData>>()),
				IsValidFuncs = (slots.IsValidFuncs ?? Array.Empty<Func<ItemData, bool>>())
			};
		}

		public static SlotInfo GetQuickSlots()
		{
			AzuEPI.SlotInfo quickSlots = AzuEPI.API.GetQuickSlots();
			return new SlotInfo
			{
				SlotNames = (quickSlots.SlotNames ?? Array.Empty<string>()),
				SlotPositions = (quickSlots.SlotPositions ?? Array.Empty<Vector2>()),
				GetItemFuncs = (quickSlots.GetItemFuncs ?? Array.Empty<Func<Player, ItemData>>()),
				IsValidFuncs = (quickSlots.IsValidFuncs ?? Array.Empty<Func<ItemData, bool>>())
			};
		}

		public static List<ItemData> GetQuickSlotsItems()
		{
			return AzuEPI.API.GetQuickSlotsItems();
		}

		public static int GetAddedRows(int width)
		{
			return AzuEPI.API.GetAddedRows(width);
		}

		public static void HudAwake(Hud h)
		{
		}

		public static void HudAwakeComplete(Hud h)
		{
		}

		public static void HudUpdate(Hud h)
		{
		}

		public static void HudUpdateComplete(Hud h)
		{
		}

		private static void SafeInvoke(Action a)
		{
			try
			{
				a();
			}
			catch
			{
			}
		}
	}
	[PublicAPI]
	public class SlotInfo
	{
		public string[] SlotNames { get; set; } = Array.Empty<string>();


		public Vector2[] SlotPositions { get; set; } = Array.Empty<Vector2>();


		public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = Array.Empty<Func<Player, ItemData>>();


		public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = Array.Empty<Func<ItemData, bool>>();

	}
}
namespace AlmanacClasses.API
{
	public static class ClassesAPI
	{
		private static readonly MethodInfo? API_AddExperience;

		private static readonly MethodInfo? API_GetLevel;

		private static readonly MethodInfo? API_GetCharacteristic;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public const string PluginName = "Deathlink";

		public const string PluginVersion = "0.8.3";

		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 (AzuExtendedPlayerInventory.API.IsLoaded())
			{
				AzuEPILoaded = true;
			}
			if (BepInExUtils.GetPlugins(false).Keys.Contains("WackyMole.EpicMMOSystem"))
			{
				EpicMMOSystem_API.Init();
				if (EpicMMOSystem_API.state == EpicMMOSystem_API.API_State.Ready)
				{
					WackyMMOLoaded = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API loaded.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API installed but API not ready.");
				}
			}
			if (BepInExUtils.GetPlugins(false).Keys.Contains("RustyMods.AlmanacClasses"))
			{
				RustyAlmanacClassesLoaded = true;
			}
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			DeathConfigurationData.Init();
			TerminalCommands.AddCommands();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Death is not the end.");
		}

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

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

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

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

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

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

		public static API_State state;

		private static MethodInfo eGetLevel;

		private static MethodInfo eAddExp;

		private static MethodInfo eGetAttribute;

		private static MethodInfo eGetAttributeRusty;

		private static MethodInfo eSetSingleRate;

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

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

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

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

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

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

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

		private static string specialColor = "#ffa64d";
	}
	public static class DeathChoiceEnable
	{
		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class ShowDeathChoiceUI
		{
			public static void Postfix(InventoryGui __instance)
			{
				if (ValConfig.UsePrivateKeysForDeathChoice.Value)
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey))
					{
						return;
					}
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null && DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID()))
				{
					return;
				}
				if ((Object)(object)((Component)__instance).gameObject.GetComponent<DeathChoices.DeathChoiceUI>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<DeathChoices.DeathChoiceUI>();
				}
				DeathChoices.DeathChoiceUI.Instance.Show();
			}
		}

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

			private static GameObject DeathChoicePanel;

			private static GameObject ChoicesScrollView;

			private static GameObject ChoicesContent;

			private static GameObject ChoicesContainer;

			private static GameObject manualCloseButton;

			private static GameObject selectChoiceButton;

			private static Text DeathPenaltyDescription;

			private static Text XPModifiersDescription;

			private static Text LootModifersDescription;

			private static Text HarvestModifiersDescription;

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

			private static ToggleGroup choiceGroup;

			private static string selectedDeathChoice = "none";

			public static DeathChoiceUI Instance => _instance ?? (_instance = new DeathChoiceUI());

			public void Awake()
			{
				CreateStaticUIObjects();
				SetChoiceList();
			}

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

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

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

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

			private void CreateStaticUIObjects()
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_020d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0217: Expected O, but got Unknown
				//IL_024a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0259: Unknown result type (might be due to invalid IL or missing references)
				//IL_0268: Unknown result type (might be due to invalid IL or missing references)
				//IL_027e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0284: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_02da: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0300: Unknown result type (might be due to invalid IL or missing references)
				//IL_0369: Unknown result type (might be due to invalid IL or missing references)
				//IL_0378: Unknown result type (might be due to invalid IL or missing references)
				//IL_0387: Unknown result type (might be due to invalid IL or missing references)
				//IL_039d: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0408: Unknown result type (might be due to invalid IL or missing references)
				//IL_0419: Unknown result type (might be due to invalid IL or missing references)
				//IL_041f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0488: Unknown result type (might be due to invalid IL or missing references)
				//IL_0497: Unknown result type (might be due to invalid IL or missing references)
				//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0509: Unknown result type (might be due to invalid IL or missing references)
				//IL_0518: Unknown result type (might be due to invalid IL or missing references)
				//IL_0527: Unknown result type (might be due to invalid IL or missing references)
				//IL_0538: Unknown result type (might be due to invalid IL or missing references)
				//IL_053e: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_05db: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0628: Unknown result type (might be due to invalid IL or missing references)
				//IL_0637: Unknown result type (might be due to invalid IL or missing references)
				//IL_0646: Unknown result type (might be due to invalid IL or missing references)
				//IL_0657: Unknown result type (might be due to invalid IL or missing references)
				//IL_065d: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_06e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0713: Unknown result type (might be due to invalid IL or missing references)
				//IL_071d: Expected O, but got Unknown
				//IL_0747: Unknown result type (might be due to invalid IL or missing references)
				//IL_074c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0771: Unknown result type (might be due to invalid IL or missing references)
				//IL_078f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0790: Unknown result type (might be due to invalid IL or missing references)
				//IL_07e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_07f4: Expected O, but got Unknown
				//IL_0825: Unknown result type (might be due to invalid IL or missing references)
				//IL_087c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0881: Unknown result type (might be due to invalid IL or missing references)
				//IL_08da: Unknown result type (might be due to invalid IL or missing references)
				//IL_08e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_090e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0914: Unknown result type (might be due to invalid IL or missing references)
				if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
				{
					Logger.LogWarning("GUIManager not setup, skipping static object creation.");
					return;
				}
				Logger.LogDebug("Creating static UI");
				DeathChoicePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 800f, true);
				DeathChoicePanel.SetActive(false);
				((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 360f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false)).name = "DLHeader";
				Text component = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 315f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 560f, 60f, false).GetComponent<Text>();
				component.resizeTextForBestFit = true;
				component.resizeTextMaxSize = 20;
				component.alignment = (TextAnchor)4;
				manualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$close"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(360f, 360f), 60f, 60f);
				Button component2 = manualCloseButton.GetComponent<Button>();
				((Selectable)component2).interactable = true;
				((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide));
				manualCloseButton.SetActive(true);
				((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 220f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "DeathPenaltyTitle";
				GameObject obj = GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, 110f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 500f, 200f, false);
				((Object)obj).name = "DeathPenaltyDesc";
				DeathPenaltyDescription = obj.GetComponent<Text>();
				DeathPenaltyDescription.resizeTextForBestFit = true;
				DeathPenaltyDescription.resizeTextMaxSize = 18;
				((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 30f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "xpModifiersTitle";
				GameObject obj2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_mod_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
				((Object)obj2).name = "xpModifiersDesc";
				XPModifiersDescription = obj2.GetComponent<Text>();
				XPModifiersDescription.resizeTextForBestFit = true;
				XPModifiersDescription.resizeTextMaxSize = 18;
				((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -130f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "lootModifiersTitle";
				GameObject obj3 = GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -240f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
				((Object)obj3).name = "lootModifersDesc";
				LootModifersDescription = obj3.GetComponent<Text>();
				LootModifersDescription.resizeTextForBestFit = true;
				LootModifersDescription.resizeTextMaxSize = 18;
				((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -260f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "harvestModifiersTitle";
				GameObject obj4 = GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -370f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
				((Object)obj4).name = "harvestModifersDesc";
				HarvestModifiersDescription = obj4.GetComponent<Text>();
				HarvestModifiersDescription.resizeTextForBestFit = true;
				HarvestModifiersDescription.resizeTextMaxSize = 18;
				selectChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$deathchoice_select"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-240f, -290f), 200f, 80f);
				((UnityEvent)selectChoiceButton.GetComponent<Button>().onClick).AddListener(new UnityAction(MakePlayerDeathSelection));
				Logger.LogDebug("Setting up scroll entry");
				ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 250f, 400f);
				ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2
				{
					x = -260f,
					y = -30f
				});
				ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject;
				ChoicesScrollView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f;
				choiceGroup = ChoicesContent.AddComponent<ToggleGroup>();
				Logger.LogDebug("Setting up death choice template entry");
				ChoicesContainer = Object.Instantiate<GameObject>(new GameObject("DeathChoice"), DeathChoicePanel.transform);
				RectTransform obj5 = ChoicesContainer.AddComponent<RectTransform>();
				obj5.SetSizeWithCurrentAnchors((Axis)0, 100f);
				obj5.SetSizeWithCurrentAnchors((Axis)1, 50f);
				((Transform)obj5).position = new Vector3(0f, 0f);
				ChoicesContainer.AddComponent<LayoutElement>().minHeight = 50f;
				ChoicesContainer.SetActive(false);
				GameObject obj6 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f);
				obj6.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f));
				((Object)obj6).name = "selecter";
				((Component)obj6.transform.Find("Label")).gameObject.SetActive(false);
				obj6.GetComponent<Toggle>().isOn = false;
				((Object)GUIManager.Instance.CreateText("Name", ChoicesContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 0f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false)).name = "ChoiceName";
			}
		}
	}
	public static class DeathProgressionSkill
	{
		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		public class Deathskill_EXP_Patch
		{
			public static void Postfix(Player __instance)
			{
				//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
				timeSinceGameStart += Time.deltaTime;
				if (lastSkillIncreaseTickTime == 0f)
				{
					lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value;
					PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
					_bossKills = playerProfile.m_playerStats.m_stats[(PlayerStatType)85];
					_enemykills = playerProfile.m_playerStats.m_stats[(PlayerStatType)6];
					_piecesBuilt = playerProfile.m_playerStats.m_stats[(PlayerStatType)2];
					_treesChopped = playerProfile.m_playerStats.m_stats[(PlayerStatType)27];
					_mineAmount = playerProfile.m_playerStats.m_stats[(PlayerStatType)38];
					_craftAndUpgrades = playerProfile.m_playerStats.m_stats[(PlayerStatType)1];
				}
				if (timeSinceGameStart > lastSkillIncreaseTickTime)
				{
					lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value;
					PlayerProfile playerProfile2 = Game.instance.GetPlayerProfile();
					float num = playerProfile2.m_playerStats.m_stats[(PlayerStatType)85];
					float num2 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)6];
					float num3 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)2];
					float num4 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)27];
					float num5 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)38];
					float num6 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)1];
					float num7 = 0f;
					float num8 = 0f;
					float num9 = 0f;
					float num10 = 0f;
					float num11 = 0f;
					float num12 = 0f;
					if (num > _bossKills || num2 > _enemykills)
					{
						num12 = (num - _bossKills) * ValConfig.SkillGainOnBossKills.Value;
						num11 = (num2 - _enemykills) * ValConfig.SkillGainOnKills.Value;
						Logger.LogDebug($"DeathProgression kill skill bosskill: {num12} kill: {num11}");
						_bossKills = num;
						_enemykills = num2;
					}
					if (num3 > _piecesBuilt)
					{
						num10 = (num3 - _piecesBuilt) * ValConfig.SkillGainOnBuilding.Value;
						Logger.LogDebug($"DeathProgression building skill: {num10}");
						_piecesBuilt = num3;
					}
					if (num4 > _treesChopped || num5 > _mineAmount)
					{
						num9 = (num4 - _treesChopped) * ValConfig.SkillGainOnResourceGathering.Value;
						num8 = (num5 - _mineAmount) * ValConfig.SkillGainOnResourceGathering.Value;
						Logger.LogDebug($"DeathProgression harvesting skill tree_harvest: {num9} mining: {num8}");
						_treesChopped = num4;
						_mineAmount = num5;
					}
					if (num6 > _craftAndUpgrades)
					{
						num7 = (num6 - _craftAndUpgrades) * ValConfig.SkillGainOnCrafts.Value;
						Logger.LogDebug($"DeathProgression crafting skill crafting: {num7}");
						_craftAndUpgrades = num6;
					}
					float num13 = num12 + num11 + num10 + num10 + num9 + num8 + num7;
					float num14 = (float)Math.Log(__instance.m_timeSinceDeath) / 5f * 0.5f;
					float num15 = num14 * num13;
					if (Deathlink.RustyAlmanacClassesLoaded)
					{
						int num16 = Mathf.RoundToInt(num15 * ValConfig.AlmanacClassesXPGainScale.Value);
						Logger.LogDebug($"Almanac XP Gain {num16}");
						ClassesAPI.AddEXP(num16);
					}
					if (Deathlink.WackyMMOLoaded)
					{
						int num17 = Mathf.RoundToInt(num15 * ValConfig.WackyMMOXPGainScale.Value);
						Logger.LogDebug($"WackyMMO XP Gain {num17}");
						EpicMMOSystem_API.AddExp(num17);
					}
					Logger.LogDebug($"DeathProgression skill bonus from survival (survive time: {__instance.m_timeSinceDeath}) {num14} x {num13} = {num15}");
					((Character)Player.m_localPlayer).RaiseSkill(DeathSkill, num15);
				}
			}
		}

		public static SkillType DeathSkill;

		private static float lastSkillIncreaseTickTime;

		private static float timeSinceGameStart;

		private static float _bossKills;

		private static float _enemykills;

		private static float _piecesBuilt;

		private static float _mineAmount;

		private static float _treesChopped;

		private static float _craftAndUpgrades;

		public static void SetupDeathSkill()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			SkillConfig val = new SkillConfig();
			val.Name = LocalizationManager.Instance.TryTranslate("$death_skill");
			val.Description = LocalizationManager.Instance.TryTranslate("$death_skill_description");
			val.Icon = Deathlink.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/death_skill.png");
			val.Identifier = "midnightsfx.deathskill";
			val.IncreaseStep = 0.1f;
			DeathSkill = SkillManager.Instance.AddSkill(val);
			if (!SkillsChanges.skills_to_avoid_standard_death_penalty.Contains(DeathSkill))
			{
				SkillsChanges.skills_to_avoid_standard_death_penalty.Add(DeathSkill);
			}
		}

		public static float DeathSkillCalculatePercentWithBonus(float bonus = 0f, float min = 0.01f, float max = 1f)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(DeathSkill);
				num += skillFactor;
			}
			num += bonus;
			if (num < min)
			{
				num = min;
			}
			if (num > max)
			{
				num = max;
			}
			return num;
		}
	}
	public static class HarvestModifiers
	{
		[HarmonyPatch(typeof(TreeLog), "Destroy")]
		public static class IncreaseDropsFromTree
		{
			private static void Postfix(TreeLog __instance, HitData hitData)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hitData != null && (Object)(object)Player.m_localPlayer != (Object)null && hitData.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
				{
					IncreaseDrops(__instance.m_dropWhenDestroyed, ((Component)__instance).transform.position);
				}
			}
		}

		[HarmonyPatch(typeof(Pickable), "Drop")]
		public static class IncreaseDropsPickable
		{
			private static void Prefix(Pickable __instance, GameObject prefab, int offset)
			{
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				if (Deathlink.pcfg().ResourceModifiers == null || Deathlink.pcfg().ResourceModifiers.Count <= 0 || !((Object)(object)Player.m_localPlayer != (Object)null))
				{
					return;
				}
				float num = Deathlink.pcfg().GetResouceEarlyCache(prefab.gameObject) - 1f;
				int num2 = 0;
				while (num > 0f)
				{
					float value = Random.value;
					Logger.LogDebug($"Checking to increase drops {value} <= {num}");
					if (value <= num)
					{
						num2++;
					}
					num -= 1f;
				}
				if (num2 > 0)
				{
					Vector2 val = Random.insideUnitCircle * 0.2f;
					Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset + new Vector3(val.x, 0.5f * (float)offset, val.y);
					Quaternion val3 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
					for (int i = 0; i < num2; i++)
					{
						Object.Instantiate<GameObject>(prefab, val2, val3);
					}
				}
			}
		}

		[HarmonyPatch(typeof(MineRock5), "RPC_SetAreaHealth")]
		public static class Minerock5DestroyPatch
		{
			private static void Postfix(MineRock5 __instance, long sender, int index, float health)
			{
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && (Object)(object)Player.m_localPlayer != (Object)null && health <= 0f)
				{
					IncreaseDrops(__instance.m_dropItems, ((Component)__instance).gameObject.transform.position);
				}
			}
		}

		[HarmonyPatch(typeof(Destructible), "Destroy")]
		public static class IncreaseDropsFromDestructible
		{
			private static void Prefix(Destructible __instance, HitData hit)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
				{
					IncreaseDestructibleDrops(__instance);
				}
			}

			public static void IncreaseDestructibleDrops(Destructible destructible)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)destructible.m_spawnWhenDestroyed != (Object)null))
				{
					Vector3 position = ((Component)destructible).transform.position;
					DropOnDestroyed component = ((Component)destructible).GetComponent<DropOnDestroyed>();
					if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null)
					{
						IncreaseDrops(component.m_dropWhenDestroyed, position);
					}
				}
			}
		}

		public static void IncreaseDrops(DropTable drops, Vector3 position)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
			List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollHarvestLoot();
			if (list2.Count > 0)
			{
				list.AddRange(list2);
			}
			int num = Random.Range(drops.m_dropMin, drops.m_dropMax);
			int num2 = drops.m_drops.Count;
			if (num == 0)
			{
				num = 1;
			}
			if (num2 == 0)
			{
				num2 = 1;
			}
			int num3 = Mathf.RoundToInt((float)(num / num2));
			foreach (DropData drop in drops.m_drops)
			{
				float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(drop.m_item);
				if (resouceEarlyCache != 1f)
				{
					int num4 = Mathf.RoundToInt((float)num3 * resouceEarlyCache);
					if (num4 > 0)
					{
						list.Add(new KeyValuePair<GameObject, int>(drop.m_item, num4));
					}
				}
			}
			if (list.Count <= 0)
			{
				return;
			}
			Logger.LogDebug("Deathlink drop increase.");
			foreach (KeyValuePair<GameObject, int> item in list)
			{
				Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
				int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
				int num5 = item.Value;
				if (num5 > maxStackSize)
				{
					int num6 = num5 / maxStackSize;
					for (int i = 0; i < num6; i++)
					{
						Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize;
						Logger.LogDebug($"Dropping {maxStackSize} of {((Object)item.Key).name} to the world.");
					}
					num5 -= maxStackSize * num6;
				}
				Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num5;
				Logger.LogDebug($"Dropping {num5} of {((Object)item.Key).name} to the world.");
			}
		}
	}
	public static class LootModifiers
	{
		[HarmonyPatch(typeof(CharacterDrop))]
		public static class CalculateLootByModifiers
		{
			[HarmonyPostfix]
			[HarmonyPatch("GenerateDropList")]
			private static void Postfix(List<KeyValuePair<GameObject, int>> __result, CharacterDrop __instance)
			{
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.m_character.m_localPlayerHasHit || Deathlink.pcfg().DeathLootModifiers == null || Deathlink.pcfg().DeathLootModifiers.Count == 0)
				{
					return;
				}
				List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
				foreach (KeyValuePair<GameObject, int> item in __result)
				{
					float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(((Object)item.Key).name);
					if (resouceEarlyCache == 1f)
					{
						list.Add(item);
						continue;
					}
					int num = Mathf.RoundToInt((float)item.Value * resouceEarlyCache);
					if (num >= 1)
					{
						list.Add(new KeyValuePair<GameObject, int>(item.Key, num));
					}
				}
				List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollKillLoot();
				if (list2.Count > 0)
				{
					foreach (KeyValuePair<GameObject, int> item2 in list2)
					{
						for (int i = 0; i < item2.Value; i++)
						{
							Object.Instantiate<GameObject>(item2.Key, ((Component)__instance).transform.position, Quaternion.identity);
						}
					}
				}
				__result = list;
			}
		}
	}
	public static class SkillsChanges
	{
		[HarmonyPatch(typeof(Skills), "OnDeath")]
		private static class OnDeath_Patch
		{
			private static bool Prefix(Skills __instance)
			{
				if (((Character)__instance.m_player).m_seman.HaveStatusEffect(SEMan.s_statusEffectSoftDeath))
				{
					return false;
				}
				if (Deathlink.pcfg().DeathStyle.skillLossOnDeath)
				{
					float num = Mathf.Lerp(Deathlink.pcfg().DeathStyle.maxSkillLossPercentage, Deathlink.pcfg().DeathStyle.minSkillLossPercentage, DeathProgressionSkill.DeathSkillCalculatePercentWithBonus());
					Logger.LogDebug($"{num}");
					LowerConfigurableSkills(__instance, num);
				}
				return false;
			}

			private static void LowerConfigurableSkills(Skills skills, float factor)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				foreach (KeyValuePair<SkillType, Skill> skillDatum in skills.m_skillData)
				{
					if (skills_to_avoid_standard_death_penalty.Contains(skillDatum.Key))
					{
						Logger.LogDebug($"Skipping lowering skill {skillDatum.Key} current level: {skillDatum.Value.m_level}");
						continue;
					}
					float num = skillDatum.Value.m_level * factor;
					Skill value = skillDatum.Value;
					value.m_level -= num;
					skillDatum.Value.m_accumulator = 0f;
				}
				if (Deathlink.RustyAlmanacClassesLoaded && ValConfig.EnableAlmanacClassesXPLossOnDeath.Value)
				{
					int level = ClassesAPI.GetLevel();
					int num2 = Mathf.RoundToInt((float)level * factor * 500f * ValConfig.AlmanacClassesXPLossScale.Value) * -1;
					Logger.LogDebug($"Almanac (lvl {level}) XP Loss: {num2}");
					ClassesAPI.AddEXP(num2);
				}
				if (Deathlink.WackyMMOLoaded && ValConfig.EnableWackyMMOXPLossOnDeath.Value)
				{
					int level2 = EpicMMOSystem_API.GetLevel();
					int num3 = Mathf.RoundToInt((float)level2 * factor * 500f * ValConfig.WackyMMOXPLossScale.Value) * -1;
					Logger.LogDebug($"WackyMMO (lvl {level2}) XP Loss: {num3}");
					EpicMMOSystem_API.AddExp(num3);
				}
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null);
				}
			}
		}

		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		private static class SkillRaisePatch
		{
			private static void Prefix(Skills __instance, SkillType skillType, float factor)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				float skillBonusLazyCache = Deathlink.pcfg().GetSkillBonusLazyCache(skillType);
				Logger.LogDebug($"{skillType} skillGain Modified {skillBonusLazyCache}");
				if (skillBonusLazyCache != 0f)
				{
					factor *= skillBonusLazyCache;
				}
			}
		}

		public static List<SkillType> skills_to_avoid_standard_death_penalty = new List<SkillType>();
	}
	public static class OnDeathChanges
	{
		[HarmonyPatch(typeof(Player))]
		public static class OnDeath_Tombstone_Patch
		{
			[HarmonyTranspiler]
			[HarmonyPatch("OnDeath")]
			private static IEnumerable<CodeInstruction> ConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Expected O, but got Unknown
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Expected O, but got Unknown
				CodeMatcher val = new CodeMatcher(instructions, generator);
				val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Player), "CreateTombStone", (Type[])null, (Type[])null), (string)null)
				}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<Player>>((Action<Player>)ModifyDeath) })
					.CreateLabelOffset(out var label, 4)
					.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Br, (object)label)
					})
					.ThrowIfNotMatch("Unable to patch Deathlink player death changes.", Array.Empty<CodeMatch>());
				return val.Instructions();
			}

			private static void ModifyDeath(Player __instance)
			{
				TombstoneOnDeath(__instance);
				FoodLossOnDeath(__instance);
			}

			public static void FoodLossOnDeath(Player instance)
			{
				if (!Deathlink.pcfg().DeathStyle.foodLossOnDeath)
				{
					return;
				}
				if (Deathlink.pcfg().DeathStyle.foodLossUsesDeathlink && instance.m_foods.Count > 0)
				{
					float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus();
					if (num >= 0.9f)
					{
						return;
					}
					if (num >= 0.6f && num < 0.9f)
					{
						instance.m_foods.Remove(instance.m_foods[0]);
					}
					else if (num > 0.3f && num < 0.6f)
					{
						instance.m_foods.Remove(instance.m_foods[0]);
						if (instance.m_foods.Count > 0)
						{
							instance.m_foods.Remove(instance.m_foods[0]);
						}
					}
					else
					{
						instance.m_foods.Clear();
					}
				}
				else
				{
					instance.m_foods.Clear();
				}
			}

			public static void TombstoneOnDeath(Player instance)
			{
				//IL_0366: Unknown result type (might be due to invalid IL or missing references)
				//IL_0376: Unknown result type (might be due to invalid IL or missing references)
				//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_04df: Unknown result type (might be due to invalid IL or missing references)
				//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
				List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems();
				List<ItemData> list = new List<ItemData>();
				List<ItemData> list2 = new List<ItemData>();
				Inventory inventory = ((Humanoid)instance).m_inventory;
				Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>();
				string[] source = ValConfig.ItemsNotSkillChecked.Value.Split(new char[1] { ',' });
				foreach (ItemData item in allItems)
				{
					if ((Object)(object)item.m_dropPrefab != (Object)null && source.Contains(((Object)item.m_dropPrefab).name))
					{
						list2.Add(item);
					}
					else
					{
						list.Add(item);
					}
				}
				switch (Deathlink.pcfg().DeathStyle.itemLossStyle)
				{
				case DataObjects.ItemLossStyle.None:
					Logger.LogDebug("No items destroyed on death.");
					dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemSaved, list);
					break;
				case DataObjects.ItemLossStyle.DestroyNonWeaponArmor:
					Logger.LogDebug("Destroying non Equipment items.");
					dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list.GetNotEquipment());
					dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, list.GetEquipment());
					foreach (ItemData item2 in list.GetNotEquipment())
					{
						((Humanoid)instance).m_inventory.RemoveItem(item2);
					}
					if (!Deathlink.AzuEPILoaded)
					{
						break;
					}
					Logger.LogDebug("AzuEPI| Removing non-equipment items from quickslots.");
					foreach (ItemData quickSlotsItem in AzuExtendedPlayerInventory.API.GetQuickSlotsItems())
					{
						if (!quickSlotsItem.IsEquipment())
						{
							((Humanoid)instance).m_inventory.RemoveItem(quickSlotsItem);
							dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, quickSlotsItem);
						}
						else
						{
							dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, quickSlotsItem);
						}
					}
					break;
				case DataObjects.ItemLossStyle.DestroyAll:
					Logger.LogDebug("Destroying all non skill checked items.");
					dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list);
					foreach (ItemData item3 in list)
					{
						((Humanoid)instance).m_inventory.RemoveItem(item3);
					}
					if (Deathlink.AzuEPILoaded)
					{
						Logger.LogDebug("AzuEPI| Destroying quickslot items.");
						dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, AzuExtendedPlayerInventory.API.GetQuickSlotsItems());
						AzuExtendedPlayerInventory.API.GetQuickSlotsItems().ForEach(delegate(ItemData item)
						{
							((Humanoid)instance).m_inventory.RemoveItem(item);
						});
					}
					break;
				case DataObjects.ItemLossStyle.DeathlinkBased:
					Logger.LogDebug("Destroying random items based on deathlink skill");
					dictionary = DetermineItemResultsByDeathlink(instance, list);
					dictionary[DataObjects.ItemResults.EquipmentLost].ForEach(delegate(ItemData item)
					{
						((Humanoid)instance).m_inventory.RemoveItem(item);
					});
					dictionary[DataObjects.ItemResults.ItemLost].ForEach(delegate(ItemData item)
					{
						((Humanoid)instance).m_inventory.RemoveItem(item);
					});
					break;
				}
				if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Destroy)
				{
					Logger.LogDebug("Non skill checked being destroyed.");
					dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list2);
				}
				if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Save)
				{
					Logger.LogDebug("Non skill checked items being left on player.");
				}
				if ((!dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) || dictionary[DataObjects.ItemResults.EquipmentSaved].Count <= 0) && (!dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) || dictionary[DataObjects.ItemResults.ItemSaved].Count <= 0) && (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction != DataObjects.NonSkillCheckedItemAction.Tombstone || list2.Count() <= 0))
				{
					return;
				}
				Logger.LogDebug("Tombstone needed");
				GameObject obj = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation);
				Inventory inventory2 = obj.GetComponent<Container>().GetInventory();
				if (Deathlink.pcfg().DeathStyle.itemSavedStyle == DataObjects.ItemSavedStyle.Tombstone)
				{
					Logger.LogDebug("Adding saved items to tombstone.");
					if (dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) && dictionary[DataObjects.ItemResults.EquipmentSaved].Count > 0)
					{
						AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.EquipmentSaved]);
						dictionary[DataObjects.ItemResults.EquipmentSaved].ForEach(delegate(ItemData item)
						{
							((Humanoid)instance).m_inventory.RemoveItem(item);
						});
					}
					if (dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) && dictionary[DataObjects.ItemResults.ItemSaved].Count > 0)
					{
						AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.ItemSaved]);
						dictionary[DataObjects.ItemResults.ItemSaved].ForEach(delegate(ItemData item)
						{
							((Humanoid)instance).m_inventory.RemoveItem(item);
						});
					}
				}
				if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Tombstone)
				{
					Logger.LogDebug("Adding saved non-skill checked items to tombstone.");
					AddItemsToTombstone(inventory2, list2);
					list2.ForEach(delegate(ItemData item)
					{
						((Humanoid)instance).m_inventory.RemoveItem(item);
					});
				}
				TombStone component = obj.GetComponent<TombStone>();
				PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
				string name = playerProfile.GetName();
				long playerID = playerProfile.GetPlayerID();
				component.Setup(name, playerID);
				inventory.Changed();
				if (ValConfig.ShowDeathMapMarker.Value)
				{
					Minimap.instance.AddPin(((Component)instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, default(PlatformUserID));
				}
			}

			public static void AddItemsToTombstone(Inventory tombstone, List<ItemData> transferItems)
			{
				int num = Mathf.RoundToInt(Mathf.Sqrt((float)transferItems.Count())) + 1;
				tombstone.m_width += num;
				tombstone.m_height += num;
				foreach (ItemData transferItem in transferItems)
				{
					tombstone.m_inventory.Add(transferItem);
				}
				tombstone.Changed();
			}

			internal static Dictionary<DataObjects.ItemResults, List<ItemData>> DetermineItemResultsByDeathlink(Player player, List<ItemData> playerItemsWithoutNonSkillCheckedItems)
			{
				float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus();
				int num2 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxItemsKept - Deathlink.pcfg().DeathStyle.minItemsKept) * num + (float)Deathlink.pcfg().DeathStyle.minItemsKept);
				int num3 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxEquipmentKept - Deathlink.pcfg().DeathStyle.minEquipmentKept) * num + (float)Deathlink.pcfg().DeathStyle.minEquipmentKept);
				int remainingsaves = num2 + num3;
				Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>
				{
					{
						DataObjects.ItemResults.EquipmentSaved,
						new List<ItemData>()
					},
					{
						DataObjects.ItemResults.EquipmentLost,
						new List<ItemData>()
					},
					{
						DataObjects.ItemResults.ItemSaved,
						new List<ItemData>()
					},
					{
						DataObjects.ItemResults.ItemLost,
						new List<ItemData>()
					}
				};
				int equipment_saved_count = 0;
				foreach (ItemData item in Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetEquipment()))
				{
					if (remainingsaves > 0)
					{
						if (RemoveEquipmentByStyle(equipment_saved_count, num3, item, remainingsaves, out remainingsaves, out equipment_saved_count))
						{
							Logger.LogDebug("Save: " + item.m_shared.m_name);
							dictionary[DataObjects.ItemResults.EquipmentSaved].Add(item);
						}
						else
						{
							Logger.LogDebug("Remove by style: " + item.m_shared.m_name);
							dictionary[DataObjects.ItemResults.EquipmentLost].Add(item);
						}
					}
					else
					{
						Logger.LogDebug("Save limit reached, removing: " + item.m_shared.m_name);
						dictionary[DataObjects.ItemResults.EquipmentLost].Add(item);
					}
				}
				if (Deathlink.AzuEPILoaded)
				{
					foreach (ItemData quickSlotsItem in AzuExtendedPlayerInventory.API.GetQuickSlotsItems())
					{
						if (quickSlotsItem.IsEquipment() && remainingsaves > 0)
						{
							remainingsaves--;
							num2--;
							dictionary[DataObjects.ItemResults.EquipmentSaved].Add(quickSlotsItem);
						}
						else if (remainingsaves > 0)
						{
							remainingsaves--;
							num2--;
							dictionary[DataObjects.ItemResults.ItemSaved].Add(quickSlotsItem);
						}
						else
						{
							dictionary[DataObjects.ItemResults.ItemLost].Add(quickSlotsItem);
						}
					}
				}
				List<ItemData> list = Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetNotEquipment());
				if (remainingsaves > 0)
				{
					foreach (ItemData item2 in list)
					{
						if (remainingsaves > 0 && num2 > 0)
						{
							Logger.LogDebug("NonEq| Saving: " + item2.m_shared.m_name);
							dictionary[DataObjects.ItemResults.ItemSaved].Add(item2);
							remainingsaves--;
							num2--;
						}
						else
						{
							Logger.LogDebug("NonEq| Removing: " + item2.m_shared.m_name);
							dictionary[DataObjects.ItemResults.ItemLost].Add(item2);
						}
					}
				}
				else
				{
					Logger.LogDebug($"NonEq| Removing: {list.Count} due to no saves remaining.");
					foreach (ItemData item3 in list)
					{
						dictionary[DataObjects.ItemResults.ItemLost].Add(item3);
					}
				}
				return dictionary;
			}

			internal static bool RemoveEquipmentByStyle(int equipment_saved, int max_equipment_savable, ItemData equipment, int numberOfItemsSavable, out int remainingsaves, out int equipment_saved_count)
			{
				equipment_saved_count = 0;
				remainingsaves = 0;
				if (numberOfItemsSavable <= 0)
				{
					return false;
				}
				if (equipment_saved >= max_equipment_savable)
				{
					Logger.LogDebug($"Max equipment retained ({max_equipment_savable}) reached, removing {((Object)equipment.m_dropPrefab).name}");
					return false;
				}
				Logger.LogDebug($"Saving equipment remaining savable?({numberOfItemsSavable}) {((Object)equipment.m_dropPrefab).name}");
				equipment_saved_count = equipment_saved + 1;
				remainingsaves = numberOfItemsSavable - 1;
				return true;
			}
		}
	}
}
namespace Deathlink.Common
{
	internal static class TerminalCommands
	{
		internal class ResetPlayerDeathChoice : ConsoleCommand
		{
			public override string Name => "DL-RESET-CHOICE";

			public override bool IsNetwork => true;

			public override string Help => "Format: [steamID|playerName] resets the deathlink choice for the target player. Accepts a platform Steam ID or a case-insensitive player name.";

			public override void Run(string[] args)
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: 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)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Expected O, but got Unknown
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				if (!SynchronizationManager.Instance.PlayerIsAdmin)
				{
					Logger.LogWarning("You are not an admin, and not allowed to run this command.");
					return;
				}
				if (args.Length < 1)
				{
					Logger.LogInfo("Player Steam ID or name required");
					return;
				}
				string text = args[0];
				bool flag = false;
				foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
				{
					string text2 = player.m_userInfo.m_id.m_userID.ToString();
					string displayName = player.m_userInfo.m_displayName;
					bool flag2 = text2 == text;
					bool flag3 = string.Equals(displayName, text, StringComparison.OrdinalIgnoreCase);
					Logger.LogDebug("Checking Player " + displayName + " (platformID: " + text2 + ") against '" + text + "'");
					if (flag2 || flag3)
					{
						ZPackage val = new ZPackage();
						val.Write(text2);
						Logger.LogDebug("Requesting server reset of player saved Deathlink choice");
						ValConfig.resetChoiceRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val);
						Logger.LogDebug("Checking for " + player.m_name + " peer");
						ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(player.m_name);
						if (peerByPlayerName == null)
						{
							Logger.LogWarning("Player " + displayName + " found in player list but has no active peer.");
							break;
						}
						ValConfig.resetChoiceRPC.SendPackage(peerByPlayerName.m_uid, val);
						Logger.LogInfo($"Matched player {player.m_name}|{displayName} (platformID: {text2}, peerUID: {peerByPlayerName.m_uid})");
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					Logger.LogInfo("Player could not be found, are they online?");
				}
			}
		}

		internal static void AddCommands()
		{
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ResetPlayerDeathChoice());
		}
	}
	public class DataObjects
	{
		public enum ItemLossStyle
		{
			None,
			DestroyNonWeaponArmor,
			DeathlinkBased,
			DestroyAll
		}

		public enum ItemResults
		{
			EquipmentSaved,
			EquipmentLost,
			ItemSaved,
			ItemLost
		}

		public enum ItemSavedStyle
		{
			OnCharacter,
			Tombstone
		}

		public enum ResourceGainTypes
		{
			Kills,
			Harvesting
		}

		public enum NonSkillCheckedItemAction
		{
			Destroy,
			Tombstone,
			Save
		}

		public class DeathProgressionDetails
		{
			public bool foodLossOnDeath = true;

			public bool foodLossUsesDeathlink = true;

			public int minItemsKept;

			public int maxItemsKept;

			public int minEquipmentKept;

			public int maxEquipmentKept;

			public bool skillLossOnDeath = true;

			public float maxSkillLossPercentage;

			public float minSkillLossPercentage;

			public ItemLossStyle itemLossStyle;

			public ItemSavedStyle itemSavedStyle;

			public NonSkillCheckedItemAction nonSkillCheckedItemAction = NonSkillCheckedItemAction.Tombstone;
		}

		public class DeathResourceModifier
		{
			public bool skillInfluence { get; set; } = true;


			public List<string> prefabs { get; set; }

			public float bonusModifer { get; set; }

			public List<ResourceGainTypes> bonusActions { get; set; }
		}

		public class DeathSkillModifier
		{
			public bool skillInfluence { get; set; } = true;


			public SkillType skill { get; set; }

			public float bonusModifer { get; set; }
		}

		public class DeathLootModifier
		{
			private bool skillInfluence { get; set; } = true;


			public string prefab { get; set; }

			public float chance { get; set; }

			public int amount { get; set; } = 1;


			public List<ResourceGainTypes> bonusActions { get; set; }
		}

		public class DeathChoiceLevel
		{
			private Dictionary<SkillType, float> CalculatedSkillMods = new Dictionary<SkillType, float>();

			private Dictionary<string, float> CalculatedResourceMods = new Dictionary<string, float>();

			private bool CalculatedResourceModsCached;

			private Dictionary<GameObject, Tuple<float, int>> KillLootModifiers = new Dictionary<GameObject, Tuple<float, int>>();

			private bool CalculatedKillLootModifiersCached;

			private Dictionary<GameObject, Tuple<float, int>> ResourceLootModifiers = new Dictionary<GameObject, Tuple<float, int>>();

			private bool CalculatedHarvestLootModifiersCached;

			public string DisplayName { get; set; }

			public DeathProgressionDetails DeathStyle { get; set; }

			public float DeathSkillRate { get; set; } = 1f;


			public Dictionary<string, DeathResourceModifier> ResourceModifiers { get; set; }

			public Dictionary<string, DeathSkillModifier> SkillModifiers { get; set; }

			public Dictionary<string, DeathLootModifier> DeathLootModifiers { get; set; }

			public List<KeyValuePair<GameObject, int>> RollKillLoot()
			{
				if (!CalculatedKillLootModifiersCached)
				{
					if (DeathLootModifiers != null && DeathLootModifiers.Count > 0)
					{
						foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers)
						{
							if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Kills))
							{
								GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab);
								if ((Object)(object)prefab == (Object)null)
								{
									Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building kill loot table, it will be skipped.");
								}
								else
								{
									KillLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount));
								}
							}
						}
					}
					CalculatedKillLootModifiersCached = true;
				}
				List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
				foreach (KeyValuePair<GameObject, Tuple<float, int>> killLootModifier in KillLootModifiers)
				{
					float value = Random.value;
					Logger.LogDebug($"Rolling chance loot for: {((Object)killLootModifier.Key.gameObject).name} {value} < {killLootModifier.Value.Item1}");
					if (value < killLootModifier.Value.Item1)
					{
						list.Add(new KeyValuePair<GameObject, int>(killLootModifier.Key, killLootModifier.Value.Item2));
					}
				}
				return list;
			}

			public List<KeyValuePair<GameObject, int>> RollHarvestLoot()
			{
				if (!CalculatedHarvestLootModifiersCached)
				{
					if (DeathLootModifiers != null && DeathLootModifiers.Count > 0)
					{
						foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers)
						{
							if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Harvesting))
							{
								GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab);
								if ((Object)(object)prefab == (Object)null)
								{
									Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building harvest loot table, it will be skipped.");
								}
								else
								{
									ResourceLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount));
								}
							}
						}
					}
					CalculatedHarvestLootModifiersCached = true;
				}
				List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
				foreach (KeyValuePair<GameObject, Tuple<float, int>> resourceLootModifier in ResourceLootModifiers)
				{
					if (Random.value < resourceLootModifier.Value.Item1)
					{
						list.Add(new KeyValuePair<GameObject, int>(resourceLootModifier.Key, resourceLootModifier.Value.Item2));
					}
				}
				return list;
			}

			public float GetResouceEarlyCache(string prefab)
			{
				if (!CalculatedResourceModsCached)
				{
					Logger.LogDebug("Building cache entry for " + prefab);
					if (ResourceModifiers != null)
					{
						foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers)
						{
							if (resourceModifier.Value.prefabs == null)
							{
								continue;
							}
							foreach (string prefab2 in resourceModifier.Value.prefabs)
							{
								Logger.LogDebug($"Building cache entry for {prefab2} - {resourceModifier.Value.bonusModifer}");
								CalculatedResourceMods.Add(prefab2, resourceModifier.Value.bonusModifer);
							}
						}
					}
					CalculatedResourceModsCached = true;
				}
				if (CalculatedResourceMods.ContainsKey(prefab))
				{
					return CalculatedResourceMods[prefab];
				}
				return 1f;
			}

			public float GetResouceEarlyCache(GameObject prefab)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					return 1f;
				}
				return GetResouceEarlyCache(((Object)prefab).name);
			}

			public float GetSkillBonusLazyCache(SkillType skilltype)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Invalid comparison between Unknown and I4
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				if (CalculatedSkillMod