Decompiled source of Needleforge v0.9.0

Needleforge.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using GlobalSettings;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using Microsoft.CodeAnalysis;
using Needleforge.Attacks;
using Needleforge.Components;
using Needleforge.Data;
using Needleforge.Makers;
using Needleforge.Patches.HUD;
using Needleforge.Utils;
using PrepatcherPlugin;
using Silksong.FsmUtil;
using Silksong.FsmUtil.Actions;
using TeamCherry.Localization;
using TeamCherry.NestedFadeGroup;
using TeamCherry.SharedUtils;
using UnityEngine;
using UnityEngine.Events;

[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("Needleforge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+3c5214ad51d3069bf5a4c54f8eda259689187696")]
[assembly: AssemblyProduct("Needleforge")]
[assembly: AssemblyTitle("Needleforge")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/GamingInfinite/Needleforge")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace Needleforge
{
	internal static class ModHelper
	{
		public static void Log(string msg)
		{
			NeedleforgePlugin.logger.LogInfo((object)msg);
		}

		public static void LogError(string msg)
		{
			LogError(msg, stackTrace: false);
		}

		public static void LogError(string msg, bool stackTrace)
		{
			if (stackTrace)
			{
				msg = $"{msg}\n{new StackTrace(1, fNeedFileInfo: true)}";
			}
			NeedleforgePlugin.logger.LogError((object)msg);
		}

		public static void LogWarning(string msg)
		{
			LogWarning(msg, stackTrace: false);
		}

		public static void LogWarning(string msg, bool stackTrace)
		{
			if (stackTrace)
			{
				msg = $"{msg}\n{new StackTrace(1, fNeedFileInfo: true)}";
			}
			NeedleforgePlugin.logger.LogWarning((object)msg);
		}
	}
	[BepInPlugin("io.github.needleforge", "Needleforge", "0.9.0")]
	public class NeedleforgePlugin : BaseUnityPlugin
	{
		internal static ManualLogSource logger;

		internal static Harmony harmony;

		internal static List<ToolData> newToolData = new List<ToolData>();

		internal static List<CrestData> newCrestData = new List<CrestData>();

		internal static List<ToolCrest> newCrests = new List<ToolCrest>();

		internal static List<ToolItem> newTools = new List<ToolItem>();

		internal static ObservableCollection<ColorData> newColors = new ObservableCollection<ColorData>();

		internal static Dictionary<string, GameObject> hudRoots = new Dictionary<string, GameObject>();

		internal static Dictionary<string, CrestData.BindEventHandler> bindEvents = new Dictionary<string, CrestData.BindEventHandler>();

		internal static Dictionary<string, Action> bindCompleteEvents = new Dictionary<string, Action>();

		internal static Dictionary<string, UniqueBindEvent> uniqueBind = new Dictionary<string, UniqueBindEvent>();

		internal static Dictionary<string, Action> toolEventHooks = new Dictionary<string, Action>();

		public static readonly ColorData GreenTools = AddToolColor("Green", new Color(0.57f, 0.86f, 0.59f, 1f));

		public static readonly ColorData PinkTools = AddToolColor("Pink", new Color(1f, 0.59f, 0.78f, 1f), isAttackType: true);

		public static readonly ColorData BlackTools = AddToolColor("Black", new Color(0.4f, 0.4f, 0.4f, 1f), isAttackType: true);

		public const string Id = "io.github.needleforge";

		public static string Name => "Needleforge";

		public static string Version => "0.9.0";

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.needleforge) has loaded!"));
			harmony = new Harmony("io.github.needleforge");
			harmony.PatchAll();
			newColors.CollectionChanged += NewColors_CollectionChanged;
			GreenTools.AddValidTypes((ToolItemType)2, (ToolItemType)1);
			PinkTools.AddValidTypes(default(ToolItemType), (ToolItemType)3);
			BlackTools.allColorsValid = true;
		}

		private void NewColors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			InventoryToolCrest.TOOL_TYPES = (ToolItemType[])Enum.GetValues(typeof(ToolItemType));
		}

		public static ToolData? GetToolDataByName(string name)
		{
			string name2 = name;
			return newToolData.FirstOrDefault((ToolData t) => t.name == name2);
		}

		public static ColorData AddToolColor(string name, Color color, bool isAttackType = false)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			ColorData colorData = new ColorData
			{
				name = name,
				color = color,
				isAttackType = isAttackType
			};
			newColors.Add(colorData);
			return colorData;
		}

		public static LiquidToolData AddLiquidTool(string name, int maxRefills, int storageAmount, string InfiniteRefillsPD, Color liquidColor, ReplenishResources resource, ReplenishUsages replenishUsage, float replenishMult, StateSprites? fullSprites, StateSprites? emptySprites, string clip = "Charge Up")
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0042: 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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			LiquidToolData data = new LiquidToolData
			{
				type = (ToolItemType)0,
				name = name,
				color = liquidColor,
				maxRefills = maxRefills,
				storageAmount = storageAmount,
				infiniteRefills = InfiniteRefillsPD,
				clip = clip,
				resource = resource,
				replenishUsage = replenishUsage,
				replenishMult = replenishMult,
				FullSprites = fullSprites,
				EmptySprites = emptySprites
			};
			newToolData.Add(data);
			toolEventHooks[data.name + " BEFORE ANIM"] = delegate
			{
				ModHelper.Log("BEFORE ANIM for " + data.name);
			};
			toolEventHooks[data.name + " AFTER ANIM"] = delegate
			{
				ModHelper.Log("AFTER ANIM for " + data.name);
			};
			return data;
		}

		public static LiquidToolData AddLiquidTool(string name, int maxRefills, int storageAmount, string InfiniteRefillsPD, Color liquidColor, ReplenishResources resource, ReplenishUsages replenishUsage, float replenishMult)
		{
			//IL_0004: 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)
			return AddLiquidTool(name, maxRefills, storageAmount, InfiniteRefillsPD, liquidColor, resource, replenishUsage, replenishMult, null, null);
		}

		public static LiquidToolData AddLiquidTool(string name, int maxRefills, int storageAmount, string InfiniteRefillsPD, Color liquidColor)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return AddLiquidTool(name, maxRefills, storageAmount, InfiniteRefillsPD, liquidColor, (ReplenishResources)1, (ReplenishUsages)0, 1f);
		}

		public static LiquidToolData AddLiquidTool(string name, int maxRefills, int storageAmount, Color liquidColor)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return AddLiquidTool(name, maxRefills, storageAmount, "", liquidColor);
		}

		public static ToolData AddTool(string name, ToolItemType type, LocalisedString displayName, LocalisedString description, Sprite? InventorySprite)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ToolData data = new ToolData
			{
				inventorySprite = InventorySprite,
				type = type,
				name = name,
				displayName = displayName,
				description = description
			};
			PlayerDataVariableEvents.OnGetBool += (PlayerData pd, string fieldname, bool current) => (fieldname == data.unlockedPDString) ? data.UnlockedAtStart : current;
			newToolData.Add(data);
			return data;
		}

		public static ToolData AddTool(string name, ToolItemType type, Sprite? InventorySprite)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			return AddTool(name, type, new LocalisedString
			{
				Key = name + "LocalKey",
				Sheet = "Mods.your.mod.id"
			}, new LocalisedString
			{
				Key = name + "LocalKeyDesc",
				Sheet = "Mods.your.mod.id"
			}, InventorySprite);
		}

		public static ToolData AddTool(string name, ToolItemType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return AddTool(name, type, null);
		}

		public static ToolData AddTool(string name, ToolItemType type, LocalisedString displayName, LocalisedString description)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return AddTool(name, type, displayName, description, null);
		}

		public static ToolData AddTool(string name, LocalisedString displayName, LocalisedString description)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return AddTool(name, (ToolItemType)2, displayName, description, null);
		}

		public static ToolData AddTool(string name)
		{
			return AddTool(name, (ToolItemType)2, null);
		}

		public static CrestData AddCrest(string name, LocalisedString displayName, LocalisedString description, Sprite? RealSprite, Sprite? Silhouette, Sprite? CrestGlow)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			string name2 = name;
			CrestData crestData = new CrestData(name2, displayName, description, RealSprite, Silhouette, CrestGlow);
			newCrestData.Add(crestData);
			bindEvents[name2] = delegate
			{
				ModHelper.Log("Running Bind for " + name2 + " Crest");
			};
			bindCompleteEvents[name2] = delegate
			{
				ModHelper.Log("Bind for " + name2 + " Crest Complete");
			};
			return crestData;
		}

		public static CrestData AddCrest(string name, Sprite? RealSprite, Sprite? Silhouette, Sprite? CrestGlow)
		{
			//IL_0003: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			return AddCrest(name, new LocalisedString
			{
				Key = name + "LocalKey",
				Sheet = "Mods.your.mod.id"
			}, new LocalisedString
			{
				Key = name + "LocalKeyDesc",
				Sheet = "Mods.your.mod.id"
			}, RealSprite, Silhouette, CrestGlow);
		}

		public static CrestData AddCrest(string name, LocalisedString displayName, LocalisedString description, Sprite? RealSprite, Sprite? Silhouette)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return AddCrest(name, displayName, description, RealSprite, Silhouette, null);
		}

		public static CrestData AddCrest(string name, Sprite? RealSprite, Sprite? Silhouette)
		{
			return AddCrest(name, RealSprite, Silhouette, null);
		}

		public static CrestData AddCrest(string name, LocalisedString displayName, LocalisedString description, Sprite? RealSprite)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return AddCrest(name, displayName, description, RealSprite, null);
		}

		public static CrestData AddCrest(string name, Sprite? RealSprite)
		{
			return AddCrest(name, RealSprite, null);
		}

		public static CrestData AddCrest(string name, LocalisedString displayName, LocalisedString description)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return AddCrest(name, displayName, description, null);
		}

		public static CrestData AddCrest(string name)
		{
			return AddCrest(name, null);
		}
	}
}
namespace Needleforge.Utils
{
	internal static class ILUtils
	{
		internal static bool Ldloc(CodeInstruction x)
		{
			int index;
			return Ldloc(x, out index);
		}

		internal static bool Ldloc(CodeInstruction x, int index)
		{
			if (Ldloc(x, out var index2))
			{
				return index == index2;
			}
			return false;
		}

		internal static bool Ldloc(CodeInstruction x, out int index)
		{
			index = -1;
			if (x.opcode == OpCodes.Ldloc_0)
			{
				index = 0;
			}
			else if (x.opcode == OpCodes.Ldloc_1)
			{
				index = 1;
			}
			else if (x.opcode == OpCodes.Ldloc_2)
			{
				index = 2;
			}
			else if (x.opcode == OpCodes.Ldloc_3)
			{
				index = 3;
			}
			else if ((x.opcode == OpCodes.Ldloc || x.opcode == OpCodes.Ldloc_S) && x.operand is LocalBuilder localBuilder)
			{
				index = localBuilder.LocalIndex;
			}
			return index >= 0;
		}

		internal static bool Stloc(CodeInstruction x)
		{
			int index;
			return Stloc(x, out index);
		}

		internal static bool Stloc(CodeInstruction x, int index)
		{
			if (Stloc(x, out var index2))
			{
				return index == index2;
			}
			return false;
		}

		internal static bool Stloc(CodeInstruction x, out int index)
		{
			index = -1;
			if (x.opcode == OpCodes.Stloc_0)
			{
				index = 0;
			}
			else if (x.opcode == OpCodes.Stloc_1)
			{
				index = 1;
			}
			else if (x.opcode == OpCodes.Stloc_2)
			{
				index = 2;
			}
			else if (x.opcode == OpCodes.Stloc_3)
			{
				index = 3;
			}
			else if ((x.opcode == OpCodes.Stloc || x.opcode == OpCodes.Stloc_S) && x.operand is LocalBuilder localBuilder)
			{
				index = localBuilder.LocalIndex;
			}
			return index >= 0;
		}

		internal static bool Ldfld(CodeInstruction x)
		{
			string name;
			return Ldfld(x, out name);
		}

		internal static bool Ldfld(CodeInstruction x, string name)
		{
			if (Ldfld(x, out string name2))
			{
				return name == name2;
			}
			return false;
		}

		internal static bool Ldfld(CodeInstruction x, out string name)
		{
			name = "";
			if (x.opcode == OpCodes.Ldfld && x.operand is FieldInfo fieldInfo)
			{
				name = fieldInfo.Name;
			}
			return !string.IsNullOrWhiteSpace(name);
		}

		internal static bool Stfld(CodeInstruction x)
		{
			string name;
			return Stfld(x, out name);
		}

		internal static bool Stfld(CodeInstruction x, string name, out FieldInfo field)
		{
			field = ((x.operand is FieldInfo fieldInfo) ? fieldInfo : null);
			return Stfld(x, name);
		}

		internal static bool Stfld(CodeInstruction x, string name)
		{
			if (Stfld(x, out string name2))
			{
				return name == name2;
			}
			return false;
		}

		internal static bool Stfld(CodeInstruction x, out string name)
		{
			name = "";
			if (x.opcode == OpCodes.Stfld && x.operand is FieldInfo fieldInfo)
			{
				name = fieldInfo.Name;
			}
			return !string.IsNullOrWhiteSpace(name);
		}

		internal static bool Br(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Br))
			{
				return x.opcode == OpCodes.Br_S;
			}
			return true;
		}

		internal static bool Br(CodeInstruction x, out Label label)
		{
			label = ((x.operand is Label label2) ? label2 : default(Label));
			return Br(x);
		}

		internal static bool Brfalse(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Brfalse))
			{
				return x.opcode == OpCodes.Brfalse_S;
			}
			return true;
		}

		internal static bool Brfalse(CodeInstruction x, out Label label)
		{
			label = ((x.operand is Label label2) ? label2 : default(Label));
			return Brfalse(x);
		}

		internal static bool Brtrue(CodeInstruction x)
		{
			if (!(x.opcode == OpCodes.Brtrue))
			{
				return x.opcode == OpCodes.Brtrue_S;
			}
			return true;
		}

		internal static bool Call(CodeInstruction x, string name)
		{
			if (x.opcode == OpCodes.Call && x.operand is MethodInfo methodInfo)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		internal static bool Call(CodeInstruction x, MethodInfo method)
		{
			if (x.opcode == OpCodes.Call && x.operand is MethodInfo methodInfo)
			{
				return methodInfo == method;
			}
			return false;
		}

		internal static bool Callvirt(CodeInstruction x, string name)
		{
			if (x.opcode == OpCodes.Callvirt && x.operand is MethodInfo methodInfo)
			{
				return methodInfo.Name == name;
			}
			return false;
		}

		internal static bool Callvirt(CodeInstruction x, MethodInfo method)
		{
			if (x.opcode == OpCodes.Callvirt && x.operand is MethodInfo methodInfo)
			{
				return methodInfo == method;
			}
			return false;
		}

		internal static CodeMatcher StealLabel(this CodeMatcher cm, Label newLabel, out Label oldLabel)
		{
			return cm.StealLabel(0, newLabel, out oldLabel);
		}

		internal static CodeMatcher StealLabel(this CodeMatcher cm, int i, Label newLabel, out Label oldLabel)
		{
			oldLabel = cm.Instruction.labels[i];
			cm.Instruction.labels[i] = newLabel;
			return cm;
		}
	}
	internal static class MiscUtils
	{
		internal static Vector2[] ScalePolygon(Vector2[] poly, float mult)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (poly.Length == 0)
			{
				return Array.Empty<Vector2>();
			}
			Vector2[] array = poly.ToArray();
			Vector2 val = Vector2.zero;
			Vector2[] array2 = array;
			foreach (Vector2 val2 in array2)
			{
				val += val2;
			}
			val /= (float)array.Length;
			for (int j = 0; j < array.Length; j++)
			{
				array[j] = val + (array[j] - val) * mult;
			}
			return array;
		}

		internal static void CallMethod<T>(this T component, string fnName, Action<T>? fallbackFn = null) where T : Component
		{
			MethodInfo method = ((object)component).GetType().GetMethod(fnName, Array.Empty<Type>());
			if (method != null)
			{
				method.Invoke(component, Array.Empty<object>());
			}
			else
			{
				fallbackFn?.Invoke(component);
			}
		}

		internal static void StartAttack(this NailAttackBase nab)
		{
			nab.CallMethod<NailAttackBase>("StartSlash", (Action<NailAttackBase>?)delegate(NailAttackBase x)
			{
				x.OnSlashStarting();
				x.OnPlaySlash();
			});
		}

		internal static void EndAttack(this NailAttackBase nab)
		{
			nab.CallMethod<NailAttackBase>("CancelAttack", (Action<NailAttackBase>?)delegate(NailAttackBase x)
			{
				x.OnCancelAttack();
			});
		}
	}
}
namespace Needleforge.Patches
{
	[HarmonyPatch]
	internal class AddNewColors
	{
		[HarmonyPatch(typeof(Enum), "GetValues", new Type[] { typeof(Type) })]
		[HarmonyPostfix]
		private static void AddNewColorsUnordered(Type enumType, ref Array __result)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!(enumType == typeof(ToolItemType)))
			{
				return;
			}
			List<ToolItemType> list = new List<ToolItemType>();
			foreach (object item in __result)
			{
				list.Add((ToolItemType)item);
			}
			foreach (ColorData newColor in NeedleforgePlugin.newColors)
			{
				list.Add(newColor.Type);
			}
			__result = list.ToArray();
		}

		[HarmonyPatch(typeof(EnumExtenstions), "GetValuesWithOrder", new Type[] { typeof(Type) })]
		[HarmonyPostfix]
		private static void AddNewColorsOrdered(Type type, ref IEnumerable<int> __result)
		{
			if (type == typeof(ToolItemType))
			{
				for (int i = 0; i < NeedleforgePlugin.newColors.Count; i++)
				{
					int num = i + 4;
					__result = CollectionExtensions.AddItem<int>(__result, num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ToolItemManager), "Awake")]
	internal class AddToolsAndCrests
	{
		[HarmonyPostfix]
		private static void AddCrests()
		{
			ModHelper.Log("Adding Crests...");
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				ModHelper.Log("Adding " + newCrestDatum.name);
				CrestMaker.CreateCrest(newCrestDatum);
			}
		}

		[HarmonyPostfix]
		private static void AddTools()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			ModHelper.Log("Adding Tools...");
			foreach (ToolData newToolDatum in NeedleforgePlugin.newToolData)
			{
				ModHelper.Log("Adding " + newToolDatum.name);
				if (newToolDatum is LiquidToolData liquidToolData)
				{
					ToolMaker.CreateLiquidTool(liquidToolData.name, liquidToolData.storageAmount, liquidToolData.maxRefills, liquidToolData.color, liquidToolData.infiniteRefills, liquidToolData.resource, liquidToolData.replenishUsage, liquidToolData.replenishMult, liquidToolData.FullSprites, liquidToolData.EmptySprites, newToolDatum.displayName, newToolDatum.description);
				}
				else
				{
					ToolMaker.CreateBasicTool(newToolDatum.inventorySprite, newToolDatum.type, newToolDatum.name, newToolDatum.displayName, newToolDatum.description);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CountCrestUnlockPoints), "OnEnter")]
	internal static class EvaProgressionOptOut
	{
		private static void Prefix(CountCrestUnlockPoints __instance)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			ToolCrestList val = ScriptableObject.CreateInstance<ToolCrestList>();
			HashSet<ToolCrest> hashSet = new HashSet<ToolCrest>();
			foreach (ToolCrest item in from x in NeedleforgePlugin.newCrestData
				where !x.slotsCountForEvaQuest
				select x.ToolCrest)
			{
				hashSet.Add(item);
			}
			HashSet<ToolCrest> hashSet2 = hashSet;
			foreach (ToolCrest item2 in (NamedScriptableObjectList<ToolCrest>)(ToolCrestList)__instance.CrestList.Value)
			{
				if (!hashSet2.Contains(item2))
				{
					((NamedScriptableObjectList<ToolCrest>)(object)val).Add(item2);
				}
			}
			__instance.CrestList.Value = (Object)(object)val;
		}
	}
	[HarmonyPatch(typeof(HeroDownAttack))]
	internal static class PogoLogicTweaks
	{
		[HarmonyPatch("OnEndedDamage")]
		[HarmonyPrefix]
		private static void PreventDoubleBounces(HeroDownAttack __instance, bool didHit)
		{
			if (didHit && __instance.bounceQueued && Object.op_Implicit((Object)(object)__instance.attack))
			{
				__instance.hc.AffectedByGravity(true);
			}
			__instance.bounceQueued = false;
		}

		[HarmonyPatch("ContinueBounceTrigger")]
		[HarmonyPrefix]
		private static void AllowTravellingBounces(HeroDownAttack __instance, GameObject otherObj)
		{
			NailAttackTravel nailAttackTravel = default(NailAttackTravel);
			if (!HeroDownAttack.IsNonBounce(otherObj) && ((Component)__instance).TryGetComponent<NailAttackTravel>(ref nailAttackTravel) && ((Behaviour)nailAttackTravel).enabled)
			{
				__instance.hc.AllowRecoil();
			}
		}
	}
	[HarmonyPatch]
	internal class SaveDataSetup
	{
		[HarmonyPatch(typeof(PlayerData), "SetupNewPlayerData")]
		[HarmonyPostfix]
		private static void AddToNewSaveData(PlayerData __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				if ((Object)(object)newCrestDatum.ToolCrest != (Object)null && newCrestDatum.UnlockedAtStart)
				{
					((SerializableNamedList<Data, NamedData>)(object)__instance.ToolEquips).SetData(newCrestDatum.name, CrestMaker.CreateDefaultSaveData());
				}
			}
		}

		[HarmonyPatch(typeof(PlayerData), "SetupExistingPlayerData")]
		[HarmonyPostfix]
		private static void AddToExistingSaveData(PlayerData __instance)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			List<string> validNames = ((SerializableNamedList<Data, NamedData>)(object)__instance.ToolEquips).GetValidNames((Func<Data, bool>)null);
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				if ((Object)(object)newCrestDatum.ToolCrest != (Object)null && newCrestDatum.UnlockedAtStart && !validNames.Contains(newCrestDatum.name))
				{
					((SerializableNamedList<Data, NamedData>)(object)__instance.ToolEquips).SetData(newCrestDatum.name, CrestMaker.CreateDefaultSaveData());
				}
			}
		}
	}
	[HarmonyPatch(typeof(UI), "GetToolTypeColor")]
	internal class UIToolColorArray
	{
		[HarmonyPrefix]
		private static bool Prefix(ToolItemType type, ref Color __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((int)type > 3)
			{
				__result = NeedleforgePlugin.newColors[type - 4].color;
				return false;
			}
			return true;
		}
	}
}
namespace Needleforge.Patches.Inventory
{
	[HarmonyPatch]
	internal class HighlightTools
	{
		[HarmonyPatch(typeof(InventoryItemToolManager), "RefreshTools", new Type[]
		{
			typeof(bool),
			typeof(bool)
		})]
		[HarmonyPostfix]
		private static void RefreshTools(InventoryItemToolManager __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0046: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_006e: 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_007a: Expected I4, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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)
			for (int i = 0; i < __instance.listSectionHeaders.Length; i++)
			{
				Color color = __instance.listSectionHeaders[i].Color;
				ColorData colorData = ((i <= 3) ? null : NeedleforgePlugin.newColors[i - 4]);
				if (Object.op_Implicit((Object)(object)__instance.SelectedSlot) && (int)__instance.SelectedSlot.Type > 3)
				{
					bool flag = colorData?.allColorsValid ?? false;
					InventoryToolCrestSlot selectedSlot = __instance.SelectedSlot;
					if ((int)selectedSlot.Type > 3)
					{
						ColorData colorData2 = NeedleforgePlugin.newColors[selectedSlot.Type - 4];
						bool flag2 = colorData2.ValidTypes.Contains((ToolItemType)i) || flag || colorData2.allColorsValid;
						NestedFadeGroupSpriteRenderer obj = __instance.listSectionHeaders[i];
						Color color2 = color;
						color2.a = (flag2 ? 1f : 0.5f);
						obj.Color = color2;
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryItemTool), "UpdateEquippedDisplay")]
		[HarmonyPostfix]
		private static void UpdateEquippedDisplay(InventoryItemTool __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_003c: 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_0048: Expected I4, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			//IL_0064: 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_0070: Expected I4, but got Unknown
			//IL_0089: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.manager.SelectedSlot != (Object)null && (int)__instance.manager.SelectedSlot.Type > 3)
			{
				ColorData colorData = NeedleforgePlugin.newColors[__instance.manager.SelectedSlot.Type - 4];
				ColorData colorData2 = null;
				if ((int)__instance.itemData.Type > 3)
				{
					colorData2 = NeedleforgePlugin.newColors[__instance.itemData.Type - 4];
				}
				bool flag = false;
				if (colorData2 != null)
				{
					flag = colorData2.allColorsValid;
				}
				Color color = ((colorData.ValidTypes.Contains(__instance.itemData.Type) || colorData.allColorsValid || flag) ? Color.white : InventoryToolCrestSlot.InvalidItemColor);
				if ((Object)(object)__instance.itemIcon != (Object)null)
				{
					__instance.itemIcon.color = color;
				}
			}
		}
	}
	[HarmonyPatch]
	internal class InventoryCloning
	{
		[HarmonyPatch(typeof(InventoryToolCrest), "OnValidate")]
		[HarmonyPostfix]
		private static void AddTemplateSlots(InventoryToolCrest __instance)
		{
			//IL_003a: 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)
			foreach (ColorData newColor in NeedleforgePlugin.newColors)
			{
				if (newColor.isAttackType)
				{
					__instance.templateSlots[newColor.Type] = __instance.templateSlots[0];
				}
				else
				{
					__instance.templateSlots[newColor.Type] = __instance.templateSlots[1];
				}
			}
		}

		[HarmonyPatch(typeof(InventoryItemTool), "OnValidate")]
		[HarmonyPostfix]
		private static void AddAnimators(InventoryItemTool __instance)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			foreach (ColorData newColor in NeedleforgePlugin.newColors)
			{
				RuntimeAnimatorController val = __instance.slotAnimatorControllers[(!newColor.isAttackType) ? 1u : 0u];
				__instance.slotAnimatorControllers[newColor.Type] = val;
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "OnValidate")]
		[HarmonyPostfix]
		private static void AddHeaders(InventoryItemToolManager __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			foreach (ColorData newColor in NeedleforgePlugin.newColors)
			{
				if (!Object.op_Implicit((Object)(object)__instance.listSectionHeaders[newColor.Type]))
				{
					NestedFadeGroupSpriteRenderer obj = __instance.listSectionHeaders[1];
					NestedFadeGroupSpriteRenderer val = Object.Instantiate<NestedFadeGroupSpriteRenderer>(obj, ((Component)obj).transform.parent);
					((Object)val).name = newColor.name + " Section Header";
					if ((Object)(object)newColor.header != (Object)null)
					{
						val.Sprite = newColor.header;
					}
					__instance.listSectionHeaders[newColor.Type] = val;
				}
			}
		}
	}
	[HarmonyPatch]
	internal class MultiSlot
	{
		[HarmonyPatch(typeof(ToolItemTypeExtensions), "IsAttackType")]
		[HarmonyPostfix]
		private static void CustomColorAttackType(ToolItemType type, ref bool __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected I4, but got Unknown
			if (!__result && (int)type > 3)
			{
				ColorData colorData = NeedleforgePlugin.newColors[type - 4];
				__result = colorData.isAttackType;
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "GetAvailableSlotCount")]
		[HarmonyPostfix]
		private static void GetAvailableSlotCountMultiColor(IEnumerable<InventoryToolCrestSlot> slots, ToolItemType? toolType, bool checkEmpty, ref int __result)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected I4, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected I4, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (InventoryToolCrestSlot slot in slots)
			{
				if (slot.IsLocked && !((Object)(object)slot.EquippedItem == (Object)null) && checkEmpty)
				{
					continue;
				}
				ToolItemType valueOrDefault = toolType.GetValueOrDefault();
				if ((int)slot.Type > 3)
				{
					ColorData colorData = NeedleforgePlugin.newColors[slot.Type - 4];
					if (colorData.ValidTypes.Contains(valueOrDefault) || colorData.allColorsValid)
					{
						num++;
					}
				}
				else if ((int)valueOrDefault > 3)
				{
					ColorData colorData2 = NeedleforgePlugin.newColors[valueOrDefault - 4];
					if (colorData2.ValidTypes.Contains(slot.Type) || colorData2.allColorsValid)
					{
						num++;
					}
				}
			}
			__result += num;
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "GetAvailableSlot")]
		[HarmonyPostfix]
		private static void GetAvailableSlotMultiColor(IEnumerable<InventoryToolCrestSlot> slots, ToolItemType toolType, ref InventoryToolCrestSlot __result)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_002d: 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_0039: Expected I4, but got Unknown
			//IL_0040: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected I4, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			foreach (InventoryToolCrestSlot slot in slots)
			{
				if (slot.IsLocked)
				{
					continue;
				}
				if ((int)slot.Type > 3)
				{
					ColorData colorData = NeedleforgePlugin.newColors[slot.Type - 4];
					if ((colorData.ValidTypes.Contains(toolType) || colorData.allColorsValid) && (Object)(object)slot.EquippedItem == (Object)null)
					{
						__result = slot;
					}
				}
				else if ((int)toolType > 3)
				{
					ColorData colorData2 = NeedleforgePlugin.newColors[toolType - 4];
					if ((colorData2.ValidTypes.Contains(slot.Type) || colorData2.allColorsValid) && (Object)(object)slot.EquippedItem == (Object)null)
					{
						__result = slot;
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "PlaceTool")]
		[HarmonyPrefix]
		private static bool PlaceMultiColorTool(InventoryItemToolManager __instance, InventoryToolCrestSlot slot, bool isManual)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected I4, but got Unknown
			//IL_006e: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected I4, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			InventoryItemToolManager __instance2 = __instance;
			InventoryToolCrestSlot slot2 = slot;
			if ((Object)(object)slot2 == (Object)null)
			{
				return true;
			}
			ToolItem tool;
			if ((int)slot2.Type > 3)
			{
				ColorData colorData = NeedleforgePlugin.newColors[slot2.Type - 4];
				tool = __instance2.PickedUpTool;
				if (colorData.ValidTypes.Contains(tool.Type) || colorData.allColorsValid)
				{
					RealPlace();
				}
				return false;
			}
			if ((int)__instance2.PickedUpTool.Type > 3)
			{
				ColorData colorData2 = NeedleforgePlugin.newColors[__instance2.PickedUpTool.Type - 4];
				if (colorData2.ValidTypes.Contains(slot2.Type) || colorData2.allColorsValid)
				{
					tool = __instance2.PickedUpTool;
					RealPlace();
				}
				return false;
			}
			return true;
			void RealPlace()
			{
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: 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)
				__instance2.PickedUpTool = null;
				__instance2.EquipState = (EquipStates)0;
				if (isManual)
				{
					slot2.SetEquipped(tool, true, true);
				}
				if (Object.op_Implicit((Object)(object)__instance2.selectedBeforePickup))
				{
					if (isManual)
					{
						slot2.PreOpenSlot();
					}
					if (Object.op_Implicit((Object)(object)__instance2.tweenTool) && Object.op_Implicit((Object)(object)slot2))
					{
						__instance2.tweenTool.DoPlace(Vector2.op_Implicit(((Component)__instance2.selectedBeforePickup).transform.position), Vector2.op_Implicit(((Component)slot2).transform.position), tool, (Action)Selected);
					}
					else
					{
						Selected();
					}
				}
			}
			void Selected()
			{
				((InventoryItemManager)__instance2).SetSelected(__instance2.selectedBeforePickup, (SelectionDirection?)null, false);
				__instance2.selectedBeforePickup = null;
			}
		}
	}
	[HarmonyPatch]
	internal class MultiSlotNav
	{
		[MethodImpl(MethodImplOptions.NoInlining)]
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(InventoryItemSelectableDirectional), "GetNextSelectable", new Type[] { typeof(SelectionDirection) })]
		private static InventoryItemSelectable BaseGetNextSelectable(InventoryItemTool instance, SelectionDirection direction)
		{
			return null;
		}

		[HarmonyPatch(typeof(InventoryItemTool), "GetNextSelectable")]
		[HarmonyPostfix]
		private static void MultiColorNav(SelectionDirection direction, InventoryItemTool __instance, ref InventoryItemSelectable __result)
		{
			//IL_000e: 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_0037: Invalid comparison between Unknown and I4
			//IL_0049: 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_0055: Expected I4, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected I4, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)(object)__result))
			{
				return;
			}
			InventoryItemSelectable val = BaseGetNextSelectable(__instance, direction);
			InventoryItemTool val2 = (InventoryItemTool)(object)((val is InventoryItemTool) ? val : null);
			if (!((Object)(object)val2 == (Object)null) && (int)__instance.manager.SelectedSlot.Type > 3)
			{
				ColorData colorData = NeedleforgePlugin.newColors[__instance.manager.SelectedSlot.Type - 4];
				ColorData colorData2 = null;
				if ((int)val2.itemData.Type > 3)
				{
					colorData2 = NeedleforgePlugin.newColors[val2.itemData.Type - 4];
				}
				bool flag = false;
				if (colorData2 != null)
				{
					flag = colorData2.allColorsValid;
				}
				if (colorData.ValidTypes.Contains(val2.ToolType) || flag || colorData.allColorsValid)
				{
					__result = val;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "EndSelection")]
		[HarmonyPrefix]
		private static bool MultiColorEndSelection(InventoryItemTool tool, InventoryItemToolManager __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0047: 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_0053: Expected I4, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			InventoryItemToolManager __instance2 = __instance;
			if ((int)__instance2.SelectedSlot.Type > 3)
			{
				if (!Object.op_Implicit((Object)(object)__instance2.SelectedSlot))
				{
					return true;
				}
				ColorData colorData = NeedleforgePlugin.newColors[__instance2.SelectedSlot.Type - 4];
				if (Object.op_Implicit((Object)(object)tool) && Object.op_Implicit((Object)(object)((InventoryItemToolBase)tool).ItemData) && (colorData.ValidTypes.Contains(tool.ToolType) || colorData.allColorsValid))
				{
					if (Object.op_Implicit((Object)(object)__instance2.tweenTool))
					{
						__instance2.SelectedSlot.SetEquipped(((InventoryItemToolBase)tool).ItemData, true, true);
						__instance2.tweenTool.DoPlace(Vector2.op_Implicit(((Component)tool).transform.position), Vector2.op_Implicit(((Component)__instance2.SelectedSlot).transform.position), ((InventoryItemToolBase)tool).ItemData, (Action)SelectionEnd);
						return false;
					}
					__instance2.SelectedSlot.SetEquipped(((InventoryItemToolBase)tool).ItemData, true, true);
				}
				SelectionEnd();
				return false;
			}
			return true;
			void SelectionEnd()
			{
				((InventoryItemManager)__instance2).PlayMoveSound();
				((InventoryItemManager)__instance2).SetSelected((InventoryItemSelectable)(object)__instance2.SelectedSlot, (SelectionDirection?)null, false);
				__instance2.SelectedSlot = null;
				__instance2.EquipState = (EquipStates)0;
				__instance2.RefreshTools();
			}
		}

		[HarmonyPatch(typeof(InventoryItemToolManager), "StartSelection")]
		[HarmonyPrefix]
		private static bool MultiColorStartSelection(InventoryToolCrestSlot slot, InventoryItemToolManager __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected I4, but got Unknown
			if ((int)slot.Type > 3)
			{
				if ((Object)(object)__instance.toolList == (Object)null)
				{
					return true;
				}
				ColorData slotData = NeedleforgePlugin.newColors[slot.Type - 4];
				List<InventoryItemTool> listItems = __instance.toolList.GetListItems<InventoryItemTool>((Func<InventoryItemTool, bool>)((InventoryItemTool tool) => (slotData.ValidTypes.Contains(tool.ToolType) || slotData.allColorsValid) && !((ToolBase)tool.itemData).IsEquipped));
				InventoryItemTool val = null;
				if (listItems.Count > 0)
				{
					val = listItems[0];
				}
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				__instance.SelectedSlot = slot;
				__instance.EquipState = (EquipStates)2;
				((InventoryItemManager)__instance).PlayMoveSound();
				((InventoryItemManager)__instance).SetSelected((InventoryItemSelectable)(object)val, (SelectionDirection?)null, false);
				__instance.RefreshTools();
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(InventoryToolCrestSlot), "IsSlotInvalid")]
		[HarmonyPostfix]
		private static void MultiColorInvalid(ToolItemType type, InventoryToolCrestSlot nextSlot, InventoryToolCrestSlot __instance, ref bool __result)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//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_0036: 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_0042: Expected I4, but got Unknown
			//IL_004a: 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: Invalid comparison between Unknown and I4
			//IL_00a7: 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_00b3: Expected I4, but got Unknown
			if (!__result)
			{
				return;
			}
			ToolItemType type2 = __instance.manager.PickedUpTool.Type;
			if (!((Object)(object)nextSlot.EquippedItem != (Object)null))
			{
				if ((int)nextSlot.Type > 3)
				{
					ColorData colorData = NeedleforgePlugin.newColors[nextSlot.Type - 4];
					__result = (!colorData.ValidTypes.Contains(type2) && !colorData.allColorsValid) || (nextSlot.IsLocked && !__instance.manager.CanUnlockSlot);
				}
				else if (type2 == nextSlot.Type)
				{
					__result = nextSlot.IsLocked && !__instance.manager.CanUnlockSlot;
				}
				if ((int)type2 > 3 && NeedleforgePlugin.newColors[nextSlot.Type - 4].allColorsValid)
				{
					__result = nextSlot.IsLocked && !__instance.manager.CanUnlockSlot;
				}
			}
		}
	}
}
namespace Needleforge.Patches.HUD
{
	[HarmonyPatch(typeof(BindOrbHudFrame), "Awake")]
	internal class AddHudRootsAndAnims
	{
		[HarmonyPostfix]
		private static void Postfix(BindOrbHudFrame __instance)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			GameObject val = new GameObject("NeedleforgeHudRoots")
			{
				layer = 5
			};
			val.transform.SetParent(((Component)__instance).transform);
			ResetPos(val);
			Extensions.SetLocalPositionZ(val.transform, -0.0001f);
			ModHelper.Log("Adding Needleforge Hud Roots");
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				GameObject val2 = new GameObject(newCrestDatum.name + "HUDRoot")
				{
					layer = 5
				};
				val2.transform.SetParent(val.transform);
				ResetPos(val2);
				NeedleforgePlugin.hudRoots[newCrestDatum.name] = val2;
				UpdateHudAnimLibrary(__instance, newCrestDatum.HudFrame);
				newCrestDatum.HudFrame.InitializeRoot();
			}
			static void ResetPos(GameObject go)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				go.transform.localScale = Vector3.one;
				go.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			}
		}

		private static void UpdateHudAnimLibrary(BindOrbHudFrame hudFrame, HudFrameData hudData)
		{
			if (hudData.HasAnyRegularCustomAnims)
			{
				List<tk2dSpriteAnimationClip> list = hudFrame.animator.Library.clips.ToList();
				foreach (tk2dSpriteAnimationClip item in hudData.AllRegularCustomAnims())
				{
					Extensions.AddIfNotPresent<tk2dSpriteAnimationClip>(list, item);
				}
				hudFrame.animator.Library.clips = list.ToArray();
				hudFrame.animator.Library.isValid = false;
				hudFrame.animator.Library.ValidateLookup();
			}
			if (!hudData.HasAnySteelCustomAnims)
			{
				return;
			}
			SteelSoulAnimProxy component = ((Component)hudFrame).GetComponent<SteelSoulAnimProxy>();
			List<tk2dSpriteAnimationClip> list2 = component.steelSoulAnims.clips.ToList();
			foreach (tk2dSpriteAnimationClip item2 in hudData.AllSteelCustomAnims())
			{
				Extensions.AddIfNotPresent<tk2dSpriteAnimationClip>(list2, item2);
			}
			component.steelSoulAnims.clips = list2.ToArray();
			component.steelSoulAnims.isValid = false;
			component.steelSoulAnims.ValidateLookup();
		}

		internal static void UpdateHudAnimLibrary(HudFrameData hudData)
		{
			BindOrbHudFrame val = Object.FindAnyObjectByType<BindOrbHudFrame>();
			if (Object.op_Implicit((Object)(object)hudData.Root) && Object.op_Implicit((Object)(object)val) && ((MonoBehaviour)val).didAwake)
			{
				UpdateHudAnimLibrary(val, hudData);
			}
		}
	}
	[HarmonyPatch(typeof(BindOrbHudFrame), "DoChangeFrame")]
	internal static class ReplaceInGameHud
	{
		private enum ReturnBehaviour
		{
			ReturnFalse,
			NextElseIf,
			ElseIfCompleted
		}

		private const BindingFlags PUBLICSTATIC = BindingFlags.Static | BindingFlags.Public;

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ChangeHud(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_007e: 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_00a3: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//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)
			//IL_01d4: Expected O, but got Unknown
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			MethodInfo get_HunterCrest2 = typeof(Gameplay).GetProperty("HunterCrest2", BindingFlags.Static | BindingFlags.Public).GetGetMethod();
			MethodInfo get_ToolBase_IsEquipped = typeof(ToolBase).GetProperty("IsEquipped").GetGetMethod();
			int localsObject_idx = -1;
			int hunter2_idx = -1;
			FieldInfo newFrameAnims_f = null;
			FieldInfo customAnimRoutine_f = null;
			Label elseIfCompleted_label = default(Label);
			Label label = generator.DefineLabel();
			Label label2 = generator.DefineLabel();
			Label oldLabel;
			return new CodeMatcher(instructions, generator).Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Ldloc(x, out localsObject_idx)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Ldfld(x, "newFrameAnims")), (string)null)
			}).Start()
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Stfld(x, "newFrameAnims", out newFrameAnims_f)), (string)null)
				})
				.Start()
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Stfld(x, "customAnimRoutine", out customAnimRoutine_f)), (string)null)
				})
				.Start()
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Call(x, get_HunterCrest2)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Stloc(x, out hunter2_idx)), (string)null)
				})
				.MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
				{
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Br(x, out elseIfCompleted_label)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Ldloc(x, hunter2_idx)), (string)null),
					new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => ILUtils.Callvirt(x, get_ToolBase_IsEquipped)), (string)null)
				})
				.Advance(1)
				.StealLabel(label, out oldLabel)
				.Insert((CodeInstruction[])(object)new CodeInstruction[9]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
					{
						labels = new List<Label>(1) { oldLabel }
					},
					new CodeInstruction(OpCodes.Ldloc, (object)localsObject_idx),
					new CodeInstruction(OpCodes.Ldflda, (object)newFrameAnims_f),
					new CodeInstruction(OpCodes.Ldloc, (object)localsObject_idx),
					new CodeInstruction(OpCodes.Ldflda, (object)customAnimRoutine_f),
					Transpilers.EmitDelegate<<>F{00000048}<BindOrbHudFrame, BasicFrameAnims, CoroutineFunction, ReturnBehaviour>>((<>F{00000048}<BindOrbHudFrame, BasicFrameAnims, CoroutineFunction, ReturnBehaviour>)SetCustomHudVars),
					new CodeInstruction(OpCodes.Switch, (object)new Label[3] { label2, label, elseIfCompleted_label }),
					new CodeInstruction(OpCodes.Ldc_I4_0, (object)null)
					{
						labels = new List<Label>(1) { label2 }
					},
					new CodeInstruction(OpCodes.Ret, (object)null)
				})
				.InstructionEnumeration();
		}

		private static ReturnBehaviour SetCustomHudVars(BindOrbHudFrame self, ref BasicFrameAnims basicFrameAnims, ref CoroutineFunction? coroutineFunction)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			BindOrbHudFrame self2 = self;
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				CrestData crest = newCrestDatum;
				if (crest.IsEquipped)
				{
					if ((Object)(object)crest.ToolCrest == (Object)(object)self2.currentFrameCrest)
					{
						return ReturnBehaviour.ReturnFalse;
					}
					self2.currentFrameCrest = crest.ToolCrest;
					basicFrameAnims = (crest.HudFrame.HasRegularCustomBasicAnims ? crest.HudFrame.CustomBasicFrameAnims() : PresetBasicAnims(self2, crest.HudFrame.Preset));
					if (crest.HudFrame.Coroutine != null)
					{
						coroutineFunction = new CoroutineFunction(HudCoro);
					}
					return ReturnBehaviour.ElseIfCompleted;
				}
				IEnumerator HudCoro()
				{
					return crest.HudFrame.Coroutine(self2);
				}
			}
			return ReturnBehaviour.NextElseIf;
		}

		private static BasicFrameAnims PresetBasicAnims(BindOrbHudFrame self, VanillaCrest crest)
		{
			return (BasicFrameAnims)(crest switch
			{
				VanillaCrest.HUNTER_V2 => self.hunterV2FrameAnims, 
				VanillaCrest.HUNTER_V3 => self.hunterV3FrameAnims, 
				VanillaCrest.BEAST => self.warriorFrameAnims, 
				VanillaCrest.REAPER => self.reaperFrameAnims, 
				VanillaCrest.WANDERER => self.wandererFrameAnims, 
				VanillaCrest.WITCH => self.witchFrameAnims, 
				VanillaCrest.ARCHITECT => self.toolmasterFrameAnims, 
				VanillaCrest.SHAMAN => self.spellFrameAnims, 
				VanillaCrest.CURSED => self.cursedV1FrameAnims, 
				VanillaCrest.CLOAKLESS => self.cloaklessFrameAnims, 
				_ => self.defaultFrameAnims, 
			});
		}
	}
	[HarmonyPatch(typeof(SaveProfileHealthBar), "ShowHealth")]
	internal static class ReplaceProfileHud
	{
		private static void Postfix(SaveProfileHealthBar __instance, bool steelsoulMode, string crestId)
		{
			//IL_0037: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				if (newCrestDatum.name == crestId)
				{
					CrestTypeInfo val = __instance.crests[ConvertCrestType(newCrestDatum.HudFrame.Preset)];
					Sprite val2 = (Sprite)(((Object)(object)newCrestDatum.HudFrame.ProfileIcon != (Object)null) ? ((object)newCrestDatum.HudFrame.ProfileIcon) : ((object)val.SpoolImage));
					Sprite val3 = (Sprite)(((Object)(object)newCrestDatum.HudFrame.SteelProfileIcon != (Object)null) ? ((object)newCrestDatum.HudFrame.SteelProfileIcon) : ((object)val.SpoolImageSteel));
					__instance.spoolImage.sprite = (steelsoulMode ? val3 : val2);
				}
			}
		}

		private static CrestTypes ConvertCrestType(VanillaCrest crest)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			return (CrestTypes)(crest switch
			{
				VanillaCrest.HUNTER_V2 => 1, 
				VanillaCrest.HUNTER_V3 => 2, 
				VanillaCrest.BEAST => 9, 
				VanillaCrest.REAPER => 5, 
				VanillaCrest.WANDERER => 8, 
				VanillaCrest.WITCH => 10, 
				VanillaCrest.ARCHITECT => 7, 
				VanillaCrest.SHAMAN => 6, 
				VanillaCrest.CURSED => 4, 
				VanillaCrest.CLOAKLESS => 3, 
				_ => 0, 
			});
		}
	}
	[HarmonyPatch]
	internal static class ReplaceProfileHud_EnumTryParse
	{
		private static MethodBase TargetMethod()
		{
			return typeof(Enum).GetMethods().Single((MethodInfo x) => x.Name == "TryParse" && x.GetParameters().Length == 2).MakeGenericMethod(typeof(CrestTypes));
		}

		private static bool Prefix(string value, ref CrestTypes result, ref bool __result)
		{
			string value2 = value;
			if (NeedleforgePlugin.newCrestData.FindIndex((CrestData x) => x.name == value2) >= 0)
			{
				result = (CrestTypes)0;
				__result = true;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class ShowBindCostInHud
	{
		private static void Postfix(ref float __result)
		{
			CrestData crestData = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
			if (crestData != null)
			{
				__result = crestData.bindCost;
			}
		}
	}
}
namespace Needleforge.Patches.HeroControl
{
	[HarmonyPatch(typeof(HeroController))]
	internal static class AddMovesetsAndAnims
	{
		private static readonly Dictionary<string, (string orig, bool keepTriggers)> requiredAnimations = new Dictionary<string, (string, bool)>
		{
			{
				"DownSlash",
				("DownSpike", true)
			},
			{
				"DownSlashAlt",
				("DownSpike", true)
			},
			{
				"Slash_Charged_Loop",
				("Slash_Charged", false)
			},
			{
				"Dash Attack 1",
				("Dash Attack", true)
			},
			{
				"Dash Attack Antic 1",
				("Dash Attack Antic", true)
			}
		};

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void InitMovesets(HeroController __instance)
		{
			ModHelper.Log("Initializing Crest Movesets...");
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				ModHelper.Log("Init " + newCrestDatum.name + " Moveset");
				TryAddDefaultAnimations(__instance);
				MovesetMaker.InitializeMoveset(newCrestDatum.Moveset);
			}
		}

		[HarmonyPatch("SetConfigGroup")]
		[HarmonyPrefix]
		private static bool SilenceError(HeroController __instance, ConfigGroup configGroup)
		{
			HeroController __instance2 = __instance;
			if (((MonoBehaviour)__instance2).didStart)
			{
				return true;
			}
			if (configGroup == null && NeedleforgePlugin.newCrests.Any((ToolCrest x) => x.HeroConfig == __instance2.crestConfig))
			{
				return false;
			}
			return true;
		}

		private static void TryAddDefaultAnimations(HeroController hc)
		{
			tk2dSpriteAnimation library = hc.AnimCtrl.animator.Library;
			List<tk2dSpriteAnimationClip> list = new List<tk2dSpriteAnimationClip>();
			foreach (KeyValuePair<string, (string, bool)> requiredAnimation in requiredAnimations)
			{
				requiredAnimation.Deconstruct(out var key, out var value);
				(string, bool) tuple = value;
				string text = key;
				var (text2, keepTriggers) = tuple;
				if (library.GetClipByName(text) == null)
				{
					tk2dSpriteAnimationClip clipByName = library.GetClipByName(text2);
					list.Add(CopyClip(text, clipByName, keepTriggers));
				}
			}
			if (list.Count <= 0)
			{
				return;
			}
			tk2dSpriteAnimation val = library;
			tk2dSpriteAnimationClip[] clips = library.clips;
			List<tk2dSpriteAnimationClip> list2 = list;
			int num = 0;
			tk2dSpriteAnimationClip[] array = (tk2dSpriteAnimationClip[])(object)new tk2dSpriteAnimationClip[clips.Length + list2.Count];
			ReadOnlySpan<tk2dSpriteAnimationClip> readOnlySpan = new ReadOnlySpan<tk2dSpriteAnimationClip>(clips);
			readOnlySpan.CopyTo(new Span<tk2dSpriteAnimationClip>(array).Slice(num, readOnlySpan.Length));
			num += readOnlySpan.Length;
			foreach (tk2dSpriteAnimationClip item in list2)
			{
				array[num] = item;
				num++;
			}
			val.clips = array;
			library.isValid = false;
			library.ValidateLookup();
		}

		private static tk2dSpriteAnimationClip CopyClip(string newName, tk2dSpriteAnimationClip orig, bool keepTriggers)
		{
			//IL_0035: 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_0041: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			tk2dSpriteAnimationFrame[] array = orig.frames;
			if (!keepTriggers)
			{
				array = ((IEnumerable<tk2dSpriteAnimationFrame>)array).Select((Func<tk2dSpriteAnimationFrame, tk2dSpriteAnimationFrame>)((tk2dSpriteAnimationFrame f) => new tk2dSpriteAnimationFrame
				{
					spriteCollection = f.spriteCollection,
					spriteId = f.spriteId,
					triggerEvent = false
				})).ToArray();
			}
			return new tk2dSpriteAnimationClip
			{
				name = newName,
				fps = orig.fps,
				frames = array,
				loopStart = orig.loopStart,
				wrapMode = orig.wrapMode
			};
		}
	}
	[HarmonyPatch(typeof(HeroController), "BindCompleted")]
	internal class BindComplete
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				if (newCrestDatum.IsEquipped)
				{
					newCrestDatum.BindCompleteEvent();
				}
			}
		}
	}
	[HarmonyPatch]
	internal class CustomDownspikeBehaviour
	{
		[HarmonyPatch(typeof(HeroController), "Downspike")]
		[HarmonyPostfix]
		private static void SetVelocity(HeroController __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__instance.Config.DownSlashType == 0 && __instance.Config.DownspikeThrusts && __instance.cState.downSpiking && __instance.Config is HeroConfigNeedleforge heroConfigNeedleforge && __instance.downSpikeTimer - Time.deltaTime <= __instance.Config.DownSpikeTime)
			{
				Vector2 val = (Vector2)(__instance.cState.facingRight ? new Vector2(-1f, 1f) : Vector2.one);
				__instance.rb2d.linearVelocity = (heroConfigNeedleforge.DownspikeVelocity + heroConfigNeedleforge.DownspikeAcceleration * __instance.downSpikeTimer) * val;
			}
		}

		[HarmonyPatch(typeof(HeroController), "DownspikeBounce")]
		[HarmonyPrefix]
		private static void SetBounceConfig(HeroController __instance, ref HeroSlashBounceConfig bounceConfig)
		{
			if (__instance.currentDownspike is DownspikeWithBounceConfig downspikeWithBounceConfig)
			{
				bounceConfig = downspikeWithBounceConfig.bounceConfig;
			}
		}
	}
	[HarmonyPatch(typeof(HeroController), "Start")]
	internal static class MovesetFSMEdits
	{
		private static readonly FsmEvent needleforgeDefaultEvent = FsmEvent.GetFsmEvent("NEEDLEFORGE DEFAULT");

		private static readonly FsmEvent noEvent = FsmEvent.GetFsmEvent("");

		private static void Prefix(HeroController __instance)
		{
			ModHelper.Log("Editing Moveset FSMs...");
			DownSlashFSMEdits(__instance);
			DashSlashFSMEdits(__instance);
			ChargedSlashFSMEdits(__instance);
		}

		private static void DownSlashFSMEdits(HeroController hc)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Invalid comparison between Unknown and I4
			IEnumerable<MovesetData> enumerable = from cd in NeedleforgePlugin.newCrestData
				select cd.Moveset into m
				where Object.op_Implicit((Object)(object)m.HeroConfig) && ((int)((HeroControllerConfig)m.HeroConfig).DownSlashType == 2 || m.HeroConfig.DownSlashFsmEdit != null)
				select m;
			if (!enumerable.Any())
			{
				return;
			}
			PlayMakerFSM crestAttacksFSM = hc.crestAttacksFSM;
			if (!crestAttacksFSM.Fsm.preprocessed)
			{
				crestAttacksFSM.Preprocess();
			}
			FsmState state = FsmUtil.GetState(crestAttacksFSM, "Idle");
			FsmState state2 = FsmUtil.GetState(crestAttacksFSM, "End");
			foreach (MovesetData item in enumerable)
			{
				string name = item.Crest.name;
				ModHelper.Log(name + " Down Slash");
				HeroConfigNeedleforge.FsmEdit downSlashFsmEdit = item.HeroConfig.DownSlashFsmEdit;
				if (downSlashFsmEdit == null)
				{
					ModHelper.LogError("Crest " + name + " has a custom downslash type, but doesn't define a DownSlashFsmEdit function.");
					continue;
				}
				if ((int)((HeroControllerConfig)item.HeroConfig).DownSlashType != 2)
				{
					ModHelper.LogError("Crest " + name + " has a DownSlashFsmEdit function, but its DownSlashType " + $"is not {(object)(DownSlashTypes)2}.");
					continue;
				}
				if (string.IsNullOrWhiteSpace(((HeroControllerConfig)item.HeroConfig).downSlashEvent))
				{
					ModHelper.LogError("Crest " + name + " has a custom downslash, but doesn't have a valid downSlashEvent.");
					continue;
				}
				FsmState val = FsmUtil.AddState(crestAttacksFSM, name + " Start");
				FsmUtil.AddTransition(state, ((HeroControllerConfig)item.HeroConfig).downSlashEvent, val.Name);
				downSlashFsmEdit(crestAttacksFSM, val, out var endStates);
				FsmState[] array = endStates;
				for (int i = 0; i < array.Length; i++)
				{
					FsmUtil.AddTransition(array[i], "FINISHED", state2.Name);
				}
			}
		}

		private static void DashSlashFSMEdits(HeroController hc)
		{
			PlayMakerFSM fsm = hc.sprintFSM;
			if (!fsm.Fsm.preprocessed)
			{
				fsm.Preprocess();
			}
			FsmState state = FsmUtil.GetState(fsm, "Start Attack");
			FsmState state2 = FsmUtil.GetState(fsm, "Regain Control Normal");
			FsmInt crestIdx = FsmUtil.AddIntVariable(fsm, "Equipped Crest io.github.needleforge");
			FsmUtil.InsertMethod(state, 1 + Array.FindLastIndex(state.Actions, (FsmStateAction x) => x is SetIntValue), (Action)delegate
			{
				crestIdx.Value = NeedleforgePlugin.newCrestData.FindIndex((CrestData x) => x.IsEquipped);
				if (crestIdx.Value >= 0)
				{
					CrestData crestData = NeedleforgePlugin.newCrestData[crestIdx.Value];
					Transform transform3 = crestData.Moveset.ConfigGroup.DashStab.transform;
					FsmUtil.GetIntVariable(fsm, "Attack Steps").Value = transform3.childCount;
					if (transform3.childCount <= 0)
					{
						ModHelper.LogWarning(crestData.name + ": DashSlash has no steps; the attack won't do anything.");
					}
					else if (((HeroControllerConfig)crestData.Moveset.HeroConfig).dashStabSteps > transform3.childCount)
					{
						ModHelper.LogWarning(crestData.name + ": The HeroConfig.dashStabSteps field has no effect for Needleforge crests. Modify the DashSlash.Steps array instead.");
					}
					fsm.Fsm.Event("MULTIPLE");
				}
			}, false);
			FsmState state3 = FsmUtil.GetState(fsm, "Set Attack Multiple");
			FsmUtil.InsertMethod(state3, Array.FindLastIndex(state3.Actions, (FsmStateAction x) => x is SetPolygonCollider), (Action)delegate
			{
				if (crestIdx.Value >= 0)
				{
					Transform transform2 = NeedleforgePlugin.newCrestData[crestIdx.Value].Moveset.ConfigGroup.DashStab.transform;
					int num3 = FsmUtil.GetIntVariable(fsm, "Attack Step").Value - 1;
					FsmUtil.GetStringVariable(fsm, "Attack Child Name").Value = ((Object)transform2.GetChild(num3)).name;
				}
			}, false);
			FsmState AttackDashStart = FsmUtil.GetState(fsm, "Attack Dash Start");
			FsmUtil.InsertMethod(AttackDashStart, 0, (Action)delegate
			{
				CallMethodProper[] actionsOfType = FsmUtil.GetActionsOfType<CallMethodProper>(AttackDashStart);
				foreach (CallMethodProper val3 in actionsOfType)
				{
					if (typeof(NailAttackBase).IsAssignableFrom(val3.cachedType) && val3.cachedType != typeof(DashStabNailAttack))
					{
						val3.cachedType = null;
						val3.cachedMethodInfo = null;
						val3.cachedParameterInfo = Array.Empty<ParameterInfo>();
					}
				}
			}, false);
			FsmUtil.InsertMethod(AttackDashStart, Array.FindIndex(AttackDashStart.Actions, (FsmStateAction x) => x is PlayAudioEvent), (Action)delegate
			{
				if (crestIdx.Value >= 0)
				{
					Transform transform = NeedleforgePlugin.newCrestData[crestIdx.Value].Moveset.ConfigGroup.DashStab.transform;
					int num2 = FsmUtil.GetIntVariable(fsm, "Attack Step").Value - 1;
					AudioSource component = ((Component)transform.GetChild(num2)).GetComponent<AudioSource>();
					if (Object.op_Implicit((Object)(object)component))
					{
						fsm.FsmVariables.FindFsmObject("Clip").Value = (Object)(object)component.clip;
					}
				}
			}, false);
			IEnumerable<MovesetData> enumerable = from cd in NeedleforgePlugin.newCrestData
				select cd.Moveset into m
				where Object.op_Implicit((Object)(object)m.HeroConfig) && m.HeroConfig.DashSlashFsmEdit != null
				select m;
			if (!enumerable.Any())
			{
				return;
			}
			int num = 1 + Array.FindLastIndex(state.Actions, (FsmStateAction x) => x is CheckIfCrestEquipped);
			foreach (MovesetData item in enumerable)
			{
				string name = item.Crest.name;
				ModHelper.Log(name + " Dash Slash");
				FsmState val = FsmUtil.AddState(fsm, name + " Start");
				CheckIfCrestEquipped val2 = CreateCrestEquipCheck(item.Crest);
				FsmUtil.InsertAction(state, num, (FsmStateAction)(object)val2);
				FsmUtil.AddTransition(state, ((CheckFsmStateAction)val2).trueEvent.Name, val.name);
				item.HeroConfig.DashSlashFsmEdit(fsm, val, out var endStates);
				FsmState[] array = endStates;
				for (int i = 0; i < array.Length; i++)
				{
					FsmUtil.AddTransition(array[i], "FINISHED", state2.Name);
				}
			}
		}

		private static void ChargedSlashFSMEdits(HeroController hc)
		{
			//IL_007a: 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_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_0091: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00b9: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00f7: Expected O, but got Unknown
			//IL_00f7: 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_0113: Expected O, but got Unknown
			PlayMakerFSM fsm = FsmUtil.GetFsmPreprocessed(((Component)hc).gameObject, "Nail Arts");
			FsmState state = FsmUtil.GetState(fsm, "Antic Type");
			FsmState state2 = FsmUtil.GetState(fsm, "Set Finished");
			FsmState val = FsmUtil.AddState(fsm, "Needleforge Kickoff");
			FsmUtil.AddMethod(state, (Action)delegate
			{
				CrestData crestData = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
				if (crestData != null && crestData.Moveset.HeroConfig.ChargedSlashFsmEdit == null)
				{
					GameObject val4 = crestData.Moveset.ChargedSlash?.GameObject;
					if (Object.op_Implicit((Object)(object)val4) && val4.transform.childCount <= 0)
					{
						ModHelper.LogWarning(crestData.name + ": ChargedSlash has no steps; the attack won't do anything.");
					}
					fsm.Fsm.Event(needleforgeDefaultEvent);
				}
			}, false);
			FsmUtil.AddTransition(state, needleforgeDefaultEvent.Name, val.Name);
			FsmUtil.AddAction(val, (FsmStateAction)new CheckIsCharacterGrounded
			{
				Target = new FsmOwnerDefault
				{
					OwnerOption = (OwnerDefaultOption)0
				},
				RayCount = new FsmInt
				{
					Value = 3
				},
				GroundDistance = new FsmFloat
				{
					Value = 0.2f
				},
				SkinWidth = new FsmFloat
				{
					Value = -0.05f
				},
				SkinHeight = new FsmFloat
				{
					Value = 0.1f
				},
				StoreResult = new FsmBool
				{
					Value = false
				},
				NotGroundedEvent = FsmEvent.GetFsmEvent("FINISHED"),
				EveryFrame = false
			});
			FsmUtil.AddMethod(val, (Action)delegate
			{
				HeroController instance = HeroController.instance;
				if (instance.Config is HeroConfigNeedleforge heroConfigNeedleforge && heroConfigNeedleforge.ChargedSlashDoesKickoff)
				{
					instance.rb2d.linearVelocityY = 10f;
				}
			}, false);
			FsmUtil.AddTransition(val, "FINISHED", "Antic");
			FsmState state3 = FsmUtil.GetState(fsm, "Slash Recoil?");
			if (state3 != null)
			{
				FsmUtil.DisableActionsOfType<CheckIfCrestEquipped>(state3);
			}
			IEnumerable<MovesetData> enumerable = from cd in NeedleforgePlugin.newCrestData
				select cd.Moveset into m
				where Object.op_Implicit((Object)(object)m.HeroConfig) && m.HeroConfig.ChargedSlashFsmEdit != null
				select m;
			if (!enumerable.Any())
			{
				return;
			}
			int num = 1 + Array.FindLastIndex(state.Actions, (FsmStateAction x) => x is CheckIfCrestEquipped);
			foreach (MovesetData item in enumerable)
			{
				string name = item.Crest.name;
				ModHelper.Log(name + " Charged Slash");
				FsmState val2 = FsmUtil.AddState(fsm, name + " Start");
				CheckIfCrestEquipped val3 = CreateCrestEquipCheck(item.Crest);
				FsmUtil.InsertAction(state, num, (FsmStateAction)(object)val3);
				FsmUtil.AddTransition(state, ((CheckFsmStateAction)val3).trueEvent.Name, val2.name);
				item.HeroConfig.ChargedSlashFsmEdit(fsm, val2, out var endStates);
				FsmState[] array = endStates;
				for (int i = 0; i < array.Length; i++)
				{
					FsmUtil.AddTransition(array[i], "FINISHED", state2.Name);
				}
			}
		}

		private static CheckIfCrestEquipped CreateCrestEquipCheck(CrestData crest)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			return new CheckIfCrestEquipped
			{
				Crest = new FsmObject
				{
					Value = (Object)(object)crest.ToolCrest
				},
				trueEvent = FsmEvent.GetFsmEvent(crest.name),
				falseEvent = noEvent,
				storeValue = FsmBool.op_Implicit(false)
			};
		}
	}
	[HarmonyPatch(typeof(HeroController), "Start")]
	internal class Tool_CrestFSMEdits
	{
		private static readonly CrestData.BindEventHandler defaultBind = delegate(FsmInt value, FsmInt amount, FsmFloat time, PlayMakerFSM fsm)
		{
			value.Value = 3;
			amount.Value = 1;
			time.Value = 1.2f;
		};

		private static readonly Dictionary<UniqueBindDirection, Func<bool>> directionGet = new Dictionary<UniqueBindDirection, Func<bool>>
		{
			{
				UniqueBindDirection.UP,
				() => ((OneAxisInputControl)HeroInput.Up).IsPressed
			},
			{
				UniqueBindDirection.DOWN,
				() => ((OneAxisInputControl)HeroInput.Down).IsPressed
			},
			{
				UniqueBindDirection.LEFT,
				() => ((OneAxisInputControl)HeroInput.Left).IsPressed
			},
			{
				UniqueBindDirection.RIGHT,
				() => ((OneAxisInputControl)HeroInput.Right).IsPressed
			}
		};

		private static HeroActions HeroInput => HeroController.instance.inputHandler.inputActions;

		[HarmonyPrefix]
		private static void AddCrests(HeroController __instance)
		{
			//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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			PlayMakerFSM bind = FsmUtil.GetFsmPreprocessed(((Component)__instance).gameObject, "Bind");
			FsmState state = FsmUtil.GetState(bind, "Can Bind?");
			FsmState state2 = FsmUtil.GetState(bind, "Bind Type");
			FsmState state3 = FsmUtil.GetState(bind, "Quick Bind?");
			FsmState state4 = FsmUtil.GetState(bind, "Bind Bell?");
			FsmState state5 = FsmUtil.GetState(bind, "End Bind");
			FsmState state6 = FsmUtil.GetState(bind, "Quick Craft?");
			FsmState state7 = FsmUtil.GetState(bind, "Use Reserve Bind?");
			FsmState state8 = FsmUtil.GetState(bind, "Reserve Bind Burst");
			FsmInt healValue = FsmUtil.GetIntVariable(bind, "Heal Amount");
			FsmInt healAmount = FsmUtil.GetIntVariable(bind, "Bind Amount");
			FsmFloat healTime = FsmUtil.GetFloatVariable(bind, "Bind Time");
			FsmState val = FsmUtil.AddState(bind, "Which Crest?");
			FsmUtil.AddTransition(val, "Toolmaster", state6.name);
			FsmUtil.AddMethod(val, (Action)delegate
			{
				if (!NeedleforgePlugin.uniqueBind.ContainsKey(PlayerData.instance.CurrentCrestID))
				{
					bind.SendEvent("Toolmaster");
				}
			}, false);
			FsmUtil.ChangeTransition(state7, "FALSE", val.name);
			FsmUtil.ChangeTransition(state8, "FINISHED", val.name);
			foreach (ToolCrest crest in NeedleforgePlugin.newCrests)
			{
				FsmBool val2 = FsmUtil.AddBoolVariable(bind, "Is " + crest.name + " Equipped");
				FsmUtil.AddAction(state, (FsmStateAction)new CheckIfCrestEquipped
				{
					Crest = FsmObject.op_Implicit((Object)(object)crest),
					storeValue = val2
				});
				FsmState val3 = FsmUtil.AddState(bind, crest.name + " Bind");
				FsmEvent isTrue = FsmUtil.AddTransition(state2, crest.name ?? "", val3.name);
				FsmUtil.AddAction(state2, (FsmStateAction)new BoolTest
				{
					boolVariable = val2,
					isTrue = isTrue,
					everyFrame = false
				});
				FsmUtil.AddTransition(val3, "FINISHED", state3.name);
				FsmUtil.AddMethod(val3, (Action)delegate
				{
					defaultBind(healValue, healAmount, healTime, bind);
					NeedleforgePlugin.bindEvents[crest.name](healValue, healAmount, healTime, bind);
				}, false);
				if (!NeedleforgePlugin.uniqueBind.TryGetValue(crest.name, out UniqueBindEvent bindData))
				{
					continue;
				}
				FsmState val4 = FsmUtil.AddState(bind, crest.name + " Special Bind?");
				FsmState val5 = FsmUtil.AddState(bind, crest.name + " Special Bind Trigger");
				FsmUtil.AddTransition(val, crest.name + " Special", val4.name);
				FsmUtil.AddMethod(val, (Action)delegate
				{
					if (((ToolBase)crest).IsEquipped)
					{
						bind.SendEvent(crest.name + " Special");
					}
				}, false);
				FsmUtil.AddTransition(val4, "FALSE", state4.name);
				FsmUtil.AddTransition(val4, "TRUE", val5.name);
				FsmUtil.AddMethod(val4, (Action)delegate
				{
					bind.SendEvent(directionGet[bindData.Direction]() ? "TRUE" : "FALSE");
				}, false);
				FsmUtil.AddTransition(val5, "FINISHED", state5.name);
				FsmUtil.AddLambdaMethod(val5, bindData.lambdaMethod);
			}
			DelegateAction<Action> val6 = new DelegateAction<Action>
			{
				Method = delegate(Action action)
				{
					FsmInt intVariable = FsmUtil.GetIntVariable(bind, "Current Silk Cost");
					FsmInt intVariable2 = FsmUtil.GetIntVariable(bind, "Silk Cost Witch");
					FsmBool boolVariable = FsmUtil.GetBoolVariable(bind, "Is Witch Equipped");
					bool flag = true;
					if (boolVariable.Value)
					{
						intVariable.Value = intVariable2.Value;
					}
					else
					{
						foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
						{
							if (newCrestDatum.IsEquipped)
							{
								intVariable.Value = newCrestDatum.bindCost;
								flag = false;
							}
						}
						if (flag)
						{
							intVariable.Value = 9;
						}
					}
					action();
				}
			};
			val6.Arg = ((FsmStateAction)val6).Finish;
			int num = Array.FindIndex(state.Actions, delegate(FsmStateAction x)
			{
				ConvertBoolToInt val7 = (ConvertBoolToInt)(object)((x is ConvertBoolToInt) ? x : null);
				return val7 != null && ((NamedVariable)val7.intVariable).Name == "Current Silk Cost";
			});
			FsmUtil.ReplaceAction(state, num, (FsmStateAction)(object)val6);
		}

		[HarmonyPrefix]
		private static void AddTools(HeroController __instance)
		{
			PlayMakerFSM toolEventTarget = __instance.toolEventTarget;
			FsmState state = FsmUtil.GetState(toolEventTarget, "Tool Choice");
			foreach (ToolData newTool in NeedleforgePlugin.newToolData)
			{
				if (newTool is LiquidToolData liquidToolData)
				{
					FsmState val = FsmUtil.AddState(toolEventTarget, liquidToolData.name + " ANIM");
					tk2dSpriteAnimator animator = ((Component)__instance).GetComponent<tk2dSpriteAnimator>();
					string clipName = liquidToolData.clip;
					FsmUtil.AddLambdaMethod(val, (Action<Action>)delegate(Action finish)
					{
						Action finish2 = finish;
						animator.Play(clipName);
						tk2dSpriteAnimator obj = animator;
						obj.AnimationCompleted = (Action<tk2dSpriteAnimator, tk2dSpriteAnimationClip>)Delegate.Combine(obj.AnimationCompleted, new Action<tk2dSpriteAnimator, tk2dSpriteAnimationClip>(FinishEventThenRemove));
						NeedleforgePlugin.toolEventHooks[newTool.name + " BEFORE ANIM"]();
						void FinishEventThenRemove(tk2dSpriteAnimator sprite, tk2dSpriteAnimationClip clip)
						{
							if (!(clip.name != clipName))
							{
								NeedleforgePlugin.toolEventHooks[newTool.name + " AFTER ANIM"]();
								tk2dSpriteAnimator obj2 = animator;
								obj2.AnimationCompleted = (Action<tk2dSpriteAnimator, tk2dSpriteAnimationClip>)Delegate.Remove(obj2.AnimationCompleted, new Action<tk2dSpriteAnimator, tk2dSpriteAnimationClip>(FinishEventThenRemove));
								finish2();
							}
						}
					});
					FsmEvent val2 = FsmUtil.AddTransition(state, liquidToolData.name ?? "", val.name);
					Fsm fsm = toolEventTarget.FsmTemplate.fsm;
					FsmEvent[] events = toolEventTarget.Fsm.Events;
					int num = 0;
					FsmEvent[] array = (FsmEvent[])(object)new FsmEvent[1 + events.Length];
					ReadOnlySpan<FsmEvent> readOnlySpan = new ReadOnlySpan<FsmEvent>(events);
					readOnlySpan.CopyTo(new Span<FsmEvent>(array).Slice(num, readOnlySpan.Length));
					num += readOnlySpan.Length;
					array[num] = val2;
					fsm.Events = array;
					FsmUtil.AddTransition(val, "FINISHED", "Return Control");
				}
			}
		}
	}
}
namespace Needleforge.Makers
{
	internal static class CrestMaker
	{
		internal static Data CreateDefaultSaveData()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Data result = default(Data);
			result.IsUnlocked = true;
			result.Slots = new List<SlotData>();
			result.DisplayNewIndicator = true;
			return result;
		}

		internal static ToolCrest CreateCrest(CrestData crestData)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			ToolCrest val = ToolItemManager.GetAllCrests()[0];
			ToolCrest val2 = ScriptableObject.CreateInstance<ToolCrest>();
			val2.name = crestData.name;
			val2.crestGlow = (Sprite)(Object.op_Implicit((Object)(object)crestData.CrestGlow) ? ((object)crestData.CrestGlow) : ((object)val.crestGlow));
			val2.crestSilhouette = (Sprite)(Object.op_Implicit((Object)(object)crestData.Silhouette) ? ((object)crestData.Silhouette) : ((object)val.crestSilhouette));
			val2.crestSprite = (Sprite)(Object.op_Implicit((Object)(object)crestData.RealSprite) ? ((object)crestData.RealSprite) : ((object)val.crestSprite));
			val2.displayName = crestData.displayName;
			val2.description = crestData.description;
			val2.slots = crestData.slots.ToArray();
			val2.heroConfig = (HeroControllerConfig)(object)crestData.Moveset.HeroConfig;
			((NamedScriptableObjectList<ToolCrest>)(object)ManagerSingleton<ToolItemManager>.Instance.crestList).Add(val2);
			NeedleforgePlugin.newCrests.Add(val2);
			return val2;
		}
	}
	internal class MovesetMaker
	{
		private static ConfigGroup? hunter;

		internal static void InitializeMoveset(MovesetData moveset)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_007c: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_016f: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			HeroControll