Decompiled source of DevaClan v0.3.1

plugins/DevaClan/DevaClan.dll

Decompiled a day 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 BepInEx;
using BepInEx.Logging;
using Conductor.Extensions;
using Conductor.TrackedValues;
using Conductor.Triggers;
using Conductor.UI;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Configuration;
using SimpleInjector;
using TrainworksReloaded.Base.Extensions;
using TrainworksReloaded.Base.Localization;
using TrainworksReloaded.Core;
using TrainworksReloaded.Core.Extensions;
using TrainworksReloaded.Core.Interfaces;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DevaClan
{
	[HarmonyPatch(typeof(CardManager), "FireUnitTriggersForCardPlayed")]
	[HarmonyAfter(new string[] { "Conductor" })]
	internal static class AbilityEvents
	{
		private static IEnumerator Postfix(IEnumerator result, ICharacterManager characterManager, CardState playedCard, CharacterState characterThatActivatedAbility, int playedRoomIndex, AllGameManagers ___allGameManagers)
		{
			ICoreGameManagers g = ___allGameManagers.GetCoreManagers();
			while (result.MoveNext())
			{
				yield return result.Current;
			}
			if ((object)characterManager != g.GetMonsterManager())
			{
				yield break;
			}
			if (Plugin.Is(playedCard, "SixRealms"))
			{
				BattleMemory.Active.Discounts.Remove(playedCard);
			}
			if (!playedCard.IsAnyAbility() || ((Object)(object)characterThatActivatedAbility != (Object)null && (int)characterThatActivatedAbility.GetTeamType() != 2))
			{
				yield break;
			}
			Memory memory = BattleMemory.Active;
			foreach (CardState item in g.GetCardManager().GetHand(false))
			{
				if (Plugin.Is(item, "SixRealms"))
				{
					memory.Discounts.TryGetValue(item, out var value);
					memory.Discounts[item] = value + 1;
				}
			}
			g.GetCardManager().RefreshHandCards(false, false);
			if ((Object)(object)characterThatActivatedAbility != (Object)null)
			{
				memory.Abilities++;
				yield return SingingBowl.AfterAbility(playedCard, characterThatActivatedAbility, Plugin.Has(g, "SingingBowl"));
				if (Plugin.Has(g, "PrayerWheel") && memory.Abilities % 3 == 0)
				{
					g.GetCardManager().DrawCards(1, (CardState)null, (CardType)4, -1);
				}
				if (Plugin.Has(g, "InsightCircuit") && RandomManager.Range(0, 4, (RngId)(g.GetSaveManager().PreviewMode ? 13 : 6)) == 0)
				{
					characterThatActivatedAbility.RemoveStatusEffect("cooldown", 999, false);
				}
				yield break;
			}
			foreach (CharacterState item2 in Plugin.Floor(g.GetRoomManager().GetRoom(playedRoomIndex), (Type)2))
			{
				yield return g.GetCombatManager().QueueAndRunTrigger(item2, CharacterTriggers.Evoke, (CharacterState)null, true, true, (FireTriggersData)null, 1, (CharacterTriggerState)null);
			}
		}
	}
	[HarmonyPatch(typeof(CardState), "GetCost")]
	internal static class SixRealmsCost
	{
		private static void Postfix(CardState __instance, ref int __result)
		{
			if (Plugin.Is(__instance, "SixRealms") && BattleMemory.Active.Discounts.TryGetValue(__instance, out var value))
			{
				__result = Math.Max(0, __result - value);
			}
		}
	}
	public sealed class CardEffectImmediateAttack : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			yield return Effects.Attack(DevaEffectBase.Actor(p), g);
		}
	}
	public sealed class CardEffectDirectedAttack : DevaTargetEffect
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (DevaEffectBase.Alive(target) && (int)target.GetTeamType() == 1)
			{
				int currentRoomIndex = target.GetCurrentRoomIndex();
				CharacterState characterThatActivatedAbility = p.characterThatActivatedAbility;
				return currentRoomIndex == ((characterThatActivatedAbility != null) ? new int?(characterThatActivatedAbility.GetCurrentRoomIndex()) : ((int?)null));
			}
			return false;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				yield return Effects.Attack(DevaEffectBase.Actor(p), g, item);
			}
		}
	}
	public sealed class CardEffectFrontAllyAttack : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			yield return Effects.Attack(Plugin.Floor(DevaEffectBase.Room(p, g), (Type)2).FirstOrDefault(), g);
		}
	}
	public sealed class CardEffectIdatenRecall : DevaEffectBase
	{
		public override bool CanPlayWhenHandFull => false;

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			CharacterState self = DevaEffectBase.Actor(p);
			yield return Effects.Attack(self, g);
			if (g.GetSaveManager().PreviewMode || !DevaEffectBase.Alive(self) || self.HasStatusEffect("cardless"))
			{
				yield break;
			}
			CardManager cm = g.GetCardManager();
			CardState card = self.GetSpawnerCard();
			if (card != null && cm.GetBelowHandSize() && !cm.IsCardInStandByPile(card) && !cm.GetHand(false).Contains(card) && card.HasTrait<CardTraitEphemeral>() && cm.GetPurgedPile(false).Contains(card))
			{
				cm.GetPurgedPile(false).RemoveAll((CardState c) => c == card);
				cm.MoveToStandByPile(card, false, false, new RemoveFromStandByCondition((Func<CardPile>)(() => cm.CheckMonsterRemoveFromStandByCondition(self)), (OnReturnEnumerator)null), (DiscardCardParams)null, (DiscardEffect)0, true);
			}
			if (card != null && cm.IsCardInStandByPile(card) && !cm.GetHand(false).Contains(card))
			{
				yield return cm.ReturnUnitCardToHand(self, true, false, false);
			}
		}
	}
	public sealed class CardEffectVajraGlare : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			CharacterState self = DevaEffectBase.Actor(p);
			if (!DevaEffectBase.Alive(self))
			{
				yield break;
			}
			foreach (CharacterState item in Plugin.Floor(DevaEffectBase.Room(p, g), (Type)1))
			{
				yield return Effects.Damage(item, self.GetAttackDamage(), p, g);
			}
		}
	}
	public sealed class CardEffectFloorFocusAttack : DevaTargetEffect
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState target in DevaEffectBase.Targets(p))
			{
				foreach (CharacterState item in Plugin.Floor(target.GetCurrentRoom(false), (Type)2))
				{
					yield return Effects.Attack(item, g, target);
				}
			}
		}
	}
	public sealed class CardEffectSilkPull : DevaTargetEffect
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (DevaEffectBase.Alive(target) && (Object)(object)p.characterThatActivatedAbility != (Object)null && (Object)(object)target != (Object)(object)p.characterThatActivatedAbility && target.GetCurrentRoomIndex() != p.characterThatActivatedAbility.GetCurrentRoomIndex() && !target.IsOuterTrainBoss() && !target.HasStatusEffect("immobile"))
			{
				RoomState currentRoom = p.characterThatActivatedAbility.GetCurrentRoom(false);
				return ((currentRoom != null && currentRoom.GetRemainingSpawnPointCount(target.GetTeamType()) != 0) ? 1 : 0) > (false ? 1 : 0);
			}
			return false;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			CharacterState self = DevaEffectBase.Actor(p);
			foreach (CharacterState item in from t in DevaEffectBase.Targets(p)
				where ((CardEffectBase)this).TestEffectOnTarget(e, p, t, g)
				select t)
			{
				CardEffectParams val = new CardEffectParams
				{
					playedCard = p.playedCard,
					characterThatActivatedAbility = self
				};
				val.targets.Add(item);
				yield return CardEffectBump.Bump((CardEffectState)null, val, g, self.GetCurrentRoomIndex() - item.GetCurrentRoomIndex(), (SpawnPoint)null);
			}
		}
	}
	public sealed class CardEffectRetainFloorKarmergy : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			RoomState val = DevaEffectBase.Room(p, g);
			if ((Object)(object)val != (Object)null)
			{
				BattleMemory.Active.RetainKarmergyFloors.Add(val.GetRoomIndex());
			}
			yield break;
		}
	}
	public sealed class ConstructSummonResource : SimpleGlobalTrackedValueHandler
	{
		public override void UpdateStatsForNextTurn()
		{
		}

		public override void UpdateStatsForFirstTurn()
		{
			((AbstractTrackedValueHandler)this).Reset();
		}
	}
	internal static class BalanceRules
	{
		internal static int RetainedKarmergy(int stacks, bool friendly, int liberation, bool feast)
		{
			if (friendly)
			{
				if (!feast && liberation != 3)
				{
					if (liberation <= 0)
					{
						return 0;
					}
					return stacks / 2;
				}
				return stacks;
			}
			return 0;
		}

		internal static int ConstructAttackBonus(int summonCount)
		{
			return summonCount * 2;
		}

		internal static HashSet<int> ConsumeFeast()
		{
			HashSet<int> result = new HashSet<int>(BattleMemory.Active.RetainKarmergyFloors);
			BattleMemory.Active.RetainKarmergyFloors.Clear();
			return result;
		}

		internal static void AfterSummon(CharacterState unit, ICoreGameManagers g)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)unit == (Object)null) && (int)unit.GetTeamType() == 2 && Plugin.IsConstruct(unit) && Plugin.ConstructSummons != null)
			{
				g.GetCardStatistics().IncrementStat(unit.GetSpawnerCard(), Plugin.ConstructSummonStat, 1);
				if (unit.IsAlive && !unit.IsDestroyed && Plugin.Has(g, "BinaryPrayerBeads"))
				{
					unit.BuffDamage(ConstructAttackBonus(((SimpleGlobalTrackedValueHandler)Plugin.ConstructSummons).GetCurrentValue(g.GetSaveManager().PreviewMode)), (RelicState)null, false);
				}
			}
		}

		internal static IEnumerator AfterReset(CharacterState replacement, ICoreGameManagers g)
		{
			if ((Object)(object)replacement != (Object)null && replacement.IsAlive && !replacement.IsDestroyed && (int)replacement.GetTeamType() == 2 && Plugin.Has(g, "NirvanicWrath"))
			{
				yield return Effects.Attack(replacement, g);
			}
		}
	}
	internal sealed class Memory
	{
		public Dictionary<CardState, int> Karma = new Dictionary<CardState, int>();

		public Dictionary<CardState, int> Discounts = new Dictionary<CardState, int>();

		public HashSet<CardState> Dead = new HashSet<CardState>();

		public int Abilities;

		public HashSet<int> RetainKarmergyFloors = new HashSet<int>();

		public HashSet<int> Relentless = new HashSet<int>();

		public Dictionary<CardState, CardState> GiantOwners = new Dictionary<CardState, CardState>();

		public HashSet<CharacterState> Stasis = new HashSet<CharacterState>();

		public Dictionary<CharacterState, int> TurnSilence = new Dictionary<CharacterState, int>();

		public HashSet<CardState> TemporaryCards = new HashSet<CardState>();

		public HashSet<CharacterState> TemporaryUnits = new HashSet<CharacterState>();

		public Memory Clone()
		{
			return new Memory
			{
				Karma = new Dictionary<CardState, int>(Karma),
				Discounts = new Dictionary<CardState, int>(Discounts),
				Dead = new HashSet<CardState>(Dead),
				Abilities = Abilities,
				RetainKarmergyFloors = new HashSet<int>(RetainKarmergyFloors),
				Relentless = new HashSet<int>(Relentless),
				GiantOwners = new Dictionary<CardState, CardState>(GiantOwners),
				Stasis = new HashSet<CharacterState>(Stasis),
				TurnSilence = new Dictionary<CharacterState, int>(TurnSilence),
				TemporaryCards = new HashSet<CardState>(TemporaryCards),
				TemporaryUnits = new HashSet<CharacterState>(TemporaryUnits)
			};
		}
	}
	internal static class BattleMemory
	{
		private static Memory actual = new Memory();

		private static Memory preview = new Memory();

		private static bool isPreview;

		internal static Memory Active
		{
			get
			{
				if (!isPreview)
				{
					return actual;
				}
				return preview;
			}
		}

		internal static void Clear()
		{
			actual = new Memory();
			preview = new Memory();
			isPreview = false;
		}

		internal static void BeginPreview()
		{
			preview = actual.Clone();
			isPreview = true;
		}

		internal static void EndPreview()
		{
			preview = actual.Clone();
			isPreview = false;
		}

		internal static void Remember(CharacterState unit)
		{
			TemporaryMemory.Remember(unit);
			CardState val = ((unit != null) ? unit.GetSpawnerCard() : null);
			if (val != null && Plugin.KarmaId != null)
			{
				Active.Karma[val] = unit.GetStatusEffectStacks(Plugin.KarmaId);
			}
		}
	}
	internal static class ChampionStats
	{
		internal static int Extra(CardState card)
		{
			bool flag = Plugin.Is(card, "Mara");
			bool flag2 = Plugin.Is(card, "Nayuta");
			if (!flag && !flag2)
			{
				return 0;
			}
			string[] obj = ((!flag) ? new string[3] { "NayutaServer", "NayutaSwarm", "NayutaRecreate" } : new string[3] { "MaraCreator", "MaraLiberation", "MaraAsura" });
			int num = 0;
			int num2 = 0;
			string[] array = obj;
			foreach (string text in array)
			{
				for (int num3 = 3; num3 > 0; num3--)
				{
					if (Plugin.Upgrades.TryGetValue(text + num3, out var value) && card.HasUpgrade(value))
					{
						num += num3;
						num2 += (flag ? (20 * (num3 - 1)) : (new int[3] { 0, 5, 15 })[num3 - 1]);
						break;
					}
				}
			}
			if (num == 0)
			{
				return 0;
			}
			return (flag ? (20 * (Math.Min(3, num) - 1)) : (new int[3] { 0, 5, 15 })[Math.Min(3, num) - 1]) - num2;
		}
	}
	[HarmonyPatch(typeof(CardState), "GetTotalAttackDamage")]
	internal static class MixedAttack
	{
		private static void Postfix(CardState __instance, ref int __result)
		{
			__result += ChampionStats.Extra(__instance);
		}
	}
	[HarmonyPatch(typeof(CardState), "GetHealth")]
	internal static class MixedHealth
	{
		private static void Postfix(CardState __instance, ref float __result)
		{
			__result += ChampionStats.Extra(__instance);
		}
	}
	[HarmonyPatch(typeof(CharacterState), "Setup")]
	internal static class MixedSpawn
	{
		private static IEnumerator Postfix(IEnumerator result, CharacterState __instance)
		{
			while (result.MoveNext())
			{
				yield return result.Current;
			}
			int num = ChampionStats.Extra(__instance.GetSpawnerCard());
			if (num > 0)
			{
				__instance.BuffDamage(num, (RelicState)null, false);
				__instance.SetHealth(__instance.GetHP() + num, __instance.GetMaxHP() + num);
			}
		}
	}
	internal static class ChargeAbilities
	{
		internal static bool Affordable(int cooldown, int charge)
		{
			if (cooldown > 0)
			{
				return charge >= cooldown;
			}
			return false;
		}

		internal static bool CanPay(int cooldown, ICoreGameManagers g)
		{
			if (g != null && Plugin.Charge != null)
			{
				return Affordable(cooldown, ((SimpleGlobalTrackedValueHandler)Plugin.Charge).GetCurrentValue(g.GetSaveManager().PreviewMode));
			}
			return false;
		}

		internal static bool CanPayCurrent(int cooldown)
		{
			if (Plugin.Charge != null)
			{
				return Affordable(cooldown, ((SimpleGlobalTrackedValueHandler)Plugin.Charge).GetCurrentValue(false));
			}
			return false;
		}

		internal static TrainRoomAttachmentState FindRoomAbility(RoomState room, CardState ability, bool preview)
		{
			if ((Object)(object)room == (Object)null || ability == null)
			{
				return null;
			}
			return ((IEnumerable<TrainRoomAttachmentState>)(preview ? room.PreviewAttachments : room.Attachments)).FirstOrDefault((Func<TrainRoomAttachmentState, bool>)((TrainRoomAttachmentState a) => a.IsActive && (int)a.TrainSide == 2 && a.UpgradeStates.Any<(CardUpgradeState, CardUpgradeData)>(delegate((CardUpgradeState, CardUpgradeData) u)
			{
				CardData roomAbilityUpgrade = u.Item2.GetRoomAbilityUpgrade();
				return ((roomAbilityUpgrade != null) ? ((GameData)roomAbilityUpgrade).GetID() : null) == ability.GetCardDataID();
			})));
		}
	}
	[HarmonyPatch(typeof(CharacterState), "GetUnitAbilityAvailability")]
	internal static class ChargeAvailability
	{
		private static void Postfix(CharacterState __instance, CombatManager combatManager, AllGameManagers ___allGameManagers, ref UnitAbilityAvailability __result)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			if ((int)__result == 1 && !((Object)(object)combatManager == (Object)null) && !combatManager.IsPlacementPhase)
			{
				ICoreGameManagers coreManagers = ___allGameManagers.GetCoreManagers();
				if ((int)__instance.GetTeamType() == 2 && ChargeAbilities.CanPay(__instance.GetStatusEffectStacks("cooldown"), coreManagers) && (coreManagers.GetCardManager().GetBelowHandSize() || __instance.GetUnitAbilityCardState().CanBePlayedWhenHandFull()))
				{
					__result = (UnitAbilityAvailability)3;
				}
			}
		}
	}
	[HarmonyPatch(typeof(RoomAbilitySelectionBehaviour), "GetCurrentAbilityAvailability")]
	internal static class RoomChargeAvailability
	{
		private static void Prefix(TrainRoomAttachmentState ___selectedRoomAttachmentState, ref UnitAbilityAvailability __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			if (___selectedRoomAttachmentState != null && ___selectedRoomAttachmentState.IsActive && (int)___selectedRoomAttachmentState.TrainSide == 2 && ___selectedRoomAttachmentState.CurrentAbilityCooldown > 0 && ChargeAbilities.CanPayCurrent(___selectedRoomAttachmentState.CurrentAbilityCooldown))
			{
				__result = (UnitAbilityAvailability)3;
			}
		}

		private static void Postfix(TrainRoomAttachmentState ___selectedRoomAttachmentState, ref UnitAbilityAvailability __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if ((int)__result == 1 && ___selectedRoomAttachmentState != null && (int)___selectedRoomAttachmentState.TrainSide == 2 && ___selectedRoomAttachmentState.IsActive)
			{
				AllGameManagers instance = AllGameManagers.Instance;
				ICoreGameManagers g = ((instance != null) ? instance.GetCoreManagers() : null);
				if (ChargeAbilities.CanPay(___selectedRoomAttachmentState.CurrentAbilityCooldown, g))
				{
					__result = (UnitAbilityAvailability)3;
				}
			}
		}
	}
	[HarmonyPatch(typeof(UnitAbilityUIState), "Create", new Type[]
	{
		typeof(CharacterState),
		typeof(CombatManager)
	})]
	internal static class ChargeAbilityDisplayState
	{
		private static void Postfix(CharacterState characterState, ref UnitAbilityUIState __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((int)__result.abilityAvailability == 3 && (Object)(object)characterState != (Object)null)
			{
				int statusEffectStacks = characterState.GetStatusEffectStacks("cooldown");
				if (statusEffectStacks > 0)
				{
					__result = UnitAbilityUIState.Create(__result.abilityAvailability, true, statusEffectStacks, false);
				}
			}
		}
	}
	[HarmonyPatch(typeof(UnitAbilityUI), "Set")]
	internal static class ChargeAbilityVisuals
	{
		private static readonly Dictionary<Graphic, Color> OriginalColors = new Dictionary<Graphic, Color>();

		private static readonly Color ChargeReadyTint = new Color(0.25f, 0.85f, 1f, 1f);

		internal static bool UsesChargeVisual(UnitAbilityUIState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)state.abilityAvailability == 3 && state.hasCooldown && state.cooldown > 0)
			{
				return !state.isSilenced;
			}
			return false;
		}

		private static void Prefix(ref UnitAbilityUIState state, out bool __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			__state = UsesChargeVisual(state);
			if (__state)
			{
				state = UnitAbilityUIState.Create((UnitAbilityAvailability)1, true, state.cooldown, false);
			}
		}

		private static void Postfix(Transform ___unitAbilityInactive, bool __state)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)___unitAbilityInactive == (Object)null)
			{
				return;
			}
			Graphic[] array = OriginalColors.Keys.Where((Graphic g) => (Object)(object)g == (Object)null).ToArray();
			foreach (Graphic key in array)
			{
				OriginalColors.Remove(key);
			}
			Image[] componentsInChildren = ((Component)___unitAbilityInactive).GetComponentsInChildren<Image>(true);
			foreach (Image val in componentsInChildren)
			{
				if (!OriginalColors.TryGetValue((Graphic)(object)val, out var value))
				{
					OriginalColors.Add((Graphic)(object)val, value = ((Graphic)val).color);
				}
				((Graphic)val).color = (__state ? Color.Lerp(value, ChargeReadyTint, 0.62f) : value);
			}
		}
	}
	[HarmonyPatch(typeof(TrainRoomAttachmentDisplay), "RefreshDisplay")]
	internal static class RoomChargeVisuals
	{
		private static void Postfix(TrainRoomAttachmentDisplay __instance, Image ___previewIcon)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			if (SaveManager.IsInUndoModeStatic || ((Object)(object)___previewIcon != (Object)null && ((Component)___previewIcon).gameObject.activeSelf))
			{
				return;
			}
			TrainRoomAttachmentState attachmentState = __instance.GetAttachmentState();
			AllGameManagers instance = AllGameManagers.Instance;
			ICoreGameManagers val = ((instance != null) ? instance.GetCoreManagers() : null);
			if (attachmentState != null && attachmentState.HasRoomAbility && attachmentState.IsActive && (int)attachmentState.TrainSide == 2 && val != null && !val.GetSaveManager().PreviewMode && !val.GetCombatManager().IsPlacementPhase && ChargeAbilities.CanPay(attachmentState.CurrentAbilityCooldown, val))
			{
				UnitAbilityUI abilityUi = __instance.AbilityUi;
				if (abilityUi != null)
				{
					abilityUi.Set(UnitAbilityUIState.Create((UnitAbilityAvailability)3, true, attachmentState.CurrentAbilityCooldown, false));
				}
			}
		}
	}
	[HarmonyPatch(typeof(CardManager), "PlayAnyCard")]
	internal static class ChargePayment
	{
		private static bool Prefix(CardState cardState, CharacterState characterThatActivatedAbility, RoomState roomThatActivatedAbility, AllGameManagers ___allGameManagers, ref bool __result, out int __state, ref SelectionError lastFailedEffectError)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			ICoreGameManagers coreManagers = ___allGameManagers.GetCoreManagers();
			int num;
			if (!((Object)(object)characterThatActivatedAbility != (Object)null) || (int)characterThatActivatedAbility.GetTeamType() != 2)
			{
				TrainRoomAttachmentState obj = ChargeAbilities.FindRoomAbility(roomThatActivatedAbility, cardState, coreManagers.GetSaveManager().PreviewMode);
				num = ((obj != null) ? obj.CurrentAbilityCooldown : 0);
			}
			else
			{
				num = characterThatActivatedAbility.GetStatusEffectStacks("cooldown");
			}
			__state = num;
			if (__state <= 0 || ChargeAbilities.CanPay(__state, coreManagers))
			{
				return true;
			}
			lastFailedEffectError = (SelectionError)14;
			__result = false;
			return false;
		}

		private static void Postfix(bool __result, CardState cardState, int __state, AllGameManagers ___allGameManagers)
		{
			if (__result && __state > 0)
			{
				Plugin.Gain(___allGameManagers.GetCoreManagers(), -__state, cardState);
			}
		}
	}
	public sealed class CardEffectGainCharge : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			Plugin.Gain(g, e.GetParamInt(), p.playedCard);
			yield break;
		}
	}
	public sealed class CardEffectDevaSpike : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			int lastPlayedCost = p.playedCard.GetLastPlayedCost();
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				AddStatus(item, Plugin.KarmaId, DevaEffectBase.StatusCount(e, 2) * lastPlayedCost, e, p);
			}
			Plugin.Gain(g, lastPlayedCost, p.playedCard);
			yield break;
		}
	}
	public sealed class ChargeHud : ClassMechanicHud
	{
		public override void Refresh(SaveManager saveManager, PlayerManager playerManager, CardManager cardManager)
		{
			if (Plugin.Charge != null)
			{
				((HudCountUI)this).ShowCount(((SimpleGlobalTrackedValueHandler)Plugin.Charge).GetCurrentValue(false));
			}
		}

		protected override void HandleValueChanged(TrackedValueChangedParams changedParams)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			if ((int)changedParams.entryDuration == 0)
			{
				if (SaveManager.IsInUndoModeStatic)
				{
					((HudCountUI)this).ShowCount(changedParams.value);
				}
				else
				{
					((ClassMechanicHud)this).HandleValueChanged(changedParams);
				}
			}
		}
	}
	public sealed class ChargeResource : SimpleGlobalTrackedValueHandler
	{
		public override void UpdateStatsForNextTurn()
		{
		}

		public override void UpdateStatsForFirstTurn()
		{
			((AbstractTrackedValueHandler)this).Reset();
		}

		public override void Reset()
		{
			((SimpleGlobalTrackedValueHandler)this).Reset();
			BattleMemory.Clear();
		}

		public override void OnCombatPreviewEnabled()
		{
			((SimpleGlobalTrackedValueHandler)this).OnCombatPreviewEnabled();
			BattleMemory.BeginPreview();
		}

		public override void OnCombatPreviewDisabled()
		{
			((SimpleGlobalTrackedValueHandler)this).OnCombatPreviewDisabled();
			BattleMemory.EndPreview();
		}
	}
	public sealed class CardEffectCreateConstruct : DevaEffectBase
	{
		public override bool CanPlayWhenHandFull => false;

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			Effects.CreateConstruct(g, ephemeral: false);
			yield break;
		}
	}
	public sealed class CardEffectFormatConstruct : DevaTargetEffect
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (DevaEffectBase.Alive(target) && (int)target.GetTeamType() == 2)
			{
				return Plugin.IsConstruct(target);
			}
			return false;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p).Where(Plugin.IsConstruct))
			{
				yield return item.Sacrifice(p.playedCard, false, false, (CharacterState)null);
				Plugin.Gain(g, e.GetParamInt(), p.playedCard);
				if (!g.GetSaveManager().PreviewMode)
				{
					g.GetCardManager().DrawCards(1, p.playedCard, (CardType)4, -1);
				}
			}
		}
	}
	public sealed class CardEffectPerfectCreation : DevaEffectBase
	{
		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return DevaEffectBase.CanSpawn(p, g);
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			yield return Effects.Spawn("Perfect" + e.GetParamInt(), DevaEffectBase.Room(p, g), p, g, temporary: true, DevaEffectBase.Actor(p));
		}

		public override void GetTooltipsStatusList(CardEffectState e, ref List<string> ids)
		{
			base.GetTooltipsStatusList(e, ref ids);
			if (!ids.Contains(Effects.TemporaryId))
			{
				ids.Add(Effects.TemporaryId);
			}
		}
	}
	public sealed class CardEffectGiantCreation : DevaEffectBase
	{
		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return DevaEffectBase.CanSpawn(p, g);
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			yield return Effects.Spawn("Giant", DevaEffectBase.Room(p, g), p, g, temporary: false, DevaEffectBase.Actor(p));
		}
	}
	public sealed class CardEffectFirewallCreation : DevaEffectBase
	{
		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return DevaEffectBase.CanSpawn(p, g);
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			yield return Effects.Spawn("Firewall", DevaEffectBase.Room(p, g), p, g, temporary: true);
		}

		public override void GetTooltipsStatusList(CardEffectState e, ref List<string> ids)
		{
			base.GetTooltipsStatusList(e, ref ids);
			if (!ids.Contains(Effects.TemporaryId))
			{
				ids.Add(Effects.TemporaryId);
			}
		}
	}
	public sealed class CardEffectHologram : DevaTargetEffect
	{
		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			if (DevaEffectBase.CanSpawn(p, g))
			{
				return base.TestEffect(e, p, g);
			}
			return false;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				CharacterState clone = null;
				yield return g.GetMonsterManager().CloneMonsterState(item, item.GetCurrentRoomIndex(), (Action<CharacterState>)delegate(CharacterState c)
				{
					clone = c;
				}, g, (SpawnMode)0, (SpawnPoint)null, (Action<CharacterState>)null, false, (CharacterData)null, (List<string>)null, (AddStatusEffectParams)null, false, (Action<CharacterState>)null, p.playedCard);
				if (DevaEffectBase.Alive(clone))
				{
					TemporaryMemory.Mark(clone);
				}
			}
		}

		public override void GetTooltipsStatusList(CardEffectState e, ref List<string> ids)
		{
			base.GetTooltipsStatusList(e, ref ids);
			if (!ids.Contains(Effects.TemporaryId))
			{
				ids.Add(Effects.TemporaryId);
			}
		}
	}
	internal static class ContentIds
	{
		internal static readonly string[] Cards = new string[66]
		{
			"Mantra", "Activate", "NayutaConstruct", "AsuraSlash", "AsuraSwordsman", "GuardConstruct", "Chant", "ChantTechnician", "SilkPull", "MechSpider",
			"ResonanceConstruct", "Rite", "RitualTechnician", "IdatenSpeed", "Idaten", "VajraGlare", "Vajra", "SirenSong", "Siren", "ChargeShot",
			"ChargeGunner", "Convert", "EmberConverter", "Focus", "AttackConstruct", "Sinner", "Perfect1", "Perfect2", "Perfect3", "Giant",
			"Firewall", "Mara", "Nayuta", "PerfectCreation1", "PerfectCreation2", "PerfectCreation3", "Improve1", "Improve2", "Improve3", "Format",
			"Creation", "Restart", "Nectar", "Isolation", "Exorcise", "Liberation", "Asceticism", "Nirvana", "Protect", "Samadhi",
			"Hologram", "Feast", "Anoint", "DevaSpike", "BookOfRebirth", "HeavenlyWrath", "Purify", "SixRealms", "AsuraArena", "MeditationChamber",
			"CollectiveRites", "AccelerationMatrix", "ChargedSpear", "SoulBackup", "AsuraDrive", "AsuraSecret"
		};

		internal static readonly string[] Units = new string[21]
		{
			"NayutaConstruct", "AsuraSwordsman", "GuardConstruct", "ChantTechnician", "MechSpider", "ResonanceConstruct", "RitualTechnician", "Idaten", "Vajra", "Siren",
			"ChargeGunner", "EmberConverter", "AttackConstruct", "Sinner", "Perfect1", "Perfect2", "Perfect3", "Giant", "Firewall", "Mara",
			"Nayuta"
		};

		internal static readonly string[] Upgrades = new string[30]
		{
			"EphemeralUpgrade", "StatGrowth", "RebirthFree", "GiantGrowth1", "GiantGrowth2", "GiantGrowth3", "MaraCreator1", "MaraCreator2", "MaraCreator3", "MaraLiberation1",
			"MaraLiberation2", "MaraLiberation3", "MaraAsura1", "MaraAsura2", "MaraAsura3", "NayutaServer1", "NayutaServer2", "NayutaServer3", "NayutaSwarm1", "NayutaSwarm2",
			"NayutaSwarm3", "NayutaRecreate1", "NayutaRecreate2", "NayutaRecreate3", "AsuraArenaUpgrade", "MeditationChamberUpgrade", "AccelerationMatrixUpgrade", "ChargedSpearUpgrade", "SoulBackupUpgrade", "AsuraDriveUpgrade"
		};

		internal static readonly string[] Relics = new string[11]
		{
			"ConstructBlueprint", "KarmicIncense", "ChargeRecycler", "ReserveEnergy", "SingingBowl", "PrayerWheel", "PrajnaShield", "NirvanicWrath", "BinaryPrayerBeads", "InsightCircuit",
			"AsuraMark"
		};

		internal static readonly string[] Triggers = new string[21]
		{
			"GuardRevenge", "ResonanceEvoke", "SinnerSummon", "MaraLiberationEvoke1", "MaraLiberationEvoke2", "MaraLiberationEvoke3", "MaraAsuraSlay1", "MaraAsuraSlay2", "MaraAsuraSlay3", "NayutaServerEvoke1",
			"NayutaServerEvoke2", "NayutaServerEvoke3", "NayutaSwarmEvoke1", "NayutaSwarmEvoke2", "NayutaSwarmEvoke3", "NayutaRecreateSummon1", "NayutaRecreateSummon2", "NayutaRecreateSummon3", "SpearEvoke", "SinnerReset",
			"SoulBackupReset"
		};

		internal static readonly string[] RandomConstructs = new string[6] { "GuardConstruct", "ResonanceConstruct", "Idaten", "Vajra", "EmberConverter", "AttackConstruct" };
	}
	[HarmonyPatch(typeof(CommonSelectionBehavior), "PrunePossibleTargets")]
	internal static class ConversionTargetingScope
	{
		[ThreadStatic]
		internal static int Depth;

		private static void Prefix(CardState thisCard, out bool __state)
		{
			__state = Plugin.Is(thisCard, "Convert");
			if (__state)
			{
				Depth++;
			}
		}

		private static Exception Finalizer(Exception __exception, bool __state)
		{
			if (__state)
			{
				Depth--;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(GameEffectHelper), "TestEffect")]
	internal static class ConversionTargetingTest
	{
		private static void Prefix(CardEffectState effectState, CardEffectParams cardEffectParams, ref bool previewMode)
		{
			if (ConversionTargetingScope.Depth > 0 && Plugin.Is(cardEffectParams.playedCard, "Convert") && effectState.GetCardEffect() is CardEffectGainEnergy)
			{
				previewMode = false;
			}
		}
	}
	internal static class Effects
	{
		internal static string TemporaryId => "sanson.DevaClan".ToLowerInvariant() + "_temporary";

		internal static void CreateConstruct(ICoreGameManagers g, bool ephemeral)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (!g.GetSaveManager().PreviewMode)
			{
				string[] randomConstructs = ContentIds.RandomConstructs;
				CardData val = Plugin.Cards[randomConstructs[RandomManager.Range(0, randomConstructs.Length, (RngId)6)]];
				AddCardUpgradingInfo val2 = new AddCardUpgradingInfo
				{
					tempCardUpgrade = true
				};
				if (ephemeral)
				{
					val2.upgradeDatas.Add(Plugin.Upgrades["EphemeralUpgrade"]);
				}
				g.GetCardManager().AddNewCardWithSpecialPlacement(val, (CardPile)3, ephemeral, false, 0, 1, val2);
			}
		}

		internal static IEnumerator Attack(CharacterState c, ICoreGameManagers g, CharacterState enemy = null)
		{
			if ((Object)(object)c == (Object)null || !c.IsAlive || c.IsDestroyed || ((Object)(object)enemy != (Object)null && (!enemy.IsAlive || enemy.IsDestroyed)))
			{
				yield break;
			}
			yield return g.GetCombatManager().RunUnitTurn(c, (ICharacterManager)(object)g.GetMonsterManager(), (ICharacterManager)(object)g.GetHeroManager(), c.GetCurrentRoomIndex(), false, ((Object)(object)enemy == (Object)null) ? null : new List<CharacterState> { enemy }, true, (Action<int>)null, false);
			if (!g.GetSaveManager().PreviewMode && (Object)(object)c != (Object)null && !c.IsDestroyed)
			{
				AttackInfo val = new AttackInfo();
				RoomState currentRoom = c.GetCurrentRoom(false);
				if (currentRoom != null)
				{
					currentRoom.AddCharactersToList(val.othersInRoom, (Type)3, false, true);
				}
				yield return g.GetCombatManager().DoForegroundMoveAnimations(val);
			}
		}

		internal static IEnumerator Damage(CharacterState c, int n, CardEffectParams p, ICoreGameManagers g)
		{
			if (!((Object)(object)c == (Object)null) && c.IsAlive && !c.IsDestroyed)
			{
				yield return g.GetCombatManager().ApplyDamageToTarget(n, c, new ApplyDamageToTargetParameters
				{
					playedCard = p.playedCard,
					selfTarget = p.selfTarget,
					finalEffectInSequence = true
				});
			}
		}

		internal static IEnumerator Grow(CharacterState c, int attack, int health, ICoreGameManagers g, bool permanent)
		{
			CardUpgradeState up = new CardUpgradeState();
			up.Setup(Plugin.Upgrades["StatGrowth"], false, false);
			up.SetSerializeScalingValues(true);
			up.SetAttackDamage(attack);
			up.SetAdditionalHP(health);
			yield return c.ApplyCardUpgrade(up, false, "", true, false, (CardState)null, (Action<UpgradeApplicationResult>)null, (TrainRoomAttachmentState)null, false);
			CardState spawnerCard = c.GetSpawnerCard();
			if (permanent && spawnerCard != null && !g.GetSaveManager().PreviewMode)
			{
				spawnerCard.GetCardStateModifiers().AddUpgrade(up, (CardStateModifiers)null);
			}
		}

		internal static void Standby(CardState card, CharacterState c, ICoreGameManagers g)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (card != null && !c.HasStatusEffect("cardless") && !g.GetSaveManager().PreviewMode)
			{
				CardManager cm = g.GetCardManager();
				cm.RestoreExhaustedOrEatenCard(card, true);
				RemoveFromStandByCondition val = new RemoveFromStandByCondition((Func<CardPile>)(() => cm.CheckMonsterRemoveFromStandByCondition(c)), (OnReturnEnumerator)null);
				if (cm.IsCardInStandByPile(card))
				{
					cm.ChangeStandbyCondition(card, val);
				}
				else
				{
					cm.MoveToStandByPile(card, false, false, val, (DiscardCardParams)null, (DiscardEffect)0, false);
				}
			}
		}

		internal static IEnumerator Reset(CharacterState c, CardEffectParams p, ICoreGameManagers g, Action<CharacterState> done = null)
		{
			if ((Object)(object)c == (Object)null || !c.IsAlive || c.IsDestroyed || (int)c.GetTeamType() != 2)
			{
				yield break;
			}
			TemporaryMemory.Remember(c);
			bool temporary = TemporaryMemory.Contains(c);
			RoomState room = c.GetCurrentRoom(false);
			int index = c.GetSpawnPoint(false).GetIndexInRoom();
			CharacterData data = c.GetSourceCharacterData();
			CardState card = c.GetSpawnerCard();
			int karma = c.GetStatusEffectStacks(Plugin.KarmaId);
			ResetContext reset = new ResetContext(c, karma);
			ResetLifecycle.Begin(reset);
			try
			{
				yield return g.GetCombatManager().QueueAndRunTrigger(c, Plugin.ResetTrigger, (CharacterState)null, true, true, (FireTriggersData)null, 1, (CharacterTriggerState)null);
				karma = reset.Karma;
				bool construct = Plugin.IsConstruct(c);
				CardState backup = reset.Equipment;
				KeyValuePair<string, int>[] saved = reset.PositiveStatuses;
				c.RemoveStatusEffect("undying", -1, false);
				yield return c.Sacrifice(p.playedCard, false, false, (CharacterState)null);
				if (card != null)
				{
					BattleMemory.Active.Karma[card] = karma;
				}
				CharacterState replacement = null;
				ResetLifecycle.BeginReplacement();
				yield return g.GetMonsterManager().CreateMonsterState(data, card, room.GetRoomIndex(), (Action<CharacterState>)delegate(CharacterState n)
				{
					replacement = n;
				}, (SpawnMode)3, room.GetMonsterPoint(Math.Min(index, g.GetSaveManager().GetNumSpawnPointsPerFloor((Type)2) - 1)), (Action<CharacterState>)null, false, (CharacterData)null, (List<string>)null, (AddStatusEffectParams)null, false, (Action<CharacterState>)null, true, (CardState)null);
				if ((Object)(object)replacement == (Object)null)
				{
					yield break;
				}
				if (temporary)
				{
					TemporaryMemory.Mark(replacement);
				}
				Standby(card, replacement, g);
				if (card == null && karma > 0)
				{
					replacement.AddStatusEffect(Plugin.KarmaId, karma, (CharacterState)null, false, false);
				}
				if (backup != null)
				{
					yield return replacement.AddEquipment(backup, g, false);
					if (!g.GetSaveManager().PreviewMode)
					{
						CardManager cardManager = g.GetCardManager();
						cardManager.RestoreExhaustedOrEatenCard(backup, true);
						RemoveFromStandByCondition val = new RemoveFromStandByCondition((Func<CardPile>)(() => (replacement.IsAlive && !replacement.IsDestroyed && replacement.GetEquipment().Contains(backup)) ? ((CardPile)4) : ((CardPile)1)), (OnReturnEnumerator)null);
						if (cardManager.IsCardInStandByPile(backup))
						{
							cardManager.ChangeStandbyCondition(backup, val);
						}
						else
						{
							cardManager.MoveToStandByPile(backup, false, false, val, (DiscardCardParams)null, (DiscardEffect)0, false);
						}
					}
					KeyValuePair<string, int>[] array = saved;
					for (int num = 0; num < array.Length; num++)
					{
						KeyValuePair<string, int> keyValuePair = array[num];
						int num2 = keyValuePair.Value - replacement.GetStatusEffectStacks(keyValuePair.Key);
						if (num2 > 0)
						{
							replacement.AddStatusEffect(keyValuePair.Key, num2, (CharacterState)null, false, false);
						}
					}
				}
				if (construct && Plugin.Has(g, "PrajnaShield"))
				{
					replacement.AddStatusEffect("damage shield", 1, (CharacterState)null, true, false);
				}
				done?.Invoke(replacement);
				yield return BalanceRules.AfterReset(replacement, g);
			}
			finally
			{
				ResetLifecycle.End(c);
			}
		}

		internal static IEnumerator Spawn(string id, RoomState room, CardEffectParams p, ICoreGameManagers g, bool temporary, CharacterState owner = null)
		{
			if ((Object)(object)room == (Object)null || room.GetRemainingSpawnPointCount((Type)2) <= 0)
			{
				yield break;
			}
			CardState card = new CardState();
			card.Setup(Plugin.Cards[id], g.GetSaveManager(), true, false);
			if (id == "Giant" && (Object)(object)owner != (Object)null)
			{
				CardState spawnerCard = owner.GetSpawnerCard();
				foreach (CardUpgradeState item in ((spawnerCard != null) ? spawnerCard.GetCardStateModifiers().GetCardUpgrades() : null) ?? new List<CardUpgradeState>())
				{
					for (int i = 1; i <= 3; i++)
					{
						if (item.GetCardUpgradeDataId() == ((GameData)Plugin.Upgrades["GiantGrowth" + i]).GetID())
						{
							CardUpgradeState val = new CardUpgradeState();
							val.Setup(Plugin.Upgrades["StatGrowth"], false, false);
							val.SetSerializeScalingValues(true);
							val.SetAttackDamage((i != 3) ? 1 : 2);
							val.SetAdditionalHP((i != 1) ? 1 : 0);
							card.GetCardStateModifiers().AddUpgrade(val, (CardStateModifiers)null);
						}
					}
				}
				BattleMemory.Active.GiantOwners[card] = spawnerCard;
			}
			CharacterState spawned = null;
			SpawnPoint val2 = (((id.StartsWith("Perfect", StringComparison.Ordinal) || id == "Giant") && (Object)(object)owner != (Object)null) ? owner.GetSpawnPoint(false) : ((id == "Firewall") ? room.GetMonsterPoint(0) : null));
			yield return g.GetMonsterManager().CreateMonsterState(Plugin.Units[id], card, room.GetRoomIndex(), (Action<CharacterState>)delegate(CharacterState c)
			{
				spawned = c;
			}, (SpawnMode)((val2 != null) ? 3 : 0), val2, (Action<CharacterState>)null, false, (CharacterData)null, (List<string>)null, (AddStatusEffectParams)null, false, (Action<CharacterState>)delegate(CharacterState c)
			{
				if (temporary)
				{
					TemporaryMemory.Mark(c);
				}
			}, true, (CardState)null);
			if ((Object)(object)spawned != (Object)null)
			{
				Standby(card, spawned, g);
			}
		}
	}
	public sealed class StatusEffectTemporary : StatusEffectState
	{
		public override void OnStacksAdded(CharacterState c, int n, AddStatusEffectParams p, ICoreGameManagers g)
		{
			if (n > 0)
			{
				TemporaryMemory.Remember(c, force: true);
			}
		}
	}
	public abstract class DevaEffectBase : CardEffectBase
	{
		public override PropDescriptions CreateEditorInspectorDescriptions()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			return new PropDescriptions();
		}

		protected static bool Alive(CharacterState c)
		{
			if ((Object)(object)c != (Object)null && c.IsAlive)
			{
				return !c.IsDestroyed;
			}
			return false;
		}

		protected static CharacterState Actor(CardEffectParams p)
		{
			return p.characterThatActivatedAbility ?? p.selfTarget;
		}

		protected static IEnumerable<CharacterState> Targets(CardEffectParams p)
		{
			return p.targets.Where(Alive).ToArray();
		}

		protected static RoomState Room(CardEffectParams p, ICoreGameManagers g)
		{
			CharacterState obj = Actor(p);
			return ((obj != null) ? obj.GetCurrentRoom(false) : null) ?? p.GetSelectedRoom(g.GetRoomManager());
		}

		protected static bool CanSpawn(CardEffectParams p, ICoreGameManagers g)
		{
			RoomState val = Room(p, g);
			if ((Object)(object)val != (Object)null && !val.GetIsPyreRoom())
			{
				return val.GetRemainingSpawnPointCount((Type)2) > 0;
			}
			return false;
		}

		protected static int StatusCount(CardEffectState e, int fallback, int index = 0)
		{
			StatusEffectStackData[] paramStatusEffectStackData = e.GetParamStatusEffectStackData();
			if (paramStatusEffectStackData == null || paramStatusEffectStackData.Length <= index)
			{
				return fallback;
			}
			return paramStatusEffectStackData[index].count;
		}

		protected static string StatusId(CardEffectState e, string fallback, int index = 0)
		{
			StatusEffectStackData[] paramStatusEffectStackData = e.GetParamStatusEffectStackData();
			if (paramStatusEffectStackData == null || paramStatusEffectStackData.Length <= index || string.IsNullOrEmpty(paramStatusEffectStackData[index].statusId))
			{
				return fallback;
			}
			return paramStatusEffectStackData[index].statusId;
		}

		protected void AddStatus(CharacterState target, string id, int count, CardEffectState e, CardEffectParams p)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0034: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if (Alive(target) && count != 0)
			{
				AddStatusEffectParams val = new AddStatusEffectParams
				{
					sourceCardState = p.playedCard,
					sourceRelicState = p.sourceRelic,
					sourceIsHero = ((int)e.GetSourceTeamType() == 1),
					fromEffectType = ((object)this).GetType()
				};
				target.AddStatusEffect(id, count, val, Actor(p), true, p.isFromHiddenTrigger, true, false, false);
			}
		}

		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			return Alive(target);
		}

		public override void GetTooltipsStatusList(CardEffectState e, ref List<string> ids)
		{
			StatusEffectStackData[] paramStatusEffectStackData = e.GetParamStatusEffectStackData();
			if (paramStatusEffectStackData == null)
			{
				return;
			}
			StatusEffectStackData[] array = paramStatusEffectStackData;
			foreach (StatusEffectStackData val in array)
			{
				if (!string.IsNullOrEmpty(val.statusId) && !ids.Contains(val.statusId))
				{
					ids.Add(val.statusId);
				}
			}
		}
	}
	public abstract class DevaTargetEffect : DevaEffectBase
	{
		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return p.targets.Any((CharacterState t) => ((CardEffectBase)this).TestEffectOnTarget(e, p, t, g));
		}
	}
	public sealed class CardEffectOtherAllyStatus : CardEffectAddStatusEffect
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if ((Object)(object)target != (Object)null && target.IsAlive && !target.IsDestroyed && (int)target.GetTeamType() == 2 && (Object)(object)p.characterThatActivatedAbility != (Object)null && (Object)(object)target != (Object)(object)p.characterThatActivatedAbility)
			{
				return target.GetCurrentRoomIndex() == p.characterThatActivatedAbility.GetCurrentRoomIndex();
			}
			return false;
		}

		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return p.targets.Any((CharacterState t) => ((CardEffectBase)this).TestEffectOnTarget(e, p, t, g));
		}
	}
	public sealed class StatusEffectKarmergy : StatusEffectState
	{
		private int AttackPerStack(ICoreGameManagers g)
		{
			return 10 + (Plugin.Has(g, "KarmicIncense") ? 5 : 0);
		}

		public override void OnStacksAdded(CharacterState c, int n, AddStatusEffectParams p, ICoreGameManagers g)
		{
			c.BuffDamage(n * AttackPerStack(g), (RelicState)null, true);
			c.SetHealth(c.GetHP() + n * 10, c.GetMaxHP() + n * 10);
		}

		public override void OnStacksRemoved(CharacterState c, int n, ICoreGameManagers g)
		{
			c.DebuffDamage(n * AttackPerStack(g), (RelicState)null, true);
			int num = Math.Max(1, c.GetMaxHP() - n * 10);
			c.SetHealth(Math.Min(num, Math.Max(c.IsAlive ? 1 : 0, c.GetHP() - n * 10)), num);
		}

		public override int GetEffectMagnitude(int stacks = 1)
		{
			return stacks * 10;
		}
	}
	public sealed class RelicEffectDevaMarker : RelicEffectBase
	{
		public override PropDescriptions CreateEditorInspectorDescriptions()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			return new PropDescriptions();
		}
	}
	[HarmonyPatch(typeof(CustomLocalizationTermRegistry), "SetLanguage")]
	internal static class LocalizationCompatibility
	{
		internal static int RepairedTerms;

		internal static bool IsDevaTerm(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return false;
			}
			if (key.StartsWith("Default/", StringComparison.Ordinal) || key.StartsWith("Default\\", StringComparison.Ordinal))
			{
				key = key.Substring(8);
			}
			int num = key.IndexOf("sanson.DevaClan", StringComparison.Ordinal);
			if (num < 0 || (num > 0 && key[num - 1] != '-'))
			{
				return false;
			}
			int num2 = num + "sanson.DevaClan".Length;
			if (num2 < key.Length)
			{
				if (key[num2] != '-')
				{
					return key[num2] == '_';
				}
				return true;
			}
			return false;
		}

		internal static void Prefix(TermData termData)
		{
			if (termData != null && IsDevaTerm(termData.Term))
			{
				LanguageSourceData languageSourceData = termData.languageSourceData;
				if (languageSourceData != null && termData.Languages.Length < languageSourceData.mLanguages.Count)
				{
					termData.Group = termData.Group;
					termData.SetNumLanguages(languageSourceData.mLanguages.Count);
					RepairedTerms++;
				}
			}
		}
	}
	[HarmonyPatch(typeof(CustomLocalizationTermRegistry), "LoadData")]
	internal static class LocalizationVerification
	{
		private static void Postfix()
		{
			int num = 0;
			int num2 = 0;
			bool flag = false;
			bool flag2 = false;
			foreach (LanguageSourceData source in LocalizationManager.Sources)
			{
				int languageIndex = source.GetLanguageIndex("Chinese", true, false);
				if (languageIndex < 0)
				{
					continue;
				}
				foreach (TermData mTerm in source.mTerms)
				{
					if (LocalizationCompatibility.IsDevaTerm(mTerm.Term))
					{
						num++;
						string text = ((languageIndex < mTerm.Languages.Length) ? mTerm.Languages[languageIndex] : null);
						if (string.IsNullOrEmpty(text))
						{
							num2++;
						}
						if (mTerm.Term == "CardData_nameKey-sanson.DevaClan-Card-Mara")
						{
							flag = true;
							flag2 = text == "“魔罗”波甸";
							Plugin.Log.LogInfo((object)("DEVA LOCALIZATION CHECK: language=" + source.mLanguages[languageIndex].Name + "; Mara=" + text + "; expected=“魔罗”波甸."));
						}
					}
				}
			}
			string text2 = string.Format("DEVA LOCALIZATION CHECK: repaired={0}; terms={1}; missing Chinese={2}; Mara={3}.", LocalizationCompatibility.RepairedTerms, num, num2, (flag && flag2) ? "PASS" : "FAIL");
			if (num == 0 || num2 != 0 || !flag || !flag2)
			{
				Plugin.Log.LogError((object)text2);
			}
			else
			{
				Plugin.Log.LogInfo((object)text2);
			}
		}
	}
	[HarmonyPatch(typeof(StatusEffectManager), "GetLocalizedCardTooltipTextKey")]
	internal static class NativeStatusTooltips
	{
		internal static string Resolve(string statusId, string cardKey, Func<string, bool> hasTranslation)
		{
			if (statusId != "relentless" && statusId != "untouchable")
			{
				return cardKey;
			}
			if (hasTranslation(cardKey))
			{
				return cardKey;
			}
			string localizedCharacterTooltipTextKey = StatusEffectManager.GetLocalizedCharacterTooltipTextKey(statusId);
			if (!hasTranslation(localizedCharacterTooltipTextKey))
			{
				return cardKey;
			}
			return localizedCharacterTooltipTextKey;
		}

		private static void Postfix(string statusId, ref string __result)
		{
			__result = Resolve(statusId, __result, (string key) => LocalizationExtensions.HasTranslation(key));
		}
	}
	[BepInPlugin("sanson.DevaClan", "Deva Clan / 天人氏族", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "sanson.DevaClan";

		internal static ManualLogSource Log;

		internal static ChargeResource Charge;

		internal static ConstructSummonResource ConstructSummons;

		internal static TrackedValueType ConstructSummonStat;

		internal static TrackedValueType ChargeStat;

		internal static readonly Dictionary<string, CardData> Cards = new Dictionary<string, CardData>();

		internal static readonly Dictionary<string, CharacterData> Units = new Dictionary<string, CharacterData>();

		internal static readonly Dictionary<string, CardUpgradeData> Upgrades = new Dictionary<string, CardUpgradeData>();

		internal static readonly Dictionary<string, RelicData> Relics = new Dictionary<string, RelicData>();

		internal static readonly Dictionary<string, CharacterTriggerData> Triggers = new Dictionary<string, CharacterTriggerData>();

		internal static SubtypeData Construct;

		internal static string KarmaId;

		internal static Trigger ResetTrigger;

		public void Awake()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			string root = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			string[] files = (from p in Directory.GetFiles(Path.Combine(root, "json"), "*.json", SearchOption.AllDirectories)
				select p.Substring(root.Length + 1).Replace('\\', '/')).OrderBy<string, string>((string p) => p, StringComparer.Ordinal).ToArray();
			if (files.Length == 0)
			{
				throw new InvalidOperationException("DevaClan content JSON is missing; install the complete package.");
			}
			if (files.Length > 1 && files.Any((string p) => string.Equals(p, "json/content.json", StringComparison.OrdinalIgnoreCase)))
			{
				throw new InvalidOperationException("Old json/content.json and modular JSON coexist. Back up and replace the complete DevaClan folder, or run Install.cmd.");
			}
			Railhead.GetBuilder().Configure("sanson.DevaClan", (Action<IConfigurationBuilder>)delegate(IConfigurationBuilder c)
			{
				ConfigurationExtensions.AddMergedJsonFile(c, files.ToList());
			});
			Railend.ConfigurePostAction((Action<Container>)delegate(Container c)
			{
				//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_020d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0212: Unknown result type (might be due to invalid IL or missing references)
				//IL_0232: Unknown result type (might be due to invalid IL or missing references)
				//IL_0237: Unknown result type (might be due to invalid IL or missing references)
				//IL_0246: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_0260: Unknown result type (might be due to invalid IL or missing references)
				//IL_026a: Unknown result type (might be due to invalid IL or missing references)
				IRegister<CardData> instance = c.GetInstance<IRegister<CardData>>();
				string[] cards = ContentIds.Cards;
				foreach (string text in cards)
				{
					Cards[text] = IEnumerableUtility.GetValueOrDefault<string, CardData>((IDictionary<string, CardData>)instance, StringExtensions.GetId("sanson.DevaClan", "Card", text), (CardData)null);
				}
				IRegister<CharacterData> instance2 = c.GetInstance<IRegister<CharacterData>>();
				cards = ContentIds.Units;
				foreach (string text2 in cards)
				{
					Units[text2] = IEnumerableUtility.GetValueOrDefault<string, CharacterData>((IDictionary<string, CharacterData>)instance2, StringExtensions.GetId("sanson.DevaClan", "Character", text2), (CharacterData)null);
				}
				IRegister<CardUpgradeData> instance3 = c.GetInstance<IRegister<CardUpgradeData>>();
				cards = ContentIds.Upgrades;
				foreach (string text3 in cards)
				{
					Upgrades[text3] = IEnumerableUtility.GetValueOrDefault<string, CardUpgradeData>((IDictionary<string, CardUpgradeData>)instance3, StringExtensions.GetId("sanson.DevaClan", "Upgrade", text3), (CardUpgradeData)null);
				}
				IRegister<RelicData> instance4 = c.GetInstance<IRegister<RelicData>>();
				cards = ContentIds.Relics;
				foreach (string text4 in cards)
				{
					Relics[text4] = IEnumerableUtility.GetValueOrDefault<string, RelicData>((IDictionary<string, RelicData>)instance4, StringExtensions.GetId("sanson.DevaClan", "RelicData", text4), (RelicData)null);
				}
				IRegister<CharacterTriggerData> instance5 = c.GetInstance<IRegister<CharacterTriggerData>>();
				cards = ContentIds.Triggers;
				foreach (string text5 in cards)
				{
					Triggers[text5] = IEnumerableUtility.GetValueOrDefault<string, CharacterTriggerData>((IDictionary<string, CharacterTriggerData>)instance5, StringExtensions.GetId("sanson.DevaClan", "CTrigger", text5), (CharacterTriggerData)null);
				}
				Construct = IEnumerableUtility.GetValueOrDefault<string, SubtypeData>((IDictionary<string, SubtypeData>)c.GetInstance<IRegister<SubtypeData>>(), StringExtensions.GetId("sanson.DevaClan", "Subtype", "Construct"), (SubtypeData)null);
				KarmaId = IEnumerableUtility.GetValueOrDefault<string, StatusEffectData>((IDictionary<string, StatusEffectData>)c.GetInstance<IRegister<StatusEffectData>>(), StringExtensions.GetId("sanson.DevaClan", "StatusEffect", "karmergy"), (StatusEffectData)null).GetStatusId();
				ChargeStat = IEnumerableUtility.GetValueOrDefault<string, TrackedValueType>((IDictionary<string, TrackedValueType>)c.GetInstance<IRegister<TrackedValueType>>(), StringExtensions.GetId("sanson.DevaClan", "TrackedValueTypeEnum", "Charge"), (TrackedValueType)0);
				ResetTrigger = IEnumerableUtility.GetValueOrDefault<string, Trigger>((IDictionary<string, Trigger>)c.GetInstance<IRegister<Trigger>>(), StringExtensions.GetId("sanson.DevaClan", "CTriggerEnum", "OnReset"), (Trigger)0);
				ConstructSummonStat = IEnumerableUtility.GetValueOrDefault<string, TrackedValueType>((IDictionary<string, TrackedValueType>)c.GetInstance<IRegister<TrackedValueType>>(), StringExtensions.GetId("sanson.DevaClan", "TrackedValueTypeEnum", "ConstructSummons"), (TrackedValueType)0);
				ConstructSummons = new ConstructSummonResource();
				TrackedValueTypeExtensions.SetTrackedValueHandler(ConstructSummonStat, (AbstractTrackedValueHandler)(object)ConstructSummons);
				Charge = new ChargeResource();
				TrackedValueTypeExtensions.SetTrackedValueHandler(ChargeStat, (AbstractTrackedValueHandler)(object)Charge);
				ClassMechanicHud hUD = HudManager.GetHUD("sanson.DevaClan", "ChargeHud");
				if (hUD != null)
				{
					hUD.SetTrackedValueHandler((AbstractTrackedValueHandler)(object)Charge);
				}
				int num = Cards.Count((KeyValuePair<string, CardData> k) => (Object)(object)k.Value == (Object)null) + Units.Count((KeyValuePair<string, CharacterData> k) => (Object)(object)k.Value == (Object)null) + Upgrades.Count((KeyValuePair<string, CardUpgradeData> k) => (Object)(object)k.Value == (Object)null) + Relics.Count((KeyValuePair<string, RelicData> k) => (Object)(object)k.Value == (Object)null) + Triggers.Count((KeyValuePair<string, CharacterTriggerData> k) => k.Value == null);
				Log.LogInfo((object)$"DEVA VALIDATION: {Cards.Count} cards, {Units.Count} units, {Relics.Count} relics; missing registrations={num}.");
				if (num != 0)
				{
					Log.LogError((object)"Deva content registration incomplete.");
				}
				Log.LogInfo((object)$"DEVA LOCALIZATION: initialized translation storage for {LocalizationCompatibility.RepairedTerms} terms.");
			});
			new Harmony("sanson.DevaClan").PatchAll();
			Log.LogInfo((object)"Deva Clan 0.3.0 loaded; balance update candidate.");
		}

		internal static bool Has(ICoreGameManagers g, string id)
		{
			if (g != null && Relics.TryGetValue(id, out var data) && (Object)(object)data != (Object)null)
			{
				return g.GetSaveManager().GetAllRelics().Any((RelicState r) => r.GetRelicDataID() == ((GameData)data).GetID());
			}
			return false;
		}

		internal static bool Is(CharacterState c, string id)
		{
			if ((Object)(object)c != (Object)null && Units.TryGetValue(id, out var value))
			{
				return (Object)(object)c.GetSourceCharacterData() == (Object)(object)value;
			}
			return false;
		}

		internal static bool Is(CardState c, string id)
		{
			if (c != null && Cards.TryGetValue(id, out var value))
			{
				return c.GetCardDataID() == ((GameData)value).GetID();
			}
			return false;
		}

		internal static bool IsConstruct(CharacterState c)
		{
			if ((Object)(object)c != (Object)null && Construct != null)
			{
				return c.GetHasSubtype(Construct);
			}
			return false;
		}

		internal static bool IsConstruct(CardState c)
		{
			if (c == null)
			{
				return false;
			}
			CharacterData spawnCharacterData = c.GetSpawnCharacterData();
			return ((spawnCharacterData == null) ? ((bool?)null) : spawnCharacterData.GetSubtypes()?.Contains(Construct)) == true;
		}

		internal static int Level(CharacterState c, string path)
		{
			if ((Object)(object)c == (Object)null)
			{
				return 0;
			}
			CardState spawnerCard = c.GetSpawnerCard();
			for (int num = 3; num > 0; num--)
			{
				if (Upgrades.TryGetValue(path + num, out var value) && ((spawnerCard != null && spawnerCard.HasUpgrade(value)) || c.HasUpgrade(value)))
				{
					return num;
				}
			}
			return 0;
		}

		internal static List<CharacterState> Floor(RoomState room, Type team = (Type)2)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			List<CharacterState> list = new List<CharacterState>();
			if ((Object)(object)room != (Object)null)
			{
				room.AddCharactersToList(list, team, false, true);
			}
			return list.Where((CharacterState c) => (Object)(object)c != (Object)null && c.IsAlive && !c.IsDestroyed).ToList();
		}

		internal static void Gain(ICoreGameManagers g, int n, CardState card = null)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Charge == null)
			{
				return;
			}
			g.GetCardStatistics().IncrementStat(card, ChargeStat, n);
			if (!g.GetSaveManager().PreviewMode && !SaveManager.IsInUndoModeStatic)
			{
				g.GetMonsterManager().RefreshCharacterAbilityUI();
				RoomManager roomManager = g.GetRoomManager();
				RoomUI roomUI = roomManager.GetRoomUI();
				if ((Object)(object)roomUI != (Object)null && roomManager.IsValidRoomIndex(roomManager.GetSelectedRoom()))
				{
					roomUI.RefreshTrainRoomAttachmentDisplay(roomManager.GetRoom(roomManager.GetSelectedRoom()));
				}
			}
		}
	}
	public sealed class CardEffectRebirth : DevaEffectBase
	{
		public override bool CanPlayWhenHandFull => false;

		public override bool TestEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g)
		{
			return new RebirthSelection(g.GetCardManager()).HasCandidates;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			if (g.GetSaveManager().PreviewMode)
			{
				yield break;
			}
			RebirthSelection selection = new RebirthSelection(g.GetCardManager());
			if (!selection.HasCandidates)
			{
				yield break;
			}
			ScreenManager screens = sys.GetScreenManager();
			screens.SetScreenActive((ScreenName)3, true, (ScreenActiveCallback)delegate(IScreen screen)
			{
				DeckScreen val2 = (DeckScreen)(object)((screen is DeckScreen) ? screen : null);
				if (val2 == null)
				{
					selection.Cancel();
				}
				else
				{
					val2.Setup(selection.CreateParams(p.playedCard.GetTitleKey()));
					selection.Bind(val2, delegate
					{
						screens.SetScreenActive((ScreenName)3, false, (ScreenActiveCallback)null);
					});
				}
			});
			while (!selection.Completed)
			{
				yield return null;
			}
			CardState selected = selection.Selected;
			if (RebirthSelection.IsCandidate(selected, g.GetCardManager()))
			{
				CardUpgradeState val = new CardUpgradeState();
				val.Setup(Plugin.Upgrades["RebirthFree"], false, false);
				val.SetSerializeScalingValues(true);
				val.SetCostReduction(Math.Max(0, selected.GetCostWithoutTraits(false)));
				selected.GetTemporaryCardStateModifiers().AddUpgrade(val, (CardStateModifiers)null);
				BattleMemory.Active.Karma.TryGetValue(selected, out var value);
				BattleMemory.Active.Karma[selected] = value + DevaEffectBase.StatusCount(e, 5);
				g.GetCardManager().RestoreExhaustedOrEatenCard(selected, true);
				g.GetCardManager().DrawSpecificCard(selected, false, (DrawSource)2, p.playedCard, 1, 1);
			}
		}
	}
	internal sealed class RebirthSelection
	{
		private readonly CardManager cards;

		internal bool Completed { get; private set; }

		internal CardState Selected { get; private set; }

		internal bool HasCandidates => cards.GetExhaustedPile(false).Any((CardState c) => IsCandidate(c, cards));

		internal RebirthSelection(CardManager cards)
		{
			this.cards = cards;
		}

		internal static bool IsCandidate(CardState card, CardManager cards)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			if (card != null && (int)card.GetCardType() == 1 && BattleMemory.Active.Dead.Contains(card))
			{
				return cards.GetExhaustedPile(false).Contains(card);
			}
			return false;
		}

		internal Params CreateParams(string titleKey)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_005d: Expected O, but got Unknown
			return new Params
			{
				mode = (Mode)9,
				targetMode = (TargetMode)15,
				cardTypeFilter = (CardType)1,
				allowSelectChampion = true,
				showCancel = true,
				excludeFilteredOutCards = true,
				ignoreDefaultFilters = true,
				titleKey = titleKey,
				instructionsKey = "ScreenDeck_Select_CardEffectRecursion",
				filterFunc = (FilterCardStateDelegate)((CardState c) => !IsCandidate(c, cards))
			};
		}

		internal void Choose(CardState card)
		{
			if (!Completed)
			{
				Selected = (IsCandidate(card, cards) ? card : null);
				Completed = true;
			}
		}

		internal void Cancel()
		{
			if (!Completed)
			{
				Selected = null;
				Completed = true;
			}
		}

		internal void Bind(DeckScreen deck, Action close)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			deck.AddDeckScreenCardStateChosenDelegate((CardStateChosenDelegate)delegate(CardState c)
			{
				Choose(c);
				close();
			});
			deck.AddDeckScreenCancelCallback((Action)Cancel);
		}
	}
	public class CardEffectResetUnit : DevaTargetEffect
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in from t in DevaEffectBase.Targets(p)
				where ((CardEffectBase)this).TestEffectOnTarget(e, p, t, g)
				select t)
			{
				yield return Effects.Reset(item, p, g);
			}
		}
	}
	public sealed class CardEffectResetConstruct : CardEffectResetUnit
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (DevaEffectBase.Alive(target) && (int)target.GetTeamType() == 2)
			{
				return Plugin.IsConstruct(target);
			}
			return false;
		}
	}
	public sealed class CardEffectRitualReset : CardEffectResetUnit
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (DevaEffectBase.Alive(target) && (int)target.GetTeamType() == 2)
			{
				return !Plugin.Is(target, "RitualTechnician");
			}
			return false;
		}
	}
	public sealed class CardEffectResetFloor : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in Plugin.Floor(DevaEffectBase.Room(p, g), (Type)2))
			{
				yield return Effects.Reset(item, p, g);
			}
		}
	}
	public sealed class CardEffectImproveGiant : DevaTargetEffect
	{
		public override bool TestEffectOnTarget(CardEffectState e, CardEffectParams p, CharacterState target, ICoreGameManagers g)
		{
			if (DevaEffectBase.Alive(target))
			{
				return Plugin.Is(target, "Giant");
			}
			return false;
		}

		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			int level = e.GetParamInt();
			foreach (CharacterState item in from t in DevaEffectBase.Targets(p)
				where Plugin.Is(t, "Giant")
				select t)
			{
				CardState spawnerCard = item.GetSpawnerCard();
				CardState owner = null;
				if (spawnerCard != null)
				{
					BattleMemory.Active.GiantOwners.TryGetValue(spawnerCard, out owner);
				}
				object obj = owner;
				if (obj == null)
				{
					CharacterState obj2 = DevaEffectBase.Actor(p);
					obj = ((obj2 != null) ? obj2.GetSpawnerCard() : null);
				}
				owner = (CardState)obj;
				CharacterState replacement = null;
				yield return Effects.Reset(item, p, g, delegate(CharacterState c)
				{
					replacement = c;
				});
				if (!((Object)(object)replacement == (Object)null) && replacement.IsAlive && !replacement.IsDestroyed)
				{
					int attack = ((level != 3) ? 1 : 2);
					int health = ((level != 1) ? 1 : 0);
					yield return Effects.Grow(replacement, attack, health, g, permanent: true);
					if (owner != null && !g.GetSaveManager().PreviewMode)
					{
						CardUpgradeState val = new CardUpgradeState();
						val.Setup(Plugin.Upgrades["GiantGrowth" + level], false, false);
						owner.GetCardStateModifiers().AddUpgrade(val, (CardStateModifiers)null);
					}
				}
			}
		}
	}
	public sealed class CardEffectLiberation : DevaTargetEffect
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				int damage = item.GetAttackDamage();
				RoomState floor = item.GetCurrentRoom(false);
				yield return item.Sacrifice(p.playedCard, false, false, (CharacterState)null);
				foreach (CharacterState item2 in Plugin.Floor(floor, (Type)1))
				{
					yield return Effects.Damage(item2, damage, p, g);
				}
			}
		}
	}
	public sealed class CardEffectConvertKarmergy : DevaTargetEffect
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				int statusEffectStacks = item.GetStatusEffectStacks(Plugin.KarmaId);
				item.RemoveStatusEffect(Plugin.KarmaId, statusEffectStacks, false);
				yield return Effects.Grow(item, statusEffectStacks * e.GetParamInt(), statusEffectStacks * e.GetParamInt(), g, permanent: true);
			}
		}
	}
	[HarmonyPatch(typeof(CombatManager), "QueueAndRunTrigger")]
	internal static class SuppressSummonOnReset
	{
		private static bool Prefix(CharacterState character, Trigger trigger)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)trigger == 2)
			{
				return !ResetLifecycle.IsResetReplacementActive;
			}
			return true;
		}
	}
	internal sealed class ResetContext
	{
		internal readonly CharacterState Original;

		internal int Karma;

		internal CardState Equipment;

		internal KeyValuePair<string, int>[] PositiveStatuses = new KeyValuePair<string, int>[0];

		internal ResetContext(CharacterState original, int karma)
		{
			Original = original;
			Karma = karma;
		}

		internal void PreserveEquipment()
		{
			Equipment = ((IEnumerable<CardState>)Original.GetEquipment()).FirstOrDefault((Func<CardState, bool>)((CardState e) => Plugin.Is(e, "SoulBackup")));
			if (Equipment != null)
			{
				List<StatusEffectStack> source = new List<StatusEffectStack>();
				Original.GetStatusEffects(ref source, false);
				PositiveStatuses = (from s in source
					where s.Count > 0 && (int)s.State.GetDisplayCategory() == 0 && s.State.GetStatusId() != Plugin.KarmaId
					select new KeyValuePair<string, int>(s.State.GetStatusId(), s.Count)).ToArray();
			}
		}
	}
	internal static class ResetLifecycle
	{
		private static readonly Dictionary<CharacterState, ResetContext> contexts = new Dictionary<CharacterState, ResetContext>();

		internal static bool IsResetReplacementActive { get; private set; }

		internal static void Begin(ResetContext context)
		{
			contexts.Add(context.Original, context);
		}

		internal static void End(CharacterState unit)
		{
			contexts.Remove(unit);
			IsResetReplacementActive = false;
		}

		internal static ResetContext Get(CharacterState unit)
		{
			if (!((Object)(object)unit != (Object)null) || !contexts.TryGetValue(unit, out var value))
			{
				return null;
			}
			return value;
		}

		internal static void BeginReplacement()
		{
			IsResetReplacementActive = true;
		}
	}
	public sealed class CardEffectDoubleResetKarmergy : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			ResetContext resetContext = ResetLifecycle.Get(p.selfTarget);
			if (resetContext != null)
			{
				resetContext.Karma *= 2;
			}
			yield break;
		}
	}
	public sealed class CardEffectPreserveResetStatuses : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			ResetLifecycle.Get(p.selfTarget)?.PreserveEquipment();
			yield break;
		}
	}
	internal static class AsuraArenaFilter
	{
		internal static bool Excludes(TrainRoomAttachmentState attachment, CharacterState character)
		{
			if (Plugin.Is((attachment != null) ? attachment.CardState : null, "AsuraArena") && (Object)(object)character != (Object)null)
			{
				if (!character.IsAnyBoss())
				{
					return character.IsCompanionBoss();
				}
				return true;
			}
			return false;
		}

		internal static bool ArenaRelentlessOnly(CharacterState character)
		{
			if ((Object)(object)character == (Object)null || character.IsAnyBoss() || character.IsCompanionBoss() || !Plugin.Upgrades.TryGetValue("AsuraArenaUpgrade", out var value) || !character.HasUpgrade(value))
			{
				return false;
			}
			CharacterData sourceCharacterData = character.GetSourceCharacterData();
			if (!((Object)(object)sourceCharacterData == (Object)null))
			{
				StatusEffectStackData[] startingStatusEffects = sourceCharacterData.GetStartingStatusEffects();
				if (startingStatusEffects == null)
				{
					return true;
				}
				return !startingStatusEffects.Any((StatusEffectStackData s) => s.statusId == "relentless" && s.count > 0);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterState), "CanDestroyRoom")]
	internal static class AsuraArenaNoRoomDestruction
	{
		private static void Postfix(CharacterState __instance, ref bool __result)
		{
			if (__result && AsuraArenaFilter.ArenaRelentlessOnly(__instance))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(TrainRoomAttachmentState), "ShouldIgnoreCharacter")]
	internal static class AsuraArenaIgnoreBosses
	{
		private static void Postfix(TrainRoomAttachmentState __instance, CharacterState characterState, ref bool __result)
		{
			if (AsuraArenaFilter.Excludes(__instance, characterState))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(TrainRoomAttachmentState), "ApplyToCharacter")]
	internal static class AsuraArenaApplyGuard
	{
		private static IEnumerator Postfix(IEnumerator result, TrainRoomAttachmentState __instance, CharacterState characterState)
		{
			if (!AsuraArenaFilter.Excludes(__instance, characterState))
			{
				while (result.MoveNext())
				{
					yield return result.Current;
				}
			}
		}
	}
	public sealed class RelicEffectBlueprint : RelicEffectBase, ITurnPhaseStartOfPlayerTurnAfterDrawRelicEffect, ITurnPhaseTimingRelicEffect, IRelicEffect
	{
		public override PropDescriptions CreateEditorInspectorDescriptions()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			return new PropDescriptions();
		}

		public bool TestEffectTurnPhaseTiming(RelicEffectParams p, ICoreGameManagers g)
		{
			return true;
		}

		public IEnumerator ApplyEffectTurnPhaseTiming(RelicEffectParams p, ICoreGameManagers g)
		{
			Effects.CreateConstruct(g, ephemeral: true);
			yield break;
		}
	}
	[HarmonyPatch(typeof(CombatManager), "CheckTriggerRelentless")]
	internal static class AsuraMark
	{
		private static IEnumerator Postfix(IEnumerator result, RoomState room, AllGameManagers ___allGameManagers)
		{
			ICoreGameManagers coreManagers = ___allGameManagers.GetCoreManagers();
			List<CharacterState> source = Plugin.Floor(room, (Type)3);
			if (Plugin.Has(coreManagers, "AsuraMark") && source.Any((CharacterState c) => c.HasStatusEffect("relentless")) && room.HasCharacters((Type)2, true) && (room.HasCharacters((Type)1, true) || room.HasOuterTrainBoss()) && BattleMemory.Active.Relentless.Add(room.GetRoomIndex()))
			{
				foreach (CharacterState item in Plugin.Floor(room, (Type)2))
				{
					item.AddStatusEffect(Plugin.KarmaId, 2, (CharacterState)null, true, false);
				}
			}
			while (result.MoveNext())
			{
				yield return result.Current;
			}
		}
	}
	internal static class SingingBowl
	{
		internal static IEnumerator AfterAbility(CardState ability, CharacterState user, bool hasRelic)
		{
			if (hasRelic && ability != null && ability.IsUnitAbility() && !((Object)(object)user == (Object)null) && (int)user.GetTeamType() == 2 && !user.IsDestroyed && user.IsAlive)
			{
				CardUpgradeState val = new CardUpgradeState();
				val.Setup();
				val.SetSerializeScalingValues(true);
				val.SetAttackDamage(3);
				val.SetAdditionalHP(3);
				yield return user.ApplyCardUpgrade(val, false, "", true, false, (CardState)null, (Action<UpgradeApplicationResult>)null, (TrainRoomAttachmentState)null, false);
			}
		}
	}
	public sealed class CardEffectTurnSilence : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in from t in DevaEffectBase.Targets(p)
				where (int)t.GetTeamType() == 1
				select t)
			{
				int statusEffectStacks = item.GetStatusEffectStacks("silenced");
				AddStatus(item, DevaEffectBase.StatusId(e, "silenced"), DevaEffectBase.StatusCount(e, e.GetParamInt()), e, p);
				int num = Math.Max(0, item.GetStatusEffectStacks("silenced") - statusEffectStacks);
				if (num > 0)
				{
					BattleMemory.Active.TurnSilence[item] = (BattleMemory.Active.TurnSilence.TryGetValue(item, out var value) ? (value + num) : num);
				}
			}
			yield break;
		}
	}
	public sealed class CardEffectTurnStasis : DevaEffectBase
	{
		public override IEnumerator ApplyEffect(CardEffectState e, CardEffectParams p, ICoreGameManagers g, ISystemManagers sys)
		{
			foreach (CharacterState item in DevaEffectBase.Targets(p))
			{
				item.AddStatusEffect("untouchable", 1, (CharacterState)null, true, false);
				BattleMemory.Active.Stasis.Add(item);
			}
			yield break;
		}
	}
	internal static class TemporaryMemory
	{
		internal static bool Contains(CharacterState unit)
		{
			if ((Object)(object)unit == (Object)null)
			{
				return false;
			}
			Memory active = BattleMemory.Active;
			CardState spawnerCard = unit.GetSpawnerCard();
			if (!active.TemporaryUnits.Contains(unit) && (spawnerCard == null || !active.TemporaryCards.Contains(spawnerCard)))
			{
				if (!unit.IsDestroyed)
				{
					return unit.GetStatusEffectStacks(Effects.TemporaryId) > 0;
				}
				return false;
			}
			return true;
		}

		internal static void Remember(CharacterState unit, bool force = false)
		{
			if (!((Object)(object)unit == (Object)null) && (force || Contains(unit)))
			{
				BattleMemory.Active.TemporaryUnits.Add(unit);
				CardState spawnerCard = unit.GetSpawnerCard();
				if (spawnerCard != null)
				{
					BattleMemory.Active.TemporaryCards.Add(spawnerCard);
				}
			}
		}

		internal static void Mark(CharacterState unit)
		{
			if (!((Object)(object)unit == (Object)null) && !unit.IsDestroyed)
			{
				Remember(unit, force: true);
				if (unit.GetStatusEffectStacks(Effects.TemporaryId) == 0)
				{
					unit.AddStatusEffect(Effects.TemporaryId, 1, (CharacterState)null, false, false);
				}
			}
		}

		internal static void Restore(CharacterState unit)
		{
			if (Contains(unit))
			{
				Mark(unit);
			}
		}

		internal static void Copy(CardState source, CardState copy)
		{
			if (source != null && copy != null && BattleMemory.Active.TemporaryCards.Contains(source))
			{
				BattleMemory.Active.TemporaryCards.Add(copy);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterState), "RemoveStatusEffect", new Type[]
	{
		typeof(string),
		typeof(int),
		typeof(RemoveStatusEffectParams),
		typeof(bool)
	})]
	internal static class PreserveTemporaryStatus
	{
		private static bool Prefix(CharacterState __instance, string statusId)
		{
			if (!string.Equals(statusId, Effects.TemporaryId, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			TemporaryMemory.Remember(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(CardManager), "CopyCardState")]
	internal static class CopyTemporaryCard
	{
		private static void Postfix(CardState sourceCardState, CardState __result)
		{
			TemporaryMemory.Copy(sourceCardState, __result);
		}
	}
	[HarmonyPatch(typeof(CharacterHelper), "CopyCharacterStats")]
	internal static class CopyTemporaryUnit
	{
		private static void Postfix(CharacterState copyToChar, CharacterState copyFromChar)
		{
			if (TemporaryMemory.Contains(copyFromChar))
			{
				TemporaryMemory.Mark(copyToChar);
			}
		}
	}
	[HarmonyPatch(typeof(CombatManager), "RunMonsterTurn")]
	internal static class TurnStart
	{
		private static IEnumerator Postfix(IEnumerator result, bool isFirstTurn, AllGameManagers ___allGameManagers)
		{
			ICoreGameManagers g = ___allGameManagers.GetCoreManagers();
			HashSet<int> feastFloors = BalanceRules.ConsumeFeast();
			BattleMemory.Active.Karma.Clear();
			BattleMemory.Active.Relentless.Clear();
			KeyValuePair<CharacterState, int>[] array = BattleMemory.Active.TurnSilence.ToArray();
			int i;
			for (i = 0; i < array.Length; i++)
			{
				KeyValuePair<CharacterState, int> keyValuePair = array[i];
				CharacterState key = keyValuePair.Key;
				if ((Object)(object)key != (Object)null && !key.IsDestroyed && key.IsAlive)
				{
					int statusEffectStacks = key.GetStatusEffectStacks("silenced");
					if (statusEffectStacks > 0)
					{
						key.RemoveStatusEffect("silenced", Math.Min(statusEffectStacks, keyValuePair.Value), false);
					}
				}
			}
			BattleMemory.Active.TurnSilence.Clear();
			foreach (CharacterState stasi in BattleMemory.Active.Stasis)
			{
				if ((Object)(object)stasi != (Object)null && !stasi.IsDestroyed && stasi.IsAlive)
				{
					stasi.RemoveStatusEffect("untouchable", 1, false);
				}
			}
			BattleMemory.Active.Stasis.Clear();
			for (int i2 = 0; i2 < g.GetRoomManager().GetNumRooms(); i2 = i)
			{
				List<CharacterState> list = Plugin.Floor(g.GetRoomManager().GetRoom(i2), (Type)3);
				int retain = (from c in list
					where (int)c.GetTeamType() == 2 && !c.HasStatusEffect("silenced")
					select Plugin.Level(c, "MaraLiberation")).DefaultIfEmpty(0).Max();
				foreach (CharacterState item in list)
				{
					int statusEffectStacks2 = item.GetStatusEffectStacks(Plugin.KarmaId);
					int num = BalanceRules.RetainedKarmergy(statusEffectStacks2, (int)item.GetTeamType() == 2, retain, feastFloors.Contains(i2));
					if (statusEffectStacks2 > num)
					{
						item.RemoveStatusEffect(Plugin.KarmaId, statusEffectStacks2 - num, false);
					}
					if (TemporaryMemory.Contains(item))
					{
						yield return item.Sacrifice((CardState)null, false, false, (CharacterState)null);
					}
				}
				i = i2 + 1;
			}
			if (isFirstTurn && Plugin.Has(g, "ReserveEnergy"))
			{
				Plugin.Gain(g, 5);
			}
			while (result.MoveNext())
			{
				yield return result.Current;
			}
		}
	}
	[HarmonyPatch(typeof(CardManager), "OnCharacterKilled")]
	internal static class DeathMemory
	{
		private static void Prefix(CharacterState killedUnit, ICoreGameManagers coreGameManagers)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)killedUnit.GetTeamType() == 2)
			{
				BattleMemory.Remember(killedUnit);
				CardState spawnerCard = killedUnit.GetSpawnerCard();
				if (spawnerCard != null && !killedUnit.HasStatusEffect("cardless"))
				{
					BattleMemory.Active.Dead.Add(spawnerCard);
				}
				if (Plugin.IsConstruct(killedUnit) && Plugin.Has(coreGameManagers, "ChargeRecycler"))
				{
					Plugin.Gain(coreGameManagers, 1);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CardManager), "ReturnUnitCardToHand")]
	internal static class ReturnMemory
	{
		private static void Prefix(CharacterState character)
		{
			BattleMemory.Remember(character);
		}
	}
	[HarmonyPatch(typeof(CharacterState), "OnSpawn")]
	internal static class SpawnMemory
	{
		private static IEnumerator Postfix(IEnumerator result, CharacterState __instance, AllGameManagers ___allGameManagers)
		{
			ICoreGameManagers g = ___allGameManagers.GetCoreManagers();
			if ((int)__instance.GetTeamType() == 2 && Plugin.KarmaId != null)
			{
				CardState spawnerCard = __instance.GetSpawnerCard();
				if (spawnerCard != null && BattleMemory.Active.Karma.TryGetValue(spawnerCard, out var value) && value > 0)
				{
					__instance.AddStatusEffect(Plugin.KarmaId, value, (CharacterState)null, false, false);
				}
			}
			TemporaryMemory.Restore(__instance);
			while (result.MoveNext())
			{
				yield return result.Current;
			}
			BalanceRules.AfterSummon(__instance, g);
		}
	}
}