Decompiled source of New Spell Card Toolkit v1.2.5

Infiniscryption.Spells.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiskCardGame;
using GBC;
using HarmonyLib;
using Infiniscryption.Core.Helpers;
using Infiniscryption.Spells.Patchers;
using Infiniscryption.Spells.Sigils;
using InscryptionAPI.Card;
using InscryptionAPI.Guid;
using InscryptionAPI.Helpers.Extensions;
using Microsoft.CodeAnalysis;
using Pixelplacement;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;

[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("Infiniscryption.Spells")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("An updated version of Infiniscryption's Spell Card Toolkit with new features and general improvements.")]
[assembly: AssemblyFileVersion("1.2.5.0")]
[assembly: AssemblyInformationalVersion("1.2.5")]
[assembly: AssemblyProduct("Infiniscryption.Spells")]
[assembly: AssemblyTitle("Infiniscryption.Spells")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.5.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]
	[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 NewSpellsAPI
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Infiniscryption.Spells";

		public const string PLUGIN_NAME = "Infiniscryption.Spells";

		public const string PLUGIN_VERSION = "1.2.5";
	}
}
namespace Infiniscryption.Spells
{
	public class SpellSniperVisualiser : ManagedBehaviour
	{
		public List<GameObject> sniperIcons = new List<GameObject>();

		private GameObject sniperIconPrefab;

		private GameObject tempSniperIcon;

		public void VisualizeStartSniperAbility(CardSlot sniperSlot)
		{
		}

		public void VisualizeAimSniperAbility(CardSlot sniperSlot, CardSlot targetSlot)
		{
			//IL_0066: 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)
			if ((Object)(object)tempSniperIcon != (Object)null)
			{
				CleanUpTargetIcon(tempSniperIcon);
				tempSniperIcon = null;
			}
			if ((Object)(object)sniperIconPrefab == (Object)null)
			{
				sniperIconPrefab = ResourceBank.Get<GameObject>("Prefabs/Cards/SpecificCardModels/CannonTargetIcon");
			}
			GameObject val = Object.Instantiate<GameObject>(sniperIconPrefab, ((Component)targetSlot).transform);
			val.transform.localPosition = new Vector3(0f, 0.25f, 0f);
			val.transform.localRotation = Quaternion.identity;
			tempSniperIcon = val;
		}

		public void CleanUpTargetIcon(GameObject icon)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Tween.LocalScale(icon.transform, Vector3.zero, 0.1f, 0f, Tween.EaseIn, (LoopType)0, (Action)null, (Action)delegate
			{
				Object.Destroy((Object)(object)icon);
			}, true);
		}

		public void VisualizeConfirmSniperAbility(CardSlot targetSlot)
		{
			//IL_0045: 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)
			if ((Object)(object)sniperIconPrefab == (Object)null)
			{
				sniperIconPrefab = ResourceBank.Get<GameObject>("Prefabs/Cards/SpecificCardModels/CannonTargetIcon");
			}
			GameObject val = Object.Instantiate<GameObject>(sniperIconPrefab, ((Component)targetSlot).transform);
			val.transform.localPosition = new Vector3(0f, 0.25f, 0f);
			val.transform.localRotation = Quaternion.identity;
			sniperIcons.Add(val);
			if ((Object)(object)tempSniperIcon != (Object)null)
			{
				CleanUpTargetIcon(tempSniperIcon);
				tempSniperIcon = null;
			}
		}

		public void VisualizeClearSniperAbility()
		{
			sniperIcons.ForEach(delegate(GameObject x)
			{
				if ((Object)(object)x != (Object)null)
				{
					CleanUpTargetIcon(x);
				}
			});
			sniperIcons.Clear();
			if ((Object)(object)tempSniperIcon != (Object)null)
			{
				CleanUpTargetIcon(tempSniperIcon);
				tempSniperIcon = null;
			}
		}
	}
	[BepInPlugin("zorro.inscryption.infiniscryption.spells", "New Infiniscryption Spells", "1.2.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class InfiniscryptionSpellsPlugin : BaseUnityPlugin
	{
		internal const string OriginalPluginGuid = "zorro.infiniscryption.sigils";

		public const string PluginGuid = "zorro.inscryption.infiniscryption.spells";

		internal const string PluginName = "New Infiniscryption Spells";

		internal const string PluginVersion = "1.2.5";

		internal const string CardPrefix = "ZSPL";

		internal static ManualLogSource Log;

		private bool AddCards => ((BaseUnityPlugin)this).Config.Bind<bool>("InfiniscryptionSpells", "AddCards", false, new ConfigDescription("If true, this will add the sample cards to the card pool.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		private bool AllowStatBoost => ((BaseUnityPlugin)this).Config.Bind<bool>("InfiniscryptionSpells", "AllowStatBoost", true, new ConfigDescription("If true, this will allow stat-showing spells to be buffed at campfires.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		private bool AllowCardMerge => ((BaseUnityPlugin)this).Config.Bind<bool>("InfiniscryptionSpells", "AllowCardMerge", true, new ConfigDescription("If true, this will allow spell cards to gain and transfer their sigils.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		internal static bool SpellMerge { get; private set; }

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony val = new Harmony("zorro.inscryption.infiniscryption.spells");
			SpellMerge = AllowCardMerge;
			val.PatchAll(typeof(SpellBehavior));
			if (AllowStatBoost)
			{
				MethodInfo method = typeof(CardStatBoostSequencer).GetMethod("GetValidCards", BindingFlags.Instance | BindingFlags.NonPublic);
				MethodInfo method2 = typeof(SpellBehavior).GetMethod("AllowStatBoostForSpells");
				val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			TargetedSpellAbility.Register();
			GlobalSpellAbility.Register();
			InstaGlobalSpellAbility.Register();
			RuntimeHelpers.RunClassConstructor(typeof(SpellBehavior.SpellBackgroundAppearance).TypeHandle);
			RuntimeHelpers.RunClassConstructor(typeof(SpellBehavior.RareSpellBackgroundAppearance).TypeHandle);
			DrawTwoCards.Register();
			DestroyAllCardsOnDeath.Register();
			DirectDamage.Register();
			DirectHeal.Register();
			AttackBuff.Register();
			AttackNerf.Register();
			Fishhook.Register();
			GiveStats.Register();
			GiveSigils.Register();
			GiveStatsSigils.Register();
			if (AddCards)
			{
				SpellCards.RegisterCustomCards();
			}
			CardManager.ModifyCardList += delegate(List<CardInfo> cards)
			{
				//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)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				foreach (CardInfo item in cards.Where((CardInfo x) => x.IsSpell()))
				{
					if (item.IsTargetedSpell() && item.SpecialStatIcon != TargetedSpellAbility.Icon)
					{
						item.SetTargetedSpell();
					}
					else if (item.IsInstaGlobalSpell() && item.specialStatIcon != InstaGlobalSpellAbility.Icon)
					{
						item.SetInstaGlobalSpell();
					}
					else if (item.IsGlobalSpell() && item.specialStatIcon == GlobalSpellAbility.Icon)
					{
						item.SetGlobalSpell();
					}
					if (!item.hideAttackAndHealth && (item.baseHealth != 0 || item.baseAttack != 0))
					{
						if (!CardExtensions.GetExtendedPropertyAsBool(item, "Spells:NegativeStats").HasValue && (item.baseHealth < 0 || item.baseAttack < 0))
						{
							item.SetNegativeStats();
						}
						CardExtensions.SetHideStats(item, false);
					}
				}
				return cards;
			};
			((BaseUnityPlugin)this).Logger.LogInfo((object)"New Infiniscryption Spells is loaded!");
		}
	}
}
namespace Infiniscryption.Spells.Sigils
{
	public class AttackNerf : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null && slot.Card.Attack > 0)
			{
				return ((AbilityBehaviour)this).Card.OpponentCard != slot.Card.OpponentCard;
			}
			return false;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			Singleton<ViewManager>.Instance.SwitchToView((View)4, false, false);
			yield return (object)new WaitForSeconds(0.2f);
			foreach (CardSlot slot in Singleton<BoardManager>.Instance.GetSlots(((AbilityBehaviour)this).Card.OpponentCard))
			{
				if ((Object)(object)slot.Card != (Object)null)
				{
					slot.Card.AddTemporaryMod(new CardModificationInfo(-1, 0));
				}
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			slot.Card.AddTemporaryMod(new CardModificationInfo(-1, 0));
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public static void Register()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Attack Down";
			val.rulebookDescription = "Decreases the target's attack for the rest of the battle.";
			val.canStack = true;
			val.powerLevel = 1;
			val.opponentUsable = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("attack_down_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(AttackNerf), (Texture)(object)AssetHelper.LoadTexture("ability_attack_down", (FilterMode)0)).Id;
		}
	}
	public class AttackBuff : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToSacrifice()
		{
			return true;
		}

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null)
			{
				return ((AbilityBehaviour)this).Card.OpponentCard == slot.Card.OpponentCard;
			}
			return false;
		}

		public override IEnumerator OnSacrifice()
		{
			PlayableCard currentSacrificeDemandingCard = Singleton<BoardManager>.Instance.CurrentSacrificeDemandingCard;
			((Card)currentSacrificeDemandingCard).Anim.LightNegationEffect();
			if ((Object)(object)currentSacrificeDemandingCard != (Object)null)
			{
				currentSacrificeDemandingCard.AddTemporaryMod(new CardModificationInfo(1, 0));
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public override IEnumerator OnResolveOnBoard()
		{
			Singleton<ViewManager>.Instance.SwitchToView((View)4, false, false);
			yield return (object)new WaitForSeconds(0.2f);
			foreach (CardSlot slot in Singleton<BoardManager>.Instance.GetSlots(CardExtensions.IsPlayerCard(((AbilityBehaviour)this).Card)))
			{
				if ((Object)(object)slot.Card != (Object)null)
				{
					((Card)slot.Card).Anim.LightNegationEffect();
					slot.Card.AddTemporaryMod(new CardModificationInfo(1, 0));
				}
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			((Card)slot.Card).Anim.LightNegationEffect();
			slot.Card.AddTemporaryMod(new CardModificationInfo(1, 0));
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public static void Register()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Attack Up";
			val.rulebookDescription = "Increases the target's attack for the rest of the battle.";
			val.canStack = true;
			val.powerLevel = 1;
			val.opponentUsable = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("attack_up_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(AttackBuff), (Texture)(object)AssetHelper.LoadTexture("ability_attack_up", (FilterMode)0)).Id;
		}
	}
	public static class CardHelpers
	{
		public static Trait NeverBoostStats = GuidManager.GetEnumValue<Trait>("zorro.infiniscryption.sigils", "NeverBoostStats");

		public static CardInfo SetGlobalSpell(this CardInfo card)
		{
			//IL_0008: 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_004f: Expected I4, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			card.hideAttackAndHealth = true;
			CardExtensions.SetStatIcon(card, GlobalSpellAbility.Icon);
			if (CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)3))
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.RareSpellBackgroundAppearance.ID });
				card.appearanceBehaviour.Remove((Appearance)7);
			}
			else
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.SpellBackgroundAppearance.ID });
			}
			return card;
		}

		public static CardInfo SetInstaGlobalSpell(this CardInfo card)
		{
			//IL_0008: 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_004f: Expected I4, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			card.hideAttackAndHealth = true;
			CardExtensions.SetStatIcon(card, InstaGlobalSpellAbility.Icon);
			if (CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)3))
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.RareSpellBackgroundAppearance.ID });
				card.appearanceBehaviour.Remove((Appearance)7);
			}
			else
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.SpellBackgroundAppearance.ID });
			}
			return card;
		}

		public static CardInfo SetTargetedSpell(this CardInfo card)
		{
			//IL_0008: 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_004f: Expected I4, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			card.hideAttackAndHealth = true;
			CardExtensions.SetStatIcon(card, TargetedSpellAbility.Icon);
			if (CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)3))
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.RareSpellBackgroundAppearance.ID });
				card.appearanceBehaviour.Remove((Appearance)7);
			}
			else
			{
				CardExtensions.AddAppearances(card, (Appearance[])(object)new Appearance[1] { (Appearance)(int)SpellBehavior.SpellBackgroundAppearance.ID });
			}
			return card;
		}

		public static CardInfo SetTargetedSpellStats(this CardInfo card)
		{
			card.SetTargetedSpell();
			card.hideAttackAndHealth = false;
			return card;
		}

		public static CardInfo SetGlobalSpellStats(this CardInfo card)
		{
			card.SetGlobalSpell();
			card.hideAttackAndHealth = false;
			return card;
		}

		public static CardInfo SetInstaGlobalSpellStats(this CardInfo card)
		{
			card.SetInstaGlobalSpell();
			card.hideAttackAndHealth = false;
			return card;
		}

		public static CardInfo SetNeverBoostStats(this CardInfo card)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected I4, but got Unknown
			CardExtensions.AddTraits(card, (Trait[])(object)new Trait[1] { (Trait)(int)NeverBoostStats });
			return card;
		}

		public static List<Ability> GetDistinctShownAbilities(CardInfo info, List<CardModificationInfo> mods, List<Ability> hiddenAbilities)
		{
			List<Ability> abilities = info.Abilities;
			abilities.AddRange(AbilitiesUtil.GetAbilitiesFromMods(mods));
			abilities = AbilitiesUtil.RemoveNonDistinctNonStacking(abilities);
			abilities.RemoveAll((Ability x) => mods.Exists((CardModificationInfo m) => m.negateAbilities.Contains(x)));
			if (hiddenAbilities != null)
			{
				abilities.RemoveAll(hiddenAbilities.Contains);
			}
			return abilities;
		}

		public static FullAbility SetCanMerge(this FullAbility info, bool canMerge = true)
		{
			AbilityExtensions.SetExtendedProperty(info, "Spells:CanMerge", (object)canMerge);
			return info;
		}

		public static AbilityInfo SetCanMerge(this AbilityInfo info, bool canMerge = true)
		{
			AbilityExtensions.SetExtendedProperty(info, "Spells:CanMerge", (object)canMerge);
			return info;
		}

		public static CardInfo SetNegativeStats(this CardInfo info, bool negativeStats = true)
		{
			CardExtensions.SetExtendedProperty(info, "Spells:NegativeStats", (object)negativeStats);
			return info;
		}

		public static bool CanMerge(this AbilityInfo info)
		{
			return AbilityExtensions.GetExtendedPropertyAsBool(info, "Spells:CanMerge") ?? true;
		}

		public static bool CanMerge(this Ability ability)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return AbilityExtensions.GetExtendedPropertyAsBool(ability, "Spells:CanMerge") ?? true;
		}
	}
	public class DestroyAllCardsOnDeath : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return true;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence();
			Singleton<ViewManager>.Instance.SwitchToView((View)4, false, false);
			foreach (CardSlot item in Singleton<BoardManager>.Instance.OpponentSlotsCopy)
			{
				if ((Object)(object)item.Card != (Object)null)
				{
					yield return item.Card.Die(true, (PlayableCard)null, true);
				}
			}
			foreach (CardSlot item2 in Singleton<BoardManager>.Instance.PlayerSlotsCopy)
			{
				if ((Object)(object)item2.Card != (Object)null)
				{
					yield return item2.Card.Die(true, (PlayableCard)null, true);
				}
			}
			yield return (object)new WaitForSeconds(0.5f);
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
			Singleton<ViewManager>.Instance.SwitchToView((View)1, false, false);
		}

		public static void Register()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Cataclysm";
			val.rulebookDescription = "When [creature] dies, all other cards on the boards perish as well.";
			val.canStack = false;
			val.powerLevel = 6;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("nuke_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(DestroyAllCardsOnDeath), (Texture)(object)AssetHelper.LoadTexture("ability_nuke", (FilterMode)0)).Id;
		}
	}
	public class DirectDamage : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null)
			{
				return ((AbilityBehaviour)this).Card.OpponentCard != slot.Card.OpponentCard;
			}
			return false;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			Singleton<ViewManager>.Instance.SwitchToView((View)4, false, false);
			yield return (object)new WaitForSeconds(0.2f);
			foreach (CardSlot item in BoardManagerExtensions.GetSlotsCopy(Singleton<BoardManager>.Instance, !((AbilityBehaviour)this).Card.OpponentCard))
			{
				if ((Object)(object)item.Card != (Object)null)
				{
					yield return item.Card.TakeDamage(1, (PlayableCard)null);
				}
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			yield return slot.Card.TakeDamage(1, attacker);
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}

		public static void Register()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Direct Damage";
			val.rulebookDescription = "Deals damage directly to a target.";
			val.canStack = true;
			val.powerLevel = 1;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("damage_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(DirectDamage), (Texture)(object)AssetHelper.LoadTexture("ability_damage", (FilterMode)0)).Id;
		}
	}
	public class DirectHeal : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToSacrifice()
		{
			return true;
		}

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null)
			{
				return ((AbilityBehaviour)this).Card.OpponentCard == slot.Card.OpponentCard;
			}
			return false;
		}

		public override IEnumerator OnSacrifice()
		{
			PlayableCard currentSacrificeDemandingCard = Singleton<BoardManager>.Instance.CurrentSacrificeDemandingCard;
			if ((Object)(object)currentSacrificeDemandingCard != (Object)null)
			{
				currentSacrificeDemandingCard.HealDamage(1);
				yield return (object)new WaitForSeconds(0.45f);
				yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
			}
		}

		public override IEnumerator OnResolveOnBoard()
		{
			foreach (CardSlot slot in Singleton<BoardManager>.Instance.GetSlots(true))
			{
				if ((Object)(object)slot.Card != (Object)null)
				{
					((AbilityBehaviour)this).Card.HealDamage(1);
				}
			}
			yield return (object)new WaitForSeconds(0.45f);
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			slot.Card.HealDamage(1);
			yield return (object)new WaitForSeconds(0.45f);
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
		}

		public static void Register()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Direct Heal";
			val.rulebookDescription = "Heals the target. This can heal the target beyond its original max health.";
			val.canStack = true;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("direct_heal_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(DirectHeal), (Texture)(object)AssetHelper.LoadTexture("ability_health_up", (FilterMode)0)).Id;
		}
	}
	public class DrawTwoCards : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public static void Register()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Draw Twice";
			val.rulebookDescription = "When [creature] dies, draw two more cards and add them to your deck.";
			val.canStack = true;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("drawtwocardsondeath_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(DrawTwoCards), (Texture)(object)AssetHelper.LoadTexture("ability_drawtwocardsondeath", (FilterMode)0)).Id;
		}

		public override bool RespondsToResolveOnBoard()
		{
			return !((Card)((AbilityBehaviour)this).Card).Info.IsSpell();
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsSpell();
		}

		public override IEnumerator OnResolveOnBoard()
		{
			return Effect();
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			if (((AbilityBehaviour)this).Card.OpponentCard)
			{
				int randomSeed = SaveManager.SaveFile.GetCurrentRandomSeed();
				List<CardInfo> possibleCards = new List<CardInfo>();
				foreach (List<CardInfo> item in Singleton<TurnManager>.Instance.Opponent.TurnPlan)
				{
					foreach (CardInfo item2 in item)
					{
						if ((Object)(object)((Card)((AbilityBehaviour)this).Card).Info != (Object)(object)item2)
						{
							possibleCards.Add(item2);
						}
					}
				}
				for (int i = 0; i < 2; i++)
				{
					List<CardSlot> list = Singleton<BoardManager>.Instance.OpponentSlotsCopy.Where((CardSlot s) => !Singleton<TurnManager>.Instance.Opponent.QueuedSlots.Contains(s)).ToList();
					if (list.Count() > 0)
					{
						CardSlot val = list[SeededRandom.Range(0, list.Count, randomSeed++)];
						CardInfo cardToQueue = possibleCards[SeededRandom.Range(0, possibleCards.Count, randomSeed++)];
						yield return Singleton<TurnManager>.Instance.Opponent.QueueCard(cardToQueue, val, true, true, true);
						possibleCards.Remove(cardToQueue);
					}
				}
				yield return (object)new WaitForSeconds(0.45f);
			}
			else
			{
				yield return Effect();
			}
		}

		private IEnumerator Effect()
		{
			yield return ((AbilityBehaviour)this).PreSuccessfulTriggerSequence();
			Singleton<ViewManager>.Instance.SwitchToView((View)1, false, false);
			if (Singleton<CardDrawPiles>.Instance is CardDrawPiles3D)
			{
				CardDrawPiles instance = Singleton<CardDrawPiles>.Instance;
				CardDrawPiles3D cardPiles = (CardDrawPiles3D)(object)((instance is CardDrawPiles3D) ? instance : null);
				yield return ((CardDrawPiles)cardPiles).DrawCardFromDeck((CardInfo)null, (Action<PlayableCard>)null);
				yield return cardPiles.DrawFromSidePile();
			}
			else
			{
				yield return Singleton<CardDrawPiles>.Instance.DrawCardFromDeck((CardInfo)null, (Action<PlayableCard>)null);
				yield return Singleton<CardDrawPiles>.Instance.DrawCardFromDeck((CardInfo)null, (Action<PlayableCard>)null);
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0.5f);
		}
	}
	public class Fishhook : AbilityBehaviour
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null && (Object)(object)slot.opposingSlot.Card == (Object)null)
			{
				return ((AbilityBehaviour)this).Card.OpponentCard != slot.Card.OpponentCard;
			}
			return false;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			foreach (CardSlot slot in Singleton<BoardManager>.Instance.GetSlots(((AbilityBehaviour)this).Card.OpponentCard))
			{
				if ((Object)(object)slot.Card != (Object)null && (Object)(object)slot.opposingSlot.Card == (Object)null)
				{
					yield return HookEffect(slot);
					yield return (object)new WaitForSeconds(0.2f);
				}
			}
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			yield return HookEffect(slot);
			yield return (object)new WaitForSeconds(0.2f);
		}

		private IEnumerator HookEffect(CardSlot slot)
		{
			PlayableCard targetCard = slot.Card;
			targetCard.SetIsOpponentCard(false);
			Transform transform = ((Component)targetCard).transform;
			transform.eulerAngles += new Vector3(0f, 0f, -180f);
			yield return Singleton<BoardManager>.Instance.AssignCardToSlot(targetCard, slot.opposingSlot, 0.1f, (Action)null, true);
			if (((Card)targetCard).FaceDown)
			{
				((Card)targetCard).SetFaceDown(false, false);
				targetCard.UpdateFaceUpOnBoardEffects();
			}
		}

		public static void Register()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Gain Control";
			val.rulebookDescription = "Takes control of the targeted creature.";
			val.powerLevel = 8;
			val.canStack = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("fishhook_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(Fishhook), (Texture)(object)AssetHelper.LoadTexture("ability_fishhook", (FilterMode)0)).Id;
		}
	}
	public abstract class GiveAbility : AbilityBehaviour
	{
		public enum TargetBehaviour
		{
			TargetFriendlies,
			TargetOpponents,
			TargetAny
		}

		public virtual TargetBehaviour TargetMode { get; set; }

		private bool ValidTarget(PlayableCard card)
		{
			return TargetMode switch
			{
				TargetBehaviour.TargetFriendlies => card.OpponentCard == ((AbilityBehaviour)this).Card.OpponentCard, 
				TargetBehaviour.TargetOpponents => card.OpponentCard != ((AbilityBehaviour)this).Card.OpponentCard, 
				_ => true, 
			};
		}

		public override bool RespondsToSacrifice()
		{
			return true;
		}

		public override IEnumerator OnSacrifice()
		{
			PlayableCard currentSacrificeDemandingCard = Singleton<BoardManager>.Instance.CurrentSacrificeDemandingCard;
			if ((Object)(object)currentSacrificeDemandingCard != (Object)null)
			{
				yield return OnValidTarget(currentSacrificeDemandingCard);
				yield return (object)new WaitForSeconds(0.5f);
				yield return ((AbilityBehaviour)this).LearnAbility(0f);
			}
		}

		public override bool RespondsToResolveOnBoard()
		{
			return ((Card)((AbilityBehaviour)this).Card).Info.IsGlobalSpell();
		}

		public override IEnumerator OnResolveOnBoard()
		{
			foreach (CardSlot item in Singleton<BoardManager>.Instance.AllSlotsCopy.Where((CardSlot x) => (Object)(object)x.Card != (Object)null && ValidTarget(x.Card)))
			{
				yield return OnValidTarget(item.Card);
			}
			yield return (object)new WaitForSeconds(0.5f);
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
		}

		public override bool RespondsToSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			if (((Card)((AbilityBehaviour)this).Card).Info.IsSpell() && (Object)(object)slot.Card != (Object)null)
			{
				return ValidTarget(slot.Card);
			}
			return false;
		}

		public override IEnumerator OnSlotTargetedForAttack(CardSlot slot, PlayableCard attacker)
		{
			yield return OnValidTarget(slot.Card);
			yield return (object)new WaitForSeconds(0.5f);
			yield return ((AbilityBehaviour)this).LearnAbility(0f);
		}

		public abstract IEnumerator OnValidTarget(PlayableCard card);
	}
	public class GiveSigils : GiveAbility
	{
		public const int MaxSigilsToGive = 4;

		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override IEnumerator OnValidTarget(PlayableCard card)
		{
			List<Ability> distinctShownAbilities = CardHelpers.GetDistinctShownAbilities(((Card)card).Info, card.TemporaryMods, card.Status.hiddenAbilities);
			if (distinctShownAbilities.Count > 4)
			{
				yield break;
			}
			List<Ability> list = CardExtensions.AllAbilities(((AbilityBehaviour)this).Card);
			list.RemoveAll((Ability ab) => AbilityExtensions.GetExtendedPropertyAsBool(ab, "Spells:GiveAbility") == true);
			CardModificationInfo val = new CardModificationInfo();
			CardModificationInfo val2 = new CardModificationInfo
			{
				fromCardMerge = true
			};
			List<Ability> list2 = new List<Ability>();
			foreach (Ability item in list)
			{
				if (distinctShownAbilities.Count + val.abilities.Count + val2.abilities.Count >= 4)
				{
					break;
				}
				if (AbilityExtensions.AbilityByID((IEnumerable<AbilityInfo>)AbilityManager.AllAbilityInfos, item).canStack)
				{
					list2.Add(item);
				}
				else if (((Card)card).Info.Abilities.Count + val.abilities.Count < 4)
				{
					CardModificationInfoExtensions.AddAbilities(val, (Ability[])(object)new Ability[1] { (Ability)(int)item });
				}
				else if (((Card)card).Info.ModAbilities.Count + card.TemporaryMods.Count((CardModificationInfo tm) => tm.fromCardMerge) + val2.abilities.Count < 4)
				{
					val2.abilities.Add(item);
				}
			}
			val.abilities.AddRange(list2);
			((Card)card).Anim.PlayTransformAnimation();
			if (((Object)((Card)card).Info).name == "!DEATHCARD_BASE")
			{
				CardExtensions.AddTemporaryMods(card, (CardModificationInfo[])(object)new CardModificationInfo[2] { val, val2 });
			}
			else
			{
				object obj = ((Card)card).Info.Clone();
				CardInfo val3 = (CardInfo)((obj is CardInfo) ? obj : null);
				val3.Mods.Add(val);
				val3.Mods.Add(val2);
				((Card)card).SetInfo(val3);
			}
		}

		public static void Register()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Give Sigils";
			val.rulebookDescription = "Gives this card's sigils to the target.";
			val.canStack = true;
			val.powerLevel = 3;
			val.opponentUsable = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("give_sigils_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityExtensions.SetExtendedProperty(val, "Spells:GiveAbility", (object)true);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(GiveSigils), (Texture)(object)AssetHelper.LoadTexture("ability_give_sigils", (FilterMode)0)).Id;
		}
	}
	public class GiveStats : GiveAbility
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override IEnumerator OnValidTarget(PlayableCard card)
		{
			CardModificationInfo val = new CardModificationInfo(((AbilityBehaviour)this).Card.Attack, 0);
			if (((AbilityBehaviour)this).Card.Health < 0)
			{
				card.AddTemporaryMod(val);
				yield return card.TakeDamage(-((AbilityBehaviour)this).Card.Health, (PlayableCard)null);
			}
			else
			{
				val.healthAdjustment = ((AbilityBehaviour)this).Card.Health;
				card.AddTemporaryMod(val);
			}
		}

		public static void Register()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Give Stats";
			val.rulebookDescription = "Gives this card's stats to the target.";
			val.canStack = true;
			val.powerLevel = 2;
			val.opponentUsable = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("give_stats_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityExtensions.SetExtendedProperty(val, "Spells:GiveAbility", (object)true);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(GiveStats), (Texture)(object)AssetHelper.LoadTexture("ability_give_stats", (FilterMode)0)).Id;
		}
	}
	public class GiveStatsSigils : GiveAbility
	{
		public override Ability Ability => AbilityID;

		public static Ability AbilityID { get; private set; }

		public override IEnumerator OnValidTarget(PlayableCard card)
		{
			CardModificationInfo baseMod = new CardModificationInfo(((AbilityBehaviour)this).Card.Attack, 0);
			if (CardExtensions.LacksAbility(((AbilityBehaviour)this).Card, GiveStats.AbilityID))
			{
				if (((AbilityBehaviour)this).Card.Health < 0)
				{
					baseMod = new CardModificationInfo(((AbilityBehaviour)this).Card.Attack, 0);
					yield return card.TakeDamage(-((AbilityBehaviour)this).Card.Health, (PlayableCard)null);
					if ((Object)(object)card == (Object)null || card.Dead)
					{
						yield break;
					}
				}
				else
				{
					baseMod.healthAdjustment = ((AbilityBehaviour)this).Card.Health;
				}
			}
			if (CardExtensions.LacksAbility(((AbilityBehaviour)this).Card, GiveSigils.AbilityID))
			{
				List<Ability> distinctShownAbilities = CardHelpers.GetDistinctShownAbilities(((Card)card).Info, card.TemporaryMods, card.Status.hiddenAbilities);
				if (distinctShownAbilities.Count > 4)
				{
					yield break;
				}
				List<Ability> list = CardExtensions.AllAbilities(((AbilityBehaviour)this).Card);
				list.RemoveAll((Ability ab) => AbilityExtensions.GetExtendedPropertyAsBool(ab, "Spells:GiveAbility") == true);
				CardModificationInfo val = new CardModificationInfo
				{
					fromCardMerge = true
				};
				List<Ability> list2 = new List<Ability>();
				foreach (Ability item in list)
				{
					if (distinctShownAbilities.Count + baseMod.abilities.Count + val.abilities.Count >= 4)
					{
						break;
					}
					if (AbilityExtensions.AbilityByID((IEnumerable<AbilityInfo>)AbilityManager.AllAbilityInfos, item).canStack)
					{
						list2.Add(item);
					}
					else if (((Card)card).Info.Abilities.Count + baseMod.abilities.Count < 4)
					{
						CardModificationInfoExtensions.AddAbilities(baseMod, (Ability[])(object)new Ability[1] { (Ability)(int)item });
					}
					else if (((Card)card).Info.ModAbilities.Count + card.TemporaryMods.Count((CardModificationInfo tm) => tm.fromCardMerge) + val.abilities.Count < 4)
					{
						val.abilities.Add(item);
					}
				}
				baseMod.abilities.AddRange(list2);
				((Card)card).Anim.PlayTransformAnimation();
				if (((Object)((Card)card).Info).name == "!DEATHCARD_BASE")
				{
					CardExtensions.AddTemporaryMods(card, (CardModificationInfo[])(object)new CardModificationInfo[2] { baseMod, val });
				}
				else
				{
					object obj = ((Card)card).Info.Clone();
					CardInfo val2 = (CardInfo)((obj is CardInfo) ? obj : null);
					val2.Mods.Add(baseMod);
					val2.Mods.Add(val);
					((Card)card).SetInfo(val2);
				}
			}
			else
			{
				card.AddTemporaryMod(baseMod);
			}
		}

		public static void Register()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			AbilityInfo val = ScriptableObject.CreateInstance<AbilityInfo>();
			val.rulebookName = "Give Stats and Sigils";
			val.rulebookDescription = "Gives this card's stats and sigils to the target.";
			val.canStack = true;
			val.powerLevel = 5;
			val.opponentUsable = false;
			val.passive = false;
			val.metaCategories = new List<AbilityMetaCategory> { (AbilityMetaCategory)0 };
			AbilityExtensions.SetPixelAbilityIcon(val, AssetHelper.LoadTexture("give_stats_sigils_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityID = AbilityManager.Add("zorro.infiniscryption.sigils", val, typeof(GiveStatsSigils), (Texture)(object)AssetHelper.LoadTexture("ability_give_stats_sigils", (FilterMode)0)).Id;
		}
	}
	public class GlobalSpellAbility : VariableStatBehaviour
	{
		private static SpecialStatIcon _icon;

		private static SpecialTriggeredAbility _id;

		public static SpecialStatIcon Icon => _icon;

		public override SpecialStatIcon IconType => _icon;

		public static SpecialTriggeredAbility ID => _id;

		public static void Register()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			StatIconInfo val = ScriptableObject.CreateInstance<StatIconInfo>();
			val.appliesToAttack = true;
			val.appliesToHealth = true;
			val.rulebookName = "Spell (Global)";
			val.rulebookDescription = "When this card is played anywhere on the board, it will cause an immediate effect and then disappear.";
			val.gbcDescription = "GLOBAL SPELL.";
			val.iconGraphic = (Texture)(object)AssetHelper.LoadTexture("global_spell_stat_icon", (FilterMode)0);
			AbilityExtensions.SetPixelIcon(val, AssetHelper.LoadTexture("global_spell_icon_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityExtensions.SetDefaultPart1Ability(val);
			FullStatIcon obj = StatIconManager.Add("zorro.infiniscryption.sigils", val, typeof(GlobalSpellAbility));
			_icon = obj.Id;
			_id = obj.AbilityId;
		}

		public override int[] GetStatValues()
		{
			return new int[2];
		}
	}
	public class InstaGlobalSpellAbility : VariableStatBehaviour
	{
		private static SpecialStatIcon _icon;

		private static SpecialTriggeredAbility _id;

		public static SpecialStatIcon Icon => _icon;

		public override SpecialStatIcon IconType => _icon;

		public static SpecialTriggeredAbility ID => _id;

		public static void Register()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			StatIconInfo val = ScriptableObject.CreateInstance<StatIconInfo>();
			val.appliesToAttack = true;
			val.appliesToHealth = true;
			val.rulebookName = "Spell (Global, Instant)";
			val.rulebookDescription = "When this card is played, it will cause an immediate effect and then disappear.";
			val.gbcDescription = "INSTA-GLOBAL SPELL.";
			val.iconGraphic = (Texture)(object)AssetHelper.LoadTexture("insta_global_spell_stat_icon", (FilterMode)0);
			AbilityExtensions.SetPixelIcon(val, AssetHelper.LoadTexture("insta_global_spell_icon_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityExtensions.SetDefaultPart1Ability(val);
			FullStatIcon obj = StatIconManager.Add("zorro.infiniscryption.sigils", val, typeof(InstaGlobalSpellAbility));
			_icon = obj.Id;
			_id = obj.AbilityId;
		}

		public override int[] GetStatValues()
		{
			return new int[2];
		}
	}
	public class TargetedSpellAbility : VariableStatBehaviour
	{
		private static SpecialStatIcon _icon;

		private static SpecialTriggeredAbility _id;

		public static SpecialStatIcon Icon => _icon;

		public override SpecialStatIcon IconType => _icon;

		public static SpecialTriggeredAbility ID => _id;

		public static void Register()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			StatIconInfo val = ScriptableObject.CreateInstance<StatIconInfo>();
			val.appliesToAttack = true;
			val.appliesToHealth = true;
			val.rulebookName = "Spell (Targeted)";
			val.rulebookDescription = "When this card is played, it will target and affect a chosen space on the board and then disappear.";
			val.gbcDescription = "TARGETED SPELL.";
			val.iconGraphic = (Texture)(object)AssetHelper.LoadTexture("targeted_spell_stat_icon", (FilterMode)0);
			AbilityExtensions.SetPixelIcon(val, AssetHelper.LoadTexture("targeted_spell_icon_pixel", (FilterMode)0), (FilterMode?)null);
			AbilityExtensions.SetDefaultPart1Ability(val);
			_icon = StatIconManager.Add("zorro.infiniscryption.sigils", val, typeof(TargetedSpellAbility)).Id;
			_id = ((IEnumerable<FullStatIcon>)StatIconManager.AllStatIcons).FirstOrDefault((Func<FullStatIcon, bool>)((FullStatIcon sii) => sii.Id == Icon)).AbilityId;
		}

		public override int[] GetStatValues()
		{
			return new int[2];
		}
	}
}
namespace Infiniscryption.Spells.Patchers
{
	public class Act1QueuedCardInteractable : MainInputInteractable
	{
		public HighlightedInteractable queueSlot;

		public PlayableCard playableCard;

		public void QueueCursorEnter()
		{
			PlayableCard obj = playableCard;
			if ((Object)(object)((obj != null) ? obj.QueuedSlot : null) == (Object)null)
			{
				playableCard = null;
			}
			else
			{
				SpellBehavior.UpdateStatsSpellDisplay((Card)(object)playableCard, showStats: true);
			}
		}

		public void QueueCursorExit()
		{
			PlayableCard obj = playableCard;
			if ((Object)(object)((obj != null) ? obj.QueuedSlot : null) == (Object)null)
			{
				playableCard = null;
			}
			else
			{
				SpellBehavior.UpdateStatsSpellDisplay((Card)(object)playableCard, showStats: false);
			}
		}
	}
	public static class SpellBehavior
	{
		public class SpellBackgroundAppearance : CardAppearanceBehaviour
		{
			public static Appearance ID = CardAppearanceBehaviourManager.Add("zorro.infiniscryption.sigils", "SpellBackground", typeof(SpellBackgroundAppearance)).Id;

			private static readonly Texture _emptySpell = (Texture)(object)AssetHelper.LoadTexture("empty_spell_background", (FilterMode)0);

			public override void ApplyAppearance()
			{
				((CardAppearanceBehaviour)this).Card.RenderInfo.baseTextureOverride = _emptySpell;
			}
		}

		public class RareSpellBackgroundAppearance : CardAppearanceBehaviour
		{
			public static Appearance ID = CardAppearanceBehaviourManager.Add("zorro.infiniscryption.sigils", "RareSpellBackground", typeof(RareSpellBackgroundAppearance)).Id;

			private static readonly Texture _emptySpell = (Texture)(object)AssetHelper.LoadTexture("empty_spell_background_rare", (FilterMode)0);

			public override void ApplyAppearance()
			{
				((CardAppearanceBehaviour)this).Card.RenderInfo.baseTextureOverride = _emptySpell;
			}
		}

		public static Hint TargetSpellsNeedTargetHint = new Hint("NoValidTargets", 2);

		public static Color GBCGreenText = new Color(0.1f, 0.6f, 0.3f);

		public static bool IsGlobalSpell(this CardInfo card)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected I4, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected I4, but got Unknown
			return CardExtensions.HasAnyOfSpecialAbilities(card, (SpecialTriggeredAbility[])(object)new SpecialTriggeredAbility[2]
			{
				(SpecialTriggeredAbility)(int)GlobalSpellAbility.ID,
				(SpecialTriggeredAbility)(int)InstaGlobalSpellAbility.ID
			});
		}

		public static bool IsInstaGlobalSpell(this CardInfo card)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return CardExtensions.HasSpecialAbility(card, InstaGlobalSpellAbility.ID);
		}

		public static bool IsTargetedSpell(this CardInfo card)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return CardExtensions.HasSpecialAbility(card, TargetedSpellAbility.ID);
		}

		public static bool IsSpell(this CardInfo card)
		{
			if (!card.IsTargetedSpell())
			{
				return card.IsGlobalSpell();
			}
			return true;
		}

		public static bool IsSpellShowStats(this CardInfo card)
		{
			if (card.IsSpell())
			{
				return !card.hideAttackAndHealth;
			}
			return false;
		}

		public static List<CardSlot> GetAffectedSlots(this CardSlot slot, PlayableCard card)
		{
			if (card.HasAbility((Ability)33))
			{
				return Singleton<BoardManager>.Instance.AllSlotsCopy.FindAll((CardSlot s) => s.IsValidTarget(card));
			}
			List<CardSlot> list = new List<CardSlot>();
			if (CardExtensions.HasAnyOfAbilities(card, (Ability[])(object)new Ability[2]
			{
				(Ability)24,
				(Ability)25
			}))
			{
				CardSlot adjacent = Singleton<BoardManager>.Instance.GetAdjacent(slot, true);
				CardSlot adjacent2 = Singleton<BoardManager>.Instance.GetAdjacent(slot, false);
				if ((Object)(object)adjacent != (Object)null)
				{
					list.Add(adjacent);
				}
				if ((Object)(object)adjacent2 != (Object)null)
				{
					list.Add(adjacent2);
				}
				if (card.HasAbility((Ability)25))
				{
					list.Add(slot);
				}
			}
			else
			{
				list.Add(slot);
			}
			list.Sort((CardSlot a, CardSlot b) => a.Index - b.Index);
			return list;
		}

		public static bool IsValidTarget(this CardSlot slot, PlayableCard card, bool checkSingleSlot = false)
		{
			if (!Object.op_Implicit((Object)(object)slot))
			{
				return false;
			}
			if (checkSingleSlot)
			{
				if (card.TriggerHandler.RespondsToTrigger((Trigger)3, Array.Empty<object>()))
				{
					return true;
				}
				if (card.TriggerHandler.CustomRespondsToTrigger((Trigger)6, slot, card))
				{
					return true;
				}
				return false;
			}
			return slot.GetAffectedSlots(card).Exists((CardSlot subSlot) => subSlot.IsValidTarget(card, checkSingleSlot: true));
		}

		public static bool HasValidTarget(this PlayableCard card)
		{
			foreach (CardSlot item in Singleton<BoardManager>.Instance.AllSlotsCopy)
			{
				if (item.IsValidTarget(card))
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(DialogueDataUtil), "ReadDialogueData")]
		[HarmonyPostfix]
		public static void SpellHints()
		{
			DialogueHelper.AddOrModifySimpleDialogEvent("NoValidTargets", new string[1] { "You cannot use that without a target." });
		}

		[HarmonyPatch(typeof(HintsHandler), "OnNonplayableCardClicked")]
		[HarmonyPrefix]
		public static bool TargetSpellsNeedATarget(PlayableCard card)
		{
			if (((Card)card).Info.IsTargetedSpell() && !card.HasValidTarget())
			{
				TargetSpellsNeedTargetHint.TryPlayDialogue((string[])null);
				return false;
			}
			return true;
		}

		public static bool StatsSpellInfo(CardInfo info)
		{
			if ((Object)(object)info != (Object)null)
			{
				return info.IsSpellShowStats();
			}
			return false;
		}

		public static void UpdateStatsSpellDisplay(Card card, bool showStats)
		{
			if (StatsSpellInfo(card.Info))
			{
				card.RenderInfo.showSpecialStats = showStats;
				card.RenderCard();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Card), "RenderCard")]
		private static bool UpdateSpellStatsDisplay(Card __instance)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			if (StatsSpellInfo(__instance.Info))
			{
				PlayableCard val = (PlayableCard)(object)((__instance is PlayableCard) ? __instance : null);
				if (val != null)
				{
					__instance.RenderInfo.attack = val.Attack;
					__instance.RenderInfo.health = val.Health;
				}
				else
				{
					__instance.RenderInfo.attack = __instance.Info.Attack;
					__instance.RenderInfo.health = __instance.Info.Health;
				}
				Color val2 = (SaveManager.SaveFile.IsPart2 ? GBCGreenText : GameColors.Instance.darkBlue);
				if (__instance.RenderInfo.attack < 0)
				{
					__instance.RenderInfo.attackTextColor = GameColors.Instance.darkFuschia;
				}
				else if (__instance.RenderInfo.attack > 0)
				{
					__instance.RenderInfo.attackTextColor = val2;
				}
				else
				{
					__instance.RenderInfo.attackTextColor = Color.black;
				}
				if (__instance.RenderInfo.health < 0)
				{
					__instance.RenderInfo.healthTextColor = GameColors.Instance.darkFuschia;
				}
				else if (__instance.RenderInfo.health > 0)
				{
					__instance.RenderInfo.healthTextColor = val2;
				}
				else
				{
					__instance.RenderInfo.healthTextColor = Color.black;
				}
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SelectableCard), "OnCursorEnter")]
		private static void ShowStatsSelectableCards(SelectableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayableCard), "OnCursorEnter")]
		private static void ShowStatsPlayableCards(PlayableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PixelSelectableCard), "OnCursorEnter")]
		private static void ShowStatsPixelSelectableCards(PixelSelectableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PixelPlayableCard), "OnCursorEnter")]
		private static void ShowStatsPixelPlayableCards(PixelPlayableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: true);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PixelSelectableCard), "OnCursorExit")]
		private static void HideStatsPixelSelectableCards(PixelSelectableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: false);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PixelPlayableCard), "OnCursorExit")]
		private static void HideStatsPixelPlayableCards(PixelPlayableCard __instance)
		{
			UpdateStatsSpellDisplay((Card)(object)__instance, showStats: false);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MainInputInteractable), "OnCursorExit")]
		private static void ShowStatsSelectableCards(MainInputInteractable __instance)
		{
			Card val = (Card)(object)((__instance is Card) ? __instance : null);
			if (val != null)
			{
				UpdateStatsSpellDisplay(val, showStats: false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(BoardManager), "QueueCardForSlot")]
		private static void ShowStatsSelectableCards(PlayableCard card)
		{
			if (SaveManager.SaveFile.IsPart2 || !StatsSpellInfo(((Card)card).Info))
			{
				return;
			}
			HighlightedInteractable val = Singleton<BoardManager>.Instance.opponentQueueSlots[card.QueuedSlot.Index];
			Act1QueuedCardInteractable interactable = ((Component)val).GetComponent<Act1QueuedCardInteractable>();
			if ((Object)(object)interactable == (Object)null)
			{
				interactable = ((Component)val).gameObject.AddComponent<Act1QueuedCardInteractable>();
				((MainInputInteractable)val).CursorEntered = (Action<MainInputInteractable>)Delegate.Combine(((MainInputInteractable)val).CursorEntered, (Action<MainInputInteractable>)delegate
				{
					interactable.QueueCursorEnter();
				});
				((MainInputInteractable)val).CursorExited = (Action<MainInputInteractable>)Delegate.Combine(((MainInputInteractable)val).CursorExited, (Action<MainInputInteractable>)delegate
				{
					interactable.QueueCursorExit();
				});
			}
			interactable.playableCard = card;
		}

		public static void AllowStatBoostForSpells(List<CardInfo> __result)
		{
			List<CardInfo> list = new List<CardInfo>(RunState.DeckList);
			list.RemoveAll((CardInfo ci) => __result.Contains(ci) || !ci.IsSpellShowStats() || (ci.baseAttack <= 0 && ci.baseHealth <= 0 && !CardExtensions.GetExtendedPropertyAsBool(ci, "Spells:NegativeStats").GetValueOrDefault()) || ci.HasTrait((Trait)12));
			__result.AddRange(list);
		}

		[HarmonyPrefix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static bool AllowNegativeAttack(ref int __result, PlayableCard __instance)
		{
			if (CardExtensions.GetExtendedPropertyAsBool(((Card)__instance).Info, "Spells:NegativeStats").GetValueOrDefault())
			{
				__result = ((Card)__instance).Info.Attack + __instance.GetAttackModifications() + __instance.GetPassiveAttackBuffs();
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static bool AllowNegativeHealth(ref int __result, PlayableCard __instance)
		{
			if (CardExtensions.GetExtendedPropertyAsBool(((Card)__instance).Info, "Spells:NegativeStats").GetValueOrDefault())
			{
				__result = __instance.MaxHealth - __instance.Status.damageTaken;
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CardDisplayer3D), "SetStatsText")]
		public static bool NegativeStatsText(CardDisplayer3D __instance, int attack, int health)
		{
			if (CardExtensions.GetExtendedPropertyAsBool(((CardDisplayer)__instance).info, "Spells:NegativeStats").GetValueOrDefault())
			{
				((TMP_Text)__instance.attackText).text = attack.ToString();
				((TMP_Text)__instance.healthText).text = health.ToString();
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PixelCardDisplayer), "SetStatsText")]
		public static bool NegativeStatsTextPixel(PixelCardDisplayer __instance, int attack, int health)
		{
			if (CardExtensions.GetExtendedPropertyAsBool(((CardDisplayer)__instance).info, "Spells:NegativeStats").GetValueOrDefault())
			{
				PixelText attackText = __instance.attackText;
				if (attackText != null)
				{
					attackText.SetText(attack.ToString(), false);
				}
				PixelText healthText = __instance.healthText;
				if (healthText != null)
				{
					healthText.SetText(health.ToString(), false);
				}
				PixelText queuedAttackText = __instance.queuedAttackText;
				if (queuedAttackText != null)
				{
					queuedAttackText.SetText(attack.ToString(), false);
				}
				PixelText queuedHealthText = __instance.queuedHealthText;
				if (queuedHealthText != null)
				{
					queuedHealthText.SetText(health.ToString(), false);
				}
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(BoardManager), "SacrificesCreateRoomForCard")]
		public static bool SpellsDoNotNeedSpace(PlayableCard card, BoardManager __instance, List<CardSlot> sacrifices, ref bool __result)
		{
			if ((Object)(object)card == (Object)null || !((Card)card).Info.IsSpell())
			{
				return true;
			}
			if (((Card)card).Info.BloodCost <= 0)
			{
				__result = true;
				return false;
			}
			foreach (CardSlot item in __instance.AllSlotsCopy)
			{
				if ((!sacrifices.Contains(item) || ((Object)(object)item.Card != (Object)null && item.Card.HasAbility((Ability)20))) && item.IsValidTarget(card))
				{
					__result = true;
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayableCard), "CanPlay")]
		[HarmonyPostfix]
		public static void TargetSpellsMustHaveValidTarget(ref bool __result, ref PlayableCard __instance)
		{
			if (__result && ((Card)__instance).Info.IsTargetedSpell() && !__instance.HasValidTarget())
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(PlayerHand), "SelectSlotForCard")]
		[HarmonyPostfix]
		public static IEnumerator SpellsResolveDifferently(IEnumerator sequenceResult, PlayableCard card)
		{
			if ((Object)(object)card != (Object)null && !((Card)card).Info.IsSpell())
			{
				while (sequenceResult.MoveNext())
				{
					yield return sequenceResult.Current;
				}
				yield break;
			}
			Singleton<PlayerHand>.Instance.CardsInHand.ForEach(delegate(PlayableCard x)
			{
				((InteractableBase)x).SetEnabled(false);
			});
			yield return (object)new WaitWhile((Func<bool>)(() => Singleton<PlayerHand>.Instance.ChoosingSlot));
			Singleton<PlayerHand>.Instance.OnSelectSlotStartedForCard(card);
			RuleBookController instance = Singleton<RuleBookController>.Instance;
			if (instance != null)
			{
				instance.SetShown(false, true);
			}
			Singleton<BoardManager>.Instance.CancelledSacrifice = false;
			Singleton<PlayerHand>.Instance.choosingSlotCard = card;
			if ((Object)(object)card != (Object)null && (Object)(object)((Card)card).Anim != (Object)null)
			{
				((Card)card).Anim.SetSelectedToPlay(true);
			}
			Singleton<BoardManager>.Instance.ShowCardNearBoard(card, true);
			if ((Object)(object)Singleton<TurnManager>.Instance.SpecialSequencer != (Object)null)
			{
				yield return Singleton<TurnManager>.Instance.SpecialSequencer.CardSelectedFromHand(card);
			}
			bool cardWasPlayed = false;
			bool requiresSacrifices = ((Card)card).Info.BloodCost > 0;
			if (requiresSacrifices)
			{
				List<CardSlot> list = Singleton<BoardManager>.Instance.PlayerSlotsCopy.FindAll((CardSlot x) => (Object)(object)x.Card != (Object)null);
				yield return Singleton<BoardManager>.Instance.ChooseSacrificesForCard(list, card);
			}
			List<CardSlot> allSlots = Singleton<BoardManager>.Instance.AllSlotsCopy;
			if (!Singleton<BoardManager>.Instance.CancelledSacrifice)
			{
				bool flag = true;
				if (!((Card)card).Info.IsInstaGlobalSpell())
				{
					IEnumerator chooseSlotEnumerator2 = Singleton<BoardManager>.Instance.ChooseSlot(allSlots, !requiresSacrifices);
					chooseSlotEnumerator2.MoveNext();
					foreach (CardSlot item in allSlots)
					{
						bool flag2 = !((Card)card).Info.IsTargetedSpell() || item.IsValidTarget(card);
						((InteractableBase)item).SetEnabled(flag2);
						((HighlightedInteractable)item).ShowState((State)((!flag2) ? 1 : 2), false, 0.15f);
						item.Chooseable = flag2;
					}
					yield return chooseSlotEnumerator2.Current;
					while (chooseSlotEnumerator2.MoveNext())
					{
						yield return chooseSlotEnumerator2.Current;
					}
					flag = ((!SaveManager.SaveFile.IsPart2 || !InputButtons.GetButtonDown((Button)2) || !((Card)card).Info.IsTargetedSpell()) ? (!Singleton<BoardManager>.Instance.cancelledPlacementWithInput) : ((CardSlot)/*isinst with value type is only supported in some contexts*/).IsValidTarget(card, checkSingleSlot: true));
				}
				if (flag)
				{
					cardWasPlayed = true;
					((Card)card).Anim.SetSelectedToPlay(false);
					if (Singleton<PlayerHand>.Instance.CardsInHand.Contains(card))
					{
						if (((Card)card).Info.BonesCost > 0)
						{
							yield return Singleton<ResourcesManager>.Instance.SpendBones(((Card)card).Info.BonesCost);
						}
						if (card.EnergyCost > 0)
						{
							yield return Singleton<ResourcesManager>.Instance.SpendEnergy(card.EnergyCost);
						}
						Singleton<PlayerHand>.Instance.RemoveCardFromHand(card);
						if (card.TriggerHandler.RespondsToTrigger((Trigger)2, Array.Empty<object>()))
						{
							yield return card.TriggerHandler.OnTrigger((Trigger)2, Array.Empty<object>());
						}
						if (card.TriggerHandler.RespondsToTrigger((Trigger)3, Array.Empty<object>()))
						{
							List<CardSlot> list2 = ((!((Card)card).Info.IsTargetedSpell()) ? new List<CardSlot> { null } : Singleton<BoardManager>.Instance.LastSelectedSlot.GetAffectedSlots(card));
							foreach (CardSlot item2 in list2)
							{
								card.Slot = item2;
								IEnumerator chooseSlotEnumerator2 = card.TriggerHandler.OnTrigger((Trigger)3, Array.Empty<object>());
								bool active = true;
								while (active)
								{
									try
									{
										active = chooseSlotEnumerator2.MoveNext();
									}
									catch (Exception ex)
									{
										Debug.Log((object)("IteratorFunction() threw exception: " + ex));
									}
									if (active)
									{
										yield return chooseSlotEnumerator2.Current;
									}
								}
								card.Slot = null;
							}
						}
						if (((Card)card).Info.IsTargetedSpell())
						{
							CardSlot slot = (CardSlot)(SaveManager.SaveFile.IsPart2 ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)Singleton<BoardManager>.Instance.LastSelectedSlot));
							foreach (CardSlot affectedSlot in slot.GetAffectedSlots(card))
							{
								object[] array = new object[2] { affectedSlot, card };
								yield return card.TriggerHandler.OnTrigger((Trigger)6, array);
							}
						}
						card.Dead = true;
						((Card)card).Anim.PlayDeathAnimation(false);
						object[] array2 = new object[2] { true, null };
						if (card.TriggerHandler.RespondsToTrigger((Trigger)12, array2))
						{
							yield return card.TriggerHandler.OnTrigger((Trigger)12, array2);
						}
						yield return (object)new WaitUntil((Func<bool>)(() => Singleton<GlobalTriggerHandler>.Instance.StackSize == 0));
						if (Singleton<TurnManager>.Instance.IsPlayerTurn)
						{
							Singleton<BoardManager>.Instance.playerCardsPlayedThisRound.Add(((Card)card).Info);
						}
						Singleton<InteractionCursor>.Instance.ClearForcedCursorType();
						yield return (object)new WaitForSeconds(0.6f);
						Object.Destroy((Object)(object)((Component)card).gameObject, 0.5f);
						Singleton<ViewManager>.Instance.SwitchToView((View)1, false, false);
					}
				}
			}
			if (!cardWasPlayed)
			{
				Singleton<BoardManager>.Instance.ShowCardNearBoard(card, false);
			}
			Singleton<PlayerHand>.Instance.choosingSlotCard = null;
			if ((Object)(object)card != (Object)null && (Object)(object)((Card)card).Anim != (Object)null)
			{
				((Card)card).Anim.SetSelectedToPlay(false);
			}
			Singleton<PlayerHand>.Instance.CardsInHand.ForEach(delegate(PlayableCard x)
			{
				((InteractableBase)x).SetEnabled(true);
			});
			foreach (CardSlot item3 in allSlots)
			{
				((InteractableBase)item3).SetEnabled(true);
				((HighlightedInteractable)item3).ShowState((State)2, false, 0.15f);
				item3.Chooseable = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardMergeSequencer), "GetValidCardsForSacrifice")]
		private static void RemoveFromValidCardsForSacrifice(ref List<CardInfo> __result)
		{
			__result.RemoveAll((CardInfo x) => x.Abilities.Exists((Ability x) => !x.CanMerge()));
			if (InfiniscryptionSpellsPlugin.SpellMerge)
			{
				__result.RemoveAll((CardInfo x) => x.IsSpell() && x.hideAttackAndHealth);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardMergeSequencer), "GetValidCardsForHost")]
		private static void RemoveFromValidCardsForHost(ref List<CardInfo> __result)
		{
			__result.RemoveAll((CardInfo x) => x.Abilities.Exists((Ability x) => !x.CanMerge()));
			if (InfiniscryptionSpellsPlugin.SpellMerge)
			{
				__result.RemoveAll((CardInfo x) => x.IsSpell());
			}
		}

		[HarmonyPatch(typeof(BoardManager), "ResolveCardOnBoard")]
		[HarmonyPostfix]
		public static IEnumerator OpponentSpellsResolveDifferently(IEnumerator enumerator, PlayableCard card, CardSlot slot)
		{
			if ((Object)(object)card != (Object)null && card.OpponentCard && ((Card)card).Info.IsSpell())
			{
				CombatPhaseManager instance = Singleton<CombatPhaseManager>.Instance;
				SpellSniperVisualiser visualiser = null;
				SaveFile saveFile = SaveManager.SaveFile;
				if (((saveFile != null) ? new bool?(saveFile.IsPart1) : null).GetValueOrDefault())
				{
					visualiser = ((Component)instance).GetComponent<SpellSniperVisualiser>() ?? ((Component)instance).gameObject.AddComponent<SpellSniperVisualiser>();
				}
				CardSlot targetSlot = null;
				if (((Card)card).Info.IsTargetedSpell())
				{
					targetSlot = OpponentGetTargetSlot(Singleton<BoardManager>.Instance.AllSlotsCopy.FindAll((CardSlot s) => s.IsValidTarget(card)));
				}
				bool targetPlayer = ((Card)card).Info.IsGlobalSpell() || ((Object)(object)targetSlot != (Object)null && card.OpponentCard == targetSlot.IsPlayerSlot);
				Singleton<ViewManager>.Instance.SwitchToView((View)6, false, false);
				yield return (object)new WaitForSeconds(0.3f);
				Tween.LocalPosition(((Component)card).transform, new Vector3(0.65f, 6.2f, targetPlayer ? 0f : 1f), 0.1f, 0f, Tween.EaseOut, (LoopType)0, (Action)delegate
				{
					if (targetPlayer)
					{
						Singleton<ViewManager>.Instance.SwitchToView((View)4, false, false);
					}
					if (((Card)card).Info.IsSpellShowStats())
					{
						UpdateStatsSpellDisplay((Card)(object)card, showStats: true);
					}
				}, (Action)delegate
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					((Card)card).Anim.PlayRiffleSound();
					Tween.Rotation(((Component)card).transform, ((Component)slot).transform.GetChild(0).rotation, 0.1f, 0f, Tween.EaseOut, (LoopType)0, (Action)null, (Action)null, true);
				}, true);
				yield return (object)new WaitForSeconds(0.4f);
				if (card.TriggerHandler.RespondsToTrigger((Trigger)2, Array.Empty<object>()))
				{
					yield return card.TriggerHandler.OnTrigger((Trigger)2, Array.Empty<object>());
				}
				if (card.TriggerHandler.RespondsToTrigger((Trigger)3, Array.Empty<object>()))
				{
					List<CardSlot> resolveSlots = ((!((Card)card).Info.IsTargetedSpell()) ? new List<CardSlot> { null } : slot.GetAffectedSlots(card));
					if (((Card)card).Info.IsTargetedSpell())
					{
						foreach (CardSlot item in resolveSlots)
						{
							instance.VisualizeAimSniperAbility(card.Slot, item);
							visualiser?.VisualizeAimSniperAbility(card.Slot, item);
							instance.VisualizeConfirmSniperAbility(item);
							visualiser?.VisualizeConfirmSniperAbility(item);
							yield return (object)new WaitForSeconds(0.1f);
						}
						yield return (object)new WaitForSeconds(0.4f);
					}
					for (int j = 0; j < resolveSlots.Count; j++)
					{
						card.Slot = resolveSlots[j];
						IEnumerator resolveTrigger = card.TriggerHandler.OnTrigger((Trigger)3, Array.Empty<object>());
						bool active = true;
						while (active)
						{
							try
							{
								active = resolveTrigger.MoveNext();
							}
							catch (Exception ex)
							{
								Debug.Log((object)("IteratorFunction() threw exception: " + ex));
							}
							if (active)
							{
								yield return resolveTrigger.Current;
							}
						}
						SpellSniperVisualiser spellSniperVisualiser = visualiser;
						if (spellSniperVisualiser != null && spellSniperVisualiser.sniperIcons.Count > j && (Object)(object)visualiser?.sniperIcons[j] != (Object)null)
						{
							visualiser?.CleanUpTargetIcon(visualiser?.sniperIcons[j]);
						}
						card.Slot = null;
					}
					yield return (object)new WaitForSeconds(0.2f);
					instance.VisualizeClearSniperAbility();
					visualiser?.VisualizeClearSniperAbility();
				}
				if (((Card)card).Info.IsTargetedSpell() && (Object)(object)targetSlot != (Object)null)
				{
					List<CardSlot> resolveSlots = targetSlot.GetAffectedSlots(card);
					resolveSlots.RemoveAll((CardSlot s) => !card.TriggerHandler.CustomRespondsToTrigger((Trigger)6, s, card));
					foreach (CardSlot item2 in resolveSlots)
					{
						instance.VisualizeAimSniperAbility(card.Slot, item2);
						visualiser?.VisualizeAimSniperAbility(card.Slot, item2);
						instance.VisualizeConfirmSniperAbility(item2);
						visualiser?.VisualizeConfirmSniperAbility(item2);
						yield return (object)new WaitForSeconds(0.1f);
					}
					yield return (object)new WaitForSeconds(0.2f);
					for (int j = 0; j < resolveSlots.Count; j++)
					{
						SpellSniperVisualiser spellSniperVisualiser2 = visualiser;
						if (spellSniperVisualiser2 != null && spellSniperVisualiser2.sniperIcons.Count > j && (Object)(object)visualiser?.sniperIcons[j] != (Object)null)
						{
							visualiser?.CleanUpTargetIcon(visualiser?.sniperIcons[j]);
						}
						yield return card.TriggerHandler.OnTrigger((Trigger)6, new object[2]
						{
							resolveSlots[j],
							card
						});
					}
					yield return (object)new WaitForSeconds(0.2f);
					instance.VisualizeClearSniperAbility();
					visualiser?.VisualizeClearSniperAbility();
				}
				card.Dead = true;
				((Card)card).Anim.PlayDeathAnimation(false);
				object[] array = new object[2] { true, null };
				if (card.TriggerHandler.RespondsToTrigger((Trigger)12, array))
				{
					yield return card.TriggerHandler.OnTrigger((Trigger)12, array);
				}
				yield return (object)new WaitUntil((Func<bool>)(() => Singleton<GlobalTriggerHandler>.Instance.StackSize == 0));
			}
			else
			{
				yield return enumerator;
			}
		}

		[HarmonyPatch(typeof(Opponent), "PlayCardsInQueue")]
		[HarmonyPostfix]
		public static IEnumerator QueuedSpellsGoLast(IEnumerator enumerator, Opponent __instance, float tweenLength)
		{
			if (__instance.Queue.Count <= 0)
			{
				yield break;
			}
			if (!__instance.Queue.Exists((PlayableCard x) => ((Card)x).Info.IsSpell()))
			{
				yield return enumerator;
				yield break;
			}
			yield return __instance.VisualizePrePlayQueuedCards();
			List<PlayableCard> playedCards = new List<PlayableCard>();
			List<PlayableCard> queuedCards = new List<PlayableCard>(__instance.Queue);
			queuedCards.Sort((PlayableCard a, PlayableCard b) => a.QueuedSlot.Index - b.QueuedSlot.Index);
			foreach (PlayableCard queuedCard in queuedCards.Where((PlayableCard qc) => !((Card)qc).Info.IsSpell()))
			{
				if (!__instance.QueuedCardIsBlocked(queuedCard))
				{
					CardSlot queuedSlot = queuedCard.QueuedSlot;
					queuedCard.QueuedSlot = null;
					PlayableCard obj = queuedCard;
					if (obj != null)
					{
						obj.OnPlayedFromOpponentQueue();
					}
					yield return Singleton<BoardManager>.Instance.ResolveCardOnBoard(queuedCard, queuedSlot, tweenLength, (Action)null, true);
					playedCards.Add(queuedCard);
				}
			}
			foreach (PlayableCard queuedCard in queuedCards.Where((PlayableCard qc) => ((Card)qc).Info.IsSpell()))
			{
				if (!__instance.QueuedCardIsBlocked(queuedCard))
				{
					CardSlot queuedSlot2 = queuedCard.QueuedSlot;
					queuedCard.QueuedSlot = null;
					PlayableCard obj2 = queuedCard;
					if (obj2 != null)
					{
						obj2.OnPlayedFromOpponentQueue();
					}
					yield return Singleton<BoardManager>.Instance.ResolveCardOnBoard(queuedCard, queuedSlot2, tweenLength, (Action)null, true);
					playedCards.Add(queuedCard);
				}
			}
			__instance.Queue.RemoveAll(playedCards.Contains);
			yield return (object)new WaitForSeconds(0.5f);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Opponent), "QueuedCardIsBlocked")]
		private static void QueuedSpellsCantBeBlocked(ref bool __result, PlayableCard queuedCard)
		{
			if ((Object)(object)queuedCard != (Object)null && ((Card)queuedCard).Info.IsSpell())
			{
				__result = false;
			}
		}

		public static CardSlot OpponentGetTargetSlot(List<CardSlot> validTargets)
		{
			CardSlot result = null;
			if (validTargets.Count > 0)
			{
				validTargets.Sort((CardSlot a, CardSlot b) => AIEvaluateTarget(b.Card) - AIEvaluateTarget(a.Card));
				result = validTargets[0];
			}
			return result;
		}

		private static int AIEvaluateTarget(PlayableCard card)
		{
			if ((Object)(object)card == (Object)null)
			{
				return Random.Range(0, 5);
			}
			int result = card.PowerLevel;
			if (((Card)card).Info.HasTrait((Trait)12))
			{
				result = 10 * (card.OpponentCard ? 1 : (-1));
			}
			return result;
		}

		private static bool CustomRespondsToTrigger(this CardTriggerHandler handler, Trigger trigger, params object[] otherArgs)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			foreach (TriggerReceiver allReceiver in GetAllReceivers(handler))
			{
				if (GlobalTriggerHandler.ReceiverRespondsToTrigger(trigger, allReceiver, otherArgs))
				{
					return true;
				}
			}
			return false;
		}

		private static List<TriggerReceiver> GetAllReceivers(CardTriggerHandler handler)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			List<TriggerReceiver> list = new List<TriggerReceiver>();
			foreach (Tuple<SpecialTriggeredAbility, SpecialCardBehaviour> specialAbility in handler.specialAbilities)
			{
				list.Add((TriggerReceiver)(object)specialAbility.Item2);
			}
			foreach (Tuple<Ability, AbilityBehaviour> triggeredAbility in handler.triggeredAbilities)
			{
				if ((int)triggeredAbility.Item1 != 35)
				{
					list.Add((TriggerReceiver)(object)triggeredAbility.Item2);
				}
			}
			list.AddRange((IEnumerable<TriggerReceiver>)handler.permanentlyAttachedBehaviours);
			list.Sort((TriggerReceiver a, TriggerReceiver b) => b.Priority.CompareTo(a.Priority));
			return list;
		}
	}
	public static class SpellCards
	{
		internal static void RegisterCustomCards()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected I4, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected I4, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected I4, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected I4, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected I4, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected I4, but got Unknown
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Expected I4, but got Unknown
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Expected I4, but got Unknown
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Expected I4, but got Unknown
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Expected I4, but got Unknown
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Expected I4, but got Unknown
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Expected I4, but got Unknown
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Expected I4, but got Unknown
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Kettle_of_Avarice", "Kettle of Avarice", 0, 0, "A jug that allows you to draw two more cards from your deck.")), AssetHelper.LoadTexture("kettle_of_avarice", (FilterMode)0), (FilterMode?)null).SetGlobalSpell(), (int?)1, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)(int)DrawTwoCards.AbilityID });
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetRare(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Anger_of_the_Gods", "Anger of the Gods", 0, 0, "For when nothing else will do the trick.")), AssetHelper.LoadTexture("anger_of_all", (FilterMode)0), (FilterMode?)null).SetGlobalSpell()), (int?)2, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)(int)DestroyAllCardsOnDeath.AbilityID });
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Lightning", "Lightning", 0, 0, "A perfectly serviceable amount of damage.")), AssetHelper.LoadTexture("lightning_bolt", (FilterMode)0), (FilterMode?)null).SetTargetedSpell(), (int?)1, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)(int)DirectDamage.AbilityID,
				(Ability)(int)DirectDamage.AbilityID
			});
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Backpack", "Trip to the Store", 0, 0, "Send one of your creatures on a trip to the store. Who knows what they will come back with.")), AssetHelper.LoadTexture("backpack", (FilterMode)0), (FilterMode?)null).SetGlobalSpell(), (int?)2, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)29 });
			CardInfo obj = CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Rot_Healing", "Rot Healing", 0, 0, "Restores just a little bit of health.")), AssetHelper.LoadTexture("plague_doctor", (FilterMode)0), (FilterMode?)null).SetTargetedSpell();
			int? num = 1;
			CardExtensions.AddAbilities(CardExtensions.SetCost(obj, (int?)0, num, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)(int)DirectHeal.AbilityID,
				(Ability)(int)DirectHeal.AbilityID
			});
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Dammed_up", "Dammed Up", 0, 0, "So many dams...")), AssetHelper.LoadTexture("dammed_up", (FilterMode)0), (FilterMode?)null).SetTargetedSpell(), (int?)1, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)33,
				(Ability)6
			});
			CardInfo obj2 = CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Irritate", "Irritate", 0, 0, "This is what happens when you poke the bear...or wolf.")), AssetHelper.LoadTexture("snarling_wolf", (FilterMode)0), (FilterMode?)null).SetTargetedSpell();
			num = 2;
			CardExtensions.AddAbilities(CardExtensions.SetCost(obj2, (int?)0, num, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)(int)AttackBuff.AbilityID,
				(Ability)(int)DirectDamage.AbilityID
			});
			CardInfo obj3 = CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Compost", "Compost", 0, 0, "Time to recycle those old bones.")), AssetHelper.LoadTexture("compost", (FilterMode)0), (FilterMode?)null).SetGlobalSpell();
			num = 5;
			CardExtensions.AddAbilities(CardExtensions.SetCost(obj3, (int?)0, num, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)(int)DrawTwoCards.AbilityID });
			CardExtensions.AddAbilities(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Fetch", "Go Fetch", 0, 0, "Good doggy.")), AssetHelper.LoadTexture("wolf_fetch", (FilterMode)0), (FilterMode?)null).SetGlobalSpell(), (Ability[])(object)new Ability[1] { (Ability)12 });
			CardInfo obj4 = CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Body", "Body Without a Soul", 0, 3, "A husk to be used and discarded.")), AssetHelper.LoadTexture("body", (FilterMode)0), (FilterMode?)null).SetTargetedSpellStats();
			num = 2;
			CardExtensions.AddAbilities(CardExtensions.SetCost(obj4, (int?)0, num, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)(int)GiveStats.AbilityID });
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Soul", "Soul Without a Body", 0, 0, "A disembodied soul. It will empower one of your creatures.")), AssetHelper.LoadTexture("soul", (FilterMode)0), (FilterMode?)null).SetTargetedSpell(), (int?)1, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)5,
				(Ability)(int)GiveSigils.AbilityID
			});
			CardExtensions.AddAbilities(CardExtensions.SetCost(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Desire", "Another's Desire", 2, 0, "Nothing short of victory will suffice.")), AssetHelper.LoadTexture("desire", (FilterMode)0), (FilterMode?)null).SetTargetedSpellStats(), (int?)1, (int?)0, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[2]
			{
				(Ability)35,
				(Ability)(int)GiveStatsSigils.AbilityID
			});
			CardInfo obj5 = CardExtensions.SetRare(CardExtensions.SetPortrait(CardExtensions.SetDefaultPart1Card(CardManager.New("ZSPL", "Spell_Hope", "Hope", 1, 1, "A rare, fleeting feeling. Hold onto it.")), AssetHelper.LoadTexture("hope", (FilterMode)0), (FilterMode?)null).SetGlobalSpellStats());
			num = 2;
			CardExtensions.AddAbilities(CardExtensions.SetCost(obj5, (int?)0, num, (int?)0, (List<GemType>)null), (Ability[])(object)new Ability[1] { (Ability)(int)GiveStats.AbilityID });
		}
	}
}
namespace Infiniscryption.Core.Helpers
{
	public static class AssetHelper
	{
		public static string FindResourceName(string key, string type, Assembly target)
		{
			string value = "." + key.ToLowerInvariant() + "." + type.ToLowerInvariant();
			string[] manifestResourceNames = target.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (text.ToLowerInvariant().EndsWith(value))
				{
					return text;
				}
			}
			return null;
		}

		private static byte[] GetResourceBytes(string key, string type, Assembly target)
		{
			string text = FindResourceName(key, type, target);
			if (string.IsNullOrEmpty(text))
			{
				string text2 = "";
				string[] manifestResourceNames = target.GetManifestResourceNames();
				foreach (string text3 in manifestResourceNames)
				{
					text2 = text2 + "," + text3;
				}
				throw new InvalidDataException("Could not find resource matching " + key + ". This is what I have: " + text2);
			}
			using Stream stream = target.GetManifestResourceStream(text);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public static string GetResourceString(string key, string type)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = FindResourceName(key, type, executingAssembly);
			if (string.IsNullOrEmpty(text))
			{
				string text2 = "";
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text3 in manifestResourceNames)
				{
					text2 = text2 + "," + text3;
				}
				throw new InvalidDataException("Could not find resource matching " + key + ". This is what I have: " + text2);
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		public static Texture2D LoadTexture(string texture, FilterMode filterMode = 0)
		{
			//IL_0002: 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_001f: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2);
			byte[] resourceBytes = GetResourceBytes(texture, "png", Assembly.GetExecutingAssembly());
			ImageConversion.LoadImage(val, resourceBytes);
			((Object)val).name = "Infiniscryption_" + texture;
			((Texture)val).filterMode = filterMode;
			return val;
		}

		private static string WriteWavToFile(string wavname)
		{
			byte[] resourceBytes = GetResourceBytes(wavname, "wav", Assembly.GetExecutingAssembly());
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), wavname + ".wav");
			File.WriteAllBytes(text, resourceBytes);
			return text;
		}

		public static void LoadAudioClip(string clipname, ManualLogSource log = null, string group = "Loops")
		{
			List<AudioClip> value = Traverse.Create((object)AudioController.Instance).Field(group).GetValue<List<AudioClip>>();
			if ((Object)(object)value.Find((AudioClip clip) => ((Object)clip).name.Equals(clipname)) != (Object)null)
			{
				return;
			}
			string text = WriteWavToFile(clipname);
			try
			{
				if (log != null)
				{
					log.LogInfo((object)("About to get audio clip at file://" + text));
				}
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)20);
				try
				{
					audioClip.SendWebRequest();
					while (audioClip.IsExecuting())
					{
					}
					if (audioClip.isHttpError)
					{
						throw new InvalidOperationException("Bad request getting audio clip " + audioClip.error);
					}
					AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
					((Object)content).name = clipname;
					value.Add(content);
				}
				finally
				{
					((IDisposable)audioClip)?.Dispose();
				}
			}
			finally
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
		}
	}
	public static class AudioHelper
	{
		public struct AudioState
		{
			public int sourceNum;

			public string clipName;

			public float position;

			public bool isPlaying;

			public float volume;
		}

		public static List<AudioState> PauseAllLoops()
		{
			List<AudioSource> value = Traverse.Create((object)AudioController.Instance).Field("loopSources").GetValue<List<AudioSource>>();
			List<AudioState> list = new List<AudioState>();
			for (int i = 0; i < value.Count; i++)
			{
				AudioSource val = value[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val.clip == (Object)null)
				{
					list.Add(new AudioState
					{
						sourceNum = i,
						position = 0f,
						clipName = null,
						isPlaying = false
					});
				}
				else
				{
					list.Add(new AudioState
					{
						sourceNum = i,
						position = (val.isPlaying ? (val.time / val.clip.length) : 0f),
						clipName = ((Object)val.clip).name,
						isPlaying = val.isPlaying,
						volume = val.volume
					});
				}
			}
			AudioController.Instance.StopAllLoops();
			return list;
		}

		public static void ResumeAllLoops(List<AudioState> states)
		{
			for (int i = 0; i < states.Count; i++)
			{
				if (states[i].isPlaying)
				{
					AudioController.Instance.SetLoopAndPlay(states[i].clipName, i, true, true);
					AudioController.Instance.SetLoopVolumeImmediate(0f, i);
					AudioController.Instance.SetLoopTimeNormalized(states[i].position, i);
					AudioController.Instance.FadeInLoop(1f, states[i].volume, new int[1] { i });
				}
				else
				{
					AudioController.Instance.StopLoop(i);
				}
			}
		}
	}
	public static class DialogueHelper
	{
		public static LineSet CreateLineSet(string[] lineString, Emotion emotion = 0, LetterAnimation animation = 2, Face p03Face = 0, int speakerIndex = 0)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			return new LineSet
			{
				lines = ((IEnumerable<string>)lineString).Select((Func<string, Line>)((string s) => new Line
				{
					text = s,
					emotion = emotion,
					letterAnimation = animation,
					p03Face = p03Face,
					speakerIndex = speakerIndex
				})).ToList()
			};
		}

		public static void AddOrModifySimpleDialogEvent(string eventId, string line, LetterAnimation? animation = null, Emotion? emotion = null)
		{
			string[] lines = new string[1] { line };
			AddOrModifySimpleDialogEvent(eventId, lines, null, animation, emotion);
		}

		private static void SyncLineCollection(List<Line> curLines, string[] newLines, LetterAnimation? animation, Emotion? emotion)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			while (curLines.Count > newLines.Length)
			{
				curLines.RemoveAt(curLines.Count - 1);
			}
			for (int i = 0; i < curLines.Count; i++)
			{
				curLines[i].text = newLines[i];
			}
			for (int j = curLines.Count; j < newLines.Length; j++)
			{
				Line val = CloneLine(curLines[0]);
				val.text = newLines[j];
				if (animation.HasValue)
				{
					val.letterAnimation = animation.Value;
				}
				if (emotion.HasValue)
				{
					val.emotion = emotion.Value;
				}
				curLines.Add(val);
			}
		}

		public static void AddOrModifySimpleDialogEvent(string eventId, string[] lines, string[][] repeatLines = null, LetterAnimation? animation = null, Emotion? emotion = null, string template = "NewRunDealtDeckDefault")
		{
			bool flag = false;
			DialogueEvent val = DialogueDataUtil.Data.GetEvent(eventId);
			if (val == null)
			{
				flag = true;
				val = CloneDialogueEvent(DialogueDataUtil.Data.GetEvent(template), eventId);
				while (val.mainLines.lines.Count > lines.Length)
				{
					val.mainLines.lines.RemoveAt(lines.Length);
				}
			}
			SyncLineCollection(val.mainLines.lines, lines, animation, emotion);
			if (repeatLines == null)
			{
				val.repeatLines.Clear();
			}
			else
			{
				while (val.repeatLines.Count > repeatLines.Length)
				{
					val.repeatLines.RemoveAt(val.repeatLines.Count - 1);
				}
				for (int i = 0; i < val.repeatLines.Count; i++)
				{
					SyncLineCollection(val.repeatLines[i].lines, repeatLines[i], animation, emotion);
				}
			}
			if (flag)
			{
				DialogueDataUtil.Data.events.Add(val);
			}
		}

		public static Line CloneLine(Line line)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_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_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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			return new Line
			{
				p03Face = line.p03Face,
				emotion = line.emotion,
				letterAnimation = line.letterAnimation,
				speakerIndex = line.speakerIndex,
				text = line.text,
				specialInstruction = line.specialInstruction,
				storyCondition = line.storyCondition,
				storyConditionMustBeMet = line.storyConditionMustBeMet
			};
		}

		public static DialogueEvent CloneDialogueEvent(DialogueEvent dialogueEvent, string newId, bool includeRepeat = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: 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_003a: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			DialogueEvent val = new DialogueEvent
			{
				id = newId,
				groupId = dialogueEvent.groupId,
				mainLines = new LineSet(),
				speakers = new List<Speaker>(),
				repeatLines = new List<LineSet>()
			};
			foreach (Line line in dialogueEvent.mainLines.lines)
			{
				val.mainLines.lines.Add(CloneLine(line));
			}
			if (includeRepeat)
			{
				foreach (LineSet repeatLine in dialogueEvent.repeatLines)
				{
					LineSet val2 = new LineSet();
					foreach (Line line2 in repeatLine.lines)
					{
						val2.lines.Add(CloneLine(line2));
					}
					val.repeatLines.Add(val2);
				}
			}
			foreach (Speaker speaker in dialogueEvent.speakers)
			{
				val.speakers.Add(speaker);
			}
			return val;
		}
	}
	public static class JSONParser
	{
		[ThreadStatic]
		private static Stack<List<string>> splitArrayPool;

		[ThreadStatic]
		private static StringBuilder stringBuilder;

		[ThreadStatic]
		private static Dictionary<Type, Dictionary<string, FieldInfo>> fieldInfoCache;

		[ThreadStatic]
		private static Dictionary<Type, Dictionary<string, PropertyInfo>> propertyInfoCache;

		public static T FromJson<T>(this string json)
		{
			if (propertyInfoCache == null)
			{
				propertyInfoCache = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
			}
			if (fieldInfoCache == null)
			{
				fieldInfoCache = new Dictionary<Type, Dictionary<string, FieldInfo>>();
			}
			if (stringBuilder == null)
			{
				stringBuilder = new StringBuilder();
			}
			if (splitArrayPool == null)
			{
				splitArrayPool = new Stack<List<string>>();
			}
			stringBuilder.Length = 0;
			for (int i = 0; i < json.Length; i++)
			{
				char c = json[i];
				if (c == '"')
				{
					i = AppendUntilStringEnd(appendEscapeCharacter: true, i, json);
				}
				else if (!char.IsWhiteSpace(c))
				{
					stringBuilder.Append(c);
				}
			}
			return (T)ParseValue(typeof(T), stringBuilder.ToString());
		}

		private static int AppendUntilStringEnd(bool appendEscapeCharacter, int startIdx, string json)
		{
			stringBuilder.Append(json[startIdx]);
			for (int i = startIdx + 1; i < json.Length; i++)
			{
				if (json[i] == '\\')
				{
					if (appendEscapeCharacter)
					{
						stringBuilder.Append(json[i]);
					}
					stringBuilder.Append(json[i + 1]);
					i++;
				}
				else
				{
					if (json[i] == '"')
					{
						stringBuilder.Append(json[i]);
						return i;
					}
					stringBuilder.Append(json[i]);
				}
			}
			return json.Length - 1;
		}

		private static List<string> Split(string json)
		{
			L