Decompiled source of From The Neverwhere v1.0.2

FromTheNeverwhere.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using DiskCardGame;
using HarmonyLib;
using InscryptionAPI.Card;
using InscryptionAPI.Helpers;
using InscryptionAPI.Saves;
using InscryptionAPI.Sound;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("FromTheNeverwhere")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Cynara's card pack for Act 1 and Kaycee's Mod")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FromTheNeverwhere")]
[assembly: AssemblyTitle("FromTheNeverwhere")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FTN
{
	public class FiredrakeAppearance : CardAppearanceBehaviour
	{
		public static Appearance appearance;

		private static Texture2D texture;

		public static void Init()
		{
			//IL_001a: 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)
			appearance = CardAppearanceBehaviourManager.Add("FTN", "FiredrakeAppearance", typeof(FiredrakeAppearance)).Id;
		}

		public override void ApplyAppearance()
		{
			if ((Object)(object)texture == (Object)null)
			{
				string text = Path.Combine(Plugin.ModRoot, "Resources", "Appearances", "Firedrake_Cardback.png");
				if (!File.Exists(text))
				{
					return;
				}
				texture = TextureHelper.GetImageAsTexture(text, (FilterMode)0);
			}
			((CardAppearanceBehaviour)this).Card.RenderInfo.baseTextureOverride = (Texture)(object)texture;
		}
	}
	[BepInPlugin("FTN", "From the Neverwhere", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "FTN";

		public const string PluginName = "From the Neverwhere";

		public const string PluginVersion = "0.1.0";

		internal static ManualLogSource Log;

		internal static string ModRoot;

		internal static readonly List<AudioClip> CustomClips = new List<AudioClip>();

		private void Awake()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModRoot = FindModRoot(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			new Harmony("FTN").PatchAll();
			AuroraBehaviour.Init();
			LycanBiteBehaviour.Init();
			GrowUpBehaviour.Init();
			DeadEndBehaviour.Init();
			EscapeBehaviour.Init();
			InfernoBehaviour.Init();
			StoneborneBehaviour.Init();
			HollowHuntBehaviour.Init();
			MiasmaBehaviour.Init();
			MomentumBehaviour.Init();
			PearlSpewerBehaviour.Init();
			PlunderBehaviour.Init();
			ReprisalBehaviour.Init();
			SecondLifeBehaviour.Init();
			WitnessBehaviour.Init();
			FiredrakeAppearance.Init();
			LoadSounds();
		}

		private static string FindModRoot(string startDir)
		{
			string text = startDir;
			for (int i = 0; i < 8; i++)
			{
				if (string.IsNullOrEmpty(text))
				{
					break;
				}
				if (Directory.Exists(Path.Combine(text, "Cards")))
				{
					return text;
				}
				text = Path.GetDirectoryName(text);
			}
			return startDir;
		}

		private static void LoadSounds()
		{
			string[] files = Directory.GetFiles(ModRoot, "*.*", SearchOption.AllDirectories);
			foreach (string path in files)
			{
				string text = Path.GetExtension(path).ToLowerInvariant();
				if (text == ".wav" || text == ".ogg" || text == ".mp3")
				{
					LoadSound(Path.GetFileName(path), Path.GetFileNameWithoutExtension(path));
				}
			}
		}

		private static void LoadSound(string fileName, string soundName)
		{
			AudioClip val = SoundManager.LoadAudioClip("FTN", fileName);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)("Could not load " + fileName));
				return;
			}
			((Object)val).name = soundName;
			CustomClips.Add(val);
		}
	}
	[HarmonyPatch(typeof(AudioController), "GetAudioClip")]
	internal static class AudioControllerPatch
	{
		[HarmonyPrefix]
		private static void AddCustomClips(ref List<AudioClip> ___SFX)
		{
			foreach (AudioClip customClip in Plugin.CustomClips)
			{
				if (!___SFX.Contains(customClip))
				{
					___SFX.Add(customClip);
				}
			}
		}
	}
	public class AuroraBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Aurora", typeof(AuroraBehaviour)).Id;
		}

		public override bool RespondsToDrawn()
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null;
		}

		public override IEnumerator OnDrawn()
		{
			List<CardInfo> pool = Util.CardsFromNames(Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "FTN_Celestials"));
			if (pool.Count != 0)
			{
				CardInfo chosen = CardLoader.GetCardByName(((Object)pool[Random.Range(0, pool.Count)]).name);
				yield return (object)new WaitForSeconds(0.4f);
				Util.PlaySound(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "FTN_AuroraSound");
				((Card)((SpecialCardBehaviour)this).PlayableCard).Anim.PlayTransformAnimation();
				((Card)((SpecialCardBehaviour)this).PlayableCard).SetInfo(chosen);
			}
		}
	}
	public class DeadEndBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const int MaxWalls = 4;

		private const string WallProperty = "DeadEndOverride";

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "DeadEnd", typeof(DeadEndBehaviour)).Id;
		}

		internal static bool IsWall(PlayableCard minotaur, PlayableCard other)
		{
			string text = Util.Prop(((Card)minotaur).Info, "DeadEndOverride");
			return !string.IsNullOrEmpty(text) && ((Object)((Card)other).Info).name == text;
		}

		public override bool RespondsToTurnEnd(bool playerTurnEnd)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && playerTurnEnd == !((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnTurnEnd(bool playerTurnEnd)
		{
			CardInfo wall = Util.GetCard(Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "DeadEndOverride"));
			if ((Object)(object)wall == (Object)null)
			{
				yield break;
			}
			BoardManager board = Singleton<BoardManager>.Instance;
			if (board.CardsOnBoard.Count((PlayableCard c) => (Object)(object)c != (Object)null && ((Object)((Card)c).Info).name == ((Object)wall).name) < 4)
			{
				List<CardSlot> free = (from s in board.GetSlots(((SpecialCardBehaviour)this).PlayableCard.OpponentCard)
					where (Object)(object)s.Card == (Object)null
					select s).ToList();
				if (free.Count != 0)
				{
					yield return board.CreateCardInSlot(wall, free[Random.Range(0, free.Count)], 0.15f, true);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayableCard), "AttackIsBlocked")]
	internal static class MinotaurRefusalPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayableCard __instance, CardSlot opposingSlot, ref bool __result)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!__result && !((Object)(object)opposingSlot == (Object)null) && !((Object)(object)opposingSlot.Card == (Object)null) && ((Card)__instance).Info.SpecialAbilities.Contains(DeadEndBehaviour.ability) && DeadEndBehaviour.IsWall(__instance, opposingSlot.Card))
			{
				__result = true;
			}
		}
	}
	public class EscapeBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Escape", typeof(EscapeBehaviour)).Id;
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return !wasSacrifice && (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && !((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			CardDrawPiles piles = Singleton<CardDrawPiles>.Instance;
			piles.Deck.AddCard(((Card)((SpecialCardBehaviour)this).PlayableCard).Info);
			CardDrawPiles3D piles3D = (CardDrawPiles3D)(object)((piles is CardDrawPiles3D) ? piles : null);
			if ((Object)(object)piles3D != (Object)null)
			{
				piles3D.Pile.CreateCards(1, 15f);
			}
			yield return (object)new WaitForSeconds(0.2f);
		}
	}
	public class HollowHuntBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const int MaxTenants = 3;

		private int released;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "HollowHunt", typeof(HollowHuntBehaviour)).Id;
		}

		private List<CardSlot> FreeSlots()
		{
			return (from s in Singleton<BoardManager>.Instance.GetSlots(!((SpecialCardBehaviour)this).PlayableCard.OpponentCard)
				where (Object)(object)s.Card == (Object)null
				select s).ToList();
		}

		private List<CardInfo> Tenants()
		{
			return Util.CardsFromNames(Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "FTN_Tenants"));
		}

		private IEnumerator Release(CardSlot slot, List<CardInfo> tenants)
		{
			released++;
			CardInfo chosen = tenants[Random.Range(0, tenants.Count)];
			yield return Singleton<BoardManager>.Instance.CreateCardInSlot(CardLoader.GetCardByName(((Object)chosen).name), slot, 0.15f, true);
		}

		public override bool RespondsToTurnEnd(bool playerTurnEnd)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && playerTurnEnd == !((SpecialCardBehaviour)this).PlayableCard.OpponentCard && released < 3 && FreeSlots().Count > 0;
		}

		public override IEnumerator OnTurnEnd(bool playerTurnEnd)
		{
			List<CardInfo> tenants = Tenants();
			List<CardSlot> free = FreeSlots();
			if (tenants.Count > 0 && free.Count > 0)
			{
				yield return Release(free[Random.Range(0, free.Count)], tenants);
			}
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return !wasSacrifice && (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			List<CardInfo> tenants = Tenants();
			List<CardSlot> free = FreeSlots();
			while (tenants.Count > 0 && released < 3 && free.Count > 0)
			{
				CardSlot slot = free[Random.Range(0, free.Count)];
				free.Remove(slot);
				yield return Release(slot, tenants);
			}
		}
	}
	public class InfernoBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Inferno", typeof(InfernoBehaviour)).Id;
		}

		public override bool RespondsToResolveOnBoard()
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			yield return IgniteAll();
		}

		public override bool RespondsToUpkeep(bool playerUpkeep)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && playerUpkeep == !((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnUpkeep(bool playerUpkeep)
		{
			yield return IgniteAll();
		}

		public override bool RespondsToOtherCardResolve(PlayableCard otherCard)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && (Object)(object)otherCard != (Object)null && otherCard.OpponentCard != ((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnOtherCardResolve(PlayableCard otherCard)
		{
			yield return Ignite(otherCard);
		}

		private IEnumerator IgniteAll()
		{
			foreach (PlayableCard card in Singleton<BoardManager>.Instance.CardsOnBoard.ToList())
			{
				if ((Object)(object)card != (Object)null && card.OpponentCard != ((SpecialCardBehaviour)this).PlayableCard.OpponentCard)
				{
					yield return Ignite(card);
				}
			}
		}

		private IEnumerator Ignite(PlayableCard target)
		{
			if (!((Object)(object)target == (Object)null) && !target.Dead && Util.TryFindAbility("Burning", out var burning) && !target.HasAbility(burning))
			{
				target.AddTemporaryMod(new CardModificationInfo(burning));
				((Card)target).Anim.PlayTransformAnimation();
				yield return (object)new WaitForSeconds(0.1f);
			}
		}
	}
	public class LycanBiteBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private readonly HashSet<PlayableCard> marked = new HashSet<PlayableCard>();

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "LycanBite", typeof(LycanBiteBehaviour)).Id;
		}

		public override bool RespondsToDealDamage(int amount, PlayableCard target)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && (Object)(object)target != (Object)null && !target.Dead && target.Health > 0 && !marked.Contains(target);
		}

		public override IEnumerator OnDealDamage(int amount, PlayableCard target)
		{
			marked.Add(target);
			yield break;
		}

		public override bool RespondsToOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && ((Object)(object)killer == (Object)(object)((SpecialCardBehaviour)this).PlayableCard || marked.Contains(card));
		}

		public override IEnumerator OnOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer)
		{
			marked.Remove(card);
			List<CardSlot> free = (from s in Singleton<BoardManager>.Instance.GetSlots(!((SpecialCardBehaviour)this).PlayableCard.OpponentCard)
				where (Object)(object)s.Card == (Object)null
				select s).ToList();
			CardInfo pup = Util.GetCard(Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "LycanBiteOverride"));
			if (free.Count != 0 && !((Object)(object)pup == (Object)null))
			{
				yield return Singleton<BoardManager>.Instance.CreateCardInSlot(pup, free[Random.Range(0, free.Count)], 0.15f, true);
			}
		}
	}
	public class GrowUpBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const int TurnsToGrow = 1;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "GrowUp", typeof(GrowUpBehaviour)).Id;
		}

		public override bool RespondsToResolveOnBoard()
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			List<CardInfo> canines = (from c in CardLoader.GetUnlockedCards((CardMetaCategory)0, (CardTemple)0)
				where c.IsOfTribe((Tribe)3) && ((Object)c).name != ((Object)((Card)((SpecialCardBehaviour)this).PlayableCard).Info).name
				select c).ToList();
			if (canines.Count != 0)
			{
				((Card)((SpecialCardBehaviour)this).PlayableCard).Info.evolveParams = new EvolveParams
				{
					turnsToEvolve = 1,
					evolution = canines[Random.Range(0, canines.Count)]
				};
			}
			yield break;
		}
	}
	public class MiasmaBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Miasma", typeof(MiasmaBehaviour)).Id;
		}

		internal static bool Has(PlayableCard card)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)((Card)card).Info != (Object)null && ((Card)card).Info.SpecialAbilities.Contains(ability);
		}
	}
	[HarmonyPatch(typeof(PlayableCard), "GetPassiveAttackBuffs")]
	internal static class MiasmaPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayableCard __instance, ref int __result)
		{
			if (!__instance.OnBoard || __instance.HasAbility((Ability)105))
			{
				return;
			}
			BoardManager instance = Singleton<BoardManager>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			int num = 0;
			foreach (PlayableCard item in instance.CardsOnBoard)
			{
				if (!((Object)(object)item == (Object)null) && item.OpponentCard != __instance.OpponentCard && !((Card)item).FaceDown && MiasmaBehaviour.Has(item) && (!item.HasAbility((Ability)83) || !((Object)(object)__instance.Slot != (Object)null) || !((Object)(object)__instance.Slot.opposingSlot == (Object)(object)item.Slot)))
				{
					num++;
				}
			}
			__result -= num;
		}
	}
	public class PearlSpewerBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const int MaxPearls = 3;

		private int pearls;

		private static Texture2D pearlTex;

		private static readonly FieldInfo particleField = AccessTools.Field(typeof(PaperCardAnimationController), "deathParticles");

		private const float PearlSize = 0.18f;

		private ParticleSystem system;

		private readonly Particle[] buffer = (Particle[])(object)new Particle[3];

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "PearlSpewer", typeof(PearlSpewerBehaviour)).Id;
		}

		public override void ManagedUpdate()
		{
			if (pearls > 0 && (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && !((SpecialCardBehaviour)this).PlayableCard.Dead)
			{
				if ((Object)(object)system == (Object)null)
				{
					system = CreateSystem(((SpecialCardBehaviour)this).PlayableCard);
				}
				if ((Object)(object)system != (Object)null)
				{
					Orbit();
				}
			}
			((ManagedBehaviour)this).ManagedUpdate();
		}

		private void Orbit()
		{
			//IL_0006: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			while (system.particleCount < pearls)
			{
				EmitParams val = default(EmitParams);
				((EmitParams)(ref val)).startLifetime = 100000f;
				((EmitParams)(ref val)).startSize = 0.18f;
				((EmitParams)(ref val)).startColor = Color32.op_Implicit(Color.white);
				((EmitParams)(ref val)).velocity = Vector3.zero;
				((EmitParams)(ref val)).position = ((Component)((SpecialCardBehaviour)this).PlayableCard).transform.position;
				system.Emit(val, 1);
			}
			int particles = system.GetParticles(buffer);
			Vector3 position = ((Component)((SpecialCardBehaviour)this).PlayableCard).transform.position;
			for (int i = 0; i < particles; i++)
			{
				float num = Time.time * 0.9f + (float)i * MathF.PI * 2f / 3f;
				((Particle)(ref buffer[i])).position = position + Vector3.right * Mathf.Cos(num) * 0.6f + Vector3.forward * Mathf.Sin(num) * 0.75f + Vector3.up * 0.15f;
				((Particle)(ref buffer[i])).velocity = Vector3.zero;
				((Particle)(ref buffer[i])).remainingLifetime = 100000f;
			}
			system.SetParticles(buffer, particles);
		}

		private static ParticleSystem CreateSystem(PlayableCard card)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			CardAnimationController anim = ((Card)card).Anim;
			PaperCardAnimationController val = (PaperCardAnimationController)(object)((anim is PaperCardAnimationController) ? anim : null);
			GameObject val2 = (GameObject)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			if ((Object)(object)pearlTex == (Object)null)
			{
				pearlTex = LoadTexture();
			}
			GameObject val3 = Object.Instantiate<GameObject>(val2);
			ParticleSystem component = val3.GetComponent<ParticleSystem>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val3);
				return null;
			}
			val3.transform.SetParent(((Component)card).transform, false);
			val3.transform.localScale = Vector3.one;
			component.Stop(true, (ParticleSystemStopBehavior)0);
			MainModule main = component.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			((MainModule)(ref main)).maxParticles = 3;
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(100000f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.18f);
			((MainModule)(ref main)).startColor = new MinMaxGradient(Color.white);
			EmissionModule emission = component.emission;
			((EmissionModule)(ref emission)).enabled = false;
			ShapeModule shape = component.shape;
			((ShapeModule)(ref shape)).enabled = false;
			VelocityOverLifetimeModule velocityOverLifetime = component.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false;
			ForceOverLifetimeModule forceOverLifetime = component.forceOverLifetime;
			((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = false;
			ColorOverLifetimeModule colorOverLifetime = component.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = false;
			SizeOverLifetimeModule sizeOverLifetime = component.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = false;
			RotationOverLifetimeModule rotationOverLifetime = component.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = false;
			NoiseModule noise = component.noise;
			((NoiseModule)(ref noise)).enabled = false;
			LimitVelocityOverLifetimeModule limitVelocityOverLifetime = component.limitVelocityOverLifetime;
			((LimitVelocityOverLifetimeModule)(ref limitVelocityOverLifetime)).enabled = false;
			ParticleSystemRenderer component2 = ((Component)component).GetComponent<ParticleSystemRenderer>();
			((Renderer)component2).material = new Material(((Renderer)component2).material)
			{
				mainTexture = (Texture)(object)pearlTex
			};
			component2.renderMode = (ParticleSystemRenderMode)0;
			component2.minParticleSize = 0f;
			component2.maxParticleSize = 1f;
			val3.SetActive(true);
			component.Play();
			return component;
		}

		private static Texture2D LoadTexture()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Plugin.ModRoot, "Resources", "Appearances", "Pearl_Decal.png");
			if (File.Exists(text))
			{
				return TextureHelper.GetImageAsTexture(text, (FilterMode)0);
			}
			Texture2D val = new Texture2D(24, 24, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)0;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(11.5f, 11.5f);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(val2.x - 4f, val2.y + 4f);
			float num = 11f;
			Vector2 val4 = default(Vector2);
			for (int i = 0; i < 24; i++)
			{
				for (int j = 0; j < 24; j++)
				{
					((Vector2)(ref val4))..ctor((float)j, (float)i);
					if (Vector2.Distance(val4, val2) > num)
					{
						val.SetPixel(j, i, Color.clear);
						continue;
					}
					float num2 = Mathf.Clamp01(1f - Vector2.Distance(val4, val3) / (num * 1.6f));
					val.SetPixel(j, i, Color.Lerp(new Color(0.55f, 0.62f, 0.75f), Color.white, num2));
				}
			}
			val.Apply();
			return val;
		}

		public override bool RespondsToTakeDamage(PlayableCard source)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && ((SpecialCardBehaviour)this).PlayableCard.Health > 0 && pearls < 3;
		}

		public override IEnumerator OnTakeDamage(PlayableCard source)
		{
			pearls++;
			((Card)((SpecialCardBehaviour)this).PlayableCard).Anim.PlayTransformAnimation();
			yield return (object)new WaitForSeconds(0.15f);
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && !((SpecialCardBehaviour)this).PlayableCard.OpponentCard && pearls > 0;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			Util.PlaySound(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "FTN_PearlSound");
			string pearlName = Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "PearlSpewerOverride");
			for (int i = 0; i < pearls; i++)
			{
				CardInfo pearl = Util.GetCard(pearlName);
				if ((Object)(object)pearl == (Object)null)
				{
					break;
				}
				yield return Singleton<CardSpawner>.Instance.SpawnCardToHand(pearl, 0.25f);
			}
		}
	}
	public class PlunderBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const int MaxLoot = 2;

		private readonly List<Ability> loot = new List<Ability>();

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Plunder", typeof(PlunderBehaviour)).Id;
		}

		private List<Ability> Stealable(PlayableCard target)
		{
			return ((Card)target).Info.Abilities.Where((Ability a) => (int)a != 0 && !((SpecialCardBehaviour)this).PlayableCard.HasAbility(a)).Distinct().ToList();
		}

		public override bool RespondsToDealDamage(int amount, PlayableCard target)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && (Object)(object)target != (Object)null && !target.Dead && loot.Count < 2 && Stealable(target).Count > 0;
		}

		public override IEnumerator OnDealDamage(int amount, PlayableCard target)
		{
			List<Ability> options = Stealable(target);
			Ability stolen = options[Random.Range(0, options.Count)];
			loot.Add(stolen);
			target.AddTemporaryMod(new CardModificationInfo
			{
				negateAbilities = new List<Ability> { stolen }
			});
			((SpecialCardBehaviour)this).PlayableCard.AddTemporaryMod(new CardModificationInfo(stolen));
			((Card)((SpecialCardBehaviour)this).PlayableCard).Anim.PlayTransformAnimation();
			yield return (object)new WaitForSeconds(0.2f);
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && loot.Count > 0;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			List<PlayableCard> allies = (from s in Singleton<BoardManager>.Instance.GetSlots(!((SpecialCardBehaviour)this).PlayableCard.OpponentCard)
				select s.Card into c
				where (Object)(object)c != (Object)null && (Object)(object)c != (Object)(object)((SpecialCardBehaviour)this).PlayableCard && c.OnBoard
				select c).ToList();
			if (allies.Count == 0)
			{
				yield break;
			}
			PlayableCard heir = allies[Random.Range(0, allies.Count)];
			foreach (Ability stolen in loot)
			{
				if (!heir.HasAbility(stolen))
				{
					heir.AddTemporaryMod(new CardModificationInfo(stolen));
				}
			}
			((Card)heir).Anim.PlayTransformAnimation();
			yield return (object)new WaitForSeconds(0.2f);
		}
	}
	public class ReprisalBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private bool striking;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Reprisal", typeof(ReprisalBehaviour)).Id;
		}

		public override bool RespondsToDealDamage(int amount, PlayableCard target)
		{
			if (striking || (Object)(object)((SpecialCardBehaviour)this).PlayableCard == (Object)null || !((SpecialCardBehaviour)this).PlayableCard.OnBoard || (Object)(object)((SpecialCardBehaviour)this).PlayableCard.Slot == (Object)null)
			{
				return false;
			}
			if ((Object)(object)target == (Object)null || target.Dead || (Object)(object)target.Slot == (Object)null)
			{
				return false;
			}
			return (Object)(object)target.Slot != (Object)(object)((SpecialCardBehaviour)this).PlayableCard.Slot.opposingSlot;
		}

		public override IEnumerator OnDealDamage(int amount, PlayableCard target)
		{
			striking = true;
			yield return (object)new WaitForSeconds(0.15f);
			if ((Object)(object)target != (Object)null && !target.Dead)
			{
				((Card)((SpecialCardBehaviour)this).PlayableCard).Anim.PlayTransformAnimation();
				yield return target.TakeDamage(amount, ((SpecialCardBehaviour)this).PlayableCard);
			}
			striking = false;
		}
	}
	public class SecondLifeBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "SecondLife", typeof(SecondLifeBehaviour)).Id;
		}

		public override bool RespondsToDie(bool wasSacrifice, PlayableCard killer)
		{
			return !wasSacrifice && (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard;
		}

		public override IEnumerator OnDie(bool wasSacrifice, PlayableCard killer)
		{
			CardInfo cat = ((Card)((SpecialCardBehaviour)this).PlayableCard).Info;
			CardInfo grin = Util.GetCard(Util.Prop(cat, "SecondLifeLeaveBehind"));
			if (!((Object)(object)grin == (Object)null))
			{
				yield return Singleton<BoardManager>.Instance.CreateCardInSlot(grin, ((SpecialCardBehaviour)this).PlayableCard.Slot, 0.15f, true);
				Util.PlaySound(cat, "FTN_SecondLifeSound");
			}
		}
	}
	public class StoneborneBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const string VariantPrefix = "FTN_StoneborneFrom_";

		internal const string RefusalLine = "{0} is flesh. That creature will take only stone.";

		internal const string NeedStoneLine = "That creature demands stone. Only terrain can pay its price.";

		private static string lastTerrain;

		private static float lastTime;

		private static float lastSpoken = -100f;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Stoneborne", typeof(StoneborneBehaviour)).Id;
		}

		internal static bool IsStoneborne(PlayableCard card)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)card != (Object)null && (Object)(object)((Card)card).Info != (Object)null && ((Card)card).Info.SpecialAbilities.Contains(ability);
		}

		internal static void RecordSacrifice(string terrainCardName)
		{
			lastTerrain = terrainCardName;
			lastTime = Time.time;
		}

		internal static void Say(string line)
		{
			if (!(Time.time - lastSpoken < 4f))
			{
				lastSpoken = Time.time;
				TextDisplayer instance = Singleton<TextDisplayer>.Instance;
				((MonoBehaviour)instance).StartCoroutine(instance.ShowThenClear(line, 3f, 0f, (Emotion)0, (LetterAnimation)0, (Speaker)0, (string[])null));
			}
		}

		public override bool RespondsToResolveOnBoard()
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null;
		}

		public override IEnumerator OnResolveOnBoard()
		{
			string terrain = lastTerrain;
			bool recent = Time.time - lastTime < 20f;
			lastTerrain = null;
			if (recent && !string.IsNullOrEmpty(terrain))
			{
				string variant = Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "FTN_StoneborneFrom_" + terrain);
				if (!string.IsNullOrEmpty(variant))
				{
					yield return (object)new WaitForSeconds(0.3f);
					yield return ((SpecialCardBehaviour)this).PlayableCard.TransformIntoCard(CardLoader.GetCardByName(variant), (Action)null, (Action)null);
				}
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class StoneborneSacrificePatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayableCard __instance, ref bool __result)
		{
			BoardManager instance = Singleton<BoardManager>.Instance;
			if (!((Object)(object)instance == (Object)null) && StoneborneBehaviour.IsStoneborne(instance.CurrentSacrificeDemandingCard))
			{
				__result = !((Card)__instance).FaceDown && ((Card)__instance).Info.HasTrait((Trait)12);
			}
		}
	}
	[HarmonyPatch(typeof(HintsHandler), "OnNonsacrificableCardClicked")]
	internal static class StoneborneRefusalPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PlayableCard card)
		{
			BoardManager instance = Singleton<BoardManager>.Instance;
			if ((Object)(object)instance == (Object)null || !StoneborneBehaviour.IsStoneborne(instance.CurrentSacrificeDemandingCard) || ((Card)card).Info.HasTrait((Trait)12))
			{
				return true;
			}
			StoneborneBehaviour.Say($"{((Card)card).Info.DisplayedNameLocalized} is flesh. That creature will take only stone.");
			return false;
		}
	}
	[HarmonyPatch(typeof(HintsHandler), "OnNonplayableCardClicked")]
	internal static class StoneborneNeedsStonePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PlayableCard card)
		{
			if (!StoneborneBehaviour.IsStoneborne(card))
			{
				return true;
			}
			BoardManager instance = Singleton<BoardManager>.Instance;
			ResourcesManager instance2 = Singleton<ResourcesManager>.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				return true;
			}
			if (((Card)card).Info.BonesCost > instance2.PlayerBones || card.EnergyCost > instance2.PlayerEnergy)
			{
				return true;
			}
			int num = instance.CardsOnBoard.Count((PlayableCard c) => (Object)(object)c != (Object)null && !c.OpponentCard && !((Card)c).FaceDown && ((Card)c).Info.HasTrait((Trait)12));
			if (num >= ((Card)card).Info.BloodCost)
			{
				return true;
			}
			StoneborneBehaviour.Say("That creature demands stone. Only terrain can pay its price.");
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayableCard), "CanPlay")]
	internal static class StonebornePlayPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayableCard __instance, ref bool __result)
		{
			if (!StoneborneBehaviour.IsStoneborne(__instance))
			{
				return;
			}
			BoardManager instance = Singleton<BoardManager>.Instance;
			ResourcesManager instance2 = Singleton<ResourcesManager>.Instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance2 == (Object)null))
			{
				int num = instance.CardsOnBoard.Count((PlayableCard c) => (Object)(object)c != (Object)null && !c.OpponentCard && !((Card)c).FaceDown && ((Card)c).Info.HasTrait((Trait)12));
				__result = num >= ((Card)__instance).Info.BloodCost && ((Card)__instance).Info.BonesCost <= instance2.PlayerBones && __instance.EnergyCost <= instance2.PlayerEnergy;
			}
		}
	}
	[HarmonyPatch(typeof(PlayableCard), "Die")]
	internal static class TerrainSacrificeRecorder
	{
		[HarmonyPrefix]
		private static void Prefix(PlayableCard __instance, bool wasSacrifice)
		{
			if (wasSacrifice && !__instance.OpponentCard && ((Card)__instance).Info.HasTrait((Trait)12))
			{
				StoneborneBehaviour.RecordSacrifice(((Object)((Card)__instance).Info).name);
			}
		}
	}
	public class WitnessBehaviour : SpecialCardBehaviour
	{
		public static SpecialTriggeredAbility ability;

		private const string CountKey = "SixHorns_Witnessed";

		private const int Needed = 6;

		public static void Init()
		{
			//IL_001a: 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)
			ability = SpecialTriggeredAbilityManager.Add("FTN", "Witness", typeof(WitnessBehaviour)).Id;
		}

		public override bool RespondsToOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && ((SpecialCardBehaviour)this).PlayableCard.OnBoard && (Object)(object)card != (Object)(object)((SpecialCardBehaviour)this).PlayableCard && !fromCombat && card.OpponentCard == ((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnOtherCardDie(PlayableCard card, CardSlot deathSlot, bool fromCombat, PlayableCard killer)
		{
			int count = ModdedSaveManager.RunState.GetValueAsInt("FTN", "SixHorns_Witnessed") + 1;
			ModdedSaveManager.RunState.SetValue("FTN", "SixHorns_Witnessed", (object)count);
			if (count < 6)
			{
				yield break;
			}
			CardInfo form = Util.GetCard(Util.Prop(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "WitnessOverride"));
			if (!((Object)(object)form == (Object)null))
			{
				ModdedSaveManager.RunState.SetValue("FTN", "SixHorns_Witnessed", (object)0);
				DeckInfo deck = SaveManager.SaveFile.CurrentDeck;
				CardInfo inDeck = ((IEnumerable<CardInfo>)((CardCollectionInfo)deck).Cards).FirstOrDefault((Func<CardInfo, bool>)((CardInfo c) => ((Object)c).name == ((Object)((Card)((SpecialCardBehaviour)this).PlayableCard).Info).name));
				if ((Object)(object)inDeck != (Object)null)
				{
					((CardCollectionInfo)deck).RemoveCard(inDeck);
					((CardCollectionInfo)deck).AddCard(CardLoader.GetCardByName(((Object)form).name));
				}
				Util.PlaySound(((Card)((SpecialCardBehaviour)this).PlayableCard).Info, "Witness.wav");
				yield return Singleton<TextDisplayer>.Instance.ShowUntilInput("The six horn have seen enough.", -2.5f, 0.5f, (Emotion)0, (LetterAnimation)0, (Speaker)0, (string[])null, true);
				yield return ((SpecialCardBehaviour)this).PlayableCard.TransformIntoCard(form, (Action)null, (Action)null);
			}
		}
	}
	public class MomentumBehaviour : VariableStatBehaviour
	{
		public static SpecialStatIcon icon;

		private const string Marker = "FTN_Momentum:";

		private int value;

		private int moved;

		private bool loaded;

		private CardSlot lastSlot;

		public override SpecialStatIcon IconType => icon;

		public static void Init()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			StatIconInfo val = StatIconManager.New("FTN", "Momentum", "The value represented with this sigil is equal to the number of spaces moved this run. The value will reset if no movement occurs in one turn.", typeof(MomentumBehaviour));
			val.appliesToAttack = true;
			val.appliesToHealth = false;
			AbilityExtensions.SetDefaultPart1Ability(val);
			string text = Path.Combine(Plugin.ModRoot, "Resources", "SpecialDamage", "Momentum.png");
			if (File.Exists(text))
			{
				AbilityExtensions.SetIcon(val, text, (FilterMode?)null);
			}
			icon = val.iconType;
		}

		public override void ManagedUpdate()
		{
			Load();
			CountMovement();
			((VariableStatBehaviour)this).ManagedUpdate();
		}

		public override int[] GetStatValues()
		{
			Load();
			return new int[2] { value, 0 };
		}

		public override bool RespondsToUpkeep(bool playerUpkeep)
		{
			return (Object)(object)((SpecialCardBehaviour)this).PlayableCard != (Object)null && playerUpkeep == !((SpecialCardBehaviour)this).PlayableCard.OpponentCard;
		}

		public override IEnumerator OnUpkeep(bool playerUpkeep)
		{
			if (moved == 0 && value != 0)
			{
				value = 0;
				Save();
			}
			moved = 0;
			yield break;
		}

		private CardModificationInfo FindMarker()
		{
			return ((Card)((SpecialCardBehaviour)this).PlayableCard).Info.Mods.Find((CardModificationInfo m) => m.singletonId != null && m.singletonId.StartsWith("FTN_Momentum:"));
		}

		private void Load()
		{
			if (!loaded && !((Object)(object)((SpecialCardBehaviour)this).PlayableCard == (Object)null) && !((Object)(object)((Card)((SpecialCardBehaviour)this).PlayableCard).Info == (Object)null))
			{
				loaded = true;
				CardModificationInfo val = FindMarker();
				if (val != null)
				{
					int.TryParse(val.singletonId.Substring("FTN_Momentum:".Length), out value);
				}
			}
		}

		private void Save()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			CardModificationInfo val = FindMarker();
			if (val == null)
			{
				val = new CardModificationInfo();
				((Card)((SpecialCardBehaviour)this).PlayableCard).Info.Mods.Add(val);
			}
			val.singletonId = "FTN_Momentum:" + value;
		}

		private void CountMovement()
		{
			if ((Object)(object)((SpecialCardBehaviour)this).PlayableCard == (Object)null || ((SpecialCardBehaviour)this).PlayableCard.Dead)
			{
				return;
			}
			CardSlot slot = ((SpecialCardBehaviour)this).PlayableCard.Slot;
			if (!((Object)(object)slot == (Object)null) && !((Object)(object)slot == (Object)(object)lastSlot))
			{
				if ((Object)(object)lastSlot != (Object)null)
				{
					int num = Mathf.Abs(slot.Index - lastSlot.Index);
					value += num;
					moved += num;
					Save();
				}
				lastSlot = slot;
			}
		}
	}
	internal static class Util
	{
		private static readonly Dictionary<string, Ability> abilityCache = new Dictionary<string, Ability>();

		internal static string Prop(CardInfo card, string key)
		{
			return ((Object)(object)card != (Object)null) ? CardExtensions.GetExtendedProperty(card, key) : null;
		}

		internal static List<CardInfo> CardsFromNames(string names)
		{
			if (string.IsNullOrEmpty(names))
			{
				return new List<CardInfo>();
			}
			List<string> wanted = (from n in names.Split(new char[1] { ',' })
				select n.Trim() into n
				where n.Length > 0
				select n).ToList();
			return CardManager.AllCardsCopy.FindAll((CardInfo c) => wanted.Contains(((Object)c).name));
		}

		internal static CardInfo GetCard(string name)
		{
			if (string.IsNullOrEmpty(name) || !CardManager.AllCardsCopy.Exists((CardInfo c) => ((Object)c).name == name))
			{
				Plugin.Log.LogWarning((object)("Card not found: " + name));
				return null;
			}
			return CardLoader.GetCardByName(name);
		}

		internal static bool TryFindAbility(string rulebookName, out Ability ability)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected I4, but got Unknown
			if (abilityCache.TryGetValue(rulebookName, out ability))
			{
				return true;
			}
			AbilityInfo val = ((IEnumerable<AbilityInfo>)AbilityManager.AllAbilityInfos).FirstOrDefault((Func<AbilityInfo, bool>)((AbilityInfo i) => i.rulebookName == rulebookName));
			if ((Object)(object)val == (Object)null)
			{
				ability = (Ability)0;
				return false;
			}
			ability = (Ability)(int)val.ability;
			abilityCache[rulebookName] = ability;
			return true;
		}

		internal static void PlaySound(CardInfo card, string key)
		{
			string text = Prop(card, key);
			if (!string.IsNullOrEmpty(text))
			{
				AudioController.Instance.PlaySound2D(text, (MixerGroup)0, 1f, 0f, (Pitch)null, (Repetition)null, (Randomization)null, (Distortion)null, false);
			}
		}
	}
}