Decompiled source of Armory v1.4.3

Armory.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using ArmoryHotFixes;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using Jewelcrafting;
using LocalizationManager;
using MagicaCloth2;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using PieceManager;
using ServerSync;
using SoundMixManager;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: ComVisible(false)]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: AssemblyFileVersion("1.4.3")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Therzie")]
[assembly: AssemblyProduct("Armory")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyTitle("Armory")]
[assembly: AssemblyDescription("")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class ArmoryQualityRequirementPatch
{
	[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
	public static class HaveRequirementItemsPatch
	{
		public static void Postfix(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			if ((discover | __result) || (Object)(object)piece.m_item == (Object)null || !((Object)((Component)piece.m_item).gameObject).name.EndsWith("_TW"))
			{
				return;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
			bool flag = true;
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if ((Object.op_Implicit((Object)(object)currentCraftingStation) && currentCraftingStation.m_upgrader != val.m_upgraderResource) || (!Object.op_Implicit((Object)(object)currentCraftingStation) && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem))
				{
					continue;
				}
				int num = val.GetAmount(qualityLevel) * amount;
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				Dictionary<int, int> dictionary = new Dictionary<int, int>();
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (!(allItem.m_shared.m_name != name))
					{
						dictionary.TryGetValue(allItem.m_quality, out var value);
						dictionary[allItem.m_quality] = value + allItem.m_stack;
					}
				}
				int num2 = 0;
				foreach (int value2 in dictionary.Values)
				{
					if (value2 > num2)
					{
						num2 = value2;
					}
				}
				if (piece.m_requireOnlyOneIngredient)
				{
					if (num2 >= num)
					{
						__result = true;
						return;
					}
				}
				else if (num2 < num)
				{
					flag = false;
					break;
				}
			}
			if (!piece.m_requireOnlyOneIngredient)
			{
				__result = flag;
			}
		}
	}

	[HarmonyPatch(typeof(Player), "GetFirstRequiredItem")]
	public static class GetFirstRequiredItemPatch
	{
		public static void Postfix(Player __instance, Inventory inventory, Recipe recipe, int qualityLevel, int craftMultiplier, ref ItemData __result, ref int amount, ref int extraAmount)
		{
			if (__result != null || (Object)(object)recipe.m_item == (Object)null || !((Object)((Component)recipe.m_item).gameObject).name.EndsWith("_TW"))
			{
				return;
			}
			CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation();
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement val in resources)
			{
				if ((Object.op_Implicit((Object)(object)currentCraftingStation) && currentCraftingStation.m_upgrader != val.m_upgraderResource) || (!Object.op_Implicit((Object)(object)currentCraftingStation) && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem))
				{
					continue;
				}
				int num = val.GetAmount(qualityLevel) * craftMultiplier;
				string name = val.m_resItem.m_itemData.m_shared.m_name;
				Dictionary<int, int> dictionary = new Dictionary<int, int>();
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (!(allItem.m_shared.m_name != name))
					{
						dictionary.TryGetValue(allItem.m_quality, out var value);
						dictionary[allItem.m_quality] = value + allItem.m_stack;
					}
				}
				foreach (KeyValuePair<int, int> item in dictionary)
				{
					if (item.Value >= num)
					{
						amount = num;
						extraAmount = val.m_extraAmountOnlyOneIngredient;
						__result = inventory.GetItem(name, item.Key, false);
						return;
					}
				}
			}
		}
	}
}
namespace PieceManager
{
	internal static class PieceManagerCategorySync
	{
		private const string RegistryKey = "PieceManager.CategoryRegistry";

		private static Dictionary<string, int>? _registry;

		private static readonly Type PiecePrefabManagerType;

		private static readonly FieldInfo PieceCategoriesField;

		private static readonly FieldInfo CustomCategoryValuesField;

		private static readonly FieldInfo CustomCategoryNamesField;

		private static readonly FieldInfo OwnCategoryLabelsField;

		private static readonly MethodInfo GetCategoryTokenMethod;

		private const int CustomTagIdBase = 16777216;

		private static Dictionary<string, int> Registry
		{
			get
			{
				if (_registry != null)
				{
					return _registry;
				}
				if (AppDomain.CurrentDomain.GetData("PieceManager.CategoryRegistry") is Dictionary<string, int> registry)
				{
					_registry = registry;
				}
				else
				{
					_registry = new Dictionary<string, int>();
					AppDomain.CurrentDomain.SetData("PieceManager.CategoryRegistry", _registry);
				}
				return _registry;
			}
		}

		public static void Init()
		{
		}

		static PieceManagerCategorySync()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00e3: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			PiecePrefabManagerType = typeof(PiecePrefabManager);
			PieceCategoriesField = AccessTools.Field(PiecePrefabManagerType, "PieceCategories");
			CustomCategoryValuesField = AccessTools.Field(PiecePrefabManagerType, "customCategoryValues");
			CustomCategoryNamesField = AccessTools.Field(PiecePrefabManagerType, "customCategoryNames");
			OwnCategoryLabelsField = AccessTools.Field(PiecePrefabManagerType, "OwnCategoryLabels");
			GetCategoryTokenMethod = AccessTools.Method(PiecePrefabManagerType, "GetCategoryToken", new Type[1] { typeof(string) }, (Type[])null);
			Harmony val = new Harmony("org.bepinex.helpers.PieceManager.CategorySync");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(PiecePrefabManagerType, "GetCategory", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ByUsagePieceList), "UpdateAvailableTags", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "DedupAvailableTags", (Type[])null, (Type[])null))
			{
				priority = -1000
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ByUsagePieceList), "GetAvailablePiecesWithTag", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "DedupAvailablePiecesWithTag", (Type[])null, (Type[])null))
			{
				priority = -1000
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static bool Prefix(string name, ref PieceCategory __result)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected I4, but got Unknown
			if (!Registry.TryGetValue(name, out var value))
			{
				return true;
			}
			Dictionary<string, PieceCategory> dictionary = (Dictionary<string, PieceCategory>)PieceCategoriesField.GetValue(null);
			if (dictionary.ContainsKey(name))
			{
				return true;
			}
			PieceCategory val = (dictionary[name] = (PieceCategory)value);
			PieceCategory[] array = (PieceCategory[])CustomCategoryValuesField.GetValue(null);
			CustomCategoryValuesField.SetValue(null, AddToArray(array, val));
			string[] array2 = (string[])CustomCategoryNamesField.GetValue(null);
			CustomCategoryNamesField.SetValue(null, AddToArray(array2, name));
			string text = (string)GetCategoryTokenMethod.Invoke(null, new object[1] { name });
			Dictionary<PieceCategory, string> dictionary2 = (Dictionary<PieceCategory, string>)OwnCategoryLabelsField.GetValue(null);
			dictionary2[val] = "$" + text;
			Localization.instance.AddWord(text, name);
			__result = (PieceCategory)(int)val;
			return false;
		}

		private static void Postfix(string name, PieceCategory __result)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected I4, but got Unknown
			Dictionary<string, PieceCategory> dictionary = (Dictionary<string, PieceCategory>)PieceCategoriesField.GetValue(null);
			if (dictionary.ContainsKey(name) && !Registry.ContainsKey(name))
			{
				Registry[name] = (int)__result;
			}
		}

		private static void DedupAvailableTags(ByUsagePieceList __instance)
		{
			if (Registry.Count == 0)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (int value in Registry.Values)
			{
				hashSet.Add(16777216 + value);
			}
			List<int> availableTags = __instance.m_availableTags;
			HashSet<int> hashSet2 = new HashSet<int>();
			for (int num = availableTags.Count - 1; num >= 0; num--)
			{
				int item = availableTags[num];
				if (hashSet.Contains(item) && !hashSet2.Add(item))
				{
					availableTags.RemoveAt(num);
				}
			}
		}

		private static void DedupAvailablePiecesWithTag(int tagId, IList<Piece> resultOut)
		{
			if (tagId < 16777216)
			{
				return;
			}
			int num = tagId - 16777216;
			bool flag = false;
			foreach (int value in Registry.Values)
			{
				if (value == num)
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return;
			}
			HashSet<Piece> hashSet = new HashSet<Piece>();
			for (int num2 = resultOut.Count - 1; num2 >= 0; num2--)
			{
				if (!hashSet.Add(resultOut[num2]))
				{
					resultOut.RemoveAt(num2);
				}
			}
		}

		private static T[] AddToArray<T>(T[] array, T item)
		{
			T[] array2 = new T[array.Length + 1];
			Array.Copy(array, array2, array.Length);
			array2[^1] = item;
			return array2;
		}
	}
}
namespace ArmoryHotFixes
{
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ColliderFix
	{
		[HarmonyPriority(0)]
		private static void Postfix(ZNetScene __instance)
		{
			GameObject prefab = __instance.GetPrefab("ArmorRogueChest_TW");
			object obj;
			if (prefab == null)
			{
				obj = null;
			}
			else
			{
				Transform obj2 = prefab.transform.Find("log");
				obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			}
			GameObject val = (GameObject)obj;
			if ((Object)(object)val != (Object)null && !val.activeSelf)
			{
				val.SetActive(true);
			}
		}
	}
	public static class CapeClothColliderFix
	{
		[HarmonyPatch(typeof(VisEquipment), "AttachArmor")]
		private static class AttachArmor_Patch
		{
			private static void Postfix(VisEquipment __instance, int itemHash, List<GameObject> __result)
			{
				if (__result == null || !s_registered.Contains(itemHash))
				{
					return;
				}
				foreach (GameObject item in __result)
				{
					BodyClothColliders.ApplyTo(__instance, item);
				}
			}
		}

		[HarmonyPatch(typeof(VisEquipment), "AttachItem")]
		private static class AttachItem_Patch
		{
			private static void Postfix(VisEquipment __instance, int itemHash, GameObject __result)
			{
				if (!((Object)(object)__result == (Object)null) && s_registered.Contains(itemHash))
				{
					BodyClothColliders.ApplyTo(__instance, __result);
				}
			}
		}

		[Serializable]
		private class MagicaColliderData
		{
			public Vector3 center;

			public Vector3 size;

			public int direction = 1;

			public bool reverseDirection;

			public bool radiusSeparation;

			public bool alignedOnCenter = true;
		}

		private class BodyClothColliders : MonoBehaviour
		{
			private class Entry
			{
				public Transform source;

				public MagicaColliderData data;

				public bool isSphere;

				public CapsuleCollider collider;

				public float extraRadius;

				public float extraLength;

				public float trimTop;
			}

			private readonly List<Entry> m_entries = new List<Entry>();

			private CapsuleCollider[] m_colliderArray = (CapsuleCollider[])(object)new CapsuleCollider[0];

			private GameObject m_root;

			private readonly List<Cloth> m_cloths = new List<Cloth>();

			public static void ApplyTo(VisEquipment vis, GameObject item)
			{
				if ((Object)(object)vis == (Object)null || (Object)(object)item == (Object)null)
				{
					return;
				}
				Cloth[] componentsInChildren = item.GetComponentsInChildren<Cloth>(true);
				if (componentsInChildren.Length == 0)
				{
					return;
				}
				BodyClothColliders bodyClothColliders = ((Component)vis).GetComponent<BodyClothColliders>();
				if ((Object)(object)bodyClothColliders == (Object)null)
				{
					bodyClothColliders = ((Component)vis).gameObject.AddComponent<BodyClothColliders>();
					bodyClothColliders.Build(vis);
				}
				if (bodyClothColliders.m_colliderArray.Length == 0)
				{
					return;
				}
				Cloth[] array = componentsInChildren;
				foreach (Cloth val in array)
				{
					List<CapsuleCollider> list = new List<CapsuleCollider>(bodyClothColliders.m_colliderArray);
					if (val.capsuleColliders != null)
					{
						CapsuleCollider[] capsuleColliders = val.capsuleColliders;
						foreach (CapsuleCollider val2 in capsuleColliders)
						{
							if ((Object)(object)val2 != (Object)null && !list.Contains(val2))
							{
								list.Add(val2);
							}
						}
					}
					val.capsuleColliders = list.ToArray();
					if (val.clothSolverFrequency < 240f)
					{
						val.clothSolverFrequency = 240f;
					}
					bodyClothColliders.m_cloths.Add(val);
				}
				((Behaviour)bodyClothColliders).enabled = true;
				bodyClothColliders.Sync();
			}

			private void Build(VisEquipment vis)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Expected O, but got Unknown
				m_root = new GameObject("CapeClothColliders_" + ((Object)((Component)vis).gameObject).name);
				int num = LayerMask.NameToLayer("effect");
				if (vis.m_clothColliders != null)
				{
					foreach (ColliderComponent clothCollider in vis.m_clothColliders)
					{
						if ((Object)(object)clothCollider == (Object)null)
						{
							continue;
						}
						string text = (((Object)(object)((Component)clothCollider).transform.parent != (Object)null) ? ((Object)((Component)clothCollider).transform.parent).name : "");
						if (s_skipBones.Contains(text))
						{
							continue;
						}
						string name = ((object)clothCollider).GetType().Name;
						bool flag = name == "MagicaSphereCollider";
						bool flag2 = name == "MagicaCapsuleCollider";
						if (flag || flag2)
						{
							MagicaColliderData data = JsonUtility.FromJson<MagicaColliderData>(JsonUtility.ToJson((object)clothCollider));
							GameObject val = new GameObject(name + "_" + text);
							val.transform.SetParent(m_root.transform, false);
							if (num >= 0)
							{
								val.layer = num;
							}
							CapsuleCollider val2 = val.AddComponent<CapsuleCollider>();
							((Collider)val2).isTrigger = true;
							val2.direction = 1;
							s_adjustByBone.TryGetValue(text, out (float, float) value);
							s_trimTopByBone.TryGetValue(text, out var value2);
							m_entries.Add(new Entry
							{
								source = ((Component)clothCollider).transform,
								data = data,
								isSphere = flag,
								collider = val2,
								extraRadius = value.Item1,
								extraLength = value.Item2,
								trimTop = value2
							});
						}
					}
				}
				if (m_entries.Count == 0)
				{
					Debug.LogWarning((object)("[CapeClothColliderFix] No MagicaCloth body colliders found on " + ((Object)((Component)vis).gameObject).name));
				}
				m_colliderArray = m_entries.ConvertAll((Entry e) => e.collider).ToArray();
				Sync();
			}

			private void LateUpdate()
			{
				for (int num = m_cloths.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)m_cloths[num] == (Object)null)
					{
						m_cloths.RemoveAt(num);
					}
				}
				if (m_cloths.Count == 0)
				{
					((Behaviour)this).enabled = false;
				}
				else
				{
					Sync();
				}
			}

			private void Sync()
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: 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_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_0156: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: 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)
				//IL_017e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0232: Unknown result type (might be due to invalid IL or missing references)
				//IL_023c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0241: Unknown result type (might be due to invalid IL or missing references)
				//IL_0243: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_020c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0203: Unknown result type (might be due to invalid IL or missing references)
				//IL_0205: Unknown result type (might be due to invalid IL or missing references)
				//IL_020e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0210: Unknown result type (might be due to invalid IL or missing references)
				//IL_0212: Unknown result type (might be due to invalid IL or missing references)
				//IL_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0221: Unknown result type (might be due to invalid IL or missing references)
				//IL_0226: Unknown result type (might be due to invalid IL or missing references)
				foreach (Entry entry in m_entries)
				{
					if ((Object)(object)entry.source == (Object)null)
					{
						continue;
					}
					MagicaColliderData data = entry.data;
					Vector3 lossyScale = entry.source.lossyScale;
					float num = Mathf.Max(new float[3]
					{
						Mathf.Abs(lossyScale.x),
						Mathf.Abs(lossyScale.y),
						Mathf.Abs(lossyScale.z)
					});
					float num2 = (data.radiusSeparation ? Mathf.Max(data.size.x, data.size.y) : data.size.x);
					float num3 = Mathf.Max(0.001f, num2 * num + entry.extraRadius);
					Vector3 val = entry.source.TransformPoint(data.center);
					Transform transform = ((Component)entry.collider).transform;
					entry.collider.radius = num3;
					if (entry.isSphere)
					{
						transform.position = val;
						transform.rotation = Quaternion.identity;
						entry.collider.height = num3 * 2f;
						continue;
					}
					Vector3 val2 = ((data.direction == 0) ? Vector3.right : ((data.direction == 2) ? Vector3.forward : Vector3.up));
					if (data.reverseDirection)
					{
						val2 = -val2;
					}
					Vector3 val3 = entry.source.TransformDirection(val2);
					Vector3 normalized = ((Vector3)(ref val3)).normalized;
					float num4 = Mathf.Max(0f, data.size.z * num + entry.extraLength);
					if (!data.alignedOnCenter)
					{
						val += normalized * (num4 * 0.5f);
					}
					if (entry.trimTop > 0f)
					{
						float num5 = Mathf.Min(entry.trimTop, num4);
						Vector3 val4 = ((Vector3.Dot(normalized, Vector3.up) >= 0f) ? normalized : (-normalized));
						val -= val4 * (num5 * 0.5f);
						num4 -= num5;
					}
					transform.position = val;
					transform.rotation = Quaternion.FromToRotation(Vector3.up, normalized);
					entry.collider.height = num4 + num3 * 2f;
				}
			}

			private void OnEnable()
			{
				if ((Object)(object)m_root != (Object)null)
				{
					m_root.SetActive(true);
				}
			}

			private void OnDisable()
			{
				if ((Object)(object)m_root != (Object)null)
				{
					m_root.SetActive(false);
				}
			}

			private void OnDestroy()
			{
				if ((Object)(object)m_root != (Object)null)
				{
					Object.Destroy((Object)(object)m_root);
				}
			}
		}

		private static readonly HashSet<int> s_registered = new HashSet<int>();

		private static readonly Dictionary<string, (float extraRadius, float extraLength)> s_adjustByBone = new Dictionary<string, (float, float)> { 
		{
			"Spine1",
			(0.025f, 0f)
		} };

		private static readonly Dictionary<string, float> s_trimTopByBone = new Dictionary<string, float>();

		private static readonly HashSet<string> s_skipBones = new HashSet<string>();

		private const float ClothSolverFrequency = 240f;

		public static void Register(string itemPrefabName)
		{
			if (!string.IsNullOrEmpty(itemPrefabName))
			{
				s_registered.Add(StringExtensionMethods.GetStableHashCode(itemPrefabName));
			}
		}
	}
}
namespace StatusEffectManager
{
	[PublicAPI]
	[Description("The ItemDrop effect to apply the status effect")]
	public enum EffectType
	{
		Equip,
		Attack,
		Consume,
		Set
	}
	public struct SE_Item
	{
		public StatusEffect Effect;

		public EffectType Type;
	}
	[PublicAPI]
	public class CustomSE
	{
		private static readonly List<CustomSE> RegisteredEffects = new List<CustomSE>();

		private static readonly Dictionary<StatusEffect, CustomSE> CustomEffectMap = new Dictionary<StatusEffect, CustomSE>();

		internal static readonly List<StatusEffect> CustomSEs = new List<StatusEffect>();

		internal static readonly Dictionary<SE_Item, string> AddToPrefabs = new Dictionary<SE_Item, string>();

		[Description("Instance of the StatusEffect.")]
		public readonly StatusEffect Effect;

		public EffectType Type;

		private string _folderName = "icons";

		private AssetBundle _assetBundle = null;

		[Description("Sets the icon for the StatusEffect. Must be 64x64")]
		public Sprite? IconSprite = null;

		private string? IconName = null;

		private LocalizeKey? _name;

		private static Localization? _english;

		private static BaseUnityPlugin? _plugin;

		private static bool hasConfigSync = true;

		private static object? _configSync;

		[Description("Sets the icon for the StatusEffect. Must be 64x64")]
		public string? Icon
		{
			get
			{
				return IconName;
			}
			set
			{
				IconName = value;
				IconSprite = ((IconName == null) ? null : loadSprite(IconName));
				Effect.m_icon = IconSprite;
			}
		}

		[Description("Sets the in-game name for the StatusEffect")]
		public LocalizeKey Name
		{
			get
			{
				LocalizeKey name = _name;
				if (name != null)
				{
					return name;
				}
				StatusEffect effect = Effect;
				if (effect.m_name.StartsWith("$"))
				{
					_name = new LocalizeKey(effect.m_name);
				}
				else
				{
					string text = "$statuseffect_" + ((Object)Effect).name.Replace(" ", "_");
					_name = new LocalizeKey(text).English(effect.m_name);
					effect.m_name = text;
				}
				return _name;
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static object? configSync
		{
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " ItemManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		public CustomSE(string assetBundleFileName, string customEffectName, string folderName = "assets")
			: this(EffectManager.RegisterAssetBundle(assetBundleFileName, folderName), customEffectName)
		{
		}

		public CustomSE(AssetBundle bundle, string customEffectName)
		{
			Effect = EffectManager.RegisterCustomSE(bundle, customEffectName);
			RegisteredEffects.Add(this);
			CustomEffectMap[Effect] = this;
		}

		public CustomSE(string customEffectName)
		{
			Effect = ScriptableObject.CreateInstance<StatusEffect>();
			EffectManager.RegisterCustomSE(Effect, customEffectName);
			RegisteredEffects.Add(this);
			CustomEffectMap[Effect] = this;
		}

		private byte[]? ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ((_folderName == "") ? "" : ".") + _folderName + "." + name);
			if (manifestResourceStream == null)
			{
				return null;
			}
			manifestResourceStream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private Texture2D? loadTexture(string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			byte[] array = ReadEmbeddedFileBytes(name);
			if (array != null)
			{
				Texture2D val = new Texture2D(0, 0);
				ImageConversion.LoadImage(val, array);
				return val;
			}
			return null;
		}

		private Sprite loadSprite(string name)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = loadTexture(name);
			if (val != null)
			{
				return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), Vector2.zero);
			}
			AssetBundle assetBundle = _assetBundle;
			Sprite val2 = ((assetBundle != null) ? assetBundle.LoadAsset<Sprite>(name) : null);
			if (val2 != null)
			{
				return val2;
			}
			throw new FileNotFoundException("Could not find a file named " + name + " for the effect icon");
		}

		public void AddSEToPrefab(CustomSE customSE, string prefabName)
		{
			SE_Item key = new SE_Item
			{
				Effect = customSE.Effect,
				Type = customSE.Type
			};
			AddToPrefabs.Add(key, prefabName);
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description);
			configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T))
				.Invoke(configSync, new object[1] { val });
			return val;
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[PublicAPI]
	public class LocalizeKey
	{
		private static readonly List<LocalizeKey> keys = new List<LocalizeKey>();

		public readonly string Key;

		public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>();

		public LocalizeKey(string key)
		{
			Key = key.Replace("$", "");
			keys.Add(this);
		}

		public void Alias(string alias)
		{
			Localizations.Clear();
			if (!alias.Contains("$"))
			{
				alias = "$" + alias;
			}
			Localizations["alias"] = alias;
			if (Localization.m_instance != null)
			{
				Localization.instance.AddWord(Key, Localization.instance.Localize(alias));
			}
		}

		public LocalizeKey English(string key)
		{
			return addForLang("English", key);
		}

		public LocalizeKey Swedish(string key)
		{
			return addForLang("Swedish", key);
		}

		public LocalizeKey French(string key)
		{
			return addForLang("French", key);
		}

		public LocalizeKey Italian(string key)
		{
			return addForLang("Italian", key);
		}

		public LocalizeKey German(string key)
		{
			return addForLang("German", key);
		}

		public LocalizeKey Spanish(string key)
		{
			return addForLang("Spanish", key);
		}

		public LocalizeKey Russian(string key)
		{
			return addForLang("Russian", key);
		}

		public LocalizeKey Romanian(string key)
		{
			return addForLang("Romanian", key);
		}

		public LocalizeKey Bulgarian(string key)
		{
			return addForLang("Bulgarian", key);
		}

		public LocalizeKey Macedonian(string key)
		{
			return addForLang("Macedonian", key);
		}

		public LocalizeKey Finnish(string key)
		{
			return addForLang("Finnish", key);
		}

		public LocalizeKey Danish(string key)
		{
			return addForLang("Danish", key);
		}

		public LocalizeKey Norwegian(string key)
		{
			return addForLang("Norwegian", key);
		}

		public LocalizeKey Icelandic(string key)
		{
			return addForLang("Icelandic", key);
		}

		public LocalizeKey Turkish(string key)
		{
			return addForLang("Turkish", key);
		}

		public LocalizeKey Lithuanian(string key)
		{
			return addForLang("Lithuanian", key);
		}

		public LocalizeKey Czech(string key)
		{
			return addForLang("Czech", key);
		}

		public LocalizeKey Hungarian(string key)
		{
			return addForLang("Hungarian", key);
		}

		public LocalizeKey Slovak(string key)
		{
			return addForLang("Slovak", key);
		}

		public LocalizeKey Polish(string key)
		{
			return addForLang("Polish", key);
		}

		public LocalizeKey Dutch(string key)
		{
			return addForLang("Dutch", key);
		}

		public LocalizeKey Portuguese_European(string key)
		{
			return addForLang("Portuguese_European", key);
		}

		public LocalizeKey Portuguese_Brazilian(string key)
		{
			return addForLang("Portuguese_Brazilian", key);
		}

		public LocalizeKey Chinese(string key)
		{
			return addForLang("Chinese", key);
		}

		public LocalizeKey Japanese(string key)
		{
			return addForLang("Japanese", key);
		}

		public LocalizeKey Korean(string key)
		{
			return addForLang("Korean", key);
		}

		public LocalizeKey Hindi(string key)
		{
			return addForLang("Hindi", key);
		}

		public LocalizeKey Thai(string key)
		{
			return addForLang("Thai", key);
		}

		public LocalizeKey Abenaki(string key)
		{
			return addForLang("Abenaki", key);
		}

		public LocalizeKey Croatian(string key)
		{
			return addForLang("Croatian", key);
		}

		public LocalizeKey Georgian(string key)
		{
			return addForLang("Georgian", key);
		}

		public LocalizeKey Greek(string key)
		{
			return addForLang("Greek", key);
		}

		public LocalizeKey Serbian(string key)
		{
			return addForLang("Serbian", key);
		}

		public LocalizeKey Ukrainian(string key)
		{
			return addForLang("Ukrainian", key);
		}

		private LocalizeKey addForLang(string lang, string value)
		{
			Localizations[lang] = value;
			if (Localization.m_instance != null)
			{
				if (Localization.instance.GetSelectedLanguage() == lang)
				{
					Localization.instance.AddWord(Key, value);
				}
				else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key))
				{
					Localization.instance.AddWord(Key, value);
				}
			}
			return this;
		}

		[HarmonyPriority(300)]
		internal static void AddLocalizedKeys(Localization __instance, string language)
		{
			foreach (LocalizeKey key in keys)
			{
				string value2;
				if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value))
				{
					__instance.AddWord(key.Key, value);
				}
				else if (key.Localizations.TryGetValue("alias", out value2))
				{
					__instance.AddWord(key.Key, Localization.instance.Localize(value2));
				}
			}
		}
	}
	public static class LocalizationCache
	{
		private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>();

		internal static void LocalizationPostfix(Localization __instance, string language)
		{
			string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key;
			if (key != null)
			{
				localizations.Remove(key);
			}
			if (!localizations.ContainsKey(language))
			{
				localizations.Add(language, __instance);
			}
		}

		public static Localization ForLanguage(string? language = null)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value))
			{
				return value;
			}
			value = new Localization();
			if (language != null)
			{
				value.SetupLanguage(language);
			}
			return value;
		}
	}
	public static class EffectManager
	{
		private struct BundleId
		{
			[UsedImplicitly]
			public string assetBundleFileName;

			[UsedImplicitly]
			public string folderName;
		}

		private static readonly Dictionary<BundleId, AssetBundle> bundleCache;

		static EffectManager()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			bundleCache = new Dictionary<BundleId, AssetBundle>();
			Harmony val = new Harmony("org.bepinex.helpers.StatusEffectManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(EffectManager), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(EffectManager), "Patch_ZNetSceneAwake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static AssetBundle RegisterAssetBundle(string assetBundleFileName, string folderName = "assets")
		{
			BundleId key = new BundleId
			{
				assetBundleFileName = assetBundleFileName,
				folderName = folderName
			};
			if (!bundleCache.TryGetValue(key, out var value))
			{
				Dictionary<BundleId, AssetBundle> dictionary = bundleCache;
				AssetBundle? obj = ((IEnumerable<AssetBundle>)Resources.FindObjectsOfTypeAll<AssetBundle>()).FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle a) => ((Object)a).name == assetBundleFileName)) ?? AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ((folderName == "") ? "" : ".") + folderName + "." + assetBundleFileName));
				AssetBundle result = obj;
				dictionary[key] = obj;
				return result;
			}
			return value;
		}

		public static StatusEffect RegisterCustomSE(string assetBundleFileName, string customEffectName, string folderName = "assets")
		{
			return RegisterCustomSE(RegisterAssetBundle(assetBundleFileName, folderName), customEffectName);
		}

		public static StatusEffect RegisterCustomSE(AssetBundle assets, string customEffectName)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			StatusEffect val = (StatusEffect)assets.LoadAsset<ScriptableObject>(customEffectName);
			CustomSE.CustomSEs.Add(val);
			return val;
		}

		public static StatusEffect RegisterCustomSE(StatusEffect customSE, string customEffectName)
		{
			((Object)customSE).name = customEffectName;
			CustomSE.CustomSEs.Add(customSE);
			return customSE;
		}

		[HarmonyPriority(700)]
		private static void Patch_ObjectDBInit(ObjectDB __instance)
		{
			foreach (StatusEffect customSE in CustomSE.CustomSEs)
			{
				if (!__instance.m_StatusEffects.Contains(customSE))
				{
					__instance.m_StatusEffects.Add(customSE);
				}
			}
			__instance.UpdateRegisters();
		}

		[HarmonyPriority(700)]
		private static void Patch_ZNetSceneAwake(ZNetScene __instance)
		{
			foreach (KeyValuePair<SE_Item, string> addToPrefab in CustomSE.AddToPrefabs)
			{
				try
				{
					GameObject prefab = __instance.GetPrefab(addToPrefab.Value);
					ItemDrop val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<ItemDrop>() : prefab.GetComponentInChildren<ItemDrop>());
					Aoe val2 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<Aoe>() : prefab.GetComponentInChildren<Aoe>());
					EffectArea val3 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<EffectArea>() : prefab.GetComponentInChildren<EffectArea>());
					if (Object.op_Implicit((Object)(object)val))
					{
						switch (addToPrefab.Key.Type)
						{
						case EffectType.Equip:
							val.m_itemData.m_shared.m_equipStatusEffect = addToPrefab.Key.Effect;
							break;
						case EffectType.Attack:
							val.m_itemData.m_shared.m_attackStatusEffect = addToPrefab.Key.Effect;
							break;
						case EffectType.Consume:
							val.m_itemData.m_shared.m_consumeStatusEffect = addToPrefab.Key.Effect;
							break;
						case EffectType.Set:
							val.m_itemData.m_shared.m_setSize = 1;
							val.m_itemData.m_shared.m_setName = ((Object)addToPrefab.Key.Effect).name;
							val.m_itemData.m_shared.m_setStatusEffect = addToPrefab.Key.Effect;
							break;
						default:
							throw new ArgumentOutOfRangeException();
						}
					}
					else if (Object.op_Implicit((Object)(object)val2))
					{
						val2.m_statusEffect = ((Object)addToPrefab.Key.Effect).name;
					}
					else if (Object.op_Implicit((Object)(object)val3))
					{
						val3.m_statusEffect = ((Object)addToPrefab.Key.Effect).name;
					}
					else
					{
						Debug.LogWarning((object)("The prefab '" + ((Object)prefab).name + "' does not have an ItemDrop, AOE, or EffectArea component. Cannot add the StatusEffect to the prefab."));
					}
				}
				catch (Exception arg)
				{
					Debug.LogWarning((object)$"BROKE : {arg}");
				}
			}
		}
	}
	public static class StatusEffectManagerVersion
	{
		public const string Version = "1.0.0";
	}
}
namespace SoundMixManager
{
	public static class AudioMixerFix
	{
		private static readonly Harmony _harmony;

		private static ManualLogSource Logger;

		private static readonly List<Hook> _hooks;

		private static bool _hooksInstalled;

		private static readonly List<GameObject> TrackedPrefabs;

		private static readonly HashSet<AudioMixer> KnownDuplicateMixers;

		private static bool _fixedOnce;

		private static readonly Type EffectListType;

		private static readonly Type GameObjectType;

		private static readonly Type GameObjectArrayType;

		private static readonly Type GameObjectListType;

		static AudioMixerFix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_harmony = new Harmony("org.bepinex.helpers.Armory.AudioMixerFix");
			_hooks = new List<Hook>();
			TrackedPrefabs = new List<GameObject>();
			KnownDuplicateMixers = new HashSet<AudioMixer>();
			EffectListType = typeof(EffectList);
			GameObjectType = typeof(GameObject);
			GameObjectArrayType = typeof(GameObject[]);
			GameObjectListType = typeof(List<GameObject>);
			_harmony.PatchAll(typeof(AudioMixerFix));
		}

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
			if (!_hooksInstalled)
			{
				_hooksInstalled = true;
				InstallRegistrationHooks();
			}
			Logger.LogDebug((object)"AudioMixerFix initialized.");
		}

		private static void Install(string label, MethodBase target, Delegate hook)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if (target == null)
			{
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("Could not find " + label + " - prefabs registered through it won't get the audio fix."));
				}
				return;
			}
			try
			{
				_hooks.Add(new Hook(target, hook));
				ManualLogSource logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogDebug((object)("Hooked " + label));
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger3 = Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)$"Failed to hook {label}: {arg}");
				}
			}
		}

		public static void Track(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				TrackedPrefabs.Add(prefab);
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("Track: " + ((Object)prefab).name));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioMan), "Awake")]
		private static void Postfix_AudioManAwake(AudioMan __instance)
		{
			if (_fixedOnce || (Object)(object)__instance.m_masterMixer == (Object)null)
			{
				return;
			}
			_fixedOnce = true;
			AudioMixer masterMixer = __instance.m_masterMixer;
			ManualLogSource logger = Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"Postfix_AudioManAwake firing. TrackedPrefabs={TrackedPrefabs.Count}, realMixer={((Object)masterMixer).name}");
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			foreach (GameObject trackedPrefab in TrackedPrefabs)
			{
				if ((Object)(object)trackedPrefab == (Object)null)
				{
					continue;
				}
				try
				{
					FixPrefabAndEffects(trackedPrefab, masterMixer, hashSet);
				}
				catch (Exception arg)
				{
					ManualLogSource logger2 = Logger;
					if (logger2 != null)
					{
						logger2.LogError((object)$"Exception fixing prefab '{((Object)trackedPrefab).name}': {arg}");
					}
				}
			}
			ManualLogSource logger3 = Logger;
			if (logger3 != null)
			{
				logger3.LogDebug((object)$"Postfix_AudioManAwake done. KnownDuplicateMixers={KnownDuplicateMixers.Count}, EffectPrefabsVisited={hashSet.Count}");
			}
		}

		private static void FixPrefabAndEffects(GameObject prefab, AudioMixer realMixer, HashSet<GameObject> visited)
		{
			if ((Object)(object)prefab == (Object)null || !visited.Add(prefab))
			{
				return;
			}
			AudioSource[] componentsInChildren = prefab.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource src in componentsInChildren)
			{
				FixAudioSource(src, realMixer);
			}
			Component[] componentsInChildren2 = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					Type fieldType = fieldInfo.FieldType;
					bool flag = fieldType == EffectListType;
					bool flag2 = fieldType == GameObjectType;
					bool flag3 = fieldType == GameObjectArrayType;
					bool flag4 = fieldType == GameObjectListType;
					if (!flag && !flag2 && !flag3 && !flag4)
					{
						continue;
					}
					object value;
					try
					{
						value = fieldInfo.GetValue(val);
					}
					catch (Exception ex)
					{
						ManualLogSource logger = Logger;
						if (logger != null)
						{
							logger.LogWarning((object)("Could not read field '" + fieldInfo.Name + "' on '" + type.Name + "' (" + ((Object)prefab).name + "): " + ex.Message));
						}
						continue;
					}
					if (flag)
					{
						EffectList val2 = (EffectList)((value is EffectList) ? value : null);
						if (val2 == null)
						{
							continue;
						}
						EffectData[] effectPrefabs = val2.m_effectPrefabs;
						if (effectPrefabs == null)
						{
							continue;
						}
						EffectData[] array = effectPrefabs;
						for (int l = 0; l < array.Length; l++)
						{
							GameObject val3 = array[l]?.m_prefab;
							if (!((Object)(object)val3 == (Object)null))
							{
								ManualLogSource logger2 = Logger;
								if (logger2 != null)
								{
									logger2.LogDebug((object)("Following EffectList '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> effect prefab '" + ((Object)val3).name + "'"));
								}
								FixPrefabAndEffects(val3, realMixer, visited);
							}
						}
					}
					else if (flag2)
					{
						GameObject val4 = (GameObject)((value is GameObject) ? value : null);
						if (val4 != null && !((Object)(object)val4 == (Object)null))
						{
							ManualLogSource logger3 = Logger;
							if (logger3 != null)
							{
								logger3.LogDebug((object)("Following GameObject field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)val4).name + "'"));
							}
							FixPrefabAndEffects(val4, realMixer, visited);
						}
					}
					else if (flag3)
					{
						if (!(value is GameObject[] array2))
						{
							continue;
						}
						GameObject[] array3 = array2;
						foreach (GameObject val5 in array3)
						{
							if (!((Object)(object)val5 == (Object)null))
							{
								ManualLogSource logger4 = Logger;
								if (logger4 != null)
								{
									logger4.LogDebug((object)("Following GameObject[] field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)val5).name + "'"));
								}
								FixPrefabAndEffects(val5, realMixer, visited);
							}
						}
					}
					else
					{
						if (!flag4 || !(value is List<GameObject> list))
						{
							continue;
						}
						foreach (GameObject item in list)
						{
							if (!((Object)(object)item == (Object)null))
							{
								ManualLogSource logger5 = Logger;
								if (logger5 != null)
								{
									logger5.LogDebug((object)("Following List<GameObject> field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)item).name + "'"));
								}
								FixPrefabAndEffects(item, realMixer, visited);
							}
						}
					}
				}
			}
		}

		private static void FixAudioSource(AudioSource src, AudioMixer realMixer)
		{
			if ((Object)(object)src.outputAudioMixerGroup == (Object)null)
			{
				AudioMixerGroup[] array = realMixer.FindMatchingGroups("SFX");
				if (array.Length == 0)
				{
					array = realMixer.FindMatchingGroups("Sfx");
				}
				if (array.Length != 0)
				{
					ManualLogSource logger = Logger;
					if (logger != null)
					{
						logger.LogDebug((object)("Assigned mixer group to previously-ungrouped AudioSource '" + ((Object)((Component)src).gameObject).name + "': null -> " + ((Object)realMixer).name + "/" + ((Object)array[0]).name));
					}
					src.outputAudioMixerGroup = array[0];
				}
				else
				{
					ManualLogSource logger2 = Logger;
					if (logger2 != null)
					{
						logger2.LogWarning((object)("AudioSource '" + ((Object)((Component)src).gameObject).name + "' has no mixer group and no SFX/Sfx group found on real mixer '" + ((Object)realMixer).name + "' - left ungrouped."));
					}
				}
				if (src.bypassEffects)
				{
					src.bypassEffects = false;
				}
				return;
			}
			AudioMixer audioMixer = src.outputAudioMixerGroup.audioMixer;
			if ((Object)(object)audioMixer == (Object)(object)realMixer)
			{
				if (src.bypassEffects)
				{
					src.bypassEffects = false;
				}
				return;
			}
			KnownDuplicateMixers.Add(audioMixer);
			string name = ((Object)src.outputAudioMixerGroup).name;
			AudioMixerGroup[] array2 = realMixer.FindMatchingGroups(name);
			if (array2.Length == 0)
			{
				array2 = realMixer.FindMatchingGroups("SFX");
			}
			if (array2.Length == 0)
			{
				array2 = realMixer.FindMatchingGroups("Sfx");
			}
			if (array2.Length != 0)
			{
				ManualLogSource logger3 = Logger;
				if (logger3 != null)
				{
					logger3.LogDebug((object)("Fixed AudioSource '" + ((Object)((Component)src).gameObject).name + "': " + ((Object)audioMixer).name + "/" + name + " -> " + ((Object)realMixer).name + "/" + ((Object)array2[0]).name));
				}
				src.outputAudioMixerGroup = array2[0];
			}
			else
			{
				ManualLogSource logger4 = Logger;
				if (logger4 != null)
				{
					logger4.LogWarning((object)("No matching group for '" + name + "' (or SFX/Sfx fallback) on real mixer '" + ((Object)realMixer).name + "' - '" + ((Object)((Component)src).gameObject).name + "' left unfixed."));
				}
			}
			if (src.bypassEffects)
			{
				src.bypassEffects = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZSFX), "Awake")]
		private static void ZsfxCatchAll(ZSFX __instance)
		{
			if (KnownDuplicateMixers.Count == 0)
			{
				return;
			}
			AudioSource component = ((Component)__instance).GetComponent<AudioSource>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.outputAudioMixerGroup == (Object)null)
			{
				return;
			}
			AudioMixer audioMixer = component.outputAudioMixerGroup.audioMixer;
			if (!KnownDuplicateMixers.Contains(audioMixer))
			{
				return;
			}
			AudioMan instance = AudioMan.instance;
			AudioMixer val = (((Object)(object)instance != (Object)null) ? instance.m_masterMixer : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string name = ((Object)component.outputAudioMixerGroup).name;
			AudioMixerGroup[] array = val.FindMatchingGroups(name);
			if (array.Length == 0)
			{
				array = val.FindMatchingGroups("SFX");
			}
			if (array.Length == 0)
			{
				array = val.FindMatchingGroups("Sfx");
			}
			if (array.Length != 0)
			{
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("ZsfxCatchAll fixed '" + ((Object)((Component)__instance).gameObject).name + "': " + ((Object)audioMixer).name + "/" + name + " -> " + ((Object)val).name + "/" + ((Object)array[0]).name));
				}
				component.outputAudioMixerGroup = array[0];
			}
			if (component.bypassEffects)
			{
				component.bypassEffects = false;
			}
		}

		private static void InstallRegistrationHooks()
		{
			Install("ItemManager.PrefabManager.RegisterPrefab", AccessTools.Method(typeof(PrefabManager), "RegisterPrefab", new Type[3]
			{
				typeof(AssetBundle),
				typeof(string),
				typeof(bool)
			}, (Type[])null), (Func<Func<AssetBundle, string, bool, GameObject>, AssetBundle, string, bool, GameObject>)delegate(Func<AssetBundle, string, bool, GameObject> orig, AssetBundle assets, string prefabName, bool flag)
			{
				GameObject val = orig(assets, prefabName, flag);
				Track(val);
				return val;
			});
			Install("PieceManager.PiecePrefabManager.RegisterPrefab", AccessTools.Method(typeof(PiecePrefabManager), "RegisterPrefab", new Type[2]
			{
				typeof(AssetBundle),
				typeof(string)
			}, (Type[])null), (Func<Func<AssetBundle, string, GameObject>, AssetBundle, string, GameObject>)delegate(Func<AssetBundle, string, GameObject> orig, AssetBundle assets, string prefabName)
			{
				GameObject val = orig(assets, prefabName);
				Track(val);
				return val;
			});
		}
	}
}
namespace SkillManager
{
	[PublicAPI]
	public class Skill
	{
		public static class LocalizationCache
		{
			private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>();

			internal static void LocalizationPostfix(Localization __instance, string language)
			{
				string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key;
				if (key != null)
				{
					localizations.Remove(key);
				}
				if (!localizations.ContainsKey(language))
				{
					localizations.Add(language, __instance);
				}
			}

			public static Localization ForLanguage(string? language = null)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value))
				{
					return value;
				}
				value = new Localization();
				if (language != null)
				{
					value.SetupLanguage(language);
				}
				return value;
			}
		}

		[PublicAPI]
		public class LocalizeKey
		{
			private static readonly List<LocalizeKey> keys = new List<LocalizeKey>();

			public readonly string Key;

			public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>();

			public LocalizeKey(string key)
			{
				Key = key.Replace("$", "");
				keys.Add(this);
			}

			public void Alias(string alias)
			{
				Localizations.Clear();
				if (!alias.Contains("$"))
				{
					alias = "$" + alias;
				}
				Localizations["alias"] = alias;
				if (Localization.m_instance != null)
				{
					Localization.instance.AddWord(Key, Localization.instance.Localize(alias));
				}
			}

			public LocalizeKey English(string key)
			{
				return addForLang("English", key);
			}

			public LocalizeKey Swedish(string key)
			{
				return addForLang("Swedish", key);
			}

			public LocalizeKey French(string key)
			{
				return addForLang("French", key);
			}

			public LocalizeKey Italian(string key)
			{
				return addForLang("Italian", key);
			}

			public LocalizeKey German(string key)
			{
				return addForLang("German", key);
			}

			public LocalizeKey Spanish(string key)
			{
				return addForLang("Spanish", key);
			}

			public LocalizeKey Russian(string key)
			{
				return addForLang("Russian", key);
			}

			public LocalizeKey Romanian(string key)
			{
				return addForLang("Romanian", key);
			}

			public LocalizeKey Bulgarian(string key)
			{
				return addForLang("Bulgarian", key);
			}

			public LocalizeKey Macedonian(string key)
			{
				return addForLang("Macedonian", key);
			}

			public LocalizeKey Finnish(string key)
			{
				return addForLang("Finnish", key);
			}

			public LocalizeKey Danish(string key)
			{
				return addForLang("Danish", key);
			}

			public LocalizeKey Norwegian(string key)
			{
				return addForLang("Norwegian", key);
			}

			public LocalizeKey Icelandic(string key)
			{
				return addForLang("Icelandic", key);
			}

			public LocalizeKey Turkish(string key)
			{
				return addForLang("Turkish", key);
			}

			public LocalizeKey Lithuanian(string key)
			{
				return addForLang("Lithuanian", key);
			}

			public LocalizeKey Czech(string key)
			{
				return addForLang("Czech", key);
			}

			public LocalizeKey Hungarian(string key)
			{
				return addForLang("Hungarian", key);
			}

			public LocalizeKey Slovak(string key)
			{
				return addForLang("Slovak", key);
			}

			public LocalizeKey Polish(string key)
			{
				return addForLang("Polish", key);
			}

			public LocalizeKey Dutch(string key)
			{
				return addForLang("Dutch", key);
			}

			public LocalizeKey Portuguese_European(string key)
			{
				return addForLang("Portuguese_European", key);
			}

			public LocalizeKey Portuguese_Brazilian(string key)
			{
				return addForLang("Portuguese_Brazilian", key);
			}

			public LocalizeKey Chinese(string key)
			{
				return addForLang("Chinese", key);
			}

			public LocalizeKey Japanese(string key)
			{
				return addForLang("Japanese", key);
			}

			public LocalizeKey Korean(string key)
			{
				return addForLang("Korean", key);
			}

			public LocalizeKey Hindi(string key)
			{
				return addForLang("Hindi", key);
			}

			public LocalizeKey Thai(string key)
			{
				return addForLang("Thai", key);
			}

			public LocalizeKey Abenaki(string key)
			{
				return addForLang("Abenaki", key);
			}

			public LocalizeKey Croatian(string key)
			{
				return addForLang("Croatian", key);
			}

			public LocalizeKey Georgian(string key)
			{
				return addForLang("Georgian", key);
			}

			public LocalizeKey Greek(string key)
			{
				return addForLang("Greek", key);
			}

			public LocalizeKey Serbian(string key)
			{
				return addForLang("Serbian", key);
			}

			public LocalizeKey Ukrainian(string key)
			{
				return addForLang("Ukrainian", key);
			}

			private LocalizeKey addForLang(string lang, string value)
			{
				Localizations[lang] = value;
				if (Localization.m_instance != null)
				{
					if (Localization.instance.GetSelectedLanguage() == lang)
					{
						Localization.instance.AddWord(Key, value);
					}
					else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key))
					{
						Localization.instance.AddWord(Key, value);
					}
				}
				return this;
			}

			[HarmonyPriority(300)]
			internal static void AddLocalizedKeys(Localization __instance, string language)
			{
				foreach (LocalizeKey key in keys)
				{
					string value2;
					if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value))
					{
						__instance.AddWord(key.Key, value);
					}
					else if (key.Localizations.TryGetValue("alias", out value2))
					{
						__instance.AddWord(key.Key, Localization.instance.Localize(value2));
					}
				}
			}
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public string? Category;
		}

		[HarmonyPatch(typeof(Skills), "IsSkillValid")]
		private static class Patch_Skills_IsSkillValid
		{
			private static void Postfix(SkillType type, ref bool __result)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (!__result && skills.ContainsKey(type))
				{
					__result = true;
				}
			}
		}

		private static readonly Dictionary<SkillType, Skill> skills;

		internal static readonly Dictionary<string, Skill> skillByName;

		private readonly string skillName;

		private readonly string internalSkillName;

		private readonly SkillDef skillDef;

		public readonly LocalizeKey Name;

		public readonly LocalizeKey Description;

		private float skillEffectFactor = 1f;

		private int skillLoss = 5;

		public bool Configurable = false;

		private static bool InitializedTerminal;

		private static Localization? _english;

		private static BaseUnityPlugin? _plugin;

		private static bool hasConfigSync;

		private static object? _configSync;

		public float SkillGainFactor
		{
			get
			{
				return skillDef.m_increseStep;
			}
			set
			{
				skillDef.m_increseStep = value;
				this.SkillGainFactorChanged?.Invoke(value);
			}
		}

		public float SkillEffectFactor
		{
			get
			{
				return skillEffectFactor;
			}
			set
			{
				skillEffectFactor = value;
				this.SkillEffectFactorChanged?.Invoke(value);
			}
		}

		public int SkillLoss
		{
			get
			{
				return skillLoss;
			}
			set
			{
				skillLoss = value;
				this.SkillLossChanged?.Invoke(value);
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Expected O, but got Unknown
				object obj = _plugin;
				if (obj == null)
				{
					BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
					_plugin = val;
					obj = (object)val;
				}
				return (BaseUnityPlugin)obj;
			}
		}

		private static object? configSync
		{
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		public event Action<float>? SkillGainFactorChanged;

		public event Action<float>? SkillEffectFactorChanged;

		public event Action<float>? SkillLossChanged;

		public Skill(string englishName, string icon)
			: this(englishName, loadSprite(icon, 64, 64))
		{
		}

		public unsafe Skill(string englishName, Sprite icon)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			SkillType val = fromName(englishName);
			string text = new Regex("[^a-zA-Z]").Replace(englishName, "_");
			skills[val] = this;
			skillByName[englishName] = this;
			skillDef = new SkillDef
			{
				m_description = "$skilldesc_" + text,
				m_icon = icon,
				m_increseStep = 1f,
				m_skill = val
			};
			internalSkillName = text;
			skillName = englishName;
			Name = new LocalizeKey("skill_" + ((object)(*(SkillType*)(&val))/*cast due to .constrained prefix*/).ToString()).English(englishName);
			Description = new LocalizeKey("skilldesc_" + text);
		}

		public static SkillType fromName(string englishName)
		{
			return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName));
		}

		static Skill()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01ad: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			//IL_023f: Expected O, but got Unknown
			skills = new Dictionary<SkillType, Skill>();
			skillByName = new Dictionary<string, Skill>();
			InitializedTerminal = false;
			hasConfigSync = true;
			Harmony val = new Harmony("org.bepinex.helpers.skillmanager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null);
		}

		private static void Patch_FejdStartup()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			foreach (Skill skill in skills.Values)
			{
				if (skill.Configurable)
				{
					string key = skill.Name.Key;
					string text = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim();
					string category = Localization.instance.Localize(key).Trim();
					ConfigEntry<float> skillGain = config(text, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillGainFactor = skillGain.Value;
					skillGain.SettingChanged += delegate
					{
						skill.SkillGainFactor = skillGain.Value;
					};
					ConfigEntry<float> skillEffect = config(text, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillEffectFactor = skillEffect.Value;
					skillEffect.SettingChanged += delegate
					{
						skill.SkillEffectFactor = skillEffect.Value;
					};
					ConfigEntry<int> skillLoss = config(text, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.skillLoss = skillLoss.Value;
					skillLoss.SettingChanged += delegate
					{
						skill.skillLoss = skillLoss.Value;
					};
				}
			}
		}

		private static void Patch_Skills_GetSkillDef(ref SkillDef? __result, List<SkillDef> ___m_skills, SkillType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null)
			{
				SkillDef val = GetSkillDef(type);
				if (val != null)
				{
					___m_skills.Add(val);
					__result = val;
				}
			}
		}

		private unsafe static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				Skill skill = skills[key];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					Skill skill2 = __instance.GetSkill(key);
					skill2.m_level += value;
					skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f);
					((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(*(SkillType*)(&key))/*cast due to .constrained prefix*/).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon, false);
					Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level);
					return false;
				}
			}
			return true;
		}

		private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				Skill skill = skills[key];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					__instance.ResetSkill(key);
					Console.instance.Print("Skill " + skill.internalSkillName + " reset");
					return false;
				}
			}
			return true;
		}

		private static void Patch_Skills_OnDeath_Prefix(Skills __instance, ref Dictionary<SkillType, Skill>? __state)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				__state = new Dictionary<SkillType, Skill>();
			}
			foreach (KeyValuePair<SkillType, Skill> skill in skills)
			{
				if (__instance.m_skillData.TryGetValue(skill.Key, out var value))
				{
					__state[skill.Key] = value;
					if (skill.Value.skillLoss > 0)
					{
						Skill obj = value;
						obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f;
						value.m_accumulator = 0f;
					}
					__instance.m_skillData.Remove(skill.Key);
				}
			}
		}

		private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, ref Dictionary<SkillType, Skill>? __state)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				return;
			}
			foreach (KeyValuePair<SkillType, Skill> item in __state)
			{
				__instance.m_skillData[item.Key] = item.Value;
			}
			__state = null;
		}

		private static void Patch_Terminal_InitTerminal_Prefix()
		{
			InitializedTerminal = Terminal.m_terminalInitialized;
		}

		private static void Patch_Terminal_InitTerminal()
		{
			if (!InitializedTerminal)
			{
				AddSkill(Terminal.commands["raiseskill"]);
				AddSkill(Terminal.commands["resetskill"]);
			}
			static void AddSkill(ConsoleCommand command)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected O, but got Unknown
				ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher;
				command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)delegate
				{
					List<string> list = fetcher.Invoke();
					list.AddRange(skills.Values.Select((Skill skill) => skill.internalSkillName));
					return list;
				};
			}
		}

		private static SkillDef? GetSkillDef(SkillType skillType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!skills.ContainsKey(skillType))
			{
				return null;
			}
			Skill skill = skills[skillType];
			return skill.skillDef;
		}

		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D loadTexture(string name)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		private static Sprite loadSprite(string name, int width, int height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description);
			configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T))
				.Invoke(configSync, new object[1] { val });
			return val;
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	public static class SkillManagerVersion
	{
		public const string Version = "1.7.0";
	}
	[PublicAPI]
	public static class SkillExtensions
	{
		public static float GetSkillFactor(this Character character, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static float GetSkillFactor(this Skills skills, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static void RaiseSkill(this Character character, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			character.RaiseSkill(Skill.fromName(name), value);
		}

		public static void RaiseSkill(this Skills skill, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			skill.RaiseSkill(Skill.fromName(name), value);
		}

		public static void LowerSkill(this Character character, string name, float factor = 1f)
		{
			character.GetSkills().LowerSkill(name, factor);
		}

		public static void LowerSkill(this Skills skills, string name, float factor)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (factor > 0f && skills.m_skillData.TryGetValue(Skill.fromName(name), out var value))
			{
				Skill obj = value;
				obj.m_level -= value.m_level * factor;
				value.m_accumulator = 0f;
			}
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public static event Action? OnLocalizationComplete;

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out var value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out var value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			_ = plugin;
		}

		public static void LoadLocalizationLater(Localization __instance)
		{
			LoadLocalization(Localization.instance, __instance.GetSelectedLanguage());
		}

		public static void SafeCallLocalizeComplete()
		{
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string[] array = Path.GetFileNameWithoutExtension(item).Split('.');
				if (array.Length >= 2)
				{
					string text = array[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
			}
			byte[] array2 = LoadTranslationFromAssembly("English");
			if (array2 == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.TryGetValue(language, out var value))
				{
					text2 = File.ReadAllText(value);
				}
				else
				{
					byte[] array3 = LoadTranslationFromAssembly(language);
					if (array3 != null)
					{
						text2 = Encoding.UTF8.GetString(array3);
					}
				}
			}
			if (text2 == null && dictionary.TryGetValue("English", out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string>(2) { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager." + Assembly.GetExecutingAssembly().GetName().Name);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	public static class LocalizationManagerVersion
	{
		public const string Version = "1.4.3";
	}
}
namespace ItemManager
{
	[PublicAPI]
	public enum CraftingTable
	{
		Disabled,
		Inventory,
		[InternalName("piece_workbench")]
		Workbench,
		[InternalName("piece_cauldron")]
		Cauldron,
		[InternalName("piece_MeadCauldron")]
		MeadCauldron,
		[InternalName("forge")]
		Forge,
		[InternalName("piece_artisanstation")]
		ArtisanTable,
		[InternalName("piece_stonecutter")]
		StoneCutter,
		[InternalName("piece_magetable")]
		MageTable,
		[InternalName("piece_preptable")]
		PrepTable,
		[InternalName("blackforge")]
		BlackForge,
		Custom
	}
	[PublicAPI]
	public enum ConversionPiece
	{
		Disabled,
		[InternalName("smelter")]
		Smelter,
		[InternalName("charcoal_kiln")]
		CharcoalKiln,
		[InternalName("blastfurnace")]
		BlastFurnace,
		[InternalName("windmill")]
		Windmill,
		[InternalName("piece_spinningwheel")]
		SpinningWheel,
		[InternalName("eitrrefinery")]
		EitrRefinery,
		Custom
	}
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[PublicAPI]
	public class RequiredResourceList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public bool Free = false;

		public void Add(string itemName, int amount, int quality = 0, bool upgraderResource = false)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amount = amount,
				quality = quality,
				upgraderResource = upgraderResource
			});
		}

		public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0, bool upgraderResource = false)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amountConfig = amountConfig,
				quality = quality,
				upgraderResource = upgraderResource
			});
		}
	}
	[PublicAPI]
	public class CraftingStationList
	{
		public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>();

		public void Add(CraftingTable table, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = table,
				level = level
			});
		}

		public void Add(string customTable, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = CraftingTable.Custom,
				level = level,
				custom = customTable
			});
		}
	}
	[PublicAPI]
	public class ItemRecipe
	{
		public readonly RequiredResourceList RequiredItems = new RequiredResourceList();

		public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList();

		public readonly CraftingStationList Crafting = new CraftingStationList();

		public int CraftAmount = 1;

		public bool RequireOnlyOneIngredient = false;

		public float QualityResultAmountMultiplier = 1f;

		public ConfigEntryBase? RecipeIsActive = null;
	}
	[PublicAPI]
	public class Trade
	{
		public Trader Trader = Trader.None;

		public uint Price = 0u;

		public uint Stack = 1u;

		public string? RequiredGlobalKey = null;
	}
	[PublicAPI]
	[Flags]
	public enum Trader
	{
		None = 0,
		Haldor = 1,
		Hildir = 2
	}
	public struct Requirement
	{
		public string itemName;

		public int amount;

		public ConfigEntry<int>? amountConfig;

		[Description("Set to a non-zero value to apply the requirement only for a specific quality")]
		public int quality;

		public bool upgraderResource;
	}
	public struct CraftingStationConfig
	{
		public CraftingTable Table;

		public int level;

		public string? custom;
	}
	[Flags]
	public enum Configurability
	{
		Disabled = 0,
		Recipe = 1,
		Stats = 2,
		Drop = 4,
		Trader = 8,
		Full = 0xF
	}
	[PublicAPI]
	public class DropTargets
	{
		public readonly List<DropTarget> Drops = new List<DropTarget>();

		public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true)
		{
			Drops.Add(new DropTarget
			{
				creature = creatureName,
				chance = chance,
				min = min,
				max = (max ?? min),
				levelMultiplier = levelMultiplier
			});
		}
	}
	public struct DropTarget
	{
		public string creature;

		public int min;

		public int max;

		public float chance;

		public bool levelMultiplier;
	}
	public enum Toggle
	{
		On = 1,
		Off = 0
	}
	[PublicAPI]
	public class Item
	{
		private class ItemConfig
		{
			public ConfigEntry<string>? craft;

			public ConfigEntry<string>? upgrade;

			public ConfigEntry<CraftingTable> table = null;

			public ConfigEntry<int> tableLevel = null;

			public ConfigEntry<string> customTable = null;

			public ConfigEntry<int>? maximumTableLevel;

			public ConfigEntry<Toggle> requireOneIngredient = null;

			public ConfigEntry<float> qualityResultAmountMultiplier = null;
		}

		private class TraderConfig
		{
			public ConfigEntry<Trader> trader = null;

			public ConfigEntry<uint> price = null;

			public ConfigEntry<uint> stack = null;

			public ConfigEntry<string> requiredGlobalKey = null;
		}

		private class RequirementQuality
		{
			public int quality;
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string? Category;

			[UsedImplicitly]
			public Action<ConfigEntryBase>? CustomDrawer;

			public Func<bool>? browsability;
		}

		[PublicAPI]
		public enum DamageModifier
		{
			Normal,
			Resistant,
			Weak,
			Immune,
			Ignore,
			VeryResistant,
			VeryWeak,
			None
		}

		private delegate void setDmgFunc(ref DamageTypes dmg, float value);

		private class SerializedRequirements
		{
			public readonly List<Requirement> Reqs;

			public SerializedRequirements(List<Requirement> reqs)
			{
				Reqs = reqs;
			}

			public SerializedRequirements(string reqs)
				: this(reqs.Split(',').Select(delegate(string r)
				{
					string[] array = r.Split(':');
					int result;
					int result2;
					return new Requirement
					{
						itemName = array[0],
						amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result),
						quality = ((array.Length > 2 && int.TryParse(array[2], out result2)) ? result2 : 0),
						upgraderResource = (array.Length > 3 && array[3] == "U")
					};
				}).ToList())
			{
			}

			public override string ToString()
			{
				return string.Join(",", Reqs.Select(delegate(Requirement r)
				{
					string text = $"{r.itemName}:{r.amount}";
					if (r.quality > 0 || r.upgraderResource)
					{
						text += $":{r.quality}";
					}
					if (r.upgraderResource)
					{
						text += ":U";
					}
					return text;
				}));
			}

			public static ItemDrop? fetchByName(ObjectDB objectDB, string name)
			{
				GameObject itemPrefab = objectDB.GetItemPrefab(name);
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)("The required item '" + name + "' does not exist."));
				}
				return val;
			}

			public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade)
			{
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0201: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Expected O, but got Unknown
				//IL_0209: Expected O, but got Unknown
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Expected O, but got Unknown
				Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)((Requirement r) => r.itemName), (Func<Requirement, Requirement>)delegate(Requirement r)
				{
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Unknown result type (might be due to invalid IL o