Decompiled source of Skyheim v1.3.11

skyheim.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SimpleJSON;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;
using UnityEngine.UI;
using skyheim;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("skyheim")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("skyheim")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("454bec7c-7837-4169-b004-c0b761e01612")]
[assembly: AssemblyFileVersion("1.3.11.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.11.0")]
[module: UnverifiableCode]
public class AssetManager
{
	public static AssetBundle AssetBundle;

	public static Object[] AssetBundleObjects;

	public static UnityAction<ZNetScene> OnSceneAwake;

	public static UnityAction<ObjectDB> OnObjectDBAwake;

	public static void Create(Harmony harmony, string assetBundle)
	{
		harmony.PatchAll(typeof(AssetManager));
		LoadAssetsFromBundle(assetBundle);
	}

	public static void LoadAssetsFromBundle(string bundleName)
	{
		AssetBundle = GetAssetBundleFromResources(bundleName);
		AssetBundleObjects = AssetBundle.LoadAllAssets();
	}

	public static AssetBundle GetAssetBundleFromResources(string fileName)
	{
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(fileName));
		using Stream stream = executingAssembly.GetManifestResourceStream(name);
		return AssetBundle.LoadFromStream(stream);
	}

	public static IEnumerable<T> GetGameObjects<T>() where T : Component
	{
		Object[] assetBundleObjects = AssetBundleObjects;
		foreach (Object obj in assetBundleObjects)
		{
			GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
			if (val != null)
			{
				T component = val.GetComponent<T>();
				if (component != null)
				{
					yield return component;
				}
			}
		}
	}

	public static T GetGameObject<T>(string id) where T : Component
	{
		Object[] assetBundleObjects = AssetBundleObjects;
		foreach (Object obj in assetBundleObjects)
		{
			GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
			if (val != null && ((Object)val).name == id)
			{
				T component = val.GetComponent<T>();
				if (component != null)
				{
					return component;
				}
			}
		}
		return default(T);
	}

	public static GameObject GetGameObject(string id)
	{
		Object[] assetBundleObjects = AssetBundleObjects;
		foreach (Object obj in assetBundleObjects)
		{
			GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
			if (val != null && ((Object)val).name == id)
			{
				return val;
			}
		}
		return null;
	}

	public static IEnumerable<T> GetAssets<T>()
	{
		Object[] assetBundleObjects = AssetBundleObjects;
		foreach (Object val in assetBundleObjects)
		{
			if (val is T)
			{
				yield return (T)(object)((val is T) ? val : null);
			}
		}
	}

	public static T GetAsset<T>(string name)
	{
		Object[] assetBundleObjects = AssetBundleObjects;
		foreach (Object val in assetBundleObjects)
		{
			if (val.name == name && val is T)
			{
				return (T)(object)((val is T) ? val : null);
			}
		}
		return default(T);
	}

	public static T LoadAsset<T>(string name) where T : Object
	{
		return AssetBundle.LoadAsset<T>(name);
	}

	public static void LoadItems(ObjectDB db)
	{
		IEnumerable<ItemDrop> gameObjects = AssetManager.GetGameObjects<ItemDrop>();
		db.m_items.AddRange(gameObjects.Select((ItemDrop x) => ((Component)x).gameObject));
		db.UpdateItemHashes();
	}

	public static void RegisterRecipes(ObjectDB db)
	{
		db.m_recipes.AddRange(from x in GetAssets<SkyheimRecipe>()
			select x.Convert());
		db.m_recipes.AddRange(GetAssets<Recipe>());
	}

	public static void RegisterStatusEffects(ObjectDB db)
	{
		db.m_StatusEffects.AddRange(GetAssets<StatusEffect>());
	}

	public static void RegisterPieces()
	{
		foreach (SkyheimPieceData gameObject in AssetManager.GetGameObjects<SkyheimPieceData>())
		{
			ItemDrop tool = gameObject.Tool;
			if (tool != null)
			{
				List<GameObject> pieces = tool.m_itemData.m_shared.m_buildPieces.m_pieces;
				if (!pieces.Contains(((Component)gameObject).gameObject))
				{
					gameObject.Convert();
					pieces.Add(((Component)gameObject).gameObject);
				}
			}
		}
	}

	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	[HarmonyPostfix]
	public static void ObjectDB_Awake_Postfix(ObjectDB __instance)
	{
		if ((Object)(object)ZNetScene.instance != (Object)null)
		{
			OnObjectDBAwake?.Invoke(__instance);
			LoadItems(__instance);
			RegisterRecipes(__instance);
			RegisterStatusEffects(__instance);
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "SetupObjectDB")]
	[HarmonyPostfix]
	public static void FejdStartup_SetupObjectDB_Postfix(FejdStartup __instance)
	{
		LoadItems(((Component)__instance).GetComponent<ObjectDB>());
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	[HarmonyPostfix]
	public static void ZNetScene_Awake_Postfix(ZNetScene __instance)
	{
		foreach (ZNetView gameObject in AssetManager.GetGameObjects<ZNetView>())
		{
			__instance.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name), ((Component)gameObject).gameObject);
		}
		RegisterPieces();
		OnSceneAwake?.Invoke(__instance);
	}
}
public class AssetType : PropertyAttribute
{
	public Type Type { get; protected set; }

	public AssetType(Type type)
	{
		Type = type;
	}
}
public static class CommonUtils
{
	[Serializable]
	public class SerializableWrapper<T>
	{
		public T Value;

		public SerializableWrapper(T v)
		{
			Value = v;
		}
	}

	public struct DistanceSort : IComparer<Collider>
	{
		private Vector3 _target;

		public DistanceSort(Vector3 target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			_target = target;
		}

		public int Compare(Collider a, Collider b)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			Vector3 position = ((Component)a).transform.position;
			Vector3 position2 = ((Component)b).transform.position;
			return Vector3.Distance(position, _target).CompareTo(Vector3.Distance(position2, _target));
		}
	}

	public static long PlayerID => Game.instance.GetPlayerProfile().GetPlayerID();

	[Conditional("DEBUG")]
	public static void Log(string str)
	{
		Debug.Log((object)str);
	}

	[Conditional("DEBUG")]
	public static void LogFields(object obj)
	{
		FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
		foreach (FieldInfo obj2 in fields)
		{
			_ = obj2.Name;
			obj2.GetValue(obj);
		}
	}

	public static T ConvertPrefabReference<T>(string prefabReference) where T : Component
	{
		if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !string.IsNullOrEmpty(prefabReference))
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabReference);
			if ((Object)(object)prefab != (Object)null)
			{
				return prefab.GetComponent<T>();
			}
		}
		return default(T);
	}

	public static GameObject ConvertPrefabReference(string prefabReference)
	{
		if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !string.IsNullOrEmpty(prefabReference))
		{
			return ZNetScene.instance.GetPrefab(prefabReference);
		}
		return null;
	}

	public static T GetItemComponent<T>(ItemData item) where T : Component
	{
		if (item == null || !Object.op_Implicit((Object)(object)item.m_dropPrefab))
		{
			return default(T);
		}
		return item.m_dropPrefab.GetComponent<T>();
	}

	public static T Clone<T>(T obj)
	{
		return (T)obj.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(obj, null);
	}

	public static T Get<T>(this IDictionary dict, string key, T defaultValue = default(T))
	{
		if (dict.Contains(key))
		{
			return (T)Convert.ChangeType(dict[key], typeof(T));
		}
		return defaultValue;
	}

	public static JSONNode ToJSON<T>(T obj)
	{
		Type type = obj.GetType();
		if (obj is IList)
		{
			JSONArray jSONArray = new JSONArray();
			{
				foreach (object item in obj as IList)
				{
					jSONArray.Add(ToJSON(item));
				}
				return jSONArray;
			}
		}
		if (type.IsClass && !(obj is string))
		{
			Type type2 = obj.GetType();
			JSONObject jSONObject = new JSONObject();
			FieldInfo[] fields = type2.GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				jSONObject.Add(fieldInfo.Name, ToJSON(fieldInfo.GetValue(obj)));
			}
			return jSONObject;
		}
		return (JSONNode)typeof(JSONNode).GetMethod("op_Implicit", new Type[1] { obj.GetType() }).Invoke(null, new object[1] { obj });
	}
}
public class NameAttribute : PropertyAttribute
{
	public string Name { get; private set; }

	public NameAttribute(string name)
	{
		Name = name;
	}
}
public class PrefabReferenceType : PropertyAttribute
{
	public Type ComponentType { get; protected set; }

	public PrefabReferenceType(Type componentType)
	{
		ComponentType = componentType;
	}
}
public class SkyheimPieceData : MonoBehaviour, ISerializationCallbackReceiver
{
	[Header("Requirements")]
	[SerializeField]
	[PrefabReferenceType(typeof(CraftingStation))]
	[FormerlySerializedAs("m_craftingStation")]
	private string _craftingStation;

	[SerializeField]
	[PrefabReferenceType(typeof(ItemDrop))]
	[FormerlySerializedAs("m_craftingTool")]
	private string _craftingTool;

	[SerializeField]
	[PrefabReferenceType(typeof(Piece))]
	[FormerlySerializedAs("m_template")]
	private string _template;

	[SerializeField]
	[FormerlySerializedAs("m_resources")]
	private List<SkyheimRecipe.SkyheimRequirement> _resources;

	[SerializeField]
	[HideInInspector]
	[FormerlySerializedAs("m_resources_internal")]
	private string _resourcesInternal;

	public ItemDrop Tool => CommonUtils.ConvertPrefabReference<ItemDrop>(_craftingTool);

	public void Convert()
	{
		RuntimeDeserialize();
		Piece component = ((Component)this).GetComponent<Piece>();
		component.m_craftingStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_craftingStation);
		component.m_resources = ((IEnumerable<SkyheimRecipe.SkyheimRequirement>)_resources).Select((Func<SkyheimRecipe.SkyheimRequirement, Requirement>)((SkyheimRecipe.SkyheimRequirement x) => x)).ToArray();
		Piece val = (string.IsNullOrEmpty(_template) ? null : CommonUtils.ConvertPrefabReference<Piece>(_template));
		if (!((Object)(object)val != (Object)null))
		{
			return;
		}
		component.m_placeEffect = val.m_placeEffect;
		WearNTear component2 = ((Component)component).GetComponent<WearNTear>();
		if (Object.op_Implicit((Object)(object)component2))
		{
			WearNTear component3 = ((Component)val).GetComponent<WearNTear>();
			if (component3 != null)
			{
				component2.m_hitEffect = component3.m_hitEffect;
				component2.m_destroyedEffect = component3.m_destroyedEffect;
				component2.m_switchEffect = component3.m_switchEffect;
			}
		}
	}

	public void RuntimeDeserialize()
	{
		_resources = new List<SkyheimRecipe.SkyheimRequirement>();
		JSONNode.Enumerator enumerator = JSONNode.Parse(_resourcesInternal).AsArray.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<string, JSONNode> current = enumerator.Current;
			_resources.Add(new SkyheimRecipe.SkyheimRequirement(current.Value));
		}
	}

	public void OnBeforeSerialize()
	{
		JSONNode jSONNode = CommonUtils.ToJSON(_resources);
		_resourcesInternal = jSONNode.ToString();
	}

	public void OnAfterDeserialize()
	{
	}
}
[CreateAssetMenu(menuName = "Skyheim/Recipe")]
public class SkyheimRecipe : ScriptableObject, ISerializationCallbackReceiver
{
	[Serializable]
	public class SkyheimRequirement
	{
		[PrefabReferenceType(typeof(ItemDrop))]
		[FormerlySerializedAs("ResItem")]
		public string ResourceItem;

		[FormerlySerializedAs("m_amount")]
		public int Amount = 1;

		[FormerlySerializedAs("m_amountPerLevel")]
		public int AmountPerLevel = 1;

		[FormerlySerializedAs("m_recover")]
		public bool Recover = true;

		public SkyheimRequirement()
		{
		}

		public SkyheimRequirement(JSONNode j)
		{
			ResourceItem = j["ResourceItem"];
			Amount = j["Amount"];
			AmountPerLevel = j["AmountPerLevel"];
			Recover = j["Recover"];
		}

		public static implicit operator Requirement(SkyheimRequirement r)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			return new Requirement
			{
				m_resItem = CommonUtils.ConvertPrefabReference<ItemDrop>(r.ResourceItem),
				m_amount = r.Amount,
				m_amountPerLevel = r.AmountPerLevel,
				m_recover = r.Recover
			};
		}
	}

	[SerializeField]
	[PrefabReferenceType(typeof(ItemDrop))]
	[FormerlySerializedAs("m_item")]
	private string _item;

	[SerializeField]
	[FormerlySerializedAs("m_amount")]
	private int _amount = 1;

	[SerializeField]
	[FormerlySerializedAs("m_enabled")]
	private bool _enabled = true;

	[Header("Requirements")]
	[SerializeField]
	[PrefabReferenceType(typeof(CraftingStation))]
	[FormerlySerializedAs("m_craftingStation")]
	private string _craftingStation;

	[SerializeField]
	[PrefabReferenceType(typeof(CraftingStation))]
	[FormerlySerializedAs("m_repairStation")]
	private string _repairStation;

	[SerializeField]
	[FormerlySerializedAs("m_minStationLevel")]
	private int _minStationLevel = 1;

	[SerializeField]
	[FormerlySerializedAs("m_resources")]
	private List<SkyheimRequirement> _resources;

	[SerializeField]
	[HideInInspector]
	[FormerlySerializedAs("m_resources_internal")]
	private string _resourcesInternal;

	public Recipe Convert()
	{
		RuntimeDeserialize();
		Recipe obj = ScriptableObject.CreateInstance<Recipe>();
		((Object)obj).name = ((Object)this).name;
		obj.m_item = CommonUtils.ConvertPrefabReference<ItemDrop>(_item);
		obj.m_craftingStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_craftingStation);
		obj.m_repairStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_repairStation);
		obj.m_resources = ((IEnumerable<SkyheimRequirement>)_resources).Select((Func<SkyheimRequirement, Requirement>)((SkyheimRequirement x) => x)).ToArray();
		obj.m_amount = _amount;
		obj.m_enabled = _enabled;
		obj.m_minStationLevel = _minStationLevel;
		return obj;
	}

	public void RuntimeDeserialize()
	{
		JSONNode jSONNode = JSONNode.Parse(_resourcesInternal);
		_resources = new List<SkyheimRequirement>();
		JSONNode.Enumerator enumerator = jSONNode.AsArray.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<string, JSONNode> current = enumerator.Current;
			_resources.Add(new SkyheimRequirement(current.Value));
		}
	}

	public void OnBeforeSerialize()
	{
		JSONNode jSONNode = CommonUtils.ToJSON(_resources);
		_resourcesInternal = jSONNode.ToString();
	}

	public void OnAfterDeserialize()
	{
	}
}
public class ChainAoe : MonoBehaviour, IProjectile
{
	[Flags]
	public enum EHitFlags
	{
		None = 0,
		Owner = 1,
		Friendly = 2,
		Enemy = 4,
		Characters = 8,
		Props = 0x10
	}

	public float Radius = 10f;

	public int ChainCount = 5;

	public SkyheimItemData.ESkillType Skill;

	public EHitFlags HitFlags;

	public LineRenderer Chain;

	public float Lifetime = 1f;

	public float HitDelay = 0.1f;

	public string OriginJoint;

	public float ScaleMin = 1f;

	public float ScaleMax = 1f;

	public EffectList ImpactEffects = new EffectList();

	private ZNetView _nview;

	private Character _owner;

	private HitData _hitData;

	private int _rayMask;

	private Transform _chainOrigin;

	private readonly List<GameObject> _targets = new List<GameObject>();

	private readonly List<Collider> _colliders = new List<Collider>();

	private Vector3[] _positions;

	private int _hitIndex;

	protected void Awake()
	{
		_positions = (Vector3[])(object)new Vector3[ChainCount + 1];
		Chain.useWorldSpace = true;
		_nview = ((Component)this).GetComponentInParent<ZNetView>();
		if ((Object)(object)_nview != (Object)null && _nview.GetZDO() != null)
		{
			_nview.Register<ZPackage>("Trigger", (Action<long, ZPackage>)RPC_Trigger);
		}
	}

	public string GetTooltipString(int itemQuality)
	{
		return string.Empty;
	}

	public int GetRayMask()
	{
		if (_rayMask == 0)
		{
			if (HitFlags.HasFlag(EHitFlags.Characters))
			{
				_rayMask |= LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" });
			}
			if (HitFlags.HasFlag(EHitFlags.Props))
			{
				_rayMask |= LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "hitbox", "character_noenv", "vehicle" });
			}
		}
		return _rayMask;
	}

	public void Setup(Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemData item, ItemData ammo)
	{
		_hitData = hitData;
		_owner = owner;
	}

	private void UpdateChain()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		_positions[0] = (Object.op_Implicit((Object)(object)_chainOrigin) ? _chainOrigin.position : _owner.GetCenterPoint());
		for (int i = 0; i <= _hitIndex; i++)
		{
			Collider val = _colliders[i];
			if ((Object)(object)val != (Object)null)
			{
				Vector3[] positions = _positions;
				int num = i + 1;
				Bounds bounds = val.bounds;
				positions[num] = ((Bounds)(ref bounds)).center;
			}
		}
		Chain.positionCount = _hitIndex + 2;
		Chain.SetPositions(_positions);
		Chain.widthMultiplier = Random.Range(ScaleMin, ScaleMax);
		((Renderer)Chain).material.SetTextureOffset("_MainTex", Vector2.left * Time.time);
	}

	protected void FixedUpdate()
	{
		if (_targets.Count > 0)
		{
			UpdateChain();
		}
		if (_nview.IsOwner() && Lifetime > 0f)
		{
			Lifetime -= Time.fixedDeltaTime;
			if (Lifetime <= 0f)
			{
				ZNetScene.instance.Destroy(((Component)this).gameObject);
			}
		}
	}

	private IEnumerator StaggerVisuals()
	{
		int i = 0;
		while (i < _targets.Count)
		{
			_hitIndex = i;
			EffectList impactEffects = ImpactEffects;
			Bounds bounds = _colliders[i].bounds;
			impactEffects.Create(((Bounds)(ref bounds)).center, Quaternion.identity, (Transform)null, 1f, -1);
			yield return (object)new WaitForSecondsRealtime(HitDelay);
			int num = i + 1;
			i = num;
		}
	}

	private IEnumerator StaggerDamage()
	{
		int i = 0;
		while (i < _targets.Count)
		{
			yield return (object)new WaitForSecondsRealtime(HitDelay);
			GameObject obj = _targets[i];
			Collider val = _colliders[i];
			IDestructible component = obj.GetComponent<IDestructible>();
			Vector3 position = ((Component)val).transform.position;
			HitData val2 = CommonUtils.Clone<HitData>(_hitData);
			val2.m_hitCollider = val;
			Vector3 val3 = position - ((Component)this).transform.position;
			val2.m_dir = ((Vector3)(ref val3)).normalized;
			val2.m_point = position;
			component.Damage(val2);
			int num = i + 1;
			i = num;
		}
	}

	private void SeekTargets(Transform origin)
	{
		//IL_0001: 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)
		Collider[] array = Physics.OverlapSphere(origin.position, Radius, GetRayMask());
		Array.Sort(array, new CommonUtils.DistanceSort(origin.position));
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			GameObject val2 = Projectile.FindHitObject(val);
			if (IsValidTarget(_owner, val2))
			{
				_targets.Add(val2);
				if (_targets.Count < ChainCount)
				{
					SeekTargets(((Component)val).transform);
				}
				break;
			}
		}
	}

	public void Trigger(GameObject target)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)target) && _nview.IsOwner())
		{
			SeekTargets(target.transform);
			int count = _targets.Count;
			ZPackage val = new ZPackage();
			val.Write(((Component)_owner).GetComponent<ZNetView>().GetZDO().m_uid);
			val.Write(count);
			for (int i = 0; i < count; i++)
			{
				ZDOID uid = _targets[i].GetComponent<ZNetView>().GetZDO().m_uid;
				val.Write(uid);
			}
			_targets.Clear();
			_nview.InvokeRPC("Trigger", new object[1] { val });
			if (Object.op_Implicit((Object)(object)_owner) && _owner.IsPlayer() && Skill != 0)
			{
				_owner.RaiseSkill((SkillType)Skill, 1f);
			}
		}
	}

	public bool IsValidTarget(Character owner, GameObject gameObject)
	{
		IDestructible val = default(IDestructible);
		if (!gameObject.TryGetComponent<IDestructible>(ref val))
		{
			return false;
		}
		if (_targets.Contains(gameObject))
		{
			return false;
		}
		if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<ZNetView>()))
		{
			return false;
		}
		Character component = gameObject.GetComponent<Character>();
		if (component != null)
		{
			if (!HitFlags.HasFlag(EHitFlags.Characters))
			{
				return false;
			}
			if (!HitFlags.HasFlag(EHitFlags.Owner) && (Object)(object)component == (Object)(object)owner)
			{
				return false;
			}
			bool flag = BaseAI.IsEnemy(owner, component);
			if (!HitFlags.HasFlag(EHitFlags.Enemy) && flag)
			{
				return false;
			}
			if (!HitFlags.HasFlag(EHitFlags.Friendly) && !flag)
			{
				return false;
			}
		}
		else if (!HitFlags.HasFlag(EHitFlags.Props))
		{
			return false;
		}
		return true;
	}

	private void RPC_Trigger(long playerId, ZPackage data)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		ZDOID val = data.ReadZDOID();
		GameObject val2 = ZNetScene.instance.FindInstance(val);
		_owner = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Character>() : null);
		if ((Object)(object)_owner == (Object)null)
		{
			return;
		}
		if (!string.IsNullOrEmpty(OriginJoint))
		{
			_chainOrigin = Utils.FindChild(_owner.GetVisual().transform, OriginJoint, (IterativeSearchType)0);
		}
		int num = data.ReadInt();
		for (int i = 0; i < num; i++)
		{
			ZDOID val3 = data.ReadZDOID();
			GameObject val4 = ZNetScene.instance.FindInstance(val3);
			if ((Object)(object)val4 != (Object)null)
			{
				Collider componentInChildren = val4.GetComponentInChildren<Collider>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					_colliders.Add(componentInChildren);
					_targets.Add(val4);
				}
			}
		}
		((MonoBehaviour)this).StartCoroutine(StaggerVisuals());
		if (_nview.IsOwner())
		{
			((MonoBehaviour)this).StartCoroutine(StaggerDamage());
		}
	}
}
[CreateAssetMenu(menuName = "Skyheim/DropModifier")]
public class DropModifier : ScriptableObject
{
	[PrefabReferenceType(typeof(CharacterDrop))]
	public string EnemyDrop;

	[PrefabReferenceType(typeof(ItemDrop))]
	public string ItemDrop;

	public Drop Drop = new Drop();

	public void Apply()
	{
		Drop.m_prefab = ZNetScene.instance.GetPrefab(ItemDrop);
		ZNetScene.instance.GetPrefab(EnemyDrop).GetComponent<CharacterDrop>().m_drops.Add(Drop);
	}
}
public class SkyheimAltar : MonoBehaviour
{
	public enum ImbueType
	{
		Eitr
	}

	public Action OnProcessComplete;

	[SerializeField]
	private SkyheimAltarContainer _chest;

	[SerializeField]
	private GameObject _activeEffect;

	private bool _inUse;

	private static SkyheimAltarTuning s_tuning;

	private ZNetView _nview;

	private bool _processing;

	private float _startTime;

	private float _duration;

	public SkyheimAltarContainer Container => _chest;

	public bool Processing => _processing;

	public float TimeRemaining
	{
		get
		{
			float num = ZNet.instance.GetTime().Ticks / 10000000;
			return Mathf.Max(0f, _duration - (num - _startTime));
		}
	}

	private SkyheimAltarTuning Tuning
	{
		get
		{
			if ((Object)(object)s_tuning == (Object)null)
			{
				s_tuning = AssetManager.GetAsset<SkyheimAltarTuning>("altar_tuning");
				s_tuning.RuntimeDeserialize();
			}
			return s_tuning;
		}
	}

	private bool NetValidate
	{
		get
		{
			_ = (Object)(object)_nview == (Object)null;
			return (Object)(object)_nview != (Object)null;
		}
	}

	protected void Awake()
	{
		if (((Component)this).TryGetComponent<ZNetView>(ref _nview))
		{
			_nview.Register<float, float>("RPC_StartProcess", (Action<long, float, float>)RPC_StartProcess);
			_nview.Register<bool>("RPC_StopProcess", (Action<long, bool>)RPC_StopProcess);
		}
		Load();
		UpdateVisual();
	}

	private void Load()
	{
		ZDO zDO = _nview.GetZDO();
		if (zDO != null)
		{
			_processing = zDO.GetBool("Started", false);
			_startTime = zDO.GetFloat("StartTime", 0f);
			_duration = zDO.GetFloat("Duration", 0f);
		}
	}

	private void Save()
	{
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		if (NetValidate)
		{
			_nview.IsOwner();
			ZDO zDO = _nview.GetZDO();
			if (zDO != null)
			{
				zDO.Set("Started", _processing);
				zDO.Set("StartTime", _startTime);
				zDO.Set("Duration", _duration);
				ZDOMan.instance.ForceSendZDO(_nview.GetZDO().m_uid);
			}
		}
	}

	private void StartProcess(float duration)
	{
		if (NetValidate && _nview.IsOwner())
		{
			float startTime = ZNet.instance.GetTime().Ticks / 10000000;
			_processing = true;
			_startTime = startTime;
			_duration = duration;
			Save();
			_nview.InvokeRPC(0L, "RPC_StartProcess", new object[2] { _startTime, _duration });
		}
	}

	public void CancelProcess()
	{
		FinishProcess(completed: false);
	}

	public SkyheimArmorRecipe GetActiveRecipe()
	{
		foreach (SkyheimArmorRecipe recipe in Tuning.Recipes)
		{
			ItemData item = ((Container)_chest).GetInventory().GetItem(recipe.SourceItemDrop, -1, true);
			if (item != null && !item.m_customData.ContainsKey("sh_mod_type"))
			{
				return recipe;
			}
		}
		return null;
	}

	public bool HasEitrShards(SkyheimArmorRecipe recipe)
	{
		return ((Container)_chest).GetInventory().CountPrefabItems(Tuning.EitrShardPrefab) >= recipe.EitrShardsRequired;
	}

	private void FinishProcess(bool completed)
	{
		if (NetValidate && _processing && _nview.IsOwner())
		{
			_nview.InvokeRPC(0L, "RPC_StopProcess", new object[1] { completed });
		}
	}

	private void RPC_StartProcess(long playerID, float startTime, float duration)
	{
		_processing = true;
		_startTime = startTime;
		_duration = duration;
		UpdateVisual();
	}

	private void UpdateVisual()
	{
		_activeEffect.SetActive(_processing);
	}

	private void RPC_StopProcess(long playerID, bool completed)
	{
		_processing = false;
		UpdateVisual();
		if (_nview.IsOwner())
		{
			Save();
			if (completed)
			{
				CraftItem();
			}
		}
	}

	private void CraftItem()
	{
		foreach (SkyheimArmorRecipe recipe in Tuning.Recipes)
		{
			Inventory inventory = ((Container)_chest).GetInventory();
			bool flag = false;
			ItemData item = inventory.GetItem(recipe.SourceItemDrop, -1, true);
			if (item != null && !item.m_customData.ContainsKey("sh_mod_eitr") && inventory.CountPrefabItems(Tuning.EitrShardPrefab) >= recipe.EitrShardsRequired)
			{
				inventory.RemovePrefabItem(Tuning.EitrShardPrefab, recipe.EitrShardsRequired);
				item.m_customData["sh_mod_type"] = ImbueType.Eitr.ToString();
				item.m_customData["sh_mod_eitr"] = recipe.EitrModifier.ToString();
				item.m_customData["sh_mod_eitr_regen"] = recipe.EitrRegenModifier.ToString();
				item.m_customData["sh_mod_armor"] = recipe.ArmorModifier.ToString();
				item.m_customData["sh_mod_name"] = "Imbued " + item.m_shared.m_name;
				flag = true;
			}
			if (flag)
			{
				((Container)_chest).Save();
			}
		}
	}

	protected void Update()
	{
		if (_processing)
		{
			if (TimeRemaining <= 0f)
			{
				FinishProcess(completed: true);
				OnProcessComplete?.Invoke();
			}
		}
		else if (((Container)_chest).IsInUse() && ((Container)_chest).IsOwner())
		{
			_inUse = true;
		}
		else if (_inUse && !((Container)_chest).IsInUse())
		{
			_inUse = false;
			SkyheimArmorRecipe activeRecipe = GetActiveRecipe();
			if (activeRecipe != null && HasEitrShards(activeRecipe))
			{
				StartProcess(((Character)Player.m_localPlayer).InGodMode() ? 5f : activeRecipe.CraftingTime);
			}
		}
	}
}
public class ManaBar : MonoBehaviour
{
	[SerializeField]
	[FormerlySerializedAs("m_manaBar")]
	private GameObject _manaBar;

	[SerializeField]
	[FormerlySerializedAs("m_manaAnimator")]
	private Animator _manaAnimator;

	[SerializeField]
	[FormerlySerializedAs("m_manaBar2Root")]
	private RectTransform _manaBar2Root;

	[SerializeField]
	[FormerlySerializedAs("m_manaBar2Fast")]
	private GuiBar _manaBar2Fast;

	[SerializeField]
	[FormerlySerializedAs("m_manaBar2Slow")]
	private GuiBar _manaBar2Slow;

	private readonly float _manaBarBorderBuffer = 16f;

	private void SetManaBarSize(float size)
	{
		_manaBar2Root.SetSizeWithCurrentAnchors((Axis)0, size + _manaBarBorderBuffer);
		_manaBar2Slow.SetWidth(size);
		_manaBar2Fast.SetWidth(size);
	}

	public void UpdateMana(Hud hud, float mana, float maxMana)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		_manaBar.SetActive(false);
		_manaAnimator.SetBool("Visible", mana < maxMana);
		SetManaBarSize(maxMana / 25f * 32f);
		Transform transform = ((Component)_manaBar2Root).transform;
		RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		if (hud.m_buildHud.activeSelf || hud.m_shipHudRoot.activeSelf)
		{
			val.anchoredPosition = new Vector2(0f, 158f);
		}
		else
		{
			val.anchoredPosition = new Vector2(0f, 98f);
		}
		_manaBar2Slow.SetValue(mana / maxMana);
		_manaBar2Fast.SetValue(mana / maxMana);
	}
}
public class RandomAttackOffset : SkyheimAttack
{
	[SerializeField]
	private float _attackOffset;

	public override bool OnFiringProjectileBurst(Player player, Attack attack)
	{
		attack.m_attackOffset = Random.Range(0f - _attackOffset, _attackOffset);
		return true;
	}
}
public class ResetRotation : MonoBehaviour
{
	protected void Start()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.rotation = Quaternion.identity;
	}

	protected void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.rotation = Quaternion.identity;
	}
}
[CreateAssetMenu(menuName = "Skyheim/SE/Barkskin")]
public class SE_Barkskin : StatusEffect
{
	[Header("SE_Barskin")]
	[SerializeField]
	private float _maxArmor;

	[SerializeField]
	private float _staminaMultiplier;

	[SerializeField]
	private float _maxArmorPerQuality;

	[SerializeField]
	private float _baseDuration;

	[SerializeField]
	private float _durationMultiplierPerSkillLevel;

	private int? _staminaModifier;

	private int _armorModifier;

	public float ArmorModifier => _armorModifier;

	public override void Setup(Character character)
	{
		base.m_character = character;
		Player val = (Player)(object)((character is Player) ? character : null);
		if (val != null)
		{
			_staminaModifier = GetStaminaModifier(val);
			((Character)val).UseStamina((float)_staminaModifier.Value, false);
		}
		TriggerStartEffects();
	}

	protected void TriggerStartEffects()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		((StatusEffect)this).RemoveStartEffects();
		Transform val = ((Component)base.m_character).transform;
		int num = -1;
		Character character = base.m_character;
		Player val2 = (Player)(object)((character is Player) ? character : null);
		if (val2 != null)
		{
			num = val2.GetPlayerModel();
			val = ((Component)val2).GetComponent<VisEquipment>().m_backShield;
		}
		float radius = base.m_character.GetRadius();
		base.m_startEffectInstances = base.m_startEffects.Create(base.m_character.GetCenterPoint(), ((Component)base.m_character).transform.rotation, val, radius * 2f, num);
	}

	public override void SetLevel(int itemLevel, float skillLevel)
	{
		float num = _staminaModifier ?? GetStaminaModifier(null);
		_armorModifier = Mathf.FloorToInt(Mathf.Min(num, _maxArmor + _maxArmorPerQuality * (float)(itemLevel - 1)));
		base.m_ttl = _baseDuration + _baseDuration * _durationMultiplierPerSkillLevel * skillLevel;
		((StatusEffect)this).SetLevel(itemLevel, skillLevel);
	}

	public override string GetTooltipString()
	{
		string timeString = StatusEffect.GetTimeString(base.m_ttl, true, false);
		string text = SkyheimPlugin.L("$sh_se_rune_barskin_desc_detailed", _armorModifier, _staminaMultiplier * 100f, timeString);
		return base.m_tooltip + "\n" + text;
	}

	public float ModifyMaxStamina(float maxStamina)
	{
		return maxStamina * (1f - _staminaMultiplier);
	}

	private int GetStaminaModifier(Player player)
	{
		float num = (((Object)(object)player == (Object)null) ? Player.m_localPlayer.m_maxStamina : player.m_maxStamina);
		float num2 = num * (1f - _staminaMultiplier);
		return Mathf.FloorToInt(num - num2);
	}
}
[CreateAssetMenu(menuName = "Skyheim/SE/Frozen")]
public class SE_Frozen : StatusEffect
{
	public override void Setup(Character character)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		((StatusEffect)this).Setup(character);
		GameObject[] startEffectInstances = base.m_startEffectInstances;
		for (int i = 0; i < startEffectInstances.Length; i++)
		{
			startEffectInstances[i].transform.localPosition = Vector3.zero;
		}
	}

	public override void UpdateStatusEffect(float dt)
	{
		((StatusEffect)this).UpdateStatusEffect(dt);
	}

	public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir)
	{
		speed = 0f;
	}
}
[CreateAssetMenu(menuName = "Skyheim/SE/Heal")]
public class SE_Heal : SE_Stats
{
	[Header("SE_Heal")]
	[SerializeField]
	[Tooltip("Increases amount healed by x per quality.")]
	private float _healthPerQuality = 5f;

	[SerializeField]
	[Tooltip("Increases duration of effect by x% per skill level.")]
	private float _durationPerSkill = 0.01f;

	[SerializeField]
	[Tooltip("Base amount to heal.")]
	private float _baseHealth = 40f;

	[SerializeField]
	[Tooltip("Base duration.")]
	private float _baseDuration = 4f;

	public override void Setup(Character character)
	{
		((SE_Stats)this).Setup(character);
	}

	public override void SetLevel(int itemLevel, float skillLevel)
	{
		float num = 1f + _durationPerSkill * skillLevel;
		base.m_healthOverTimeDuration = _baseDuration * num;
		((StatusEffect)this).m_ttl = base.m_healthOverTimeDuration;
		base.m_healthOverTimeTicks = base.m_healthOverTimeDuration / base.m_healthOverTimeInterval;
		base.m_healthOverTimeTickHP = (_baseHealth + _healthPerQuality * (float)(itemLevel - 1)) / base.m_healthOverTimeTicks * num;
		((StatusEffect)this).SetLevel(itemLevel, skillLevel);
	}

	public override string GetTooltipString()
	{
		int num = Mathf.CeilToInt(base.m_healthOverTimeTickHP * base.m_healthOverTimeTicks);
		string timeString = StatusEffect.GetTimeString(((StatusEffect)this).m_ttl, true, false);
		return ((StatusEffect)this).m_tooltip + "\n" + SkyheimPlugin.L("$sh_se_rune_heal_desc_detailed", num, timeString);
	}
}
[CreateAssetMenu(menuName = "Skyheim/SE/Windfury")]
public class SE_Windfury : StatusEffect
{
	[Header("SE_Windfury")]
	[SerializeField]
	[Tooltip("Proc Chance per item level.")]
	private float[] _procChance = new float[5] { 0.2f, 0.25f, 0.3f, 0.4f, 0.45f };

	[SerializeField]
	private EffectList _onDamageDealtEffects;

	private float _currentProcChance = 0.2f;

	private GameObject[] _activeOnHitEffects;

	public override void Setup(Character character)
	{
		((StatusEffect)this).Setup(character);
	}

	public override void SetLevel(int itemLevel, float skillLevel)
	{
		_currentProcChance = _procChance[itemLevel - 1];
		((StatusEffect)this).SetLevel(itemLevel, skillLevel);
	}

	public override string GetTooltipString()
	{
		float num = Mathf.CeilToInt(_currentProcChance * 100f);
		string text = SkyheimPlugin.L("$sh_se_rune_windfury_desc_detailed", num);
		return base.m_tooltip + "\n" + text;
	}

	public void OnDamageDealt(Character target, HitData hit)
	{
		Character attacker = hit.GetAttacker();
		Humanoid val = (Humanoid)(object)((attacker is Humanoid) ? attacker : null);
		if (val != null && IsMeleeAttack(val.m_currentAttack) && Random.Range(0f, 1f) <= _currentProcChance)
		{
			ApplyOnHitEffect();
			HitData val2 = hit.Clone();
			target.m_nview.InvokeRPC("RPC_Damage", new object[1] { val2 });
		}
		static bool IsMeleeAttack(Attack attack)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if ((int)attack.m_attackType != 0)
			{
				return (int)attack.m_attackType == 1;
			}
			return true;
		}
	}

	public override void Stop()
	{
		((StatusEffect)this).Stop();
		RemoveOnHitEffects();
	}

	private void RemoveOnHitEffects()
	{
		if (_activeOnHitEffects == null || !((Object)(object)ZNetScene.instance != (Object)null))
		{
			return;
		}
		GameObject[] activeOnHitEffects = _activeOnHitEffects;
		foreach (GameObject val in activeOnHitEffects)
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				ZNetView component = val.GetComponent<ZNetView>();
				if (component.IsValid())
				{
					component.ClaimOwnership();
					component.Destroy();
				}
			}
		}
		_activeOnHitEffects = null;
	}

	private void ApplyOnHitEffect()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		RemoveOnHitEffects();
		float radius = base.m_character.GetRadius();
		Character character = base.m_character;
		Player val = (Player)(object)((character is Player) ? character : null);
		int num = ((val != null) ? val.GetPlayerModel() : (-1));
		_activeOnHitEffects = _onDamageDealtEffects.Create(base.m_character.GetCenterPoint(), ((Component)base.m_character).transform.rotation, ((Component)base.m_character).transform, radius * 2f, num);
	}
}
public class SkyheimAltarContainer : Container, Hoverable, Interactable
{
	private SkyheimAltar _parent;

	protected void Awake()
	{
		((Container)this).Awake();
		_parent = ((Component)this).GetComponentInParent<SkyheimAltar>();
		if (Object.op_Implicit((Object)(object)base.m_nview))
		{
			base.m_nview.Unregister("OpenRespons");
			base.m_nview.Register<bool>("OpenRespons", (Action<long, bool>)RPC_OpenRespons);
		}
	}

	public void RPC_OpenRespons(long uid, bool granted)
	{
		if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
		{
			if (granted)
			{
				InventoryGui.instance.Show((Container)(object)this, 1);
				SkyheimAltarPanel.Instance.Show(_parent);
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null);
			}
		}
	}
}
public class SkyheimAltarPanel : MonoBehaviour
{
	public static SkyheimAltarPanel Instance;

	[SerializeField]
	private Transform _leftRoot;

	[SerializeField]
	private Transform _rightRoot;

	[SerializeField]
	private Text _header;

	[SerializeField]
	private Text _timeText;

	[SerializeField]
	private Text _descriptionText;

	private static GameObject s_inventoryElement;

	private Element _leftSlot;

	private Element _rightSlot;

	private Container _container;

	private SkyheimAltar _altar;

	private long _containerRevision;

	public static void Bind(Harmony harmony)
	{
		harmony.PatchAll(typeof(SkyheimAltarPanel));
	}

	public void Show(SkyheimAltar altar)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		if (_leftSlot == null && _rightSlot == null)
		{
			_leftSlot = CreateElement(_leftRoot, new Vector2i(0, 0));
			_rightSlot = CreateElement(_rightRoot, new Vector2i(1, 0));
		}
		_altar = altar;
		_container = (Container)(object)altar.Container;
		_containerRevision = _container.m_lastRevision;
		_header.text = _container.GetHoverName();
		_altar.OnProcessComplete = delegate
		{
			UpdateGui();
		};
		((Component)this).gameObject.SetActive(true);
		UpdateGui();
	}

	protected void SetTimeRemaining(float t)
	{
		t = Mathf.Floor(t);
		string timeString = StatusEffect.GetTimeString(t, true, false);
		_timeText.text = SkyheimPlugin.L("$sh_altar_time_remaining", timeString);
	}

	protected void Awake()
	{
		InventoryGrid playerGrid = InventoryGui.instance.m_playerGrid;
		playerGrid.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Combine(playerGrid.m_onSelected, new Action<InventoryGrid, ItemData, Vector2i, Modifier>(OnSelected));
	}

	protected void Update()
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_container != (Object)null && _container.IsOwner())
		{
			InventoryGui instance = InventoryGui.instance;
			_container.SetInUse(true);
			((Component)instance.m_container).gameObject.SetActive(false);
			instance.m_containerGrid.UpdateInventory(_container.GetInventory(), (Player)null, instance.m_dragItem);
			if (instance.m_firstContainerUpdate)
			{
				instance.m_containerGrid.ResetView();
				instance.m_firstContainerUpdate = false;
			}
			float autoCloseDistance = instance.m_autoCloseDistance;
			if (Vector3.Distance(((Component)_container).transform.position, ((Component)Player.m_localPlayer).transform.position) > autoCloseDistance)
			{
				Close();
			}
		}
		if ((Object)(object)_altar != (Object)null && _altar.Processing)
		{
			SetTimeRemaining(_altar.TimeRemaining);
		}
	}

	private Element CreateElement(Transform parent, Vector2i position)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: 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_0166: Expected O, but got Unknown
		GameObject val = Object.Instantiate<GameObject>(s_inventoryElement, parent);
		Transform transform = val.transform;
		((RectTransform)((transform is RectTransform) ? transform : null)).anchoredPosition = Vector2.zero;
		((Behaviour)((Component)val.transform.Find("binding")).GetComponent<TMP_Text>()).enabled = false;
		val.GetComponentInChildren<UIInputHandler>().m_onLeftDown = OnLeftClick;
		return new Element
		{
			m_pos = position,
			m_go = val,
			m_icon = ((Component)val.transform.Find("icon")).GetComponent<Image>(),
			m_amount = ((Component)val.transform.Find("amount")).GetComponent<TMP_Text>(),
			m_quality = ((Component)val.transform.Find("quality")).GetComponent<TMP_Text>(),
			m_equiped = ((Component)val.transform.Find("equiped")).GetComponent<Image>(),
			m_queued = ((Component)val.transform.Find("queued")).GetComponent<Image>(),
			m_noteleport = ((Component)val.transform.Find("noteleport")).GetComponent<Image>(),
			m_food = ((Component)val.transform.Find("foodicon")).GetComponent<Image>(),
			m_selected = ((Component)val.transform.Find("selected")).gameObject,
			m_tooltip = val.GetComponent<UITooltip>(),
			m_durability = ((Component)val.transform.Find("durability")).GetComponent<GuiBar>()
		};
	}

	private void UpdateSlot(Element element)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		ItemData itemAt = _container.GetInventory().GetItemAt(element.m_pos.x, element.m_pos.y);
		if (itemAt != null)
		{
			((Behaviour)element.m_icon).enabled = true;
			element.m_icon.sprite = itemAt.GetIcon();
			((Graphic)element.m_icon).color = Color.white;
			bool flag = itemAt.m_shared.m_useDurability && itemAt.m_durability < itemAt.GetMaxDurability();
			((Component)element.m_durability).gameObject.SetActive(flag);
			if (flag)
			{
				if (itemAt.m_durability <= 0f)
				{
					element.m_durability.SetValue(1f);
					element.m_durability.SetColor((Color)((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : new Color(0f, 0f, 0f, 0f)));
				}
				else
				{
					element.m_durability.SetValue(itemAt.GetDurabilityPercentage());
					element.m_durability.ResetColor();
				}
			}
			((Behaviour)element.m_equiped).enabled = false;
			((Behaviour)element.m_queued).enabled = false;
			((Behaviour)element.m_noteleport).enabled = !itemAt.m_shared.m_teleportable;
			((Behaviour)element.m_food).enabled = false;
			((Behaviour)element.m_quality).enabled = itemAt.m_shared.m_maxQuality > 1;
			if (itemAt.m_shared.m_maxQuality > 1)
			{
				element.m_quality.text = itemAt.m_quality.ToString();
			}
			((Behaviour)element.m_amount).enabled = itemAt.m_shared.m_maxStackSize > 1;
			if (itemAt.m_shared.m_maxStackSize > 1)
			{
				element.m_amount.text = $"{itemAt.m_stack}/{itemAt.m_shared.m_maxStackSize}";
			}
		}
		else
		{
			((Component)element.m_durability).gameObject.SetActive(false);
			((Behaviour)element.m_icon).enabled = false;
			((Behaviour)element.m_amount).enabled = false;
			((Behaviour)element.m_quality).enabled = false;
			((Behaviour)element.m_equiped).enabled = false;
			((Behaviour)element.m_queued).enabled = false;
			((Behaviour)element.m_noteleport).enabled = false;
			((Behaviour)element.m_food).enabled = false;
			element.m_tooltip.m_text = "";
			element.m_tooltip.m_topic = "";
		}
	}

	private void CheckRevisionChanged()
	{
		if (_container.m_lastRevision != _containerRevision)
		{
			_containerRevision = _container.m_lastRevision;
			_altar.CancelProcess();
		}
	}

	private void OnLeftClick(UIInputHandler clickHandler)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: 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)
		GameObject gameObject = ((Component)clickHandler).gameObject;
		Vector2i buttonPos = GetButtonPos(gameObject);
		ItemData itemAt = _container.GetInventory().GetItemAt(buttonPos.x, buttonPos.y);
		Modifier val = (Modifier)0;
		InventoryGrid containerGrid = InventoryGui.instance.m_containerGrid;
		InventoryGui.instance.OnSelectedItem(containerGrid, itemAt, buttonPos, val);
		CheckRevisionChanged();
		UpdateGui();
	}

	private void OnSelected(InventoryGrid grid, ItemData data, Vector2i i, Modifier modifier)
	{
		if (((Component)this).gameObject.activeSelf)
		{
			CheckRevisionChanged();
			UpdateGui();
		}
	}

	private Vector2i GetButtonPos(GameObject gameObject)
	{
		//IL_0025: 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)
		if (!((Object)(object)_leftSlot.m_go == (Object)(object)gameObject))
		{
			return _rightSlot.m_pos;
		}
		return _leftSlot.m_pos;
	}

	protected void OnDisable()
	{
		_altar.OnProcessComplete = null;
		_container.SetInUse(false);
		((Component)this).gameObject.SetActive(false);
	}

	private void UpdateGui()
	{
		UpdateSlot(_leftSlot);
		UpdateSlot(_rightSlot);
		SkyheimArmorRecipe skyheimArmorRecipe = (((Object)(object)_altar != (Object)null) ? _altar.GetActiveRecipe() : null);
		_descriptionText.text = ((skyheimArmorRecipe != null) ? skyheimArmorRecipe.GetImbueTooltip() : string.Empty);
		if (_altar.Processing)
		{
			return;
		}
		if (skyheimArmorRecipe != null)
		{
			if (_altar.HasEitrShards(skyheimArmorRecipe))
			{
				_timeText.text = SkyheimPlugin.L("$sh_altar_close_to_start");
			}
			else
			{
				_timeText.text = SkyheimPlugin.L("$sh_altar_needs_more_shards");
			}
		}
		else
		{
			_timeText.text = SkyheimPlugin.L("$sh_altar_place_armor");
		}
	}

	private void Close()
	{
		((Component)this).gameObject.SetActive(false);
		InventoryGui.instance.CloseContainer();
	}

	[HarmonyPatch(typeof(InventoryGui), "Awake")]
	[HarmonyPostfix]
	protected static void InventoryGui_Awake_Postfix(InventoryGui __instance)
	{
		GameObject obj = Object.Instantiate<GameObject>(AssetManager.GetGameObject("altar_panel"), ((Component)__instance.m_inventoryRoot).transform);
		Instance = obj.GetComponent<SkyheimAltarPanel>();
		UIGroupHandler component = obj.GetComponent<UIGroupHandler>();
		CollectionExtensions.AddItem<UIGroupHandler>((IEnumerable<UIGroupHandler>)__instance.m_uiGroups, component);
		s_inventoryElement = __instance.m_containerGrid.m_elementPrefab;
		int siblingIndex = ((Transform)__instance.m_container).GetSiblingIndex();
		obj.transform.SetSiblingIndex(siblingIndex + 1);
	}

	[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
	[HarmonyPrefix]
	protected static bool InventoryGui_UpdateContainer_Prefix()
	{
		return !((Component)Instance).gameObject.activeSelf;
	}
}
[CreateAssetMenu(menuName = "Skyheim/Altar Tuning")]
public class SkyheimAltarTuning : ScriptableObject, ISerializationCallbackReceiver
{
	[PrefabReferenceType(typeof(ItemDrop))]
	public string EitrShardPrefab;

	public List<SkyheimArmorRecipe> Recipes;

	[SerializeField]
	[HideInInspector]
	private string _recipesInternal;

	public void RuntimeDeserialize()
	{
		JSONNode jSONNode = JSONNode.Parse(_recipesInternal);
		Recipes = new List<SkyheimArmorRecipe>();
		JSONNode.Enumerator enumerator = jSONNode.AsArray.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<string, JSONNode> current = enumerator.Current;
			Recipes.Add(new SkyheimArmorRecipe(current.Value));
		}
	}

	public void OnBeforeSerialize()
	{
		if (Recipes != null)
		{
			JSONNode jSONNode = CommonUtils.ToJSON(Recipes);
			_recipesInternal = jSONNode.ToString();
		}
	}

	public void OnAfterDeserialize()
	{
	}
}
[Serializable]
public class SkyheimArmorRecipe
{
	public string SourceItemDrop;

	public int EitrShardsRequired;

	public float EitrModifier;

	public float EitrRegenModifier;

	public float ArmorModifier;

	public float CraftingTime = 30f;

	public SkyheimArmorRecipe()
	{
	}

	public SkyheimArmorRecipe(JSONNode j)
	{
		SourceItemDrop = j["SourceItemDrop"];
		EitrShardsRequired = j["EitrShardsRequired"];
		EitrModifier = j["EitrModifier"];
		EitrRegenModifier = j["EitrRegenModifier"];
		ArmorModifier = j["ArmorModifier"];
		CraftingTime = j["CraftingTime"];
	}

	public string GetImbueTooltip()
	{
		string text = $"Eitr Shards Required: <color=orange>{EitrShardsRequired}</color>\nMaximum Eitr: <color=orange>+{EitrModifier}</color>";
		if (EitrRegenModifier != 0f)
		{
			text += $"\nEitr Regen Modifier: <color=orange>+{EitrRegenModifier * 100f}%</color>";
		}
		if (ArmorModifier != 0f)
		{
			text += $"\nArmor Modifier: <color=orange>-{ArmorModifier * 100f}%</color>";
		}
		string timeString = StatusEffect.GetTimeString(CraftingTime, true, true);
		return text + "\nTime to Craft: <color=orange>" + timeString + "</color>";
	}
}
public class SkyheimAttack : MonoBehaviour
{
	public virtual bool OnAttackStart(Attack attack, Player player, ItemData weapon)
	{
		return true;
	}

	public virtual void OnAttackStarted(Player player, Attack attack)
	{
	}

	public virtual bool OnAttackTrigger(Player player, Attack attack)
	{
		return true;
	}

	public virtual void OnAttackUpdate(Player player, Attack attack, float dt)
	{
	}

	public virtual bool OnFiringProjectileBurst(Player player, Attack attack)
	{
		return true;
	}

	public virtual void OnProjectileFired(Player player, Attack attack, IProjectile projectile)
	{
	}

	public virtual void OnAttackStop(Player player, Attack attack)
	{
	}
}
public class SkyheimAttackBlink : SkyheimAttack
{
	public float Speed = 2f;

	public override void OnAttackStarted(Player player, Attack attack)
	{
		attack.m_zanim.SetSpeed(Speed);
	}

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		//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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		int mask = LayerMask.GetMask(new string[12]
		{
			"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
			"character_noenv", "vehicle"
		});
		Vector3 val = ((Component)player).transform.position + ((Component)player).transform.up * 1.5f;
		Vector3 aimDir = ((Humanoid)player).GetAimDir(val);
		float num = 15f + (float)(attack.GetWeapon().m_quality - 1) * 5f;
		RaycastHit val2 = default(RaycastHit);
		Vector3 val3 = (Physics.Raycast(val, aimDir, ref val2, num, mask, (QueryTriggerInteraction)1) ? (((RaycastHit)(ref val2)).point + aimDir * -1f) : (val + aimDir * num));
		player.m_teleportCooldown = 2f;
		((Character)player).TeleportTo(val3, ((Character)player).GetLookYaw(), false);
		player.m_teleportTimer = 20f;
		return true;
	}
}
public class SkyheimAttackChainLightning : SkyheimAttack
{
	public float Range = 25f;

	private readonly Dictionary<Attack, GameObject> _targets = new Dictionary<Attack, GameObject>();

	public override bool OnAttackStart(Attack attack, Player player, ItemData weapon)
	{
		GameObject attackProjectile = weapon.m_shared.m_attack.m_attackProjectile;
		if ((Object)(object)attackProjectile == (Object)null)
		{
			return false;
		}
		GameObject target = GetTarget(player, attackProjectile.GetComponent<IProjectile>());
		if ((Object)(object)target == (Object)null)
		{
			((Character)player).Message((MessageType)2, "No target in range", 0, (Sprite)null);
			return false;
		}
		_targets[attack] = target;
		return true;
	}

	private GameObject GetTarget(Player player, IProjectile projectile)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		ChainAoe chainAoe = projectile as ChainAoe;
		if ((Object)(object)chainAoe == (Object)null)
		{
			return null;
		}
		int rayMask = chainAoe.GetRayMask();
		Vector3 centerPoint = ((Character)player).GetCenterPoint();
		Vector3 val = centerPoint + ((Humanoid)player).GetAimDir(centerPoint) * Range;
		Collider[] array = Physics.OverlapCapsule(centerPoint, val, 1f, rayMask, (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			GameObject val2 = Projectile.FindHitObject(array[i]);
			if (Object.op_Implicit((Object)(object)val2) && chainAoe.IsValidTarget((Character)(object)player, val2))
			{
				return val2;
			}
		}
		return null;
	}

	public override void OnProjectileFired(Player player, Attack attack, IProjectile projectile)
	{
		_targets.TryGetValue(attack, out var value);
		if ((Object)(object)value != (Object)null)
		{
			_targets.Remove(attack);
			ChainAoe chainAoe = projectile as ChainAoe;
			if ((Object)(object)chainAoe != (Object)null)
			{
				chainAoe.Trigger(value);
			}
		}
	}
}
public class SkyheimAttackGlacialSpike : SkyheimAttack
{
	[SerializeField]
	private float _attackOffset;

	[SerializeField]
	private int _baseProjectileBursts = 3;

	[SerializeField]
	private int _projectileBurstPerQuality = 1;

	[SerializeField]
	private EffectList _spawnEffects = new EffectList();

	private bool _attackTriggered;

	public override bool OnAttackStart(Attack attack, Player player, ItemData weapon)
	{
		weapon.m_shared.m_attack.m_projectileBursts = _baseProjectileBursts + _projectileBurstPerQuality * (weapon.m_quality - 1);
		return true;
	}

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		_attackTriggered = true;
		return true;
	}

	public override void OnAttackUpdate(Player player, Attack attack, float dt)
	{
		if (_attackTriggered && attack.m_attackDone)
		{
			if (attack.m_projectileBurstsFired < attack.m_projectileBursts)
			{
				attack.UpdateProjectile(dt);
			}
			else
			{
				_attackTriggered = false;
			}
		}
	}

	public override bool OnFiringProjectileBurst(Player player, Attack attack)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		_spawnEffects.Create(((Component)player).transform.position, ((Component)player).transform.rotation, (Transform)null, 1f, -1);
		float attackOffset = Random.Range(0f - _attackOffset, _attackOffset);
		attack.m_attackOffset = attackOffset;
		return true;
	}
}
public class SkyheimAttackGoodberry : SkyheimAttack
{
	[SerializeField]
	private ItemDrop _spawnItem;

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		if ((Object)(object)_spawnItem != (Object)null)
		{
			ItemData val = _spawnItem.m_itemData.Clone();
			val.m_dropPrefab = ((Component)_spawnItem).gameObject;
			val.m_stack = attack.m_weapon.m_quality;
			((Humanoid)player).GetInventory().AddItem(val);
		}
		return true;
	}
}
public class SkyheimAttackInvigorate : SkyheimAttack
{
	[SerializeField]
	private SE_Stats _statusEffect;

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		float num = Mathf.Max(0f, (float)(attack.GetWeapon().m_quality - 1));
		_statusEffect.m_staminaOverTimeDuration = 10f + 10f * num;
		((StatusEffect)_statusEffect).m_ttl = _statusEffect.m_staminaOverTimeDuration;
		_statusEffect.m_staminaOverTime = 20f + 25f * num;
		((Character)player).GetSEMan().AddStatusEffect((StatusEffect)(object)_statusEffect, true, 0, 0f);
		float num2 = 0.2f + num * 0.05f;
		((Character)player).AddStamina(((Character)player).GetMaxStamina() * num2);
		return true;
	}
}
public class SkyheimAttackLight : SkyheimAttack
{
	private float _cooldownStart;

	public override bool OnAttackStart(Attack attack, Player player, ItemData weapon)
	{
		if (_cooldownStart > 0f && Time.time - _cooldownStart < 0.5f)
		{
			return false;
		}
		_cooldownStart = Time.time;
		GameObject lastProjectile = weapon.m_lastProjectile;
		if ((Object)(object)lastProjectile != (Object)null)
		{
			ZNetScene.instance.Destroy(lastProjectile);
			weapon.m_lastProjectile = null;
			return false;
		}
		return true;
	}
}
public class SkyheimAttackRecall : SkyheimAttack
{
	public override bool OnAttackStart(Attack attack, Player player, ItemData weapon)
	{
		if (!((Humanoid)player).IsTeleportable())
		{
			((Character)player).Message((MessageType)1, "An item prevents you from teleporting.", 0, (Sprite)null);
			return false;
		}
		return true;
	}

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		Game.instance.RequestRespawn(1.25f, false);
		return true;
	}
}
public class SkyheimAttackStatusEffect : SkyheimAttack
{
	[SerializeField]
	private StatusEffect _statusEffect;

	public override bool OnAttackTrigger(Player player, Attack attack)
	{
		if ((Object)(object)_statusEffect != (Object)null)
		{
			int quality = attack.GetWeapon().m_quality;
			((Character)player).GetSEMan().AddStatusEffect(_statusEffect, true, quality, 0f);
		}
		return true;
	}
}
public class SkyheimCooldownItem : MonoBehaviour
{
	[SerializeField]
	private Text _text;

	[SerializeField]
	private Image _swipe;

	public Vector2i Location { get; private set; } = new Vector2i(-1, -1);


	public void SetCooldown(float duration, float pct)
	{
		_text.text = ((duration > 0f) ? StatusEffect.GetTimeString(duration, false, false) : string.Empty);
		_swipe.fillAmount = pct;
	}

	public void Awake()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		InventoryGrid componentInParent = ((Component)this).GetComponentInParent<InventoryGrid>();
		if (componentInParent != null)
		{
			int count = componentInParent.m_elements.Count;
			int width = componentInParent.m_width;
			int num = count / width;
			Location = new Vector2i(count - num * width, num);
		}
		else
		{
			HotkeyBar componentInParent2 = ((Component)this).GetComponentInParent<HotkeyBar>();
			if (componentInParent2 != null)
			{
				Location = new Vector2i(componentInParent2.m_elements.Count, 0);
			}
		}
	}

	public void OnEnable()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if (Location.x >= 0 && Location.y >= 0)
		{
			SkyheimCooldown.Instance.RegisterUpdateable(this);
		}
		SetCooldown(0f, 0f);
	}

	public void OnDisable()
	{
		SkyheimCooldown.Instance.UnregisterUpdateable(this);
		SetCooldown(0f, 0f);
	}
}
public class SkyheimItemData : MonoBehaviour
{
	public enum ESkillType
	{
		None = 0,
		Swords = 1,
		Knives = 2,
		Clubs = 3,
		Polearms = 4,
		Spears = 5,
		Blocking = 6,
		Axes = 7,
		Bows = 8,
		vFireMagic = 9,
		vFrostMagic = 10,
		Unarmed = 11,
		Pickaxes = 12,
		WoodCutting = 13,
		Jump = 100,
		Sneak = 101,
		Run = 102,
		Swim = 103,
		NatureMagic = 200,
		HolyMagic = 201,
		FireMagic = 202,
		FrostMagic = 203,
		All = 999
	}

	public ESkillType SkillType;

	public float ManaUsed;

	public float ManaDrain;

	public float Cooldown;

	public bool Beneficial;

	protected void Awake()
	{
		ItemDrop component = ((Component)this).GetComponent<ItemDrop>();
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine(SkyheimPlugin.L(component.m_itemData.m_shared.m_description));
		if (Cooldown > 0f)
		{
			stringBuilder.AppendLine(SkyheimPlugin.L("$sh_item_cooldown", StatusEffect.GetTimeString(Cooldown, true, false)));
		}
		if (ManaDrain > 0f)
		{
			stringBuilder.AppendLine(SkyheimPlugin.L("$sh_item_eitr_drain", ManaDrain));
		}
		component.m_itemData.m_shared.m_description = stringBuilder.ToString();
	}
}
[CreateAssetMenu(menuName = "Skyheim/Tuning")]
public class SkyheimTuning : ScriptableObject
{
	private static SkyheimTuning s_instance;

	public static SkyheimTuning Tuning
	{
		get
		{
			if ((Object)(object)s_instance == (Object)null)
			{
				s_instance = AssetManager.GetAsset<SkyheimTuning>("skyheim_tuning");
			}
			return s_instance;
		}
	}
}
public static class InventoryExtensions
{
	public static int CountPrefabItems(this Inventory inventory, string name)
	{
		return inventory.GetAllItems().Sum((ItemData x) => (((Object)x.m_dropPrefab).name == name) ? x.m_stack : 0);
	}

	public static void RemovePrefabItem(this Inventory inventory, string name, int count)
	{
		ItemData item = inventory.GetItem(name, -1, true);
		inventory.RemoveItem(item.m_shared.m_name, count, -1, true);
	}

	public static bool HasResources(this Inventory inventory, List<SkyheimRecipe.SkyheimRequirement> resources)
	{
		foreach (SkyheimRecipe.SkyheimRequirement resource in resources)
		{
			if (inventory.CountPrefabItems(resource.ResourceItem) <= resource.Amount)
			{
				return false;
			}
		}
		return true;
	}

	public static void RemoveResources(this Inventory inventory, List<SkyheimRecipe.SkyheimRequirement> resources)
	{
		foreach (SkyheimRecipe.SkyheimRequirement resource in resources)
		{
			inventory.RemovePrefabItem(resource.ResourceItem, resource.Amount);
		}
	}
}
namespace skyheim
{
	public class SkyheimArmor
	{
		public static void Create(Harmony harmony)
		{
			harmony.PatchAll(typeof(SkyheimArmor));
		}

		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		[HarmonyPrefix]
		public static bool Player_SetMaxEitr_Prefix(Player __instance, ref float eitr)
		{
			float totalModifier = 0f;
			AccumulateItem(((Humanoid)__instance).m_chestItem);
			AccumulateItem(((Humanoid)__instance).m_helmetItem);
			AccumulateItem(((Humanoid)__instance).m_legItem);
			eitr += totalModifier;
			return true;
			void AccumulateItem(ItemData data)
			{
				if (data != null)
				{
					totalModifier += data.m_customData.Get("sh_mod_eitr", 0);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "GetEquipmentEitrRegenModifier")]
		[HarmonyPostfix]
		public static void Player_GetEquipmentEitrRegenModifier_Postfix(Player __instance, ref float __result)
		{
			float totalModifier = 0f;
			AccumulateItem(((Humanoid)__instance).m_chestItem);
			AccumulateItem(((Humanoid)__instance).m_helmetItem);
			AccumulateItem(((Humanoid)__instance).m_legItem);
			__result += totalModifier;
			void AccumulateItem(ItemData data)
			{
				if (data != null)
				{
					totalModifier += data.m_customData.Get("sh_mod_eitr_regen", 0f);
				}
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "GetHoverName")]
		[HarmonyPostfix]
		public static void ItemDrop_GetHoverName_Postfix(ItemDrop __instance, ref string __result)
		{
			if (__instance.m_itemData != null)
			{
				__result = Localization.instance.Localize(__instance.m_itemData.m_customData.Get("sh_mod_name", __result));
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
		[HarmonyPostfix]
		public static void ItemDrop_GetHoverText_Postfix(ItemDrop __instance, ref string __result)
		{
			if (__instance.m_itemData != null)
			{
				string text = __instance.m_itemData.m_customData.Get<string>("sh_mod_name");
				if (text != null)
				{
					string oldValue = Localization.instance.Localize(__instance.m_itemData.m_shared.m_name);
					__result = Localization.instance.Localize(__result.Replace(oldValue, text));
				}
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetArmor", new Type[]
		{
			typeof(int),
			typeof(float)
		})]
		[HarmonyPostfix]
		public static void ItemDrop_GetArmor_Postfix(ItemData __instance, ref float __result)
		{
			float num = __instance.m_customData.Get("sh_mod_armor", 0f);
			__result = Mathf.Round(Mathf.Max(1f, __result - __result * num));
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { })]
		[HarmonyPostfix]
		public static void ItemDrop_GetTooltip_Postfix(ItemData __instance, ref string __result)
		{
			string text = __instance.m_customData.Get<string>("sh_mod_eitr");
			if (text != null)
			{
				StringBuilder stringBuilder = new StringBuilder("\n\n");
				stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_eitr_imbued"));
				stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_eitr_max", text));
				float num = __instance.m_customData.Get("sh_mod_eitr_regen", 0f);
				if (num > 0f)
				{
					stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_eitr_regen", (int)(num * 100f)));
				}
				float num2 = __instance.m_customData.Get("sh_mod_armor", 0f);
				if (num2 > 0f)
				{
					stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_reduced_armor", (int)(num2 * 100f)));
				}
				__result += stringBuilder;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")]
		[HarmonyPrefix]
		public static bool InventoryGrid_CreateItemTooltip_Prefix(InventoryGrid __instance, ItemData item, UITooltip tooltip)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			string text = item.m_customData.Get("sh_mod_name", item.m_shared.m_name);
			tooltip.Set(text, item.GetTooltip(), __instance.m_tooltipAnchor, default(Vector2));
			return false;
		}
	}
	public class SkyheimCooldown
	{
		public class Cooldown
		{
			public float Value;

			public static implicit operator Cooldown(float f)
			{
				return new Cooldown
				{
					Value = f
				};
			}

			public static implicit operator float(Cooldown c)
			{
				return c.Value;
			}

			public override string ToString()
			{
				return Value.ToString();
			}
		}

		public static SkyheimCooldown Instance;

		private readonly GameObject _cooldownPrefab;

		private readonly Dictionary<string, Cooldown> _cooldowns = new Dictionary<string, Cooldown>();

		private readonly List<SkyheimCooldownItem> _updateables = new List<SkyheimCooldownItem>();

		private const string COOLDOWN_PREFIX = "sh_";

		public static void Create(Harmony harmony)
		{
			harmony.PatchAll(typeof(SkyheimCooldown));
			Instance = new SkyheimCooldown();
		}

		public SkyheimCooldown()
		{
			_cooldownPrefab = AssetManager.GetGameObject("item_cooldown");
			SkyheimPlugin.Instance.OnUpdate += Update;
		}

		public void SetCooldown(string id, float duration)
		{
			_cooldowns[id] = duration;
		}

		public float GetCooldown(string id)
		{
			if (!_cooldowns.TryGetValue(id, out var value))
			{
				return 0f;
			}
			return value.Value;
		}

		public bool OnAttackStart(ItemData weapon)
		{
			SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(weapon);
			if ((Object)(object)itemComponent != (Object)null && itemComponent.Cooldown > 0f)
			{
				return GetCooldown(((Object)itemComponent).name) <= 0f;
			}
			return true;
		}

		public void OnAttackTrigger(SkyheimItemData itemData)
		{
			if ((Object)(object)itemData != (Object)null && itemData.Cooldown > 0f)
			{
				SetCooldown(((Object)itemData).name, itemData.Cooldown);
			}
		}

		public void RegisterUpdateable(SkyheimCooldownItem item)
		{
			if (!_updateables.Contains(item))
			{
				_updateables.Add(item);
			}
		}

		public void UnregisterUpdateable(SkyheimCooldownItem item)
		{
			_updateables.Remove(item);
		}

		public void Update(float dt)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<string, Cooldown> cooldown2 in _cooldowns)
			{
				Cooldown value = cooldown2.Value;
				float value2 = Mathf.Max(0f, (float)cooldown2.Value - dt);
				value.Value = value2;
			}
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			foreach (SkyheimCooldownItem updateable in _updateables)
			{
				SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(inventory.GetItemAt(updateable.Location.x, updateable.Location.y));
				if ((Object)(object)itemComponent != (Object)null && itemComponent.Cooldown > 0f)
				{
					float cooldown = GetCooldown(((Object)itemComponent).name);
					updateable.SetCooldown(cooldown, cooldown / itemComponent.Cooldown);
				}
				else
				{
					updateable.SetCooldown(0f, 0f);
				}
			}
		}

		public List<string> SaveCooldowns(Dictionary<string, string> data)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Cooldown> cooldown in _cooldowns)
			{
				if ((float)cooldown.Value > 30f)
				{
					string key = "sh_" + cooldown.Key;
					data[key] = cooldown.Value.ToString();
					list.Add(cooldown.Key);
				}
			}
			return list;
		}

		public void LoadCooldowns(Dictionary<string, string> data)
		{
			_cooldowns.Clear();
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, string> datum in data)
			{
				if (datum.Key.StartsWith("sh_"))
				{
					string key = datum.Key.Substring("sh_".Length);
					_cooldowns[key] = float.Parse(datum.Value);
					list.Add(datum.Key);
				}
			}
			foreach (string item in list)
			{
				data.Remove(item);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		[HarmonyPostfix]
		public static void InventoryGui_Awake_Postfix(InventoryGui __instance)
		{
			InventoryGrid componentInChildren = ((Component)__instance.m_player).GetComponentInChildren<InventoryGrid>();
			GameObject val = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab);
			val.GetComponent<UITooltip>().m_text = string.Empty;
			Object.Instantiate<GameObject>(Instance._cooldownPrefab, val.transform);
			componentInChildren.m_elementPrefab = val;
		}

		[HarmonyPatch(typeof(Hud), "Awake")]
		[HarmonyPostfix]
		public static void Hud_Awake_Postfix(Hud __instance)
		{
			HotkeyBar componentInChildren = ((Component)((Component)__instance).transform).GetComponentInChildren<HotkeyBar>();
			GameObject val = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab);
			Object.Instantiate<GameObject>(Instance._cooldownPrefab, val.transform);
			componentInChildren.m_elementPrefab = val;
		}

		[HarmonyPatch(typeof(Player), "Save")]
		[HarmonyPrefix]
		public static void Player_Save_Prefix(Player __instance, out List<string> __state)
		{
			__state = Instance.SaveCooldowns(__instance.m_knownTexts);
		}

		[HarmonyPatch(typeof(Player), "Save")]
		[HarmonyPostfix]
		public static void Player_Save_Postfix(Player __instance, List<string> __state)
		{
			foreach (string item in __state)
			{
				__instance.m_knownTexts.Remove(item);
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		[HarmonyPostfix]
		public static void Player_Load_Postfix(Player __instance)
		{
			Instance.LoadCooldowns(__instance.m_knownTexts);
		}
	}
	public delegate void UpdateEvent(float dt);
	[BepInPlugin("skyheim", "Skyheim", "1.3.10")]
	public class SkyheimPlugin : BaseUnityPlugin
	{
		public static SkyheimPlugin Instance;

		private Harmony _harmony;

		private static readonly int _statusEffectBarkskin = StringExtensionMethods.GetStableHashCode("se_rune_barkskin");

		private static readonly int _statusEffectWarmth = StringExtensionMethods.GetStableHashCode("se_rune_warmth");

		private static readonly int _statusEffectWindfury = StringExtensionMethods.GetStableHashCode("se_rune_windfury");

		public event UpdateEvent OnUpdate;

		public static string L(string key, params object[] values)
		{
			string[] array = values.Select((object x) => $"{x}").ToArray();
			return Localization.instance.Localize(key, array);
		}

		public static string L(string key)
		{
			return Localization.instance.Localize(key);
		}

		protected void Awake()
		{
			Instance = this;
			_harmony = Harmony.CreateAndPatchAll(typeof(SkyheimPlugin), (string)null);
			AssetManager.Create(_harmony, "skyheim");
			AssetManager.OnSceneAwake = OnSceneAwake;
			SkyheimSkills.Create(_harmony);
			SkyheimCooldown.Create(_harmony);
			SkyheimArmor.Create(_harmony);
			SkyheimAltarPanel.Bind(_harmony);
		}

		protected void Update()
		{
			this.OnUpdate?.Invoke(Time.deltaTime);
		}

		protected void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchAll((string)null);
			}
		}

		private void OnSceneAwake(ZNetScene _)
		{
			ApplyDropModifiers();
		}

		private static string GetAssemblyDirectory()
		{
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		}

		private void ApplyDropModifiers()
		{
			foreach (DropModifier asset in AssetManager.GetAssets<DropModifier>())
			{
				asset.Apply();
			}
		}

		private static void ApplyLocalization()
		{
			try
			{
				StreamReader streamReader = new StreamReader(Path.Combine(GetAssemblyDirectory(), "skyheim.json"));
				string aJSON = streamReader.ReadToEnd();
				streamReader.Close();
				JSONNode jSONNode = JSON.Parse(aJSON);
				string selectedLanguage = Localization.instance.GetSelectedLanguage();
				JSONNode.Enumerator enumerator = (jSONNode.GetValueOrDefault(selectedLanguage, null) ?? jSONNode["English"]).GetEnumerator();
				while (enumerator.MoveNext())
				{
					KeyValuePair<string, JSONNode> current = enumerator.Current;
					Localization.instance.AddWord(current.Key, (string)current.Value);
				}
			}
			catch (Exception)
			{
			}
		}

		[HarmonyPatch(typeof(SE_Wet), "UpdateStatusEffect")]
		[HarmonyPostfix]
		public static void SE_Wet_UpdateStatusEffect_Postfix(SE_Wet __instance, float dt)
		{
			if (((StatusEffect)__instance).m_character.m_seman.HaveStatusEffect(_statusEffectWarmth))
			{
				((StatusEffect)__instance).m_time = ((StatusEffect)__instance).m_time + dt * 10f;
			}
		}

		[HarmonyPatch(typeof(EnvMan), "CalculateWet")]
		[HarmonyPostfix]
		public static void EnvMan_CalculateWet_Postfix(ref bool __result)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).m_seman.HaveStatusEffect(_statusEffectWarmth))
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		[HarmonyPrefix]
		public static void Character_RPC_Damage_Prefix(Character __instance, HitData hit)
		{
			if (hit.m_statusEffectHash != 0)
			{
				__instance.m_seman.RemoveStatusEffect(hit.m_statusEffectHash, true);
			}
		}

		[HarmonyPatch(typeof(Player), "GetBodyArmor")]
		[HarmonyPostfix]
		public static void Player_GetBodyArmor_Postfix(Player __instance, ref float __result)
		{
			StatusEffect statusEffect = ((Character)__instance).m_seman.GetStatusEffect(_statusEffectBarkskin);
			if ((Object)(object)statusEffect != (Object)null && statusEffect is SE_Barkskin sE_Barkskin)
			{
				__result += sE_Barkskin.ArmorModifier;
			}
		}

		[HarmonyPatch(typeof(Player), "GetMaxStamina")]
		[HarmonyPostfix]
		public static void Player_GetMaxStamina_Postfix(Player __instance, ref float __result)
		{
			StatusEffect statusEffect = ((Character)__instance).m_seman.GetStatusEffect(_statusEffectBarkskin);
			if ((Object)(object)statusEffect != (Object)null && statusEffect is SE_Barkskin sE_Barkskin)
			{
				__result = sE_Barkskin.ModifyMaxStamina(__result);
			}
		}

		[HarmonyPatch(typeof(HitData), "SetAttacker")]
		[HarmonyPostfix]
		public static void HitData_SetAttacker_Postfix(HitData __instance, Character attacker)
		{
			//IL_003d: 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)
			if (!Object.op_Implicit((Object)(object)attacker) || !attacker.IsPlayer())
			{
				return;
			}
			GameObject dropPrefab = ((Humanoid)((attacker is Player) ? attacker : null)).GetCurrentWeapon().m_dropPrefab;
			if ((Object)(object)dropPrefab != (Object)null)
			{
				SkyheimItemData component = dropPrefab.GetComponent<SkyheimItemData>();
				if (component != null && component.Beneficial)
				{
					__instance.m_attacker = ZDOID.None;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Load")]
		[HarmonyPostfix]
		public static void Player_Load_Postfix()
		{
			ApplyLocalization();
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		[HarmonyPrefix]
		public static bool Attack_Start_Prefix(Attack __instance, Humanoid character, ItemData weapon, ZSyncAnimation zanim)
		{
			if ((Object)(object)character != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			__instance.m_zanim = zanim;
			if (!((Character)character).InGodMode() && !SkyheimCooldown.Instance.OnAttackStart(weapon))
			{
				return false;
			}
			SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(weapon);
			if (!((Object)(object)itemComponent == (Object)null))
			{
				return itemComponent.OnAttackStart(__instance, Player.m_localPlayer, weapon);
			}
			return true;
		}

		[HarmonyPatch(typeof(Attack), "HaveAmmo")]
		[HarmonyPostfix]
		public static void Attack_HaveAmmo_Postfix(Humanoid character, ItemData weapon, ref bool __result)
		{
			if (__result && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && !((Character)character).InGodMode() && !SkyheimCooldown.Instance.OnAttackStart(weapon))
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		[HarmonyPostfix]
		public static void Attack_Start_Postfix(Attack __instance, ref bool __result)
		{
			if (!((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && __result)
			{
				CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon)?.OnAttackStarted(Player.m_localPlayer, __instance);
			}
		}

		[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
		[HarmonyPrefix]
		public static bool Attack_OnAttackTrigger_Prefix(Attack __instance)
		{
			if ((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(__instance.m_weapon);
			if (itemComponent != null)
			{
				SkyheimCooldown.Instance.OnAttackTrigger(itemComponent);
			}
			SkyheimAttack itemComponent2 = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon);
			if (Object.op_Implicit((Object)(object)itemComponent2) && !itemComponent2.OnAttackTrigger(Player.m_localPlayer, __instance))
			{
				__instance.Stop();
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
		[HarmonyPrefix]
		public static bool Attack_FireProjectileBurst_Prefix(Attack __instance)
		{
			if ((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon);
			if (!((Object)(object)itemComponent == (Object)null))
			{
				return itemComponent.OnFiringProjectileBurst(Player.m_localPlayer, __instance);
			}
			return true;
		}

		[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
		[HarmonyPostfix]
		public static void Attack_FireProjectileBurst_Postfix(Attack __instance)
		{
			if (!((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && !((Object)(object)__instance.m_weapon.m_lastProjectile == (Object)null))
			{
				SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon);
				if ((Object)(object)itemComponent != (Object)null)
				{
					IProjectile component = __instance.m_weapon.m_lastProjectile.GetComponent<IProjectile>();
					itemComponent.OnProjectileFired(Player.m_localPlayer, __instance, component);
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "Stop")]
		[HarmonyPostfix]
		public static void Attack_Stop_Postfix(Attack __instance)
		{
			if ((Object)(object)__instance.m_character == (Object)(object)Player.m_localPlayer)
			{
				SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon);
				if ((Object)(object)itemComponent != (Object)null)
				{
					itemComponent.OnAttackStop(Player.m_localPlayer, __instance);
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "Update")]
		[HarmonyPostfix]
		public static void Attack_Update_Postfix(Attack __instance, float dt)
		{
			if ((Object)(object)__instance.m_character == (Object)(object)Player.m_localPlayer)
			{
				SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon);
				if ((Object)(object)itemComponent != (Object)null)
				{
					itemComponent.OnAttackUpdate(Player.m_localPlayer, __instance, dt);
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		[HarmonyPostfix]
		public static void Hud_Update_Postfix()
		{
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			ItemData currentWeapon = ((Humanoid)Player.m_localPlayer).GetCurrentWeapon();
			if (currentWeapon == null || !((Object)(object)currentWeapon.m_dropPrefab != (Object)null))
			{
				return;
			}
			SkyheimItemData component = currentWeapon.m_dropPrefab.GetComponent<SkyheimItemData>();
			if (Object.op_Implicit((Object)(object)component) && component.ManaDrain > 0f)
			{
				Player localPlayer = Player.m_localPlayer;
				localPlayer.m_eitr -= component.ManaDrain * Time.deltaTime;
				if (Player.m_localPlayer.m_eitr <= 0f)
				{
					((Humanoid)Player.m_localPlayer).UnequipItem(currentWeapon, true);
				}
			}
		}

		[HarmonyPatch(typeof(CraftingStation), "GetLevel")]
		[HarmonyPostfix]
		public static void CraftingStation_GetLevel_Postfix(CraftingStation __instance, ref int __result)
		{
			SkyheimAltar skyheimAltar = default(SkyheimAltar);
			if (((Component)__instance).TryGetComponent<SkyheimAltar>(ref skyheimAltar))
			{
				__result = 5;
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		[HarmonyPostfix]
		public static void Character_Damage_Postfix(Character __instance, HitData hit)
		{
			if (__instance.m_nview.IsValid() && !((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer))
			{
				SEMan sEMan = hit.GetAttacker().GetSEMan();
				if (sEMan.HaveStatusEffect(_statusEffectWindfury))
				{
					(sEMan.GetStatusEffect(_statusEffectWindfury) as SE_Windfury).OnDamageDealt(__instance, hit);
				}
			}
		}
	}
	public class SkyheimSkills
	{
		private class SkillInfo
		{
			public string Name;

			public SkillDef SkillDef;
		}

		private static readonly Dictionary<int, SkillInfo> s_skills = new Dictionary<int, SkillInfo>();

		public static void Create(Harmony harmony)
		{
			harmony.PatchAll(typeof(SkyheimSkills));
			Register(SkyheimItemData.ESkillType.NatureMagic, "Nature magic", "Nature magic", AssetManager.GetAsset<Sprite>("skill_nature_magic"));
			Register(SkyheimItemData.ESkillType.HolyMagic, "Holy magic", "Holy magic", AssetManager.GetAsset<Sprite>("skill_holy_magic"));
			Register(SkyheimItemData.ESkillType.FireMagic, "Fire magic", "Fire magic", AssetManager.GetAsset<Sprite>("skill_fire_magic"));
			Register(SkyheimItemData.ESkillType.FrostMagic, "Frost magic", "Frost magic", AssetManager.GetAsset<Sprite>("skill_frost_magic"));
			foreach (SkyheimItemData gameObject in AssetManager.GetGameObjects<SkyheimItemData>())
			{
				SetSkillType(gameObject);
			}
		}

		private static void SetSkillType(SkyheimItemData itemData)
		{
			SetSkillType(((Component)itemData).GetComponent<ItemDrop>(), itemData.SkillType);
		}

		private static void SetSkillType<T>(ItemDrop itemDrop, T skill_type) where T : IConvertible
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			int num = Convert.ToInt32(skill_type);
			itemDrop.m_itemData.m_shared.m_skillType = (SkillType)num;
			GameObject attackProjectile = itemDrop.m_itemData.m_shared.m_attack.m_attackProjectile;
			Aoe val = (((Object)(object)attackProjectile != (Object)null) ? attackProjectile.GetComponent<Aoe>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.m_skill = (SkillType)num;
			}
		}

		private static void Register<T>(T id, string name, string description, Sprite icon, float increaseStep = 1f) where T : IConvertible
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			int num = Convert.ToInt32(id);
			s_skills[num] = new SkillInfo
			{
				Name = name,
				SkillDef = new SkillDef
				{
					m_skill = (SkillType)num,
					m_increseStep = increaseStep,
					m_description = description,
					m_icon = icon
				}
			};
		}

		private static SkillDef GetSkill(SkillType type)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected I4, but got Unknown
			s_skills.TryGetValue((int)type, out var value);
			return value?.SkillDef;
		}

		private static SkillDef GetSkill(string name)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected I4, but got Unknown
			name = name.ToLower();
			foreach (SkillInfo value in s_skills.Values)
			{
				if (((SkyheimItemData.ESkillType)value.SkillDef.m_skill).ToString().ToLower() == name)
				{
					return value.SkillDef;
				}
			}
			return null;
		}

		[HarmonyPatch(typeof(Skills), "GetSkillDef")]
		[HarmonyPostfix]
		protected static void Skills_GetSkillDef_Postfix(Skills __instance, SkillType type, ref SkillDef __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null)
			{
				SkillDef skill = GetSkill(type);
				if (skill != null)
				{
					__instance.m_skills.Add(skill);
					__result = skill;
				}
			}
		}

		[HarmonyPatch(typeof(Skills), "CheatRaiseSkill")]
		[HarmonyPrefix]
		protected static bool Skills_CheatRaiseSkill_Prefix(Skills __instance, string name, float value)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			SkillDef skill = GetSkill(name);
			if (skill != null)
			{
				Skill skill2 = __instance.GetSkill(skill.m_skill);
				skill2.m_level = Mathf.Clamp(skill2.m_level + value, 0f, 100f);
				if (__instance.m_useSkillCap)
				{
					__instance.RebalanceSkills(skill.m_skill);
				}
				string text = $"Skill increased {skill2.m_info.m_skill}: {(int)skill2.m_level}";
				((Character)__instance.m_player).Message((MessageType)1, text, 0, skill2.m_info.m_icon);
				Console.instance.Print($"Skill {name} = {skill2.m_level}");
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Skills), "CheatResetSkill")]
		[HarmonyPrefix]
		protected static bool Skills_CheatResetSkill_Prefix(Skills __instance, string name)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			SkillDef skill = GetSkill(name);
			if (skill != null)
			{
				__instance.ResetSkill(skill.m_skill);
				Console.instance.Print("Skill " + name + " reset");
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Skills), "IsSkillValid")]
		[HarmonyPostfix]
		protected static void Skills_IsSkillValid_Postfix(SkillType type, ref bool __result)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected I4, but got Unknown
			__result = __result || s_skills.ContainsKey((int)type);
		}
	}
}
namespace SimpleJSON
{
	public enum JSONNodeType
	{
		Array = 1,
		Object = 2,
		String = 3,
		Number = 4,
		NullValue = 5,
		Boolean = 6,
		None = 7,
		Custom = 255
	}
	public enum JSONTextMode
	{
		Compact,
		Indent
	}
	public abstract class JSONNode
	{
		public struct Enumerator
		{
			private enum Type
			{
				None,
				Array,
				Object
			}

			private Type type;

			private Dictionary<string, JSONNode>.Enumerator m_Object;

			private List<JSONNode>.Enumerator m_Array;

			public bool IsValid => type != Type.None;

			public KeyValuePair<string, JSONNode> Current
			{
				get
				{
					if (type == Type.Array)
					{
						return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
					}
					if (type == Type.Object)
					{
						return m_Object.Current;
					}
					return new KeyValuePair<string, JSONNode>(string.Empty, null);
				}
			}

			public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
			{
				type = Type.Array;
				m_Object = default(Dictionary<string, JSONNode>.Enumerator);
				m_Array = aArrayEnum;
			}

			public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
			{
				type = Type.Object;
				m_Object = aDictEnum;
				m_Array = default(List<JSONNode>.Enumerator);
			}

			public bool MoveNext()
			{
				if (type == Type.Array)
				{
					return m_Array.MoveNext();
				}
				if (type == Type.Object)
				{
					return m_Object.MoveNext();
				}
				return false;
			}
		}

		public struct ValueEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Value;

			public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public ValueEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public ValueEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public struct KeyEnumerator
		{
			private Enumerator m_Enumerator;

			public string Current => m_Enumerator.Current.Key;

			public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public KeyEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public KeyEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable
		{
			private JSONNode m_Node;

			private Enumerator m_Enumerator;

			public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current;

			object IEnumerator.Current => m_Enumerator.Current;

			internal LinqEnumerator(JSONNode aNode)
			{
				m_Node = aNode;
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public void Dispose()
			{
				m_Node = null;
				m_Enumerator = default(Enumerator);
			}

			public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}

			public void Reset()
			{
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}
		}

		public static bool forceASCII = false;

		public static bool longAsString = false;

		public static bool allowLineComments = true;

		[ThreadStatic]
		private static StringBuilder m_EscapeBuilder;

		public abstract JSONNodeType Tag { get; }

		public virtual JSONNode this[int aIndex]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual JSONNode this[string aKey]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Value
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual int Count => 0;

		public virtual bool IsNumber => false;

		public virtual bool IsString => false;

		public virtual bool IsBoolean => false;

		public virtual bool IsNull => false;

		public virtual bool IsArray => false;

		public virtual bool IsObject => false;

		public virtual bool Inline
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public virtual IEnumerable<JSONNode> Children
		{
			get
			{
				yield break;
			}
		}

		public IEnumerable<JSONNode> DeepChildren
		{
			get
			{
				foreach (JSONNode child in Children)
				{
					foreach (JSONNode deepChild in child.DeepChildren)
					{
						yield return deepChild;
					}
				}
			}
		}

		public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this);

		public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator());

		public ValueEnumerator Values => new ValueEnumerator(GetEnumerator());

		public virtual double AsDouble
		{
			get
			{
				double result = 0.0;
				if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0.0;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual int AsInt
		{
			get
			{
				return (int)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual float AsFloat
		{
			get
			{
				return (float)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual bool AsBool
		{
			get
			{
				bool result = false;
				if (bool.TryParse(Value, out result))
				{
					return result;
				}
				return !string.IsNullOrEmpty(Value);
			}
			set
			{
				Value = (value ? "true" : "false");
			}
		}

		public virtual long AsLong
		{
			get
			{
				long result = 0L;
				if (long.TryParse(Value, out result))
				{
					return result;
				}
				return 0L;
			}
			set
			{
				Value = value.ToString();
			}
		}

		public virtual ulong AsULong
		{
			get
			{
				ulong result = 0uL;
				if (ulong.TryParse(Value, out result))
				{
					return result;
				}
				return 0uL;
			}
			set
			{
				Value = value.ToString();
			}
		}

		public virtual JSONArray AsArray => this as JSONArray;

		public virtual JSONObject AsObject => this as JSONObject;

		internal static StringBuilder EscapeBuilder
		{
			get
			{
				if (m_EscapeBuilder == null)
				{
					m_EscapeBuilder = new StringBuilder();
				}
				return m_EscapeBuilder;
			}
		}