Decompiled source of Death Tweaks v1.2.0

DeathTweaks.dll

Decompiled a year ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AedenthornUtils
{
	public static bool IgnoreKeyPresses(bool extra = false)
	{
		int result;
		if (!extra)
		{
			if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
			{
				Chat instance = Chat.instance;
				if (instance == null || !instance.HasFocus())
				{
					result = (Menu.IsVisible() ? 1 : 0);
					goto IL_005f;
				}
			}
			result = 1;
			goto IL_005f;
		}
		int result2;
		if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
		{
			Chat instance2 = Chat.instance;
			if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible())
			{
				TextViewer instance3 = TextViewer.instance;
				result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0);
				goto IL_00d9;
			}
		}
		result2 = 1;
		goto IL_00d9;
		IL_005f:
		return (byte)result != 0;
		IL_00d9:
		return (byte)result2 != 0;
	}

	public static bool CheckKeyDown(string value)
	{
		try
		{
			return Input.GetKeyDown(value.ToLower());
		}
		catch
		{
			return false;
		}
	}

	public static bool CheckKeyHeld(string value, bool req = true)
	{
		try
		{
			return Input.GetKey(value.ToLower());
		}
		catch
		{
			return !req;
		}
	}
}
namespace DeathTweaks;

[BepInPlugin("aedenthorn.DeathTweaks", "Death Tweaks", "1.3.0")]
public class BepInExPlugin : BaseUnityPlugin
{
	private class InventoryInfos
	{
		public List<ItemData> drop_list;

		public Inventory inventory;

		public InventoryInfos(Inventory i, List<ItemData> d)
		{
			drop_list = d;
			inventory = i;
		}
	}

	[HarmonyPatch(typeof(Player), "OnDeath")]
	[HarmonyPriority(800)]
	private static class OnDeath_Patch
	{
		private static bool Prefix(Player __instance, Inventory ___m_inventory, ref float ___m_timeSinceDeath, float ___m_hardDeathCooldown, ZNetView ___m_nview, List<Food> ___m_foods, Skills ___m_skills, SEMan ___m_seman, HitData ___m_lastHit)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected I4, but got Unknown
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08da: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bc9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bdd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c0e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c13: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c18: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c1a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a10: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a15: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a28: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a34: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a63: Unknown result type (might be due to invalid IL or missing references)
			//IL_0afe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d18: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d73: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d78: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Invalid comparison between O and Unknown
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0734: Unknown result type (might be due to invalid IL or missing references)
			//IL_0784: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled.Value)
			{
				return true;
			}
			___m_nview.GetZDO().Set("dead", true);
			___m_nview.InvokeRPC(ZNetView.Everybody, "OnDeath", new object[0]);
			Game.instance.IncrementPlayerStat((PlayerStatType)0, 1f);
			HitType hitType = ___m_lastHit.m_hitType;
			HitType val = hitType;
			switch ((int)val)
			{
			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 ___m_lastHit.m_hitType)).ToString()));
				break;
			}
			Game.instance.GetPlayerProfile().SetDeathPoint(((Component)__instance).transform.position);
			if (createDeathEffects.Value)
			{
				Traverse.Create((object)__instance).Method("CreateDeathEffects", Array.Empty<object>()).GetValue();
			}
			List<InventoryInfos> list = new List<InventoryInfos>();
			if (!keepAllItems.Value)
			{
				if (quickSlotsAssembly != null)
				{
					object obj = quickSlotsAssembly.GetType("EquipmentAndQuickSlots.InventoryExtensions").GetMethod("Extended", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { ___m_inventory });
					foreach (Inventory item in (List<Inventory>)quickSlotsAssembly.GetType("EquipmentAndQuickSlots.ExtendedInventory").GetField("_inventories", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj))
					{
						list.Add(new InventoryInfos(item, new List<ItemData>()));
					}
				}
				else
				{
					list.Add(new InventoryInfos(___m_inventory, new List<ItemData>()));
				}
				string[] source = (string.IsNullOrEmpty(keepItemTypes.Value) ? new string[0] : keepItemTypes.Value.Split(new char[1] { ',' }));
				string[] source2 = (string.IsNullOrEmpty(keepItemNames.Value) ? new string[0] : keepItemNames.Value.Split(new char[1] { ',' }));
				string[] source3 = (string.IsNullOrEmpty(destroyItemTypes.Value) ? new string[0] : destroyItemTypes.Value.Split(new char[1] { ',' }));
				string[] source4 = (string.IsNullOrEmpty(destroyItemNames.Value) ? new string[0] : destroyItemNames.Value.Split(new char[1] { ',' }));
				string[] source5 = (string.IsNullOrEmpty(dropItemTypes.Value) ? new string[0] : dropItemTypes.Value.Split(new char[1] { ',' }));
				string[] source6 = (string.IsNullOrEmpty(dropItemNames.Value) ? new string[0] : dropItemNames.Value.Split(new char[1] { ',' }));
				for (int i = 0; i < list.Count; i++)
				{
					Inventory inventory = list[i].inventory;
					List<ItemData> drop_list = list[i].drop_list;
					Dbgl($"  inventory {i}");
					List<ItemData> allItems = inventory.GetAllItems();
					for (int num = allItems.Count - 1; num >= 0; num--)
					{
						ItemData val2 = allItems[num];
						Dbgl($"   Item  Name: {((Object)val2.m_dropPrefab).name}   Cat: {val2.m_shared.m_itemType}");
					}
					if (quickSlotsAssembly != null && keepQuickSlotItems.Value && (object)inventory == (object)(Inventory)quickSlotsAssembly.GetType("EquipmentAndQuickSlots.PlayerExtensions").GetMethod("GetQuickSlotInventory", BindingFlags.Static | BindingFlags.Public).Invoke(null, new object[1] { __instance }))
					{
						Dbgl("Skipping quick slot inventory");
						continue;
					}
					List<ItemData> value = Traverse.Create((object)inventory).Field("m_inventory").GetValue<List<ItemData>>();
					if (destroyAllItems.Value)
					{
						value.Clear();
					}
					else
					{
						for (int num2 = value.Count - 1; num2 >= 0; num2--)
						{
							ItemData val3 = value[num2];
							if ((!keepEquippedItems.Value || !val3.m_equipped) && (!keepHotbarItems.Value || !(inventory.GetName() == ___m_inventory.GetName()) || val3.m_gridPos.y != 0) && !val3.m_shared.m_questItem)
							{
								if (source3.Contains<string>(Enum.GetName(typeof(ItemType), val3.m_shared.m_itemType)))
								{
									value.RemoveAt(num2);
								}
								else if (source4.Contains(((Object)val3.m_dropPrefab).name))
								{
									value.RemoveAt(num2);
								}
								else if (!source.Contains<string>(Enum.GetName(typeof(ItemType), val3.m_shared.m_itemType)) && !source2.Contains(((Object)val3.m_dropPrefab).name))
								{
									if (source5.Contains<string>(Enum.GetName(typeof(ItemType), val3.m_shared.m_itemType)))
									{
										drop_list.Add(val3);
										value.RemoveAt(num2);
									}
									else if (source6.Contains(((Object)val3.m_dropPrefab).name))
									{
										drop_list.Add(val3);
										value.RemoveAt(num2);
									}
									else if (!val3.m_shared.m_teleportable || !keepTeleportableItems.Value)
									{
										drop_list.Add(val3);
										value.RemoveAt(num2);
									}
								}
							}
						}
					}
					Traverse.Create((object)inventory).Method("Changed", Array.Empty<object>()).GetValue();
				}
			}
			for (int j = 0; j < list.Count; j++)
			{
				Inventory inventory2 = list[j].inventory;
				List<ItemData> drop_list2 = list[j].drop_list;
				if (useTombStone.Value && drop_list2.Any())
				{
					Dbgl("    dropItems.Any");
					Vector3 val4 = ((Character)__instance).GetCenterPoint() + Vector3.left * (float)(j * 2);
					GameObject val5 = Object.Instantiate<GameObject>(__instance.m_tombstone, val4, ((Component)__instance).transform.rotation);
					val5.GetComponent<Container>().GetInventory().RemoveAll();
					int value2 = Traverse.Create((object)inventory2).Field("m_width").GetValue<int>();
					int value3 = Traverse.Create((object)inventory2).Field("m_height").GetValue<int>();
					Traverse.Create((object)val5.GetComponent<Container>().GetInventory()).Field("m_width").SetValue((object)value2);
					Traverse.Create((object)val5.GetComponent<Container>().GetInventory()).Field("m_height").SetValue((object)value3);
					TombStone component = val5.GetComponent<TombStone>();
					PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
					switch (j)
					{
					case 0:
						component.Setup(playerProfile.GetName(), playerProfile.GetPlayerID());
						break;
					case 1:
						component.Setup(playerProfile.GetName() + "- Quickslots", playerProfile.GetPlayerID());
						foreach (ItemData item2 in drop_list2)
						{
							Vector2i gridPos = item2.m_gridPos;
							item2.m_customData["eaqs-qs"] = $"{gridPos.x},{gridPos.y}";
							Dbgl($"   Quickslot Item  Name: {((Object)item2.m_dropPrefab).name}   Cat: {item2.m_shared.m_itemType}");
						}
						break;
					case 2:
						component.Setup(playerProfile.GetName() + "- Eqipment", playerProfile.GetPlayerID());
						foreach (ItemData item3 in drop_list2)
						{
							item3.m_customData["eaqs-e"] = "1";
							Dbgl($"   Eqipment Item  Name: {((Object)item3.m_dropPrefab).name}   Cat: {item3.m_shared.m_itemType}");
						}
						break;
					}
					Traverse.Create((object)val5.GetComponent<Container>().GetInventory()).Field("m_inventory").SetValue((object)drop_list2);
					Traverse.Create((object)val5.GetComponent<Container>().GetInventory()).Method("Changed", Array.Empty<object>()).GetValue();
					continue;
				}
				Dbgl("   !! dropItems.Any");
				foreach (ItemData item4 in drop_list2)
				{
					Dbgl("       Item : " + ((Object)item4.m_dropPrefab).name);
					Vector3 val6 = ((Component)__instance).transform.position + Vector3.up * 0.5f + Random.insideUnitSphere * 0.3f;
					Quaternion val7 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
					ItemDrop.DropItem(item4, 0, val6, val7);
				}
			}
			if (!keepFoodLevels.Value)
			{
				___m_foods.Clear();
			}
			bool flag = noSkillProtection.Value || ___m_timeSinceDeath > ___m_hardDeathCooldown;
			if (flag && reduceSkills.Value)
			{
				___m_skills.LowerAllSkills(skillReduceFactor.Value);
			}
			___m_seman.RemoveAllStatusEffects(false);
			Game.instance.RequestRespawn(10f, false);
			___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);
			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;
		}
	}

	[HarmonyPatch(typeof(Player), "HardDeath")]
	private static class HardDeath_Patch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!modEnabled.Value || !noSkillProtection.Value)
			{
				return true;
			}
			__result = true;
			return false;
		}
	}

	[HarmonyPatch(typeof(Game), "FindSpawnPoint")]
	private static class FindSpawnPoint_Patch
	{
		private static bool Prefix(ref Vector3 point, ref bool usedLogoutPoint, bool ___m_firstSpawn, ref bool __result)
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled.Value || ___m_firstSpawn)
			{
				return true;
			}
			if (spawnAtStart.Value)
			{
				usedLogoutPoint = false;
				Vector3 val = default(Vector3);
				if (ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref val))
				{
					point = val + Vector3.up * 2f;
					ZNet.instance.SetReferencePosition(point);
					__result = ZNetScene.instance.IsAreaReady(point);
					if (__result)
					{
						Dbgl($"respawning at start: {point}");
					}
				}
				else
				{
					Dbgl("start point not found");
					ZNet.instance.SetReferencePosition(Vector3.zero);
					point = Vector3.zero;
					__result = false;
				}
				return false;
			}
			if (useFixedSpawnCoordinates.Value)
			{
				usedLogoutPoint = false;
				point = fixedSpawnCoordinates.Value;
				ZNet.instance.SetReferencePosition(point);
				__result = ZNetScene.instance.IsAreaReady(point);
				if (__result)
				{
					Dbgl($"respawning at custom point {point}");
				}
				return false;
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(Skills), "OnDeath")]
	private static class Skills_OnDeath_Patch
	{
		private static bool Prefix()
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			return reduceSkills.Value;
		}
	}

	[HarmonyPatch(typeof(Terminal), "InputText")]
	private static class InputText_Patch
	{
		private static bool Prefix(Terminal __instance)
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			string text = ((TMP_InputField)__instance.m_input).text;
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
			{
				((BaseUnityPlugin)context).Config.Reload();
				((BaseUnityPlugin)context).Config.Save();
				__instance.AddString(text);
				__instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded");
				return false;
			}
			return true;
		}
	}

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> isDebug;

	public static ConfigEntry<int> nexusID;

	public static ConfigEntry<bool> keepEquippedItems;

	public static ConfigEntry<bool> keepHotbarItems;

	public static ConfigEntry<bool> keepAllItems;

	public static ConfigEntry<bool> destroyAllItems;

	public static ConfigEntry<bool> useTombStone;

	public static ConfigEntry<bool> keepFoodLevels;

	public static ConfigEntry<bool> keepQuickSlotItems;

	public static ConfigEntry<bool> keepTeleportableItems;

	public static ConfigEntry<bool> createDeathEffects;

	public static ConfigEntry<bool> reduceSkills;

	public static ConfigEntry<bool> noSkillProtection;

	public static ConfigEntry<bool> useFixedSpawnCoordinates;

	public static ConfigEntry<bool> spawnAtStart;

	public static ConfigEntry<Vector3> fixedSpawnCoordinates;

	public static ConfigEntry<float> skillReduceFactor;

	public static ConfigEntry<string> keepItemTypes;

	public static ConfigEntry<string> dropItemTypes;

	public static ConfigEntry<string> destroyItemTypes;

	public static ConfigEntry<string> keepItemNames;

	public static ConfigEntry<string> dropItemNames;

	public static ConfigEntry<string> destroyItemNames;

	private static BepInExPlugin context;

	private static List<string> typeEnums = new List<string>();

	private static Assembly quickSlotsAssembly;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug.Value)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		foreach (int value in Enum.GetValues(typeof(ItemType)))
		{
			typeEnums.Add(Enum.GetName(typeof(ItemType), value));
		}
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs");
		nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1068, "Nexus mod ID for updates");
		keepItemTypes = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "KeepItemTypes", "", "List of items to keep (comma-separated). Leave empty if using DropItemTypes. Valid types: " + string.Join(",", typeEnums));
		dropItemTypes = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "DropItemTypes", "", "List of items to drop (comma-separated). Leave empty if using KeepItemTypes. Valid types: " + string.Join(",", typeEnums));
		destroyItemTypes = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "DestroyItemTypes", "", "List of items to destroy (comma-separated). Overrides other lists. Valid types: " + string.Join(",", typeEnums));
		keepItemNames = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "KeepItems", "", "List of items to keep (comma-separated). Use Item names, for example: Iron,IronScrap,BronzeOre");
		dropItemNames = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "DropItems", "", "List of items to drop (comma-separated). Use Item names, for example: Iron,IronScrap,BronzeOre");
		destroyItemNames = ((BaseUnityPlugin)this).Config.Bind<string>("ItemLists", "DestroyItems", "", "List of items to destroy (comma-separated). Overrides other lists. Use Item names, for example: Iron,IronScrap,BronzeOre");
		keepAllItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepAllItems", false, "Overrides all other item options if true.");
		destroyAllItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "DestroyAllItems", false, "Overrides all other item options except KeepAllItems if true.");
		keepEquippedItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepEquippedItems", false, "Overrides item lists if true.");
		keepTeleportableItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepTeleportableItems", false, "Doesn't override item lists.");
		keepHotbarItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepHotbarItems", false, "Overrides item lists if true.");
		useTombStone = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "UseTombStone", true, "Use tombstone (if false, drops items on ground).");
		createDeathEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "CreateDeathEffects", true, "Create death effects.");
		keepFoodLevels = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepFoodLevels", false, "Keep food levels.");
		keepQuickSlotItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "KeepQuickSlotItems", false, "Keep QuickSlot items.");
		useFixedSpawnCoordinates = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "UseFixedSpawnCoordinates", false, "Use fixed spawn coordinates.");
		spawnAtStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "SpawnAtStart", false, "Respawn at start location.");
		fixedSpawnCoordinates = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Spawn", "FixedSpawnCoordinates", Vector3.zero, "Fixed spawn coordinates.");
		noSkillProtection = ((BaseUnityPlugin)this).Config.Bind<bool>("Skills", "NoSkillProtection", false, "Prevents skill protection after death.");
		reduceSkills = ((BaseUnityPlugin)this).Config.Bind<bool>("Skills", "ReduceSkills", true, "Reduce skills.");
		skillReduceFactor = ((BaseUnityPlugin)this).Config.Bind<float>("Skills", "SkillReduceFactor", 0.25f, "Reduce skills by this fraction.");
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
	}

	private void Start()
	{
		if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.equipmentandquickslots"))
		{
			quickSlotsAssembly = ((object)Chainloader.PluginInfos["randyknapp.mods.equipmentandquickslots"].Instance).GetType().Assembly;
		}
	}
}