Decompiled source of Deathlink v0.3.4

plugins/Deathlink.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security.Permissions;
using AzuExtendedPlayerInventory;
using BepInEx;
using BepInEx.Configuration;
using Deathlink.Common;
using Deathlink.Death;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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 Deathlink
{
	public static class Extensions
	{
		private static readonly List<ItemType> EquipmentTypes = new List<ItemType>
		{
			(ItemType)7,
			(ItemType)12,
			(ItemType)6,
			(ItemType)11,
			(ItemType)4,
			(ItemType)5,
			(ItemType)19,
			(ItemType)17,
			(ItemType)18,
			(ItemType)3,
			(ItemType)14,
			(ItemType)22,
			(ItemType)20
		};

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

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

		public static bool IsEquipment(this ItemData item)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (EquipmentTypes.Contains(item.m_shared.m_itemType))
			{
				return true;
			}
			return false;
		}
	}
	[BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.3.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*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.3.4";

		public ValConfig cfg;

		internal static AssetBundle EmbeddedResourceBundle;

		internal static DeathSkillContainment Player_death_skill_monitor;

		internal static bool AzuEPILoaded = false;

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

		private void Awake()
		{
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Deathlink.AssetsEmbedded.deathless", typeof(Deathlink).Assembly);
			DeathProgressionSkill.SetupDeathSkill();
			Player_death_skill_monitor = new DeathSkillContainment();
			if (API.IsLoaded())
			{
				AzuEPILoaded = true;
			}
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Logger.LogInfo((object)"Death is not the end.");
		}

		public static List<T> shuffleList<T>(List<T> inputList)
		{
			int i = 0;
			int count = inputList.Count;
			int num = 0;
			T val = default(T);
			List<T> list = new List<T>();
			list.AddRange(inputList);
			for (; i < count; i++)
			{
				num = Random.Range(i, list.Count);
				val = list[i];
				list[i] = list[num];
				list[num] = val;
			}
			return list;
		}
	}
}
namespace Deathlink.Death
{
	public static class DeathProgressionSkill
	{
		[HarmonyPatch(typeof(Player), "RaiseSkill")]
		public class Deathskill_EXP_Patch
		{
			public static void Postfix(Player __instance)
			{
				//IL_036f: Unknown result type (might be due to invalid IL or missing references)
				timeSinceGameStart += Time.deltaTime;
				if (lastSkillIncreaseTickTime == 0f)
				{
					Deathlink.Player_death_skill_monitor.Setup();
					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];
				}
				Logger.LogDebug((object)$"DeathSkill increase interval check: {timeSinceGameStart} > {lastSkillIncreaseTickTime}");
				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((object)$"DeathProgression kill skill bosskill: {num12} kill: {num11}");
						_bossKills = num;
						_enemykills = num2;
					}
					if (num3 > _piecesBuilt)
					{
						num10 = (num3 - _piecesBuilt) * ValConfig.SkillGainOnBuilding.Value;
						Logger.LogDebug((object)$"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((object)$"DeathProgression harvesting skill tree_harvest: {num9} mining: {num8}");
						_treesChopped = num4;
						_mineAmount = num5;
					}
					if (num6 > _craftAndUpgrades)
					{
						num7 = (num6 - _craftAndUpgrades) * ValConfig.SkillGainOnCrafts.Value;
						Logger.LogDebug((object)$"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;
					Logger.LogDebug((object)$"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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			SkillConfig val = new SkillConfig();
			val.Name = "Deathlink";
			val.Description = "How apt you are at avoiding loss from death.";
			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);
		}

		public static float DeathSkillCalculatePercentWithBonus(float bonus = 0f, float min = 0.1f, 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 * ValConfig.DeathSkillPerLevelBonus.Value;
			}
			num += bonus;
			if (num < min)
			{
				num = min;
			}
			if (num > max)
			{
				num = max;
			}
			return num;
		}
	}
	public class DeathSkillContainment
	{
		public DataObjects.DictionaryZNetProperty PlayerSkillGains;

		public void Setup()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				Logger.LogWarning((object)"Death skill setup failed due to player instance not being available.");
			}
			else if (PlayerSkillGains == null)
			{
				Dictionary<SkillType, float> defaultValue = new Dictionary<SkillType, float>();
				PlayerSkillGains = new DataObjects.DictionaryZNetProperty("PlayerSkillGains", ((Component)Player.m_localPlayer).GetComponent<ZNetView>(), defaultValue);
			}
		}

		public void AddSkillIncrease(SkillType skill, float value)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (PlayerSkillGains != null)
			{
				Dictionary<SkillType, float> dictionary = PlayerSkillGains.Get();
				if (PlayerSkillGains.Get().ContainsKey(skill))
				{
					dictionary[skill] += value;
				}
				else
				{
					dictionary.Add(skill, value);
				}
				PlayerSkillGains.Set(dictionary);
			}
		}

		public Dictionary<SkillType, float> GetSkillGains()
		{
			if (PlayerSkillGains == null)
			{
				return new Dictionary<SkillType, float>();
			}
			return PlayerSkillGains.Get();
		}

		public void Clear()
		{
			if (PlayerSkillGains != null)
			{
				PlayerSkillGains.Set(new Dictionary<SkillType, float>());
			}
		}

		public bool ContainsKey(SkillType skill)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return PlayerSkillGains.Get().ContainsKey(skill);
		}
	}
	public static class SkillsChanges
	{
		[HarmonyPatch(typeof(Skills), "OnDeath")]
		private static class OnDeath_Patch
		{
			private static bool Prefix(Skills __instance)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				if (ValConfig.OnlyXPLossFromSkillGains.Value)
				{
					foreach (KeyValuePair<SkillType, float> skillGain in skillGainMonitor.GetSkillGains())
					{
						float num = skillGain.Value * ValConfig.GainedSkillLossFactor.Value;
						Skill obj = __instance.m_skillData[skillGain.Key];
						obj.m_level -= num;
					}
					skillGainMonitor.Clear();
				}
				else
				{
					__instance.LowerAllSkills(ValConfig.GainedSkillLossFactor.Value);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		private static class SkillRaisePatch
		{
			private static void Postfix(Skills __instance, SkillType skillType, float factor)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				skillGainMonitor.AddSkillIncrease(skillType, factor);
			}
		}

		private static DeathSkillContainment skillGainMonitor = new DeathSkillContainment();
	}
	public static class OnDeathChanges
	{
		[HarmonyPatch(typeof(Player), "OnDeath")]
		private static class OnDeath_Tombstone_Patch
		{
			private static bool Prefix(Player __instance)
			{
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				if (!((Character)__instance).m_nview.IsOwner())
				{
					Debug.Log((object)"OnDeath call but not the owner");
					return false;
				}
				bool flag = __instance.HardDeath();
				((Character)__instance).m_nview.GetZDO().Set(ZDOVars.s_dead, true);
				((Character)__instance).m_nview.InvokeRPC(ZNetView.Everybody, "OnDeath", Array.Empty<object>());
				Game.instance.IncrementPlayerStat((PlayerStatType)0, 1f);
				OnDeathStat(__instance);
				Game.instance.GetPlayerProfile().SetDeathPoint(((Component)__instance).transform.position);
				__instance.CreateDeathEffects();
				TombstoneOnDeath(__instance);
				FoodLossOnDeath(__instance);
				if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)17))
				{
					__instance.m_skills.Clear();
				}
				else if (flag)
				{
					__instance.m_skills.OnDeath();
				}
				((Character)__instance).m_seman.RemoveAllStatusEffects(false);
				Game.instance.RequestRespawn(10f, true);
				__instance.m_timeSinceDeath = 0f;
				if (!flag)
				{
					((Character)__instance).Message((MessageType)1, "$msg_softdeath", 0, (Sprite)null);
				}
				((Character)__instance).Message((MessageType)2, "$msg_youdied", 0, (Sprite)null);
				__instance.ShowTutorial("death", false);
				if (ValConfig.ShowDeathMapMarker.Value)
				{
					Minimap.instance.AddPin(((Component)__instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, "");
				}
				if (((Character)__instance).m_onDeath != null)
				{
					((Character)__instance).m_onDeath();
				}
				Biome currentBiome = __instance.GetCurrentBiome();
				string text = "biome:" + ((object)(Biome)(ref currentBiome)).ToString();
				Gogan.LogEvent("Game", "Death", text, 0L);
				return false;
			}

			public static void FoodLossOnDeath(Player instance)
			{
				if (!ValConfig.FoodLossOnDeath.Value)
				{
					return;
				}
				if (ValConfig.FoodLossOnDeathBySkillLevel.Value)
				{
					float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus();
					if (!(num >= 0.9f))
					{
						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]);
							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_04f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
				List<ItemData> list = new List<ItemData>();
				new List<ItemData>();
				List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems();
				List<ItemData> list2 = new List<ItemData>();
				List<ItemData> list3 = new List<ItemData>();
				string[] source = ValConfig.ItemsNotSkillChecked.Value.Split(new char[1] { ',' });
				foreach (ItemData item in allItems)
				{
					if (source.Contains(((Object)item.m_dropPrefab).name))
					{
						list2.Add(item);
					}
					else
					{
						list3.Add(item);
					}
				}
				int num = (int)((float)allItems.Count * DeathProgressionSkill.DeathSkillCalculatePercentWithBonus()) + ValConfig.MinimumEquipmentRetainedOnDeath.Value;
				Logger.LogDebug((object)$"Player number of items {allItems.Count}, savable due to skill {num}");
				if (ValConfig.MaxPercentTotalItemsRetainedOnDeath.Value > (float)num / (float)allItems.Count)
				{
					num = (int)((float)allItems.Count * (ValConfig.MaxPercentTotalItemsRetainedOnDeath.Value / 100f));
					Logger.LogDebug((object)$"Number of items savable reduced due to configured max ({ValConfig.MaxPercentTotalItemsRetainedOnDeath.Value}%) now: {num}");
				}
				if (Deathlink.AzuEPILoaded)
				{
					foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems())
					{
						if (source.Contains(quickSlotsItem.m_shared.m_name))
						{
							list2.Add(quickSlotsItem);
						}
						else
						{
							list3.Add(quickSlotsItem);
						}
					}
				}
				List<ItemData> list4 = Deathlink.shuffleList(list3.GetEquipment());
				int num2 = 0;
				if (list4.Count <= num)
				{
					foreach (ItemData item2 in list4)
					{
						if (num2 >= ValConfig.MaximumEquipmentRetainedOnDeath.Value)
						{
							Logger.LogDebug((object)$"Max equipment retained ({ValConfig.MaximumEquipmentRetainedOnDeath.Value}) reached, deleting {((Object)item2.m_dropPrefab).name}");
							((Humanoid)instance).m_inventory.RemoveItem(item2);
							continue;
						}
						Logger.LogDebug((object)("Saving equipment " + ((Object)item2.m_dropPrefab).name));
						if (item2.m_equipped)
						{
							num2++;
							continue;
						}
						list.Add(item2);
						num2++;
					}
					num -= list4.Count;
					if (num > 0)
					{
						List<ItemData> list5 = Deathlink.shuffleList(list3.GetNotEquipment());
						int num3 = (int)(ValConfig.MaxPercentResourcesRetainedOnDeath.Value * (float)list5.Count);
						foreach (ItemData item3 in list5)
						{
							if (num > 0 && num3 > 0)
							{
								Logger.LogDebug((object)("Saving " + ((Object)item3.m_dropPrefab).name));
								list.Add(item3);
								num--;
								num3--;
								continue;
							}
							break;
						}
					}
					((Humanoid)instance).m_inventory.RemoveUnequipped();
					if (Deathlink.AzuEPILoaded)
					{
						Logger.LogDebug((object)$"Quickslot items found {API.GetQuickSlotsItems().Count}");
						foreach (ItemData quickSlotsItem2 in API.GetQuickSlotsItems())
						{
							if (!list.Contains(quickSlotsItem2))
							{
								Logger.LogDebug((object)("Removing quickslot item that was not saved " + ((Object)quickSlotsItem2.m_dropPrefab).name));
								((Humanoid)instance).UnequipItem(quickSlotsItem2, true);
								((Humanoid)instance).m_inventory.RemoveItem(quickSlotsItem2);
							}
						}
					}
					switch (ValConfig.ItemsNotSkillCheckedAction.Value)
					{
					case "DropOnDeath":
					{
						Logger.LogDebug((object)"Dropping non-skill-checked items on death");
						foreach (ItemData item4 in list2)
						{
							((Humanoid)instance).m_inventory.AddItem(item4);
						}
						GameObject obj = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation);
						obj.GetComponent<Container>().GetInventory().MoveInventoryToGrave(((Humanoid)instance).m_inventory);
						TombStone component = obj.GetComponent<TombStone>();
						PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
						string name = playerProfile.GetName();
						long playerID = playerProfile.GetPlayerID();
						component.Setup(name, playerID);
						break;
					}
					case "AlwaysDestroy":
						Logger.LogDebug((object)"Destroying non-skill-checked items on death");
						break;
					case "AlwaysSave":
						Logger.LogDebug((object)"Saving non-skill-checked items on death");
						list.AddRange(list2);
						break;
					}
					foreach (ItemData item5 in list)
					{
						((Humanoid)instance).m_inventory.AddItem(item5);
					}
					if (ValConfig.ItemsSavedToTombstone.Value)
					{
						instance.CreateTombStone();
					}
					return;
				}
				foreach (ItemData item6 in list4)
				{
					if (num > 0)
					{
						if (num2 >= ValConfig.MaximumEquipmentRetainedOnDeath.Value)
						{
							Logger.LogDebug((object)$"Max equipment retained ({ValConfig.MaximumEquipmentRetainedOnDeath.Value}) reached, deleting {((Object)item6.m_dropPrefab).name}");
							((Humanoid)instance).m_inventory.RemoveItem(item6);
						}
						else
						{
							Logger.LogDebug((object)("Saving equipment " + ((Object)item6.m_dropPrefab).name));
							num--;
						}
					}
					else
					{
						((Humanoid)instance).m_inventory.RemoveItem(item6);
					}
				}
				((Humanoid)instance).m_inventory.RemoveUnequipped();
			}

			public static void OnDeathStat(Player instance)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected I4, but got Unknown
				HitType hitType = ((Character)instance).m_lastHit.m_hitType;
				switch ((int)hitType)
				{
				case 0:
					Game.instance.IncrementPlayerStat((PlayerStatType)55, 1f);
					break;
				case 1:
					Game.instance.IncrementPlayerStat((PlayerStatType)56, 1f);
					break;
				case 2:
					Game.instance.IncrementPlayerStat((PlayerStatType)57, 1f);
					break;
				case 3:
					Game.instance.IncrementPlayerStat((PlayerStatType)58, 1f);
					break;
				case 4:
					Game.instance.IncrementPlayerStat((PlayerStatType)59, 1f);
					break;
				case 5:
					Game.instance.IncrementPlayerStat((PlayerStatType)60, 1f);
					break;
				case 6:
					Game.instance.IncrementPlayerStat((PlayerStatType)61, 1f);
					break;
				case 7:
					Game.instance.IncrementPlayerStat((PlayerStatType)62, 1f);
					break;
				case 8:
					Game.instance.IncrementPlayerStat((PlayerStatType)64, 1f);
					break;
				case 9:
					Game.instance.IncrementPlayerStat((PlayerStatType)63, 1f);
					break;
				case 10:
					Game.instance.IncrementPlayerStat((PlayerStatType)65, 1f);
					break;
				case 11:
					Game.instance.IncrementPlayerStat((PlayerStatType)66, 1f);
					break;
				case 12:
					Game.instance.IncrementPlayerStat((PlayerStatType)67, 1f);
					break;
				case 13:
					Game.instance.IncrementPlayerStat((PlayerStatType)68, 1f);
					break;
				case 14:
					Game.instance.IncrementPlayerStat((PlayerStatType)69, 1f);
					break;
				case 15:
					Game.instance.IncrementPlayerStat((PlayerStatType)70, 1f);
					break;
				case 16:
					Game.instance.IncrementPlayerStat((PlayerStatType)71, 1f);
					break;
				case 17:
					Game.instance.IncrementPlayerStat((PlayerStatType)72, 1f);
					break;
				case 18:
					Game.instance.IncrementPlayerStat((PlayerStatType)73, 1f);
					break;
				default:
					ZLog.LogWarning((object)("Not implemented death type " + ((object)(HitType)(ref ((Character)instance).m_lastHit.m_hitType)).ToString()));
					break;
				}
			}
		}
	}
}
namespace Deathlink.Common
{
	public class DataObjects
	{
		public abstract class ZNetProperty<T>
		{
			protected readonly ZNetView zNetView;

			public string Key { get; private set; }

			public T DefaultValue { get; private set; }

			protected ZNetProperty(string key, ZNetView zNetView, T defaultValue)
			{
				Key = key;
				DefaultValue = defaultValue;
				this.zNetView = zNetView;
			}

			private void ClaimOwnership()
			{
				if (!zNetView.IsOwner())
				{
					zNetView.ClaimOwnership();
				}
			}

			public void Set(T value)
			{
				SetValue(value);
			}

			public void ForceSet(T value)
			{
				ClaimOwnership();
				Set(value);
			}

			public abstract T Get();

			protected abstract void SetValue(T value);
		}

		public class BoolZNetProperty : ZNetProperty<bool>
		{
			public BoolZNetProperty(string key, ZNetView zNetView, bool defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}

			public override bool Get()
			{
				return zNetView.GetZDO().GetBool(base.Key, base.DefaultValue);
			}

			protected override void SetValue(bool value)
			{
				zNetView.GetZDO().Set(base.Key, value);
			}
		}

		public class IntZNetProperty : ZNetProperty<int>
		{
			public IntZNetProperty(string key, ZNetView zNetView, int defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}

			public override int Get()
			{
				return zNetView.GetZDO().GetInt(base.Key, base.DefaultValue);
			}

			protected override void SetValue(int value)
			{
				zNetView.GetZDO().Set(base.Key, value);
			}
		}

		public class StringZNetProperty : ZNetProperty<string>
		{
			public StringZNetProperty(string key, ZNetView zNetView, string defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}

			public override string Get()
			{
				return zNetView.GetZDO().GetString(base.Key, base.DefaultValue);
			}

			protected override void SetValue(string value)
			{
				zNetView.GetZDO().Set(base.Key, value);
			}
		}

		public class Vector3ZNetProperty : ZNetProperty<Vector3>
		{
			public Vector3ZNetProperty(string key, ZNetView zNetView, Vector3 defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}//IL_0003: Unknown result type (might be due to invalid IL or missing references)


			public override Vector3 Get()
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				return zNetView.GetZDO().GetVec3(base.Key, base.DefaultValue);
			}

			protected override void SetValue(Vector3 value)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				zNetView.GetZDO().Set(base.Key, value);
			}
		}

		public class DictionaryZNetProperty : ZNetProperty<Dictionary<SkillType, float>>
		{
			private BinaryFormatter binFormatter = new BinaryFormatter();

			public DictionaryZNetProperty(string key, ZNetView zNetView, Dictionary<SkillType, float> defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}

			public override Dictionary<SkillType, float> Get()
			{
				byte[] byteArray = zNetView.GetZDO().GetByteArray(base.Key, (byte[])null);
				if (byteArray == null)
				{
					return new Dictionary<SkillType, float>();
				}
				MemoryStream serializationStream = new MemoryStream(byteArray);
				return (Dictionary<SkillType, float>)binFormatter.Deserialize(serializationStream);
			}

			protected override void SetValue(Dictionary<SkillType, float> value)
			{
				MemoryStream memoryStream = new MemoryStream();
				binFormatter.Serialize(memoryStream, value);
				zNetView.GetZDO().Set(base.Key, memoryStream.ToArray());
			}

			public void UpdateDictionary()
			{
			}
		}

		public class ZDOIDZNetProperty : ZNetProperty<ZDOID>
		{
			public ZDOIDZNetProperty(string key, ZNetView zNetView, ZDOID defaultValue)
				: base(key, zNetView, defaultValue)
			{
			}//IL_0003: Unknown result type (might be due to invalid IL or missing references)


			public override ZDOID Get()
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				return zNetView.GetZDO().GetZDOID(base.Key);
			}

			protected override void SetValue(ZDOID value)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				zNetView.GetZDO().Set(base.Key, value);
			}
		}
	}
	public class ValConfig
	{
		public static ConfigFile cfg;

		public static ConfigEntry<bool> EnableDebugMode;

		public static ConfigEntry<string> ItemsNotSkillCheckedAction;

		public static ConfigEntry<string> ItemsNotSkillChecked;

		public static ConfigEntry<float> DeathSkillPerLevelBonus;

		public static ConfigEntry<int> MinimumEquipmentRetainedOnDeath;

		public static ConfigEntry<int> MaximumEquipmentRetainedOnDeath;

		public static ConfigEntry<float> MaxPercentResourcesRetainedOnDeath;

		public static ConfigEntry<float> MaxPercentTotalItemsRetainedOnDeath;

		public static ConfigEntry<float> GainedSkillLossFactor;

		public static ConfigEntry<bool> OnlyXPLossFromSkillGains;

		public static ConfigEntry<float> SkillGainOnKills;

		public static ConfigEntry<float> SkillGainOnBossKills;

		public static ConfigEntry<float> SkillGainOnCrafts;

		public static ConfigEntry<float> SkillGainOnResourceGathering;

		public static ConfigEntry<float> SkillGainOnBuilding;

		public static ConfigEntry<bool> FoodLossOnDeath;

		public static ConfigEntry<bool> FoodLossOnDeathBySkillLevel;

		public static ConfigEntry<bool> ShowDeathMapMarker;

		public static ConfigEntry<bool> ItemsSavedToTombstone;

		public static ConfigEntry<float> SkillProgressUpdateCheckInterval;

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

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Expected O, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Expected O, but got Unknown
			DeathSkillPerLevelBonus = BindServerConfig("DeathProgression", "DeathSkillPerLevelBonus", 1f, "How impactful death skill progression is. This impacts how much each level improves your skill and item retention.", advanced: false, 0f, 10f);
			MinimumEquipmentRetainedOnDeath = BindServerConfig("DeathProgression", "MinimumEquipmentRetainedOnDeath", 2, "The minimum amount of Equipment that can be retained on death, depends on players individual skill.", advanced: true, 0, 30);
			MaximumEquipmentRetainedOnDeath = BindServerConfig("DeathProgression", "MaximumEquipmentRetainedOnDeath", 10, "The maximum amount of Equipment that can be retained on death, depends on players individual skill.", advanced: true, 0, 30);
			MaxPercentResourcesRetainedOnDeath = BindServerConfig("DeathProgression", "MaxPercentResourcesRetainedOnDeath", 20f, "The maximum amount of Resources that can be retained on death, depends on players individual skill.", advanced: true, 0f, 100f);
			MaxPercentTotalItemsRetainedOnDeath = BindServerConfig("DeathProgression", "MaxPercentTotalItemsRetainedOnDeath", 90f, "The maximum amount of total items that can be retained on death, depends on players individual skill.", advanced: true, 0f, 100f);
			OnlyXPLossFromSkillGains = BindServerConfig("SkillLossModifiers", "OnlyXPLossFromSkillGains", value: true, "When enabled, you can only loose XP gained since the last death. Repeated deaths regardless of time without skill gains will not result in XP loss.");
			GainedSkillLossFactor = BindServerConfig("SkillLossModifiers", "GainedSkillLossFactor", 0.2f, "The percentage of skills that are lost when dying.", advanced: false, 0f, 1f);
			ItemsSavedToTombstone = BindServerConfig("DeathProgression", "ItemsSavedToTombstone", value: false, "Items are saved to your tombstone instead of saved to your character.");
			ItemsNotSkillChecked = BindServerConfig("DeathProgression", "ItemsNotSkillChecked", "Tin,TinOre,Copper,CopperOre,CopperScrap,Bronze,Iron,IronScrap,Silver,SilverOre,DragonEgg,chest_hildir1,chest_hildir2,chest_hildir3,BlackMetal,BlackMetalScrap,DvergrNeedle,MechanicalSpring,FlametalNew,FlametalOreNew", "List of items that are not rolled to be saved through death progression.");
			ItemsNotSkillCheckedAction = BindServerConfig("DeathProgression", "ItemsNotSkillCheckedAction", "dropOnDeath", "What happens to non-teleportable items. DropOnDeath = placed into a tombstone on death, AlwaysDestroy = never saved, AlwaysSave = These items are never destroyed and do not count towards save limits.", new AcceptableValueList<string>(new string[3] { "DropOnDeath", "AlwaysDestroy", "AlwaysSave" }));
			SkillGainOnKills = BindServerConfig("DeathSkillGain", "SkillGainOnKills", 0.05f, "Skill Gain from killing non-boss creatures.");
			SkillGainOnBossKills = BindServerConfig("DeathSkillGain", "SkillGainOnBossKills", 0.2f, "Skill Gain from killing boss creatures.");
			SkillGainOnCrafts = BindServerConfig("DeathSkillGain", "SkillGainOnCrafts", 0.08f, "Skill Gain from crafting.");
			SkillGainOnResourceGathering = BindServerConfig("DeathSkillGain", "SkillGainOnResourceGathering", 0.001f, "Skill Gain from resource gathering.");
			SkillGainOnBuilding = BindServerConfig("DeathSkillGain", "SkillGainOnBuilding", 0.005f, "Skill Gain from resource gathering.");
			SkillProgressUpdateCheckInterval = BindServerConfig("DeathSkillGain", "SkillProgressUpdateCheckInterval", 1f, "How frequently skill gains are computed and added. More frequently means smaller xp gains more often.", advanced: true, 0.1f, 5f);
			FoodLossOnDeath = BindServerConfig("DeathTweaks", "FoodLossOnDeath", value: true, "Whether or not dying will cause you to loose your current food.");
			FoodLossOnDeathBySkillLevel = BindServerConfig("DeathTweaks", "FoodLossOnDeathBySkillLevel", value: true, "Whether or not dying will cause you to loose your eaten foods based on skill level.");
			ShowDeathMapMarker = BindServerConfig("DeathTweaks", "ShowDeathMapMarker", value: true, "Whether or not a map marker is placed on your death location.");
			EnableDebugMode = Config.Bind<bool>("Client config", "EnableDebugMode", false, new ConfigDescription("Enables Debug logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdvanced = true
			} }));
		}

		public static ConfigEntry<bool> BindServerConfig(string catagory, string key, bool value, string description, AcceptableValueBase acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<bool>(catagory, key, value, new ConfigDescription(description, acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<int> BindServerConfig(string catagory, string key, int value, string description, bool advanced = false, int valmin = 0, int valmax = 150)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<int>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<float> BindServerConfig(string catagory, string key, float value, string description, bool advanced = false, float valmin = 0f, float valmax = 150f)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			return cfg.Bind<float>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(valmin, valmax), new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}

		public static ConfigEntry<string> BindServerConfig(string catagory, string key, string value, string description, AcceptableValueList<string> acceptableValues = null, bool advanced = false)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			return cfg.Bind<string>(catagory, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)acceptableValues, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true,
				IsAdvanced = advanced
			} }));
		}
	}
}
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 AzuExtendedPlayerInventory
{
	[PublicAPI]
	internal class API
	{
		public delegate void SlotAddedHandler(string slotName);

		public delegate void SlotRemovedHandler(string slotName);

		public static event Action<Hud>? OnHudAwake;

		public static event Action<Hud>? OnHudAwakeComplete;

		public static event Action<Hud>? OnHudUpdate;

		public static event Action<Hud>? OnHudUpdateComplete;

		public static event SlotAddedHandler? SlotAdded;

		public static event SlotRemovedHandler? SlotRemoved;

		public static bool IsLoaded()
		{
			return false;
		}

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

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

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

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

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

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


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


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


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

	}
}