Decompiled source of Deathlink v0.1.0

plugins/Deathlink.dll

Decompiled 5 hours 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 BepInEx;
using BepInEx.Configuration;
using Deathlink.Common;
using Deathlink.Death;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
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();
		}
	}
	[BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*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.1.0";

		public ValConfig cfg;

		internal static AssetBundle EmbeddedResourceBundle;

		internal static DeathSkillContainment Player_death_skill_monitor;

		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();
			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 TombstoneChanges
	{
		[HarmonyPatch(typeof(Player), "CreateTombStone")]
		private static class OnDeath_Tombstone_Patch
		{
			private static bool Prefix(Player __instance)
			{
				//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
				List<ItemData> list = 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(item.m_shared.m_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}");
				}
				List<ItemData> equipment = list3.GetEquipment();
				if (equipment.Count <= num)
				{
					foreach (ItemData item2 in equipment)
					{
						if (!item2.m_equipped)
						{
							list.Add(item2);
						}
					}
					num -= equipment.Count;
					if (num > 0)
					{
						List<ItemData> list4 = Deathlink.shuffleList(list3.GetNotEquipment());
						int num2 = (int)(ValConfig.MaxPercentResourcesRetainedOnDeath.Value * (float)list4.Count);
						foreach (ItemData item3 in list4)
						{
							if (num > 0 && num2 > 0)
							{
								list.Add(item3);
								num--;
								num2--;
								continue;
							}
							break;
						}
					}
					((Humanoid)__instance).m_inventory.RemoveUnequipped();
					switch (ValConfig.ItemsNotSkillCheckedAction.Value)
					{
					case "DropOnDeath":
					{
						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 "AlwaysSave":
						list.AddRange(list2);
						break;
					}
					foreach (ItemData item5 in list)
					{
						((Humanoid)__instance).m_inventory.AddItem(item5);
					}
					return false;
				}
				equipment = Deathlink.shuffleList(list3);
				foreach (ItemData item6 in equipment)
				{
					if (num > 0)
					{
						num--;
					}
					else
					{
						((Humanoid)__instance).UnequipItem(item6, true);
					}
				}
				((Humanoid)__instance).m_inventory.RemoveUnequipped();
				return false;
			}
		}
	}
}
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<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<float> SkillProgressUpdateCheckInterval;

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

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: 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);
			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);
			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", 1200f, "How frequently skill gains are computed and added. More frequently means smaller xp gains more often.", advanced: true, 0.1f, 100f);
			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
			} }));
		}
	}
}

plugins/ValRougelike.dll

Decompiled 5 hours 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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using ValRougelike.Common;
using ValRougelike.Death;

[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 ValRougelike
{
	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();
		}
	}
	[BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*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.1.0";

		public ValConfig cfg;

		internal static AssetBundle EmbeddedResourceBundle;

		internal static DeathSkillContainment Player_death_skill_monitor;

		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();
			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 ValRougelike.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 TombstoneChanges
	{
		[HarmonyPatch(typeof(Player), "CreateTombStone")]
		private static class OnDeath_Tombstone_Patch
		{
			private static bool Prefix(Player __instance)
			{
				//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
				List<ItemData> list = 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(item.m_shared.m_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}");
				}
				List<ItemData> equipment = list3.GetEquipment();
				if (equipment.Count <= num)
				{
					foreach (ItemData item2 in equipment)
					{
						if (!item2.m_equipped)
						{
							list.Add(item2);
						}
					}
					num -= equipment.Count;
					if (num > 0)
					{
						List<ItemData> list4 = Deathlink.shuffleList(list3.GetNotEquipment());
						int num2 = (int)(ValConfig.MaxPercentResourcesRetainedOnDeath.Value * (float)list4.Count);
						foreach (ItemData item3 in list4)
						{
							if (num > 0 && num2 > 0)
							{
								list.Add(item3);
								num--;
								num2--;
								continue;
							}
							break;
						}
					}
					((Humanoid)__instance).m_inventory.RemoveUnequipped();
					switch (ValConfig.ItemsNotSkillCheckedAction.Value)
					{
					case "DropOnDeath":
					{
						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 "AlwaysSave":
						list.AddRange(list2);
						break;
					}
					foreach (ItemData item5 in list)
					{
						((Humanoid)__instance).m_inventory.AddItem(item5);
					}
					return false;
				}
				equipment = Deathlink.shuffleList(list3);
				foreach (ItemData item6 in equipment)
				{
					if (num > 0)
					{
						num--;
					}
					else
					{
						((Humanoid)__instance).UnequipItem(item6, true);
					}
				}
				((Humanoid)__instance).m_inventory.RemoveUnequipped();
				return false;
			}
		}
	}
}
namespace ValRougelike.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<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<float> SkillProgressUpdateCheckInterval;

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

		private void CreateConfigValues(ConfigFile Config)
		{
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: 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);
			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);
			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", 1200f, "How frequently skill gains are computed and added. More frequently means smaller xp gains more often.", advanced: true, 0.1f, 100f);
			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
			} }));
		}
	}
}