Decompiled source of DebugMenu v1.3.0

DebugMenu.dll

Decompiled 4 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 HarmonyLib;
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 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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DebugMenu")]
[assembly: AssemblyTitle("DebugMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 bool DisableAllInput
		{
			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();
			}
		}

		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(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)
		{
			Act1.lastUsedStarterDeck = starterDeck;
			Plugin.Log.LogInfo((object)("New Starter Deck with " + Act1.lastUsedStarterDeck.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.DisableAllInput)
			{
				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.DisableAllInput;
		}
	}
	[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(CardDisplayer3D), "DisplayInfo")]
		private static void ForceAlternatePortrait(CardDisplayer3D __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(renderInfo.baseInfo.alternatePortrait);
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.ShieldPortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.BrokenShieldPortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.SacrificePortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(CardManager.SacrificablePortrait(renderInfo.baseInfo));
				}
				else if (mods.Exists((CardModificationInfo x) => x.singletonId == DrawCardInfo.TrapPortraitMod))
				{
					((CardDisplayer)__instance).SetPortrait(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.3.0")]
	[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.3.0";

		public static Plugin Instance;

		public static ManualLogSource Log;

		public static HotkeyController Hotkeys;

		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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			StartingFixedDeltaTime = Time.fixedDeltaTime;
			Hotkeys = new HotkeyController();
			PluginDirectory = ((BaseUnityPlugin)this).Info.Location.Replace("DebugMenu.dll", "");
			blockerParent = new GameObject("DebugMenuBlocker");
			blockerParent.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);
			new Harmony("jamesgames.inscryption.debugmenu").PatchAll();
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (type.IsSubclassOf(typeof(BaseWindow)))
				{
					((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 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()
		{
			X += ColumnWidth + 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 interface IModdedSequence
	{
		string ModGUID { get; }
	}
	public abstract class ABaseTriggerSequences
	{
		public abstract string ButtonName { get; }

		public abstract void Sequence();
	}
	public class APIModdedSequence : ABaseTriggerSequences, IModdedSequence
	{
		public FullNode CustomNodeData;

		public override string ButtonName => CustomNodeData.name + "\n(" + ModGUID + ")";

		public string ModGUID => CustomNodeData.guid;

		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 abstract class SimpleTriggerSequences : ABaseTriggerSequences
	{
		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 ModdedStubSequence : StubSequence, IModdedSequence
	{
		public override string ButtonName
		{
			get
			{
				Plugin.Log.LogInfo((object)("ModdedStubSequence " + type?.ToString() + " " + ModGUID));
				return base.ButtonName + "\n(" + ModGUID + ")";
			}
		}

		public string ModGUID { get; set; }
	}
	public class StubSequence : SimpleTriggerSequences
	{
		public Type type;

		public GameState gameState;

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

		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 ButtonName => "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 ButtonName => "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 ButtonName => "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 ButtonName => $"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 = 9;

		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 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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("(" + ((Object)cardInfo).name + ")", Helpers.HeaderLabelStyle(), 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.IsPart2)
			{
				GUILayout.Label("No emissions in Act 2!", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			else
			{
				CardModificationInfo val = cardInfo.Mods.Find((CardModificationInfo a) => a.singletonId == EmissionMod);
				if (val != null)
				{
					if (GUILayout.Button("Unforce Emission", Array.Empty<GUILayoutOption>()))
					{
						cardInfo.Mods.Remove(val);
						if (deckInfo != null)
						{
							if (deckInfo != null)
							{
								deckInfo.UpdateModDictionary();
							}
							SaveManager.SaveToFile(false);
						}
						return Result.Altered;
					}
				}
				else if (GUILayout.Button("Force Emission", Array.Empty<GUILayoutOption>()))
				{
					CardModificationInfo val2 = new CardModificationInfo
					{
						singletonId = EmissionMod
					};
					if (deckInfo != null)
					{
						deckInfo.ModifyCard(cardInfo, val2);
						SaveManager.SaveToFile(false);
					}
					else
					{
						cardInfo.Mods.Add(val2);
					}
					return Result.Altered;
				}
			}
			if (deckInfo != null)
			{
				if (((CardCollectionInfo)deckInfo).Cards.Count > 2)
				{
					if (GUILayout.Button("Remove Selected Card", Array.Empty<GUILayoutOption>()))
					{
						((CardCollectionInfo)deckInfo).RemoveCard(cardInfo);
						SaveManager.SaveToFile(false);
						return Result.Removed;
					}
				}
				else
				{
					GUILayout.Label("Cannot remove; deck too small!", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
				}
			}
			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 val3 = 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] { val3 });
						if (boardNegateSigil != flag2)
						{
							boardAsCardMerge = (boardAsTotem = (boardAsLatch = false));
						}
					}
					else
					{
						GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					}
					boardAsCardMerge = GUILayout.Toggle(boardAsCardMerge, "FromMerge", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					boardAsTotem = GUILayout.Toggle(boardAsTotem, "FromTotem", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					boardAsLatch = GUILayout.Toggle(boardAsLatch, "FromLatch", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
				}
				else
				{
					if (num3 == 0)
					{
						bool flag3 = negateSigil;
						negateSigil = GUILayout.Toggle(flag3, flag3 ? "<b>Remove</b>" : "<b>Modify</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
						if (negateSigil != flag3)
						{
							asCardMerge = (asTotem = (asLatch = false));
						}
					}
					else
					{
						GUILayout.Label("", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					}
					asCardMerge = GUILayout.Toggle(asCardMerge, "FromMerge", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					asTotem = GUILayout.Toggle(asTotem, "FromTotem", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
					asLatch = GUILayout.Toggle(asLatch, "FromLatch", (GUILayoutOption[])(object)new GUILayoutOption[1] { val3 });
				}
				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 HandleForcePortrait(CardInfo cardInfo, DeckInfo deckInfo)
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//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_01d0: Expected O, but got Unknown
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: 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", 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 && GUILayout.Button("Force Alt", Array.Empty<GUILayoutOption>()))
			{
				cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || 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;
			}
			GUILayout.Label("No Alt Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			if (flag && GUILayout.Button("Force Shield", Array.Empty<GUILayoutOption>()))
			{
				cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || 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;
			}
			GUILayout.Label("No Shield Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			if (flag2 && GUILayout.Button("Force Sacrifice", Array.Empty<GUILayoutOption>()))
			{
				cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod || 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;
			}
			GUILayout.Label("No Sacrifice Portrait", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			if (flag3 && GUILayout.Button("Force Trap", Array.Empty<GUILayoutOption>()))
			{
				cardInfo.Mods.RemoveAll((CardModificationInfo x) => x.singletonId == PortraitMod || x.singletonId == ShieldPortraitMod || x.singletonId == SacrificePortraitMod || x.singletonId == TrapPortraitMod);
				CardModificationInfo val4 = new CardModificationInfo
				{
					singletonId = TrapPortraitMod
				};
				if (deckInfo != null)
				{
					deckInfo.ModifyCard(cardInfo, val4);
					SaveManager.SaveToFile(false);
				}
				else
				{
					cardInfo.Mods.Add(val4);
				}
				return true;
			}
			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_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0675: Unknown result type (might be due to invalid IL or missing references)
			//IL_067a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: 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);
			List<GemType> list = (((Object)(object)currentCard != (Object)null) ? CardExtensions.GemsCost(currentCard) : currentCardInfo.GemsCost);
			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.Label("<b>Mox:</b> " + string.Join(",", list), Array.Empty<GUILayoutOption>());
			CardModificationInfo val = currentCardInfo.Mods.Find((CardModificationInfo a) => a.gemify);
			if (val != null)
			{
				if (GUILayout.Button("Ungemify", Array.Empty<GUILayoutOption>()))
				{
					currentCardInfo.Mods.Remove(val);
					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<CardModificationInfo> list2 = currentCardInfo.Mods.FindAll((CardModificationInfo a) => a.addGemCost != null);
			List<CardModificationInfo> list3 = currentCardInfo.Mods.FindAll((CardModificationInfo a) => CardModificationInfoExtensions.HasRemovedAnyGemCost(a));
			foreach (GemType value in Enum.GetValues(typeof(GemType)))
			{
				GemType gemType = value;
				GUILayout.Label(((object)(GemType)(ref gemType)).ToString(), Array.Empty<GUILayoutOption>());
				if (list.Contains(gemType))
				{
					GUILayout.Label("+", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
					if (GUILayout.Button("-", Array.Empty<GUILayoutOption>()))
					{
						CardModificationInfo val2 = list2.Find((CardModificationInfo a) => a.addGemCost.Contains(gemType));
						if (val2 != null)
						{
							currentCardInfo.Mods.Remove(val2);
							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 });
					}
					continue;
				}
				if (GUILayout.Button("+", Array.Empty<GUILayoutOption>()))
				{
					CardModificationInfo val3 = list3.Find((CardModificationInfo x) => CardModificationInfoExtensions.HasRemovedGemCost(x, gemType));
					if (val3 != null)
					{
						currentCardInfo.Mods.Remove(val3);
						if (currentCardInfo.GemsCost.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 });
				}
				GUILayout.Label("-", Helpers.DisabledButtonStyle(), Array.Empty<GUILayoutOption>());
			}
			CardModificationInfo val4 = currentCardInfo.Mods.Find((CardModificationInfo a) => a.nullifyGemsCost);
			if (val4 != null)
			{
				if (GUILayout.Button("Un-Nullify Gems", Array.Empty<GUILayoutOption>()))
				{
					currentCardInfo.Mods.Remove(val4);
					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);
			}
			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("-", 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("+", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 1, 0, (Ability)0, (Ability)0, 0, 0, 0, (SpecialTriggeredAbility)0, (SpecialTriggeredAbility)0);
			}
			GUILayout.Label("<b>HP:</b> " + num2, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("-", 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("+", Array.Empty<GUILayoutOption>()))
			{
				return NewCardMod(deckInfo, currentCardInfo, currentCard, 0, 1, (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_0073: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00dd: 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) / 9);
			}
			else
			{
				NewPager(ref currentPageAdd, (abilitiesThatContain.Count - 1) / 9);
			}
			int num = 0;
			int num2 = (boardEditor ? boardCurrentPageAdd : currentPageAdd) * 9;
			while (num2 < (boardEditor ? boardCurrentPageAdd : currentPageAdd) * 9 + 9 && 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: 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) / 9);
			}
			else
			{
				NewPager(ref currentPageEdit, (abilitiesThatContain.Count - 1) / 9);
			}
			int num = 0;
			int num2 = (boardEditor ? boardCurrentPageEdit : currentPageEdit) * 9;
			while (num2 < (boardEditor ? boardCurrentPageEdit : currentPageEdit) * 9 + 9 && 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)
		{
			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;
					}
					string text3 = searching.Info.rulebookName.ToLowerInvariant();
					string text4 = ((object)(Ability)(ref searching.Info.ability)).ToString();
					if (!text3.Contains(text.ToLowerInvariant()) && !text4.Contains(text.ToLowerInvariant()))
					{
						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 GrimoraModHelpers
	{
		private static Assembly GrimoraModAssembly;

		private static PropertyInfo IsGrimoraModRunProperty;

		public static RunState GetRunState()
		{
			return RunState.Run;
		}

		private static void Initialize(Assembly assembly)
		{
			GrimoraModAssembly = assembly;
			IsGrimoraModRunProperty = GrimoraModAssembly.GetType("GrimoraMod.GrimoraSaveUtil")?.GetProperty("IsGrimoraModRun");
		}

		public static bool GrimoraModIsActive()
		{
			if (GrimoraModAssembly == null)
			{
				foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
				{
					if (pluginInfo.Value.Metadata.GUID == "arackulele.inscryption.grimoramod")
					{
						Plugin.Log.LogInfo((object)"[GrimoraModHelpers] GrimoraMod found!");
						Initialize(((object)pluginInfo.Value.Instance).GetType().Assembly);
					}
				}
				if (GrimoraModAssembly == null)
				{
					return false;
				}
			}
			return (bool)IsGrimoraModRunProperty.GetValue(null);
		}
	}
	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 List<ABaseTriggerSequences> m_sequences;

		public static List<ABaseTriggerSequences> Sequences
		{
			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(window, "Select Blueprint", "Select Blueprint", GetAllBlueprints, OnChoseBlueprintButtonCallback);
		}

		public static void OnChoseBlueprintButtonCallback(int chosenIndex, string chosenValue, 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_0049: 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, string> onChoseButtonCallback = OnChoseOpponentButtonCallback;
			Type val = (Type)21;
			ButtonListPopup.OnGUI(window, "Select Opponent", "Select Opponent", getDataCallback, onChoseButtonCallback, ((object)(Type)(ref val)).ToString());
		}

		public static void OnChoseOpponentButtonCallback(int chosenIndex, string chosenValue, 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 List<string>(list.Count);
			Type id;
			string item;
			for (int i = 0; i < list.Count; list2.Add(item), id = list[i].Id, list3.Add(((object)(Type)(ref id)).ToString()), i++)
			{
				if (list[i].Opponent != null)
				{
					id = list[i].Id;
					if (int.TryParse(((object)(Type)(ref id)).ToString(), out var _))
					{
						item = list[i].Opponent.Name.Replace("Opponent", "") + $"\n({list[i].Id})";
						continue;
					}
				}
				id = list[i].Id;
				item = ((object)(Type)(ref id)).ToString();
			}
			return new Tuple<List<string>, List<string>>(list2, list3);
		}

		public static void DrawTribesGUI(TriggerCardBattleSequenceWindow window, Action<Tribe> callback)
		{
			m_selectedTribe = callback;
			ButtonListPopup.OnGUI(window, "Select Tribe", "Select Tribe", GetAllTribes, OnChoseTribeButtonCallback);
		}

		private static void OnChoseTribeButtonCallback(int chosenIndex, string chosenValue, string metaData)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			List<Tribe> list = AllTribes();
			if (chosenIndex >= 0 && chosenIndex < list.Count)
			{
				m_selectedTribe(list[chosenIndex]);
			}
		}

		public static List<Tribe> AllTribes()
		{
			List<Tribe> list = new List<Tribe>();
			list.AddRange(Enum.GetValues(typeof(Tribe)).Cast<Tribe>());
			list.AddRange(TribeManager.NewTribes.Select((TribeInfo a) => a.tribe));
			return list;
		}

		private static Tuple<List<string>, List<string>> GetAllTribes()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			List<Tribe> list = AllTribes();
			List<string> list2 = new List<string>(list.Count);
			List<string> list3 = new List<string>(list.Count);
			foreach (Tribe item in list)
			{
				Tribe current = item;
				list2.Add(((object)(Tribe)(ref current)).ToString());
				list3.Add(((object)(Tribe)(ref current)).ToString());
			}
			return new Tuple<List<string>, List<string>>(list2, list3);
		}

		public static string GetTribeName(Tribe tribe)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//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)
			if ((int)tribe >= 0 && (int)tribe <= 7)
			{
				return ((object)(Tribe)(ref tribe)).ToString();
			}
			foreach (TribeInfo newTribe in TribeManager.NewTribes)
			{
				if (newTribe.tribe == tribe)
				{
					return newTribe.name;
				}
			}
			return ((object)(Tribe)(ref tribe)).ToString();
		}

		public static void DrawAbilitysGUI(TriggerCardBattleSequenceWindow window, Action<Ability> callback)
		{
			m_selectedAbility = callback;
			ButtonListPopup.OnGUI(window, "Select Ability", "Select Ability", GetAllAbilitys, OnChoseAbilityButtonCallback);
		}

		private static void OnChoseAbilityButtonCallback(int chosenIndex, string chosenValue, string metaData)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			List<FullAbility> allAbilities = AbilityManager.AllAbilities;
			if (chosenIndex >= 0 && chosenIndex < allAbilities.Count)
			{
				m_selectedAbility(allAbilities[chosenIndex].Id);
			}
		}

		private static Tuple<List<string>, List<string>> GetAllAbilitys()
		{
			//IL_0040: 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)
			List<FullAbility> allAbilities = AbilityManager.AllAbilities;
			List<string> list = new List<string>(allAbilities.Count);
			List<string> list2 = new List<string>(allAbilities.Count);
			foreach (FullAbility item in allAbilities)
			{
				list.Add(item.Info.rulebookName);
				Ability id = item.Id;
				list2.Add(((object)(Ability)(ref id)).ToString());
			}
			return new Tuple<List<string>, List<string>>(list, list2);
		}

		public static string DumpAllInfoAsJSONUsingReflection(object o)
		{
			if (o == null)
			{
				return "null";
			}
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Type type = o.GetType();
			FieldInfo[] fields = type.GetFields();
			foreach (FieldInfo fieldInfo in fields)
			{
				dictionary[fieldInfo.Name] = SerializeData(fieldInfo.GetValue(o));
			}
			PropertyInfo[] properties = type.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.CanRead)
				{
					dictionary[propertyInfo.Name] = SerializeData(propertyInfo.GetValue(o));
				}
			}
			return SaveManager.ToJSON((object)dictionary);
		}

		private static string SerializeData(object o)
		{
			if (o == null)
			{
				return "null";
			}
			if (o.GetType().IsPrimitive || o is string)
			{
				return o.ToString();
			}
			return SaveManager.ToJSON(o);
		}

		public static object GetDefaultValue(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			return Expression.Lambda<Func<object>>(Expression.Convert(Expression.Default(type), typeof(object)), Array.Empty<ParameterExpression>()).Compile()();
		}

		public static Acts GetCurrentSavedAct()
		{
			if (SaveManager.SaveFile.IsPart1 && Object.op_Implicit((Object)(object)Singleton<GameFlowManager>.m_Instance))
			{
				return Acts.Act1;
			}
			if (SaveManager.SaveFile.IsPart2)
			{
				return Acts.Act2;
			}
			if (SaveManager.SaveFile.IsPart3)
			{
				return Acts.Act3;
			}
			if (SaveManager.SaveFile.IsGrimora)
			{
				return Acts.GrimoraAct;
			}
			if (SaveManager.SaveFile.IsMagnificus)
			{
				return Acts.MagnificusAct;
			}
			return Acts.Unknown;
		}

		public static DeckInfo CurrentDeck()
		{
			switch (GetCurrentSavedAct())
			{
			case Acts.Act2:
				return SaveData.Data.deck;
			case Acts.GrimoraAct:
				if (GrimoraModHelpers.GrimoraModIsActive())
				{
					return GrimoraModHelpers.GetRunState().playerDeck;
				}
				break;
			case Acts.Unknown:
				return null;
			}
			return SaveManager.SaveFile.CurrentDeck;
		}

		public static string ToLiteral(string input)
		{
			StringBuilder stringBuilder = new StringBuilder(input.Length + 2);
			stringBuilder.Append("\"");
			foreach (char c in input)
			{
				switch (c)
				{
				case '"':
					stringBuilder.Append("\\\"");
					continue;
				case '\\':
					stringBuilder.Append("\\\\");
					continue;
				case '\0':
					stringBuilder.Append("\\0");
					continue;
				case '\a':
					stringBuilder.Append("\\a");
					continue;
				case '\b':
					stringBuilder.Append("\\b");
					continue;
				case '\f':
					stringBuilder.Append("\\f");
					continue;
				case '\n':
					stringBuilder.Append("\\n");
					continue;
				case '\r':
					stringBuilder.Append("\\r");
					continue;
				case '\t':
					stringBuilder.Append("\\t");
					continue;
				case '\v':
					stringBuilder.Append("\\v");
					continue;
				}
				if (c >= ' ' && c <= '~')
				{
					stringBuilder.Append(c);
					cont