Decompiled source of Needleforge v0.8.0

Needleforge.dll

Decompiled a month 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.8.0.0")]
[assembly: AssemblyInformationalVersion("0.8.0+e9371ba89c050e23f3e163aee727ca442d94b7d1")]
[assembly: AssemblyProduct("Needleforge")]
[assembly: AssemblyTitle("Needleforge")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/GamingInfinite/Needleforge")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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)
		{
			NeedleforgePlugin.logger.LogError((object)msg);
		}

		public static void LogWarning(string msg)
		{
			NeedleforgePlugin.logger.LogWarning((object)msg);
		}
	}
	[BepInPlugin("io.github.needleforge", "Needleforge", "0.8.0")]
	public class NeedleforgePlugin : BaseUnityPlugin
	{
		public static ManualLogSource logger;

		public static Harmony harmony;

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

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

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

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

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

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

		public static Dictionary<string, Action<FsmInt, FsmInt, FsmFloat, PlayMakerFSM>> bindEvents = new Dictionary<string, Action<FsmInt, FsmInt, FsmFloat, PlayMakerFSM>>();

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

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

		public 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.8.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("com.example.patch");
			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)
		{
			foreach (ToolData newToolDatum in newToolData)
			{
				if (newToolDatum.name == name)
				{
					return newToolDatum;
				}
			}
			return null;
		}

		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 LdlocRelaxed(CodeInstruction ci)
		{
			if (!(ci.opcode == OpCodes.Ldloc) && !(ci.opcode == OpCodes.Ldloc_0) && !(ci.opcode == OpCodes.Ldloc_1) && !(ci.opcode == OpCodes.Ldloc_2) && !(ci.opcode == OpCodes.Ldloc_3))
			{
				return ci.opcode == OpCodes.Ldloc_S;
			}
			return true;
		}

		internal static bool LdlocWithIndex(CodeInstruction ci, int index)
		{
			if ((index != 0 || !(ci.opcode == OpCodes.Ldloc_0)) && (index != 1 || !(ci.opcode == OpCodes.Ldloc_1)) && (index != 2 || !(ci.opcode == OpCodes.Ldloc_2)) && (index != 3 || !(ci.opcode == OpCodes.Ldloc_3)))
			{
				if ((ci.opcode == OpCodes.Ldloc || ci.opcode == OpCodes.Ldloc_S) && ci.operand is int num)
				{
					return num == index;
				}
				return false;
			}
			return true;
		}

		internal static bool StlocRelaxed(CodeInstruction ci)
		{
			if (!(ci.opcode == OpCodes.Stloc) && !(ci.opcode == OpCodes.Stloc_0) && !(ci.opcode == OpCodes.Stloc_1) && !(ci.opcode == OpCodes.Stloc_2) && !(ci.opcode == OpCodes.Stloc_3))
			{
				return ci.opcode == OpCodes.Stloc_S;
			}
			return true;
		}

		internal static int GetStlocIndex(CodeInstruction ci)
		{
			if (!StlocRelaxed(ci))
			{
				return -1;
			}
			if (ci.opcode == OpCodes.Stloc_0)
			{
				return 0;
			}
			if (ci.opcode == OpCodes.Stloc_1)
			{
				return 1;
			}
			if (ci.opcode == OpCodes.Stloc_2)
			{
				return 2;
			}
			if (ci.opcode == OpCodes.Stloc_3)
			{
				return 3;
			}
			object operand = ci.operand;
			if (operand is int)
			{
				return (int)operand;
			}
			return -1;
		}

		internal static bool LdfldWithName(CodeInstruction ci, string name)
		{
			if (ci.opcode != OpCodes.Ldfld)
			{
				return false;
			}
			if (ci.operand is FieldInfo)
			{
				return (ci.operand as FieldInfo)?.Name == name;
			}
			return false;
		}

		internal static bool StfldWithName(CodeInstruction ci, string name)
		{
			if (ci.opcode == OpCodes.Stfld && ci.operand is FieldInfo fieldInfo)
			{
				return fieldInfo.Name == name;
			}
			return false;
		}

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

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

		internal static bool CallWithMethodName(CodeInstruction ci, string name)
		{
			if (ci.opcode != OpCodes.Call)
			{
				return false;
			}
			if (ci.operand is MethodInfo)
			{
				return (ci.operand as MethodInfo)?.Name == name;
			}
			return false;
		}

		internal static bool CallvirtWithMethodName(CodeInstruction ci, string name)
		{
			if (ci.opcode != OpCodes.Callvirt)
			{
				return false;
			}
			if (ci.operand is MethodInfo)
			{
				return (ci.operand as MethodInfo)?.Name == name;
			}
			return false;
		}
	}
	internal static class MathUtils
	{
		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;
		}
	}
}
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]
	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_0078: 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_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)
			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;
				}
			}
		}
	}
}
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_000b: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			GameObject val = new GameObject("NeedleforgeHudRoots");
			ModHelper.Log("Adding Needleforge Hud Roots");
			foreach (CrestData newCrestDatum in NeedleforgePlugin.newCrestData)
			{
				GameObject val2 = new GameObject(newCrestDatum.name + "HUDRoot");
				val2.transform.SetParent(val.transform);
				NeedleforgePlugin.hudRoots[newCrestDatum.name] = val2;
				UpdateHudAnimLibrary(__instance, newCrestDatum.HudFrame);
				newCrestDatum.HudFrame.InitializeRoot();
			}
			val.transform.SetParent(((Component)__instance).transform);
		}

		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();
			}
			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();
		}

		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 class ReplaceInGameHud
	{
		private enum ReturnBehaviour
		{
			ReturnFalse,
			NextElseIf,
			ElseIfCompleted
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ChangeHud(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Expected O, but got Unknown
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Expected O, but got Unknown
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Expected O, but got Unknown
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Expected O, but got Unknown
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator);
			val.Start();
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((Func<CodeInstruction, bool>)ILUtils.LdlocRelaxed, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ILUtils.LdfldWithName(ci, "newFrameAnims")), (string)null)
			});
			if (val.IsInvalid)
			{
				val.ReportFailure((MethodBase)null, (Action<string>)NeedleforgePlugin.logger.LogError);
				return instructions;
			}
			CodeInstruction instruction = val.Instruction;
			FieldInfo fieldInfo = instructions.First((CodeInstruction ci) => ILUtils.StfldWithName(ci, "newFrameAnims")).operand as FieldInfo;
			FieldInfo fieldInfo2 = instructions.First((CodeInstruction ci) => ILUtils.StfldWithName(ci, "customAnimRoutine")).operand as FieldInfo;
			val.Start();
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)ILUtils.StlocRelaxed, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ILUtils.CallWithMethodName(ci, "get_HunterCrest2")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)ILUtils.StlocRelaxed, (string)null)
			});
			if (val.IsInvalid)
			{
				val.ReportFailure((MethodBase)null, (Action<string>)NeedleforgePlugin.logger.LogError);
				return instructions;
			}
			int locHunterCrest2 = ILUtils.GetStlocIndex(val.Instruction);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((Func<CodeInstruction, bool>)ILUtils.BrRelaxed, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ILUtils.LdlocWithIndex(ci, locHunterCrest2)), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction ci) => ILUtils.CallvirtWithMethodName(ci, "get_IsEquipped")), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)ILUtils.BrfalseRelaxed, (string)null)
			});
			Label label = (Label)val.Operand;
			val.Advance(1);
			if (val.IsInvalid)
			{
				val.ReportFailure((MethodBase)null, (Action<string>)NeedleforgePlugin.logger.LogError);
				return instructions;
			}
			Label item = val.Instruction.labels[0];
			Label label2 = generator.DefineLabel();
			val.Instruction.labels = new List<Label>(1) { label2 };
			CodeInstruction val2 = new CodeInstruction(OpCodes.Ldc_I4_0, (object)null)
			{
				labels = new List<Label>(1) { generator.DefineLabel() }
			};
			val.Insert((CodeInstruction[])(object)new CodeInstruction[9]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				{
					labels = new List<Label>(1) { item }
				},
				new CodeInstruction(instruction),
				new CodeInstruction(OpCodes.Ldflda, (object)fieldInfo),
				new CodeInstruction(instruction),
				new CodeInstruction(OpCodes.Ldflda, (object)fieldInfo2),
				Transpilers.EmitDelegate<<>F{00000048}<BindOrbHudFrame, BasicFrameAnims, CoroutineFunction, ReturnBehaviour>>((<>F{00000048}<BindOrbHudFrame, BasicFrameAnims, CoroutineFunction, ReturnBehaviour>)SetCustomHudVars),
				new CodeInstruction(OpCodes.Switch, (object)new Label[3]
				{
					val2.labels[0],
					label2,
					label
				}),
				val2,
				new CodeInstruction(OpCodes.Ret, (object)null)
			});
			return val.Instructions();
		}

		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 class ReplaceProfileHud
	{
		[HarmonyPostfix]
		private static void ReplaceHUD(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, 
			});
		}
	}
}
namespace Needleforge.Patches.HeroControl
{
	[HarmonyPatch(typeof(HeroController), "Awake")]
	internal 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)
			}
		};

		private static void Postfix(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);
			}
		}

		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 name, 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 = name,
				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 class MovesetFSMEdits
	{
		private static readonly FsmEvent needleforgeDefaultEvent = FsmEvent.GetFsmEvent("NEEDLEFORGE DEFAULT");

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

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

		private static void DownSlashFSMEdits(HeroController hc)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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;
			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 fsm2 = hc.sprintFSM;
			fsm2.Preprocess();
			FsmState state2 = FsmUtil.GetState(fsm2, "Start Attack");
			FsmState state3 = FsmUtil.GetState(fsm2, "Regain Control Normal");
			FsmUtil.InsertLambdaMethod(state2, 1 + Array.FindLastIndex(state2.Actions, (FsmStateAction x) => x is SetIntValue), (Action<Action>)delegate(Action finished)
			{
				RedirectToLoopingDefault(finished, fsm2);
			});
			FsmState state4 = FsmUtil.GetState(fsm2, "Set Attack Multiple");
			FsmUtil.InsertLambdaMethod(state4, Array.FindLastIndex(state4.Actions, (FsmStateAction x) => x is SetPolygonCollider), (Action<Action>)delegate(Action finished)
			{
				DetectAttackStepName(finished, fsm2);
			});
			FsmState AttackDashStart = FsmUtil.GetState(fsm2, "Attack Dash Start");
			FsmUtil.InsertLambdaMethod(AttackDashStart, 0, (Action<Action>)delegate(Action finished)
			{
				ClearAttackCallMethodCaches(finished, AttackDashStart);
			});
			FsmUtil.InsertLambdaMethod(AttackDashStart, Array.FindIndex(AttackDashStart.Actions, (FsmStateAction x) => x is PlayAudioEvent), (Action<Action>)delegate(Action finished)
			{
				SetAttackAudioClip(finished, fsm2);
			});
			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(state2.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(fsm2, name + " Start");
				CheckIfCrestEquipped val2 = CreateCrestEquipCheck(item.Crest);
				FsmUtil.InsertAction(state2, num, (FsmStateAction)(object)val2);
				FsmUtil.AddTransition(state2, ((CheckFsmStateAction)val2).trueEvent.Name, val.name);
				item.HeroConfig.DashSlashFsmEdit(fsm2, val, out var endStates);
				FsmState[] array = endStates;
				for (int i = 0; i < array.Length; i++)
				{
					FsmUtil.AddTransition(array[i], "FINISHED", state3.Name);
				}
			}
			static void ClearAttackCallMethodCaches(Action finished, FsmState state)
			{
				foreach (CallMethodProper item2 in state.Actions.OfType<CallMethodProper>())
				{
					if (typeof(NailAttackBase).IsAssignableFrom(item2.cachedType) && item2.cachedType != typeof(DashStabNailAttack))
					{
						item2.cachedType = null;
						item2.cachedMethodInfo = null;
						item2.cachedParameterInfo = Array.Empty<ParameterInfo>();
					}
				}
				finished();
			}
			static void DetectAttackStepName(Action finished, PlayMakerFSM fsm)
			{
				CrestData crestData2 = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
				if (crestData2 != null)
				{
					int num3 = FsmUtil.GetIntVariable(fsm, "Attack Step").Value - 1;
					Transform transform = crestData2.Moveset.ConfigGroup.DashStab.transform;
					FsmUtil.GetStringVariable(fsm, "Attack Child Name").Value = ((Object)transform.GetChild(num3)).name;
				}
				finished();
			}
			static void RedirectToLoopingDefault(Action finished, PlayMakerFSM fsm)
			{
				CrestData crestData3 = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
				if (crestData3 != null)
				{
					Transform transform2 = crestData3.Moveset.ConfigGroup.DashStab.transform;
					FsmUtil.GetIntVariable(fsm, "Attack Steps").Value = transform2.childCount;
					fsm.Fsm.Event(FsmEvent.GetFsmEvent("MULTIPLE"));
				}
				finished();
			}
			static void SetAttackAudioClip(Action finished, PlayMakerFSM fsm)
			{
				CrestData crestData = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
				if (crestData != null)
				{
					int num2 = FsmUtil.GetIntVariable(fsm, "Attack Step").Value - 1;
					AudioSource component = ((Component)crestData.Moveset.ConfigGroup.DashStab.transform.GetChild(num2)).GetComponent<AudioSource>();
					if (Object.op_Implicit((Object)(object)component))
					{
						fsm.FsmVariables.FindFsmObject("Clip").Value = (Object)(object)component.clip;
					}
				}
				finished();
			}
		}

		private static void ChargedSlashFSMEdits(HeroController hc)
		{
			//IL_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0090: 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_00a2: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b8: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			PlayMakerFSM fsm2 = FsmUtil.GetFsmPreprocessed(((Component)hc).gameObject, "Nail Arts");
			FsmState state = FsmUtil.GetState(fsm2, "Antic Type");
			FsmState state2 = FsmUtil.GetState(fsm2, "Set Finished");
			FsmState val = FsmUtil.AddState(fsm2, "Needleforge Kickoff");
			FsmUtil.AddLambdaMethod(state, (Action<Action>)delegate(Action finished)
			{
				RedirectToNeedleforgeKickoff(finished, fsm2);
			});
			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.AddLambdaMethod(val, (Action<Action>)DoKickoffIfRequested);
			FsmUtil.AddTransition(val, "FINISHED", "Antic");
			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(fsm2, 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(fsm2, val2, out var endStates);
				FsmState[] array = endStates;
				for (int i = 0; i < array.Length; i++)
				{
					FsmUtil.AddTransition(array[i], "FINISHED", state2.Name);
				}
			}
			static void DoKickoffIfRequested(Action finished)
			{
				HeroController instance = HeroController.instance;
				if (instance.Config is HeroConfigNeedleforge heroConfigNeedleforge && heroConfigNeedleforge.ChargedSlashDoesKickoff)
				{
					instance.rb2d.linearVelocityY = 10f;
				}
				finished();
			}
			static void RedirectToNeedleforgeKickoff(Action finished, PlayMakerFSM fsm)
			{
				CrestData crestData = NeedleforgePlugin.newCrestData.FirstOrDefault((CrestData x) => x.IsEquipped);
				if (crestData != null && crestData.Moveset.HeroConfig.ChargedSlashFsmEdit == null)
				{
					fsm.Fsm.Event(needleforgeDefaultEvent);
				}
				finished();
			}
		}

		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 Action<FsmInt, FsmInt, FsmFloat, PlayMakerFSM> 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)HeroController.instance.inputHandler.inputActions.Up).IsPressed
			},
			{
				UniqueBindDirection.DOWN,
				() => ((OneAxisInputControl)HeroController.instance.inputHandler.inputActions.Down).IsPressed
			},
			{
				UniqueBindDirection.LEFT,
				() => ((OneAxisInputControl)HeroController.instance.inputHandler.inputActions.Left).IsPressed
			},
			{
				UniqueBindDirection.RIGHT,
				() => ((OneAxisInputControl)HeroController.instance.inputHandler.inputActions.Right).IsPressed
			}
		};

		[HarmonyPostfix]
		private static void AddCrests(HeroController __instance)
		{
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: 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.AddLambdaMethod(val, (Action<Action>)delegate(Action finish)
			{
				if (!NeedleforgePlugin.uniqueBind.ContainsKey(PlayerData.instance.CurrentCrestID))
				{
					bind.SendEvent("Toolmaster");
				}
				finish();
			});
			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.AddLambdaMethod(val3, (Action<Action>)delegate
				{
					defaultBind(healValue, healAmount, healTime, bind);
					NeedleforgePlugin.bindEvents[crest.name](healValue, healAmount, healTime, bind);
					bind.SendEvent("FINISHED");
				});
				if (!NeedleforgePlugin.uniqueBind.ContainsKey(crest.name))
				{
					continue;
				}
				UniqueBindEvent bindData = NeedleforgePlugin.uniqueBind[crest.name];
				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.AddLambdaMethod(val, (Action<Action>)delegate(Action finish)
				{
					if (((ToolBase)crest).IsEquipped)
					{
						bind.SendEvent(crest.name + " Special");
					}
					finish();
				});
				FsmUtil.AddTransition(val4, "FALSE", state4.name);
				FsmUtil.AddTransition(val4, "TRUE", val5.name);
				FsmUtil.AddLambdaMethod(val4, (Action<Action>)delegate(Action finish)
				{
					bind.SendEvent(directionGet[bindData.Direction]() ? "TRUE" : "FALSE");
					finish();
				});
				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;
			FsmUtil.ReplaceAction(state, 9, (FsmStateAction)(object)val6);
		}

		[HarmonyPostfix]
		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 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
			HeroController hc;
			GameObject root;
			if (TryFindDefaultMovesets())
			{
				if (!Object.op_Implicit((Object)(object)moveset.HeroConfig))
				{
					moveset.HeroConfig = HeroConfigNeedleforge.Copy(hunter.Config);
				}
				hc = HeroController.instance;
				root = new GameObject(moveset.Crest.name);
				root.transform.SetParent(hunter.ActiveRoot.transform.parent);
				root.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				moveset.ConfigGroup = new ConfigGroup
				{
					ActiveRoot = root,
					Config = (HeroControllerConfig)(object)moveset.HeroConfig,
					NormalSlashObject = AttackOrDefault(moveset.Slash, hunter.NormalSlashObject),
					UpSlashObject = AttackOrDefault(moveset.UpSlash, hunter.UpSlashObject),
					WallSlashObject = AttackOrDefault(moveset.WallSlash, hunter.WallSlashObject),
					DownSlashObject = AttackOrDefault(moveset.DownSlash, hunter.DownSlashObject),
					DashStab = DashAttackOrDefault(moveset.DashSlash, hunter.DashStab),
					ChargeSlash = AttackOrDefault(moveset.ChargedSlash, hunter.ChargeSlash),
					TauntSlash = AttackOrDefault(null, hunter.TauntSlash),
					AlternateSlashObject = moveset.AltSlash?.CreateGameObject(root, hc),
					AltUpSlashObject = moveset.AltUpSlash?.CreateGameObject(root, hc),
					AltDownSlashObject = moveset.AltDownSlash?.CreateGameObject(root, hc)
				};
				HeroController obj = hc;
				ConfigGroup[] configs = hc.configs;
				int num = 0;
				ConfigGroup[] array = (ConfigGroup[])(object)new ConfigGroup[1 + configs.Length];
				ReadOnlySpan<ConfigGroup> readOnlySpan = new ReadOnlySpan<ConfigGroup>(configs);
				readOnlySpan.CopyTo(new Span<ConfigGroup>(array).Slice(num, readOnlySpan.Length));
				num += readOnlySpan.Length;
				array[num] = moveset.ConfigGroup;
				obj.configs = array;
				moveset.ExtraInitialization();
				moveset.ConfigGroup.Setup();
			}
			GameObject? AttackOrDefault(GameObjectProxy? attack, GameObject? _default)
			{
				if (attack == null)
				{
					if (Object.op_Implicit((Object)(object)_default))
					{
						GameObject obj3 = Object.Instantiate<GameObject>(_default, root.transform);
						((Object)obj3).name = ((Object)obj3).name.Replace("(Clone)", "");
						return obj3;
					}
					return null;
				}
				return attack.CreateGameObject(root, hc);
			}
			GameObject? DashAttackOrDefault(GameObjectProxy? attack, GameObject? _default)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected O, but got Unknown
				//IL_0034: 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_0049: Unknown result type (might be due to invalid IL or missing references)
				if (attack == null)
				{
					if (!Object.op_Implicit((Object)(object)_default))
					{
						return null;
					}
					GameObject val = new GameObject("Dash Stab Parent");
					val.transform.parent = root.transform;
					val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
					val.transform.localScale = Vector3.one;
					GameObject obj2 = Object.Instantiate<GameObject>(_default, val.transform);
					((Object)obj2).name = ((Object)obj2).name.Replace("(Clone)", "");
					return val;
				}
				return attack.CreateGameObject(root, hc);
			}
		}

		private static bool TryFindDefaultMovesets()
		{
			HeroController instance = HeroController.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return false;
			}
			if (hunter == null || !Object.op_Implicit((Object)(object)hunter.Config) || !Object.op_Implicit((Object)(object)hunter.NormalSlashObject))
			{
				hunter = instance.configs.First((ConfigGroup c) => ((Object)c.Config).name == "Default");
			}
			return true;
		}
	}
	public class ToolMaker
	{
		public static Data CreateDefaultData()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Data result = default(Data);
			result.IsUnlocked = true;
			result.IsHidden = false;
			result.HasBeenSeen = true;
			result.HasBeenSelected = true;
			result.AmountLeft = 0;
			return result;
		}

		public static Data CreateDefaultLiquidsData()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Data result = default(Data);
			result.RefillsLeft = 20;
			result.SeenEmptyState = true;
			result.UsedExtra = false;
			return result;
		}

		public static ToolItemBasic CreateBasicTool(Sprite? inventorySprite, ToolItemType type, string name, LocalisedString displayName, LocalisedString description)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_00a5: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			ToolItem val = ((NamedScriptableObjectList<ToolItem>)(object)ManagerSingleton<ToolItemManager>.Instance.toolItems)[62];
			ToolItemBasic val2 = ScriptableObject.CreateInstance<ToolItemBasic>();
			((ToolItem)val2).name = name;
			val2.description = description;
			val2.displayName = displayName;
			((ToolItem)val2).type = type;
			((ToolItem)val2).baseStorageAmount = 0;
			val2.inventorySprite = inventorySprite ?? val.GetInventorySprite((IconVariants)0);
			((ToolItem)val2).SavedData = CreateDefaultData();
			PlayerDataTest val3 = new PlayerDataTest();
			val3.TestGroups = (TestGroup[])(object)new TestGroup[1]
			{
				new TestGroup
				{
					Tests = (Test[])(object)new Test[1]
					{
						new Test
						{
							FieldName = NeedleforgePlugin.GetToolDataByName(name).unlockedPDString,
							Type = (TestType)0,
							BoolValue = true
						}
					}
				}
			};
			((ToolItem)val2).alternateUnlockedTest = val3;
			AddCustomTool((ToolItem)(object)val2);
			return val2;
		}

		public static void AddCustomTool(ToolItem toolItem)
		{
			((NamedScriptableObjectList<ToolItem>)(object)ManagerSingleton<ToolItemManager>.Instance.toolItems).Add(toolItem);
			NeedleforgePlugin.newTools.Add(toolItem);
		}

		public static ToolItemStatesLiquid CreateLiquidTool(string name, int storageAmount, int maxRefills, Color fluidColor, string infiniteRefillsPD, ReplenishResources resource, ReplenishUsages replenishUsage, float replenishMult, StateSprites? full, StateSprites? empty, LocalisedString displayName, LocalisedString description)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			ToolItemStatesLiquid val = (ToolItemStatesLiquid)((NamedScriptableObjectList<ToolItem>)(object)ManagerSingleton<ToolItemManager>.Instance.toolItems)[26];
			ToolItemStatesLiquid obj = ScriptableObject.CreateInstance<ToolItemStatesLiquid>();
			((ToolItem)obj).name = name;
			obj.liquidColor = fluidColor;
			obj.refillsMax = maxRefills;
			((ToolItem)obj).baseStorageAmount = storageAmount;
			obj.infiniteRefillsBool = infiniteRefillsPD;
			((ToolItemStates)obj).hasUsableEmptyState = fa