Decompiled source of AtOEndlessCompat v1.0.15

plugins/AtOEndlessCompat/com.corgan.AtOEndless.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
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 BattleMatch;
using BepInEx;
using BepInEx.Logging;
using Cards;
using Cards.Data;
using Cards.Utility;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.UIElements.Collections;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("com.corgan.AtOEndless")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.15.0")]
[assembly: AssemblyInformationalVersion("1.0.15")]
[assembly: AssemblyProduct("AtOEndless")]
[assembly: AssemblyTitle("com.corgan.AtOEndless")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.15.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AtOEndless
{
	[Serializable]
	public class AtOEndlessSaveData
	{
		public HashSet<string> activeBlessings = new HashSet<string>();

		public void FillData()
		{
			Plugin.LogInfo("SET ACTIVE BLESSINGS: " + string.Join(", ", AtOEndless.activeBlessings));
			activeBlessings = AtOEndless.activeBlessings;
		}

		public void LoadData()
		{
			AtOEndless.activeBlessings = activeBlessings;
			Plugin.LogInfo("GET ACTIVE BLESSINGS: " + string.Join(", ", activeBlessings));
		}
	}
	public class AtOEndlessSaveManager : MonoBehaviourPunCallbacks
	{
		private PhotonView photonView;

		public AtOEndlessSaveData endlessData = new AtOEndlessSaveData();

		public void CreateView()
		{
			photonView = PhotonView.Get((Component)(object)this);
		}

		public void SendData()
		{
			Plugin.LogInfo("SEND ACTIVE BLESSINGS: " + string.Join(", ", endlessData.activeBlessings));
			photonView.RPC("SendDataCo", (RpcTarget)0, new object[1] { Functions.CompressString(JsonHelper.ToJson<string>(endlessData.activeBlessings.ToArray())) });
		}

		[PunRPC]
		public void SendDataCo(string activeBlessings)
		{
			endlessData.activeBlessings = JsonHelper.FromJson<string>(Functions.DecompressString(activeBlessings)).ToHashSet();
			Plugin.LogInfo("SENDCO ACTIVE BLESSINGS: " + string.Join(", ", endlessData.activeBlessings));
			endlessData.LoadData();
		}

		public void FillData(BinaryFormatter binaryFormatter, CryptoStream cryptoStream)
		{
			endlessData.FillData();
			binaryFormatter.Serialize(cryptoStream, endlessData);
			if (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.IsMaster())
			{
				Plugin.LogInfo("SEND DATA FILL");
				SendData();
			}
		}

		public void LoadData(CryptoStream cryptoStream)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			endlessData = (AtOEndlessSaveData)binaryFormatter.Deserialize(cryptoStream);
			endlessData.LoadData();
			if (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.IsMaster())
			{
				Plugin.LogInfo("SEND DATA LOAD");
				SendData();
			}
		}
	}
	[HarmonyPatch]
	public class AtOEndless
	{
		public static HashSet<string> activeBlessings = new HashSet<string>();

		public static List<string> availableBlessings = new List<string>();

		public static CardType blessingCardType = (CardType)(Enum.GetValues(typeof(CardType)).Cast<CardType>().Max() + 1);

		public static EventActivation blessingCombatStart = (EventActivation)(Enum.GetValues(typeof(EventActivation)).Cast<EventActivation>().Max() + 1);

		public static EventActivation blessingBeginRound = (EventActivation)(Enum.GetValues(typeof(EventActivation)).Cast<EventActivation>().Max() + 2);

		public static AtOEndlessSaveManager EndlessSaveManager;

		public static bool refreshed = false;

		public static Dictionary<Zone, string> portalStrings = new Dictionary<Zone, string>
		{
			{
				(Zone)0,
				"a grassy"
			},
			{
				(Zone)3,
				"an icy"
			},
			{
				(Zone)2,
				"a swampy"
			},
			{
				(Zone)1,
				"a molten"
			},
			{
				(Zone)12,
				"a sandy"
			},
			{
				(Zone)14,
				"a salty"
			},
			{
				(Zone)4,
				"a cosmic"
			}
		};

		public static List<string> blessingCards = new List<string>(21)
		{
			"armageddon", "chaoticwind", "coldfront", "deathgrip", "empower", "firecrackers", "heavenlyarmaments", "hexproof", "ironclad", "lanternfestival",
			"lavabursts", "livingforest", "poisonfields", "putrefaction", "rosegarden", "sacredground", "subzero", "thegrinch", "thunderstorm", "upwind",
			"vigorous"
		};

		public static Dictionary<Zone, List<string>> RemoveRequirementsByZone = new Dictionary<Zone, List<string>>
		{
			{
				(Zone)0,
				new List<string>(1) { "treasurehuntii" }
			},
			{
				(Zone)3,
				new List<string>(1) { "darkdeal" }
			},
			{
				(Zone)1,
				new List<string>(5) { "armblowtorch", "armchargedrod", "armcoolingengine", "armdisclauncher", "armsmallcannon" }
			},
			{
				(Zone)2,
				new List<string>()
			},
			{
				(Zone)12,
				new List<string>(3) { "ulmininportal", "ulminindown", "riftulmi61" }
			},
			{
				(Zone)14,
				new List<string>(6) { "sahtidown", "sahtipolizonevent", "sahtiship", "dreadroom", "dreadup", "dreadmastcannon" }
			},
			{
				(Zone)4,
				new List<string>()
			}
		};

		public static Dictionary<Zone, List<string>> AddRequirementsByZone = new Dictionary<Zone, List<string>>
		{
			{
				(Zone)0,
				new List<string>(6) { "crossroadnorth", "crossroadsouth", "caravannopay", "fungamemill", "riftsen47", "riftsen48" }
			},
			{
				(Zone)3,
				new List<string>(3) { "boatfaenlor", "riftfaen42", "riftfaen43" }
			},
			{
				(Zone)1,
				new List<string>(4) { "lavacascade", "goblinnorth", "riftvelka39", "riftvelka40" }
			},
			{
				(Zone)2,
				new List<string>(5) { "boatup", "boatcenter", "boatdown", "riftaqua46", "riftaqua47" }
			},
			{
				(Zone)12,
				new List<string>(3) { "ulmininup", "riftulmi60", "riftulmi61" }
			},
			{
				(Zone)14,
				new List<string>(6) { "sahtiup", "dreaddown", "sahtipirateking", "sahtipolizon", "riftsahti67", "riftsahti68" }
			},
			{
				(Zone)4,
				new List<string>(4) { "voidnorth", "voidnorthpass", "voidsouth", "voidsouthpass" }
			}
		};

		public static string[] zoneStartNodes = new string[7] { "sen_0", "faen_0", "aqua_0", "velka_0", "ulmin_0", "sahti_0", "voidlow_0" };

		private static CardDataNew GetCardSource(CardRealtimeData cardData)
		{
			if (!(cardData == (CardRealtimeData)null))
			{
				return Traverse.Create((object)cardData).Field<CardDataNew>("card").Value;
			}
			return null;
		}

		private static void SetCardSourceField<T>(CardDataNew cardData, string fieldName, T value)
		{
			Traverse.Create((object)cardData).Field(fieldName).SetValue((object)value);
		}

		private static CardRealtimeData CreateRuntimeCard(CardDataNew cardData)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			CardRealtimeData val = new CardRealtimeData(cardData, cardData.Id);
			val.PostInit();
			return val;
		}

		private static CardRealtimeData RefreshRuntimeCard(CardDataNew cardData, ref Dictionary<string, CardRealtimeData> cards)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if ((Object)(object)cardData == (Object)null)
			{
				return null;
			}
			CardRealtimeData val = CreateRuntimeCard(cardData);
			cards[cardData.Id.ToLowerInvariant()] = val;
			ItemData val2 = val.Item ?? val.ItemEnchantment;
			Plugin.LogInfo("[ENDLESS BLESSING] Refreshed runtime card " + val.Id + ": target=" + (((val2 != null) ? ((object)val2.ItemTarget/*cast due to .constrained prefix*/).ToString() : null) ?? "<none>") + ", activation=" + (((val2 != null) ? ((object)val2.Activation/*cast due to .constrained prefix*/).ToString() : null) ?? "<none>"));
			return val;
		}

		private static Hero[] GetTeamHeroes()
		{
			Hero[] array = (Hero[])(object)new Hero[4];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = AtOManager.Instance.team.GetHero(i);
			}
			return array;
		}

		private static Hero[] GetMatchHeroes()
		{
			Hero[] array = (Hero[])(object)new Hero[4];
			Team value = Traverse.Create((object)MatchManager.Instance).Property<Team>("TeamHero", (object[])null).Value;
			for (int i = 0; i < array.Length; i++)
			{
				if (value == null)
				{
					break;
				}
				if (i >= value.Count)
				{
					break;
				}
				ref Hero reference = ref array[i];
				Character obj = value[i];
				reference = (Hero)(object)((obj is Hero) ? obj : null);
			}
			return array;
		}

		private static NPC[] GetMatchNPCs()
		{
			NPC[] array = (NPC[])(object)new NPC[4];
			Team value = Traverse.Create((object)MatchManager.Instance).Property<Team>("TeamNPC", (object[])null).Value;
			for (int i = 0; i < array.Length; i++)
			{
				if (value == null)
				{
					break;
				}
				if (i >= value.Count)
				{
					break;
				}
				ref NPC reference = ref array[i];
				Character obj = value[i];
				reference = (NPC)(object)((obj is NPC) ? obj : null);
			}
			return array;
		}

		private static int GetRandomIntRange(int min, int max)
		{
			return MatchManager.Instance.Random.GetRandomIntRange(min, max, "items", "");
		}

		private static void DisableKillPet(CardRealtimeData cardData)
		{
			CardDataNew cardSource = GetCardSource(cardData);
			if (((cardSource != null) ? cardSource.PetData : null) != null)
			{
				cardSource.PetData.KillPet = false;
			}
		}

		private static string NormalizeBlessingId(string blessingId)
		{
			//IL_0044: 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)
			if (string.IsNullOrWhiteSpace(blessingId))
			{
				return blessingId;
			}
			string text = blessingId.ToLowerInvariant();
			if (text.StartsWith("endless", StringComparison.Ordinal))
			{
				return text;
			}
			string text2 = "endless" + text;
			CardRealtimeData cardData = Globals.Instance.GetCardData(text2, false);
			if (cardData != (CardRealtimeData)null && cardData.CardType == blessingCardType)
			{
				Plugin.LogInfo("[ENDLESS BLESSING] Remapped original corruption variant " + blessingId + " -> " + cardData.Id);
				return cardData.Id;
			}
			return text;
		}

		private static CardDataNew NormalizeBlessingCard(CardDataNew blessingCard)
		{
			if ((Object)(object)blessingCard == (Object)null)
			{
				return null;
			}
			string text = NormalizeBlessingId(blessingCard.Id);
			if (string.Equals(text, blessingCard.Id, StringComparison.OrdinalIgnoreCase))
			{
				return blessingCard;
			}
			return GetCardSource(Globals.Instance.GetCardData(text, false)) ?? blessingCard;
		}

		private static void NormalizeActiveBlessings()
		{
			if (activeBlessings == null || activeBlessings.Count == 0)
			{
				return;
			}
			HashSet<string> hashSet = new HashSet<string>();
			bool flag = false;
			foreach (string activeBlessing in activeBlessings)
			{
				string text = NormalizeBlessingId(activeBlessing);
				if (!string.Equals(activeBlessing, text, StringComparison.OrdinalIgnoreCase))
				{
					flag = true;
				}
				hashSet.Add(text);
			}
			if (flag)
			{
				Plugin.LogInfo("[ENDLESS BLESSING] Normalized active blessing ids: " + string.Join(", ", activeBlessings) + " -> " + string.Join(", ", hashSet));
				activeBlessings = hashSet;
			}
		}

		public static CardDataNew GetRandomBlessing(List<string> ignore = null)
		{
			List<string> list = availableBlessings.ToList();
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = Globals.Instance.GetCardData(activeBlessing, false);
				cardData = Functions.GetCardDataFromCardData(cardData, "");
				if (cardData != (CardRealtimeData)null && list.Contains(cardData.Id))
				{
					Plugin.LogInfo("Active Blessing: " + cardData.Id);
					list.Remove(cardData.Id);
				}
			}
			if (ignore != null)
			{
				foreach (string item in ignore)
				{
					CardRealtimeData cardData2 = Globals.Instance.GetCardData(item, false);
					cardData2 = Functions.GetCardDataFromCardData(cardData2, "");
					if (cardData2 != (CardRealtimeData)null && list.Contains(cardData2.Id))
					{
						Plugin.LogInfo("Ignore Blessing: " + cardData2.Id);
						list.Remove(cardData2.Id);
					}
				}
			}
			Plugin.LogInfo($"Blessing Cards: {list.Count}");
			if (list.Count > 0)
			{
				int num = Random.Range(0, list.Count);
				string text = list[num];
				Plugin.LogInfo($"Random Corruption Index: {num} - {text}");
				CardRealtimeData val = Globals.Instance.GetCardData(text, false);
				if (AtOManager.Instance.GetTownTier() == 0)
				{
					val = Functions.GetCardDataFromCardData(val, "");
					if (val != (CardRealtimeData)null)
					{
						text = val.Id;
					}
				}
				if (AtOManager.Instance.GetTownTier() >= 1)
				{
					val = Functions.GetCardDataFromCardData(val, "A");
					if (val != (CardRealtimeData)null)
					{
						text = val.Id;
					}
				}
				if (AtOManager.Instance.GetTownTier() >= 2)
				{
					val = Functions.GetCardDataFromCardData(val, "B");
					if (val != (CardRealtimeData)null)
					{
						text = val.Id;
					}
				}
				if (AtOManager.Instance.GetTownTier() >= 3)
				{
					val = Functions.GetCardDataFromCardData(val, "RARE");
					if (val != (CardRealtimeData)null)
					{
						text = val.Id;
					}
				}
				if (val == (CardRealtimeData)null)
				{
					val = Globals.Instance.GetCardData(text, false);
				}
				Plugin.LogInfo("Got Corruption Card: " + val.Id);
				CardDataNew cardSource = GetCardSource(val);
				cardSource = NormalizeBlessingCard(cardSource);
				Plugin.LogInfo("[ENDLESS BLESSING] Selected runtime blessing variant: " + (((cardSource != null) ? cardSource.Id : null) ?? "<null>"));
				return cardSource;
			}
			return null;
		}

		public static void BeginMatchBlessings()
		{
			NormalizeActiveBlessings();
			Plugin.LogInfo("BEGIN MATCH BLESSINGS " + string.Join(", ", activeBlessings));
			Hero[] matchHeroes = GetMatchHeroes();
			Plugin.LogInfo($"Got Heroes: {matchHeroes.Length}");
			NPC[] matchNPCs = GetMatchNPCs();
			Plugin.LogInfo($"Got NPCs: {matchNPCs.Length}");
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = MatchManager.Instance.GetCardData(activeBlessing, true);
				Plugin.LogInfo("Got Blessing Data for " + cardData.Id);
			}
		}

		public static void CombatStartBlessings()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			NormalizeActiveBlessings();
			Plugin.LogInfo("COMBAT START BLESSINGS " + string.Join(", ", activeBlessings));
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = MatchManager.Instance.GetCardData(activeBlessing, true);
				if (!((Object)(object)cardData.Item != (Object)null) || cardData.Item.Activation != blessingCombatStart)
				{
					continue;
				}
				cardData.EnergyCost = 0;
				cardData.Vanish = true;
				SetCardSourceField<CardClass>(GetCardSource(cardData), "cardClass", (CardClass)7);
				MatchManager.Instance.GenerateNewCard(1, activeBlessing, false, (CardPlace)4, (CardRealtimeData)null, (CardRealtimeData)null, -1, true, 0, (CopyConfig)null);
				Hero[] matchHeroes = GetMatchHeroes();
				for (int i = 0; i < 4; i++)
				{
					if (matchHeroes[i] != null && ((Character)matchHeroes[i]).Alive)
					{
						((Character)matchHeroes[i]).DoItem(blessingCombatStart, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
						break;
					}
				}
			}
		}

		public static void BeginRoundBlessings()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Invalid comparison between Unknown and I4
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Invalid comparison between Unknown and I4
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Invalid comparison between Unknown and I4
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Invalid comparison between Unknown and I4
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Invalid comparison between Unknown and I4
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Invalid comparison between Unknown and I4
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			NormalizeActiveBlessings();
			Plugin.LogInfo("BEGIN ROUND BLESSINGS " + string.Join(", ", activeBlessings));
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = MatchManager.Instance.GetCardData(activeBlessing, true);
				if (!((Object)(object)cardData.Item != (Object)null) || cardData.Item.Activation != blessingBeginRound)
				{
					continue;
				}
				Hero[] matchHeroes = GetMatchHeroes();
				NPC[] matchNPCs = GetMatchNPCs();
				Plugin.LogInfo($"{activeBlessing} - BEGIN ROUND - {cardData.Item.ItemTarget}");
				if ((int)cardData.Item.ItemTarget == 3)
				{
					for (int i = 0; i < 4; i++)
					{
						if (matchHeroes[i] != null && ((Character)matchHeroes[i]).Alive)
						{
							((Character)matchHeroes[i]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							break;
						}
					}
				}
				else if ((int)cardData.Item.ItemTarget == 1 || (int)cardData.Item.ItemTarget == 0)
				{
					if ((int)cardData.Item.ItemTarget == 0)
					{
						for (int j = 0; j < 4; j++)
						{
							if (matchHeroes[j] != null && ((Character)matchHeroes[j]).Alive)
							{
								((Character)matchHeroes[j]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							}
						}
						continue;
					}
					bool flag = false;
					while (!flag)
					{
						int randomIntRange = GetRandomIntRange(0, 4);
						if (matchHeroes[randomIntRange] != null && ((Character)matchHeroes[randomIntRange]).Alive)
						{
							((Character)matchHeroes[randomIntRange]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							flag = true;
						}
					}
				}
				else if ((int)cardData.Item.ItemTarget == 4)
				{
					for (int k = 0; k < 4; k++)
					{
						if (matchNPCs[k] != null && ((Character)matchNPCs[k]).Alive)
						{
							((Character)matchNPCs[k]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							break;
						}
					}
				}
				else
				{
					if ((int)cardData.Item.ItemTarget != 2 && (int)cardData.Item.ItemTarget != 6)
					{
						continue;
					}
					if ((int)cardData.Item.ItemTarget == 6)
					{
						for (int l = 0; l < 4; l++)
						{
							if (matchNPCs[l] != null && ((Character)matchNPCs[l]).Alive)
							{
								((Character)matchNPCs[l]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							}
						}
						continue;
					}
					bool flag2 = false;
					while (!flag2)
					{
						int randomIntRange2 = GetRandomIntRange(0, 4);
						if (matchNPCs[randomIntRange2] != null && ((Character)matchNPCs[randomIntRange2]).Alive)
						{
							((Character)matchNPCs[randomIntRange2]).DoItem(blessingBeginRound, cardData, cardData.Item.Id, (Character)null, 0, "", 0, (CardRealtimeData)null, false);
							flag2 = true;
						}
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Enum), "GetName")]
		public static void GetName(Type enumType, object value, ref string __result)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (enumType == typeof(CardType) && (CardType)value == blessingCardType)
			{
				__result = "Blessing";
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemCombatIcon), "DoHover")]
		public static void DoHover(ItemCombatIcon __instance, bool state, ref CardRealtimeData ___cardData)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!(___cardData == (CardRealtimeData)null) && ___cardData.CardType == blessingCardType)
			{
				((Component)__instance.spriteBackgroundHover).gameObject.SetActive(true);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Character), "ActivateItem")]
		public static void ActivateItem(ref Character __instance, EventActivation theEvent, Character target, int auxInt, string auxString, ref bool ___isHero, ref Item ___itemClass, ref CardRealtimeData ___cardCasted)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MatchManager.Instance == (Object)null)
			{
				return;
			}
			int num = -1;
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = MatchManager.Instance.GetCardData(activeBlessing, true);
				if (!(cardData != (CardRealtimeData)null))
				{
					continue;
				}
				ItemData val = null;
				if ((Object)(object)cardData.Item != (Object)null)
				{
					val = cardData.Item;
				}
				else if ((Object)(object)cardData.ItemEnchantment != (Object)null)
				{
					val = cardData.ItemEnchantment;
				}
				if (!((Object)(object)val != (Object)null) || (val.ActivationOnlyOnHeroes && ___isHero) || (val.Activation != theEvent && ((int)val.Activation != 20 || (int)theEvent != 29)))
				{
					continue;
				}
				if (Globals.Instance.ShowDebug)
				{
					Functions.DebugLogGD("[Character/ActivateItem] Checking if " + activeBlessing + " will activate", "item");
				}
				Plugin.LogInfo($"{theEvent} - {cardData.Id} - {__instance.HeroIndex} - {val.ItemTarget}");
				if (___itemClass.DoItem(theEvent, cardData, activeBlessing, __instance, target, auxInt, auxString, 0, ___cardCasted, true, false))
				{
					num++;
					if (Globals.Instance.ShowDebug)
					{
						Functions.DebugLogGD("[Character/ActivateItem] " + activeBlessing + "-> OK", "item");
					}
					MatchManager.Instance.DoItem(__instance, theEvent, cardData, activeBlessing, target, auxInt, auxString, num, false, (CardRealtimeData)null);
				}
				else if (Globals.Instance.ShowDebug)
				{
					Functions.DebugLogGD(activeBlessing + " -> XXXXXX", "item");
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InitiativesManager), "SetInitiatives")]
		public static void SetInitiativesPostfix()
		{
			BeginMatchBlessings();
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static IEnumerable<CodeInstruction> NextTurnContinue_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MatchManager), "corruptionItem"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(AtOEndless), "CombatStartBlessings", (Type[])null, (Type[])null))
			}).Advance(4)
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MatchManager), "corruptionItem"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(AtOEndless), "BeginRoundBlessings", (Type[])null, (Type[])null))
				});
			return val.InstructionEnumeration();
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Node), "OnMouseUp")]
		public static void OnMouseUp(ref Node __instance)
		{
			if (Functions.ClickedThisTransform(((Component)__instance).transform) && !AlertManager.Instance.IsActive() && !GameManager.Instance.IsTutorialActive() && !SettingsManager.Instance.IsActive() && !DamageMeterManager.Instance.IsActive() && (!Object.op_Implicit((Object)(object)MapManager.Instance) || !MapManager.Instance.IsCharacterUnlock()) && (!Object.op_Implicit((Object)(object)MapManager.Instance) || (!MapManager.Instance.IsCorruptionOver() && !MapManager.Instance.IsConflictOver())) && (!Object.op_Implicit((Object)(object)MapManager.Instance) || !MapManager.Instance.selectedNode) && !Object.op_Implicit((Object)(object)EventManager.Instance) && ((object)Unsafe.As<SteamId, SteamId>(ref SteamManager.Instance.steamId)/*cast due to .constrained prefix*/).ToString() == "76561197965495526")
			{
				GameManager.Instance.SetCursorPlain();
				MapManager.Instance.HidePopup();
				MapManager.Instance.PlayerSelectedNode(__instance, false);
				GameManager.Instance.PlayAudio(AudioManager.Instance.soundButtonClick, 0f, 0f);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Functions), "DebugLogGD")]
		public static bool DebugLogGD(string str, string type)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (type != "")
			{
				stringBuilder.Append("[");
				stringBuilder.Append(type.ToUpper());
				stringBuilder.Append("] ");
			}
			stringBuilder.Append(str);
			Plugin.LogInfo(stringBuilder.ToString());
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(AtOManager), "BeginAdventure")]
		public static void BeginAdventure(ref AtOManager __instance)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge())
			{
				activeBlessings = new HashSet<string>();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MatchManager), "FinishLoadTurnData")]
		public static void FinishLoadTurnData(ref MatchManager __instance)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (GameManager.Instance.IsObeliskChallenge() || GameManager.Instance.IsWeeklyChallenge())
			{
				return;
			}
			List<ItemCombatIcon> list = new List<ItemCombatIcon>();
			int num = 0;
			foreach (string activeBlessing in activeBlessings)
			{
				CardRealtimeData cardData = Globals.Instance.GetCardData(activeBlessing, false);
				ItemCombatIcon val = Object.Instantiate<ItemCombatIcon>(__instance.iconCorruption, ((Component)__instance.iconCorruption).transform.parent);
				((Object)((Component)val).gameObject).name = "CorruptionIcon";
				float num2 = ((Component)val).transform.localPosition.x - 3f - 0.7f * (float)(num % 6);
				float num3 = ((Component)val).transform.localPosition.y - 0.7f * (float)Mathf.FloorToInt((float)(num / 6));
				((Component)val).transform.localPosition = new Vector3(num2, num3, ((Component)val).transform.localPosition.z + 3f);
				Plugin.LogInfo("GAME OBJECT " + ((Object)((Component)val).gameObject).name);
				list.Add(val);
				num++;
				if (cardData != (CardRealtimeData)null)
				{
					((Component)((Component)val).transform).gameObject.SetActive(true);
					val.ShowIconCorruption(cardData);
					Plugin.LogInfo("CARD ID " + cardData.Id);
				}
				else
				{
					((Component)((Component)val).transform).gameObject.SetActive(false);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(CardDescriptionExtension), "SetDescriptionNew")]
		public static void SetDescriptionNewPre(CardRealtimeData data, bool forceDescription, Character character, bool includeInSearch, out EventActivation __state)
		{
			//IL_0005: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected I4, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected I4, but got Unknown
			__state = (EventActivation)0;
			if (data.CardType == blessingCardType && (Object)(object)data.Item != (Object)null)
			{
				if (data.Item.Activation == blessingBeginRound)
				{
					__state = (EventActivation)(int)data.Item.Activation;
					data.Item.Activation = (EventActivation)2;
				}
				if (data.Item.Activation == blessingCombatStart)
				{
					__state = (EventActivation)(int)data.Item.Activation;
					data.Item.Activation = (EventActivation)1;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardDescriptionExtension), "SetDescriptionNew")]
		public static void SetDescriptionNewPost(CardRealtimeData data, bool forceDescription, Character character, bool includeInSearch, EventActivation __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (data.CardType == blessingCardType && (Object)(object)data.Item != (Object)null && (int)__state != 0)
			{
				data.Item.Activation = __state;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveManager), "SaveGame")]
		public static void SaveGame(int slot, bool backUp)
		{
			try
			{
				string endlessSavePath = GetEndlessSavePath(slot);
				Directory.CreateDirectory(Path.GetDirectoryName(endlessSavePath));
				if (backUp && File.Exists(endlessSavePath))
				{
					File.Copy(endlessSavePath, endlessSavePath + ".bak", overwrite: true);
				}
				EndlessSaveManager.endlessData.FillData();
				File.WriteAllText(endlessSavePath, JsonHelper.ToJson<string>(EndlessSaveManager.endlessData.activeBlessings.ToArray()));
				if (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.IsMaster())
				{
					EndlessSaveManager.SendData();
				}
			}
			catch (Exception ex)
			{
				Plugin.LogInfo("Failed to save AtOEndless Data");
				Plugin.LogInfo("Reason: " + ex.Message + " " + ex.StackTrace);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveManager), "LoadGame")]
		public static void LoadGame(int slot, bool comingFromReloadCombat)
		{
			string endlessSavePath = GetEndlessSavePath(slot);
			if (!File.Exists(endlessSavePath))
			{
				Plugin.LogInfo("No AtOEndless save file exists");
				return;
			}
			try
			{
				string text = File.ReadAllText(endlessSavePath);
				EndlessSaveManager.endlessData.activeBlessings = JsonHelper.FromJson<string>(text).ToHashSet();
				EndlessSaveManager.endlessData.LoadData();
				if (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.IsMaster())
				{
					EndlessSaveManager.SendData();
				}
			}
			catch (Exception ex)
			{
				Plugin.LogInfo("Failed to load AtOEndless Data. Reason: " + ex.Message);
			}
		}

		private static string GetEndlessSavePath(int slot)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Path.Combine(Application.persistentDataPath, SteamId.op_Implicit(SteamManager.Instance.steamId).ToString(), GameManager.Instance.ProfileFolder, $"AtOEndless_save_slot_{slot}.json");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveManager), "DeleteGame")]
		public static void DeleteGame(int slot, bool sendTelemetry)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			string value = Traverse.Create(typeof(SaveManager)).Field("saveGameExtension").GetValue<string>();
			string value2 = Traverse.Create(typeof(SaveManager)).Field("saveGameExtensionBK").GetValue<string>();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Application.persistentDataPath);
			stringBuilder.Append("/");
			stringBuilder.Append(SteamId.op_Implicit(SteamManager.Instance.steamId));
			stringBuilder.Append("/");
			stringBuilder.Append(GameManager.Instance.ProfileFolder);
			stringBuilder.Append("endless_");
			stringBuilder.Append(slot);
			string path = stringBuilder.ToString() + value;
			string path2 = stringBuilder.ToString() + value2;
			if (File.Exists(path))
			{
				File.Delete(path);
			}
			if (File.Exists(path2))
			{
				File.Delete(path2);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "LevelUp")]
		public static void LevelUp(Character __instance, HeroData ___heroData)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge() && AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), "") && ___heroData.HeroSubClass.MaxHp.Length < 9)
			{
				int[] array = new int[9];
				___heroData.HeroSubClass.MaxHp.CopyTo(array, 4);
				___heroData.HeroSubClass.MaxHp.CopyTo(array, 0);
				___heroData.HeroSubClass.MaxHp = array;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SubClassData), "GetTraitLevel")]
		public static void GetTraitLevel(SubClassData __instance, string traitName, ref int __result)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge() && AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), ""))
			{
				Hero val = (from hero in GetTeamHeroes()
					where ((Character)hero).SubclassName.ToLower() == __instance.SubClassName.ToLower()
					select hero).First();
				if (((Character)val).Traits.Length < 9)
				{
					string[] array = new string[9];
					((Character)val).Traits.CopyTo(array, 0);
					((Character)val).Traits = array;
				}
				if (((Character)val).Traits[__result] != null && ((Character)val).Traits[__result] != "" && ((Character)val).Traits[__result] != traitName)
				{
					__result += 4;
				}
				Plugin.LogInfo($"GetTraitLevel: {__result} - {((Character)val).Traits.Length} - {((Character)val).Traits[__result]}");
				string[] traits = ((Character)val).Traits;
				foreach (string text in traits)
				{
					Plugin.LogInfo("GetTraitLevel: " + text);
				}
			}
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(CharacterWindowUI), "GetTraitData")]
		public static TraitData GetTraitData(CharacterWindowUI __instance, int level, int index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			return new TraitData();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CharacterWindowUI), "DrawLevelButtons")]
		public static void DrawLevelButtons(ref CharacterWindowUI __instance, int heroLevel, bool levelUp, ref Hero ___currentHero, ref SubClassData ___currentSCD)
		{
			if (GameManager.Instance.IsObeliskChallenge() || GameManager.Instance.IsWeeklyChallenge() || !AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), ""))
			{
				return;
			}
			string color = Globals.Instance.ClassColor[((Character)___currentHero).ClassName];
			int characterTier = PlayerManager.Instance.GetCharacterTier("", "trait", ((Character)___currentHero).PerkRank);
			for (int i = 1; i < 5; i++)
			{
				bool active = false;
				bool enable = false;
				int num = i * 2;
				int num2 = num + 1;
				TraitData traitData = GetTraitData(__instance, i, 0);
				if (((Character)___currentHero).HaveTrait(traitData.Id))
				{
					enable = true;
				}
				else if ((i == heroLevel || i + 4 == heroLevel) && levelUp && (((Character)___currentHero).Owner == null || ((Character)___currentHero).Owner == "" || ((Character)___currentHero).Owner == NetworkManager.Instance.GetPlayerNick()) && !((Character)___currentHero).HaveTrait(traitData.Id))
				{
					active = true;
				}
				__instance.traitLevel[num].SetHeroIndex(__instance.heroIndex);
				__instance.traitLevel[num].SetColor(color);
				__instance.traitLevel[num].SetPosition(1);
				__instance.traitLevel[num].SetEnable(enable);
				__instance.traitLevel[num].SetActive(active);
				__instance.traitLevel[num].SetTrait(traitData, characterTier);
				TraitData traitData2 = GetTraitData(__instance, i, 1);
				bool enable2 = false;
				bool active2 = false;
				if (((Character)___currentHero).HaveTrait(traitData2.Id))
				{
					enable2 = true;
				}
				else if ((i == heroLevel || i + 4 == heroLevel) && levelUp && (((Character)___currentHero).Owner == null || ((Character)___currentHero).Owner == "" || ((Character)___currentHero).Owner == NetworkManager.Instance.GetPlayerNick()) && !((Character)___currentHero).HaveTrait(traitData2.Id))
				{
					active2 = true;
				}
				__instance.traitLevel[num2].SetHeroIndex(__instance.heroIndex);
				__instance.traitLevel[num2].SetColor(color);
				__instance.traitLevel[num2].SetPosition(2);
				__instance.traitLevel[num2].SetEnable(enable2);
				__instance.traitLevel[num2].SetActive(active2);
				__instance.traitLevel[num2].SetTrait(traitData2, characterTier);
				StringBuilder stringBuilder = new StringBuilder();
				bool flag = false;
				if ((i < heroLevel || ((i == heroLevel || i + 4 == heroLevel) && levelUp)) && (((Character)___currentHero).Owner == null || ((Character)___currentHero).Owner == "" || ((Character)___currentHero).Owner == NetworkManager.Instance.GetPlayerNick()))
				{
					flag = true;
				}
				stringBuilder.Append("<size=+.4>");
				if (flag)
				{
					stringBuilder.Append("<color=#FC0>");
				}
				stringBuilder.Append(Texts.Instance.GetText("levelNumber", "").Replace("<N>", $"{i + 1}&{i + 5}"));
				if (flag)
				{
					stringBuilder.Append("</color>");
				}
				stringBuilder.Append("</size>");
				stringBuilder.Append("\n");
				if (flag)
				{
					stringBuilder.Append("<color=#EE5A3C>");
				}
				stringBuilder.Append(Texts.Instance.GetText("incrementMaxHp", "").Replace("<N>", ___currentSCD.MaxHp[i].ToString()));
				if (flag)
				{
					stringBuilder.Append("</color>");
				}
				__instance.traitLevelText[i].text = stringBuilder.ToString();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Node), "AssignNode")]
		public static void AssignNodePre(ref AtOManager __instance, out string[][] __state)
		{
			__state = new string[2][]
			{
				AtOManager.Instance.mapVisitedNodes.ToArray(),
				AtOManager.Instance.mapVisitedNodesAction.ToArray()
			};
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge())
			{
				AtOManager.Instance.mapVisitedNodes.Clear();
				AtOManager.Instance.mapVisitedNodesAction.Clear();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Node), "AssignNode")]
		public static void AssignNodePost(ref Node __instance, string[][] __state)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge())
			{
				AtOManager.Instance.mapVisitedNodes.AddRange(new <>z__ReadOnlyArray<string>(__state[0].ToArray()));
				AtOManager.Instance.mapVisitedNodesAction.AddRange(new <>z__ReadOnlyArray<string>(__state[1].ToArray()));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AtOManager), "GetTownTier")]
		public static void GetTownTier(ref AtOManager __instance, ref int ___townTier, ref int __result)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge())
			{
				__result = Math.Min(___townTier, 3);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AtOManager), "GetActNumberForText")]
		public static void GetActNumberForText(ref AtOManager __instance, ref int ___townTier, ref int __result)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge())
			{
				__result = ___townTier + 1;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(MapManager), "Awake")]
		public static void Awake(ref MapManager __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			if (refreshed)
			{
				return;
			}
			foreach (GameObject map in __instance.mapList)
			{
				foreach (Transform item in map.transform)
				{
					Transform val = item;
					if (!(((Object)((Component)val).gameObject).name == "Nodes"))
					{
						continue;
					}
					foreach (Transform item2 in val)
					{
						Transform val2 = item2;
						Node component = ((Component)val2).gameObject.GetComponent<Node>();
						if ((Object)(object)((Component)component).GetComponent<Node>().nodeData != (Object)null)
						{
							((Component)component).GetComponent<Node>().nodeData = Globals.Instance.GetNodeData(component.nodeData.NodeId);
						}
						else
						{
							Plugin.LogInfo("No Node Data for " + ((Object)((Component)val2).gameObject).name);
						}
					}
				}
			}
			refreshed = true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(NetworkManager), "Awake")]
		public static void NetworkManagerAwake(ref NetworkManager __instance)
		{
			EndlessSaveManager = ((Component)NetworkManager.Instance).gameObject.AddComponent<AtOEndlessSaveManager>();
			EndlessSaveManager.CreateView();
		}

		public static string[] GetEnabledPerks()
		{
			List<string> list = new List<string>();
			foreach (List<string> value in AtOManager.Instance.PerksManager.heroPerks.Values)
			{
				foreach (string item in value)
				{
					if (item.StartsWith("endless_") && !list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			return list.ToArray();
		}

		public static string GetRandomPerkDescription(PerkData perkData)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Invalid comparison between Unknown and I4
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Invalid comparison between Unknown and I4
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Invalid comparison between Unknown and I4
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			if (perkData.MaxHealth != 0)
			{
				stringBuilder.Append($"<sprite name=heart><space=.5>Health {perkData.MaxHealth:+#;-#;0}<space=1.5>");
			}
			if (perkData.SpeedQuantity != 0)
			{
				stringBuilder.Append($"<sprite name=speedMini><space=.5>Speed {perkData.SpeedQuantity:+#;-#;0}<space=1.5>");
			}
			if ((Object)(object)perkData.AuracurseBonus != (Object)null && perkData.AuracurseBonusValue != 0)
			{
				stringBuilder.Append($"<sprite name={((Object)perkData.AuracurseBonus.Sprite).name}><space=.5>charges {perkData.AuracurseBonusValue:+#;-#;0}<space=1.5>");
			}
			if (perkData.ResistModifiedValue != 0)
			{
				if ((int)perkData.ResistModified == 10)
				{
					stringBuilder.Append($"<sprite name=ui_resistance><space=.5>All resistances {perkData.ResistModifiedValue:+#;-#;0}%<space=1.5>");
				}
				if ((int)perkData.ResistModified != 10)
				{
					string text = ((object)perkData.ResistModified/*cast due to .constrained prefix*/).ToString().ToLower();
					if (text == "slashing")
					{
						text = "slash";
					}
					stringBuilder.Append($"<sprite name=resist_{text}><space=.5>resistance {perkData.ResistModifiedValue:+#;-#;0}%<space=1.5>");
				}
			}
			if (perkData.DamageFlatBonusValue != 0)
			{
				if ((int)perkData.DamageFlatBonus == 10)
				{
					stringBuilder.Append($"<sprite name=damage><space=.5>All damage {perkData.DamageFlatBonusValue:+#;-#;0}<space=1.5>");
				}
				if ((int)perkData.DamageFlatBonus != 10)
				{
					string text2 = ((object)perkData.DamageFlatBonus/*cast due to .constrained prefix*/).ToString().ToLower();
					if (text2 == "slashing")
					{
						text2 = "slash";
					}
					stringBuilder.Append($"<sprite name={text2}><space=.5>damage {perkData.DamageFlatBonusValue:+#;-#;0}<space=1.5>");
				}
			}
			stringBuilder.Replace("<c>", "");
			stringBuilder.Replace("</c>", "");
			return $"<space=1>{stringBuilder}";
		}

		public static string GetRandomPerkType(string[] exclude)
		{
			string[] array = new string[5] { "h", "a", "d", "r", "s" }.Where((string v) => !exclude.Contains(v)).ToArray();
			return array[Random.Range(0, array.Length)];
		}

		public unsafe static string GetRandomPerkSubtype(string type)
		{
			switch (type)
			{
			case "a":
			{
				string[] array2 = new string[16]
				{
					"bleed", "block", "burn", "chill", "dark", "fury", "insane", "poison", "regeneration", "sharp",
					"shield", "sight", "spark", "thorns", "vitality", "wet"
				};
				return array2[Random.Range(0, array2.Length)];
			}
			case "d":
			case "r":
			{
				DamageType[] array = (from DamageType d in Enum.GetValues(typeof(DamageType))
					where !((object)(*(DamageType*)(&d))/*cast due to .constrained prefix*/).Equals((object)(DamageType)0)
					select d).ToArray();
				return ((object)Unsafe.As<DamageType, DamageType>(ref array[Random.Range(0, array.Length)])/*cast due to .constrained prefix*/).ToString().ToLower();
			}
			default:
				return "";
			}
		}

		public static int GetRandomPerkValue(string type, string subtype = "")
		{
			int num = 0;
			int num2 = 0;
			if (type == "h")
			{
				num2 = 5;
				num = 15;
			}
			if (type == "a")
			{
				num2 = 1;
				num = 2;
			}
			if (type == "s")
			{
				num2 = 1;
				num = 2;
			}
			if (type == "d")
			{
				num2 = 1;
				num = 3;
			}
			if (type == "r")
			{
				num2 = 5;
				num = 10;
			}
			return Random.Range(num2, num);
		}

		private static void SanitizeEndlessReply(EventReplyData reply)
		{
			if (reply != null)
			{
				if (reply.SsFinishObeliskMap || reply.SsFinishGame || reply.SscFinishGame || reply.SsFinishEarlyAccess || reply.SscFinishEarlyAccess)
				{
					Plugin.LogInfo($"[ENDLESS EVENT] Clearing inherited completion flags: SsFinishObeliskMap={reply.SsFinishObeliskMap}, SsFinishGame={reply.SsFinishGame}, SscFinishGame={reply.SscFinishGame}, SsFinishEarlyAccess={reply.SsFinishEarlyAccess}, SscFinishEarlyAccess={reply.SscFinishEarlyAccess}");
				}
				reply.SsFinishObeliskMap = false;
				reply.SsFinishGame = false;
				reply.SscFinishGame = false;
				reply.SsFinishEarlyAccess = false;
				reply.SscFinishEarlyAccess = false;
			}
		}

		private static void ClearEndlessCardRewards(EventReplyData reply, string context)
		{
			if (reply != null)
			{
				int num = reply.SsAddCards?.Count ?? 0;
				int num2 = reply.SscAddCards?.Count ?? 0;
				int num3 = reply.FlAddCards?.Count ?? 0;
				int num4 = reply.FlcAddCards?.Count ?? 0;
				if (num > 0 || num2 > 0 || num3 > 0 || num4 > 0)
				{
					Plugin.LogInfo("[ENDLESS BLESSING] Clearing native card rewards (" + context + "): " + $"success={num}, criticalSuccess={num2}, " + $"fail={num3}, criticalFail={num4}");
				}
				reply.SsAddCards = new List<CardDataNew>();
				reply.SscAddCards = new List<CardDataNew>();
				reply.FlAddCards = new List<CardDataNew>();
				reply.FlcAddCards = new List<CardDataNew>();
			}
		}

		private static void RebuildEndlessReplyCache(EventReplyData reply, string context)
		{
			if (reply != null)
			{
				SanitizeEndlessReply(reply);
				reply.Init();
				EventReplyDataByStatus data = reply.GetData(true, false);
				EventReplyDataByStatus data2 = reply.GetData(true, true);
				string[] obj = new string[12]
				{
					"[ENDLESS EVENT] Rebuilt reply cache (",
					context,
					"): ",
					$"successFinishObeliskMap={data?.FinishObeliskMap}, ",
					$"successFinishGame={data?.FinishGame}, ",
					"successEvent=",
					null,
					null,
					null,
					null,
					null,
					null
				};
				object obj2;
				if (data == null)
				{
					obj2 = null;
				}
				else
				{
					EventData obj3 = data.Event;
					obj2 = ((obj3 != null) ? obj3.EventId : null);
				}
				if (obj2 == null)
				{
					obj2 = "<null>";
				}
				obj[6] = (string)obj2;
				obj[7] = ", ";
				obj[8] = $"criticalFinishObeliskMap={data2?.FinishObeliskMap}, ";
				obj[9] = $"criticalFinishGame={data2?.FinishGame}, ";
				obj[10] = "criticalEvent=";
				object obj4;
				if (data2 == null)
				{
					obj4 = null;
				}
				else
				{
					EventData obj5 = data2.Event;
					obj4 = ((obj5 != null) ? obj5.EventId : null);
				}
				if (obj4 == null)
				{
					obj4 = "<null>";
				}
				obj[11] = (string)obj4;
				Plugin.LogInfo(string.Concat(obj));
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(EventManager), "SetEvent")]
		public static void SetEvent(ref EventManager __instance, EventData _eventData)
		{
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0809: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Invalid comparison between Unknown and I4
			//IL_0618: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Invalid comparison between Unknown and I4
			//IL_0949: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Invalid comparison between Unknown and I4
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Invalid comparison between Unknown and I4
			//IL_0984: Unknown result type (might be due to invalid IL or missing references)
			//IL_0987: Invalid comparison between Unknown and I4
			//IL_0b11: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Invalid comparison between Unknown and I4
			//IL_0b38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b3b: Invalid comparison between Unknown and I4
			//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e4: Invalid comparison between Unknown and I4
			//IL_09c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c3: Invalid comparison between Unknown and I4
			//IL_0b60: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b63: Invalid comparison between Unknown and I4
			//IL_0709: Unknown result type (might be due to invalid IL or missing references)
			//IL_070c: Invalid comparison between Unknown and I4
			//IL_0b85: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b88: Invalid comparison between Unknown and I4
			//IL_09fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ff: Invalid comparison between Unknown and I4
			//IL_0bae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bb2: Invalid comparison between Unknown and I4
			//IL_0a38: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3c: Invalid comparison between Unknown and I4
			//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bdc: Invalid comparison between Unknown and I4
			//IL_0cc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a75: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a79: Invalid comparison between Unknown and I4
			//IL_0da7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ce6: Invalid comparison between Unknown and I4
			//IL_0d03: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d06: Invalid comparison between Unknown and I4
			//IL_0ab2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ab5: Invalid comparison between Unknown and I4
			//IL_0d20: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d23: Invalid comparison between Unknown and I4
			//IL_0d3d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d41: Invalid comparison between Unknown and I4
			//IL_0d5b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d5f: Invalid comparison between Unknown and I4
			//IL_0d79: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d7c: Invalid comparison between Unknown and I4
			if (_eventData.EventId == "e_endless_perk")
			{
				EventReplyData val = Globals.Instance.GetEventData("e_challenge_next").Replys.First();
				Random.InitState(Functions.GetDeterministicHashCode(AtOManager.Instance.GetGameId()));
				List<EventReplyData> list = new List<EventReplyData>();
				for (int i = 0; i < 5; i++)
				{
					EventReplyData val2 = val.ShallowCopy();
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append("endless_");
					List<string> list2 = new List<string>();
					for (int j = 0; j < 2; j++)
					{
						string randomPerkType = GetRandomPerkType(list2.ToArray());
						list2.Add(randomPerkType);
						string randomPerkSubtype = GetRandomPerkSubtype(randomPerkType);
						int randomPerkValue = GetRandomPerkValue(randomPerkType, randomPerkSubtype);
						stringBuilder.Append(randomPerkType + ":");
						if (randomPerkSubtype != "")
						{
							stringBuilder.Append(randomPerkSubtype + "#" + randomPerkType + "v:");
						}
						stringBuilder.Append($"{randomPerkValue}#");
					}
					stringBuilder.Length--;
					stringBuilder.Append("_" + Functions.RandomString(6f, 0f));
					val2.SsPerkData = Globals.Instance.GetPerkData(stringBuilder.ToString());
					val2.SsPerkData1 = null;
					val2.ReplyText = GetRandomPerkDescription(val2.SsPerkData);
					val2.SsRewardText = "";
					val2.SsRequirementUnlock = null;
					val2.SsDustReward = 0;
					val2.SsExperienceReward = 0;
					val2.SsGoldReward = 0;
					EventData val3 = (val2.SscEvent = (val2.SsEvent = (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_pick_blessing"), "") ? Globals.Instance.GetEventData("e_endless_blessing") : Globals.Instance.GetEventData("e_endless_obelisk"))));
					RebuildEndlessReplyCache(val2, "perk");
					Plugin.LogInfo("[ENDLESS EVENT] Perk reply next event -> " + ((val3 != null) ? val3.EventId : null));
					list.Add(val2);
				}
				Globals.Instance.GetEventData("e_endless_perk").Replys = list.ToArray();
			}
			if (_eventData.EventId == "e_endless_blessing")
			{
				EventReplyData val6 = Globals.Instance.GetEventData("e_challenge_next").Replys.First();
				Random.InitState(Functions.GetDeterministicHashCode(AtOManager.Instance.GetGameId()));
				List<EventReplyData> list3 = new List<EventReplyData>();
				List<string> list4 = new List<string>();
				for (int k = 0; k < 3; k++)
				{
					CardDataNew randomBlessing = GetRandomBlessing(list4);
					if ((Object)(object)randomBlessing != (Object)null)
					{
						list4.Add(randomBlessing.Id);
						EventReplyData val7 = val6.ShallowCopy();
						val7.SsPerkData = null;
						val7.SsPerkData1 = null;
						ClearEndlessCardRewards(val7, "build-blessing-reply");
						val7.ReplyShowCard = randomBlessing;
						val7.ReplyText = randomBlessing.CardName;
						val7.SsRewardText = "";
						val7.SsRequirementUnlock = null;
						val7.SsDustReward = 0;
						val7.SsExperienceReward = 0;
						val7.SsGoldReward = 0;
						EventData val8 = (val7.SscEvent = (val7.SsEvent = Globals.Instance.GetEventData("e_endless_obelisk")));
						RebuildEndlessReplyCache(val7, "blessing");
						Plugin.LogInfo("[ENDLESS EVENT] Blessing reply next event -> " + ((val8 != null) ? val8.EventId : null));
						list3.Add(val7);
					}
				}
				EventReplyData val10 = val6.ShallowCopy();
				val10.SsPerkData = null;
				val10.SsPerkData1 = null;
				ClearEndlessCardRewards(val10, "build-blessing-skip");
				val10.ReplyShowCard = null;
				val10.ReplyText = ((list3.Count == 0) ? "There are no more blessings to choose from." : "Skip");
				val10.SsRewardText = "";
				val10.SsRequirementUnlock = null;
				val10.SsDustReward = 0;
				val10.SsExperienceReward = 0;
				val10.SsGoldReward = 0;
				EventData val11 = (val10.SscEvent = (val10.SsEvent = Globals.Instance.GetEventData("e_endless_obelisk")));
				RebuildEndlessReplyCache(val10, "blessing-skip");
				Plugin.LogInfo("[ENDLESS EVENT] Skip blessing next event -> " + ((val11 != null) ? val11.EventId : null));
				list3.Add(val10);
				Globals.Instance.GetEventData("e_endless_blessing").Replys = list3.ToArray();
			}
			if (!(_eventData.EventId == "e_endless_obelisk"))
			{
				return;
			}
			EventReplyData val13 = Globals.Instance.GetEventData("e_sen34_a").Replys.First();
			Zone mapZone = AtOManager.Instance.GetMapZone(AtOManager.Instance.currentMapNode);
			Random.InitState(Functions.GetDeterministicHashCode(AtOManager.Instance.GetGameId()));
			bool flag = SteamManager.Instance.PlayerHaveDLC("2511580") || (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.AnyPlayersHaveSku("2511580"));
			bool flag2 = SteamManager.Instance.PlayerHaveDLC("3185630") || (GameManager.Instance.IsMultiplayer() && NetworkManager.Instance.AnyPlayersHaveSku("3185630"));
			List<NodeData> list5 = new List<NodeData>();
			list5.Add(Globals.Instance.GetNodeData("sen_0"));
			list5.Add(Globals.Instance.GetNodeData("faen_0"));
			list5.Add(Globals.Instance.GetNodeData("aqua_0"));
			list5.Add(Globals.Instance.GetNodeData("velka_0"));
			if (flag)
			{
				list5.Add(Globals.Instance.GetNodeData("ulmin_0"));
			}
			if (flag2)
			{
				list5.Add(Globals.Instance.GetNodeData("sahti_0"));
			}
			list5.Add(Globals.Instance.GetNodeData("voidlow_0"));
			bool flag3 = false;
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_unique_zones"), "") && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sen"), "") || (int)mapZone == 0) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_faen"), "") || (int)mapZone == 3) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_aqua"), "") || (int)mapZone == 2) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_velka"), "") || (int)mapZone == 1) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_ulmin"), "") || (int)mapZone == 12) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sahti"), "") || (int)mapZone == 14) && (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_void"), "") || (int)mapZone == 5))
			{
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_sen"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_faen"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_aqua"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_velka"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_ulmin"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_sahti"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_void"), "");
				flag3 = true;
			}
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_require_all_before_void"), "") && (int)mapZone == 5)
			{
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_sen"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_faen"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_aqua"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_velka"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_ulmin"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_sahti"), "");
				AtOManager.Instance.RemovePlayerRequirement(Globals.Instance.GetRequirementData("endless_complete_void"), "");
				flag3 = true;
			}
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_unique_zones"), "") || !AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_repeats"), ""))
			{
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sen"), "") || (int)mapZone == 0)
				{
					list5.Remove(Globals.Instance.GetNodeData("sen_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_faen"), "") || (int)mapZone == 3)
				{
					list5.Remove(Globals.Instance.GetNodeData("faen_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_aqua"), "") || (int)mapZone == 2)
				{
					list5.Remove(Globals.Instance.GetNodeData("aqua_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_velka"), "") || (int)mapZone == 1)
				{
					list5.Remove(Globals.Instance.GetNodeData("velka_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_ulmin"), "") || (int)mapZone == 12)
				{
					list5.Remove(Globals.Instance.GetNodeData("ulmin_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sahti"), "") || (int)mapZone == 14)
				{
					list5.Remove(Globals.Instance.GetNodeData("sahti_0"));
				}
				if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_void"), "") || (int)mapZone == 5)
				{
					list5.Remove(Globals.Instance.GetNodeData("voidlow_0"));
				}
			}
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_require_all_before_void"), "") && ((!AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sen"), "") && (int)mapZone != 0) || (!AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_faen"), "") && (int)mapZone != 3) || (!AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_aqua"), "") && (int)mapZone != 2) || (!AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_velka"), "") && (int)mapZone != 1) || (flag && !AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_ulmin"), "") && (int)mapZone != 12) || (flag2 && !AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_complete_sahti"), "") && (int)mapZone != 14)))
			{
				list5.Remove(Globals.Instance.GetNodeData("voidlow_0"));
			}
			List<EventReplyData> list6 = new List<EventReplyData>();
			int num = -1;
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_zonecount_1"), ""))
			{
				num = 1;
			}
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_zonecount_2"), ""))
			{
				num = 2;
			}
			if (AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_zonecount_3"), ""))
			{
				num = 3;
			}
			int num2 = ((num == -1) ? list5.Count : Math.Min(list5.Count, num));
			for (int l = 0; l < num2; l++)
			{
				NodeData val14 = list5[Random.Range(0, list5.Count)];
				EventReplyData val15 = val13.ShallowCopy();
				val15.ReplyActionText = (EventAction)0;
				val15.SsRequirementUnlock = null;
				if (!flag3)
				{
					if ((int)mapZone == 0)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_sen");
					}
					else if ((int)mapZone == 3)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_faen");
					}
					else if ((int)mapZone == 2)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_aqua");
					}
					else if ((int)mapZone == 1)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_velka");
					}
					else if ((int)mapZone == 12)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_ulmin");
					}
					else if ((int)mapZone == 14)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_sahti");
					}
					else if ((int)mapZone == 5)
					{
						val15.SsRequirementUnlock = Globals.Instance.GetRequirementData("endless_complete_void");
					}
				}
				val15.ReplyText = ((num == 1) ? "You are unable to focus and your mind races as you approach the obelisk." : GetPortalString(AtOManager.Instance.GetMapZone(val14.NodeId)));
				val15.SsRewardText = "";
				val15.SsNodeTravel = val14;
				val15.Init();
				list6.Add(val15);
				list5.Remove(val14);
			}
			Globals.Instance.GetEventData("e_endless_obelisk").Replys = list6.ToArray();
		}

		public static string GetPortalString(Zone zone)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return "Your focus on " + DictionaryExtensions.Get<Zone, string>((IDictionary<Zone, string>)portalStrings, zone, (string)null) + " world.";
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(EventManager), "FinalResolution")]
		public static void FinalResolutionPre(EventManager __instance, EventData ___currentEvent, EventReplyData ___replySelected)
		{
			if ((Object)(object)___currentEvent == (Object)null)
			{
				return;
			}
			if (___currentEvent.EventId != null && ___currentEvent.EventId.StartsWith("e_endless_", StringComparison.Ordinal))
			{
				RebuildEndlessReplyCache(___replySelected, "final-resolution:" + ___currentEvent.EventId);
				Plugin.LogInfo("[ENDLESS EVENT] Resolving " + ___currentEvent.EventId + " without native run-completion flags");
			}
			if (!(___currentEvent.EventId == "e_endless_blessing") || ___replySelected == null)
			{
				return;
			}
			CardDataNew val = ___replySelected.ReplyShowCard;
			if ((Object)(object)val == (Object)null && ___replySelected.SsAddCards != null && ___replySelected.SsAddCards.Count > 0)
			{
				val = ___replySelected.SsAddCards[0];
			}
			if ((Object)(object)val != (Object)null)
			{
				val = NormalizeBlessingCard(val);
				Plugin.LogInfo("Selected blessing: " + val.Id);
				activeBlessings.Add(val.Id);
				if ((Object)(object)val.Item != (Object)null && val.Item.MaxHealth > 0)
				{
					Hero[] teamHeroes = GetTeamHeroes();
					for (int i = 0; i < 4; i++)
					{
						if (teamHeroes[i] != null && (Object)(object)((Character)teamHeroes[i]).HeroData != (Object)null)
						{
							Hero obj = teamHeroes[i];
							((Character)obj).Hp = ((Character)obj).Hp + val.Item.MaxHealth;
							Hero obj2 = teamHeroes[i];
							((Character)obj2).HpCurrent = ((Character)obj2).HpCurrent + val.Item.MaxHealth;
							((Character)teamHeroes[i]).SetHP();
							((Character)teamHeroes[i]).ClearCaches();
						}
					}
				}
			}
			ClearEndlessCardRewards(___replySelected, "consume-selected-blessing");
			RebuildEndlessReplyCache(___replySelected, "blessing-no-card-reward");
			Plugin.LogInfo("[ENDLESS BLESSING] Selection stored; native card reward lists are empty (not null). Continuing native resolution.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EventManager), "FinalResolution")]
		public static void FinalResolutionPost(EventManager __instance, EventData ___currentEvent, EventReplyData ___replySelected)
		{
			if (((___currentEvent != null) ? ___currentEvent.EventId : null) == "e_endless_perk" && ___replySelected != null)
			{
				__instance.result.text = GetRandomPerkDescription(___replySelected.SsPerkData);
			}
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(EventManager), "FinalResolution")]
		public static Exception FinalResolutionFinalizer(Exception __exception, EventData ___currentEvent)
		{
			if (__exception != null && ___currentEvent != null && ___currentEvent.EventId != null && ___currentEvent.EventId.StartsWith("e_endless_", StringComparison.Ordinal))
			{
				Plugin.LogError($"[ENDLESS EVENT] FinalResolution failed for {___currentEvent.EventId}: {__exception}");
			}
			return __exception;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Globals), "GetPerkData")]
		public static void GetPerkData(Globals __instance, ref PerkData __result, ref Dictionary<string, PerkData> ____PerksSource, string id)
		{
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__result == (Object)null) || !id.StartsWith("endless_"))
			{
				return;
			}
			__result = ScriptableObject.CreateInstance<PerkData>();
			__result.Icon = Globals.Instance.GetAuraCurseData("burn").Sprite;
			__result.Id = id.ToLower();
			string[] array = id.Split(new char[1] { '_' })[1].Split(new char[1] { '#' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				string text = array2[0];
				string text2 = array2[1];
				switch (text)
				{
				case "h":
					__result.MaxHealth = int.Parse(text2);
					break;
				case "s":
					__result.SpeedQuantity = int.Parse(text2);
					break;
				case "a":
					__result.AuracurseBonus = Globals.Instance.GetAuraCurseData(text2);
					break;
				case "av":
					__result.AuracurseBonusValue = int.Parse(text2);
					break;
				case "d":
					__result.DamageFlatBonus = (DamageType)Enum.Parse(typeof(DamageType), $"{char.ToUpper(text2[0])}{text2.Substring(1).ToLower()}");
					break;
				case "dv":
					__result.DamageFlatBonusValue = int.Parse(text2);
					break;
				case "r":
					__result.ResistModified = (DamageType)Enum.Parse(typeof(DamageType), $"{char.ToUpper(text2[0])}{text2.Substring(1).ToLower()}");
					break;
				case "rv":
					__result.ResistModifiedValue = int.Parse(text2);
					break;
				case "e":
					__result.EnergyBegin = int.Parse(text2);
					break;
				}
			}
			__result.Init();
			____PerksSource.Add(__result.Id, __result);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PerksManager), "AddPerkToHero")]
		public static void AddPerkToHeroPost(Hero hero, string perkId, bool initHealth)
		{
			if ((Object)(object)Globals.Instance.GetPerkData(perkId) != (Object)null)
			{
				_ = ((Character)hero).SubclassName;
			}
		}

		public static void AddNewRequirement(string id, ref Dictionary<string, EventRequirementData> ____Requirements)
		{
			if (____Requirements.TryGetValue("_tier2", out var value))
			{
				EventRequirementData val = Object.Instantiate<EventRequirementData>(value);
				string requirementId = (((Object)val).name = id);
				val.RequirementId = requirementId;
				____Requirements.Add(val.RequirementId.ToLower(), val);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CardItem), "SetCard")]
		public static void SetCard(CardItem __instance, string id, bool deckScale, Hero _theHero, NPC _theNPC, bool GetFromGlobal, bool _generated, ref CardRealtimeData ___cardData, ref Transform ___targetTextT, ref Transform ___targetT, ref Transform ___requireTextT, ref Transform ___typeText, ref Transform ___typeTextImage, ref Transform ___descriptionTextT, ref TMP_Text ___descriptionTextTM)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (___cardData.CardType == blessingCardType)
			{
				if (((Component)___targetTextT).gameObject.activeSelf)
				{
					((Component)___targetTextT).gameObject.SetActive(false);
				}
				if (((Component)___targetT).gameObject.activeSelf)
				{
					((Component)___targetT).gameObject.SetActive(false);
				}
				if (((Component)___requireTextT).gameObject.activeSelf)
				{
					((Component)___requireTextT).gameObject.SetActive(false);
				}
				if (((Component)___typeText).gameObject.activeSelf)
				{
					((Component)___typeText).gameObject.SetActive(false);
				}
				if (((Component)___typeTextImage).gameObject.activeSelf)
				{
					((Component)___typeTextImage).gameObject.SetActive(false);
				}
				___descriptionTextT.localPosition = new Vector3(___descriptionTextT.localPosition.x, -0.63f, ___descriptionTextT.localPosition.z);
				___descriptionTextTM.margin = new Vector4(0.02f, -0.02f, 0.02f, -0.04f);
			}
		}

		public static CardDataNew AddNewCard(string id, string baseId, ref Dictionary<string, CardDataNew> ____CardsSource, ref Dictionary<string, CardRealtimeData> ____Cards)
		{
			if (____CardsSource.TryGetValue(baseId, out var value))
			{
				Plugin.LogInfo("Adding new card: " + id + " from " + baseId);
				CardDataNew val = Object.Instantiate<CardDataNew>(value);
				SetCardSourceField(val, "id", id);
				SetCardSourceField(val, "internalId", id);
				if ((Object)(object)val.Item != (Object)null)
				{
					ItemData val2 = Object.Instantiate<ItemData>(val.Item);
					val2.Id = id;
					SetCardSourceField<ItemData>(val, "item", val2);
				}
				if ((Object)(object)val.ItemEnchantment != (Object)null)
				{
					ItemData val3 = Object.Instantiate<ItemData>(val.ItemEnchantment);
					val3.Id = id;
					SetCardSourceField<ItemData>(val, "itemEnchantment", val3);
				}
				____CardsSource.Add(val.Id.ToLower(), val);
				____Cards.Add(val.Id.ToLower(), CreateRuntimeCard(val));
				return val;
			}
			return null;
		}

		private static void InitNewCard(CardDataNew newCard, ref Dictionary<CardType, List<string>> ____CardItemByType, ref Dictionary<CardType, List<string>> ____CardListByType, ref Dictionary<CardClass, List<string>> ____CardListByClass, ref List<string> ____CardListNotUpgraded, ref Dictionary<CardClass, List<string>> ____CardListNotUpgradedByClass, ref Dictionary<string, List<string>> ____CardListByClassType, ref Dictionary<string, int> ____CardEnergyCost)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			CardRealtimeData val = Globals.Instance.GetCardData(newCard.Id, false) ?? CreateRuntimeCard(newCard);
			____CardEnergyCost[newCard.Id] = val.EnergyCost;
			Globals.Instance.IncludeInSearch(newCard.CardName, newCard.Id, true);
			if (!____CardListByClass.ContainsKey(val.CardClass))
			{
				____CardListByClass[val.CardClass] = new List<string>();
			}
			____CardListByClass[val.CardClass].Add(newCard.Id);
			if ((int)val.CardUpgraded == 0)
			{
				if (!____CardListNotUpgradedByClass.ContainsKey(val.CardClass))
				{
					____CardListNotUpgradedByClass[val.CardClass] = new List<string>();
				}
				____CardListNotUpgradedByClass[val.CardClass].Add(newCard.Id);
				____CardListNotUpgraded.Add(newCard.Id);
				if ((int)val.CardClass == 8)
				{
					if (!____CardItemByType.ContainsKey(val.CardType))
					{
						____CardItemByType.Add(val.CardType, new List<string>());
					}
					____CardItemByType[val.CardType].Add(newCard.Id);
				}
			}
			List<CardType> cardTypes = val.GetCardTypes();
			for (int i = 0; i < cardTypes.Count; i++)
			{
				if (!____CardListByType.ContainsKey(cardTypes[i]))
				{
					____CardListByType.Add(cardTypes[i], new List<string>());
				}
				____CardListByType[cardTypes[i]].Add(newCard.Id);
				string key = Enum.GetName(typeof(CardClass), val.CardClass) + "_" + Enum.GetName(typeof(CardType), cardTypes[i]);
				if (!____CardListByClassType.ContainsKey(key))
				{
					____CardListByClassType[key] = new List<string>();
				}
				____CardListByClassType[key].Add(newCard.Id);
				Globals.Instance.IncludeInSearch(Texts.Instance.GetText(Enum.GetName(typeof(CardType), cardTypes[i]), ""), newCard.Id, true);
			}
			val.PostInit();
			CardDescriptionExtension.SetDescriptionNew(val, true, (Character)null, false);
		}

		public static CardDataNew CloneBlessingCard(string cardId, bool isBlessing, ref Dictionary<string, CardDataNew> ____CardsSource, ref Dictionary<string, CardRealtimeData> ____Cards, ref Dictionary<CardType, List<string>> ____CardItemByType, ref Dictionary<CardType, List<string>> ____CardListByType, ref Dictionary<CardClass, List<string>> ____CardListByClass, ref List<string> ____CardListNotUpgraded, ref Dictionary<CardClass, List<string>> ____CardListNotUpgradedByClass, ref Dictionary<string, List<string>> ____CardListByClassType, ref Dictionary<string, int> ____CardEnergyCost)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Invalid comparison between Unknown and I4
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Invalid comparison between Unknown and I4
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Invalid comparison between Unknown and I4
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Invalid comparison between Unknown and I4
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Invalid comparison between Unknown and I4
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Invalid comparison between Unknown and I4
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			//IL_0145: 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_015c: Invalid comparison between Unknown and I4
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Invalid comparison between Unknown and I4
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Invalid comparison between Unknown and I4
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Invalid comparison between Unknown and I4
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Invalid comparison between Unknown and I4
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Invalid comparison between Unknown and I4
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Invalid comparison between Unknown and I4
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			if (____CardsSource.TryGetValue("endless" + cardId, out var value))
			{
				Plugin.LogInfo("Got existing card: " + value.Id);
				return value;
			}
			Plugin.LogInfo("Creating blessing card endless" + cardId);
			CardDataNew val = AddNewCard("endless" + cardId, cardId, ref ____CardsSource, ref ____Cards);
			SetCardSourceField(val, "cardName", "Blessing: " + val.CardName);
			if (isBlessing)
			{
				SetCardSourceField<CardType>(val, "cardType", blessingCardType);
			}
			SetCardSourceField<CardClass>(val, "cardClass", (CardClass)9);
			ItemData val2 = val.Item ?? val.ItemEnchantment;
			if ((Object)(object)val2 != (Object)null)
			{
				if ((int)val2.CastedCardType != 0)
				{
					val2.CastedCardType = (CardType)0;
				}
				if ((int)val2.ItemTarget == 4)
				{
					val2.ItemTarget = (ItemTarget)3;
				}
				else if ((int)val2.ItemTarget == 3)
				{
					val2.ItemTarget = (ItemTarget)4;
				}
				if ((int)val2.ItemTarget == 2)
				{
					val2.ItemTarget = (ItemTarget)1;
				}
				else if ((int)val2.ItemTarget == 1)
				{
					val2.ItemTarget = (ItemTarget)2;
				}
				if ((int)val2.ItemTarget == 10)
				{
					val2.ItemTarget = (ItemTarget)8;
				}
				else if ((int)val2.ItemTarget == 8)
				{
					val2.ItemTarget = (ItemTarget)10;
				}
				if ((int)val2.ItemTarget == 9)
				{
					val2.ItemTarget = (ItemTarget)7;
				}
				else if ((int)val2.ItemTarget == 7)
				{
					val2.ItemTarget = (ItemTarget)9;
				}
				if ((int)val2.ItemTarget == 0)
				{
					val2.ItemTarget = (ItemTarget)6;
				}
				else if ((int)val2.ItemTarget == 6)
				{
					val2.ItemTarget = (ItemTarget)0;
				}
				if ((int)val2.CardPlace == 1 && val2.CardNum > 0)
				{
					val2.CardPlace = (CardPlace)5;
				}
				if ((int)val2.CardPlace == 5 && val2.CardNum > 0 && ((int)val2.Activation == 2 || (int)val2.Activation == 28))
				{
					val2.Activation = (EventActivation)22;
				}
				if (val2.CardNum == 0 && (int)val2.Activation == 28)
				{
					val2.Activation = blessingBeginRound;
				}
				if (val2.CardNum == 0 && (int)val2.Activation == 27)
				{
					val2.Activation = blessingCombatStart;
				}
				if ((Object)(object)val2.CardToGain != (Object)null)
				{
					val2.CardToGain = CloneBlessingCard(val2.CardToGain.Id, isBlessing: false, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
					SetCardSourceField(val2.CardToGain, "playable", value: true);
				}
				else if (val2.CardToGainList != null && val2.CardToGainList.Count > 0)
				{
					List<CardDataNew> list = new List<CardDataNew>();
					foreach (CardDataNew cardToGain in val2.CardToGainList)
					{
						CardDataNew val3 = CloneBlessingCard(cardToGain.Id, isBlessing: false, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
						SetCardSourceField(val3, "playable", value: true);
						list.Add(val3);
					}
					val2.CardToGainList = list;
				}
				if ((Object)(object)val.ItemEnchantment != (Object)null)
				{
					SetCardSourceField<ItemData>(val, "itemEnchantment", val2);
				}
				else
				{
					SetCardSourceField<ItemData>(val, "item", val2);
				}
			}
			SetCardSourceField(val, "effectRequired", "");
			if (val.Upgrade.UpgradedFrom != "")
			{
				SetCardSourceField<UpgradeData>(val, "upgrade", new UpgradeData(val.Upgrade.UpgradesTo1, val.Upgrade.UpgradesTo2, val.Upgrade.CardUpgraded, "endless" + val.Upgrade.UpgradedFrom.ToLower(), val.Upgrade.UpgradesToRare));
			}
			if (val.Upgrade.UpgradesTo1 != "")
			{
				CardDataNew val4 = CloneBlessingCard(val.Upgrade.UpgradesTo1.ToLower(), isBlessing: true, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
				SetCardSourceField<UpgradeData>(val, "upgrade", new UpgradeData(val4.Id, val.Upgrade.UpgradesTo2, val.Upgrade.CardUpgraded, val.Upgrade.UpgradedFrom, val.Upgrade.UpgradesToRare));
			}
			if (val.Upgrade.UpgradesTo2 != "")
			{
				CardDataNew val5 = CloneBlessingCard(val.Upgrade.UpgradesTo2.ToLower(), isBlessing: true, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
				SetCardSourceField<UpgradeData>(val, "upgrade", new UpgradeData(val.Upgrade.UpgradesTo1, val5.Id, val.Upgrade.CardUpgraded, val.Upgrade.UpgradedFrom, val.Upgrade.UpgradesToRare));
			}
			if ((Object)(object)val.Upgrade.UpgradesToRare != (Object)null)
			{
				CardDataNew val6 = CloneBlessingCard(val.Upgrade.UpgradesToRare.Id, isBlessing: true, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
				SetCardSourceField<UpgradeData>(val, "upgrade", new UpgradeData(val.Upgrade.UpgradesTo1, val.Upgrade.UpgradesTo2, val.Upgrade.CardUpgraded, val.Upgrade.UpgradedFrom, val6));
			}
			RefreshRuntimeCard(val, ref ____Cards);
			InitNewCard(val, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
			return val;
		}

		public static CardRealtimeData CreateCard()
		{
			return null;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Globals), "GetExperienceByLevel")]
		public static void GetExperienceByLevel(ref Globals __instance, int level, ref int __result)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge() && AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), ""))
			{
				if (level == 5)
				{
					__result = 2250;
				}
				if (level == 6)
				{
					__result = 3000;
				}
				if (level == 7)
				{
					__result = 4000;
				}
				if (level == 8)
				{
					__result = 6000;
				}
				if (level >= 9)
				{
					__result = 99999;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Character), "CalculateRewardForCharacter")]
		public static void CalculateRewardForCharacter(ref Character __instance, ref int _experience, ref int __result)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge() && AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), "") && AtOManager.Instance.GetActNumberForText("") - 1 >= 5)
			{
				if (AtOManager.Instance.IsChallengeTraitActive("smartheroes"))
				{
					_experience += Functions.FuncRoundToInt((float)_experience * 0.5f);
				}
				float num = 0.1f;
				if (__instance.Level > AtOManager.Instance.GetActNumberForText(""))
				{
					__result = Functions.FuncRoundToInt((float)_experience * num);
				}
				else if (__instance.Experience >= Globals.Instance.GetExperienceByLevel(__instance.Level))
				{
					__result = Functions.FuncRoundToInt((float)_experience * num);
				}
				else if (__instance.Experience + _experience > Globals.Instance.GetExperienceByLevel(__instance.Level))
				{
					int num2 = _experience - (Globals.Instance.GetExperienceByLevel(__instance.Level) - __instance.Experience);
					__result = Globals.Instance.GetExperienceByLevel(__instance.Level) - __instance.Experience + Functions.FuncRoundToInt((float)num2 * num);
				}
				else
				{
					__result = _experience;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(OverCharacter), "DoStats")]
		public static void DoStats(ref OverCharacter __instance, ref Hero ___hero)
		{
			if (!GameManager.Instance.IsObeliskChallenge() && !GameManager.Instance.IsWeeklyChallenge() && AtOManager.Instance.PlayerHasRequirement(Globals.Instance.GetRequirementData("endless_allow_additional_levels"), ""))
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("L");
				stringBuilder.Append(((Character)___hero).Level);
				if (((Character)___hero).Level < 9)
				{
					stringBuilder.Append("  <voffset=.15><size=-.5><color=#FFC086>[");
					stringBuilder.Append(((Character)___hero).Experience);
					stringBuilder.Append("/");
					stringBuilder.Append(Globals.Instance.GetExperienceByLevel(((Character)___hero).Level));
					stringBuilder.Append("]");
				}
				__instance.experienceText.text = stringBuilder.ToString();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Globals), "CreateGameContent")]
		public static void CreateGameContentPostfix(Globals __instance, ref Coroutine __result)
		{
			Plugin.LogInfo("Scheduling Endless content initialization");
			__result = ((MonoBehaviour)__instance).StartCoroutine(InitializeEndlessAfterContent(__instance, __result));
		}

		private static IEnumerator InitializeEndlessAfterContent(Globals globals, Coroutine original)
		{
			Plugin.LogInfo("Waiting for game content initialization");
			yield return original;
			Plugin.LogInfo("Game content ready; initializing Endless content");
			try
			{
				CreateGameContent(globals);
				Plugin.LogInfo("Endless content initialization complete");
			}
			catch (Exception ex)
			{
				Plugin.LogError("Endless content initialization failed: " + ex);
				throw;
			}
		}

		private static void CreateGameContent(Globals __instance)
		{
			Traverse obj = Traverse.Create((object)__instance);
			Dictionary<string, EventData> value = obj.Field<Dictionary<string, EventData>>("_Events").Value;
			Dictionary<string, NodeData> value2 = obj.Field<Dictionary<string, NodeData>>("_NodeDataSource").Value;
			Dictionary<string, CombatData> value3 = obj.Field<Dictionary<string, CombatData>>("_CombatDataSource").Value;
			Dictionary<string, CinematicData> value4 = obj.Field<Dictionary<string, CinematicData>>("_Cinematics").Value;
			Dictionary<string, EventRequirementData> ____Requirements = obj.Field<Dictionary<string, EventRequirementData>>("_Requirements").Value;
			Dictionary<string, CardDataNew> ____CardsSource = obj.Field<Dictionary<string, CardDataNew>>("_CardsSource").Value;
			Dictionary<string, CardRealtimeData> ____Cards = obj.Field<Dictionary<string, CardRealtimeData>>("_Cards").Value;
			Dictionary<CardType, List<string>> ____CardItemByType = obj.Field<Dictionary<CardType, List<string>>>("_CardItemByType").Value;
			Dictionary<CardType, List<string>> ____CardListByType = obj.Field<Dictionary<CardType, List<string>>>("_CardListByType").Value;
			Dictionary<CardClass, List<string>> ____CardListByClass = obj.Field<Dictionary<CardClass, List<string>>>("_CardListByClass").Value;
			List<string> ____CardListNotUpgraded = obj.Field<List<string>>("_CardListNotUpgraded").Value;
			Dictionary<CardClass, List<string>> ____CardListNotUpgradedByClass = obj.Field<Dictionary<CardClass, List<string>>>("_CardListNotUpgradedByClass").Value;
			Dictionary<string, List<string>> ____CardListByClassType = obj.Field<Dictionary<string, List<string>>>("_CardListByClassType").Value;
			Dictionary<string, int> ____CardEnergyCost = obj.Field<Dictionary<string, int>>("_CardEnergyCost").Value;
			if (GameManager.Instance.IsObeliskChallenge() || GameManager.Instance.IsWeeklyChallenge())
			{
				return;
			}
			foreach (string blessingCard in blessingCards)
			{
				CardDataNew val = CloneBlessingCard(blessingCard, isBlessing: true, ref ____CardsSource, ref ____Cards, ref ____CardItemByType, ref ____CardListByType, ref ____CardListByClass, ref ____CardListNotUpgraded, ref ____CardListNotUpgradedByClass, ref ____CardListByClassType, ref ____CardEnergyCost);
				availableBlessings.Add(val.Id);
			}
			GameManager.Instance.cardSprites = GameManager.Instance.cardSprites.Concat(GameManager.Instance.cardSprites.Where((Sprite c) => ((Object)c).name == "card-bg-special")).ToArray();
			AddNewRequirement("endless_complete_sen", ref ____Requirements);
			AddNewRequirement("endless_complete_faen", ref ____Requirements);
			AddNewRequirement("endless_complete_aqua", ref ____Requirements);
			AddNewRequirement("endless_complete_ulmin", ref ____Requirements);
			AddNewRequirement("endless_complete_velka", ref ____Requirements);
			AddNewRequirement("endless_complete_sahti", ref ____Requirements);
			AddNewRequirement("endless_complete_void", ref ____Requirements);
			AddNewRequirement("endless_unique_zones", ref ____Requirements);
			AddNewRequirement("endless_allow_repeats", ref ____Requirements);
			AddNewRequirement("endless_require_all_before_void", ref ____Requirements);
			AddNewRequirement("endless_allow_perks", ref ____Requirements);
			AddNewRequirement("endless_allow_blessings", ref ____Requirements);
			AddNewRequirement("endless_allow_blessings_starting_4", ref ____Requirements);
			AddNewRequirement("endless_allow_b