Decompiled source of UITweaks v0.1.0

plugins/UITweaks.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ShinyShoe;
using TMPro;
using UITweaks.DeckColumns;
using UITweaks.ForgeSmartToggle;
using UITweaks.GreedBlights;
using UITweaks.InscryptionWarning;
using UITweaks.JudgesScales;
using UITweaks.RerollConfirmation;
using UITweaks.TitanTransitions;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UITweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+968cf9f39c6e024ea465ebe3c3c99dc150138de2")]
[assembly: AssemblyProduct("UITweaks")]
[assembly: AssemblyTitle("UITweaks")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UITweaks
{
	[BepInPlugin("SpecialCircumstances.UITweaks", "UITweaks", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = new ManualLogSource("SpecialCircumstances.UITweaks");

		private const float ConfigPollSeconds = 1f;

		private DateTime configWriteTime;

		private float nextConfigPoll;

		private Harmony harmony;

		public void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("SpecialCircumstances.UITweaks");
			Feature("ForgeSmartToggle", "ForgeSmartToggle", delegate
			{
				HybridForgePatch.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("InscryptionWarning", "InscryptionWarning", delegate
			{
				MapHintPatch.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("RerollConfirmation", "RerollConfirmation", delegate
			{
				RerollGoldThreshold.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("JudgesScales", null, delegate
			{
				JudgesScalesHandSelection.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("TitanTransitions", null, delegate
			{
				UITweaks.TitanTransitions.TitanTransitions.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("GreedBlights", null, delegate
			{
				GreedBlightAura.Init(((BaseUnityPlugin)this).Config);
			});
			Feature("DeckColumns", null, delegate
			{
				UITweaks.DeckColumns.DeckColumns.Init(((BaseUnityPlugin)this).Config);
			});
			configWriteTime = ReadConfigWriteTime();
			Logger.LogInfo((object)"Plugin SpecialCircumstances.UITweaks is loaded!");
		}

		private void Feature(string name, string? standaloneGuid, Action init)
		{
			init();
			if (standaloneGuid != null && IsLoaded(standaloneGuid))
			{
				Logger.LogInfo((object)(name + ": off, the " + standaloneGuid + " plugin is loaded and provides it."));
				return;
			}
			string text = "UITweaks." + name;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (type.Namespace == text)
				{
					harmony.PatchAll(type);
				}
			}
		}

		private static bool IsLoaded(string standaloneGuid)
		{
			if (!Chainloader.PluginInfos.ContainsKey(standaloneGuid))
			{
				return Chainloader.PluginInfos.ContainsKey("SpecialCircumstances." + standaloneGuid);
			}
			return true;
		}

		public void Update()
		{
			PollConfig();
			JudgesScalesHandSelection.KeepDiscardButtonSelected();
		}

		private void PollConfig()
		{
			if (Time.realtimeSinceStartup < nextConfigPoll)
			{
				return;
			}
			nextConfigPoll = Time.realtimeSinceStartup + 1f;
			DateTime dateTime = ReadConfigWriteTime();
			if (!(dateTime == configWriteTime))
			{
				configWriteTime = dateTime;
				try
				{
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch (Exception ex)
				{
					Logger.LogWarning((object)("Could not reload the config file: " + ex.Message));
					return;
				}
				configWriteTime = ReadConfigWriteTime();
				Logger.LogDebug((object)"Config reloaded.");
			}
		}

		private DateTime ReadConfigWriteTime()
		{
			try
			{
				return File.GetLastWriteTimeUtc(((BaseUnityPlugin)this).Config.ConfigFilePath);
			}
			catch (Exception ex)
			{
				Logger.LogDebug((object)("Could not stat the config file: " + ex.Message));
				return configWriteTime;
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SpecialCircumstances.UITweaks";

		public const string PLUGIN_NAME = "UITweaks";

		public const string PLUGIN_VERSION = "0.1.0";
	}
}
namespace UITweaks.TitanTransitions
{
	internal static class TitanTransitions
	{
		[HarmonyPatch(typeof(TimeScaleManager), "RefreshTimeScale")]
		private static class Multiply
		{
			private static void Postfix()
			{
				if (boosting && Enabled.Value)
				{
					Time.timeScale *= speedFactor.Value;
				}
			}
		}

		[HarmonyPatch(typeof(MapScreen), "TransitionOutOfBattle")]
		private static class MapSkipped
		{
			private static bool Prefix(MapScreen __instance, SaveManager ___saveManager, RelicManager ___relicManager, GameStateManager ___gameStateManager)
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Invalid comparison between Unknown and I4
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Invalid comparison between Unknown and I4
				if (!Enabled.Value || (Object)(object)___saveManager == (Object)null)
				{
					return true;
				}
				VictorySectionState victorySectionState = ___saveManager.GetVictorySectionState();
				if ((int)victorySectionState != 1)
				{
					if ((int)victorySectionState == 2 && (int)___saveManager.GetVictoryTypeAfterGameOver() == 2)
					{
						Plugin.Logger.LogDebug((object)"Titan transition: skipping the map's victory lap, ending the run.");
						___saveManager.SetGameSequence((GameSequence)3, true);
						((MonoBehaviour)__instance).StartCoroutine(NextFrame(delegate
						{
							___gameStateManager.EndGame((EndGameReason)0);
						}));
						return false;
					}
					return true;
				}
				Plugin.Logger.LogDebug((object)"Titan transition: skipping the map's run-up, loading the battle.");
				___saveManager.SetGameSequence((GameSequence)3, true);
				((MonoBehaviour)__instance).StartCoroutine(NextFrame(delegate
				{
					___relicManager.ApplyDepartDestinationRelicEffects();
					___saveManager.LoadScenario();
				}));
				return false;
			}

			private static IEnumerator NextFrame(Action action)
			{
				yield return null;
				action();
			}
		}

		[HarmonyPatch(typeof(MapScreen), "Initialize")]
		private static class VictoryLap
		{
			private static void Postfix(SaveManager ___saveManager)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Invalid comparison between Unknown and I4
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				Boost((Object)(object)___saveManager != (Object)null && (int)___saveManager.GetVictorySectionState() == 2 && (int)___saveManager.GetVictoryTypeAfterGameOver() != 2);
			}
		}

		[HarmonyPatch(typeof(GameStateManager), "EndGame")]
		private static class RunOver
		{
			private static void Prefix()
			{
				Boost(on: false);
			}
		}

		[HarmonyPatch(typeof(CombatManager), "StartCombat")]
		private static class BattleStart
		{
			private static void Prefix()
			{
				Boost(on: false);
			}
		}

		[HarmonyPatch(typeof(HeroManager), "BeginInitialSpawn")]
		private static class BattleOpening
		{
			private static IEnumerator Postfix(IEnumerator __result, HeroManager __instance)
			{
				if (!__instance.IsTrueFinalBoss)
				{
					return __result;
				}
				return Sped(__result);
			}
		}

		[HarmonyPatch(typeof(HeroManager), "DoTrueFinalBossSpawning")]
		private static class TitanArrival
		{
			private static IEnumerator Postfix(IEnumerator __result)
			{
				return Sped(__result);
			}
		}

		[HarmonyPatch(typeof(HeroManager), "PerformHellforgedBossRelentlessAction")]
		private static class FloorsTornDown
		{
			private static IEnumerator Postfix(IEnumerator __result)
			{
				return Sped(__result);
			}
		}

		[HarmonyPatch(typeof(CombatManager), "ShowKillCam")]
		private static class TitanFalls
		{
			private static void Prefix(CharacterState killedCharacter)
			{
				if ((Object)(object)killedCharacter != (Object)null && killedCharacter.IsTrueFinalBoss())
				{
					Boost(on: true);
				}
			}
		}

		[HarmonyPatch(typeof(GameScreen), "ShowVictoryUI")]
		private static class VictoryScreen
		{
			private static void Prefix()
			{
				Boost(on: false);
			}
		}

		internal const string Section = "TitanTransitions";

		internal static ConfigEntry<bool> Enabled;

		private static ConfigEntry<float> speedFactor;

		private static bool boosting;

		public static void Init(ConfigFile config)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			Enabled = config.Bind<bool>("TitanTransitions", "Enabled", true, "Skip the map's run-up to the Titan and its victory lap after the Titan falls, and speed the Titan's arrival, the floors it destroys and its death up in the battle.");
			speedFactor = config.Bind<float>("TitanTransitions", "SpeedFactor", 5f, new ConfigDescription("How many times faster the sped-up sequences run. 1 is the game's own pace.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
		}

		internal static void Boost(bool on)
		{
			if (boosting == on)
			{
				return;
			}
			boosting = on;
			Plugin.Logger.LogDebug((object)(on ? "Titan transition: speeding up." : "Titan transition: normal speed."));
			AllGameManagers instance = AllGameManagers.Instance;
			if (instance != null)
			{
				TimeScaleManager timeScaleManager = instance.GetTimeScaleManager();
				if (timeScaleManager != null)
				{
					timeScaleManager.RefreshTimeScale();
				}
			}
		}

		private static IEnumerator Sped(IEnumerator inner)
		{
			Boost(on: true);
			try
			{
				while (inner.MoveNext())
				{
					yield return inner.Current;
				}
			}
			finally
			{
				Boost(on: false);
			}
		}
	}
}
namespace UITweaks.RerollConfirmation
{
	[HarmonyPatch(typeof(BuyButton), "Refresh")]
	internal static class BuyButton_RerollWarning_Patch
	{
		private const string WarningSuffix = " <color=#FF3B3B><b>!</b></color>";

		private static void Postfix(BuyButton __instance)
		{
			if (!RerollGoldThreshold.Enabled.Value)
			{
				return;
			}
			MerchantGoodUIBase componentInParent = ((Component)__instance).GetComponentInParent<MerchantGoodUIBase>();
			object obj;
			if (componentInParent == null)
			{
				obj = null;
			}
			else
			{
				MerchantGoodState goodState = componentInParent.GoodState;
				obj = ((goodState != null) ? ((RewardState)goodState).RewardData : null);
			}
			if (!(obj is RerollMerchantRewardData) || !componentInParent.Affordable)
			{
				return;
			}
			AllGameManagers instance = AllGameManagers.Instance;
			SaveManager val = ((instance != null) ? instance.GetSaveManager() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Traverse val2 = Traverse.Create((object)__instance);
			TMP_Text value = val2.Field<TMP_Text>("label").Value;
			if (!((Object)(object)value == (Object)null))
			{
				MerchantData value2 = Traverse.Create((object)componentInParent).Field<MerchantData>("merchantData").Value;
				if (val.GetGold() - val2.Field<int>("cost").Value < RerollGoldThreshold.GetMinimumGoldAfterReroll(value2, val))
				{
					value.text += " <color=#FF3B3B><b>!</b></color>";
				}
			}
		}
	}
	[HarmonyPatch(typeof(MerchantScreen), "TryPurchase")]
	internal static class MerchantScreen_RerollConfirmation_Patch
	{
		private static bool suppressConfirmation;

		private static bool Prefix(MerchantScreen __instance, MerchantGoodUIBase goodUI)
		{
			if (suppressConfirmation || !RerollGoldThreshold.Enabled.Value)
			{
				return true;
			}
			MerchantGoodUIBase obj = goodUI;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				MerchantGoodState goodState = obj.GoodState;
				obj2 = ((goodState != null) ? ((RewardState)goodState).RewardData : null);
			}
			if (!(obj2 is RerollMerchantRewardData))
			{
				return true;
			}
			SaveManager value = Traverse.Create((object)__instance).Field<SaveManager>("saveManager").Value;
			MerchantData value2 = Traverse.Create((object)__instance).Field<MerchantData>("sourceMerchantData").Value;
			int cost = goodUI.GoodState.GetCost(value2);
			if (!value.CanAfford(cost))
			{
				return true;
			}
			int num = value.GetGold() - cost;
			int minimumGoldAfterReroll = RerollGoldThreshold.GetMinimumGoldAfterReroll(value2, value);
			if (num >= minimumGoldAfterReroll)
			{
				return true;
			}
			Traverse.Create((object)__instance).Field<ScreenManager>("screenManager").Value.ShowConfirmationDialog($"Rerolling will leave you with only {num} gold. Reroll anyway?", (Action)delegate
			{
				suppressConfirmation = true;
				try
				{
					Traverse.Create((object)__instance).Method("TryPurchase", new object[1] { goodUI }).GetValue();
				}
				finally
				{
					suppressConfirmation = false;
				}
			}, (Action)null, (Anchor)0, false);
			return false;
		}
	}
	internal static class RerollGoldThreshold
	{
		internal const string Section = "RerollConfirmation";

		internal static ConfigEntry<bool> Enabled;

		private static ConfigEntry<int> trinketShopThreshold;

		private static ConfigEntry<int> otherShopThreshold;

		private const string TrinketShopAssetNameMarker = "ArtifactMerchant";

		private const string GuildMarkerRelicAssetKey = "CheaperMerchants";

		private const double GuildMarkerDiscountMultiplier = 0.75;

		public static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("RerollConfirmation", "Enabled", true, "Warn before a shop reroll drops gold below the shop's minimum: a red ! on the reroll button, then a confirmation dialog.");
			trinketShopThreshold = config.Bind<int>("RerollConfirmation", "TrinketShopMinimumGold", 135, "Minimum gold to keep after a reroll at the Trinket (Merchant of Trinkets) shop before warning.");
			otherShopThreshold = config.Bind<int>("RerollConfirmation", "OtherShopMinimumGold", 90, "Minimum gold to keep after a reroll at other shops (Card/Steel/Arms/Magic) before warning.");
		}

		public static int GetMinimumGoldAfterReroll(MerchantData? merchantData, SaveManager? saveManager)
		{
			int num = (((Object)(object)merchantData != (Object)null && ((Object)merchantData).name.Contains("ArtifactMerchant")) ? trinketShopThreshold.Value : otherShopThreshold.Value);
			if (!((Object)(object)saveManager != (Object)null) || !saveManager.GetAllRelics().Any((RelicState relic) => relic.GetAssetName() == "CheaperMerchants"))
			{
				return num;
			}
			return (int)Math.Round((double)num * 0.75);
		}
	}
}
namespace UITweaks.JudgesScales
{
	internal static class JudgesScalesHandSelection
	{
		internal const string Section = "JudgesScales";

		internal static ConfigEntry<bool> Enabled = null;

		private static ConfigEntry<string> selectedCardTint = null;

		internal static bool Active;

		internal static readonly List<CardState> Selected = new List<CardState>();

		internal static GameUISelectableButton? ConfirmButton;

		internal static HandUI? Hand;

		private static readonly FieldInfo FocusedCardUI = AccessTools.Field(typeof(HandUI), "focusedCardUI");

		private static readonly FieldInfo CardFrontTinter = AccessTools.Field(typeof(CardUI), "cardFrontTinter");

		private static readonly FieldInfo GraphicsToTint = AccessTools.Field(typeof(ContentTinter), "graphicsToTint");

		private static readonly FieldInfo TintColor = AccessTools.Field(typeof(ContentTinter), "tintColor");

		private static readonly FieldInfo OverlaysToShow = AccessTools.Field(typeof(ContentTinter), "overlaysToShow");

		private static readonly FieldInfo OverlayColor = AccessTools.Field(typeof(ContentTinter), "overlayColor");

		private static readonly FieldInfo ControlChildTinters = AccessTools.Field(typeof(ContentTinter), "controlChildContentTinters");

		private static readonly FieldInfo DontTintColored = AccessTools.Field(typeof(ContentTinter), "dontTintColoredGraphics");

		private static Color? configuredTint;

		private static Color? appliedTint;

		public static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("JudgesScales", "Enabled", true, "Pick the cards Judge's Scales discards all at once: a click marks a card where it sits in hand, and one Discard button discards every marked card and draws that many.");
			selectedCardTint = config.Bind<string>("JudgesScales", "SelectedCardTint", "", "Colour of the cards picked for discard, as hex RRGGBB or RRGGBBAA (808080 is a mid grey). Empty: the grey the game uses for ineligible cards. A change applies at once, even while picking.");
			config.SettingChanged += delegate(object _, SettingChangedEventArgs args)
			{
				if (args.ChangedSetting.Definition.Section == "JudgesScales")
				{
					Retint();
				}
			};
			Retint();
		}

		internal static bool CannotDiscard(CardState card)
		{
			if (!card.HasTrait<CardTraitInfusion>())
			{
				return card.HasTrait<CardTraitPersistent>();
			}
			return true;
		}

		internal static bool IsSelected(CardUI cardUI)
		{
			if ((Object)(object)cardUI != (Object)null)
			{
				return Selected.Contains(cardUI.GetCardState());
			}
			return false;
		}

		internal static List<(int index, CardState card)> SelectedByHandIndexDescending()
		{
			List<(int, CardState)> list = new List<(int, CardState)>();
			if ((Object)(object)Hand == (Object)null)
			{
				return list;
			}
			List<CardUI> cardUIList = Hand.GetCardUIList();
			for (int num = cardUIList.Count - 1; num >= 0; num--)
			{
				if (IsSelected(cardUIList[num]))
				{
					list.Add((num, cardUIList[num].GetCardState()));
				}
			}
			return list;
		}

		private static IEnumerable<CardUI> CardUIs()
		{
			if ((Object)(object)Hand == (Object)null)
			{
				yield break;
			}
			foreach (CardUI cardUI in Hand.GetCardUIList())
			{
				yield return cardUI;
			}
			object? value = FocusedCardUI.GetValue(Hand);
			CardUI val = (CardUI)((value is CardUI) ? value : null);
			if (val != null)
			{
				yield return val;
			}
		}

		internal static void Reset()
		{
			UntintSelected();
			Active = false;
			Selected.Clear();
			ConfirmButton = null;
			Hand = null;
		}

		internal static void RefreshLook(CardUI cardUI)
		{
			CardState cardState = cardUI.GetCardState();
			if (cardState != null && !CannotDiscard(cardState))
			{
				bool flag = Selected.Contains(cardState);
				Tint(cardUI, flag);
				if (flag)
				{
					cardUI.SetEdgeFxActive((EdgeHighlight)0, true);
				}
			}
		}

		internal static void RefreshAllLooks()
		{
			foreach (CardUI item in CardUIs())
			{
				RefreshLook(item);
			}
		}

		internal static void RefreshButtons(GameUISelectableButton confirm, TMP_Text confirmLabel, GameUISelectableButton cancel)
		{
			int count = Selected.Count;
			((Component)confirm).gameObject.SetActive(count > 0);
			((Component)cancel).gameObject.SetActive(count == 0);
			confirmLabel.text = LocalizationExtensions.Localize("ScreenDeck_Discard_Action", (ILocalizationParameterContext)null) + ((count > 1) ? $" ({count})" : string.Empty);
		}

		internal static void Retint()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			string text = selectedCardTint?.Value?.Trim().TrimStart('#') ?? string.Empty;
			Color? val = null;
			if (text.Length > 0)
			{
				Color value = default(Color);
				if (ColorUtility.TryParseHtmlString("#" + text, ref value))
				{
					val = value;
				}
				else
				{
					Plugin.Logger.LogWarning((object)("[Judge's Scales] SelectedCardTint '" + text + "' is not a hex colour; using the game's grey."));
				}
			}
			configuredTint = val;
			if (Active)
			{
				UntintSelected();
				appliedTint = configuredTint;
				RefreshAllLooks();
			}
		}

		private static void UntintSelected()
		{
			foreach (CardUI item in CardUIs())
			{
				if (IsSelected(item))
				{
					Tint(item, on: false);
				}
			}
		}

		internal static void Tint(CardUI card, bool on)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			if ((Object)(object)card == (Object)null)
			{
				return;
			}
			object? value = CardFrontTinter.GetValue(card);
			ContentTinter val = (ContentTinter)((value is ContentTinter) ? value : null);
			if (val != null)
			{
				if (on)
				{
					appliedTint = configuredTint;
				}
				Color? val2 = appliedTint;
				if (val2.HasValue)
				{
					Color valueOrDefault = val2.GetValueOrDefault();
					Apply(val, on ? new Color?(valueOrDefault) : ((Color?)null), valueOrDefault);
				}
				else
				{
					val.Toggle(on);
				}
			}
		}

		private static void Apply(ContentTinter tinter, Color? colour, Color previous)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			Color val = (Color)TintColor.GetValue(tinter);
			bool flag = (bool)DontTintColored.GetValue(tinter);
			foreach (Graphic item in (List<Graphic>)GraphicsToTint.GetValue(tinter))
			{
				if (!((Object)(object)item == (Object)null))
				{
					Color color = item.color;
					if (!flag || color == Color.white || color == previous || color == val)
					{
						Color val2 = (Color)(((??)colour) ?? Color.white);
						item.color = new Color(val2.r, val2.g, val2.b, color.a);
					}
				}
			}
			Color val3 = (Color)OverlayColor.GetValue(tinter);
			foreach (Graphic item2 in (List<Graphic>)OverlaysToShow.GetValue(tinter))
			{
				if ((Object)(object)item2 != (Object)null)
				{
					item2.color = (colour.HasValue ? val3 : Color.clear);
				}
			}
			if (!(bool)ControlChildTinters.GetValue(tinter))
			{
				return;
			}
			ContentTinter[] componentsInChildren = ((Component)tinter).GetComponentsInChildren<ContentTinter>();
			foreach (ContentTinter val4 in componentsInChildren)
			{
				if ((Object)(object)val4 != (Object)(object)tinter)
				{
					Apply(val4, colour, previous);
				}
			}
		}

		internal static void KeepDiscardButtonSelected()
		{
			if (Active && Selected.Count != 0 && !((Object)(object)ConfirmButton == (Object)null) && ((Component)ConfirmButton).gameObject.activeInHierarchy)
			{
				InputManager inst = InputManager.Inst;
				if (!((Object)(object)inst == (Object)null) && ((CoreInput)inst).currentInputModeUsesNavigation && !((Object)(object)EventSystem.current == (Object)null) && !((Object)(object)EventSystem.current.currentSelectedGameObject != (Object)null))
				{
					inst.SelectGameUIComponent((IGameUIComponent)(object)ConfirmButton, true, false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(RelicEffectChooseDiscardsDrawReplacementsOnPostOpeningDraw), "ApplyEffectOnPostOpeningDraw")]
	internal static class JudgesScalesDiscardAtOncePatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__Reset;

			public static CardStateChosenDelegate <1>__DiscardSelected;

			public static CancelledDelegate <2>__KeepHand;

			public static FilterCardStateDelegate <3>__CannotDiscard;
		}

		private static bool Prefix(ICoreGameManagers coreGameManagers, ref IEnumerator __result)
		{
			if (!JudgesScalesHandSelection.Enabled.Value)
			{
				return true;
			}
			AllGameManagers instance = AllGameManagers.Instance;
			ReplayManager val = ((instance != null) ? instance.GetReplayManager() : null);
			if (val != null && val.IsPlayingBackAReplay())
			{
				Plugin.Logger.LogDebug((object)"Judge's Scales: a replay is playing back, leaving the discard flow to the game.");
				return true;
			}
			__result = Run(coreGameManagers);
			return false;
		}

		private static IEnumerator Run(ICoreGameManagers coreGameManagers)
		{
			CardManager cardManager = coreGameManagers.GetCardManager();
			AnimationTimingData animationTimingData = coreGameManagers.GetAllGameData().GetBalanceData().GetAnimationTimingData();
			JudgesScalesHandSelection.Reset();
			JudgesScalesHandSelection.Active = true;
			cardManager.AddSelectCardFromHandOnCompletedCallback((Action)JudgesScalesHandSelection.Reset);
			Params val = new Params
			{
				descriptionKey = "ScreenDeck_Select_CardEffectChooseDiscard",
				overrideActionKey = "ScreenDeck_Discard_Action",
				overrideCancelKey = "ScreenDeck_DiscardComplete_Action"
			};
			object obj = <>O.<1>__DiscardSelected;
			if (obj == null)
			{
				CardStateChosenDelegate val2 = DiscardSelected;
				<>O.<1>__DiscardSelected = val2;
				obj = (object)val2;
			}
			val.cardChosenCallback = (CardStateChosenDelegate)obj;
			object obj2 = <>O.<2>__KeepHand;
			if (obj2 == null)
			{
				CancelledDelegate val3 = KeepHand;
				<>O.<2>__KeepHand = val3;
				obj2 = (object)val3;
			}
			val.cancelledCallback = (CancelledDelegate)obj2;
			object obj3 = <>O.<3>__CannotDiscard;
			if (obj3 == null)
			{
				FilterCardStateDelegate val4 = JudgesScalesHandSelection.CannotDiscard;
				<>O.<3>__CannotDiscard = val4;
				obj3 = (object)val4;
			}
			val.filterCallback = (FilterCardStateDelegate)obj3;
			val.instantApplyDelay = animationTimingData.cardDrawAnimationDuration;
			val.disableIneligibleCards = true;
			val.allowShowCancel = true;
			val.selectionHandState = (CardUIState)9;
			yield return cardManager.SelectCardFromHand(val, false);
		}

		private static IEnumerator DiscardSelected(CardState chosenCard, CardManager cardManager)
		{
			List<(int index, CardState card)> cards = JudgesScalesHandSelection.SelectedByHandIndexDescending();
			JudgesScalesHandSelection.Reset();
			if (cards.Count == 0)
			{
				yield break;
			}
			AllGameManagers instance = AllGameManagers.Instance;
			ReplayManager replay = ((instance != null) ? instance.GetReplayManager() : null);
			for (int i = 0; i < cards.Count; i++)
			{
				var (num, discardCard) = cards[i];
				if (i > 0)
				{
					if (replay != null)
					{
						replay.RecordEntry((ReplayEntry)new ReplayEntryHandSelectionCard(num));
					}
				}
				yield return cardManager.DiscardCard(new DiscardCardParams
				{
					discardCard = discardCard,
					triggeredByCard = true,
					wasPlayed = false
				}, false);
				cardManager.RefreshHandCards(true, false);
			}
			if (cardManager.GetHand(false).Any((CardState card) => !JudgesScalesHandSelection.CannotDiscard(card)))
			{
				if (replay != null)
				{
					replay.RecordEntry((ReplayEntry)new ReplayEntryHandSelectionDone());
				}
			}
			cardManager.DrawCards(cards.Count, (CardState)null, (CardType)4, -1);
		}

		private static IEnumerator KeepHand(CardManager cardManager)
		{
			JudgesScalesHandSelection.Reset();
			yield break;
		}
	}
	[HarmonyPatch(typeof(HandUI), "ReplayHandSelection")]
	internal static class JudgesScalesReplayHandSelectionPatch
	{
		private const float ConfirmTimeoutSeconds = 2f;

		private static bool Prefix(int cardIndex, ref IEnumerator __result, HandUI __instance, HandSelectionUI ___handSelectionUI, List<CardUI> ___cardUIs)
		{
			__result = Replay(cardIndex, __instance, ___handSelectionUI, ___cardUIs);
			return false;
		}

		private static IEnumerator Replay(int cardIndex, HandUI handUI, HandSelectionUI handSelectionUI, List<CardUI> cardUIs)
		{
			if (!handUI.IsHandSelectionActive() || cardIndex < 0 || cardIndex >= cardUIs.Count)
			{
				Plugin.Logger.LogDebug((object)$"Replay of hand selection card {cardIndex}: overlay active {handUI.IsHandSelectionActive()}, {cardUIs.Count} cards in hand; nothing to do.");
				yield break;
			}
			bool flag = handSelectionUI.SelectCard(cardUIs[cardIndex]);
			Plugin.Logger.LogDebug((object)$"Replay of hand selection card {cardIndex}: SelectCard returned {flag}.");
			if (!flag)
			{
				yield break;
			}
			yield return null;
			float started = Time.unscaledTime;
			while (Time.unscaledTime - started < 2f)
			{
				if (ReplayManager.TryClickButton((MonoBehaviour)(object)handSelectionUI.GetConfirmButton()))
				{
					Plugin.Logger.LogDebug((object)$"Replay of hand selection card {cardIndex}: confirmed after {Time.unscaledTime - started:f2}s.");
					yield break;
				}
				yield return null;
			}
			Plugin.Logger.LogWarning((object)$"Replay of hand selection card {cardIndex}: the confirm button never became clickable.");
		}
	}
	[HarmonyPatch(typeof(HandSelectionUI), "SelectCard")]
	internal static class JudgesScalesToggleCardPatch
	{
		private static bool Prefix(CardUI cardUI, ref bool __result, HandUI ___handUI, GameUISelectableButton ___confirmButton, TMP_Text ___confirmButtonLabel, GameUISelectableButton ___cancelButton)
		{
			if (!JudgesScalesHandSelection.Active)
			{
				return true;
			}
			JudgesScalesHandSelection.ConfirmButton = ___confirmButton;
			JudgesScalesHandSelection.Hand = ___handUI;
			CardState cardState = cardUI.GetCardState();
			List<CardState> selected = JudgesScalesHandSelection.Selected;
			if (!selected.Remove(cardState))
			{
				selected.Add(cardState);
				if (((CoreInput)InputManager.Inst).currentInputModeUsesNavigation)
				{
					InputManager.Inst.SelectGameUIComponent((IGameUIComponent)(object)___confirmButton, true, false);
				}
			}
			JudgesScalesHandSelection.RefreshAllLooks();
			JudgesScalesHandSelection.RefreshButtons(___confirmButton, ___confirmButtonLabel, ___cancelButton);
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(HandSelectionUI), "UnSelectCard")]
	internal static class JudgesScalesUnselectAllPatch
	{
		private static void Prefix(GameUISelectableButton ___confirmButton, TMP_Text ___confirmButtonLabel, GameUISelectableButton ___cancelButton)
		{
			if (JudgesScalesHandSelection.Active && JudgesScalesHandSelection.Selected.Count != 0)
			{
				JudgesScalesHandSelection.Selected.Clear();
				JudgesScalesHandSelection.RefreshAllLooks();
				JudgesScalesHandSelection.RefreshButtons(___confirmButton, ___confirmButtonLabel, ___cancelButton);
			}
		}
	}
	[HarmonyPatch(typeof(HandSelectionUI), "Finish")]
	internal static class JudgesScalesFinishPatch
	{
		private static void Prefix(ref CardUI ___currentlySelectedCardUI, HandUI ___handUI)
		{
			if (JudgesScalesHandSelection.Active && JudgesScalesHandSelection.Selected.Count != 0)
			{
				___currentlySelectedCardUI = ((IEnumerable<CardUI>)___handUI.GetCardUIList()).LastOrDefault((Func<CardUI, bool>)JudgesScalesHandSelection.IsSelected);
			}
		}
	}
	[HarmonyPatch(typeof(HandUI), "UpdateCardUIAtEndOfFrame")]
	internal static class JudgesScalesCardLookPatch
	{
		private static void Postfix(CardUI cardUI)
		{
			if (JudgesScalesHandSelection.Active)
			{
				JudgesScalesHandSelection.RefreshLook(cardUI);
			}
		}
	}
}
namespace UITweaks.InscryptionWarning
{
	internal sealed class SharedNodeMarker : MonoBehaviour
	{
	}
	internal static class MapHintPatch
	{
		internal enum CueColor
		{
			Gold,
			Red,
			Blue
		}

		internal enum CueStyle
		{
			Diegetic,
			Icon,
			Debug
		}

		private static class EventStartLocator
		{
			private static readonly MethodInfo? ActiveSaveDataGetter = AccessTools.PropertyGetter(typeof(SaveManager), "ActiveSaveData");

			private static readonly FieldInfo? ConditionsField = AccessTools.Field(typeof(FollowupEventState), "conditions");

			private static readonly FieldInfo? ConditionDataField = AccessTools.Field(typeof(FollowupConditionState), "data");

			private static readonly FieldInfo? StartDistanceField = AccessTools.Field(typeof(FollowupConditionState), "startDistance");

			private static int resolvedFrame = -1;

			private static int? cached;

			internal static bool Available
			{
				get
				{
					if (ActiveSaveDataGetter != null && ConditionsField != null && ConditionDataField != null)
					{
						return StartDistanceField != null;
					}
					return false;
				}
			}

			internal static void LogAvailability()
			{
				if (!Available)
				{
					Plugin.Logger.LogError((object)("Cannot read the Inscryption event's start distance from the save — the game's internals have moved. No hint will be shown. Missing: " + $"SaveManager.ActiveSaveData={ActiveSaveDataGetter != null}, " + $"FollowupEventState.conditions={ConditionsField != null}, " + $"FollowupConditionState.data={ConditionDataField != null}, " + $"FollowupConditionState.startDistance={StartDistanceField != null}"));
				}
			}

			internal static int? Resolve(SaveManager saveManager)
			{
				if (resolvedFrame == Time.frameCount)
				{
					return cached;
				}
				resolvedFrame = Time.frameCount;
				int? num = Lookup(saveManager);
				if (num != cached)
				{
					Plugin.Logger.LogDebug((object)((!num.HasValue) ? $"Inscryption followup no longer active (was startDistance={cached})." : $"Inscryption followup active: startDistance={num}."));
					cached = num;
				}
				return cached;
			}

			private static int? Lookup(SaveManager saveManager)
			{
				if (!Available)
				{
					return null;
				}
				object? obj = ActiveSaveDataGetter.Invoke(saveManager, null);
				SaveData val = (SaveData)((obj is SaveData) ? obj : null);
				if (val == null)
				{
					return null;
				}
				List<FollowupEventState> activeFollowupEvents = val.GetActiveFollowupEvents();
				if (activeFollowupEvents == null)
				{
					return null;
				}
				int? num = null;
				foreach (FollowupEventState item in activeFollowupEvents)
				{
					if (item == null || !(ConditionsField.GetValue(item) is IEnumerable enumerable))
					{
						continue;
					}
					foreach (object item2 in enumerable)
					{
						if (item2 == null)
						{
							continue;
						}
						object? value = ConditionDataField.GetValue(item2);
						FollowupConditionData val2 = (FollowupConditionData)((value is FollowupConditionData) ? value : null);
						if (val2 != null && !(val2.ConditionName != "FollowupConditionInscryptionEvent"))
						{
							int num2 = (int)StartDistanceField.GetValue(item2);
							if (!num.HasValue || num2 > num)
							{
								num = num2;
							}
						}
					}
				}
				return num;
			}
		}

		[HarmonyPatch(typeof(MapSection), "SetUpNodesOnBranch")]
		private static class MarkSharedNodes
		{
			private static void Postfix(List<MapNodeUI> availableNodes, BranchSelection branch)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				if ((int)branch != -1 || availableNodes == null)
				{
					return;
				}
				foreach (MapNodeUI availableNode in availableNodes)
				{
					if ((Object)(object)availableNode != (Object)null && (Object)(object)((Component)availableNode).GetComponent<SharedNodeMarker>() == (Object)null)
					{
						((Component)availableNode).gameObject.AddComponent<SharedNodeMarker>();
					}
				}
			}
		}

		[HarmonyPatch(typeof(MapNodeUI), "RefreshState")]
		private static class HintNode
		{
			private static void Postfix(MapNodeUI __instance, SaveManager saveManager)
			{
				lastSaveManager = saveManager;
				GameObject orCreateOverlay = GetOrCreateOverlay(__instance);
				if (!ShouldShowHint(__instance, saveManager))
				{
					orCreateOverlay.SetActive(false);
					return;
				}
				ApplyStyle(orCreateOverlay);
				orCreateOverlay.SetActive(true);
			}
		}

		internal const string Section = "InscryptionWarning";

		private const string OverlayName = "UITweaks_InscryptionHint";

		private const int GlowTextureSize = 128;

		private const float GlowCoreRadius = 0.2f;

		private const float DiegeticHaloScale = 1.5f;

		private static ConfigEntry<bool> enabled = null;

		private static ConfigEntry<CueStyle> style = null;

		private static ConfigEntry<CueColor> cueColor = null;

		private static ConfigEntry<float> diegeticStrength = null;

		private static ConfigEntry<bool> verboseLogging = null;

		private static Sprite? softGlowSprite;

		private static readonly List<MapNodeUI> hintedNodes = new List<MapNodeUI>();

		private static SaveManager? lastSaveManager;

		private static int loggedPlanFor = int.MinValue;

		public static void Init(ConfigFile config)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			enabled = config.Bind<bool>("InscryptionWarning", "Enabled", true, "Highlight on the map the branch the Inscryption event's secret code asks for, at each of its three choices.");
			style = config.Bind<CueStyle>("InscryptionWarning", "CueStyle", CueStyle.Diegetic, "How obvious the hint is: Diegetic (a soft halo behind the correct node), Icon (a small visible badge), Debug (an unmissable magenta marker, for diagnosing rather than playing).");
			cueColor = config.Bind<CueColor>("InscryptionWarning", "CueColor", CueColor.Gold, "Colour of the Diegetic halo and the Icon badge: Gold (the original warm tint), Red, or Blue. Debug keeps its own magenta marker so it always stands out no matter what this is set to.");
			diegeticStrength = config.Bind<float>("InscryptionWarning", "DiegeticStrength", 0.6f, new ConfigDescription("Opacity of the Diegetic halo across its core and at the node icon's edge, fading to nothing at the halo's rim. Other cue styles ignore this.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			verboseLogging = config.Bind<bool>("InscryptionWarning", "VerboseLogging", false, "Log a line for every map node the hint is evaluated against. Very chatty — one burst per map refresh — so it is meant for diagnosing a missing cue, not for normal play. State changes (event found/lost, code, branch plan) are logged either way.");
			config.SettingChanged += delegate(object _, SettingChangedEventArgs args)
			{
				if (args.ChangedSetting.Definition.Section == "InscryptionWarning")
				{
					RefreshLiveOverlays();
				}
			};
			EventStartLocator.LogAvailability();
			SelfCheck();
			Plugin.Logger.LogDebug((object)($"MapHintPatch ready: Enabled={enabled.Value}, CueStyle={style.Value}, CueColor={cueColor.Value}, " + $"DiegeticStrength={diegeticStrength.Value}, VerboseLogging={verboseLogging.Value}"));
		}

		private static void RefreshLiveOverlays()
		{
			for (int num = hintedNodes.Count - 1; num >= 0; num--)
			{
				MapNodeUI val = hintedNodes[num];
				if ((Object)(object)val == (Object)null)
				{
					hintedNodes.RemoveAt(num);
				}
				else
				{
					Transform val2 = ((Component)val).transform.Find("UITweaks_InscryptionHint");
					if ((Object)(object)val2 == (Object)null)
					{
						hintedNodes.RemoveAt(num);
					}
					else if ((Object)(object)lastSaveManager != (Object)null && ShouldShowHint(val, lastSaveManager))
					{
						ApplyStyle(((Component)val2).gameObject);
						((Component)val2).gameObject.SetActive(true);
					}
					else
					{
						((Component)val2).gameObject.SetActive(false);
					}
				}
			}
		}

		internal static BranchSelection? GetHintedBranch(int startDistance, int nodeDistance, int code)
		{
			int num = nodeDistance - (startDistance + 1);
			if (num < 0 || num > 2)
			{
				return null;
			}
			return (BranchSelection)((((code >> 2 - num) & 1) != 0) ? 1 : 0);
		}

		private static void SelfCheck()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			if ((int)GetHintedBranch(10, 11, 5).GetValueOrDefault() != 1 || GetHintedBranch(10, 12, 5) != (BranchSelection?)0 || (int)GetHintedBranch(10, 13, 5).GetValueOrDefault() != 1 || GetHintedBranch(10, 10, 5).HasValue || GetHintedBranch(10, 14, 5).HasValue)
			{
				throw new InvalidOperationException("MapHintPatch.GetHintedBranch self-check failed");
			}
		}

		private static void LogBranchPlan(int startDistance, int code)
		{
			int num = startDistance * 8 + code;
			if (loggedPlanFor != num)
			{
				loggedPlanFor = num;
				string text = string.Empty;
				for (int i = 1; i <= 3; i++)
				{
					BranchSelection? hintedBranch = GetHintedBranch(startDistance, startDistance + i, code);
					text += $" d{startDistance + i}={hintedBranch}";
				}
				Plugin.Logger.LogDebug((object)($"Inscryption path code={code} (binary {Convert.ToString(code, 2).PadLeft(3, '0')}), " + $"startDistance={startDistance}, hinting:{text}"));
			}
		}

		private static bool ShouldShowHint(MapNodeUI node, SaveManager saveManager)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled.Value || (Object)(object)saveManager == (Object)null)
			{
				return false;
			}
			int? num = EventStartLocator.Resolve(saveManager);
			if (!num.HasValue)
			{
				return false;
			}
			if (saveManager.GetInscryptionEventSuccessfullyCompleted())
			{
				return false;
			}
			Location location = node.GetLocation();
			if (location == null)
			{
				if (verboseLogging.Value)
				{
					Plugin.Logger.LogDebug((object)("Node '" + ((Object)node).name + "' has no location — skipped."));
				}
				return false;
			}
			if ((Object)(object)((Component)node).GetComponent<SharedNodeMarker>() != (Object)null)
			{
				if (verboseLogging.Value)
				{
					Plugin.Logger.LogDebug((object)($"Node '{((Object)node).name}' distance={location.Distance} is shared/pact " + "(GetBranch() reports LeftBranch for these regardless) -> hide"));
				}
				return false;
			}
			int inscryptionEventPath = saveManager.GetInscryptionEventPath();
			LogBranchPlan(num.Value, inscryptionEventPath);
			BranchSelection? hintedBranch = GetHintedBranch(num.Value, location.Distance, inscryptionEventPath);
			bool flag = hintedBranch.HasValue && (BranchSelection?)node.GetBranch() == hintedBranch;
			if (verboseLogging.Value)
			{
				Plugin.Logger.LogDebug((object)($"Node '{((Object)node).name}' distance={location.Distance} branch={node.GetBranch()} " + "hinted=" + ((hintedBranch.HasValue ? ((object)hintedBranch.GetValueOrDefault()/*cast due to .constrained prefix*/).ToString() : null) ?? "none") + " -> " + (flag ? "SHOW" : "hide")));
			}
			return flag;
		}

		private static GameObject GetOrCreateOverlay(MapNodeUI node)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			Transform val = ((Component)node).transform.Find("UITweaks_InscryptionHint");
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			GameObject val2 = new GameObject("UITweaks_InscryptionHint", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(((Component)node).transform, false);
			((Graphic)val2.GetComponent<Image>()).raycastTarget = false;
			hintedNodes.Add(node);
			return val2;
		}

		private static Sprite GetSoftGlowSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)softGlowSprite != (Object)null)
			{
				return softGlowSprite;
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = "UITweaks_InscryptionHint_Glow",
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
			Color32[] array = (Color32[])(object)new Color32[16384];
			float num = 63.5f;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num2 = ((float)j - num) / num;
					float num3 = ((float)i - num) / num;
					float num4 = Mathf.Clamp01(Mathf.Sqrt(num2 * num2 + num3 * num3));
					float num5 = Mathf.InverseLerp(0.2f, 1f, num4);
					float num6 = Mathf.SmoothStep(0f, 1f, 1f - num5);
					array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num6 * 255f));
				}
			}
			val.SetPixels32(array);
			val.Apply(false);
			softGlowSprite = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
			((Object)softGlowSprite).hideFlags = (HideFlags)61;
			return softGlowSprite;
		}

		private static Color ResolveCueColor(float alpha)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Color result = (Color)(cueColor.Value switch
			{
				CueColor.Gold => new Color(1f, 0.85f, 0.3f), 
				CueColor.Blue => new Color(0.25f, 0.55f, 1f), 
				_ => new Color(1f, 0.15f, 0.12f), 
			});
			result.a = alpha;
			return result;
		}

		private static void ApplyStyle(GameObject overlay)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)overlay.transform;
			Image component = overlay.GetComponent<Image>();
			switch (style.Value)
			{
			case CueStyle.Icon:
				overlay.transform.SetAsLastSibling();
				component.sprite = null;
				val.anchorMin = new Vector2(0.5f, 1f);
				val.anchorMax = new Vector2(0.5f, 1f);
				val.pivot = new Vector2(0.5f, 0.5f);
				val.sizeDelta = new Vector2(20f, 20f);
				val.anchoredPosition = Vector2.zero;
				((Graphic)component).color = ResolveCueColor(0.95f);
				break;
			case CueStyle.Debug:
				overlay.transform.SetAsLastSibling();
				component.sprite = null;
				val.anchorMin = Vector2.zero;
				val.anchorMax = Vector2.one;
				val.offsetMin = Vector2.zero;
				val.offsetMax = Vector2.zero;
				((Graphic)component).color = new Color(1f, 0.1f, 0.9f, 0.8f);
				break;
			default:
			{
				overlay.transform.SetAsFirstSibling();
				component.sprite = GetSoftGlowSprite();
				float num = 0.25f;
				val.anchorMin = new Vector2(0f - num, 0f - num);
				val.anchorMax = new Vector2(1f + num, 1f + num);
				val.offsetMin = Vector2.zero;
				val.offsetMax = Vector2.zero;
				((Graphic)component).color = ResolveCueColor(diegeticStrength.Value);
				break;
			}
			}
		}
	}
}
namespace UITweaks.GreedBlights
{
	internal static class GreedBlightAura
	{
		[HarmonyPatch(typeof(CardUI), "SetEdgeFxActive")]
		private static class GoldEdge
		{
			private static void Postfix(CardUI __instance)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				if (Enabled.Value && !(ChampionEdge == null) && (int)__instance.GetUIState() == 1 && DamagesPyre(__instance.GetCardState()) && GreedActive())
				{
					object? value = ChampionEdge.GetValue(__instance);
					Transform val = (Transform)((value is Transform) ? value : null);
					if (val != null)
					{
						((Component)val).gameObject.SetActive(true);
					}
				}
			}
		}

		internal const string Section = "GreedBlights";

		internal static ConfigEntry<bool> Enabled = null;

		private static readonly FieldInfo ChampionEdge = AccessTools.Field(typeof(CardUI), "_championEdgeFXTransform");

		private static int checkedFrame = -1;

		private static bool greedActive;

		public static void Init(ConfigFile config)
		{
			Enabled = config.Bind<bool>("GreedBlights", "Enabled", true, "With Fhyra's Greed (or any relic paying gold when the Pyre takes damage), give the Blights in hand that damage the Pyre a gold glow.");
			if (ChampionEdge == null)
			{
				Plugin.Logger.LogError((object)"CardUI._championEdgeFXTransform is gone; no Blight will glow.");
			}
		}

		private static bool GreedActive()
		{
			if (checkedFrame == Time.frameCount)
			{
				return greedActive;
			}
			checkedFrame = Time.frameCount;
			AllGameManagers instance = AllGameManagers.Instance;
			SaveManager val = ((instance != null) ? instance.GetSaveManager() : null);
			greedActive = (Object)(object)val != (Object)null && val.GetAllRelics().Any((RelicState relic) => relic.HasEffectOfType<RelicEffectAddGoldOnPyreDamage>());
			return greedActive;
		}

		internal static bool DamagesPyre(CardState? card)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (card == null || (int)card.GetCardType() != 5)
			{
				return false;
			}
			if (card.GetEffectStates().Any(DamagesPyre))
			{
				return true;
			}
			foreach (CardTriggerEffectState trigger in card.GetTriggers())
			{
				if (trigger.GetCardEffectParams().Any(DamagesPyre))
				{
					return true;
				}
			}
			return false;
		}

		private static bool DamagesPyre(CardEffectState effect)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (effect.GetCardEffect() is CardEffectDamage)
			{
				return (int)effect.GetTargetMode() == 21;
			}
			return false;
		}
	}
}
namespace UITweaks.ForgeSmartToggle
{
	internal enum ToggleOrder
	{
		NormalHybridDisabled,
		NormalDisabledHybrid
	}
	internal static class HybridForgePatch
	{
		[HarmonyPatch(typeof(SaveManager), "ToggleForgeActive")]
		private static class Cycle
		{
			private static bool nextHybrid;

			private static bool Prefix(SaveManager __instance)
			{
				if (!enabled.Value)
				{
					nextHybrid = false;
					return true;
				}
				(bool hybrid, bool flip) tuple = NextState(__instance.IsForgeToggleActive(), hybrid, toggleOrder.Value);
				bool item = tuple.hybrid;
				bool item2 = tuple.flip;
				nextHybrid = item;
				return item2;
			}

			private static void Postfix()
			{
				hybrid = nextHybrid;
			}
		}

		[HarmonyPatch(typeof(SaveManager), "SetForgeToggleActive")]
		private static class ClearOnDirectSet
		{
			private static void Prefix(SaveManager __instance, bool isActive)
			{
				if (__instance.IsForgeToggleActive() != isActive)
				{
					hybrid = false;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerManager), "OnCardPlayedPreEffectsFired")]
		private static class SkipForgeOnPlay
		{
			private static bool Prefix(CardState cardState, bool fromDirectPlay, ref IEnumerator __result)
			{
				if (!hybrid || !fromDirectPlay || cardState == null || !IsSkipped(cardState))
				{
					return true;
				}
				Plugin.Logger.LogDebug((object)("Hybrid forge: skipping '" + cardState.GetTitle() + "'"));
				__result = Nothing();
				return false;
			}

			private static IEnumerator Nothing()
			{
				yield break;
			}
		}

		[HarmonyPatch(typeof(ForgePointsUI), "SetStateForgingActive")]
		private static class MarkToggle
		{
			private static void Postfix(ForgePointsUI __instance)
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: 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)
				GameObject value = Traverse.Create((object)__instance).Field<GameObject>("forgingActiveToggle").Value;
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				RefreshBadge(__instance, value);
				Graphic componentInChildren = value.GetComponentInChildren<Graphic>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Color valueOrDefault = originalTint.GetValueOrDefault();
					if (!originalTint.HasValue)
					{
						valueOrDefault = componentInChildren.color;
						originalTint = valueOrDefault;
					}
					componentInChildren.color = (hybrid ? HybridTint : originalTint.Value);
				}
				Traverse.Create((object)__instance).Method("RefreshTooltip", Array.Empty<object>()).GetValue();
			}
		}

		[HarmonyPatch(typeof(ForgePointsUI), "SetTooltip")]
		private static class TooltipNote
		{
			private static void Prefix(ref string title, ref string body)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if (hybrid)
				{
					title += " (Hybrid)";
					string text = SkippedList();
					string text2 = ColorUtility.ToHtmlStringRGB(HybridTint);
					body += ((text.Length > 0) ? ("\n\n<b>Hybrid forging</b> (<color=#" + text2 + ">H</color> on the button): Forge Points are spent as usual, except on these units and cards, which are ignored:\n<color=#" + text2 + ">" + text + "</color>") : "\n\n<b>Hybrid forging</b>: nothing is ignored - both ignore lists in the [ForgeSmartToggle] section of BepInEx/config/SpecialCircumstances.UITweaks.cfg are empty.");
				}
			}
		}

		internal const string Section = "ForgeSmartToggle";

		private static ConfigEntry<bool> enabled = null;

		private static ConfigEntry<ToggleOrder> toggleOrder = null;

		private static ConfigEntry<string> skippedSubtypes = null;

		private static ConfigEntry<string> skippedCards = null;

		private static bool hybrid;

		private static Color? originalTint;

		private static TextMeshProUGUI? hybridBadge;

		private static readonly Color HybridTint = new Color(1f, 0.69f, 0.13f);

		public static void Init(ConfigFile config)
		{
			enabled = config.Bind<bool>("ForgeSmartToggle", "Enabled", true, "Enable the Hybrid forge state. When disabled, the toggle stays plain Off -> On -> Off.");
			toggleOrder = config.Bind<ToggleOrder>("ForgeSmartToggle", "ToggleOrder", ToggleOrder.NormalDisabledHybrid, "Order the forge toggle cycles the three states in.\nNormalHybridDisabled: Normal -> Hybrid -> Disabled -> Normal (one press from Disabled turns forging on as Normal).\nNormalDisabledHybrid: Normal -> Disabled -> Hybrid -> Normal (one press turns forging off again from Normal, and the press after that enters Hybrid).");
			skippedSubtypes = config.Bind<string>("ForgeSmartToggle", "SkippedSubtypes", "Morsel, Imp, Whelp, Steward", "Comma-separated unit subtypes that do NOT consume Forge Points while the forge toggle is in its Hybrid state. Matched case-insensitively as a substring of both the subtype key and its localized name.");
			skippedCards = config.Bind<string>("ForgeSmartToggle", "SkippedCards", "CraftedEquipment", "Comma-separated cards (units or equipment) that do NOT consume Forge Points while the forge toggle is in its Hybrid state. Matched case-insensitively as a substring of both the card's asset name (e.g. CraftedEquipment) and its localized title.");
			SelfCheck();
		}

		internal static bool Matches(string subtypeKey, string localizedName, string configuredList)
		{
			string[] array = configuredList.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0 && (subtypeKey.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || localizedName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					return true;
				}
			}
			return false;
		}

		internal static (bool hybrid, bool flip) NextState(bool active, bool inHybrid, ToggleOrder order)
		{
			if (order == ToggleOrder.NormalDisabledHybrid)
			{
				if (!(active && inHybrid))
				{
					return (hybrid: !active, flip: true);
				}
				return (hybrid: false, flip: false);
			}
			if (!active || inHybrid)
			{
				return (hybrid: false, flip: true);
			}
			return (hybrid: true, flip: false);
		}

		private static void SelfCheck()
		{
			if (!Matches("SubtypeData_Morsel", "Morsel", "Morsel, Imp, Whelp") || !Matches("SubtypeData_Imp", "Imp", "Morsel, Imp, Whelp") || !Matches("whatever", "Whelp", "Morsel, Imp, Whelp") || Matches("SubtypeData_Dragon", "Dragon", "Morsel, Imp, Whelp") || Matches("SubtypeData_Imp", "Imp", " , ") || !Matches("CraftedEquipment", "Crafted Equipment", "CraftedEquipment"))
			{
				throw new InvalidOperationException("HybridForgePatch.Matches self-check failed");
			}
			CycleSelfCheck(ToggleOrder.NormalHybridDisabled, (true, false), (true, true), (false, false), (true, false));
			CycleSelfCheck(ToggleOrder.NormalDisabledHybrid, (true, true), (true, false), (false, false), (true, true));
		}

		private static void CycleSelfCheck(ToggleOrder order, params (bool active, bool hybrid)[] presses)
		{
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < presses.Length; i++)
			{
				(bool, bool) tuple = presses[i];
				(bool hybrid, bool flip) tuple2 = NextState(flag, flag2, order);
				bool item = tuple2.hybrid;
				bool item2 = tuple2.flip;
				flag ^= item2;
				flag2 = item;
				if (flag != tuple.Item1 || flag2 != tuple.Item2)
				{
					throw new InvalidOperationException($"HybridForgePatch.NextState self-check failed for {order}");
				}
			}
		}

		private static bool IsSkipped(CardState card)
		{
			if (Matches(card.GetAssetName() ?? string.Empty, card.GetTitle() ?? string.Empty, skippedCards.Value))
			{
				return true;
			}
			CharacterData spawnCharacterData = card.GetSpawnCharacterData();
			List<SubtypeData> list = ((spawnCharacterData != null) ? spawnCharacterData.GetSubtypes() : null);
			if (list == null)
			{
				return false;
			}
			foreach (SubtypeData item in list)
			{
				if (Matches(item.Key ?? string.Empty, item.LocalizedName ?? string.Empty, skippedSubtypes.Value))
				{
					return true;
				}
			}
			return false;
		}

		private static string SkippedList()
		{
			IEnumerable<string> values = from entry in (skippedSubtypes.Value + "," + skippedCards.Value).Split(',')
				select entry.Trim() into entry
				where entry.Length > 0
				select entry;
			return string.Join(", ", values);
		}

		private static void RefreshBadge(ForgePointsUI ui, GameObject toggle)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hybridBadge == (Object)null)
			{
				TextMeshProUGUI value = Traverse.Create((object)ui).Field<TextMeshProUGUI>("countLabel").Value;
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				hybridBadge = Object.Instantiate<TextMeshProUGUI>(value, toggle.transform);
				((Object)hybridBadge).name = "HybridBadge";
				((TMP_Text)hybridBadge).text = "H";
				((TMP_Text)hybridBadge).fontSize = ((TMP_Text)value).fontSize * 0.65f;
				((Graphic)hybridBadge).color = HybridTint;
				((TMP_Text)hybridBadge).alignment = (TextAlignmentOptions)514;
				((Graphic)hybridBadge).raycastTarget = false;
				RectTransform rectTransform = ((TMP_Text)hybridBadge).rectTransform;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(1f, 0f);
				rectTransform.anchorMax = val;
				rectTransform.anchorMin = val;
				rectTransform.pivot = new Vector2(0.5f, 0.5f);
				rectTransform.anchoredPosition = Vector2.zero;
				rectTransform.sizeDelta = new Vector2(28f, 28f);
				((Transform)rectTransform).localScale = Vector3.one;
			}
			((Component)hybridBadge).gameObject.SetActive(hybrid);
		}
	}
}
namespace UITweaks.DeckColumns
{
	internal static class DeckColumns
	{
		[HarmonyPatch(typeof(DeckScreen), "RefreshMode")]
		private static class ColumnCount
		{
			private static void Postfix(Mode ___mode, GridLayoutGroup ___cardGrid)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				if (Applies(___mode))
				{
					___cardGrid.constraintCount = columns.Value;
				}
			}
		}

		[HarmonyPatch(typeof(DeckScreen), "UpdateCardTooltipSides")]
		private static class TooltipSides
		{
			private static void Postfix(DeckScreen __instance, Mode ___mode)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				if (!Applies(___mode) || CardInfos == null || !(CardInfos.GetValue(__instance) is List<CardInfo> list))
				{
					return;
				}
				int value = columns.Value;
				for (int i = 0; i < list.Count; i++)
				{
					CardUI cardUI = list[i].cardUI;
					if ((Object)(object)cardUI != (Object)null)
					{
						cardUI.SetTooltipSide((TooltipSide)((i % value == value - 1) ? 3 : 4));
					}
				}
			}
		}

		internal const string Section = "DeckColumns";

		private const int VanillaColumns = 4;

		internal static ConfigEntry<bool> Enabled = null;

		private static ConfigEntry<int> columns = null;

		private static readonly FieldInfo CardInfos = AccessTools.Field(typeof(DeckScreen), "cardInfos");

		public static void Init(ConfigFile config)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			Enabled = config.Bind<bool>("DeckColumns", "Enabled", true, "Lay the deck screen's cards out in more columns than the game's 4.");
			columns = config.Bind<int>("DeckColumns", "Columns", 6, new ConfigDescription("How many columns of cards the deck screen shows. 6 full-size cards fill 1730 of the screen's 1920 units; 7 overflow it.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), Array.Empty<object>()));
			if (CardInfos == null)
			{
				Plugin.Logger.LogError((object)"DeckScreen.cardInfos is gone; tooltip sides will stay the game's.");
			}
		}

		private static bool Applies(Mode mode)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			if (Enabled.Value && columns.Value != 4)
			{
				return (int)mode != 10;
			}
			return false;
		}
	}
}