Decompiled source of DebugMenu v1.4.0

DebugMenu.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DebugMenu.Scripts.Act1;
using DebugMenu.Scripts.Act2;
using DebugMenu.Scripts.Act3;
using DebugMenu.Scripts.Acts;
using DebugMenu.Scripts.All;
using DebugMenu.Scripts.Grimora;
using DebugMenu.Scripts.Hotkeys;
using DebugMenu.Scripts.Magnificus;
using DebugMenu.Scripts.Popups;
using DebugMenu.Scripts.Popups.DeckEditorPopup;
using DebugMenu.Scripts.Sequences;
using DebugMenu.Scripts.Utils;
using DiskCardGame;
using GBC;
using GrimoraMod;
using GrimoraMod.Saving;
using HarmonyLib;
using Infiniscryption.P03KayceeRun.Patchers;
using InscryptionAPI.Card;
using InscryptionAPI.CardCosts;
using InscryptionAPI.Dialogue;
using InscryptionAPI.Encounters;
using InscryptionAPI.Helpers;
using InscryptionAPI.Helpers.Extensions;
using InscryptionAPI.Nodes;
using InscryptionAPI.Regions;
using InscryptionAPI.Saves;
using InscryptionAPI.Slots;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("DebugMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("DebugMenu")]
[assembly: AssemblyTitle("DebugMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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;
		}
	}
}
public class WindowBlocker : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
	public bool isHovered;

	public RectTransform RectTransform;

	private void Awake()
	{
		RectTransform = ((Component)this).GetComponent<RectTransform>();
	}

	private void OnDisable()
	{
		if (isHovered)
		{
			OnPointerExit(null);
		}
	}

	public void OnPointerEnter(PointerEventData eventData)
	{
		isHovered = true;
	}

	public void OnPointerExit(PointerEventData eventData)
	{
		isHovered = false;
	}
}
namespace DebugMenu
{
	public static class Configs
	{
		public enum WindowSizes
		{
			OneQuarter,
			Half,
			ThreeQuarters,
			Default,
			OneAndAQuarter,
			OneAndAHalf,
			OneAndThreeQuarters,
			Double
		}

		public static ConfigEntry<bool> m_disableDialogue = Bind("General", "Disable Dialogue", defaultValue: false, "Should all dialogue be disabled?");

		public static ConfigEntry<bool> m_disablePlayerDamage = Bind("General", "Disable Player Damage", defaultValue: false, "Should the player be immune to direct damage?");

		public static ConfigEntry<bool> m_disableOpponentDamage = Bind("General", "Disable Opponent Damage", defaultValue: false, "Should the opponent be immune to direct damage?");

		public static ConfigEntry<WindowSizes> m_windowSize = Bind("General", "Window Scale", WindowSizes.Default, "How big the menu windows should be.");

		public static ConfigEntry<string> m_hotkeys = Bind("General", "Hotkeys", "F1:AllAct SetTimeScale:1,LeftControl+F1:AllAct SetTimeScale:10,LeftShift+F1:AllAct SetTimeScale:0.1,BackQuote:Debug Menu Show/Hide,F5:AllAct Reload,F9:AllAct Restart,F4:Map ToggleSkipNextNode,F3:Map ToggleAllNodes,F2:Battle DrawCard,LeftShift+F2:Battle DrawSideDeck", "Quick access buttons to control the debug menu. Use the in-game menu to change them");

		public static ConfigEntry<bool> m_showDebugMenu = Bind("General", "Show Debug Menu", defaultValue: true, "Should the in-game debug menu window be shown?");

		public static ConfigEntry<bool> m_verticalItems = Bind("General", "Display Items Vertically", defaultValue: false, "Should the items be displayed on vertically?");

		public static ConfigEntry<bool> m_instantScales = Bind("General", "Instant Scales", defaultValue: false, "Makes the debug menu deal scale damage instantly instead of one at a time.");

		public static ConfigEntry<bool> m_hideGuids = Bind("General.Sequences", "Hide Mod GUIDs", defaultValue: false, "Should Mod GUIDs be hidden in the Trigger Sequence menu?");

		public static ConfigEntry<bool> m_showAllSeqs = Bind("General.Sequences", "Show All Sequences", defaultValue: true, "Should all sequences be shown in the Trigger Sequence menu?");

		public static bool DisableDialogue
		{
			get
			{
				return m_disableDialogue.Value;
			}
			set
			{
				m_disableDialogue.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool DisablePlayerDamage
		{
			get
			{
				return m_disablePlayerDamage.Value;
			}
			set
			{
				m_disablePlayerDamage.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool DisableOpponentDamage
		{
			get
			{
				return m_disableOpponentDamage.Value;
			}
			set
			{
				m_disableOpponentDamage.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static string Hotkeys
		{
			get
			{
				return m_hotkeys.Value;
			}
			set
			{
				m_hotkeys.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool ShowDebugMenu
		{
			get
			{
				return m_showDebugMenu.Value;
			}
			set
			{
				m_showDebugMenu.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool VerticalItems
		{
			get
			{
				return m_verticalItems.Value;
			}
			set
			{
				m_verticalItems.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static WindowSizes WindowSize
		{
			get
			{
				return m_windowSize.Value;
			}
			set
			{
				m_windowSize.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool InstantScales
		{
			get
			{
				return m_instantScales.Value;
			}
			set
			{
				m_instantScales.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool HideModGUIDs
		{
			get
			{
				return m_hideGuids.Value;
			}
			set
			{
				m_hideGuids.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		public static bool ShowAllSequences
		{
			get
			{
				return m_showAllSeqs.Value;
			}
			set
			{
				m_showAllSeqs.Value = value;
				((BaseUnityPlugin)Plugin.Instance).Config.Save();
			}
		}

		private static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return ((BaseUnityPlugin)Plugin.Instance).Config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[HarmonyPatch(typeof(SpecialNodeHandler), "StartSpecialNodeSequence", new Type[] { typeof(SpecialNodeData) })]
	internal class SpecialNodeHandler_StartSpecialNodeSequence
	{
		private static bool Prefix(SpecialNodeData nodeData)
		{
			Helpers.LastSpecialNodeData = nodeData;
			return true;
		}
	}
	[HarmonyPatch(typeof(DisclaimerScreen), "BetaScreensSequence")]
	internal class Skip_Disclaimer
	{
		[HarmonyPrefix]
		private static bool SkipDisclaimerPrefix()
		{
			return false;
		}

		[HarmonyPostfix]
		private static IEnumerator SkipDisclaimerPostfix(IEnumerator previous, string ___nextSceneName)
		{
			yield return (object)new WaitForSeconds(0f);
			SceneLoader.Load(___nextSceneName);
		}
	}
	[HarmonyPatch(typeof(AscensionSaveData), "NewRun")]
	internal class SaveCardList
	{
		[HarmonyPrefix]
		private static bool SaveCardListPrefix(List<CardInfo> starterDeck)
		{
			if (P03ModHelper.Enabled && P03ModHelper.IsP03Run)
			{
				Act3.lastUsedStarterDeck = starterDeck;
			}
			else if (GrimoraModHelper.Enabled && SaveFile.IsAscension)
			{
				ActGrimora.lastUsedStarterDeck = starterDeck;
			}
			else
			{
				Act1.lastUsedStarterDeck = starterDeck;
			}
			Plugin.Log.LogInfo((object)("New starter deck with " + starterDeck.Count + " cards!"));
			return true;
		}

		[HarmonyPostfix]
		private static void SaveCardListPostfix()
		{
		}
	}
	[HarmonyPatch(typeof(MapNodeManager), "DoMoveToNewNode")]
	internal class MoveToNode_Debug
	{
		[HarmonyPrefix]
		private static bool MoveToNodePrefix()
		{
			return false;
		}

		[HarmonyPostfix]
		private static IEnumerator MoveToNodePostfix(IEnumerator previous, MapNodeManager __instance, int ___transitioningGridY, MapNode newNode)
		{
			__instance.MovingNodes = true;
			__instance.SetAllNodesInteractable(false);
			___transitioningGridY = newNode.Data.gridY;
			Singleton<ViewManager>.Instance.Controller.LockState = (ViewLockState)1;
			yield return ((AnimatedGameMapMarker)PlayerMarker.Instance).MoveToPoint(((Component)newNode).transform.position, true);
			if (Act1.SkipNextNode)
			{
				__instance.MovingNodes = false;
				RunState.Run.currentNodeId = newNode.nodeId;
				Singleton<GameFlowManager>.Instance.TransitionToGameState((GameState)1, (NodeData)null);
				yield break;
			}
			yield return newNode.OnArriveAtNode();
			Singleton<ViewManager>.Instance.Controller.LockState = (ViewLockState)0;
			__instance.MovingNodes = false;
			CustomCoroutine.WaitOnConditionThenExecute((Func<bool>)(() => !Singleton<GameFlowManager>.Instance.Transitioning), (Action)delegate
			{
				RunState.Run.currentNodeId = newNode.nodeId;
			});
		}
	}
	[HarmonyPatch(typeof(MapNode), "SetActive", new Type[] { typeof(bool) })]
	internal class MapNode_SetActive
	{
		[HarmonyPostfix]
		private static bool Prefix(MapNode __instance, ref bool active)
		{
			if (Act1.ActivateAllMapNodesActive)
			{
				active = true;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class InputButtons_Buttons
	{
		public static IEnumerable<MethodBase> TargetMethods()
		{
			Type inputButtons = typeof(InputButtons);
			yield return AccessTools.Method(inputButtons, "GetButton", (Type[])null, (Type[])null);
			yield return AccessTools.Method(inputButtons, "GetButtonDown", (Type[])null, (Type[])null);
			yield return AccessTools.Method(inputButtons, "GetButtonUp", (Type[])null, (Type[])null);
			yield return AccessTools.Method(inputButtons, "GetButtonRepeating", (Type[])null, (Type[])null);
			yield return AccessTools.Method(inputButtons, "AnyGamepadButton", (Type[])null, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix(ref bool __result)
		{
			if (AllActs.IsInputBlocked())
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch]
	internal class InputButtons_Axis
	{
		public static IEnumerable<MethodBase> TargetMethods()
		{
			Type typeFromHandle = typeof(InputButtons);
			yield return AccessTools.Method(typeFromHandle, "GetAxis", (Type[])null, (Type[])null);
		}

		[HarmonyPostfix]
		private static void Postfix(ref float __result)
		{
			if (AllActs.IsInputBlocked())
			{
				__result = 0f;
			}
		}
	}
	[HarmonyPatch(typeof(RegionManager), "GetAllRegionsForMapGeneration")]
	internal class RegionManager_GetRandomRegionFromTier
	{
		[HarmonyPostfix]
		private static bool Prefix(ref List<RegionData> __result)
		{
			if (Act1MapSequence.RegionOverride)
			{
				RegionData val = RegionManager.AllRegionsCopy.Find((RegionData a) => ((Object)a).name == Act1MapSequence.RegionNameOverride);
				if (!((Object)(object)val == (Object)null))
				{
					__result = new List<RegionData> { val };
					return false;
				}
				Plugin.Log.LogInfo((object)("Could not override region. Not found using name '" + Act1MapSequence.RegionNameOverride + "'"));
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(MapNodeManager), "GetNodeWithId", new Type[] { typeof(int) })]
	internal class MapNodeManager_GetNodeWithId
	{
		[HarmonyPrefix]
		private static bool MoveToNodePrefix(MapNodeManager __instance, ref MapNode __result, int id)
		{
			__result = __instance.nodes.Find((MapNode x) => (Object)(object)x != (Object)null && x.nodeId == id);
			return false;
		}
	}
	[HarmonyPatch]
	internal class DisableDialogue_IEnumerator_Patch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(TextDisplayer), "PlayDialogueEvent", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(TextDisplayer), "ShowUntilInput", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(TextDisplayer), "ShowThenClear", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(CardSingleChoicesSequencer), "TutorialTextSequence", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(GainConsumablesSequencer), "LearnObjectSequence", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(DialogueHandler), "PlayDialogueEvent", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(TextBox), "ShowUntilInput", (Type[])null, (Type[])null);
		}

		private static IEnumerator Postfix(IEnumerator enumerator)
		{
			if (Configs.DisableDialogue)
			{
				Singleton<InteractionCursor>.Instance.InteractionDisabled = false;
			}
			else
			{
				yield return enumerator;
			}
		}
	}
	[HarmonyPatch]
	internal class DisablePlayerDamagePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(LifeManager), "ShowDamageSequence")]
		private static IEnumerator PlayersReceiveNoDamage(IEnumerator enumerator, bool toPlayer)
		{
			if (!(Configs.DisablePlayerDamage && toPlayer) && (!Configs.DisableOpponentDamage || toPlayer))
			{
				yield return enumerator;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MagnificusLifeManager), "ShowLifeLoss")]
		private static IEnumerator PlayersReceiveNoDamageMagnificus(IEnumerator enumerator, bool player)
		{
			if (!(Configs.DisablePlayerDamage && player) && (!Configs.DisableOpponentDamage || player))
			{
				yield return enumerator;
			}
		}
	}
	[HarmonyPatch]
	internal class DisableDialogue_Patch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(TextDisplayer), "ShowMessage", (Type[])null, (Type[])null);
		}

		private static bool Prefix()
		{
			return !Configs.DisableDialogue;
		}
	}
	[HarmonyPatch]
	internal class EmissionAndPortraitPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardDisplayer3D), "EmissionEnabledForCard")]
		private static void ForceEmission(CardRenderInfo renderInfo, PlayableCard playableCard, ref bool __result)
		{
			if (renderInfo.baseInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.EmissionMod) || ((Object)(object)playableCard != (Object)null && playableCard.temporaryMods.Exists((CardModificationInfo x) => x.fromCardMerge)))
			{
				__result = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardDisplayer), "DisplayInfo")]
		private static void ForceAlternatePortrait(CardDisplayer __instance, CardRenderInfo renderInfo)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)renderInfo?.baseInfo == (Object)null))
			{
				List<CardModificationInfo> mods = renderInfo.baseInfo.Mods;
				if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.PortraitMod))
				{
					__instance.SetPortrait(SaveManager.SaveFile.IsPart2 ? CardManager.PixelAlternatePortrait(renderInfo.baseInfo) : renderInfo.baseInfo.alternatePortrait);
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.ShieldPortraitMod))
				{
					__instance.SetPortrait(SaveManager.SaveFile.IsPart2 ? CardManager.PixelBrokenShieldPortrait(renderInfo.baseInfo) : CardManager.BrokenShieldPortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.SacrificePortraitMod))
				{
					__instance.SetPortrait(SaveManager.SaveFile.IsPart2 ? CardManager.PixelSacrificablePortrait(renderInfo.baseInfo) : CardManager.SacrificablePortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.TrapPortraitMod))
				{
					__instance.SetPortrait(SaveManager.SaveFile.IsPart2 ? CardManager.PixelSteelTrapPortrait(renderInfo.baseInfo) : CardManager.SteelTrapPortrait(renderInfo.baseInfo));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PixelCardDisplayer), "DisplayInfo")]
		private static void ForcePixelAlternatePortrait(PixelCardDisplayer __instance, CardRenderInfo renderInfo)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)renderInfo?.baseInfo == (Object)null))
			{
				List<CardModificationInfo> mods = renderInfo.baseInfo.Mods;
				if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.PortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.PixelAlternatePortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.ShieldPortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.PixelBrokenShieldPortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.SacrificePortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.PixelSacrificablePortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.TrapPortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.PixelSteelTrapPortrait(renderInfo.baseInfo));
				}
			}
		}
	}
	[BepInPlugin("jamesgames.inscryption.debugmenu", "Debug Menu", "1.4.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "jamesgames.inscryption.debugmenu";

		public const string PluginName = "Debug Menu";

		public const string PluginVersion = "1.4.0";

		public static Plugin Instance;

		public static ManualLogSource Log;

		public static HotkeyController Hotkeys;

		internal static Harmony HarmonyInstance;

		public static string PluginDirectory;

		public static float StartingFixedDeltaTime;

		public static List<BaseWindow> AllWindows = new List<BaseWindow>();

		private GameObject blockerParent;

		private Canvas blockerParentCanvas;

		private List<WindowBlocker> activeRectTransforms = new List<WindowBlocker>();

		private List<WindowBlocker> rectTransformPool = new List<WindowBlocker>();

		private void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//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_0073: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			StartingFixedDeltaTime = Time.fixedDeltaTime;
			Hotkeys = new HotkeyController();
			HarmonyInstance = new Harmony("jamesgames.inscryption.debugmenu");
			PluginDirectory = ((BaseUnityPlugin)this).Info.Location.Replace("DebugMenu.dll", "");
			blockerParent = new GameObject("DebugMenuBlocker")
			{
				layer = LayerMask.NameToLayer("UI")
			};
			blockerParentCanvas = blockerParent.AddComponent<Canvas>();
			blockerParentCanvas.renderMode = (RenderMode)0;
			blockerParentCanvas.sortingOrder = 32767;
			blockerParent.AddComponent<CanvasScaler>();
			blockerParent.AddComponent<GraphicRaycaster>();
			Object.DontDestroyOnLoad((Object)(object)blockerParent);
			GrimoraModHelper._enabled = Chainloader.PluginInfos.ContainsKey("arackulele.inscryption.grimoramod");
			P03ModHelper._enabled = Chainloader.PluginInfos.ContainsKey("zorro.inscryption.infiniscryption.p03kayceerun");
			HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
			if (GrimoraModHelper.Enabled)
			{
				Log.LogDebug((object)"Patching Grimora Mod");
				GrimoraModHelper.PatchGrimoraMod();
			}
			if (P03ModHelper.Enabled)
			{
				Log.LogDebug((object)"Patching P03 Kaycee's Mod");
				P03ModHelper.PatchP03Mod();
			}
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (type.IsSubclassOf(typeof(BaseWindow)) && !type.IsAbstract)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)$"Made {type}!");
					AllWindows.Add((BaseWindow)Activator.CreateInstance(type));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Debug Menu!");
		}

		private void Update()
		{
			if (Configs.ShowDebugMenu)
			{
				for (int i = 0; i < AllWindows.Count; i++)
				{
					if (AllWindows[i].IsActive)
					{
						AllWindows[i].Update();
					}
				}
			}
			Hotkeys.Update();
		}

		private void OnGUI()
		{
			if (!Configs.ShowDebugMenu)
			{
				return;
			}
			for (int i = 0; i < AllWindows.Count; i++)
			{
				if (AllWindows[i].IsActive)
				{
					AllWindows[i].OnWindowGUI();
				}
			}
		}

		public T ToggleWindow<T>() where T : BaseWindow, new()
		{
			return (T)ToggleWindow(typeof(T));
		}

		public BaseWindow ToggleWindow(Type t)
		{
			for (int i = 0; i < AllWindows.Count; i++)
			{
				BaseWindow baseWindow = AllWindows[i];
				if (baseWindow.GetType() == t)
				{
					baseWindow.IsActive = !baseWindow.IsActive;
					return baseWindow;
				}
			}
			return null;
		}

		public T GetWindow<T>() where T : BaseWindow, new()
		{
			return (T)GetWindow(typeof(T));
		}

		public BaseWindow GetWindow(Type t)
		{
			for (int i = 0; i < AllWindows.Count; i++)
			{
				BaseWindow baseWindow = AllWindows[i];
				if (baseWindow.GetType() == t)
				{
					return baseWindow;
				}
			}
			return null;
		}

		public WindowBlocker CreateWindowBlocker()
		{
			//IL_0025: 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_0040: 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_0056: 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_0068: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("WindowBlocker", new Type[2]
			{
				typeof(RectTransform),
				typeof(WindowBlocker)
			});
			val.transform.SetParent(blockerParent.transform);
			val.layer = LayerMask.NameToLayer("UI");
			Image obj = val.AddComponent<Image>();
			Color magenta = Color.magenta;
			magenta.a = 0f;
			((Graphic)obj).color = magenta;
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2((float)(Screen.width / 4), (float)(Screen.height / 4));
			component.anchoredPosition = Vector2.zero;
			component.pivot = new Vector2(0f, 1f);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.zero;
			WindowBlocker component2 = val.GetComponent<WindowBlocker>();
			activeRectTransforms.Add(component2);
			return component2;
		}

		public bool IsInputBlocked()
		{
			if (!Configs.ShowDebugMenu)
			{
				return false;
			}
			foreach (WindowBlocker activeRectTransform in activeRectTransforms)
			{
				if (activeRectTransform.isHovered)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace DebugMenu.Scripts
{
	public abstract class DrawableGUI
	{
		public struct ButtonDisabledData
		{
			public bool Disabled;

			public string Reason;

			public ButtonDisabledData(string reason)
			{
				Disabled = true;
				Reason = reason;
			}

			public ButtonDisabledData(Func<bool> func)
			{
				Reason = null;
				Disabled = func();
			}
		}

		public struct LayoutScope : IDisposable
		{
			private readonly float originalX;

			private readonly Vector2 currentSize;

			private readonly int totalElements;

			private readonly bool horizontal;

			private readonly DrawableGUI scope;

			public readonly bool Horizontal => horizontal;

			public readonly int TotalElements => totalElements;

			public readonly Vector2 CurrentSize => currentSize;

			public LayoutScope(int totalElements, bool horizontal, DrawableGUI scope)
			{
				//IL_002c: 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)
				originalX = scope.X;
				this.totalElements = totalElements;
				this.horizontal = horizontal;
				this.scope = scope;
				currentSize = new Vector2(0f, 0f);
				scope.m_layoutScopes.Add(this);
			}

			public void Dispose()
			{
				scope.m_layoutScopes.Remove(this);
				if (horizontal)
				{
					scope.X = originalX;
					scope.Y += scope.RowHeight;
				}
			}
		}

		private const float TopOffset = 20f;

		private float X;

		private float Y;

		protected float ColumnWidth = 200f;

		protected float RowHeight = 40f;

		protected float ColumnPadding = 5f;

		private int Columns = 1;

		private float MaxHeight = 1f;

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

		private readonly List<LayoutScope> m_layoutScopes = new List<LayoutScope>();

		public GUIStyle LabelHeaderStyle = GUIStyle.none;

		public GUIStyle LabelHeaderStyleLeft = GUIStyle.none;

		public GUIStyle LabelBoldStyle = GUIStyle.none;

		public GUIStyle ButtonStyle = GUIStyle.none;

		public GUIStyle ButtonDisabledStyle = GUIStyle.none;

		public float TotalWidth => (float)Columns * ColumnWidth + (float)(Columns - 1) * ColumnPadding;

		public float Height => MaxHeight + RowHeight;

		internal static float GetDisplayScalar()
		{
			return Configs.WindowSize switch
			{
				Configs.WindowSizes.OneQuarter => 0.25f, 
				Configs.WindowSizes.Half => 0.5f, 
				Configs.WindowSizes.ThreeQuarters => 0.75f, 
				Configs.WindowSizes.OneAndAQuarter => 1.25f, 
				Configs.WindowSizes.OneAndAHalf => 1.5f, 
				Configs.WindowSizes.OneAndThreeQuarters => 1.75f, 
				Configs.WindowSizes.Double => 2f, 
				_ => 1f, 
			};
		}

		public virtual void OnGUI()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0036: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			LabelHeaderStyleLeft = Helpers.HeaderLabelStyle();
			LabelHeaderStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = 17,
				alignment = (TextAnchor)4,
				fontStyle = (FontStyle)1
			};
			LabelBoldStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1
			};
			ButtonStyle = new GUIStyle(GUI.skin.button)
			{
				wordWrap = true
			};
			ButtonDisabledStyle = Helpers.DisabledButtonStyle();
			Reset();
		}

		public virtual void Reset()
		{
			X = ColumnPadding;
			Y = 20f;
			MaxHeight = 0f;
			Columns = 0;
		}

		public virtual void StartNewColumn(float? padding = null)
		{
			X += ColumnWidth + (padding ?? ColumnPadding);
			Y = 20f;
			Columns++;
		}

		public virtual bool Button(string text, Vector2? size = null, string buttonGroup = null, Func<ButtonDisabledData> disabled = null)
		{
			//IL_00ab: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			(float X, float y, float w, float h) position = GetPosition(size);
			float item = position.X;
			float item2 = position.y;
			float item3 = position.w;
			float item4 = position.h;
			GUIStyle val = ButtonStyle;
			bool flag = false;
			ButtonDisabledData buttonDisabledData = disabled?.Invoke() ?? default(ButtonDisabledData);
			if (buttonDisabledData.Disabled)
			{
				if (!string.IsNullOrEmpty(buttonDisabledData.Reason))
				{
					GUI.Label(new Rect(item, item2, item3, item4), text + "\n(" + buttonDisabledData.Reason + ")", ButtonDisabledStyle);
				}
				else
				{
					GUI.Label(new Rect(item, item2, item3, item4), text, ButtonDisabledStyle);
				}
			}
			else if (buttonGroup == null)
			{
				flag = GUI.Button(new Rect(item, item2, item3, item4), text, ButtonStyle);
			}
			else
			{
				if (!m_buttonGroups.TryGetValue(buttonGroup, out var value))
				{
					m_buttonGroups[buttonGroup] = text;
				}
				if (value == text)
				{
					val = ButtonDisabledStyle;
				}
				flag = GUI.Button(new Rect(item, item2, item3, item4), text, val);
				if (flag)
				{
					m_buttonGroups[buttonGroup] = text;
				}
			}
			return flag;
		}

		public virtual bool Toggle(string text, ref bool value, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			(float X, float y, float w, float h) position = GetPosition(size);
			float item = position.X;
			float item2 = position.y;
			float item3 = position.w;
			float item4 = position.h;
			bool flag = GUI.Toggle(new Rect(item, item2, item3, item4), value, text);
			if (flag != value)
			{
				value = flag;
				return true;
			}
			return false;
		}

		public virtual bool Toggle(string text, ref ConfigEntry<bool> value, Vector2? size = null)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			(float X, float y, float w, float h) position = GetPosition(size);
			float item = position.X;
			float item2 = position.y;
			float item3 = position.w;
			float item4 = position.h;
			bool value2 = value.Value;
			bool flag = GUI.Toggle(new Rect(item, item2, item3, item4), value2, text);
			if (flag != value2)
			{
				value.Value = flag;
				return true;
			}
			return false;
		}

		public virtual void Label(string text, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			GUI.Label(new Rect(num, num2, num3, num4), text);
		}

		public virtual void LabelHeader(string text, Vector2? size = null, bool leftAligned = false)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			GUI.Label(new Rect(num, num2, num3, num4), text, leftAligned ? LabelHeaderStyleLeft : LabelHeaderStyle);
		}

		public virtual void LabelBold(string text, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			GUI.Label(new Rect(num, num2, num3, num4), text, LabelBoldStyle);
		}

		public virtual object InputField(object value, Type type, Vector2? size = null)
		{
			if (type == typeof(int))
			{
				return IntField((int)value, size);
			}
			if (type == typeof(float))
			{
				return FloatField((float)value, size);
			}
			if (type == typeof(string))
			{
				return TextField((string)value, size);
			}
			if (type == typeof(string))
			{
				bool value2 = (bool)value;
				Toggle("", ref value2, size);
				return value2;
			}
			Label("Unsupported type: " + type);
			return value;
		}

		public virtual string TextField(string text, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			return GUI.TextField(new Rect(num, num2, num3, num4), text);
		}

		public virtual int IntField(int text, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			if (!int.TryParse(GUI.TextField(new Rect(num, num2, num3, num4), text.ToString()), out var result))
			{
				return text;
			}
			return result;
		}

		public virtual float FloatField(float text, Vector2? size = null)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			var (num, num2, num3, num4) = GetPosition(size);
			if (!float.TryParse(GUI.TextField(new Rect(num, num2, num3, num4), text.ToString()), out var result))
			{
				return text;
			}
			return result;
		}

		public virtual void Padding(Vector2? size = null)
		{
			//IL_000b: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			float num = ((size.HasValue && size.Value.x != 0f) ? size.Value.x : ColumnWidth);
			float num2 = ((size.HasValue && size.Value.y != 0f) ? size.Value.y : RowHeight);
			float y = Y;
			Y += num2;
			MaxHeight = Mathf.Max(MaxHeight, Y);
			GUI.Label(new Rect(X, y, num, num2), "");
		}

		public (float X, float y, float w, float h) GetPosition(Vector2? size = null)
		{
			//IL_0018: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			float x = X;
			float y = Y;
			float num = ((size.HasValue && size.Value.y != 0f) ? size.Value.y : RowHeight);
			float num2 = ((size.HasValue && size.Value.x != 0f) ? size.Value.x : ColumnWidth);
			if (m_layoutScopes.Count == 0 || !m_layoutScopes[m_layoutScopes.Count - 1].Horizontal)
			{
				Y += num;
			}
			else
			{
				if (!size.HasValue)
				{
					num2 = ColumnWidth / (float)m_layoutScopes[m_layoutScopes.Count - 1].TotalElements;
				}
				X += num2;
			}
			MaxHeight = Mathf.Max(MaxHeight, Y);
			return (x, y, num2, num);
		}

		public IDisposable HorizontalScope(int elementCount)
		{
			return new LayoutScope(elementCount, horizontal: true, this);
		}

		public IDisposable VerticalScope(int elementCount)
		{
			return new LayoutScope(elementCount, horizontal: false, this);
		}
	}
}
namespace DebugMenu.Scripts.Sequences
{
	public abstract class BaseTriggerSequence
	{
		public abstract string SequenceName { get; }

		public string ModGUID { get; set; }

		public string ButtonName
		{
			get
			{
				if (ModGUID == null)
				{
					return SequenceName;
				}
				return SequenceName + "\n" + ModGUID;
			}
		}

		public abstract void Sequence();
	}
	public abstract class SimpleTriggerSequences : BaseTriggerSequence
	{
		public abstract NodeData NodeData { get; }

		public abstract Type NodeDataType { get; }

		public virtual GameState GameState => (GameState)3;

		public override void Sequence()
		{
			((MonoBehaviour)Plugin.Instance).StartCoroutine(SequenceCoroutine());
		}

		public virtual IEnumerator SequenceCoroutine()
		{
			Singleton<GameFlowManager>.Instance.TransitionToGameState(GameState, NodeData);
			yield return null;
		}
	}
	public class APIModdedSequence : BaseTriggerSequence
	{
		public FullNode CustomNodeData;

		public override string SequenceName => CustomNodeData.name;

		public override void Sequence()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			CustomSpecialNodeData val = new CustomSpecialNodeData(CustomNodeData);
			Singleton<GameFlowManager>.Instance.TransitionToGameState((GameState)3, (NodeData)(object)val);
		}
	}
	public class SimpleStubSequence : SimpleTriggerSequences
	{
		public Type type;

		public GameState gameState;

		public override string SequenceName
		{
			get
			{
				string text = NodeDataType.Name.Replace("NodeData", "");
				for (int i = 1; i < text.Length; i++)
				{
					if (char.IsUpper(text[i]))
					{
						text = text.Insert(i, " ");
						i++;
					}
				}
				return text;
			}
		}

		public override NodeData NodeData => (NodeData)Activator.CreateInstance(NodeDataType);

		public override Type NodeDataType => type;

		public override GameState GameState => gameState;
	}
	public class BossSequence : SimpleTriggerSequences
	{
		public override string SequenceName => "Boss Battle";

		public override NodeData NodeData => null;

		public override Type NodeDataType => typeof(BossBattleNodeData);

		public override void Sequence()
		{
			Plugin.Instance.ToggleWindow<TriggerCardBattleSequenceWindow>().SelectedBattleType = TriggerCardBattleSequenceWindow.BattleType.BossBattle;
		}
	}
	public class CardBattleSequence : SimpleTriggerSequences
	{
		public override string SequenceName => "Card Battle";

		public override NodeData NodeData => null;

		public override Type NodeDataType => typeof(CardBattleNodeData);

		public override void Sequence()
		{
			Plugin.Instance.ToggleWindow<TriggerCardBattleSequenceWindow>().SelectedBattleType = TriggerCardBattleSequenceWindow.BattleType.CardBattle;
		}
	}
	public class TotemBattleSequence : SimpleTriggerSequences
	{
		public override string SequenceName => "Totem Battle";

		public override NodeData NodeData => null;

		public override Type NodeDataType => typeof(TotemBattleNodeData);

		public override void Sequence()
		{
			Plugin.Instance.ToggleWindow<TriggerCardBattleSequenceWindow>().SelectedBattleType = TriggerCardBattleSequenceWindow.BattleType.TotemBattle;
		}
	}
	public abstract class ThreeCardChoiceSequences : SimpleTriggerSequences
	{
		public abstract CardChoicesType ChoiceType { get; }

		public override string SequenceName => $"3 {ChoiceType} Choice";

		public override Type NodeDataType => typeof(CardChoicesNodeData);

		public override NodeData NodeData => (NodeData)new CardChoicesNodeData
		{
			choicesType = ChoiceType
		};
	}
	public class RandomChoiceSequences : ThreeCardChoiceSequences
	{
		public override CardChoicesType ChoiceType => (CardChoicesType)0;
	}
	public class TribeChoiceSequences : ThreeCardChoiceSequences
	{
		public override CardChoicesType ChoiceType => (CardChoicesType)2;
	}
	public class CostChoiceSequences : ThreeCardChoiceSequences
	{
		public override CardChoicesType ChoiceType => (CardChoicesType)1;
	}
	public class DeathCardChoiceSequences : ThreeCardChoiceSequences
	{
		public override CardChoicesType ChoiceType => (CardChoicesType)3;
	}
}
namespace DebugMenu.Scripts.Utils
{
	public static class DrawCardInfo
	{
		public enum Result
		{
			None,
			Removed,
			Altered
		}

		private enum SigilModType
		{
			None,
			Merge,
			Totem,
			Latch
		}

		private static readonly string[] managementMenuHeaders = new string[2] { "Sigils", "Special Abilities" };

		private static readonly string[] abilityManagementTabs = new string[2] { "Edit", "Add" };

		private static readonly string[] specialManagementTabs = new string[2] { "Remove", "Add" };

		private const float toggleWidth = 100f;

		private const float abilityButtonWidth = 190f;

		private const float abilityButtonHeight = 40f;

		private const int sigilsPerRow = 3;

		private const int sigilsPerPage = 6;

		private static string nameReplacementField = "";

		private static int selectedTab = 0;

		private static int abilityManagerIndex = 0;

		private static string abilitySearch = "";

		private static string abilityGUIDSearch = "";

		private static string specialAbilitySearch = "";

		private static string specialAbilityGUIDSearch = "";

		private static int currentPageEdit = 0;

		private static int currentPageAdd = 0;

		private static int specialAbilitySelector = 0;

		private static Vector2 specialAbilityListVector2 = Vector2.zero;

		private static Vector2 specialAbilityListVector = Vector2.zero;

		private static string boardNameReplacementField = "";

		private static int boardSelectedTab = 0;

		private static int boardAbilityManagerIndex = 0;

		private static string boardAbilitySearch = "";

		private static string boardAbilityGUIDSearch = "";

		private static string boardSpecialAbilitySearch = "";

		private static string boardSpecialAbilityGUIDSearch = "";

		private static int boardCurrentPageEdit = 0;

		private static int boardCurrentPageAdd = 0;

		private static int boardSpecialAbilitySelector = 0;

		private static Vector2 boardSpecialAbilityListVector2 = Vector2.zero;

		private static Vector2 boardSpecialAbilityListVector = Vector2.zero;

		private static bool negateSigil = true;

		private static bool asCardMerge = false;

		private static bool asTotem = false;

		private static bool asLatch = false;

		private static bool boardNegateSigil = true;

		private static bool boardAsCardMerge = false;

		private static bool boardAsTotem = false;

		private static bool boardAsLatch = false;

		public static readonly string EmissionMod = "DebugMenu:EmissionMod";

		public static readonly string PortraitMod = "DebugMenu:PortraitMod";

		public static readonly string ShieldPortraitMod = "DebugMenu:ShieldPortraitMod";

		public static readonly string SacrificePortraitMod = "DebugMenu:SacrificePortraitMod";

		public static readonly string TrapPortraitMod = "DebugMenu:TrapPortraitMod";

		public static readonly string CustomCostMod = "DebugMenu:CustomCostMod";

		public static readonly string NegateDefaultStackMod = "DebugMenu:NegateDefaultStack";

		private static bool HasModFromCardMerge(CardInfo cardInfo, PlayableCard playableCard)
		{
			if (!cardInfo.HasModFromCardMerge())
			{
				if ((Object)(object)playableCard != (Object)null)
				{
					return playableCard.TemporaryMods.Exists((CardModificationInfo x) => x.fromCardMerge);
				}
				return false;
			}
			return true;
		}

		public static Result OnGUI(CardInfo cardInfo, PlayableCard playableCard = null, DeckInfo deckInfo = null)
		{
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			if ((Object)(object)cardInfo == (Object)null)
			{
				return Result.None;
			}
			bool flag = (Object)(object)playableCard != (Object)null;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Card Editor", Helpers.HeaderLabelStyle(), Array.Empty<GUILayoutOption>());
			GUILayout.Label(cardInfo.DisplayedNameLocalized + " (" + ((Object)cardInfo).name + ")", Helpers.HeaderLabelStyle(), Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			if (flag ? HandleNameReplacement(ref boardNameReplacementField, cardInfo, deckInfo) : HandleNameReplacement(ref nameReplacementField, cardInfo, deckInfo))
			{
				return Result.Altered;
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (deckInfo != null)
			{
				if (GUILayout.Button("Duplicate Selected Card", Array.Empty<GUILayoutOption>()))
				{
					object obj = cardInfo.Clone();
					CardInfo val = (CardInfo)((obj is CardInfo) ? obj : null);
					((CardCollectionInfo)deckInfo).AddCard(val);
					if (SaveManager.SaveFile.IsPart2)
					{
						SaveManager.SaveFile.CollectGBCCard(val);
					}
					SaveManager.SaveToFile(false);
					return Result.Altered;
				}
				List<CardInfo> cards = ((CardCollectionInfo)deckInfo).Cards;
				if (cards != null && cards.Count > 2)
				{
					if (GUILayout.Button("Remove Selected Card", Array.Empty<GUILayoutOption>()))
					{
						((CardCollectionInfo)deckInfo).RemoveCard(cardInfo);
						if (SaveManager.SaveFile.IsPart2)
						{
							SaveData.Data.collection.RemoveCardByName(((Object)cardInfo).name);
						}
						SaveManager.SaveToFile(false);
						return Result.Removed;
					}
				}
				else
				{
					GUILayout.Label("Deck too small! Needs at least 2 cards.", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (HasModFromCardMerge(cardInfo, playableCard))
			{
				if (GUILayout.Button("Clear Merge Data", Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.ForEach(delegate(CardModificationInfo x)
					{
						x.fromCardMerge = false;
					});
					if (flag)
					{
						playableCard.TemporaryMods.ForEach(delegate(CardModificationInfo x)
						{
							x.fromCardMerge = false;
						});
					}
					else
					{
						SaveManager.SaveToFile(false);
					}
					return Result.Altered;
				}
			}
			else
			{
				GUILayout.Label("Clear Merge Data", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			if (!SaveManager.SaveFile.IsPart1)
			{
				GUILayout.Label("No Emissions", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			else
			{
				CardModificationInfo val2 = cardInfo.Mods.Find((CardModificationInfo a) => a.singletonId == EmissionMod);
				if (val2 != null)
				{
					if (GUILayout.Button("Unforce Emission", Array.Empty<GUILayoutOption>()))
					{
						cardInfo.Mods.Remove(val2);
						if (deckInfo != null)
						{
							if (deckInfo != null)
							{
								deckInfo.UpdateModDictionary();
							}
							SaveManager.SaveToFile(false);
						}
						return Result.Altered;
					}
				}
				else if (GUILayout.Button("Force Emission", Array.Empty<GUILayoutOption>()))
				{
					CardModificationInfo val3 = new CardModificationInfo
					{
						singletonId = EmissionMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val3);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val3);
					}
					return Result.Altered;
				}
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (HandleForcePortrait(cardInfo, deckInfo))
			{
				return Result.Altered;
			}
			GUILayout.EndHorizontal();
			if (HandleCost(cardInfo, playableCard, deckInfo))
			{
				return Result.Altered;
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DisplayPortraits(cardInfo);
			GUILayout.EndHorizontal();
			if (HandleTribes(cardInfo, playableCard, deckInfo))
			{
				return Result.Altered;
			}
			if (HandleStats(cardInfo, playableCard, deckInfo, flag))
			{
				return Result.Altered;
			}
			int num;
			if (flag)
			{
				boardSelectedTab = GUILayout.Toolbar(boardSelectedTab, managementMenuHeaders, Array.Empty<GUILayoutOption>());
				num = boardSelectedTab;
			}
			else
			{
				selectedTab = GUILayout.Toolbar(selectedTab, managementMenuHeaders, Array.Empty<GUILayoutOption>());
				num = selectedTab;
			}
			if (num == 0)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				int num3;
				if (flag)
				{
					int num2 = boardAbilityManagerIndex;
					num3 = (boardAbilityManagerIndex = GUILayout.Toolbar(num2, abilityManagementTabs, Array.Empty<GUILayoutOption>()));
					if (num3 != num2)
					{
						boardAsCardMerge = (boardAsTotem = (boardAsLatch = false));
					}
				}
				else
				{
					int num2 = abilityManagerIndex;
					num3 = (abilityManagerIndex = GUILayout.Toolbar(num2, abilityManagementTabs, Array.Empty<GUILayoutOption>()));
					if (num3 != num2)
					{
						asCardMerge = (asTotem = (asLatch = false));
					}
				}
				GUILayoutOption val4 = GUILayout.Width(100f);
				if (flag)
				{
					if (num3 == 0)
					{
						bool flag2 = boardNegateSigil;
						boardNegateSigil = GUILayout.Toggle(flag2, flag2 ? "<b>Remove</b>" : "<b>Modify</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
						if (boardNegateSigil != flag2)
						{
							boardAsCardMerge = (boardAsTotem = (boardAsLatch = false));
						}
					}
					else
					{
						GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					}
					boardAsCardMerge = GUILayout.Toggle(boardAsCardMerge, "FromMerge", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					boardAsTotem = GUILayout.Toggle(boardAsTotem, "FromTotem", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					boardAsLatch = GUILayout.Toggle(boardAsLatch, "FromLatch", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
				}
				else
				{
					if (num3 == 0)
					{
						bool flag3 = negateSigil;
						negateSigil = GUILayout.Toggle(flag3, flag3 ? "<b>Remove</b>" : "<b>Modify</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
						if (negateSigil != flag3)
						{
							asCardMerge = (asTotem = (asLatch = false));
						}
					}
					else
					{
						GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					}
					asCardMerge = GUILayout.Toggle(asCardMerge, "FromMerge", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					asTotem = GUILayout.Toggle(asTotem, "FromTotem", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
					asLatch = GUILayout.Toggle(asLatch, "FromLatch", (GUILayoutOption[])(object)new GUILayoutOption[1] { val4 });
				}
				GUILayout.EndHorizontal();
				if (ManageAbilities(cardInfo, playableCard, deckInfo, flag, num3))
				{
					return Result.Altered;
				}
			}
			else
			{
				int num3 = ((!flag) ? (specialAbilitySelector = GUILayout.Toolbar(specialAbilitySelector, specialManagementTabs, Array.Empty<GUILayoutOption>())) : (boardSpecialAbilitySelector = GUILayout.Toolbar(boardSpecialAbilitySelector, specialManagementTabs, Array.Empty<GUILayoutOption>())));
				ManageSpecialAbilities(cardInfo, playableCard, deckInfo, flag, num3);
			}
			return Result.None;
		}

		private static bool HandleNameReplacement(ref string nameReplacementFieldRef, CardInfo cardInfo, DeckInfo deckInfo = null)
		{
			//IL_002b: 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_0039: Expected O, but got Unknown
			bool result = false;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			nameReplacementFieldRef = GUILayout.TextField(nameReplacementFieldRef, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Set Name Replacement", Array.Empty<GUILayoutOption>()))
			{
				CardModificationInfo val = new CardModificationInfo
				{
					nameReplacement = nameReplacementFieldRef
				};
				CardModificationInfo val2 = cardInfo.Mods.Find((CardModificationInfo a) => !Utility.IsNullOrWhiteSpace(a.nameReplacement));
				if (val2 != null)
				{
					cardInfo.Mods.Remove(val2);
				}
				if (deckInfo != null)
				{
					deckInfo.ModifyCard(cardInfo, val);
					SaveManager.SaveToFile(false);
				}
				else
				{
					cardInfo.Mods.Add(val);
				}
				result = true;
			}
			GUILayout.EndHorizontal();
			return result;
		}

		private static bool HandleForcePortrait(CardInfo cardInfo, DeckInfo deckInfo)
		{
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Expected O, but got Unknown
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Expected O, but got Unknown
			if (cardInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod || x.singletonId == TrapPortraitMod))
			{
				if (GUILayout.Button("Reset Portrait", Helpers.EnabledButtonStyle(), Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod || x.singletonId == TrapPortraitMod);
					if (deckInfo != null)
					{
						if (deckInfo != null)
						{
							deckInfo.UpdateModDictionary();
						}
						SaveManager.SaveToFile(false);
					}
					return true;
				}
			}
			else
			{
				GUILayout.Label("Reset Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			bool num = (SaveManager.SaveFile.IsPart2 ? CardExtensions.HasPixelAlternatePortrait(cardInfo) : CardExtensions.HasAlternatePortrait(cardInfo));
			bool flag = (SaveManager.SaveFile.IsPart2 ? CardExtensions.HasPixelBrokenShieldPortrait(cardInfo) : CardExtensions.HasBrokenShieldPortrait(cardInfo));
			bool flag2 = (SaveManager.SaveFile.IsPart2 ? CardExtensions.HasPixelSacrificablePortrait(cardInfo) : CardExtensions.HasSacrificablePortrait(cardInfo));
			bool flag3 = (SaveManager.SaveFile.IsPart2 ? CardExtensions.HasPixelSteelTrapPortrait(cardInfo) : CardExtensions.HasSteelTrapPortrait(cardInfo));
			if (num)
			{
				if (cardInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == PortraitMod))
				{
					GUILayout.Label("Force Alt Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
				else if (GUILayout.Button("Force Alt Portrait", Helpers.EnabledButtonStyle(), Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod || x.singletonId == TrapPortraitMod);
					CardModificationInfo val = new CardModificationInfo
					{
						singletonId = PortraitMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val);
					}
					return true;
				}
			}
			else
			{
				GUILayout.Label("No Alt Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			if (flag)
			{
				if (cardInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == ShieldPortraitMod))
				{
					GUILayout.Label("Force Shield Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
				else if (GUILayout.Button("Force Shield Portrait", Helpers.EnabledButtonStyle(), Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == SacrificePortraitMod || x.singletonId == TrapPortraitMod);
					CardModificationInfo val2 = new CardModificationInfo
					{
						singletonId = ShieldPortraitMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val2);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val2);
					}
					return true;
				}
			}
			else
			{
				GUILayout.Label("No Shield Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			if (flag2)
			{
				if (cardInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == SacrificePortraitMod))
				{
					GUILayout.Label("Force Sacrifice Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
				else if (GUILayout.Button("Force Sacrifice Portrait", Helpers.EnabledButtonStyle(), Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == TrapPortraitMod);
					CardModificationInfo val3 = new CardModificationInfo
					{
						singletonId = SacrificePortraitMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val3);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val3);
					}
					return true;
				}
			}
			else
			{
				GUILayout.Label("No Sacrifice Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			if (flag3)
			{
				if (cardInfo.Mods.Exists((CardModificationInfo x) => x.singletonId == TrapPortraitMod))
				{
					GUILayout.Label("Force Trap Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
				else if (GUILayout.Button("Force Trap Portrait", Helpers.EnabledButtonStyle(), Array.Empty<GUILayoutOption>()))
				{
					cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod);
					CardModificationInfo val4 = new CardModificationInfo
					{
						singletonId = TrapPortraitMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val4);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val4);
					}
					return true;
				}
			}
			else
			{
				GUILayout.Label("No Trap Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			return false;
		}

		private static bool HandleTribes(CardInfo cardInfo, PlayableCard playableCard, DeckInfo deckInfo)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("<b>Tribes:</b> " + string.Join(",", cardInfo.tribes.Select(Helpers.GetTribeName)), Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			return false;
		}

		private static bool DisplayPixelPortraits(CardInfo cardInfo, GUILayoutOption[] options)
		{
			bool result = false;
			Sprite pixelPortrait = cardInfo.pixelPortrait;
			if ((Object)(object)((pixelPortrait != null) ? pixelPortrait.texture : null) != (Object)null)
			{
				result = true;
				GUILayout.Label((Texture)(object)cardInfo.pixelPortrait.texture, options);
			}
			if (CardExtensions.HasPixelAlternatePortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.PixelAlternatePortrait(cardInfo).texture, options);
			}
			if (CardExtensions.HasPixelBrokenShieldPortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.PixelBrokenShieldPortrait(cardInfo).texture, options);
			}
			if (CardExtensions.HasPixelSacrificablePortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.PixelSacrificablePortrait(cardInfo).texture, options);
			}
			if (CardExtensions.HasPixelSteelTrapPortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.PixelSteelTrapPortrait(cardInfo).texture, options);
			}
			return result;
		}

		private static bool DisplayPortraits(CardInfo cardInfo, GUILayoutOption[] options)
		{
			bool result = false;
			Sprite portraitTex = cardInfo.portraitTex;
			if ((Object)(object)((portraitTex != null) ? portraitTex.texture : null) != (Object)null)
			{
				result = true;
				GUILayout.Label((Texture)(object)cardInfo.portraitTex.texture, options);
			}
			if (CardExtensions.HasAlternatePortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)cardInfo.alternatePortrait.texture, options);
			}
			if (CardExtensions.HasBrokenShieldPortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.BrokenShieldPortrait(cardInfo).texture, options);
			}
			if (CardExtensions.HasSacrificablePortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.SacrificablePortrait(cardInfo).texture, options);
			}
			if (CardExtensions.HasSteelTrapPortrait(cardInfo))
			{
				result = true;
				GUILayout.Label((Texture)(object)CardManager.SteelTrapPortrait(cardInfo).texture, options);
			}
			return result;
		}

		private static void DisplayPortraits(CardInfo cardInfo)
		{
			bool flag = Helpers.GetCurrentSavedAct() == Helpers.Acts.Act2;
			GUILayoutOption[] array = (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(114f),
				GUILayout.Height(94f)
			};
			bool flag2;
			bool flag3;
			if (flag)
			{
				flag2 = DisplayPixelPortraits(cardInfo, array);
				flag3 = DisplayPortraits(cardInfo, array);
			}
			else
			{
				flag3 = DisplayPortraits(cardInfo, array);
				flag2 = DisplayPixelPortraits(cardInfo, array);
			}
			if (!flag3 && !flag2)
			{
				GUILayout.Label("No portraits", array);
			}
		}

		private static bool NewCardMod(DeckInfo deckInfo, CardInfo cardInfo, PlayableCard playableCard = null, int attackAdjustment = 0, int healthAdjustment = 0, Ability ability = 0, Ability negateAbility = 0, int bloodCostAdjustment = 0, int boneCostAdjustment = 0, int energyCostAdjustment = 0, SpecialTriggeredAbility specialAbility = 0, SpecialTriggeredAbility removeSpecialAbility = 0, List<GemType> addGemCost = null, List<GemType> removeGemCost = null, string singletonId = null, bool? gemified = null, bool? nullifyGems = null, bool asMerge = false, bool asTotem = false, bool asLatch = false)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_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_005b: Expected O, but got Unknown
			//IL_005b: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			CardModificationInfo val = new CardModificationInfo
			{
				attackAdjustment = attackAdjustment,
				healthAdjustment = healthAdjustment,
				bloodCostAdjustment = bloodCostAdjustment,
				bonesCostAdjustment = boneCostAdjustment,
				energyCostAdjustment = energyCostAdjustment,
				fromCardMerge = asMerge,
				fromTotem = asTotem,
				fromLatch = asLatch,
				singletonId = singletonId
			};
			if ((int)ability != 0)
			{
				val.abilities.Add(ability);
			}
			if ((int)negateAbility != 0)
			{
				val.negateAbilities.Add(negateAbility);
			}
			if (addGemCost != null)
			{
				val.addGemCost = addGemCost;
			}
			if (removeGemCost != null)
			{
				CardModificationInfoExtensions.RemoveGemsCost(val, removeGemCost.ToArray());
			}
			if (nullifyGems.HasValue)
			{
				val.nullifyGemsCost = nullifyGems.Value;
			}
			if (gemified.HasValue)
			{
				val.gemify = gemified.Value;
			}
			if ((int)specialAbility != 0)
			{
				val.specialAbilities.Add(specialAbility);
			}
			if ((int)removeSpecialAbility != 0)
			{
				IEnumerable<CardModificationInfo> mods = cardInfo.Mods;
				if ((Object)(object)playableCard != (Object)null)
				{
					mods.Concat(playableCard.TemporaryMods);
				}
				foreach (CardModificationInfo item in mods)
				{
					if (!item.specialAbilities.Contains(removeSpecialAbility))
					{
						continue;
					}
					item.specialAbilities.Remove(removeSpecialAbility);
					if (Object.op_Implicit((Object)(object)playableCard))
					{
						playableCard.TriggerHandler.specialAbilities.Remove(playableCard.TriggerHandler.specialAbilities.Find((Tuple<SpecialTriggeredAbility, SpecialCardBehaviour> x) => x.Item1 == removeSpecialAbility));
						RemoveSpecialAbility<SpecialCardBehaviour>(((object)(SpecialTriggeredAbility)(ref removeSpecialAbility)).ToString(), ((Component)playableCard).gameObject);
					}
				}
			}
			if ((Object)(object)playableCard != (Object)null)
			{
				playableCard.AddTemporaryMod(val);
				foreach (SpecialTriggeredAbility specialAbility2 in val.specialAbilities)
				{
					SpecialTriggeredAbility current2 = specialAbility2;
					playableCard.TriggerHandler.permanentlyAttachedBehaviours.Add(AddSpecialAbility<SpecialCardBehaviour>(((object)(SpecialTriggeredAbility)(ref current2)).ToString(), ((Component)playableCard).gameObject));
				}
				return false;
			}
			if (deckInfo != null)
			{
				deckInfo.ModifyCard(cardInfo, val);
				SaveManager.SaveToFile(false);
			}
			return true;
		}

		private static bool HandleCost(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo)
		{
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Expected O, but got Unknown
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			int num = (((Object)(object)currentCard != (Object)null) ? CardExtensions.BloodCost(currentCard) : currentCardInfo.BloodCost);
			int num2 = (((Object)(object)currentCard != (Object)null) ? CardExtensions.BonesCost(currentCard) : currentCardInfo.BonesCost);
			int num3 = (((Object)(object)currentCard != (Object)null) ? currentCard.EnergyCost : currentCardInfo.EnergyCost);
			GUILayout.Label("<b>Blood: </b> " + num, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, (num > 0) ? (-1) : 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 1, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.Label("<b>Bones: </b> " + num2, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, (num2 > 0) ? (-1) : 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 1, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.Label("<b>Energy: </b> " + num3, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, (num3 > 0) ? (-1) : 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 1, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			List<GemType> list = (((Object)(object)currentCard != (Object)null) ? CardExtensions.GemsCost(currentCard) : currentCardInfo.GemsCost);
			List<CardModificationInfo> list2 = currentCardInfo.Mods.FindAll((CardModificationInfo a) => a.addGemCost != null);
			List<CardModificationInfo> list3 = currentCardInfo.Mods.FindAll((CardModificationInfo a) => CardModificationInfoExtensions.HasRemovedAnyGemCost(a));
			foreach (GemType gemType in Enum.GetValues(typeof(GemType)))
			{
				GUILayout.Label($"<b>{(object)gemType} Mox: </b> {list.Count((GemType x) => x == gemType)}", Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
				{
					CardModificationInfo val = list3.Find((CardModificationInfo x) => CardModificationInfoExtensions.HasRemovedGemCost(x, gemType));
					if (val != null)
					{
						currentCardInfo.Mods.Remove(val);
						list = (((Object)(object)currentCard != (Object)null) ? CardExtensions.GemsCost(currentCard) : currentCardInfo.GemsCost);
						if (list.Contains(gemType))
						{
							if (deckInfo != null)
							{
								deckInfo.UpdateModDictionary();
								SaveManager.SaveToFile(false);
							}
							return true;
						}
					}
					return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, new List<GemType> { gemType });
				}
				if (!list.Contains(gemType))
				{
					GUILayout.Label("-", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
				else if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
				{
					CardModificationInfo val2 = list2.Find((CardModificationInfo a) => a.addGemCost.Contains(gemType));
					if (val2 != null)
					{
						currentCardInfo.Mods.Remove(val2);
						list = (((Object)(object)currentCard != (Object)null) ? CardExtensions.GemsCost(currentCard) : currentCardInfo.GemsCost);
						if (deckInfo != null)
						{
							deckInfo.UpdateModDictionary();
							SaveManager.SaveToFile(false);
						}
						return true;
					}
					return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, new List<GemType> { gemType });
				}
			}
			CardModificationInfo val3 = currentCardInfo.Mods.Find((CardModificationInfo a) => a.nullifyGemsCost);
			if (val3 != null)
			{
				if (GUILayout.Button("Un-Nullify Gems", Array.Empty<GUILayoutOption>()))
				{
					currentCardInfo.Mods.Remove(val3);
					if (deckInfo != null)
					{
						deckInfo.UpdateModDictionary();
						SaveManager.SaveToFile(false);
					}
					return true;
				}
			}
			else if (GUILayout.Button("Nullify Gems", Array.Empty<GUILayoutOption>()))
			{
				bool? nullifyGems = true;
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, null, null, null, nullifyGems);
			}
			CardModificationInfo val4 = currentCardInfo.Mods.Find((CardModificationInfo a) => a.gemify);
			if (val4 != null)
			{
				if (GUILayout.Button("Ungemify", Array.Empty<GUILayoutOption>()))
				{
					currentCardInfo.Mods.Remove(val4);
					if (deckInfo != null)
					{
						deckInfo.UpdateModDictionary();
						SaveManager.SaveToFile(false);
					}
					return true;
				}
			}
			else if (GUILayout.Button("Gemify", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, null, null, true);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			List<FullCardCost> customCosts = CardExtensions.GetCustomCosts(currentCardInfo);
			if (customCosts.Count == 0)
			{
				GUILayout.Label("", Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (FullCardCost item in customCosts)
				{
					int customCost = CardExtensions.GetCustomCost(currentCardInfo, item.CostName, false);
					CardModificationInfo val5 = currentCardInfo.Mods.Find((CardModificationInfo x) => CardModificationInfoExtensions.CleanId(x) == CustomCostMod);
					if (val5 == null)
					{
						val5 = new CardModificationInfo
						{
							singletonId = CustomCostMod
						};
					}
					GUILayout.Label($"<b>{item.CostName}</b>: {customCost}", Array.Empty<GUILayoutOption>());
					if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
					{
						currentCardInfo.Mods.Remove(val5);
						int num4 = CardModificationInfoExtensions.GetCustomCostIdValue(val5, item.CostName) - 1;
						CardModificationInfoExtensions.SetCustomCostId(val5, item.CostName, (object)num4);
						if ((Object)(object)currentCard != (Object)null)
						{
							currentCard.AddTemporaryMod(val5);
						}
						else if (deckInfo != null)
						{
							deckInfo.ModifyCard(currentCardInfo, val5);
							SaveManager.SaveToFile(false);
						}
						return true;
					}
					if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
					{
						currentCardInfo.Mods.Remove(val5);
						int num5 = CardModificationInfoExtensions.GetCustomCostIdValue(val5, item.CostName) + 1;
						CardModificationInfoExtensions.SetCustomCostId(val5, item.CostName, (object)num5);
						if ((Object)(object)currentCard != (Object)null)
						{
							currentCard.AddTemporaryMod(val5);
						}
						else if (deckInfo != null)
						{
							deckInfo.ModifyCard(currentCardInfo, val5);
							SaveManager.SaveToFile(false);
						}
						return true;
					}
				}
			}
			GUILayout.EndHorizontal();
			return false;
		}

		private static bool HandleStats(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor)
		{
			int num = (((Object)(object)currentCard != (Object)null) ? currentCard.Attack : currentCardInfo.Attack);
			int num2 = (((Object)(object)currentCard != (Object)null) ? currentCard.Health : currentCardInfo.Health);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("<b>Atk: </b> " + num, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-1", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, (num > 0) ? (-1) : 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+1", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 1, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("-2", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, (num > 0) ? (-2) : 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+2", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 2, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.Label("<b>HP: </b> " + num2, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-1", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, (num2 > 0) ? (-1) : 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+1", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 1, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("-2", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, (num2 > 0) ? (-2) : 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			if (GUILayout.Button("+2", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 2, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.EndHorizontal();
			return false;
		}

		private static bool ManageAbilities(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor, int managerIndex)
		{
			if ((Object)(object)currentCardInfo == (Object)null)
			{
				GUILayout.Label("No card selected!", Helpers.HeaderLabelStyle(), Array.Empty<GUILayoutOption>());
				return false;
			}
			bool cardMerge = (boardEditor ? boardAsCardMerge : asCardMerge);
			bool totem = (boardEditor ? boardAsTotem : asTotem);
			bool latch = (boardEditor ? boardAsLatch : asLatch);
			if (managerIndex == 0)
			{
				return EditAbilities(currentCardInfo, currentCard, deckInfo, boardEditor, cardMerge, totem, latch, boardEditor ? boardNegateSigil : negateSigil);
			}
			return AddAbilities(currentCardInfo, currentCard, deckInfo, boardEditor, cardMerge, totem, latch);
		}

		private static bool AddAbilities(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor, bool cardMerge, bool totem, bool latch)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			List<FullAbility> abilitiesThatContain = GetAbilitiesThatContain(AbilityManager.AllAbilities, boardEditor);
			if (boardEditor)
			{
				NewPager(ref boardCurrentPageAdd, (abilitiesThatContain.Count - 1) / 6);
			}
			else
			{
				NewPager(ref currentPageAdd, (abilitiesThatContain.Count - 1) / 6);
			}
			int num = 0;
			int num2 = (boardEditor ? boardCurrentPageAdd : currentPageAdd) * 6;
			while (num2 < (boardEditor ? boardCurrentPageAdd : currentPageAdd) * 6 + 6 && num2 < abilitiesThatContain.Count)
			{
				FullAbility val = abilitiesThatContain[num2];
				if (num == 0)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					flag = true;
				}
				Ability id = val.Id;
				Texture image = AbilitiesUtil.LoadAbilityIcon(((object)(Ability)(ref id)).ToString(), false, false);
				if (GUILayout.Button(new GUIContent
				{
					image = image,
					text = val.Info.rulebookName
				}, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(190f),
					GUILayout.Height(40f)
				}))
				{
					Ability id2 = val.Id;
					bool asMerge = cardMerge;
					bool flag2 = totem;
					bool flag3 = latch;
					return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, id2, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, null, null, null, null, asMerge, flag2, flag3);
				}
				num++;
				num2++;
				if (num == 3)
				{
					GUILayout.EndHorizontal();
					flag = false;
					num = 0;
				}
			}
			if (flag)
			{
				GUILayout.EndHorizontal();
			}
			return false;
		}

		private static bool EditAbilities(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor, bool cardMerge, bool totem, bool latch, bool negateAbility)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			List<FullAbility> list = new List<FullAbility>(AbilityManager.AllAbilities);
			if (boardEditor)
			{
				list.RemoveAll((FullAbility x) => !CardExtensions.AllAbilities(currentCard, true).Contains(x.Id));
			}
			else
			{
				list.RemoveAll((FullAbility x) => !currentCardInfo.Abilities.Contains(x.Id));
			}
			List<FullAbility> abilitiesThatContain = GetAbilitiesThatContain(list, boardEditor);
			if (abilitiesThatContain.Count == 0)
			{
				GUILayout.Label("No Sigils", Array.Empty<GUILayoutOption>());
				return false;
			}
			bool flag = false;
			if (boardEditor)
			{
				NewPager(ref boardCurrentPageEdit, (abilitiesThatContain.Count - 1) / 6);
			}
			else
			{
				NewPager(ref currentPageEdit, (abilitiesThatContain.Count - 1) / 6);
			}
			int num = 0;
			int num2 = (boardEditor ? boardCurrentPageEdit : currentPageEdit) * 6;
			while (num2 < (boardEditor ? boardCurrentPageEdit : currentPageEdit) * 6 + 6 && num2 < abilitiesThatContain.Count)
			{
				FullAbility abilityOnCard = abilitiesThatContain[num2];
				if (num == 0)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					flag = true;
				}
				List<CardModificationInfo> list2 = currentCardInfo.Mods;
				if (boardEditor)
				{
					list2 = list2.Concat(currentCard.TemporaryMods).ToList();
				}
				CardModificationInfo val = list2.Find((CardModificationInfo x) => x.abilities != null && x.abilities.Contains(abilityOnCard.Id));
				Ability id = abilityOnCard.Id;
				Texture image = AbilitiesUtil.LoadAbilityIcon(((object)(Ability)(ref id)).ToString(), false, false);
				string text = "  " + abilityOnCard.Info.rulebookName;
				if (val != null)
				{
					text = (val.fromCardMerge ? (text + "\n  <color=#69FFA0>(Merge)</color>") : (val.fromTotem ? "\n  <color=#FBAA4E>(Totem)</color>" : (val.fromLatch ? "\n  <color=#99E6FF>(Latch)</color>" : ((!val.fromOverclock) ? (text + "\n  (Card Mod)") : "\n  <color=#FFF060>(Overclock)</color>"))));
				}
				if (GUILayout.Button(new GUIContent
				{
					image = image,
					text = text
				}, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(190f),
					GUILayout.Height(40f)
				}))
				{
					if (val == null)
					{
						if (negateAbility)
						{
							return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, abilityOnCard.Id, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
						}
						if (AbilitiesUtil.GetInfo(abilityOnCard.Id).canStack)
						{
							NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, abilityOnCard.Id, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, null, NegateDefaultStackMod);
						}
						CardInfo cardInfo = currentCardInfo;
						PlayableCard playableCard = currentCard;
						Ability id2 = abilityOnCard.Id;
						bool asMerge = cardMerge;
						bool flag2 = totem;
						bool flag3 = latch;
						return NewCardMod(deckInfo, cardInfo, playableCard, 0, 0, id2, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0, null, null, null, null, null, asMerge, flag2, flag3);
					}
					if (boardEditor)
					{
						currentCard.RemoveTemporaryMod(val, true);
					}
					currentCardInfo.Mods.Remove(val);
					if (AbilitiesUtil.GetInfo(abilityOnCard.Id).canStack)
					{
						int num3 = currentCardInfo.Mods.RemoveAll((CardModificationInfo x) => x.negateAbilities != null && x.negateAbilities.Contains(abilityOnCard.Id) && x.singletonId == NegateDefaultStackMod);
						if (boardEditor)
						{
							num3 += currentCard.TemporaryMods.RemoveAll((CardModificationInfo x) => x.negateAbilities != null && x.negateAbilities.Contains(abilityOnCard.Id) && x.singletonId == NegateDefaultStackMod);
							for (int i = 0; i < num3; i++)
							{
								currentCard.TriggerHandler.AddAbility(abilityOnCard.Id);
							}
						}
					}
					if (negateAbility)
					{
						if (deckInfo != null)
						{
							deckInfo.UpdateModDictionary();
							SaveManager.SaveToFile(false);
						}
						return true;
					}
					bool flag4 = val.fromCardMerge || val.fromTotem || val.fromLatch;
					val.fromCardMerge = cardMerge;
					val.fromTotem = totem;
					val.fromLatch = latch;
					flag4 = flag4 && (cardMerge || totem || latch);
					if (!boardEditor)
					{
						deckInfo.ModifyCard(currentCardInfo, val);
						SaveManager.SaveToFile(false);
						return true;
					}
					if (flag4)
					{
						currentCard.AddTemporaryMod(val);
						return false;
					}
				}
				num++;
				num2++;
				if (num == 3)
				{
					GUILayout.EndHorizontal();
					flag = false;
					num = 0;
				}
			}
			if (flag)
			{
				GUILayout.EndHorizontal();
			}
			return false;
		}

		private static void ManageSpecialAbilities(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor, int managerIndex)
		{
			if ((Object)(object)currentCardInfo == (Object)null)
			{
				GUILayout.Label("No card selected!", Helpers.HeaderLabelStyle(), Array.Empty<GUILayoutOption>());
			}
			else if (managerIndex == 0)
			{
				RemoveSpecialAbility(currentCardInfo, currentCard, deckInfo, boardEditor);
			}
			else
			{
				AddSpecialAbility(currentCardInfo, currentCard, deckInfo, boardEditor);
			}
		}

		private static void AddSpecialAbility(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			List<FullSpecialTriggeredAbility> specialAbilitiesThatContain = GetSpecialAbilitiesThatContain(SpecialTriggeredAbilityManager.AllSpecialTriggers, boardEditor);
			if (boardEditor)
			{
				boardSpecialAbilityListVector = GUILayout.BeginScrollView(boardSpecialAbilityListVector, Array.Empty<GUILayoutOption>());
			}
			else
			{
				specialAbilityListVector = GUILayout.BeginScrollView(specialAbilityListVector, Array.Empty<GUILayoutOption>());
			}
			foreach (FullSpecialTriggeredAbility item in specialAbilitiesThatContain)
			{
				if (GUILayout.Button(item.AbilityName, Array.Empty<GUILayoutOption>()))
				{
					NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, item.Id, (SpecialTriggeredAbility)0);
				}
			}
			GUILayout.EndScrollView();
		}

		private static void RemoveSpecialAbility(CardInfo currentCardInfo, PlayableCard currentCard, DeckInfo deckInfo, bool boardEditor)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0078: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			List<FullSpecialTriggeredAbility> list = new List<FullSpecialTriggeredAbility>(SpecialTriggeredAbilityManager.AllSpecialTriggers);
			if (boardEditor)
			{
				list.RemoveAll((FullSpecialTriggeredAbility x) => !CardExtensions.AllSpecialAbilities(currentCard).Contains(x.Id));
			}
			else
			{
				list.RemoveAll((FullSpecialTriggeredAbility x) => !currentCardInfo.SpecialAbilities.Contains(x.Id));
			}
			List<FullSpecialTriggeredAbility> specialAbilitiesThatContain = GetSpecialAbilitiesThatContain(list, boardEditor);
			if (specialAbilitiesThatContain.Count <= 0)
			{
				GUILayout.Label("No Special Abilities", Array.Empty<GUILayoutOption>());
				return;
			}
			if (boardEditor)
			{
				boardSpecialAbilityListVector2 = GUILayout.BeginScrollView(boardSpecialAbilityListVector2, Array.Empty<GUILayoutOption>());
			}
			else
			{
				specialAbilityListVector2 = GUILayout.BeginScrollView(specialAbilityListVector2, Array.Empty<GUILayoutOption>());
			}
			foreach (FullSpecialTriggeredAbility item in specialAbilitiesThatContain)
			{
				if (GUILayout.Button(item.AbilityName, Array.Empty<GUILayoutOption>()))
				{
					NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, item.Id);
				}
			}
			GUILayout.EndScrollView();
		}

		private static T AddSpecialAbility<T>(string typeString, GameObject obj) where T : TriggerReceiver
		{
			Type type = CardTriggerHandler.GetType(typeString);
			Component component = obj.GetComponent(type);
			return ((T)(object)((component is T) ? component : null)) ?? ((T)(object)/*isinst with value type is only supported in some contexts*/);
		}

		private static void RemoveSpecialAbility<T>(string typeString, GameObject obj) where T : TriggerReceiver
		{
			Type type = CardTriggerHandler.GetType(typeString);
			Component component = obj.GetComponent(type);
			T val = (T)(object)((component is T) ? component : null);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
		}

		private static bool Filter(ref string nameString, ref string guidString)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			HorizontalScope val = new HorizontalScope(Array.Empty<GUILayoutOption>());
			try
			{
				GUILayout.Label("Filter Name", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
				nameString = GUILayout.TextField(nameString, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Filter GUID", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
				guidString = GUILayout.TextField(guidString, Array.Empty<GUILayoutOption>());
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			if (string.IsNullOrEmpty(nameString) && string.IsNullOrEmpty(guidString))
			{
				return false;
			}
			return true;
		}

		private static List<FullAbility> GetAbilitiesThatContain(List<FullAbility> searchingList, bool boardEditor)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!(boardEditor ? Filter(ref boardAbilitySearch, ref boardAbilityGUIDSearch) : Filter(ref abilitySearch, ref abilityGUIDSearch)))
			{
				return searchingList;
			}
			string text = (boardEditor ? boardAbilitySearch : abilitySearch);
			string text2 = (boardEditor ? boardAbilityGUIDSearch : abilityGUIDSearch);
			List<FullAbility> list = new List<FullAbility>();
			foreach (FullAbility searching in searchingList)
			{
				if (text2 != "" && (searching.ModGUID == null || !searching.ModGUID.Contains(text2)))
				{
					continue;
				}
				if (text != "")
				{
					if ((Object)(object)searching.Info == (Object)null)
					{
						continue;
					}
					text = text.ToLowerInvariant();
					Ability id = searching.Id;
					string text3 = ((object)(Ability)(ref id)).ToString();
					if (int.TryParse(text3, out var _) && searching.AbilityBehavior != null)
					{
						text3 = searching.AbilityBehavior.Name;
					}
					if (!searching.Info.rulebookName.ToLowerInvariant().Contains(text) && !text3.ToLowerInvariant().Contains(text))
					{
						continue;
					}
				}
				list.Add(searching);
			}
			return list;
		}

		private static List<FullSpecialTriggeredAbility> GetSpecialAbilitiesThatContain(List<FullSpecialTriggeredAbility> searchingList, bool board)
		{
			if (board ? (!Filter(ref boardSpecialAbilitySearch, ref boardSpecialAbilityGUIDSearch)) : (!Filter(ref specialAbilitySearch, ref specialAbilityGUIDSearch)))
			{
				return searchingList;
			}
			string text = (board ? boardSpecialAbilitySearch : specialAbilitySearch);
			string text2 = (board ? boardSpecialAbilityGUIDSearch : specialAbilityGUIDSearch);
			List<FullSpecialTriggeredAbility> list = new List<FullSpecialTriggeredAbility>();
			foreach (FullSpecialTriggeredAbility searching in searchingList)
			{
				if ((!(text2 != "") || (searching.ModGUID != null && searching.ModGUID.Contains(text2))) && (!(text != "") || searching.AbilityName.ToLowerInvariant().Contains(text.ToLowerInvariant())))
				{
					list.Add(searching);
				}
			}
			return list;
		}

		private static void NewPager(ref int page, int max, int min = 0)
		{
			int num = page;
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Page: " + num, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("<", Array.Empty<GUILayoutOption>()))
			{
				num = ((num <= min) ? max : (num - 1));
			}
			if (GUILayout.Button(">", Array.Empty<GUILayoutOption>()))
			{
				num = ((num >= max) ? min : (num + 1));
			}
			GUILayout.EndHorizontal();
			page = num;
		}
	}
	public static class Helpers
	{
		public enum Acts
		{
			Unknown,
			Act1,
			Act2,
			Act3,
			GrimoraAct,
			MagnificusAct
		}

		public static SpecialNodeData LastSpecialNodeData;

		private static Dictionary<string, string> m_itemNameToRulebookName;

		private static Action<EncounterBlueprintData> m_selectedBlueprint;

		private static Action<Type> m_selectedOpponentType;

		private static Action<Tribe> m_selectedTribe;

		private static Action<Ability> m_selectedAbility;

		private static GUIStyle m_headerLabelStyle;

		private static GUIStyle m_closeButtonStyle;

		private static GUIStyle m_enabledButtonStyle;

		private static GUIStyle m_disabledButtonStyle;

		private static List<BaseTriggerSequence> c_sequences;

		private static List<BaseTriggerSequence> m_sequences;

		private static List<BaseTriggerSequence> m_act1Sequences;

		private static List<BaseTriggerSequence> m_act3Sequences;

		private static List<BaseTriggerSequence> m_grimoraSequences;

		public static List<BaseTriggerSequence> ShownSequences
		{
			get
			{
				if (!Configs.ShowAllSequences)
				{
					return CurrentActSequences;
				}
				return AllSequences;
			}
		}

		public static List<BaseTriggerSequence> CurrentActSequences => GetCurrentSavedAct() switch
		{
			Acts.Act1 => GetAct1Sequences(), 
			Acts.Act3 => GetAct3Sequences(), 
			Acts.GrimoraAct => GetGrimoraSequences(), 
			_ => AllSequences, 
		};

		public static List<BaseTriggerSequence> AllSequences
		{
			get
			{
				if (m_sequences == null)
				{
					m_sequences = GetAllSequences();
				}
				return m_sequences;
			}
		}

		public static bool ContainsText(this string text, string substring, bool caseSensitive = true)
		{
			if (string.IsNullOrEmpty(text))
			{
				if (string.IsNullOrEmpty(substring))
				{
					return true;
				}
				return false;
			}
			if (string.IsNullOrEmpty(substring))
			{
				return false;
			}
			return text.IndexOf(substring, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) >= 0;
		}

		public static string GetConsumableByName(string consumableName)
		{
			if (string.IsNullOrEmpty(consumableName))
			{
				return null;
			}
			if (m_itemNameToRulebookName == null)
			{
				List<ConsumableItemData> allConsumables = ItemsUtil.AllConsumables;
				m_itemNameToRulebookName = new Dictionary<string, string>(allConsumables.Count);
				for (int i = 0; i < allConsumables.Count; i++)
				{
					ConsumableItemData val = allConsumables[i];
					m_itemNameToRulebookName[((Object)val).name] = val.rulebookName;
				}
				Plugin.Log.LogInfo((object)("[GetConsumableByName] Loaded all items " + m_itemNameToRulebookName.Count));
			}
			if (m_itemNameToRulebookName.TryGetValue(consumableName, out var value))
			{
				return value;
			}
			ConsumableItemData consumableByName = ItemsUtil.GetConsumableByName(consumableName);
			if ((Object)(object)consumableByName != (Object)null)
			{
				m_itemNameToRulebookName[consumableName] = consumableByName.rulebookName;
				return consumableByName.rulebookName;
			}
			Plugin.Log.LogInfo((object)("[GetConsumableByName] Couldn't find name of item " + consumableName));
			return null;
		}

		public static IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
		{
			return from t in assembly.GetTypes()
				where t != baseType && !t.IsAbstract && baseType.IsAssignableFrom(t)
				select t;
		}

		public static void DrawBlueprintGUI(DrawableGUI window, Action<EncounterBlueprintData> OnBlueprintSelected)
		{
			m_selectedBlueprint = OnBlueprintSelected;
			ButtonListPopup.OnGUI<ButtonListPopup>(window, "Select Blueprint", "Select Blueprint", GetAllBlueprints, OnChoseBlueprintButtonCallback, Array.Empty<string>());
		}

		public static void OnChoseBlueprintButtonCallback(int chosenIndex, string chosenValue, List<string> metaData)
		{
			List<EncounterBlueprintData> allEncountersCopy = EncounterManager.AllEncountersCopy;
			if (chosenIndex >= 0 && chosenIndex < allEncountersCopy.Count)
			{
				m_selectedBlueprint(allEncountersCopy[chosenIndex]);
			}
		}

		private static Tuple<List<string>, List<string>> GetAllBlueprints()
		{
			List<EncounterBlueprintData> allEncountersCopy = EncounterManager.AllEncountersCopy;
			List<string> list = new List<string>(allEncountersCopy.Count);
			List<string> list2 = new List<string>(allEncountersCopy.Count);
			for (int i = 0; i < allEncountersCopy.Count; i++)
			{
				list.Add(((Object)allEncountersCopy[i]).name);
				list2.Add(((Object)allEncountersCopy[i]).name);
			}
			return new Tuple<List<string>, List<string>>(list, list2);
		}

		public static void DrawOpponentsGUI(DrawableGUI window, Action<Type> OnOpponentSelected)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			m_selectedOpponentType = OnOpponentSelected;
			Func<Tuple<List<string>, List<string>>> getDataCallback = GetAllOpponents;
			Action<int, string, List<string>> onChoseButtonCallback = OnChoseOpponentButtonCallback;
			string[] array = new string[1];
			Type val = (Type)21;
			array[0] = ((object)(Type)(ref val)).ToString();
			ButtonListPopup.OnGUI<ButtonListPopup>(window, "Select Opponent", "Select Opponent", getDataCallback, onChoseButtonCallback, array);
		}

		public static void OnChoseOpponentButtonCallback(int chosenIndex, string chosenValue, List<string> metaData)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			List<FullOpponent> list = new List<FullOpponent>(OpponentManager.AllOpponents);
			if (chosenIndex >= 0 && chosenIndex < list.Count)
			{
				m_selectedOpponentType(list[chosenIndex].Id);
			}
		}

		private static Tuple<List<string>, List<string>> GetAllOpponents()
		{
			//IL_00ad: 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)
			//IL_0045: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			List<FullOpponent> list = new List<FullOpponent>(OpponentManager.AllOpponents);
			List<string> list2 = new List<string>(list.Count);
			List<string> list3 = new Li