Decompiled source of FrostmourneHungers v1.2.3

BepInEx/plugins/FrostmourneHungers/FrostmourneHungers.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("demolishandrock")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3")]
[assembly: AssemblyProduct("FrostmourneHungers")]
[assembly: AssemblyTitle("FrostmourneHungers")]
[assembly: AssemblyVersion("1.2.3.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FrostmourneMod
{
	internal sealed class Authority
	{
		internal const string ClaimKey = "fm_blade_claimed";

		private const string PullRpc = "FM.Pull.v1";

		private const string ResultRpc = "FM.Result.v1";

		private const string TokenKey = "fm_claim_token";

		private const string WorldKey = "fm_world";

		private static Authority current;

		private readonly ZRoutedRpc router;

		private Journal journal;

		private ZDO pedestal;

		private bool ready;

		private bool faulted;

		private readonly List<ZDO> scan = new List<ZDO>();

		private int scanIndex;

		private long worldId;

		private Random random;

		private int attempts;

		private readonly Dictionary<long, float> cooldown = new Dictionary<long, float>();

		private readonly ClaimLease lease = new ClaimLease();

		private static string pendingOffer;

		private static float nextPull;

		internal ZRoutedRpc Router => router;

		private static long ServerId
		{
			get
			{
				if (!ZNet.instance.IsServer())
				{
					return ZNet.instance.GetServerPeer()?.m_uid ?? 0;
				}
				return ZNet.GetUID();
			}
		}

		internal static void RejectExtraPedestal(ZNetView view)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (current != null && current.ready && current.pedestal != null && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && Object.op_Implicit((Object)(object)view) && view.IsValid() && !(view.GetZDO().m_uid == current.pedestal.m_uid))
			{
				view.ClaimOwnership();
				view.Destroy();
			}
		}

		internal Authority()
		{
			current = this;
			router = ZRoutedRpc.instance;
			pendingOffer = null;
			router.Register<ZPackage>("FM.Pull.v1", (Action<long, ZPackage>)OnPull);
			router.Register<ZPackage>("FM.Result.v1", (Action<long, ZPackage>)OnResult);
		}

		internal unsafe void Tick()
		{
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			if (faulted || !ZNet.instance.IsServer() || !Object.op_Implicit((Object)(object)Plugin.SwordPrefab) || WorldGenerator.instance == null || !ZoneSystem.instance.LocationsGenerated)
			{
				return;
			}
			if (journal == null)
			{
				World world = ZNet.instance.GetWorld();
				if (world == null)
				{
					return;
				}
				worldId = world.m_uid;
				try
				{
					journal = new Journal(worldId);
				}
				catch
				{
					faulted = true;
					throw;
				}
				random = new Random((int)(worldId ^ (worldId >> 32)));
			}
			if (!ready)
			{
				if (!ZDOMan.instance.GetAllZDOsWithPrefabIterative("FM_Pedestal", scan, ref scanIndex))
				{
					return;
				}
				HashSet<ZDOID> hashSet = new HashSet<ZDOID>();
				foreach (ZDO item in scan)
				{
					if (hashSet.Add(item.m_uid))
					{
						Vector3 position = item.GetPosition();
						bool flag = (journal.Located ? (Vector3.Distance(position, journal.Position) < 0.5f) : ValidGround(ref position));
						if (pedestal == null && flag)
						{
							pedestal = item;
							continue;
						}
						ZDOID uid = item.m_uid;
						Plugin.Log("Removing duplicate pedestal ZDO " + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString());
						item.SetOwner(ZNet.GetUID());
						ZDOMan.instance.DestroyZDO(item);
					}
				}
				if (pedestal != null && !journal.Located)
				{
					journal.Position = pedestal.GetPosition();
					journal.Located = true;
					PersistJournal();
				}
				ready = true;
			}
			if (pedestal == null)
			{
				if (!journal.Located)
				{
					Vector3 position2 = default(Vector3);
					for (int i = 0; i < 250; i++)
					{
						float num = (float)(random.NextDouble() * 20000.0 - 10000.0);
						float num2 = (float)(random.NextDouble() * 20000.0 - 10000.0);
						attempts++;
						((Vector3)(ref position2))..ctor(num, 0f, num2);
						if (ValidGround(ref position2))
						{
							journal.Position = position2;
							journal.Located = true;
							PersistJournal();
							break;
						}
					}
					if (!journal.Located)
					{
						if (attempts % 10000 == 0)
						{
							Plugin.Log("Still searching for valid Deep North land after " + attempts + " samples.");
						}
						return;
					}
				}
				pedestal = ZDOMan.instance.CreateNewZDO(journal.Position, StringExtensionMethods.GetStableHashCode("FM_Pedestal"));
				pedestal.SetPrefab(StringExtensionMethods.GetStableHashCode("FM_Pedestal"));
				pedestal.Persistent = true;
				pedestal.SetType((ObjectType)0);
				pedestal.SetRotation(Quaternion.identity);
				Vector3 position3 = journal.Position;
				Plugin.Log("Unique pedestal registered at " + ((object)(*(Vector3*)(&position3))/*cast due to .constrained prefix*/).ToString());
			}
			if (journal.Issued && !ZoneSystem.instance.GetGlobalKey("fm_blade_claimed"))
			{
				ZoneSystem.instance.SetGlobalKey("fm_blade_claimed");
			}
			if (ZoneSystem.instance.GetGlobalKey("fm_blade_claimed") && !journal.Issued)
			{
				journal.Issued = true;
				journal.Token = Guid.NewGuid().ToString("N");
				PersistJournal();
			}
		}

		private void PersistJournal()
		{
			try
			{
				journal.Save();
			}
			catch
			{
				faulted = true;
				throw;
			}
		}

		private static bool ValidGround(ref Vector3 position)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0029: 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_0076: 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_009a: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref position)).sqrMagnitude > 98010000f)
			{
				return false;
			}
			WorldGenerator instance = WorldGenerator.instance;
			if ((int)instance.GetBiome(position) != 64)
			{
				return false;
			}
			float height = instance.GetHeight(position);
			if (float.IsNaN(height) || float.IsInfinity(height) || height < ZoneSystem.instance.m_waterLevel + 2f)
			{
				return false;
			}
			if (ZoneSystem.instance.ZoneHasLocation(position))
			{
				return false;
			}
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					Vector3 val = position + new Vector3((float)i * 2f, 0f, (float)j * 2f);
					if ((int)instance.GetBiome(val) != 64 || Mathf.Abs(instance.GetHeight(val) - height) > 1.25f)
					{
						return false;
					}
				}
			}
			position.y = height;
			return true;
		}

		internal static void Request(ZDOID id)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.unscaledTime < nextPull) && current != null)
			{
				nextPull = Time.unscaledTime + 1f;
				Player localPlayer = Player.m_localPlayer;
				if (Object.op_Implicit((Object)(object)localPlayer) && !((Character)localPlayer).IsDead())
				{
					ZPackage val = new ZPackage();
					val.Write(id);
					val.Write("");
					current.router.InvokeRoutedRPC(ServerId, "FM.Pull.v1", new object[1] { val });
				}
			}
		}

		private ZDO PlayerZdo(long sender)
		{
			//IL_001e: 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)
			if (sender == ZNet.GetUID() && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return ZDOMan.instance.GetZDO(((Character)Player.m_localPlayer).GetZDOID());
			}
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (peer == null || !peer.IsReady())
			{
				return null;
			}
			return ZDOMan.instance.GetZDO(peer.m_characterID);
		}

		private void OnPull(long sender, ZPackage package)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!ZNet.instance.IsServer() || !ready || pedestal == null || journal == null || faulted)
			{
				return;
			}
			try
			{
				ZDOID val = package.ReadZDOID();
				string text = package.ReadString();
				if (text.Length > 32 || val != pedestal.m_uid || (cooldown.TryGetValue(sender, out var value) && Time.unscaledTime < value))
				{
					return;
				}
				cooldown[sender] = Time.unscaledTime + 0.2f;
				ZDO val2 = PlayerZdo(sender);
				if (val2 == null || Vector3.Distance(val2.GetPosition(), pedestal.GetPosition()) > 4f)
				{
					return;
				}
				if (journal.Issued)
				{
					Reply(sender, "message", "The blade has already been claimed.");
				}
				else if (!Eligible(val2.GetFloat("health", 0f)))
				{
					Reply(sender, "unworthy", "");
				}
				else if (text.Length == 0)
				{
					if (!lease.Reserve(sender, Time.unscaledTime, out var offered))
					{
						Reply(sender, "message", "Another player is pulling the blade.");
					}
					else
					{
						Reply(sender, "offer", offered);
					}
				}
				else if (lease.Accept(sender, text, Time.unscaledTime))
				{
					journal.Issued = true;
					journal.Token = text;
					journal.PlayerId = val2.GetLong("playerID", 0L);
					try
					{
						PersistJournal();
					}
					catch
					{
						faulted = true;
						throw;
					}
					ZoneSystem.instance.SetGlobalKey("fm_blade_claimed");
					Reply(sender, "grant", journal.Token);
					Plugin.Log("Frostmourne claim committed for player " + journal.PlayerId + ", token " + journal.Token);
					lease.Clear();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log("Rejected/failed pull: " + ex.Message);
			}
		}

		internal static bool Eligible(float health)
		{
			return HealthGate.Eligible(health);
		}

		private void Reply(long peer, string kind, string token)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(kind);
			val.Write(token);
			val.Write(worldId);
			val.Write(pedestal.m_uid);
			router.InvokeRoutedRPC(peer, "FM.Result.v1", new object[1] { val });
		}

		private void OnResult(long sender, ZPackage package)
		{
			//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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (sender != ServerId)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			string text = package.ReadString();
			string text2 = package.ReadString();
			long num = package.ReadLong();
			ZDOID val = package.ReadZDOID();
			if (text == "message")
			{
				((Character)localPlayer).Message((MessageType)2, text2, 0, (Sprite)null, false);
			}
			else if (text == "unworthy")
			{
				Punish(localPlayer);
			}
			else
			{
				if (!Guid.TryParseExact(text2, "N", out var _))
				{
					return;
				}
				if (text == "offer")
				{
					if (!Eligible(((Character)localPlayer).GetHealth()))
					{
						Punish(localPlayer);
						return;
					}
					if (((Character)localPlayer).IsDead() || !((Humanoid)localPlayer).GetInventory().HaveEmptySlot())
					{
						((Character)localPlayer).Message((MessageType)2, "Make room in your inventory before pulling Frostmourne.", 0, (Sprite)null, false);
						return;
					}
					pendingOffer = text2;
					ZPackage val2 = new ZPackage();
					val2.Write(val);
					val2.Write(text2);
					((MonoBehaviour)Plugin.Instance).StartCoroutine(CommitAfterDelay(val2));
				}
				else
				{
					if (!(text == "grant") || !(pendingOffer == text2))
					{
						return;
					}
					pendingOffer = null;
					string key = "fm_receipt_" + num + "_" + text2;
					if (!localPlayer.m_customData.ContainsKey(key))
					{
						localPlayer.m_customData[key] = "issued";
						ItemData val3 = Plugin.SwordPrefab.GetComponent<ItemDrop>().m_itemData.Clone();
						val3.m_dropPrefab = Plugin.SwordPrefab;
						val3.m_customData["fm_claim_token"] = text2;
						val3.m_customData["fm_world"] = num.ToString(CultureInfo.InvariantCulture);
						if (!((Humanoid)localPlayer).GetInventory().AddItem(val3))
						{
							((Character)localPlayer).Message((MessageType)2, "Claim committed, but inventory changed. Ask the server admin to inspect the claim journal.", 0, (Sprite)null, false);
							Plugin.Log("Delivery failed for token " + text2);
						}
						else
						{
							((Character)localPlayer).Message((MessageType)2, "Frostmourne is yours.", 0, (Sprite)null, false);
						}
					}
				}
			}
		}

		private IEnumerator CommitAfterDelay(ZPackage commit)
		{
			yield return (object)new WaitForSecondsRealtime(0.3f);
			if (ZRoutedRpc.instance == router && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				if (!Eligible(((Character)Player.m_localPlayer).GetHealth()))
				{
					pendingOffer = null;
					Punish(Player.m_localPlayer);
				}
				else if (!((Humanoid)Player.m_localPlayer).GetInventory().HaveEmptySlot())
				{
					pendingOffer = null;
				}
				else
				{
					router.InvokeRoutedRPC(ServerId, "FM.Pull.v1", new object[1] { commit });
				}
			}
		}

		private static void Punish(Player player)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0062: Expected O, but got Unknown
			if (!((Character)player).IsDead())
			{
				((Character)player).GetSEMan().AddStatusEffect(Plugin.Unworthy, true, 0, 0f, (short)(-1));
				HitData val = new HitData
				{
					m_damage = new DamageTypes
					{
						m_frost = 1000f
					},
					m_point = ((Component)player).transform.position,
					m_blockable = false,
					m_dodgeable = false
				};
				((Character)player).Damage(val);
				if (!((Character)player).IsDead())
				{
					((Character)player).SetHealth(0f);
					((Character)player).OnDeath();
				}
			}
		}
	}
	internal static class HealthGate
	{
		internal static bool Eligible(float currentHealth)
		{
			if (!float.IsNaN(currentHealth) && !float.IsInfinity(currentHealth))
			{
				return currentHealth >= 300f;
			}
			return false;
		}
	}
	internal sealed class ClaimLease
	{
		private long peer;

		private string token;

		private float expires;

		internal bool Reserve(long sender, float now, out string offered)
		{
			offered = null;
			if (peer != 0L && peer != sender && now <= expires)
			{
				return false;
			}
			peer = sender;
			token = Guid.NewGuid().ToString("N");
			expires = now + 10f;
			offered = token;
			return true;
		}

		internal bool Accept(long sender, string offered, float now)
		{
			if (peer == sender && token != null && token == offered)
			{
				return now <= expires;
			}
			return false;
		}

		internal void Clear()
		{
			peer = 0L;
			token = null;
		}
	}
	internal static class CustomVisual
	{
		private static readonly string[] MaterialNames = new string[5] { "blade", "steel", "dark", "bone", "glow" };

		private static readonly Color[] Colors = (Color[])(object)new Color[5]
		{
			new Color(0.63f, 0.71f, 0.8f),
			new Color(0.63f, 0.71f, 0.8f),
			new Color(0.055f, 0.075f, 0.1f),
			new Color(0.29f, 0.37f, 0.46f),
			new Color(0.17f, 0.78f, 1f)
		};

		internal static void Apply(GameObject weapon, SharedData shared)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Invalid comparison between Unknown and I4
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Invalid comparison between Unknown and I4
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Expected O, but got Unknown
			//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Expected O, but got Unknown
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0700: Unknown result type (might be due to invalid IL or missing references)
			//IL_0711: Unknown result type (might be due to invalid IL or missing references)
			//IL_0744: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_0754: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_076a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0774: Unknown result type (might be due to invalid IL or missing references)
			//IL_0779: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			Transform val = weapon.transform.Find("attach");
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Mistwalker attach hierarchy was not found.");
			}
			Mesh val2 = LoadMesh();
			MeshRenderer[] componentsInChildren = weapon.GetComponentsInChildren<MeshRenderer>(true);
			Material val3 = null;
			Bounds val4 = default(Bounds);
			((Bounds)(ref val4))..ctor(Vector3.zero, Vector3.zero);
			bool flag = false;
			MeshRenderer[] array = componentsInChildren;
			foreach (MeshRenderer val5 in array)
			{
				MeshFilter component = ((Component)val5).GetComponent<MeshFilter>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sharedMesh) && ((Component)val5).transform.IsChildOf(val))
				{
					if (!Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)((Renderer)val5).sharedMaterial))
					{
						val3 = ((Renderer)val5).sharedMaterial;
					}
					Bounds bounds = component.sharedMesh.bounds;
					for (int j = -1; j <= 1; j += 2)
					{
						for (int k = -1; k <= 1; k += 2)
						{
							for (int l = -1; l <= 1; l += 2)
							{
								Vector3 val6 = val.InverseTransformPoint(((Component)component).transform.TransformPoint(((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)j, (float)k, (float)l))));
								if (!flag)
								{
									((Bounds)(ref val4))..ctor(val6, Vector3.zero);
									flag = true;
								}
								else
								{
									((Bounds)(ref val4)).Encapsulate(val6);
								}
							}
						}
					}
				}
				((Renderer)val5).enabled = false;
			}
			SkinnedMeshRenderer[] componentsInChildren2 = weapon.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Renderer)componentsInChildren2[i]).enabled = false;
			}
			LODGroup[] componentsInChildren3 = weapon.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			GameObject val7 = new GameObject("FM_CustomModel");
			val7.transform.SetParent(val, false);
			val7.layer = ((Component)val).gameObject.layer;
			int num = ((!(((Bounds)(ref val4)).size.x > ((Bounds)(ref val4)).size.y)) ? 1 : 0);
			float z = ((Bounds)(ref val4)).size.z;
			Vector3 val8 = ((Bounds)(ref val4)).size;
			if (z > ((Vector3)(ref val8))[num])
			{
				num = 2;
			}
			val8 = ((Bounds)(ref val4)).max;
			float num2 = Mathf.Abs(((Vector3)(ref val8))[num]);
			val8 = ((Bounds)(ref val4)).min;
			float num3;
			if (!(num2 > Mathf.Abs(((Vector3)(ref val8))[num])))
			{
				val8 = ((Bounds)(ref val4)).min;
				num3 = ((Vector3)(ref val8))[num];
			}
			else
			{
				val8 = ((Bounds)(ref val4)).max;
				num3 = ((Vector3)(ref val8))[num];
			}
			float num4 = num3;
			Vector3 val9 = Vector3.zero;
			((Vector3)(ref val9))[num] = ((num4 < 0f) ? (-1f) : 1f);
			if (!flag)
			{
				val9 = Vector3.forward;
				num4 = 1.47f;
			}
			val7.transform.localRotation = Quaternion.FromToRotation(Vector3.up, val9);
			val7.transform.localScale = Vector3.one * Mathf.Clamp(Mathf.Abs(num4) / 1.47f, 0.65f, 1.5f);
			val7.AddComponent<MeshFilter>().sharedMesh = val2;
			MeshRenderer val10 = val7.AddComponent<MeshRenderer>();
			Material[] array2 = (Material[])(object)new Material[MaterialNames.Length];
			for (int m = 0; m < array2.Length; m++)
			{
				array2[m] = CreateMaterial(val3, m);
			}
			((Renderer)val10).sharedMaterials = array2;
			int num5 = 0;
			ParticleSystem val11 = null;
			ParticleSystem[] componentsInChildren4 = weapon.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val12 in componentsInChildren4)
			{
				ShapeModule shape = val12.shape;
				if ((int)((ShapeModule)(ref shape)).shapeType == 6 || (int)((ShapeModule)(ref shape)).shapeType == 13)
				{
					if (!Object.op_Implicit((Object)(object)val11) && ((Component)val12).transform.IsChildOf(val))
					{
						val11 = val12;
					}
					((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)13;
					((ShapeModule)(ref shape)).meshRenderer = val10;
					((ShapeModule)(ref shape)).useMeshMaterialIndex = true;
					((ShapeModule)(ref shape)).meshMaterialIndex = 0;
				}
				num5++;
			}
			if (!Object.op_Implicit((Object)(object)val11))
			{
				ParticleSystem[] componentsInChildren5 = ((Component)val).GetComponentsInChildren<ParticleSystem>(true);
				if (componentsInChildren5.Length != 0)
				{
					val11 = componentsInChildren5[0];
				}
			}
			if (Object.op_Implicit((Object)(object)val11))
			{
				GameObject val13 = Object.Instantiate<GameObject>(((Component)val11).gameObject, val7.transform);
				((Object)val13).name = "FM_ExtraBladeMist";
				val13.transform.localPosition = Vector3.zero;
				val13.transform.localRotation = Quaternion.identity;
				val13.transform.localScale = Vector3.one;
				List<GameObject> list = new List<GameObject>();
				foreach (Transform item in val13.transform)
				{
					Transform val14 = item;
					if (((Component)val14).GetComponentsInChildren<ParticleSystem>(true).Length == 0)
					{
						list.Add(((Component)val14).gameObject);
					}
				}
				foreach (GameObject item2 in list)
				{
					Object.DestroyImmediate((Object)(object)item2);
				}
				MonoBehaviour[] componentsInChildren6 = val13.GetComponentsInChildren<MonoBehaviour>(true);
				for (int i = 0; i < componentsInChildren6.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren6[i]);
				}
				array = val13.GetComponentsInChildren<MeshRenderer>(true);
				for (int i = 0; i < array.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)array[i]);
				}
				componentsInChildren2 = val13.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
				}
				MeshFilter[] componentsInChildren7 = val13.GetComponentsInChildren<MeshFilter>(true);
				for (int i = 0; i < componentsInChildren7.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren7[i]);
				}
				Collider[] componentsInChildren8 = val13.GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren8.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren8[i]);
				}
				Rigidbody[] componentsInChildren9 = val13.GetComponentsInChildren<Rigidbody>(true);
				for (int i = 0; i < componentsInChildren9.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren9[i]);
				}
				ParticleSystemRenderer[] componentsInChildren10 = val13.GetComponentsInChildren<ParticleSystemRenderer>(true);
				Color val17 = default(Color);
				foreach (ParticleSystemRenderer val15 in componentsInChildren10)
				{
					if (Object.op_Implicit((Object)(object)((Renderer)val15).sharedMaterial))
					{
						Material val16 = new Material(((Renderer)val15).sharedMaterial);
						((Color)(ref val17))..ctor(0.45f, 0.8f, 1f, 0.45f);
						if (val16.HasProperty("_TintColor"))
						{
							val16.SetColor("_TintColor", val17);
						}
						if (val16.HasProperty("_Color"))
						{
							val16.SetColor("_Color", val17);
						}
						if (val16.HasProperty("_EmissionColor"))
						{
							val16.SetColor("_EmissionColor", val17 * 2f);
							val16.EnableKeyword("_EMISSION");
						}
						((Renderer)val15).sharedMaterial = val16;
					}
				}
				componentsInChildren4 = val13.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem obj in componentsInChildren4)
				{
					MainModule main = obj.main;
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).playOnAwake = true;
					((MainModule)(ref main)).maxParticles = 180;
					((MainModule)(ref main)).startLifetime = new MinMaxCurve(1.1f, 1.6f);
					((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.01f, 0.08f);
					((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
					((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * 1.2f;
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.48f, 0.83f, 1f, 0.38f));
					EmissionModule emission = obj.emission;
					((EmissionModule)(ref emission)).enabled = true;
					((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(30f);
					ShapeModule shape2 = obj.shape;
					((ShapeModule)(ref shape2)).enabled = true;
					((ShapeModule)(ref shape2)).shapeType = (ParticleSystemShapeType)13;
					((ShapeModule)(ref shape2)).meshRenderer = val10;
					((ShapeModule)(ref shape2)).useMeshMaterialIndex = true;
					((ShapeModule)(ref shape2)).meshMaterialIndex = 0;
				}
				val13.SetActive(true);
			}
			Demister[] componentsInChildren11 = weapon.GetComponentsInChildren<Demister>(true);
			for (int i = 0; i < componentsInChildren11.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren11[i]);
			}
			shared.m_icons = (Sprite[])(object)new Sprite[1] { MakeIcon(val2) };
			Plugin.Log("Custom Frostmourne mesh loaded (" + val2.vertexCount + " vertices); retained " + num5 + " Mistwalker particle systems.");
		}

		private static Material CreateMaterial(Material donor, int index)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			Shader val = (Object.op_Implicit((Object)(object)donor) ? donor.shader : (Shader.Find("Standard") ?? Shader.Find("Sprites/Default")));
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("No suitable sword shader available.");
			}
			Material val2 = (Object.op_Implicit((Object)(object)donor) ? new Material(donor) : new Material(val));
			((Object)val2).name = "FM_" + MaterialNames[index];
			if (val2.HasProperty("_MainTex"))
			{
				val2.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
			}
			if (val2.HasProperty("_EmissionMap"))
			{
				val2.SetTexture("_EmissionMap", (Texture)(object)Texture2D.whiteTexture);
			}
			if (val2.HasProperty("_BumpMap"))
			{
				val2.SetTexture("_BumpMap", (Texture)null);
				val2.DisableKeyword("_NORMALMAP");
			}
			if (val2.HasProperty("_MetallicGlossMap"))
			{
				val2.SetTexture("_MetallicGlossMap", (Texture)null);
				val2.DisableKeyword("_METALLICGLOSSMAP");
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", Colors[index]);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", (index == 2) ? 0.1f : 0.85f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", (index == 2) ? 0.2f : 0.65f);
			}
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.SetColor("_EmissionColor", (index == 4) ? (Colors[4] * 3.5f) : Color.black);
				if (index == 4)
				{
					val2.EnableKeyword("_EMISSION");
				}
				else
				{
					val2.DisableKeyword("_EMISSION");
				}
			}
			if (index == 4 && val2.HasProperty("_Cull"))
			{
				val2.SetFloat("_Cull", 0f);
			}
			return val2;
		}

		internal static Mesh LoadMesh(string resource = "Frostmourne.Assets.Frostmourne.obj", string[] materialNames = null)
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			materialNames = materialNames ?? MaterialNames;
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
			if (stream == null)
			{
				throw new InvalidOperationException("Embedded custom mesh missing.");
			}
			List<Vector3> list = new List<Vector3>();
			List<int>[] array = new List<int>[materialNames.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new List<int>();
			}
			int num = 0;
			using (StreamReader streamReader = new StreamReader(stream))
			{
				string text;
				while ((text = streamReader.ReadLine()) != null)
				{
					string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
					if (array2.Length == 0 || array2[0].StartsWith("#"))
					{
						continue;
					}
					if (array2[0] == "v")
					{
						list.Add(new Vector3(Parse(array2[1]), Parse(array2[2]), Parse(array2[3])));
					}
					else if (array2[0] == "usemtl")
					{
						num = Array.IndexOf(materialNames, array2[1]);
						if (num < 0)
						{
							throw new InvalidDataException("Unknown material.");
						}
					}
					else
					{
						if (!(array2[0] == "f"))
						{
							continue;
						}
						if (array2.Length != 4)
						{
							throw new InvalidDataException("Only triangular faces are supported.");
						}
						for (int j = 1; j < 4; j++)
						{
							int num2 = int.Parse(array2[j], CultureInfo.InvariantCulture) - 1;
							if (num2 < 0 || num2 >= list.Count)
							{
								throw new InvalidDataException("Invalid mesh index.");
							}
							array[num].Add(num2);
						}
					}
				}
			}
			Mesh val = new Mesh
			{
				name = resource,
				subMeshCount = materialNames.Length
			};
			val.SetVertices(list);
			for (int k = 0; k < array.Length; k++)
			{
				val.SetTriangles(array[k], k);
			}
			val.RecalculateNormals();
			val.RecalculateBounds();
			Vector2[] array3 = (Vector2[])(object)new Vector2[list.Count];
			for (int l = 0; l < array3.Length; l++)
			{
				array3[l] = new Vector2((list[l].x + 0.4f) / 0.8f, (list[l].y + 0.4f) / 1.87f);
			}
			val.uv = array3;
			val.RecalculateTangents();
			return val;
		}

		private static float Parse(string value)
		{
			return float.Parse(value, CultureInfo.InvariantCulture);
		}

		private static Sprite MakeIcon(Mesh mesh)
		{
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Expected O, but got Unknown
			//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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[16384];
			Vector3[] vertices = mesh.vertices;
			float[] array2 = new float[16384];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = float.NegativeInfinity;
			}
			for (int j = 0; j < MaterialNames.Length; j++)
			{
				int[] triangles = mesh.GetTriangles(j);
				for (int k = 0; k < triangles.Length; k += 3)
				{
					Vector3 val = Project(vertices[triangles[k]]);
					Vector3 val2 = Project(vertices[triangles[k + 1]]);
					Vector3 val3 = Project(vertices[triangles[k + 2]]);
					float num = (val2.y - val3.y) * (val.x - val3.x) + (val3.x - val2.x) * (val.y - val3.y);
					if (Mathf.Abs(num) < 0.0001f)
					{
						continue;
					}
					int num2 = Mathf.Clamp(Mathf.FloorToInt(Mathf.Min(new float[3] { val.x, val2.x, val3.x })), 0, 127);
					int num3 = Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(new float[3] { val.x, val2.x, val3.x })), 0, 127);
					int num4 = Mathf.Clamp(Mathf.FloorToInt(Mathf.Min(new float[3] { val.y, val2.y, val3.y })), 0, 127);
					int num5 = Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(new float[3] { val.y, val2.y, val3.y })), 0, 127);
					for (int l = num4; l <= num5; l++)
					{
						for (int m = num2; m <= num3; m++)
						{
							float num6 = ((val2.y - val3.y) * ((float)m + 0.5f - val3.x) + (val3.x - val2.x) * ((float)l + 0.5f - val3.y)) / num;
							float num7 = ((val3.y - val.y) * ((float)m + 0.5f - val3.x) + (val.x - val3.x) * ((float)l + 0.5f - val3.y)) / num;
							float num8 = 1f - num6 - num7;
							if (!(num6 < 0f) && !(num7 < 0f) && !(num8 < 0f))
							{
								float num9 = num6 * val.z + num7 * val2.z + num8 * val3.z;
								int num10 = l * 128 + m;
								if (num9 >= array2[num10])
								{
									array2[num10] = num9;
									array[num10] = Colors[j];
								}
							}
						}
					}
				}
			}
			Texture2D val4 = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = "FM_CustomIcon",
				filterMode = (FilterMode)1
			};
			val4.SetPixels(array);
			val4.Apply(false, true);
			return Sprite.Create(val4, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
		}

		private static Vector3 Project(Vector3 v)
		{
			//IL_0005: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(64f + (v.x * 0.88f + v.y * 0.32f - 0.17f) * 53f, 11f + (v.y + 0.4f) * 53f, v.z);
		}
	}
	internal sealed class Journal
	{
		internal Vector3 Position;

		internal bool Located;

		internal bool Issued;

		internal string Token = "";

		internal long PlayerId;

		private readonly string path;

		internal Journal(long world)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(Paths.ConfigPath, "FrostmourneWorlds");
			Directory.CreateDirectory(path);
			this.path = Path.Combine(path, world.ToString(CultureInfo.InvariantCulture) + ".journal");
			if (File.Exists(this.path))
			{
				string[] array = File.ReadAllLines(this.path);
				if (array.Length != 8 || array[0] != "FM1")
				{
					throw new InvalidDataException("Invalid Frostmourne journal: " + this.path);
				}
				Located = bool.Parse(array[1]);
				Position = new Vector3(Parse(array[2]), Parse(array[3]), Parse(array[4]));
				Issued = bool.Parse(array[5]);
				PlayerId = long.Parse(array[6], CultureInfo.InvariantCulture);
				Token = array[7];
				if (float.IsNaN(Position.x) || float.IsInfinity(Position.x) || float.IsNaN(Position.y) || float.IsInfinity(Position.y) || float.IsNaN(Position.z) || float.IsInfinity(Position.z))
				{
					throw new InvalidDataException("Invalid pedestal position.");
				}
				if (Issued && !Guid.TryParseExact(Token, "N", out var _))
				{
					throw new InvalidDataException("Invalid claim token.");
				}
			}
		}

		private static float Parse(string text)
		{
			return float.Parse(text, CultureInfo.InvariantCulture);
		}

		internal void Save()
		{
			string[] array = new string[8]
			{
				"FM1",
				Located.ToString(),
				Position.x.ToString("R", CultureInfo.InvariantCulture),
				Position.y.ToString("R", CultureInfo.InvariantCulture),
				Position.z.ToString("R", CultureInfo.InvariantCulture),
				Issued.ToString(),
				PlayerId.ToString(CultureInfo.InvariantCulture),
				Token
			};
			string sourceFileName = path + ".tmp";
			using (FileStream fileStream = new FileStream(sourceFileName, FileMode.Create, FileAccess.Write, FileShare.None))
			{
				using (StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8, 1024, leaveOpen: true))
				{
					string[] array2 = array;
					foreach (string value in array2)
					{
						streamWriter.WriteLine(value);
					}
					streamWriter.Flush();
				}
				fileStream.Flush(flushToDisk: true);
			}
			if (File.Exists(path))
			{
				File.Replace(sourceFileName, path, path + ".bak");
			}
			else
			{
				File.Move(sourceFileName, path);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")]
	internal static class AttackSpeedPatch
	{
		private sealed class Clock
		{
			internal float Base = 1f;

			internal float Applied = 1f;

			internal bool Modified;
		}

		private static readonly ConditionalWeakTable<Animator, Clock> clocks = new ConditionalWeakTable<Animator, Clock>();

		private static void Prefix(Animator ___m_animator)
		{
			Restore(___m_animator);
		}

		internal static void Restore(Animator animator)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				Clock orCreateValue = clocks.GetOrCreateValue(animator);
				if (orCreateValue.Modified && Mathf.Approximately(animator.speed, orCreateValue.Applied))
				{
					animator.speed = orCreateValue.Base;
				}
				orCreateValue.Modified = false;
			}
		}

		internal static void Forget(Animator animator)
		{
			if (Object.op_Implicit((Object)(object)animator))
			{
				clocks.GetOrCreateValue(animator).Modified = false;
			}
		}

		private static void Postfix(Character ___m_character, Animator ___m_animator)
		{
			if (Object.op_Implicit((Object)(object)___m_animator) && !(___m_animator.speed < 0.01f))
			{
				Player val = (Player)(object)((___m_character is Player) ? ___m_character : null);
				if (val != null && ((Character)val).InAttack() && SoulPower.Carried(val) != null)
				{
					Clock orCreateValue = clocks.GetOrCreateValue(___m_animator);
					orCreateValue.Base = ___m_animator.speed;
					orCreateValue.Applied = orCreateValue.Base * 1.25f;
					orCreateValue.Modified = true;
					___m_animator.speed = orCreateValue.Applied;
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAnimEvent), "FreezeFrame")]
	internal static class FreezePatch
	{
		private static void Prefix(Animator ___m_animator)
		{
			AttackSpeedPatch.Restore(___m_animator);
		}
	}
	[HarmonyPatch(typeof(CharacterAnimEvent), "Speed")]
	internal static class SpeedEventPatch
	{
		private static void Postfix(Animator ___m_animator)
		{
			AttackSpeedPatch.Forget(___m_animator);
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "UpdateRegisters")]
	internal static class NoRecipePatch
	{
		private static void Postfix(ObjectDB __instance)
		{
			__instance.m_recipes.RemoveAll((Recipe recipe) => Object.op_Implicit((Object)(object)recipe) && Object.op_Implicit((Object)(object)recipe.m_item) && ((Object)recipe.m_item).name == "FM_Frostmourne" && !Upgrades.IsRecipe(recipe));
		}
	}
	[HarmonyPatch]
	internal static class ProvenancePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == "AddItem")
				{
					yield return methodInfo;
				}
			}
		}

		internal static bool Valid(Dictionary<string, string> data)
		{
			long result2;
			if (data != null && data.TryGetValue("fm_claim_token", out var value) && Guid.TryParseExact(value, "N", out var _) && data.TryGetValue("fm_world", out var value2))
			{
				return long.TryParse(value2, out result2);
			}
			return false;
		}

		private static bool Prefix(object[] __args)
		{
			bool flag = false;
			Dictionary<string, string> data = null;
			foreach (object obj in __args)
			{
				ItemData val = (ItemData)((obj is ItemData) ? obj : null);
				if (val != null && Plugin.IsSword(val))
				{
					flag = true;
					data = val.m_customData;
					continue;
				}
				GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
				if (val2 != null && ((Object)val2).name == "FM_Frostmourne")
				{
					flag = true;
					data = val2.GetComponent<ItemDrop>()?.m_itemData.m_customData;
				}
				else if (obj is string text && text == "FM_Frostmourne")
				{
					flag = true;
				}
				else if (obj is Dictionary<string, string> dictionary)
				{
					data = dictionary;
				}
			}
			if (flag)
			{
				return Valid(data);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class EquipProvenancePatch
	{
		private static bool Prefix(ItemData item, ref bool __result)
		{
			if (!Plugin.IsSword(item) || ProvenancePatch.Valid(item.m_customData))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	public sealed class SwordGuard : MonoBehaviour
	{
		private IEnumerator Start()
		{
			yield return null;
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			ItemDrop component2 = ((Component)this).GetComponent<ItemDrop>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !Object.op_Implicit((Object)(object)component2) || ProvenancePatch.Valid(component2.m_itemData.m_customData))
			{
				yield break;
			}
			if (component.IsOwner())
			{
				component.Destroy();
				yield break;
			}
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}
	}
	public sealed class Pedestal : MonoBehaviour, Hoverable, Interactable
	{
		private GameObject blade;

		private ZNetView view;

		private void Awake()
		{
			Transform obj = ((Component)this).transform.Find("blade");
			blade = ((obj != null) ? ((Component)obj).gameObject : null);
			view = ((Component)this).GetComponent<ZNetView>();
		}

		private void Update()
		{
			Authority.RejectExtraPedestal(view);
			if (Object.op_Implicit((Object)(object)blade) && Object.op_Implicit((Object)(object)ZoneSystem.instance))
			{
				blade.SetActive(!ZoneSystem.instance.GetGlobalKey("fm_blade_claimed"));
			}
		}

		public string GetHoverName()
		{
			return "Frostmourne Pedestal";
		}

		public float GetHoverOffset()
		{
			return 1.5f;
		}

		public string GetHoverText()
		{
			if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !ZoneSystem.instance.GetGlobalKey("fm_blade_claimed"))
			{
				return "Frostmourne Pedestal\n[<color=yellow><b>$KEY_Use</b></color>] Pull Frostmourne";
			}
			return "Frostmourne Pedestal\nThe blade has been claimed.";
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				return false;
			}
			Authority.Request(component.GetZDO().m_uid);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal static class PedestalVisual
	{
		internal const float Top = 0.68f;

		internal static void Build(GameObject root)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			Material val = null;
			string[] array = new string[4] { "stone_floor_2x2", "stone_wall_2x1", "stone_wall_4x2", "stone_floor" };
			foreach (string text in array)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				if (Object.op_Implicit((Object)(object)prefab))
				{
					MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true);
					if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)((Renderer)componentInChildren).sharedMaterial))
					{
						val = ((Renderer)componentInChildren).sharedMaterial;
						break;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = ((Renderer)((Component)Plugin.SwordPrefab.transform.Find("attach/FM_CustomModel")).GetComponent<MeshRenderer>()).sharedMaterial;
			}
			GameObject val2 = new GameObject("FM_CarvedPedestal");
			val2.transform.SetParent(root.transform, false);
			val2.layer = root.layer;
			Mesh val3 = CustomVisual.LoadMesh("Frostmourne.Assets.Pedestal.obj", new string[3] { "stone", "carving", "glow" });
			Vector2[] array2 = (Vector2[])(object)new Vector2[val3.vertexCount];
			Vector3[] vertices = val3.vertices;
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = new Vector2(vertices[j].x * 2f, vertices[j].z * 2f + vertices[j].y);
			}
			val3.uv = array2;
			val3.RecalculateTangents();
			val2.AddComponent<MeshFilter>().sharedMesh = val3;
			Material[] array3 = (Material[])(object)new Material[3];
			for (int k = 0; k < 3; k++)
			{
				Material val4 = new Material(val)
				{
					name = "FM_Pedestal_" + k
				};
				Color val5 = (Color)(k switch
				{
					1 => new Color(0.1f, 0.13f, 0.17f), 
					0 => new Color(0.55f, 0.61f, 0.67f), 
					_ => new Color(0.15f, 0.7f, 1f), 
				});
				if (val4.HasProperty("_Color"))
				{
					val4.SetColor("_Color", val5);
				}
				if (k > 0 && val4.HasProperty("_MainTex"))
				{
					val4.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
				}
				if (val4.HasProperty("_EmissionColor"))
				{
					val4.SetColor("_EmissionColor", (k == 2) ? (val5 * 1.8f) : Color.black);
				}
				if (k == 2)
				{
					if (val4.HasProperty("_EmissionMap"))
					{
						val4.SetTexture("_EmissionMap", (Texture)(object)Texture2D.whiteTexture);
					}
					val4.EnableKeyword("_EMISSION");
					if (val4.HasProperty("_Cull"))
					{
						val4.SetFloat("_Cull", 0f);
					}
				}
				else
				{
					val4.DisableKeyword("_EMISSION");
				}
				array3[k] = val4;
			}
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = array3;
			val2.AddComponent<MeshCollider>().sharedMesh = val3;
			GameObject obj = Object.Instantiate<GameObject>(((Component)Plugin.SwordPrefab.transform.Find("attach")).gameObject, root.transform);
			((Object)obj).name = "blade";
			obj.transform.localScale = Vector3.one;
			Transform val6 = obj.transform.Find("FM_CustomModel");
			Vector3 val7 = val6.localRotation * Vector3.up;
			obj.transform.localRotation = Quaternion.FromToRotation(val7, Vector3.down);
			Bounds bounds = ((Component)val6).GetComponent<MeshFilter>().sharedMesh.bounds;
			float num = ((Bounds)(ref bounds)).max.y * val6.localScale.y;
			obj.transform.localPosition = new Vector3(0f, 0.68f + num - 0.25f, 0f);
			Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Plugin.Log("Carved pedestal created using installed-game shader " + ((Object)val.shader).name + "; blade embedded 0.25m into its socket.");
		}
	}
	[BepInPlugin("local.frostmourne.unique", "FrostmourneHungers", "1.2.3")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "local.frostmourne.unique";

		public const string Sword = "FM_Frostmourne";

		public const string Pedestal = "FM_Pedestal";

		internal static Plugin Instance;

		internal static GameObject SwordPrefab;

		internal static StatusEffect Unworthy;

		internal static string BundlePath;

		private Harmony harmony;

		private Authority authority;

		private float nextTick;

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Instance = this;
			BundlePath = ((BaseUnityPlugin)this).Config.Bind<string>("Visuals", "AssetBundle", "frostmourne_assets", "Optional bundle beside the plugin DLL, containing FM_Visual and FM_Icon.").Value;
			PrefabManager.OnVanillaPrefabsAvailable += RegisterAssets;
			harmony = new Harmony("local.frostmourne.unique");
			harmony.PatchAll();
			((Component)this).gameObject.AddComponent<SoulHud>();
			SoulAdmin.Initialize();
		}

		private void RegisterAssets()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_009d: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)SwordPrefab))
			{
				CustomItem val = new CustomItem("FM_Frostmourne", "SwordMistwalker", new ItemConfig
				{
					Name = "Frostmourne",
					Description = "A singular cursed blade. +10% movement speed and +25% attack speed while wielded or sheathed."
				});
				SwordPrefab = val.ItemPrefab;
				SharedData shared = SwordPrefab.GetComponent<ItemDrop>().m_itemData.m_shared;
				shared.m_maxStackSize = 1;
				shared.m_maxQuality = 4;
				shared.m_damages = new DamageTypes
				{
					m_slash = 215f,
					m_frost = 120f,
					m_spirit = 80f
				};
				shared.m_damagesPerLevel = new DamageTypes
				{
					m_slash = 43f,
					m_frost = 24f,
					m_spirit = 16f
				};
				shared.m_movementModifier = 0f;
				shared.m_useDurability = false;
				shared.m_attackStatusEffect = null;
				SwordPrefab.AddComponent<SwordGuard>();
				CustomVisual.Apply(SwordPrefab, shared);
				ApplyVisual(shared);
				WielderCurse wielderCurse = ScriptableObject.CreateInstance<WielderCurse>();
				((Object)wielderCurse).name = "FM_WielderCurse";
				((StatusEffect)wielderCurse).m_name = "Frostmourne's Curse";
				((StatusEffect)wielderCurse).m_tooltip = "+10% movement speed; +25% attack speed while wielded or sheathed.";
				((StatusEffect)wielderCurse).m_icon = shared.m_icons[0];
				ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)wielderCurse, false));
				shared.m_equipStatusEffect = (StatusEffect)(object)wielderCurse;
				Unworthy = ScriptableObject.CreateInstance<StatusEffect>();
				((Object)Unworthy).name = "FM_Unworthy";
				Unworthy.m_name = "Unworthy";
				Unworthy.m_tooltip = "The blade rejects you.";
				Unworthy.m_ttl = 10f;
				Unworthy.m_icon = shared.m_icons[0];
				ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(Unworthy, false));
				ItemManager.Instance.AddItem(val);
				Upgrades.Register();
				GameObject val2 = new GameObject("FM_Pedestal");
				val2.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)val2);
				val2.layer = LayerMask.NameToLayer("piece");
				ZNetView obj = val2.AddComponent<ZNetView>();
				obj.m_persistent = true;
				obj.m_distant = true;
				PedestalVisual.Build(val2);
				val2.AddComponent<Pedestal>();
				PrefabManager.Instance.AddPrefab(new CustomPrefab(val2, false));
				val2.SetActive(true);
				PrefabManager.OnVanillaPrefabsAvailable -= RegisterAssets;
			}
		}

		private void ApplyVisual(SharedData shared)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), BundlePath);
			if (!File.Exists(text))
			{
				return;
			}
			AssetBundle val = null;
			try
			{
				val = AssetBundle.LoadFromFile(text);
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("Unity could not load the asset bundle.");
				}
				GameObject val2 = val.LoadAsset<GameObject>("FM_Visual");
				if (Object.op_Implicit((Object)(object)val2))
				{
					Transform val3 = SwordPrefab.transform.Find("attach");
					Transform val4 = (Object.op_Implicit((Object)(object)val3) ? val3.Find("FM_CustomModel") : null);
					GameObject val5 = Object.Instantiate<GameObject>(val2, Object.op_Implicit((Object)(object)val3) ? val3 : SwordPrefab.transform);
					((Object)val5).name = "FM_BundleModel";
					val5.transform.localPosition = Vector3.zero;
					val5.transform.localRotation = (Object.op_Implicit((Object)(object)val4) ? val4.localRotation : Quaternion.identity);
					val5.transform.localScale = (Object.op_Implicit((Object)(object)val4) ? val4.localScale : Vector3.one);
					MonoBehaviour[] componentsInChildren = val5.GetComponentsInChildren<MonoBehaviour>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
					}
					Collider[] componentsInChildren2 = val5.GetComponentsInChildren<Collider>(true);
					for (int i = 0; i < componentsInChildren2.Length; i++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
					}
					Rigidbody[] componentsInChildren3 = val5.GetComponentsInChildren<Rigidbody>(true);
					for (int i = 0; i < componentsInChildren3.Length; i++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
					}
					if (Object.op_Implicit((Object)(object)val4))
					{
						Renderer[] componentsInChildren4 = ((Component)val4).GetComponentsInChildren<Renderer>(true);
						for (int i = 0; i < componentsInChildren4.Length; i++)
						{
							componentsInChildren4[i].enabled = false;
						}
					}
				}
				Sprite val6 = val.LoadAsset<Sprite>("FM_Icon");
				if (Object.op_Implicit((Object)(object)val6))
				{
					shared.m_icons = (Sprite[])(object)new Sprite[1] { val6 };
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Using built-in custom assets: " + ex.Message));
			}
			finally
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.Unload(false);
				}
			}
		}

		private void Update()
		{
			SoulPower.Tick();
			if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZRoutedRpc.instance == null || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || ZDOMan.instance == null || !Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				return;
			}
			if (authority == null || authority.Router != ZRoutedRpc.instance)
			{
				authority = new Authority();
			}
			if (Time.unscaledTime < nextTick)
			{
				return;
			}
			nextTick = Time.unscaledTime + 1f;
			try
			{
				authority.Tick();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Frostmourne paused this tick: " + ex));
			}
		}

		internal static bool IsSword(ItemData item)
		{
			if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return ((Object)item.m_dropPrefab).name == "FM_Frostmourne";
			}
			return false;
		}

		internal static void Log(string message)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterAssets;
		}
	}
	public sealed class WielderCurse : StatusEffect
	{
		public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 direction)
		{
			speed *= 1.1f;
		}
	}
	internal static class SoulAdmin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__8_0;

			internal void <Initialize>b__8_0(ConsoleEventArgs args)
			{
				Command(args);
			}
		}

		private const string RequestRpc = "FM_AdminSoulRequest_124";

		private const string ResultRpc = "FM_AdminSoulResult_124";

		private static ZRoutedRpc router;

		private static string pending;

		private static string pendingToken;

		private static float expires;

		private static long ServerId
		{
			get
			{
				if (!ZNet.instance.IsServer())
				{
					return ZNet.instance.GetServerPeer()?.m_uid ?? 0;
				}
				return ZNet.GetUID();
			}
		}

		internal static void Initialize()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			object obj = <>c.<>9__8_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					Command(args);
				};
				<>c.<>9__8_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("fm_soul", "fm_soul <0-100>: set your held/sheathed Frostmourne soul power (admin only).", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, true);
		}

		internal static void Register(ZRoutedRpc instance)
		{
			router = instance;
			pending = null;
			router.Register<ZPackage>("FM_AdminSoulRequest_124", (Action<long, ZPackage>)ReceiveRequest);
			router.Register<ZPackage>("FM_AdminSoulResult_124", (Action<long, ZPackage>)ReceiveResult);
		}

		private static void Command(ConsoleEventArgs args)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length != 2 || !int.TryParse(args[1], out var result) || result < 0 || result > 100)
			{
				args.Context.AddString("Usage: fm_soul <0-100>");
				return;
			}
			if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.LocalPlayerIsAdminOrHost())
			{
				args.Context.AddString("Only the host or a server administrator may use fm_soul.");
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			ItemData val = SoulPower.Carried(localPlayer);
			if (!Object.op_Implicit((Object)(object)localPlayer) || val == null || !ProvenancePatch.Valid(val.m_customData) || router == null)
			{
				args.Context.AddString("Hold or sheath your Frostmourne in a loaded world first.");
				return;
			}
			pending = Guid.NewGuid().ToString("N");
			expires = Time.unscaledTime + 10f;
			pendingToken = val.m_customData["fm_claim_token"];
			ZPackage val2 = new ZPackage();
			val2.Write(pending);
			val2.Write(((Component)localPlayer).GetComponent<ZNetView>().GetZDO().m_uid);
			val2.Write(result);
			router.InvokeRoutedRPC(ServerId, "FM_AdminSoulRequest_124", new object[1] { val2 });
		}

		private static void ReceiveRequest(long sender, ZPackage package)
		{
			//IL_0021: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer())
			{
				return;
			}
			string text = package.ReadString();
			ZDOID val = package.ReadZDOID();
			int num = package.ReadInt();
			if (Guid.TryParseExact(text, "N", out var _) && num >= 0 && num <= 100)
			{
				bool flag = false;
				if (sender == ZNet.GetUID())
				{
					Player localPlayer = Player.m_localPlayer;
					ZNetView val2 = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<ZNetView>() : null);
					flag = Object.op_Implicit((Object)(object)val2) && val2.IsValid() && val2.GetZDO().m_uid == val;
				}
				else
				{
					ZNetPeer peer = ZNet.instance.GetPeer(sender);
					flag = peer != null && peer.m_characterID == val && peer.m_socket != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName());
				}
				ZPackage val3 = new ZPackage();
				val3.Write(text);
				val3.Write(val);
				val3.Write(num);
				val3.Write(flag);
				if (flag)
				{
					Plugin.Log("Server authorized fm_soul " + num + " for peer " + sender + ".");
				}
				router.InvokeRoutedRPC(sender, "FM_AdminSoulResult_124", new object[1] { val3 });
			}
		}

		private static void ReceiveResult(long sender, ZPackage package)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)
			if (router == null || !Object.op_Implicit((Object)(object)ZNet.instance) || sender != ServerId)
			{
				return;
			}
			string text = package.ReadString();
			ZDOID val = package.ReadZDOID();
			int num = package.ReadInt();
			bool flag = package.ReadBool();
			if (pending == null || text != pending || Time.unscaledTime > expires)
			{
				return;
			}
			pending = null;
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Component)localPlayer).GetComponent<ZNetView>().GetZDO().m_uid != val)
			{
				return;
			}
			if (!flag)
			{
				((Character)localPlayer).Message((MessageType)2, "Server rejected fm_soul: you are not an administrator.", 0, (Sprite)null, false);
				return;
			}
			ItemData val2 = SoulPower.Carried(localPlayer);
			if (num >= 0 && num <= 100 && val2 != null && val2.m_customData.TryGetValue("fm_claim_token", out var value) && !(value != pendingToken))
			{
				SoulPower.SetPower(localPlayer, val2, num);
				((Character)localPlayer).Message((MessageType)2, "Frostmourne soul power: " + num + "%", 0, (Sprite)null, false);
				Plugin.Log("Administrator set Frostmourne soul power to " + num + "% for their own character.");
			}
		}
	}
	public sealed class SoulHud : MonoBehaviour
	{
		private GameObject root;

		private Image fill;

		private Image border;

		private Text label;

		private Sprite fillSprite;

		private void Update()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			bool flag = Object.op_Implicit((Object)(object)localPlayer) && !((Character)localPlayer).IsDead() && Plugin.IsSword(((Humanoid)localPlayer).RightItem) && Object.op_Implicit((Object)(object)Hud.instance);
			if (flag && !Object.op_Implicit((Object)(object)root))
			{
				Build();
			}
			if (Object.op_Implicit((Object)(object)root))
			{
				root.SetActive(flag);
				if (flag)
				{
					int num = SoulPower.Power(((Humanoid)localPlayer).RightItem);
					fill.fillAmount = (float)num / 100f;
					float num2 = ((Time.unscaledTime < SoulPower.FlashUntil) ? (0.55f + 0.45f * Mathf.Abs(Mathf.Sin(Time.unscaledTime * 28f))) : 0f);
					((Graphic)border).color = Color.Lerp(new Color(0.14f, 0.45f, 0.68f, 0.85f), new Color(0.7f, 0.95f, 1f), num2);
					((Graphic)fill).color = Color.Lerp(new Color(0.12f, 0.65f, 1f, 0.95f), Color.white, num2 * 0.6f);
					label.text = "SOUL POWER\n" + num + "%";
				}
			}
		}

		private void Build()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)fillSprite))
			{
				Object.Destroy((Object)(object)fillSprite);
			}
			root = new GameObject("FM_SoulPowerHud", new Type[1] { typeof(RectTransform) });
			Canvas componentInParent = ((Component)Hud.instance).GetComponentInParent<Canvas>();
			root.transform.SetParent(Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).transform : ((Component)Hud.instance).transform, false);
			RectTransform component = root.GetComponent<RectTransform>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(1f, 0.5f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.pivot = new Vector2(1f, 0.5f);
			component.anchoredPosition = new Vector2(-42f, 0f);
			component.sizeDelta = new Vector2(110f, 290f);
			Image val2 = Panel("Border", root.transform, new Vector2(39f, 15f), new Vector2(32f, 224f));
			border = val2;
			((Graphic)Panel("Background", root.transform, new Vector2(39f, 15f), new Vector2(24f, 216f))).color = new Color(0.015f, 0.035f, 0.065f, 0.94f);
			fill = Panel("BlueSoulPower", root.transform, new Vector2(39f, 15f), new Vector2(24f, 216f));
			Texture2D whiteTexture = Texture2D.whiteTexture;
			fillSprite = Sprite.Create(whiteTexture, new Rect(0f, 0f, (float)((Texture)whiteTexture).width, (float)((Texture)whiteTexture).height), Vector2.one * 0.5f);
			fill.sprite = fillSprite;
			fill.type = (Type)3;
			fill.fillMethod = (FillMethod)1;
			fill.fillOrigin = 0;
			GameObject val3 = new GameObject("SoulLabel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val3.transform.SetParent(root.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(140f, 54f);
			component2.anchoredPosition = new Vector2(0f, -139f);
			label = val3.GetComponent<Text>();
			Text componentInChildren = ((Component)Hud.instance).GetComponentInChildren<Text>(true);
			label.font = ((Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.font)) ? componentInChildren.font : Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"));
			label.fontSize = 16;
			label.alignment = (TextAnchor)4;
			((Graphic)label).color = new Color(0.5f, 0.87f, 1f);
			((Graphic)label).raycastTarget = false;
		}

		private static Image Panel(string name, Transform parent, Vector2 position, Vector2 size)
		{
			//IL_0021: 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_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_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchoredPosition = position;
			component.sizeDelta = size;
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).raycastTarget = false;
			return component2;
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)fillSprite))
			{
				Object.Destroy((Object)(object)fillSprite);
			}
			if (Object.op_Implicit((Object)(object)root))
			{
				Object.Destroy((Object)(object)root);
			}
		}
	}
	public sealed class FrostWave : MonoBehaviour
	{
		private float age;

		private Vector3 forward;

		private Mesh mesh;

		private Vector3[] vertices;

		private Vector3[] normals;

		private Material material;

		internal static void Create(Vector3 origin, Vector3 forward)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Plugin.SwordPrefab) || !Object.op_Implicit((Object)(object)Hud.instance))
			{
				return;
			}
			Transform val = Plugin.SwordPrefab.transform.Find("attach/FM_CustomModel");
			MeshRenderer val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<MeshRenderer>() : null);
			if (!Object.op_Implicit((Object)(object)val2) || ((Renderer)val2).sharedMaterials.Length < 5)
			{
				Plugin.Log("Frost wave material unavailable: custom sword glow renderer was not found.");
				return;
			}
			GameObject val3 = new GameObject("FM_FrostWave");
			val3.transform.position = origin;
			FrostWave frostWave = val3.AddComponent<FrostWave>();
			frostWave.forward = ((Vector3)(ref forward)).normalized;
			frostWave.forward.y = 0f;
			((Vector3)(ref frostWave.forward)).Normalize();
			frostWave.material = new Material(((Renderer)val2).sharedMaterials[4]);
			if (frostWave.material.HasProperty("_Color"))
			{
				frostWave.material.SetColor("_Color", new Color(0.15f, 0.65f, 1f, 1f));
			}
			if (frostWave.material.HasProperty("_EmissionColor"))
			{
				frostWave.material.SetColor("_EmissionColor", new Color(0.2f, 0.8f, 1f) * 2.5f);
			}
			frostWave.mesh = new Mesh
			{
				name = "FM_VisibleFrostWave"
			};
			frostWave.mesh.MarkDynamic();
			frostWave.vertices = (Vector3[])(object)new Vector3[66];
			frostWave.normals = (Vector3[])(object)new Vector3[66];
			Vector2[] array = (Vector2[])(object)new Vector2[66];
			int[] array2 = new int[384];
			for (int i = 0; i < 33; i++)
			{
				array[i * 2] = new Vector2((float)i / 32f, 0f);
				array[i * 2 + 1] = new Vector2((float)i / 32f, 1f);
			}
			for (int j = 0; j < 32; j++)
			{
				int num = j * 2;
				int num2 = j * 12;
				int[] array3 = new int[12]
				{
					num,
					num + 1,
					num + 2,
					num + 2,
					num + 1,
					num + 3,
					num + 2,
					num + 1,
					num,
					num + 3,
					num + 1,
					num + 2
				};
				for (int k = 0; k < 12; k++)
				{
					array2[num2 + k] = array3[k];
				}
			}
			frostWave.mesh.vertices = frostWave.vertices;
			frostWave.mesh.uv = array;
			frostWave.mesh.triangles = array2;
			val3.AddComponent<MeshFilter>().sharedMesh = frostWave.mesh;
			((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterial = frostWave.material;
			frostWave.Draw();
		}

		private void Update()
		{
			age += Time.deltaTime;
			if (age >= 1.2f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Draw();
			}
		}

		private void Draw()
		{
			//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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Lerp(0.65f, 20f, Mathf.Clamp01(age / 1.2f));
			float num2 = 1f - Mathf.Clamp01((age - 0.8f) / 0.4f);
			for (int i = 0; i < 33; i++)
			{
				Vector3 val = Quaternion.AngleAxis(-50f + (float)i * 100f / 32f, Vector3.up) * forward;
				vertices[i * 2] = val * num + Vector3.down * 0.65f;
				float num3 = ((i % 2 == 0) ? 0.9f : 0.45f) * num2;
				vertices[i * 2 + 1] = val * num + Vector3.up * num3;
				normals[i * 2] = (normals[i * 2 + 1] = -val);
			}
			mesh.vertices = vertices;
			mesh.normals = normals;
			mesh.RecalculateTangents();
			mesh.RecalculateBounds();
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)material))
			{
				Object.Destroy((Object)(object)material);
			}
			if (Object.op_Implicit((Object)(object)mesh))
			{
				Object.Destroy((Object)(object)mesh);
			}
		}
	}
	internal static class SoulPower
	{
		private sealed class VictimState
		{
			internal bool Rewarded;

			internal readonly HashSet<string> Casts = new HashSet<string>();
		}

		private const string Key = "fm_soul_power";

		private const string GainRpc = "FM_SoulGain_123";

		private const string ExecuteRpc = "FM_SoulExecute_123";

		private const string VisualRpc = "FM_SoulVisual_123";

		internal const float Range = 20f;

		private static ZRoutedRpc router;

		private static readonly HashSet<ZDOID> credited = new HashSet<ZDOID>();

		private static readonly Queue<ZDOID> creditOrder = new Queue<ZDOID>();

		private static readonly ConditionalWeakTable<Character, VictimState> victims = new ConditionalWeakTable<Character, VictimState>();

		private static readonly FieldInfo hiddenRight = AccessTools.Field(typeof(Humanoid), "m_hiddenRightItem");

		private static readonly FieldInfo lastHit = AccessTools.Field(typeof(Character), "m_lastHit");

		private static readonly MethodInfo checkDeath = AccessTools.Method(typeof(Character), "CheckDeath", (Type[])null, (Type[])null);

		internal static float FlashUntil;

		private static bool Holding(Player player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				return Plugin.IsSword(((Humanoid)player).RightItem);
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				return component.GetZDO().GetInt(ZDOVars.s_rightItem, 0) == StringExtensionMethods.GetStableHashCode("FM_Frostmourne");
			}
			return false;
		}

		internal static ItemData Carried(Player p)
		{
			if (!Object.op_Implicit((Object)(object)p))
			{
				return null;
			}
			object obj;
			if (!Plugin.IsSword(((Humanoid)p).RightItem))
			{
				object? value = hiddenRight.GetValue(p);
				ItemData val = (ItemData)((value is ItemData) ? value : null);
				obj = ((val != null && Plugin.IsSword(val)) ? val : null);
			}
			else
			{
				obj = ((Humanoid)p).RightItem;
			}
			ItemData val2 = (ItemData)obj;
			if (val2 == null || !((Humanoid)p).GetInventory().ContainsItem(val2))
			{
				return null;
			}
			return val2;
		}

		internal static int Power(ItemData item)
		{
			if (item != null && item.m_customData.TryGetValue("fm_soul_power", out var value) && int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
			{
				return Mathf.Clamp(result, 0, 100);
			}
			return 0;
		}

		internal static void SetPower(Player player, ItemData sword, int power)
		{
			sword.m_customData["fm_soul_power"] = Mathf.Clamp(power, 0, 100).ToString(CultureInfo.InvariantCulture);
			AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null).Invoke(((Humanoid)player).GetInventory(), new object[2] { true, false });
		}

		internal static void Tick()
		{
			if (ZRoutedRpc.instance != null && router != ZRoutedRpc.instance)
			{
				router = ZRoutedRpc.instance;
				credited.Clear();
				creditOrder.Clear();
				router.Register<ZPackage>("FM_SoulGain_123", (Action<long, ZPackage>)ReceiveGain);
				router.Register<ZPackage>("FM_SoulVisual_123", (Action<long, ZPackage>)ReceiveVisual);
				SoulAdmin.Register(router);
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead())
			{
				return;
			}
			ItemData val = Carried(localPlayer);
			SEMan sEMan = ((Character)localPlayer).GetSEMan();
			int stableHashCode = StringExtensionMethods.GetStableHashCode("FM_WielderCurse");
			if (val != null && ProvenancePatch.Valid(val.m_customData))
			{
				if (!sEMan.HaveStatusEffect(stableHashCode))
				{
					sEMan.AddStatusEffect(stableHashCode, false, 0, 0f, (short)(-1));
				}
			}
			else if (sEMan.HaveStatusEffect(stableHashCode))
			{
				sEMan.RemoveStatusEffect(stableHashCode, false);
			}
		}

		internal static bool Hostile(Character attacker, Character target)
		{
			if (!Object.op_Implicit((Object)(object)attacker) || !Object.op_Implicit((Object)(object)target) || target.IsDead())
			{
				return false;
			}
			return EligibleTarget(attacker, target);
		}

		private static bool EligibleTarget(Character attacker, Character target)
		{
			return SoulRules.CanAffect((Object)(object)target == (Object)(object)attacker, target.IsTamed(), target is Player, attacker.IsPVPEnabled(), target.IsPVPEnabled(), BaseAI.IsEnemy(attacker, target));
		}

		internal static void Register(Character target)
		{
			ZNetView component = ((Component)target).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				component.Register<ZPackage>("FM_SoulExecute_123", (Action<long, ZPackage>)delegate(long sender, ZPackage package)
				{
					ReceiveExecution(target, sender, package);
				});
			}
		}

		internal static void RewardDeath(Character target)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)target).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner())
			{
				return;
			}
			VictimState orCreateValue = victims.GetOrCreateValue(target);
			if (orCreateValue.Rewarded)
			{
				return;
			}
			object? value = lastHit.GetValue(target);
			object? obj = ((value is HitData) ? value : null);
			Character obj2 = ((obj != null) ? ((HitData)obj).GetAttacker() : null);
			Player val = (Player)(object)((obj2 is Player) ? obj2 : null);
			if (Object.op_Implicit((Object)(object)val) && Holding(val) && EligibleTarget((Character)(object)val, target))
			{
				ZNetView component2 = ((Component)val).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component2) && component2.IsValid())
				{
					orCreateValue.Rewarded = true;
					ZPackage val2 = new ZPackage();
					val2.Write(component.GetZDO().m_uid);
					val2.Write(component2.GetZDO().m_uid);
					ZRoutedRpc.instance.InvokeRoutedRPC(component2.GetZDO().GetOwner(), "FM_SoulGain_123", new object[1] { val2 });
				}
			}
		}

		private static void ReceiveGain(long sender, ZPackage package)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = package.ReadZDOID();
			ZDOID val2 = package.ReadZDOID();
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead())
			{
				return;
			}
			ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>();
			ZDO zDO = ZDOMan.instance.GetZDO(val);
			if (!Object.op_Implicit((Object)(object)component) || !component.IsOwner() || component.GetZDO().m_uid != val2 || zDO == null || zDO.GetOwner() != sender || credited.Contains(val))
			{
				return;
			}
			ItemData rightItem = ((Humanoid)localPlayer).RightItem;
			if (Plugin.IsSword(rightItem) && ProvenancePatch.Valid(rightItem.m_customData))
			{
				credited.Add(val);
				creditOrder.Enqueue(val);
				while (creditOrder.Count > 4096)
				{
					credited.Remove(creditOrder.Dequeue());
				}
				SetPower(localPlayer, rightItem, SoulRules.AddKill(Power(rightItem)));
			}
		}

		internal static void Secondary(Player player)
		{
			//IL_006f: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due