Decompiled source of AtOEndless v1.7.0

BepInEx/plugins/com.corgan.AtOEndless.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cards;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Paradox;
using Photon.Pun;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("com.corgan.AtOEndless")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion("1.7.0+7913b879ebbd8718f1b82b5391701b80e7f7dedc")]
[assembly: AssemblyProduct("AtOEndless")]
[assembly: AssemblyTitle("com.corgan.AtOEndless")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[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 AtOEndless
{
	[Serializable]
	public class BlessingDefinition
	{
		[SerializeField]
		public string Id;

		[SerializeField]
		public string Name;

		[SerializeField]
		public string Rarity = "Common";

		[SerializeField]
		public bool Enabled = true;

		[SerializeField]
		public int Tier = 0;

		[SerializeField]
		public int MinTier = 0;

		[SerializeField]
		public int MaxTier = -1;

		[SerializeField]
		public string Activation = "BeginRound";

		[SerializeField]
		public string ItemTarget = "Self";

		[SerializeField]
		public int RoundCycle = 0;

		[SerializeField]
		public int ExactRound = 0;

		[SerializeField]
		public int TimesPerTurn = 0;

		[SerializeField]
		public int TimesPerCombat = 0;

		[SerializeField]
		public bool ActivationOnlyOnHeroes = true;

		[SerializeField]
		public bool OnlyAddItemToNPCs = true;

		[SerializeField]
		public string CastedCardType = "";

		[SerializeField]
		public bool EmptyHand = false;

		[SerializeField]
		public float LowerOrEqualPercentHP = 100f;

		[SerializeField]
		public bool UsedEnergy = false;

		[SerializeField]
		public string AuraCurseSetted = "";

		[SerializeField]
		public string AuraCurseSetted2 = "";

		[SerializeField]
		public string AuraCurseSetted3 = "";

		[SerializeField]
		public int AuraCurseNumForOneEvent = 0;

		[SerializeField]
		public int MaxHealth = 0;

		[SerializeField]
		public string CharacterStatModified = "";

		[SerializeField]
		public int CharacterStatModifiedValue = 0;

		[SerializeField]
		public string CharacterStatModified2 = "";

		[SerializeField]
		public int CharacterStatModifiedValue2 = 0;

		[SerializeField]
		public string CharacterStatModified3 = "";

		[SerializeField]
		public int CharacterStatModifiedValue3 = 0;

		[SerializeField]
		public int HealFlatBonus = 0;

		[SerializeField]
		public float HealPercentBonus = 0f;

		[SerializeField]
		public int HealReceivedFlatBonus = 0;

		[SerializeField]
		public float HealReceivedPercentBonus = 0f;

		[SerializeField]
		public float HealSelfPerDamageDonePercent = 0f;

		[SerializeField]
		public string DamageFlatBonus = "";

		[SerializeField]
		public int DamageFlatBonusValue = 0;

		[SerializeField]
		public string DamageFlatBonus2 = "";

		[SerializeField]
		public int DamageFlatBonusValue2 = 0;

		[SerializeField]
		public string DamageFlatBonus3 = "";

		[SerializeField]
		public int DamageFlatBonusValue3 = 0;

		[SerializeField]
		public string DamagePercentBonus = "";

		[SerializeField]
		public float DamagePercentBonusValue = 0f;

		[SerializeField]
		public string DamagePercentBonus2 = "";

		[SerializeField]
		public float DamagePercentBonusValue2 = 0f;

		[SerializeField]
		public string DamagePercentBonus3 = "";

		[SerializeField]
		public float DamagePercentBonusValue3 = 0f;

		[SerializeField]
		public string ResistModified1 = "";

		[SerializeField]
		public int ResistModifiedValue1 = 0;

		[SerializeField]
		public string ResistModified2 = "";

		[SerializeField]
		public int ResistModifiedValue2 = 0;

		[SerializeField]
		public string ResistModified3 = "";

		[SerializeField]
		public int ResistModifiedValue3 = 0;

		[SerializeField]
		public string AuraCurseBonus1 = "";

		[SerializeField]
		public int AuraCurseBonusValue1 = 0;

		[SerializeField]
		public string AuraCurseBonus2 = "";

		[SerializeField]
		public int AuraCurseBonusValue2 = 0;

		[SerializeField]
		public string AuraCurseImmune1 = "";

		[SerializeField]
		public string AuraCurseImmune2 = "";

		[SerializeField]
		public int DrawCards = 0;

		[SerializeField]
		public bool DrawMultiplyByEnergyUsed = false;

		[SerializeField]
		public int HealQuantity = 0;

		[SerializeField]
		public SpecialValuesDef HealQuantitySpecialValue = null;

		[SerializeField]
		public int HealPercentQuantity = 0;

		[SerializeField]
		public int HealPercentQuantitySelf = 0;

		[SerializeField]
		public int HealBasedOnAuraCurse = 0;

		[SerializeField]
		public int EnergyQuantity = 0;

		[SerializeField]
		public string DamageToTargetType = "";

		[SerializeField]
		public int DamageToTarget = 0;

		[SerializeField]
		public SpecialValuesDef DamageToTargetSpecialValue = null;

		[SerializeField]
		public string DamageToTargetType2 = "";

		[SerializeField]
		public int DamageToTarget2 = 0;

		[SerializeField]
		public SpecialValuesDef DamageToTargetSpecialValue2 = null;

		[SerializeField]
		public bool DttMultiplyByEnergyUsed = false;

		[SerializeField]
		public bool DontTargetBoss = false;

		[SerializeField]
		public string AuraCurseGain1 = "";

		[SerializeField]
		public int AuraCurseGainValue1 = 0;

		[SerializeField]
		public SpecialValuesDef AuraCurseGain1SpecialValue = null;

		[SerializeField]
		public bool ACG1MultiplyByEnergyUsed = false;

		[SerializeField]
		public string AuraCurseGain2 = "";

		[SerializeField]
		public int AuraCurseGainValue2 = 0;

		[SerializeField]
		public SpecialValuesDef AuraCurseGain2SpecialValue = null;

		[SerializeField]
		public bool ACG2MultiplyByEnergyUsed = false;

		[SerializeField]
		public string AuraCurseGain3 = "";

		[SerializeField]
		public int AuraCurseGainValue3 = 0;

		[SerializeField]
		public SpecialValuesDef AuraCurseGain3SpecialValue = null;

		[SerializeField]
		public bool ACG3MultiplyByEnergyUsed = false;

		[SerializeField]
		public string AuraCurseGainSelf1 = "";

		[SerializeField]
		public int AuraCurseGainSelfValue1 = 0;

		[SerializeField]
		public string AuraCurseGainSelf2 = "";

		[SerializeField]
		public int AuraCurseGainSelfValue2 = 0;

		[SerializeField]
		public string AuraCurseGainSelf3 = "";

		[SerializeField]
		public int AuraCurseGainSelfValue3 = 0;

		[SerializeField]
		public string AuraCurseHeal1 = "";

		[SerializeField]
		public string AuraCurseHeal2 = "";

		[SerializeField]
		public string AuraCurseHeal3 = "";

		[SerializeField]
		public bool AcHealFromTarget = false;

		[SerializeField]
		public int StealAuras = 0;

		[SerializeField]
		public int ChanceToDispel = 0;

		[SerializeField]
		public int ChanceToDispelNum = 0;

		[SerializeField]
		public int ChanceToPurge = 0;

		[SerializeField]
		public int ChanceToPurgeNum = 0;

		[SerializeField]
		public int ChanceToDispelSelf = 0;

		[SerializeField]
		public int ChanceToDispelNumSelf = 0;

		[SerializeField]
		public string CardToGain = "";

		[SerializeField]
		public int CardNum = 0;

		[SerializeField]
		public string CardPlace = "Hand";

		[SerializeField]
		public string CardToGainType = "";

		[SerializeField]
		public bool CostZero = false;

		[SerializeField]
		public int CostReduction = 0;

		[SerializeField]
		public bool Vanish = false;

		[SerializeField]
		public bool Permanent = false;

		[SerializeField]
		public string EffectCaster = "";

		[SerializeField]
		public string EffectTarget = "";

		[SerializeField]
		public string SpriteSource = "";

		[SerializeField]
		public BlessingUpgrade UpgradeA = null;

		[SerializeField]
		public BlessingUpgrade UpgradeB = null;

		[SerializeField]
		public BlessingUpgrade UpgradeRare = null;
	}
	[Serializable]
	public class SpecialValuesDef
	{
		[SerializeField]
		public string Name = "RuneCharges";

		[SerializeField]
		public bool Use = false;

		[SerializeField]
		public float Multiplier = 1f;
	}
	[Serializable]
	public class BlessingUpgrade
	{
		public const int NOT_SET = -999;

		public const float NOT_SET_FLOAT = -999f;

		[SerializeField]
		public string NameSuffix = "";

		[SerializeField]
		public int MaxHealth = -999;

		[SerializeField]
		public int CharacterStatModifiedValue = -999;

		[SerializeField]
		public int CharacterStatModifiedValue2 = -999;

		[SerializeField]
		public int DrawCards = -999;

		[SerializeField]
		public int HealQuantity = -999;

		[SerializeField]
		public int HealPercentQuantity = -999;

		[SerializeField]
		public int EnergyQuantity = -999;

		[SerializeField]
		public int DamageToTarget = -999;

		[SerializeField]
		public int DamageToTarget2 = -999;

		[SerializeField]
		public int DamageFlatBonusValue = -999;

		[SerializeField]
		public float DamagePercentBonusValue = -999f;

		[SerializeField]
		public int HealFlatBonus = -999;

		[SerializeField]
		public float HealPercentBonus = -999f;

		[SerializeField]
		public int HealReceivedFlatBonus = -999;

		[SerializeField]
		public float HealReceivedPercentBonus = -999f;

		[SerializeField]
		public int ResistModifiedValue1 = -999;

		[SerializeField]
		public int ResistModifiedValue2 = -999;

		[SerializeField]
		public int CardNum = -999;

		[SerializeField]
		public float HealSelfPerDamageDonePercent = -999f;

		[SerializeField]
		public int AuraCurseBonusValue1 = -999;

		[SerializeField]
		public int AuraCurseBonusValue2 = -999;

		[SerializeField]
		public int AuraCurseGainValue1 = -999;

		[SerializeField]
		public int AuraCurseGainValue2 = -999;

		[SerializeField]
		public int AuraCurseGainValue3 = -999;

		[SerializeField]
		public int AuraCurseGainSelfValue1 = -999;

		[SerializeField]
		public int AuraCurseGainSelfValue2 = -999;

		[SerializeField]
		public int AuraCurseGainSelfValue3 = -999;

		[SerializeField]
		public int ChanceToDispel = -999;

		[SerializeField]
		public int ChanceToDispelNum = -999;

		[SerializeField]
		public int ChanceToPurge = -999;

		[SerializeField]
		public int ChanceToPurgeNum = -999;

		public static bool IsSet(int value)
		{
			return value != -999;
		}

		public static bool IsSet(float value)
		{
			return Math.Abs(value - -999f) > 0.001f;
		}
	}
	public static class BlessingDescriptionGenerator
	{
		public static bool UseCustomDescriptions = false;

		private static Dictionary<string, string> generatedDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		public static string GenerateDescription(CardData card, BlessingDefinition def)
		{
			if ((Object)(object)card == (Object)null || def == null)
			{
				return "";
			}
			if (generatedDescriptions.TryGetValue(card.Id, out var value))
			{
				return value;
			}
			StringBuilder stringBuilder = new StringBuilder();
			ItemData item = card.Item;
			if ((Object)(object)item == (Object)null)
			{
				return "";
			}
			AppendPassiveStats(stringBuilder, item, def);
			AppendActivationTrigger(stringBuilder, item, def);
			AppendFrequencyLimit(stringBuilder, item, def);
			AppendConditionals(stringBuilder, item, def);
			AppendEffects(stringBuilder, card, item, def);
			string description = stringBuilder.ToString();
			description = FormatDescription(description);
			generatedDescriptions[card.Id] = description;
			return description;
		}

		public static void ClearCache()
		{
			generatedDescriptions.Clear();
		}

		private static void AppendPassiveStats(StringBuilder sb, ItemData item, BlessingDefinition def)
		{
			if (item.MaxHealth != 0)
			{
				sb.Append(SpriteText("hp"));
				sb.Append(" ");
				sb.Append(GetText("cardsMaxHP"));
				sb.Append(NumFormat(item.MaxHealth, showPlus: true));
				sb.Append("\n");
			}
			AppendResistances(sb, item);
			AppendDamageBonuses(sb, item);
			AppendHealBonuses(sb, item);
			AppendCharacterStats(sb, item);
			AppendAuraCurseBonuses(sb, item);
			AppendImmunities(sb, item);
		}

		private static void AppendResistances(StringBuilder sb, ItemData item)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			if ((int)item.ResistModified1 != 0 && item.ResistModifiedValue1 != 0)
			{
				list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified1)) + " " + NumFormat(item.ResistModifiedValue1, showPlus: true, percent: true));
			}
			if ((int)item.ResistModified2 != 0 && item.ResistModifiedValue2 != 0)
			{
				list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified2)) + " " + NumFormat(item.ResistModifiedValue2, showPlus: true, percent: true));
			}
			if ((int)item.ResistModified3 != 0 && item.ResistModifiedValue3 != 0)
			{
				list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.ResistModified3)) + " " + NumFormat(item.ResistModifiedValue3, showPlus: true, percent: true));
			}
			if (list.Count > 0)
			{
				sb.Append(string.Join(", ", list));
				sb.Append(" resistance\n");
			}
		}

		private static void AppendDamageBonuses(StringBuilder sb, ItemData item)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Invalid comparison between Unknown and I4
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			if ((int)item.DamageFlatBonus == 10 && item.DamageFlatBonusValue != 0)
			{
				sb.Append(string.Format(GetText("itemAllDamages"), NumFormat(item.DamageFlatBonusValue, showPlus: true)));
				sb.Append("\n");
			}
			else
			{
				List<string> list = new List<string>();
				int value = 0;
				if ((int)item.DamageFlatBonus != 0 && (int)item.DamageFlatBonus != 10 && item.DamageFlatBonusValue != 0)
				{
					list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus)));
					value = item.DamageFlatBonusValue;
				}
				if ((int)item.DamageFlatBonus2 != 0 && item.DamageFlatBonusValue2 != 0)
				{
					list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus2)));
				}
				if ((int)item.DamageFlatBonus3 != 0 && item.DamageFlatBonusValue3 != 0)
				{
					list.Add(SpriteText(Enum.GetName(typeof(DamageType), item.DamageFlatBonus3)));
				}
				if (list.Count > 0)
				{
					sb.Append(string.Format(GetText("itemXDamages"), string.Join("", list), NumFormat(value, showPlus: true)));
					sb.Append("\n");
				}
			}
			if ((int)item.DamagePercentBonus == 10 && item.DamagePercentBonusValue != 0f)
			{
				sb.Append(string.Format(GetText("itemAllDamages"), NumFormat((int)item.DamagePercentBonusValue, showPlus: true, percent: true)));
				sb.Append("\n");
			}
		}

		private static void AppendHealBonuses(StringBuilder sb, ItemData item)
		{
			if (item.HealFlatBonus != 0)
			{
				sb.Append(SpriteText("heal"));
				sb.Append(" ");
				sb.Append(Functions.LowercaseFirst(GetText("healDone")));
				sb.Append(NumFormat(item.HealFlatBonus, showPlus: true));
				sb.Append("\n");
			}
			if (item.HealPercentBonus != 0f)
			{
				sb.Append(SpriteText("heal"));
				sb.Append(" ");
				sb.Append(Functions.LowercaseFirst(GetText("healDone")));
				sb.Append(NumFormat((int)item.HealPercentBonus, showPlus: true, percent: true));
				sb.Append("\n");
			}
			if (item.HealReceivedFlatBonus != 0)
			{
				sb.Append(SpriteText("heal"));
				sb.Append(" ");
				sb.Append(Functions.LowercaseFirst(GetText("healTaken")));
				sb.Append(NumFormat(item.HealReceivedFlatBonus, showPlus: true));
				sb.Append("\n");
			}
			if (item.HealReceivedPercentBonus != 0f)
			{
				sb.Append(SpriteText("heal"));
				sb.Append(" ");
				sb.Append(Functions.LowercaseFirst(GetText("healTaken")));
				sb.Append(NumFormat((int)item.HealReceivedPercentBonus, showPlus: true, percent: true));
				sb.Append("\n");
			}
			if (item.HealSelfPerDamageDonePercent > 0f)
			{
				sb.Append(string.Format(GetText("cardsHealSelfPerDamage"), item.HealSelfPerDamageDonePercent.ToString()));
				sb.Append("\n");
			}
		}

		private static void AppendCharacterStats(StringBuilder sb, ItemData item)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			if ((int)item.CharacterStatModified == 2)
			{
				sb.Append(string.Format(GetText("itemSpeed"), NumFormat(item.CharacterStatModifiedValue, showPlus: true)));
				sb.Append("\n");
			}
			if ((int)item.CharacterStatModified == 4)
			{
				sb.Append(string.Format(GetText("itemEnergyRegeneration"), SpriteText("energy"), NumFormat(item.CharacterStatModifiedValue, showPlus: true)));
				sb.Append("\n");
			}
			if ((int)item.CharacterStatModified2 == 2)
			{
				sb.Append(string.Format(GetText("itemSpeed"), NumFormat(item.CharacterStatModifiedValue2, showPlus: true)));
				sb.Append("\n");
			}
			if ((int)item.CharacterStatModified2 == 4)
			{
				sb.Append(string.Format(GetText("itemEnergyRegeneration"), SpriteText("energy"), NumFormat(item.CharacterStatModifiedValue2, showPlus: true)));
				sb.Append("\n");
			}
		}

		private static void AppendAuraCurseBonuses(StringBuilder sb, ItemData item)
		{
			if ((Object)(object)item.AuracurseBonus1 != (Object)null && item.AuracurseBonusValue1 > 0 && (Object)(object)item.AuracurseBonus2 != (Object)null && item.AuracurseBonusValue2 > 0 && item.AuracurseBonusValue1 == item.AuracurseBonusValue2)
			{
				string arg = SpriteText(item.AuracurseBonus1.ACName) + SpriteText(item.AuracurseBonus2.ACName);
				sb.Append(string.Format(GetText("itemCharges"), arg, NumFormat(item.AuracurseBonusValue1, showPlus: true)));
				sb.Append("\n");
				return;
			}
			if ((Object)(object)item.AuracurseBonus1 != (Object)null && item.AuracurseBonusValue1 > 0)
			{
				sb.Append(string.Format(GetText("itemCharges"), SpriteText(item.AuracurseBonus1.ACName), NumFormat(item.AuracurseBonusValue1, showPlus: true)));
				sb.Append("\n");
			}
			if ((Object)(object)item.AuracurseBonus2 != (Object)null && item.AuracurseBonusValue2 > 0)
			{
				sb.Append(string.Format(GetText("itemCharges"), SpriteText(item.AuracurseBonus2.ACName), NumFormat(item.AuracurseBonusValue2, showPlus: true)));
				sb.Append("\n");
			}
		}

		private static void AppendImmunities(StringBuilder sb, ItemData item)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if ((Object)(object)item.AuracurseImmune1 != (Object)null)
			{
				stringBuilder.Append(ColorText("curse", SpriteText(item.AuracurseImmune1.Id)));
			}
			if ((Object)(object)item.AuracurseImmune2 != (Object)null)
			{
				stringBuilder.Append(ColorText("curse", SpriteText(item.AuracurseImmune2.Id)));
			}
			if (stringBuilder.Length > 0)
			{
				sb.Append(string.Format(GetText("cardsImmuneTo"), stringBuilder.ToString().TrimEnd(Array.Empty<char>())));
				sb.Append("\n");
			}
		}

		private static void AppendActivationTrigger(StringBuilder sb, ItemData item, BlessingDefinition def)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected I4, but got Unknown
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Invalid comparison between Unknown and I4
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)item.Activation == 0 || (int)item.Activation == 21)
			{
				return;
			}
			if (sb.Length > 0)
			{
				sb.Append("<line-height=15%><br></line-height>");
			}
			StringBuilder stringBuilder = new StringBuilder();
			EventActivation activation = item.Activation;
			EventActivation val = activation;
			switch (val - 1)
			{
			case 0:
				stringBuilder.Append(GetText("itemCombatStart"));
				break;
			case 16:
				stringBuilder.Append(GetText("itemCombatEnd"));
				break;
			case 2:
			case 21:
			case 23:
			case 38:
				if (item.RoundCycle > 1)
				{
					stringBuilder.Append(string.Format(GetText("itemEveryNRounds"), item.RoundCycle.ToString()));
				}
				else if (item.ExactRound == 1)
				{
					stringBuilder.Append(GetText("itemFirstTurn"));
				}
				else
				{
					stringBuilder.Append(GetText("itemEveryRound"));
				}
				break;
			case 1:
				if (item.RoundCycle > 1)
				{
					stringBuilder.Append(string.Format(GetText("itemEveryRoundRoundN"), item.RoundCycle.ToString()));
				}
				else
				{
					stringBuilder.Append(GetText("itemEveryRoundRound"));
				}
				break;
			case 18:
				stringBuilder.Append(GetText("itemDamageDone"));
				break;
			case 19:
				if (item.LowerOrEqualPercentHP < 100f)
				{
					stringBuilder.Append(string.Format(GetText("itemWhenDamagedBelow"), item.LowerOrEqualPercentHP + "%"));
				}
				else
				{
					stringBuilder.Append(GetText("itemWhenDamaged"));
				}
				break;
			case 8:
				stringBuilder.Append(GetText("itemWhenHitted"));
				break;
			case 9:
				stringBuilder.Append(GetText("itemWhenBlock"));
				break;
			case 13:
				stringBuilder.Append(GetText("itemHealDoneAction"));
				break;
			case 14:
				stringBuilder.Append(GetText("itemWhenHealed"));
				break;
			case 11:
				stringBuilder.Append(GetText("itemWhenEvade"));
				break;
			case 12:
				stringBuilder.Append(GetText("itemWhenEvaded"));
				break;
			case 24:
				stringBuilder.Append(GetText("itemWhenKilled"));
				break;
			case 34:
				stringBuilder.Append("When you kill an enemy");
				break;
			case 7:
				stringBuilder.Append("When you hit an enemy");
				break;
			case 37:
				stringBuilder.Append(GetText("itemWhenBlockReachesZero"));
				break;
			case 5:
				stringBuilder.Append(GetTextOrDefault("itemWhenDrawCard", "When you draw a card"));
				break;
			case 6:
			case 15:
			case 30:
				if ((int)item.CastedCardType > 0)
				{
					string arg = ColorText("gold", GetText(Enum.GetName(typeof(CardType), item.CastedCardType)));
					stringBuilder.Append(string.Format(GetText("itemWhenYouPlay"), arg));
				}
				else
				{
					stringBuilder.Append(string.Format(GetText("itemWhenYouPlay"), SpriteText("cards")));
				}
				break;
			case 22:
			{
				if (!((Object)(object)item.AuraCurseSetted != (Object)null))
				{
					break;
				}
				StringBuilder stringBuilder2 = new StringBuilder();
				stringBuilder2.Append(SpriteText(item.AuraCurseSetted.Id));
				if ((Object)(object)item.AuraCurseSetted2 != (Object)null)
				{
					stringBuilder2.Append(SpriteText(item.AuraCurseSetted2.Id));
					if ((Object)(object)item.AuraCurseSetted3 != (Object)null)
					{
						stringBuilder2.Append(SpriteText(item.AuraCurseSetted3.Id));
					}
				}
				stringBuilder.Append(string.Format(GetText("itemWhenYouApply"), ColorText("curse", stringBuilder2.ToString())));
				break;
			}
			default:
				if (item.Activation == AtOEndless.blessingCombatStart)
				{
					stringBuilder.Append(GetText("itemCombatStart"));
				}
				else if (item.Activation == AtOEndless.blessingBeginRound)
				{
					stringBuilder.Append(GetText("itemEveryRoundRound"));
				}
				break;
			}
			if (stringBuilder.Length > 0)
			{
				sb.Append("<size=-.15><color=#444>[");
				sb.Append(stringBuilder.ToString());
				sb.Append("]</color></size><br>");
			}
		}

		private static void AppendFrequencyLimit(StringBuilder sb, ItemData item, BlessingDefinition def)
		{
			if (item.TimesPerTurn > 0)
			{
				StringBuilder stringBuilder = new StringBuilder();
				switch (item.TimesPerTurn)
				{
				case 1:
					stringBuilder.Append(GetText("itemOncePerTurn"));
					break;
				case 2:
					stringBuilder.Append(GetText("itemTwicePerTurn"));
					break;
				case 3:
					stringBuilder.Append(GetText("itemThricePerTurn"));
					break;
				case 4:
					stringBuilder.Append(GetText("itemFourPerTurn"));
					break;
				case 5:
					stringBuilder.Append(GetText("itemFivePerTurn"));
					break;
				case 6:
					stringBuilder.Append(GetText("itemSixPerTurn"));
					break;
				case 7:
					stringBuilder.Append(GetText("itemSevenPerTurn"));
					break;
				case 8:
					stringBuilder.Append(GetText("itemEightPerTurn"));
					break;
				default:
					stringBuilder.Append($"{item.TimesPerTurn}x per turn");
					break;
				}
				if (stringBuilder.Length > 0)
				{
					sb.Append("<size=-.15><color=#444>[");
					sb.Append(stringBuilder.ToString());
					sb.Append("]</color></size><br>");
				}
			}
			if (item.TimesPerCombat > 0)
			{
				string value = string.Format(GetTextOrDefault("itemTimesPerCombat", "{0}x per combat"), item.TimesPerCombat);
				sb.Append("<size=-.15><color=#444>[");
				sb.Append(value);
				sb.Append("]</color></size><br>");
			}
		}

		private static void AppendConditionals(StringBuilder sb, ItemData item, BlessingDefinition def)
		{
			if (item.UsedEnergy)
			{
				sb.Append(string.Format(GetText("itemApplyForEnergyUsed"), ColorText("system", SpriteText("energy"))));
				sb.Append("\n");
			}
			if (item.EmptyHand)
			{
				sb.Append(GetText("itemWhenHandEmpty"));
				sb.Append(":<br>");
			}
		}

		private static void AppendEffects(StringBuilder sb, CardData card, ItemData item, BlessingDefinition def)
		{
			if (item.DrawCards > 0)
			{
				sb.Append(string.Format(GetText("cardsDraw"), ColorText("", NumFormat(item.DrawCards), SpriteText("card"))));
				sb.Append("<br>");
			}
			AppendHealEffects(sb, item);
			if (item.EnergyQuantity > 0)
			{
				sb.Append(string.Format(GetText("cardsGain"), ColorText("system", NumFormat(item.EnergyQuantity), SpriteText("energy"))));
				sb.Append("<br>");
			}
			AppendDamageEffects(sb, item);
			if (item.ChanceToDispel > 0 && item.ChanceToDispelNum != 0)
			{
				if (item.ChanceToDispel < 100)
				{
					sb.Append(string.Format(GetText("itemChanceToDispel"), ColorText("aura", NumFormat(item.ChanceToDispel, showPlus: false, percent: true)), ColorText("curse", NumFormat(item.ChanceToDispelNum))));
				}
				else if (item.ChanceToDispelNum == -1)
				{
					sb.Append(GetText("cardsDispelAll"));
				}
				else
				{
					sb.Append(string.Format(GetText("cardsDispel"), ColorText("curse", NumFormat(item.ChanceToDispelNum))));
				}
				sb.Append("\n");
			}
			if (item.ChanceToPurge > 0 && item.ChanceToPurgeNum != 0)
			{
				if (item.ChanceToPurge < 100)
				{
					sb.Append(string.Format(GetText("itemChanceToPurge"), ColorText("aura", NumFormat(item.ChanceToPurge, showPlus: false, percent: true)), ColorText("curse", NumFormat(item.ChanceToPurgeNum))));
				}
				else if (item.ChanceToPurgeNum == -1)
				{
					sb.Append(GetText("cardsPurgeAll"));
				}
				else
				{
					sb.Append(string.Format(GetText("cardsPurge"), ColorText("curse", NumFormat(item.ChanceToPurgeNum))));
				}
				sb.Append("\n");
			}
			AppendSpecificCurseDispel(sb, item);
			AppendAuraGains(sb, card, item);
			AppendAuraSelfGains(sb, item);
			AppendCardGeneration(sb, item);
		}

		private static void AppendHealEffects(StringBuilder sb, ItemData item)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (item.HealQuantity > 0)
			{
				string arg = ColorText("system", NumFormat(item.HealQuantity, showPlus: true));
				string healTextForTarget = GetHealTextForTarget(item.ItemTarget, item.Activation);
				sb.Append(string.Format(healTextForTarget, arg));
				sb.Append("<br>");
			}
			else if (item.HealQuantity < 0)
			{
				string arg2 = ColorText("damage", NumFormat(item.HealQuantity, showPlus: true));
				sb.Append(string.Format(GetText("itemLoseHPSelf"), arg2));
				sb.Append("<br>");
			}
			if (item.HealPercentQuantity > 0)
			{
				string arg3 = ColorText("system", NumFormat(item.HealPercentQuantity, showPlus: true, percent: true));
				string healTextForTarget2 = GetHealTextForTarget(item.ItemTarget, item.Activation);
				sb.Append(string.Format(healTextForTarget2, arg3));
				sb.Append("<br>");
			}
		}

		private static string GetHealTextForTarget(ItemTarget target, EventActivation activation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Invalid comparison between Unknown and I4
			if ((int)target == 3)
			{
				return GetText("itemRecoverHeroes");
			}
			if ((int)target == 0)
			{
				return ((int)activation == 25) ? GetText("itemResurrectHP") : GetText("itemRecoverSelf");
			}
			if ((int)target == 4)
			{
				return GetText("itemRecoverMonsters");
			}
			if ((int)target == 1)
			{
				return GetText("itemRecoverRandomHPHero");
			}
			if ((int)target == 2)
			{
				return GetText("itemRecoverRandomHPMonster");
			}
			if ((int)target == 8)
			{
				return GetText("itemRecoverLowestHPHero");
			}
			if ((int)target == 10)
			{
				return GetText("itemRecoverLowestHPMonster");
			}
			return GetText("itemRecoverSelf");
		}

		private static void AppendDamageEffects(StringBuilder sb, ItemData item)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			StringBuilder stringBuilder = new StringBuilder();
			if (item.DamageToTarget1 > 0)
			{
				stringBuilder.Append(ColorText("damage", NumFormat(item.DamageToTarget1), SpriteText(Enum.GetName(typeof(DamageType), item.DamageToTargetType1))));
			}
			if (item.DamageToTarget2 > 0)
			{
				stringBuilder.Append(ColorText("damage", NumFormat(item.DamageToTarget2), SpriteText(Enum.GetName(typeof(DamageType), item.DamageToTargetType2))));
			}
			if (stringBuilder.Length > 0)
			{
				string key = "cardsDealDamage";
				if ((int)item.ItemTarget == 4)
				{
					key = "dealDamageToAllMonsters";
				}
				else if ((int)item.ItemTarget == 3)
				{
					key = "dealDamageToAllHeroes";
				}
				sb.Append(string.Format(GetText(key), stringBuilder.ToString().TrimEnd(Array.Empty<char>())));
				sb.Append("\n");
			}
		}

		private static void AppendAuraGains(StringBuilder sb, CardData card, ItemData item)
		{
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Expected I4, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Invalid comparison between Unknown and I4
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Invalid comparison between Unknown and I4
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Invalid comparison between Unknown and I4
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = true;
			if ((Object)(object)item.AuracurseGain1 != (Object)null && item.AuracurseGainValue1 > 0)
			{
				bool isAura = item.AuracurseGain1.IsAura;
				stringBuilder.Append(ColorText(isAura ? "aura" : "curse", NumFormat(item.AuracurseGainValue1), SpriteText(item.AuracurseGain1.Id)));
				if (!isAura)
				{
					flag = false;
				}
			}
			if ((Object)(object)item.AuracurseGain2 != (Object)null && item.AuracurseGainValue2 > 0)
			{
				bool isAura2 = item.AuracurseGain2.IsAura;
				stringBuilder.Append(ColorText(isAura2 ? "aura" : "curse", NumFormat(item.AuracurseGainValue2), SpriteText(item.AuracurseGain2.Id)));
				if (!isAura2)
				{
					flag = false;
				}
			}
			if ((Object)(object)item.AuracurseGain3 != (Object)null && item.AuracurseGainValue3 > 0)
			{
				bool isAura3 = item.AuracurseGain3.IsAura;
				stringBuilder.Append(ColorText(isAura3 ? "aura" : "curse", NumFormat(item.AuracurseGainValue3), SpriteText(item.AuracurseGain3.Id)));
				if (!isAura3)
				{
					flag = false;
				}
			}
			if (stringBuilder.Length <= 0)
			{
				return;
			}
			string arg = stringBuilder.ToString().TrimEnd(Array.Empty<char>());
			ItemTarget itemTarget = item.ItemTarget;
			ItemTarget val = itemTarget;
			switch ((int)val)
			{
			case 4:
				sb.Append(string.Format(GetText("itemApplyEnemies"), arg));
				break;
			case 3:
				sb.Append(string.Format(GetText("itemApplyHeroes"), arg));
				break;
			case 1:
				sb.Append(string.Format(GetText("itemApplyRandomHero"), arg));
				break;
			case 2:
				sb.Append(string.Format(GetText("itemApplyRandomEnemy"), arg));
				break;
			case 8:
				sb.Append(string.Format(GetText("itemApplyLowestFlatHpHero"), arg));
				break;
			case 10:
				sb.Append(string.Format(GetText("itemApplyLowestFlatHpEnemy"), arg));
				break;
			case 7:
				sb.Append(string.Format(GetText("itemApplyHighestFlatHpHero"), arg));
				break;
			case 9:
				sb.Append(string.Format(GetText("itemApplyHighestFlatHpEnemy"), arg));
				break;
			case 13:
				sb.Append(string.Format(GetTextOrDefault("itemApplyFrontEnemy", "Front enemy suffers {0}"), arg));
				break;
			case 5:
				if ((int)card.TargetSide == 1 || (int)card.TargetSide == 3)
				{
					sb.Append(string.Format(GetText("cardsGrant"), arg));
				}
				else if ((int)card.TargetSide == 0)
				{
					sb.Append(string.Format(GetText("cardsApply"), arg));
				}
				else if (flag)
				{
					sb.Append(string.Format(GetText("cardsGrant"), arg));
				}
				else
				{
					sb.Append(string.Format(GetText("cardsApply"), arg));
				}
				break;
			default:
				if (flag)
				{
					sb.Append(string.Format(GetText("cardsGain"), arg));
				}
				else
				{
					sb.Append(string.Format(GetText("cardsSuffer"), arg));
				}
				break;
			}
			sb.Append("<br>");
		}

		private static void AppendAuraSelfGains(StringBuilder sb, ItemData item)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = true;
			if ((Object)(object)item.AuracurseGainSelf1 != (Object)null && item.AuracurseGainSelfValue1 > 0)
			{
				bool isAura = item.AuracurseGainSelf1.IsAura;
				stringBuilder.Append(ColorText(isAura ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue1), SpriteText(item.AuracurseGainSelf1.Id)));
				if (!isAura)
				{
					flag = false;
				}
			}
			if ((Object)(object)item.AuracurseGainSelf2 != (Object)null && item.AuracurseGainSelfValue2 > 0)
			{
				bool isAura2 = item.AuracurseGainSelf2.IsAura;
				stringBuilder.Append(ColorText(isAura2 ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue2), SpriteText(item.AuracurseGainSelf2.Id)));
				if (!isAura2)
				{
					flag = false;
				}
			}
			if ((Object)(object)item.AuracurseGainSelf3 != (Object)null && item.AuracurseGainSelfValue3 > 0)
			{
				bool isAura3 = item.AuracurseGainSelf3.IsAura;
				stringBuilder.Append(ColorText(isAura3 ? "aura" : "curse", NumFormat(item.AuracurseGainSelfValue3), SpriteText(item.AuracurseGainSelf3.Id)));
				if (!isAura3)
				{
					flag = false;
				}
			}
			if (stringBuilder.Length > 0)
			{
				if (flag)
				{
					sb.Append(string.Format(GetText("cardsGain"), stringBuilder.ToString().TrimEnd(Array.Empty<char>())));
				}
				else
				{
					sb.Append(string.Format(GetText("cardsSuffer"), stringBuilder.ToString().TrimEnd(Array.Empty<char>())));
				}
				sb.Append("<br>");
			}
		}

		private static void AppendCardGeneration(StringBuilder sb, ItemData item)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected I4, but got Unknown
			if ((Object)(object)item.CardToGain != (Object)null && item.CardNum > 0)
			{
				string text = ColorText("gold", item.CardToGain.CardName);
				string text2 = "";
				CardPlace cardPlace = item.CardPlace;
				CardPlace val = cardPlace;
				switch ((int)val)
				{
				case 5:
					text2 = GetTextOrDefault("cardAddToHand", "add to hand");
					break;
				case 1:
				case 2:
				case 3:
					text2 = GetTextOrDefault("cardAddToDeck", "shuffle into deck");
					break;
				case 6:
					text2 = GetTextOrDefault("cardCastImmediately", "and cast it");
					break;
				case 0:
					text2 = GetTextOrDefault("cardAddToDiscard", "add to discard");
					break;
				case 4:
					text2 = GetTextOrDefault("cardVanish", "vanish after use");
					break;
				}
				if (item.CardNum == 1)
				{
					sb.Append(string.Format(GetTextOrDefault("itemGainCard", "Gain {0} {1}"), text, text2));
				}
				else
				{
					sb.Append(string.Format(GetTextOrDefault("itemGainCards", "Gain {0}x {1} {2}"), item.CardNum, text, text2));
				}
				sb.Append("<br>");
			}
		}

		private static void AppendSpecificCurseDispel(StringBuilder sb, ItemData item)
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = new StringBuilder();
			if ((Object)(object)item.AuracurseHeal1 != (Object)null)
			{
				if (item.AuracurseHeal1.IsAura)
				{
					stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal1.Id)));
				}
				else
				{
					stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal1.Id)));
				}
			}
			if ((Object)(object)item.AuracurseHeal2 != (Object)null)
			{
				if (item.AuracurseHeal2.IsAura)
				{
					stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal2.Id)));
				}
				else
				{
					stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal2.Id)));
				}
			}
			if ((Object)(object)item.AuracurseHeal3 != (Object)null)
			{
				if (item.AuracurseHeal3.IsAura)
				{
					stringBuilder.Append(ColorText("aura", SpriteText(item.AuracurseHeal3.Id)));
				}
				else
				{
					stringBuilder2.Append(ColorText("curse", SpriteText(item.AuracurseHeal3.Id)));
				}
			}
			if (stringBuilder.Length > 0)
			{
				sb.Append(string.Format(GetText("cardsPurge"), stringBuilder.ToString().TrimEnd(Array.Empty<char>())));
				sb.Append("\n");
			}
			if (stringBuilder2.Length > 0)
			{
				sb.Append(string.Format(GetText("cardsDispel"), stringBuilder2.ToString().TrimEnd(Array.Empty<char>())));
				sb.Append("\n");
			}
		}

		private static string GetText(string key)
		{
			try
			{
				return Texts.Instance.GetText(key, "") ?? key;
			}
			catch
			{
				return key;
			}
		}

		private static string GetTextOrDefault(string key, string defaultValue)
		{
			try
			{
				string text = Texts.Instance.GetText(key, "");
				return (string.IsNullOrEmpty(text) || text == key) ? defaultValue : text;
			}
			catch
			{
				return defaultValue;
			}
		}

		private static string SpriteText(string spriteName)
		{
			if (string.IsNullOrEmpty(spriteName))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			string text = spriteName.ToLower().Replace(" ", "");
			switch (text)
			{
			case "block":
			case "card":
				stringBuilder.Append("<space=.2>");
				break;
			case "piercing":
				stringBuilder.Append("<space=.4>");
				break;
			case "bleed":
			case "bless":
				stringBuilder.Append("<space=.1>");
				break;
			default:
				stringBuilder.Append("<space=.3>");
				break;
			}
			stringBuilder.Append(" <space=-.2>");
			stringBuilder.Append("<size=+.1><sprite name=");
			stringBuilder.Append(text);
			stringBuilder.Append("></size>");
			switch (text)
			{
			case "bleed":
				stringBuilder.Append("<space=-.4>");
				break;
			case "card":
				stringBuilder.Append("<space=-.2>");
				break;
			case "powerful":
			case "fury":
				stringBuilder.Append("<space=-.1>");
				break;
			default:
				stringBuilder.Append("<space=-.2>");
				break;
			case "reinforce":
			case "fire":
				break;
			}
			return stringBuilder.ToString();
		}

		private static string NumFormat(int value, bool showPlus = false, bool percent = false)
		{
			string arg = ((showPlus && value > 0) ? "+" : "");
			string arg2 = (percent ? "%" : "");
			return $"{arg}{value}{arg2}";
		}

		private static string NumFormat(int value, string sprite)
		{
			return $"{value}{sprite}";
		}

		private static string ColorText(string type, params string[] parts)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<nobr>");
			switch (type.ToLower())
			{
			case "damage":
				stringBuilder.Append("<color=#B00A00>");
				break;
			case "heal":
				stringBuilder.Append("<color=#1E650F>");
				break;
			case "aura":
				stringBuilder.Append("<color=#263ABC>");
				break;
			case "curse":
				stringBuilder.Append("<color=#720070>");
				break;
			case "system":
			case "gold":
				stringBuilder.Append("<color=#5E3016>");
				break;
			default:
			{
				for (int i = 0; i < parts.Length; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(" ");
					}
					stringBuilder.Append(parts[i]);
				}
				stringBuilder.Append("</nobr> ");
				return stringBuilder.ToString();
			}
			}
			for (int j = 0; j < parts.Length; j++)
			{
				if (j > 0)
				{
					stringBuilder.Append(" ");
				}
				stringBuilder.Append(parts[j]);
			}
			stringBuilder.Append("</color></nobr> ");
			return stringBuilder.ToString();
		}

		private static string FormatDescription(string description)
		{
			if (string.IsNullOrEmpty(description))
			{
				return description;
			}
			StringBuilder stringBuilder = new StringBuilder(description);
			stringBuilder.Replace("<c>", "<color=#5E3016>");
			stringBuilder.Replace("</c>", "</color>");
			stringBuilder.Replace("<nb>", "<nobr>");
			stringBuilder.Replace("</nb>", "</nobr>");
			stringBuilder.Replace("<br1>", "<br><line-height=15%><br></line-height>");
			stringBuilder.Replace("<br2>", "<br><line-height=30%><br></line-height>");
			stringBuilder.Replace("<br3>", "<br><line-height=50%><br></line-height>");
			stringBuilder.Replace("\n", "<br>");
			return stringBuilder.ToString();
		}
	}
	public static class BlessingDescriptionHelper
	{
		private static Dictionary<string, BlessingDefinition> cardToBlessingDef = new Dictionary<string, BlessingDefinition>(StringComparer.OrdinalIgnoreCase);

		private static Dictionary<string, string> customDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		public static void RegisterBlessing(string cardId, BlessingDefinition def, BlessingUpgrade upgrade = null)
		{
			Plugin.LogInfo("[BlessingDescriptionHelper] RegisterBlessing called: cardId=" + cardId + ", def.Id=" + (def?.Id ?? "null") + ", upgrade=" + ((upgrade != null) ? "provided" : "null"));
			cardToBlessingDef[cardId] = def;
		}

		public static BlessingDefinition GetBlessingDef(string cardId)
		{
			if (cardToBlessingDef.TryGetValue(cardId, out var value))
			{
				return value;
			}
			return null;
		}

		public static bool HasCustomDescription(string cardId)
		{
			return customDescriptions.ContainsKey(cardId);
		}

		public static string GetCustomDescription(string cardId)
		{
			if (customDescriptions.TryGetValue(cardId, out var value))
			{
				return value;
			}
			return null;
		}

		public static void EnhanceDescription(CardData card)
		{
			if ((Object)(object)card == (Object)null || (Object)(object)card.Item == (Object)null)
			{
				return;
			}
			string id = card.Id;
			BlessingDefinition blessingDef = GetBlessingDef(id);
			if (blessingDef == null)
			{
				return;
			}
			Plugin.LogInfo("[BlessingDescriptionHelper] EnhanceDescription called for blessing: " + id);
			if (HasCustomDescription(id))
			{
				string customDescription = GetCustomDescription(id);
				customDescription = (card.DescriptionNormalized = FormatCustomDescription(customDescription));
				Globals.Instance.CardsDescriptionNormalized[id] = customDescription;
				Plugin.LogInfo("[BlessingDescriptionHelper] Applied custom description for " + id);
				return;
			}
			if (BlessingDescriptionGenerator.UseCustomDescriptions)
			{
				string text2 = BlessingDescriptionGenerator.GenerateDescription(card, blessingDef);
				if (!string.IsNullOrEmpty(text2))
				{
					card.DescriptionNormalized = text2;
					Globals.Instance.CardsDescriptionNormalized[id] = text2;
					Plugin.LogInfo("[BlessingDescriptionHelper] Applied generated description for " + id);
					return;
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			AddMissingDescriptionFragments(stringBuilder, card, blessingDef);
			if (stringBuilder.Length > 0)
			{
				string text3 = card.DescriptionNormalized ?? "";
				string value = (card.DescriptionNormalized = text3 + stringBuilder.ToString());
				Globals.Instance.CardsDescriptionNormalized[id] = value;
				Plugin.LogInfo($"[BlessingDescriptionHelper] Appended {stringBuilder.Length} chars to description for {id}");
			}
		}

		private static string FormatCustomDescription(string description)
		{
			if (string.IsNullOrEmpty(description))
			{
				return description;
			}
			StringBuilder stringBuilder = new StringBuilder(description);
			stringBuilder.Replace("<c>", "<color=#5E3016>");
			stringBuilder.Replace("</c>", "</color>");
			stringBuilder.Replace("<nb>", "<nobr>");
			stringBuilder.Replace("</nb>", "</nobr>");
			stringBuilder.Replace("<br1>", "<br><line-height=15%><br></line-height>");
			stringBuilder.Replace("<br2>", "<br><line-height=30%><br></line-height>");
			stringBuilder.Replace("<br3>", "<br><line-height=50%><br></line-height>");
			stringBuilder.Replace("\n", "<br>");
			return stringBuilder.ToString();
		}

		private static void AddMissingDescriptionFragments(StringBuilder sb, CardData card, BlessingDefinition def)
		{
			ItemData item = card.Item;
			if (!((Object)(object)item == (Object)null))
			{
			}
		}

		private static bool DescriptionContains(CardData card, string text)
		{
			if ((Object)(object)card == (Object)null || string.IsNullOrEmpty(card.DescriptionNormalized))
			{
				return false;
			}
			return card.DescriptionNormalized.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		public static string SpriteText(string spriteName)
		{
			return "<sprite name=" + spriteName + ">";
		}

		public static string DamageColor(string text)
		{
			return "<color=#B00A00>" + text + "</color>";
		}

		public static string HealColor(string text)
		{
			return "<color=#00B000>" + text + "</color>";
		}

		public static string AuraColor(string text)
		{
			return "<color=#5E3016>" + text + "</color>";
		}

		public static string SystemColor(string text)
		{
			return "<color=#111111>" + text + "</color>";
		}

		public static string FormatBonus(int value, bool showPlus = true)
		{
			if (showPlus && value > 0)
			{
				return $"+{value}";
			}
			return value.ToString();
		}

		public static string FormatPercent(int value, bool showPlus = true)
		{
			string arg = ((showPlus && value > 0) ? "+" : "");
			return $"{arg}{value}%";
		}

		public static void Clear()
		{
			Plugin.LogInfo($"[BlessingDescriptionHelper] Clear called - clearing {cardToBlessingDef.Count} blessing defs and {customDescriptions.Count} custom descriptions");
			cardToBlessingDef.Clear();
			customDescriptions.Clear();
			BlessingDescriptionGenerator.ClearCache();
		}
	}
	public static class BlessingPatchHelper
	{
		public static bool ShouldSkipDueToCache<TCache>(bool useCache, TCache cache, Func<TCache, bool> hasValue)
		{
			if (!AtOEndless.IsEndlessMode())
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && hasValue(cache))
			{
				return true;
			}
			return false;
		}

		public static int ApplyIntModifierWithCache(HeroData heroData, int currentResult, bool useCache, List<int> cache, Func<ItemData, int> getModifier)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return currentResult;
			}
			bool flag = false;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					int num = getModifier(cardData.Item);
					if (num != 0)
					{
						currentResult += num;
						flag = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag)
			{
				cache[0] = currentResult;
			}
			return currentResult;
		}

		public static float ApplyFloatModifierWithCache(HeroData heroData, float currentResult, bool useCache, List<float> cache, Func<ItemData, float> getModifier)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return currentResult;
			}
			bool flag = false;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					float num = getModifier(cardData.Item);
					if (num != 0f)
					{
						currentResult += num;
						flag = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag)
			{
				cache[0] = currentResult;
			}
			return currentResult;
		}

		public static int ApplyTypedIntModifierWithCache<TKey>(HeroData heroData, TKey key, int currentResult, bool useCache, Dictionary<TKey, int> cache, Func<ItemData, TKey, int> getModifier)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return currentResult;
			}
			bool flag = false;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					int num = getModifier(cardData.Item, key);
					if (num != 0)
					{
						currentResult += num;
						flag = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.ContainsKey(key) && flag)
			{
				cache[key] = currentResult;
			}
			return currentResult;
		}

		public static float ApplyTypedFloatModifierWithCache<TKey>(HeroData heroData, TKey key, float currentResult, bool useCache, Dictionary<TKey, float> cache, Func<ItemData, TKey, float> getModifier)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return currentResult;
			}
			bool flag = false;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					float num = getModifier(cardData.Item, key);
					if (num != 0f)
					{
						currentResult += num;
						flag = true;
					}
				}
			}
			if (Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.ContainsKey(key) && flag)
			{
				cache[key] = currentResult;
			}
			return currentResult;
		}

		public static int GetDamageFlatBonus(ItemData item, DamageType damageType)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			int num = 0;
			if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10)
			{
				num += item.DamageFlatBonusValue;
			}
			if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10)
			{
				num += item.DamageFlatBonusValue2;
			}
			if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10)
			{
				num += item.DamageFlatBonusValue3;
			}
			return num;
		}

		public static float GetDamagePercentBonus(ItemData item, DamageType damageType)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			float num = 0f;
			if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10)
			{
				num += item.DamagePercentBonusValue;
			}
			if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10)
			{
				num += item.DamagePercentBonusValue2;
			}
			if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10)
			{
				num += item.DamagePercentBonusValue3;
			}
			return num;
		}

		public static int GetResistBonus(ItemData item, DamageType damageType)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			int num = 0;
			if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10)
			{
				num += item.ResistModifiedValue1;
			}
			if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10)
			{
				num += item.ResistModifiedValue2;
			}
			if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10)
			{
				num += item.ResistModifiedValue3;
			}
			return num;
		}

		public static int GetStatBonus(ItemData item, CharacterStat stat)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			if (item.CharacterStatModified == stat)
			{
				num += item.CharacterStatModifiedValue;
			}
			if (item.CharacterStatModified2 == stat)
			{
				num += item.CharacterStatModifiedValue2;
			}
			if (item.CharacterStatModified3 == stat)
			{
				num += item.CharacterStatModifiedValue3;
			}
			return num;
		}

		public static void AddDamageDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result, bool isPercent)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null)
				{
					continue;
				}
				float num = (isPercent ? GetDamagePercentBonus(cardData.Item, damageType) : ((float)GetDamageFlatBonus(cardData.Item, damageType)));
				if (num != 0f)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += (int)num;
					}
					else
					{
						result[key] = (int)num;
					}
				}
			}
		}

		public static void AddResistDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null)
				{
					continue;
				}
				int resistBonus = GetResistBonus(cardData.Item, damageType);
				if (resistBonus != 0)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += resistBonus;
					}
					else
					{
						result[key] = resistBonus;
					}
				}
			}
		}

		public static void ApplyAuraCurseModifiersWithCache(HeroData heroData, Dictionary<string, int> result, bool useCache, Dictionary<string, int> cache)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			bool flag = false;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if (!((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null))
				{
					continue;
				}
				if ((Object)(object)cardData.Item.AuracurseBonus1 != (Object)null)
				{
					string id = cardData.Item.AuracurseBonus1.Id;
					if (result.ContainsKey(id))
					{
						result[id] += cardData.Item.AuracurseBonusValue1;
					}
					else
					{
						result[id] = cardData.Item.AuracurseBonusValue1;
					}
					flag = true;
				}
				if ((Object)(object)cardData.Item.AuracurseBonus2 != (Object)null)
				{
					string id2 = cardData.Item.AuracurseBonus2.Id;
					if (result.ContainsKey(id2))
					{
						result[id2] += cardData.Item.AuracurseBonusValue2;
					}
					else
					{
						result[id2] = cardData.Item.AuracurseBonusValue2;
					}
					flag = true;
				}
			}
			if (!(Object.op_Implicit((Object)(object)MatchManager.Instance) && useCache && cache.Count > 0 && flag))
			{
				return;
			}
			foreach (KeyValuePair<string, int> item in result)
			{
				cache[item.Key] = item.Value;
			}
		}
	}
	[HarmonyPatch]
	public static class BlessingEffectManager
	{
		public static T ApplyBlessingModifier<T>(T initialValue, HeroData heroData, Func<CardData, ItemData, T, T> modifier)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return initialValue;
			}
			T val = initialValue;
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					val = modifier(cardData, cardData.Item, val);
				}
			}
			return val;
		}

		public static bool HasBlessingImmunity(HeroData heroData, string auraCurseId)
		{
			Plugin.LogInfo($"[BlessingEffectManager] HasBlessingImmunity called. heroData={heroData}, auraCurseId={auraCurseId}", LogCategory.Blessings);
			if ((Object)(object)heroData == (Object)null)
			{
				return false;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if (!((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null))
				{
					continue;
				}
				AuraCurseData auracurseImmune = cardData.Item.AuracurseImmune1;
				if (!(((auracurseImmune != null) ? auracurseImmune.Id : null) == auraCurseId))
				{
					AuraCurseData auracurseImmune2 = cardData.Item.AuracurseImmune2;
					if (!(((auracurseImmune2 != null) ? auracurseImmune2.Id : null) == auraCurseId))
					{
						continue;
					}
				}
				return true;
			}
			return false;
		}

		public static List<string> GetBlessingImmunities(HeroData heroData)
		{
			List<string> list = new List<string>();
			if ((Object)(object)heroData == (Object)null)
			{
				return list;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null)
				{
					if ((Object)(object)cardData.Item.AuracurseImmune1 != (Object)null && !list.Contains(cardData.Item.AuracurseImmune1.Id))
					{
						list.Add(cardData.Item.AuracurseImmune1.Id);
					}
					if ((Object)(object)cardData.Item.AuracurseImmune2 != (Object)null && !list.Contains(cardData.Item.AuracurseImmune2.Id))
					{
						list.Add(cardData.Item.AuracurseImmune2.Id);
					}
				}
			}
			return list;
		}

		public static int GetMaxHPBonus(HeroData heroData)
		{
			return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.MaxHealth);
		}

		public static int GetHealFlatBonus(HeroData heroData)
		{
			return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.HealFlatBonus);
		}

		public static float GetHealPercentBonus(HeroData heroData)
		{
			return ApplyBlessingModifier(0f, heroData, (CardData card, ItemData item, float total) => total + item.HealPercentBonus);
		}

		public static int GetHealReceivedFlatBonus(HeroData heroData)
		{
			return ApplyBlessingModifier(0, heroData, (CardData card, ItemData item, int total) => total + item.HealReceivedFlatBonus);
		}

		public static float GetHealReceivedPercentBonus(HeroData heroData)
		{
			return ApplyBlessingModifier(0f, heroData, (CardData card, ItemData item, float total) => total + item.HealReceivedPercentBonus);
		}

		public static int GetDamageFlatBonus(HeroData heroData, DamageType damageType)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Invalid comparison between Unknown and I4
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Invalid comparison between Unknown and I4
				int num = 0;
				if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10)
				{
					num += item.DamageFlatBonusValue;
				}
				if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10)
				{
					num += item.DamageFlatBonusValue2;
				}
				if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10)
				{
					num += item.DamageFlatBonusValue3;
				}
				return total + num;
			});
		}

		public static float GetDamagePercentBonus(HeroData heroData, DamageType damageType)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ApplyBlessingModifier(0f, heroData, delegate(CardData card, ItemData item, float total)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Invalid comparison between Unknown and I4
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Invalid comparison between Unknown and I4
				float num = 0f;
				if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10)
				{
					num += item.DamagePercentBonusValue;
				}
				if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10)
				{
					num += item.DamagePercentBonusValue2;
				}
				if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10)
				{
					num += item.DamagePercentBonusValue3;
				}
				return total + num;
			});
		}

		public static void AddDamageDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result, bool isPercent)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Invalid comparison between Unknown and I4
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Invalid comparison between Unknown and I4
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Invalid comparison between Unknown and I4
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null)
				{
					continue;
				}
				float num = 0f;
				ItemData item = cardData.Item;
				if (isPercent)
				{
					if (item.DamagePercentBonus == damageType || (int)item.DamagePercentBonus == 10)
					{
						num += item.DamagePercentBonusValue;
					}
					if (item.DamagePercentBonus2 == damageType || (int)item.DamagePercentBonus2 == 10)
					{
						num += item.DamagePercentBonusValue2;
					}
					if (item.DamagePercentBonus3 == damageType || (int)item.DamagePercentBonus3 == 10)
					{
						num += item.DamagePercentBonusValue3;
					}
				}
				else
				{
					if (item.DamageFlatBonus == damageType || (int)item.DamageFlatBonus == 10)
					{
						num += (float)item.DamageFlatBonusValue;
					}
					if (item.DamageFlatBonus2 == damageType || (int)item.DamageFlatBonus2 == 10)
					{
						num += (float)item.DamageFlatBonusValue2;
					}
					if (item.DamageFlatBonus3 == damageType || (int)item.DamageFlatBonus3 == 10)
					{
						num += (float)item.DamageFlatBonusValue3;
					}
				}
				if (num != 0f)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += (int)num;
					}
					else
					{
						result[key] = (int)num;
					}
				}
			}
		}

		public static int GetResistanceBonus(HeroData heroData, DamageType damageType)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Invalid comparison between Unknown and I4
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Invalid comparison between Unknown and I4
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Invalid comparison between Unknown and I4
				int num = 0;
				if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10)
				{
					num += item.ResistModifiedValue1;
				}
				if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10)
				{
					num += item.ResistModifiedValue2;
				}
				if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10)
				{
					num += item.ResistModifiedValue3;
				}
				return total + num;
			});
		}

		public static void AddResistanceDictionaryEntries(HeroData heroData, DamageType damageType, Dictionary<string, int> result)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Invalid comparison between Unknown and I4
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null)
				{
					continue;
				}
				int num = 0;
				ItemData item = cardData.Item;
				if (item.ResistModified1 == damageType || (int)item.ResistModified1 == 10)
				{
					num += item.ResistModifiedValue1;
				}
				if (item.ResistModified2 == damageType || (int)item.ResistModified2 == 10)
				{
					num += item.ResistModifiedValue2;
				}
				if (item.ResistModified3 == damageType || (int)item.ResistModified3 == 10)
				{
					num += item.ResistModifiedValue3;
				}
				if (num != 0)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += num;
					}
					else
					{
						result[key] = num;
					}
				}
			}
		}

		public static Dictionary<string, int> GetAuraCurseModifiers(HeroData heroData)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			if ((Object)(object)heroData == (Object)null)
			{
				return dictionary;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) == (Object)null)
				{
					continue;
				}
				ItemData item = cardData.Item;
				if ((Object)(object)item.AuracurseBonus1 != (Object)null)
				{
					string id = item.AuracurseBonus1.Id;
					if (dictionary.ContainsKey(id))
					{
						dictionary[id] += item.AuracurseBonusValue1;
					}
					else
					{
						dictionary[id] = item.AuracurseBonusValue1;
					}
				}
				if ((Object)(object)item.AuracurseBonus2 != (Object)null)
				{
					string id2 = item.AuracurseBonus2.Id;
					if (dictionary.ContainsKey(id2))
					{
						dictionary[id2] += item.AuracurseBonusValue2;
					}
					else
					{
						dictionary[id2] = item.AuracurseBonusValue2;
					}
				}
			}
			return dictionary;
		}

		public static void MergeAuraCurseModifiers(HeroData heroData, Dictionary<string, int> result)
		{
			Dictionary<string, int> auraCurseModifiers = GetAuraCurseModifiers(heroData);
			foreach (KeyValuePair<string, int> item in auraCurseModifiers)
			{
				if (result.ContainsKey(item.Key))
				{
					result[item.Key] += item.Value;
				}
				else
				{
					result[item.Key] = item.Value;
				}
			}
		}

		public static int GetStatModifier(HeroData heroData, CharacterStat stat)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ApplyBlessingModifier(0, heroData, delegate(CardData card, ItemData item, int total)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				int num = 0;
				if (item.CharacterStatModified == stat)
				{
					num += item.CharacterStatModifiedValue;
				}
				if (item.CharacterStatModified2 == stat)
				{
					num += item.CharacterStatModifiedValue2;
				}
				if (item.CharacterStatModified3 == stat)
				{
					num += item.CharacterStatModifiedValue3;
				}
				return total + num;
			});
		}

		public static void AddHealPercentDictionaryEntries(HeroData heroData, Dictionary<string, int> result)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null && (double)cardData.Item.HealPercentBonus != 0.0)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += (int)cardData.Item.HealPercentBonus;
					}
					else
					{
						result[key] = (int)cardData.Item.HealPercentBonus;
					}
				}
			}
		}

		public static void AddHealFlatDictionaryEntries(HeroData heroData, Dictionary<string, int> result)
		{
			if ((Object)(object)heroData == (Object)null)
			{
				return;
			}
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, true);
				if ((Object)(object)((cardData != null) ? cardData.Item : null) != (Object)null && cardData.Item.HealFlatBonus != 0)
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(cardData.CardName);
					stringBuilder.Append("_card");
					string key = stringBuilder.ToString();
					if (result.ContainsKey(key))
					{
						result[key] += cardData.Item.HealFlatBonus;
					}
					else
					{
						result[key] = cardData.Item.HealFlatBonus;
					}
				}
			}
		}

		public static CardData GetRandomBlessing(List<string> ignore = null)
		{
			Plugin.LogInfo($"[Blessings] GetRandomBlessing: availableBlessings.Count = {AtOEndless.availableBlessings?.Count ?? 0}", LogCategory.Blessings);
			List<string> list = new List<string>(AtOEndless.availableBlessings);
			Plugin.LogInfo($"[Blessings] Initial pool: {list.Count} blessings", LogCategory.Blessings);
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				CardData cardData = Globals.Instance.GetCardData(activeBlessing, false);
				cardData = Functions.GetCardDataFromCardData(cardData, "");
				if ((Object)(object)cardData != (Object)null && list.Contains(cardData.Id))
				{
					list.Remove(cardData.Id);
				}
			}
			Plugin.LogInfo($"[Blessings] After removing active: {list.Count} blessings", LogCategory.Blessings);
			if (ignore != null)
			{
				foreach (string item in ignore)
				{
					CardData cardData2 = Globals.Instance.GetCardData(item, false);
					cardData2 = Functions.GetCardDataFromCardData(cardData2, "");
					if ((Object)(object)cardData2 != (Object)null && list.Contains(cardData2.Id))
					{
						list.Remove(cardData2.Id);
					}
				}
			}
			Plugin.LogInfo($"[Blessings] After removing ignored: {list.Count} blessings", LogCategory.Blessings);
			if (list.Count > 0)
			{
				list.Sort();
				int townTier = AtOManager.Instance.GetTownTier();
				string text = SelectWeightedBlessing(list, townTier);
				Plugin.LogInfo("[Blessings] Selected: " + text, LogCategory.Blessings);
				CardData val = Globals.Instance.GetCardData(text, false);
				Plugin.LogInfo("[Blessings] GetCardData returned: " + (((val != null) ? val.Id : null) ?? "NULL"));
				if (townTier == 0)
				{
					val = Functions.GetCardDataFromCardData(val, "");
					if ((Object)(object)val != (Object)null)
					{
						text = val.Id;
					}
				}
				else if (townTier == 1)
				{
					val = Functions.GetCardDataFromCardData(val, "A");
					if ((Object)(object)val != (Object)null)
					{
						text = val.Id;
					}
				}
				else if (townTier == 2)
				{
					val = Functions.GetCardDataFromCardData(val, "B");
					if ((Object)(object)val != (Object)null)
					{
						text = val.Id;
					}
				}
				else if (townTier >= 3)
				{
					val = Functions.GetCardDataFromCardData(val, "RARE");
					if ((Object)(object)val != (Object)null)
					{
						text = val.Id;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Globals.Instance.GetCardData(text, false);
				}
				return val;
			}
			return null;
		}

		private static string SelectWeightedBlessing(List<string> blessingPool, int tier)
		{
			if (blessingPool == null || blessingPool.Count == 0)
			{
				return null;
			}
			if (blessingPool.Count == 1)
			{
				return blessingPool[0];
			}
			List<int> list = new List<int>(blessingPool.Count);
			int num = 0;
			foreach (string item in blessingPool)
			{
				BlessingDefinition blessingByCardId = BlessingLoader.GetBlessingByCardId(item);
				float blessingWeight = BlessingLoader.GetBlessingWeight(blessingByCardId, tier);
				int num2 = (int)(blessingWeight * 100f);
				list.Add(num2);
				num += num2;
			}
			if (num <= 0)
			{
				int randomIntRange = MapManager.Instance.GetRandomIntRange(0, blessingPool.Count);
				return blessingPool[randomIntRange];
			}
			int randomIntRange2 = MapManager.Instance.GetRandomIntRange(0, num);
			int num3 = 0;
			for (int i = 0; i < blessingPool.Count; i++)
			{
				num3 += list[i];
				if (randomIntRange2 < num3)
				{
					BlessingDefinition blessingByCardId2 = BlessingLoader.GetBlessingByCardId(blessingPool[i]);
					Plugin.LogInfo(string.Format("[Blessings] Weighted selection: {0} (rarity={1}, weight={2}/{3}, tier={4})", blessingPool[i], blessingByCardId2?.Rarity ?? "?", list[i], num, tier));
					return blessingPool[i];
				}
			}
			return blessingPool[blessingPool.Count - 1];
		}

		public static void BeginMatchBlessings()
		{
			Hero[] value = Traverse.Create((object)MatchManager.Instance).Field("TeamHero").GetValue<Hero[]>();
			NPC[] value2 = Traverse.Create((object)MatchManager.Instance).Field("TeamNPC").GetValue<NPC[]>();
			foreach (string item in AtOEndless.activeBlessings.ToList())
			{
				CardData cardData = MatchManager.Instance.GetCardData(item, true);
			}
		}

		public static void CombatStartBlessings()
		{
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings called.", LogCategory.Blessings);
			Traverse val = Traverse.Create((object)MatchManager.Instance);
			Hero[] value = val.Field("TeamHero").GetValue<Hero[]>();
			Hero val2 = null;
			int num = -1;
			for (int i = 0; i < value.Length; i++)
			{
				if (value[i] != null && ((Character)value[i]).Alive)
				{
					val2 = value[i];
					num = i;
					break;
				}
			}
			if (val2 == null)
			{
				Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: No alive heroes, skipping all blessings", LogCategory.Blessings);
				return;
			}
			Hero value2 = val.Field("theHero").GetValue<Hero>();
			int value3 = val.Field("heroActive").GetValue<int>();
			val.Field("theHero").SetValue((object)val2);
			val.Field("heroActive").SetValue((object)num);
			Plugin.LogInfo($"[BlessingEffectManager] CombatStartBlessings: Set temporary theHero to {((Character)val2).Id}, heroActive to {num}", LogCategory.Blessings);
			try
			{
				foreach (string item in AtOEndless.activeBlessings.ToList())
				{
					CardData cardData = MatchManager.Instance.GetCardData(item, true);
					if ((Object)(object)cardData == (Object)null)
					{
						Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: CardData is null for blessing " + item + ", skipping", LogCategory.Blessings);
					}
					else if ((Object)(object)cardData.Item != (Object)null && cardData.Item.Activation == AtOEndless.blessingCombatStart)
					{
						Plugin.LogInfo("[BlessingEffectManager] Activating combat start blessing: " + item, LogCategory.Blessings);
						CardData val3 = Object.Instantiate<CardData>(cardData);
						val3.EnergyCost = 0;
						val3.Vanish = true;
						val3.CardClass = (CardClass)7;
						MatchManager.Instance.GenerateNewCard(1, item, false, (CardPlace)4, (CardData)null, (CardData)null, -1, true, 0, (CopyConfig)null);
						((Character)val2).DoItem(AtOEndless.blessingCombatStart, val3, val3.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
						Object.Destroy((Object)(object)val3);
					}
				}
			}
			finally
			{
				val.Field("theHero").SetValue((object)value2);
				val.Field("heroActive").SetValue((object)value3);
				Plugin.LogInfo("[BlessingEffectManager] CombatStartBlessings: Restored original theHero and heroActive", LogCategory.Blessings);
			}
		}

		public static void BeginRoundBlessings()
		{
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Invalid comparison between Unknown and I4
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Invalid comparison between Unknown and I4
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Invalid comparison between Unknown and I4
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Invalid comparison between Unknown and I4
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings called.", LogCategory.Blessings);
			Traverse val = Traverse.Create((object)MatchManager.Instance);
			Hero[] value = val.Field("TeamHero").GetValue<Hero[]>();
			NPC[] value2 = val.Field("TeamNPC").GetValue<NPC[]>();
			Hero val2 = null;
			int num = -1;
			for (int i = 0; i < value.Length; i++)
			{
				if (value[i] != null && ((Character)value[i]).Alive)
				{
					val2 = value[i];
					num = i;
					break;
				}
			}
			if (val2 == null)
			{
				Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: No alive heroes, skipping all blessings", LogCategory.Blessings);
				return;
			}
			Hero value3 = val.Field("theHero").GetValue<Hero>();
			int value4 = val.Field("heroActive").GetValue<int>();
			val.Field("theHero").SetValue((object)val2);
			val.Field("heroActive").SetValue((object)num);
			Plugin.LogInfo($"[BlessingEffectManager] BeginRoundBlessings: Set temporary theHero to {((Character)val2).Id}, heroActive to {num}", LogCategory.Blessings);
			try
			{
				foreach (string item in AtOEndless.activeBlessings.ToList())
				{
					CardData cardData = MatchManager.Instance.GetCardData(item, true);
					if ((Object)(object)cardData == (Object)null)
					{
						Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: CardData is null for blessing " + item + ", skipping", LogCategory.Blessings);
					}
					else
					{
						if (!((Object)(object)cardData.Item != (Object)null) || cardData.Item.Activation != AtOEndless.blessingBeginRound)
						{
							continue;
						}
						if ((int)cardData.Item.ItemTarget == 0)
						{
							for (int j = 0; j < value.Length; j++)
							{
								if (value[j] != null && ((Character)value[j]).Alive)
								{
									((Character)value[j]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
								}
							}
						}
						else if ((int)cardData.Item.ItemTarget == 1)
						{
							List<int> list = new List<int>();
							for (int k = 0; k < value.Length; k++)
							{
								if (value[k] != null && ((Character)value[k]).Alive)
								{
									list.Add(k);
								}
							}
							int randomIntRange = MatchManager.Instance.GetRandomIntRange(0, list.Count, "default", "");
							int num2 = list[randomIntRange];
							((Character)value[num2]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
						}
						else if ((int)cardData.Item.ItemTarget == 6)
						{
							for (int l = 0; l < value2.Length; l++)
							{
								if (value2[l] != null && ((Character)value2[l]).Alive)
								{
									((Character)value2[l]).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
								}
							}
						}
						else if ((int)cardData.Item.ItemTarget == 2)
						{
							List<int> list2 = new List<int>();
							for (int m = 0; m < value2.Length; m++)
							{
								if (value2[m] != null && ((Character)value2[m]).Alive)
								{
									list2.Add(m);
								}
							}
							if (list2.Count > 0)
							{
								int randomIntRange2 = MatchManager.Instance.GetRandomIntRange(0, list2.Count, "default", "");
								int num3 = list2[randomIntRange2];
								((Character)val2).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)(object)value2[num3], 0, "", 0, (CardData)null, false);
							}
						}
						else
						{
							((Character)val2).DoItem(AtOEndless.blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
						}
					}
				}
			}
			finally
			{
				val.Field("theHero").SetValue((object)value3);
				val.Field("heroActive").SetValue((object)value4);
				Plugin.LogInfo("[BlessingEffectManager] BeginRoundBlessings: Restored original theHero and heroActive", LogCategory.Blessings);
			}
		}

		public static void ApplyCombatStartBlessingsToNPC(NPC npc)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (npc == null || !AtOEndless.IsEndlessMode())
			{
				return;
			}
			ApplyCorruptionToNPC(npc);
			foreach (string activeBlessing in AtOEndless.activeBlessings)
			{
				MatchManager instance = MatchManager.Instance;
				CardData val = ((instance != null) ? instance.GetCardData(activeBlessing, true) : null);
				if (!((Object)(object)((val != null) ? val.Item : null) == (Object)null) && val.Item.Activation == AtOEndless.blessingCombatStart)
				{
					ItemTarget itemTarget = val.Item.ItemTarget;
					if ((int)itemTarget == 4 || (int)itemTarget == 6 || (int)itemTarget == 2)
					{
						((Character)npc).DoItem(AtOEndless.blessingCombatStart, val, val.Item.Id, (Character)null, 0, "", 0, (CardData)null, false);
					}
				}
			}
		}

		public static void ApplyCorruptionToNPC(NPC npc)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			if (npc == null || (Object)(object)MatchManager.Instance == (Object)null)
			{
				return;
			}
			ItemData corruptionItem = MatchManager.Instance.corruptionItem;
			string corruptionCardId = MatchManager.Instance.corruptionCardId;
			if (!((Object)(object)corruptionItem == (Object)null) && !string.IsNullOrEmpty(corruptionCardId) && (int)corruptionItem.Activation == 27)
			{
				CardData cardData = MatchManager.Instance.GetCardData(corruptionCardId, true);
				if (!((Object)(object)cardData == (Object)null))
				{
					((Character)npc).DoItem((EventActivation)27, cardData, corruptionItem.Id, (Character)null, 0, "", 0, (CardData)null, false);
					NPCData npcData = ((Character)npc).NpcData;
					Plugin.LogInfo("Applied corruption combat start to newly spawned NPC " + ((npcData != null) ? npcData.NPCName : null), LogCategory.Blessings);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CardVertical), "fMouseEnter")]
		public static bool CardVertical_fMouseEnter_Prefix(CardVertical __instance)
		{
			if ((Object)(object)__instance.cardData == (Object)null)
			{
				Plugin.LogInfo("[BlessingEffectManager] CardVertical.fMouseEnter skipped - cardData is null", LogCategory.Blessings);
				return false;
			}
			return true;
		}
	}
	public static class BlessingLoader
	{
		private static readonly string BlessingsFolder = "Blessings";

		private static List<BlessingDefinition> loadedBlessings = new List<BlessingDefinition>();

		private static Dictionary<string, BlessingDefinition> blessingLookup = new Dictionary<string, BlessingDefinition>();

		private static Dictionary<string, CardData> createdCards = new Dictionary<string, CardData>();

		private static List<Object> _createdScriptableObjects = new List<Object>();

		public static void LoadAllBlessings()
		{
			Plugin.LogInfo("[BlessingLoader] LoadAllBlessings called", LogCategory.Blessings);
			loadedBlessings.Clear();
			blessingLookup.Clear();
			LoadEmbeddedBlessings();
			LoadExternalBlessings();
			Plugin.LogInfo($"Loaded {loadedBlessings.Count} total blessings ({blessingLookup.Count} unique IDs)", LogCategory.Blessings);
		}

		private static void LoadEmbeddedBlessings()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				Plugin.LogInfo($"[BlessingLoader] Assembly has {manifestResourceNames.Length} embedded resources:", LogCategory.Blessings);
				string[] array = manifestResourceNames;
				foreach (string text in array)
				{
					Plugin.LogInfo("[BlessingLoader]   - " + text, LogCategory.Blessings);
				}
				List<string> list = manifestResourceNames.Where((string r) => r.StartsWith("AtOEndless.Data.Blessings.") && r.EndsWith(".json")).ToList();
				Plugin.LogInfo($"[BlessingLoader] Found {list.Count} blessing JSON resources", LogCategory.Blessings);
				foreach (string item in list)
				{
					try
					{
						using Stream stream = executingAssembly.GetManifestResourceStream(item);
						if (stream == null)
						{
							Plugin.LogWarning("[BlessingLoader] Could not open stream for " + item);
							continue;
						}
						using StreamReader streamReader = new StreamReader(stream);
						string json = streamReader.ReadToEnd();
						LoadBlessingJson(json, item);
					}
					catch (Exception ex)
					{
						Plugin.LogWarning("[BlessingLoader] Error loading " + item + ": " + ex.Message);
					}
				}
				Plugin.LogInfo($"[BlessingLoader] Loaded {loadedBlessings.Count} blessings from embedded resources", LogCategory.Blessings);
			}
			catch (Exception ex2)
			{
				Plugin.LogInfo("[BlessingLoader] Error loading embedded blessings: " + ex2.Message, LogCategory.Blessings);
				Plugin.LogInfo("[BlessingLoader] Stack trace: " + ex2.StackTrace, LogCategory.Blessings);
			}
		}

		private static void LoadExternalBlessings()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, BlessingsFolder);
			if (!Directory.Exists(text))
			{
				Plugin.LogInfo("Blessings folder not found at " + text + ", creating it...", LogCategory.Blessings);
				Directory.CreateDirectory(text);
				return;
			}
			int count = loadedBlessings.Count;
			string[] files = Directory.GetFiles(text, "*.json");
			foreach (string text2 in files)
			{
				try
				{
					LoadBlessingFile(text2);
				}
				catch (Exception ex)
				{
					Plugin.LogInfo("Error loading blessing file " + text2 + ": " + ex.Message, LogCategory.Blessings);
				}
			}
			string[] directories = Directory.GetDirectories(text);
			foreach (string path in directories)
			{
				string fileName = Path.GetFileName(path);
				Plugin.LogInfo("[BlessingLoader] Scanning subdirectory: