Decompiled source of SoulstoneCoop v1.5.0

BepInEx/plugins/SoulstoneCoop.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ECM2.Characters;
using ECM2.Components;
using GameSmithing;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SoulstoneCoop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0")]
[assembly: AssemblyProduct("Soulstone Coop")]
[assembly: AssemblyTitle("SoulstoneCoop")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SoulstoneCoop
{
	internal static class CoopAscensions
	{
		private enum State
		{
			Unknown,
			Started,
			Paused
		}

		private sealed class Ascension
		{
			public string Name;

			public Func<Entity, Component> Get;

			public Func<Component, bool> SetUp;

			public Func<Component, bool> Paused;

			public Action<Component, PlayerPrefabReferences> SetModel;

			public Func<Component, Entity, IEnumerator> Routine;
		}

		private static State _p1 = State.Unknown;

		private static bool _mirroring;

		private static readonly Ascension[] Ascensions = new Ascension[8]
		{
			new Ascension
			{
				Name = "panther",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<NaturesGuardianComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<NaturesGuardianComponent>()._setUp,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<NaturesGuardianComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<NaturesGuardianComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<NaturesGuardianComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Arcane Power",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<ArcanePowerComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<ArcanePowerComponent>()._setUp,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<ArcanePowerComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<ArcanePowerComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<ArcanePowerComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Concentration",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<ConcentrationComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<ConcentrationComponent>()._setUp,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<ConcentrationComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<ConcentrationComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<ConcentrationComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Demonic Binding",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<DemonicBindingComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<DemonicBindingComponent>()._isSetup,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<DemonicBindingComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<DemonicBindingComponent>()._originalModel = m;
				},
				Routine = delegate(Component c, Entity e)
				{
					string text = DemonicModelPath();
					return (text == null) ? null : ((Il2CppObjectBase)c).Cast<DemonicBindingComponent>().SetupAscensionModelRoutine(e, text);
				}
			},
			new Ascension
			{
				Name = "Divine Inspiration",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<DivineInspirationComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<DivineInspirationComponent>()._setUp,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<DivineInspirationComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<DivineInspirationComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<DivineInspirationComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Mechatron",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<MechatronComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<MechatronComponent>()._setUp,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<MechatronComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<MechatronComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<MechatronComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Myrmidon's Favor",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<MyrmidonFavorComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<MyrmidonFavorComponent>().HasCompletedSetup,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<MyrmidonFavorComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<MyrmidonFavorComponent>().OriginalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<MyrmidonFavorComponent>().SetupAscensionModelRoutine(e)
			},
			new Ascension
			{
				Name = "Siege Expert",
				Get = (Entity e) => (Component)(object)((Component)e).GetComponent<SiegeExpertComponent>(),
				SetUp = (Component c) => ((Il2CppObjectBase)c).Cast<SiegeExpertComponent>()._isSetup,
				Paused = (Component c) => ((Il2CppObjectBase)c).Cast<SiegeExpertComponent>()._isPaused,
				SetModel = delegate(Component c, PlayerPrefabReferences m)
				{
					((Il2CppObjectBase)c).Cast<SiegeExpertComponent>()._originalModel = m;
				},
				Routine = (Component c, Entity e) => ((Il2CppObjectBase)c).Cast<SiegeExpertComponent>().SetupAscensionModelRoutine(e)
			}
		};

		private static readonly List<(Entity e, int slot, CharactersType hero, CharacterSkinData skin, float at, bool retried)> _checks = new List<(Entity, int, CharactersType, CharacterSkinData, float, bool)>();

		private static string _demonicPath;

		private static bool IsP1(Entity e)
		{
			try
			{
				List<Entity> playerEntities = GameManagerUtil.PlayerEntities;
				return (Object)(object)e != (Object)null && playerEntities != null && playerEntities.Count > 1 && (Object)(object)playerEntities[0] != (Object)null && ((Il2CppObjectBase)playerEntities[0]).Pointer == ((Il2CppObjectBase)e).Pointer;
			}
			catch
			{
				return false;
			}
		}

		private static void ForExtras(string what, Action<Entity> action)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if (_mirroring)
			{
				return;
			}
			_mirroring = true;
			try
			{
				List<Entity> playerEntities = GameManagerUtil.PlayerEntities;
				int num = 1;
				bool flag = default(bool);
				while (playerEntities != null && num < playerEntities.Count)
				{
					Entity val = playerEntities[num];
					if (!((Object)(object)val == (Object)null) && !((Il2CppObjectBase)val).WasCollected)
					{
						try
						{
							action(val);
						}
						catch (Exception ex)
						{
							ManualLogSource log = Plugin.Log;
							BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(19, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(what);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on P");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num + 1);
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
							}
							log.LogWarning(val2);
						}
					}
					num++;
				}
			}
			finally
			{
				_mirroring = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Entity), "StartAscension")]
		private static void Started(Entity __instance)
		{
			if (IsP1(__instance))
			{
				if (_p1 != State.Started)
				{
					Plugin.Log.LogInfo((object)"[Ascension] P1's unique skill started: extras too.");
				}
				_p1 = State.Started;
				ForExtras("start", delegate(Entity e)
				{
					e.StartAscension();
				});
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Entity), "PauseAscension")]
		private static void Paused(Entity __instance)
		{
			if (!IsP1(__instance))
			{
				return;
			}
			if ((Object)(object)__instance._health != (Object)null && __instance._health.HasBeenKilled)
			{
				Plugin.Log.LogInfo((object)"[Ascension] P1's unique skill paused by their death: not copied to the extras.");
				return;
			}
			if (_p1 != State.Paused)
			{
				Plugin.Log.LogInfo((object)"[Ascension] P1's unique skill paused: extras too.");
			}
			_p1 = State.Paused;
			ForExtras("pause", delegate(Entity e)
			{
				e.PauseAscension();
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Entity), "ResetAscensions")]
		private static void Reset(Entity __instance)
		{
			if (IsP1(__instance))
			{
				ForExtras("reset", delegate(Entity e)
				{
					e.ResetAscensions();
				});
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Entity), "SetAscensionWithSpawnPoints")]
		private static void SpawnPoints(Entity __instance)
		{
			if (IsP1(__instance))
			{
				ForExtras("spawn points", delegate(Entity e)
				{
					e.SetAscensionWithSpawnPoints();
				});
			}
		}

		internal static void OnRevived(Entity e, int slot)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if ((Object)(object)e == (Object)null || _p1 == State.Paused)
			{
				return;
			}
			_mirroring = slot > 0;
			bool flag = default(bool);
			try
			{
				e.StartAscension();
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" got up: unique skill started again.");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(23, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" restart: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val2);
			}
			finally
			{
				_mirroring = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameManagerUtil), "StartMatch")]
		private static void NewMatch()
		{
			_p1 = State.Unknown;
		}

		internal static void RetryModelSetup(Entity e, int slot, CharactersType hero, CharacterSkinData skin)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			bool flag2 = default(bool);
			try
			{
				NaturesGuardianComponent val = (((Object)(object)e != (Object)null) ? ((Component)e).GetComponent<NaturesGuardianComponent>() : null);
				if ((Object)(object)val == (Object)null || val._setUp)
				{
					return;
				}
				PlayerPrefabReferences val2 = e.PlayerPrefabReference;
				bool flag = (Object)(object)val2 != (Object)null;
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)e).GetComponentInChildren<PlayerPrefabReferences>();
				}
				if ((Object)(object)val2 == (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(55, 1, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Ascension] P");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(slot + 1);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s panther: the hero has no model to copy.");
					}
					log.LogWarning(val3);
					return;
				}
				if (!flag)
				{
					e.PlayerPrefabReference = val2;
				}
				bool flag3 = !string.IsNullOrEmpty(val2.SpawnedCharacterSkinId);
				if (!flag3 && skin != null)
				{
					val2.SpawnedCharacterSkinId = skin.CharacterSkinID;
				}
				val._originalModel = val2;
				PlayerProfileSelectedCharacter selectedCharacter = Global.PlayerProfile.SelectedCharacter;
				CharactersType characterIdAsEnum = selectedCharacter.CharacterIdAsEnum;
				try
				{
					selectedCharacter.CharacterIdAsEnum = hero;
					((MonoBehaviour)JobRunner.Instance).StartCoroutine(val.SetupAscensionModelRoutine(e));
				}
				finally
				{
					selectedCharacter.CharacterIdAsEnum = characterIdAsEnum;
				}
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(68, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("'s panther wasn't set up; set up again (model ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(flag ? "ok" : "was missing");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", skin ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(flag3 ? "ok" : "was missing");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(").");
				}
				log2.LogInfo(val4);
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(31, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s panther setup: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
				}
				log3.LogWarning(val3);
			}
			finally
			{
				_checks.Add((e, slot, hero, skin, Time.unscaledTime + 5f, false));
			}
		}

		private static string DemonicModelPath()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!string.IsNullOrEmpty(_demonicPath))
			{
				return _demonicPath;
			}
			try
			{
				foreach (SkillTreeDemonicBindingSO item in Resources.FindObjectsOfTypeAll<SkillTreeDemonicBindingSO>())
				{
					if ((Object)(object)item != (Object)null && !string.IsNullOrEmpty(item.AscensionModelPrefabName))
					{
						_demonicPath = item.AscensionModelPrefabName;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Ascension] Demonic Binding model path: " + ex.Message));
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Ascension] Demonic Binding model path: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_demonicPath ?? "not found");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
			return _demonicPath;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameLoop), "Update")]
		private static void CheckModelSetup()
		{
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			if (_checks.Count == 0)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			bool flag4 = default(bool);
			for (int num = _checks.Count - 1; num >= 0; num--)
			{
				(Entity, int, CharactersType, CharacterSkinData, float, bool) tuple = _checks[num];
				if (!(unscaledTime < tuple.Item5))
				{
					_checks.RemoveAt(num);
					try
					{
						if (!((Object)(object)tuple.Item1 == (Object)null) && !((Il2CppObjectBase)tuple.Item1).WasCollected)
						{
							bool flag = false;
							Ascension[] ascensions = Ascensions;
							foreach (Ascension ascension in ascensions)
							{
								Component val = ascension.Get(tuple.Item1);
								if ((Object)(object)val == (Object)null)
								{
									continue;
								}
								bool flag2 = ascension.SetUp(val);
								bool flag3 = ascension.Paused(val);
								ManualLogSource log = Plugin.Log;
								BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(28, 5, ref flag4);
								if (flag4)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(tuple.Item2 + 1);
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ascension.Name);
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag2 ? "is set up" : "is NOT set up");
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (paused ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(flag3);
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(tuple.Item6 ? ", after a second setup" : "");
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(").");
								}
								log.LogInfo(val2);
								if (flag2 || flag3 || tuple.Item6)
								{
									continue;
								}
								if (ascension.Routine == null)
								{
									ManualLogSource log2 = Plugin.Log;
									BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(51, 2, ref flag4);
									if (flag4)
									{
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Ascension] P");
										((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(tuple.Item2 + 1);
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s ");
										((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ascension.Name);
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": can't be set up again by the mod.");
									}
									log2.LogWarning(val3);
								}
								else
								{
									flag |= SetUpAgain(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, ascension, val);
								}
							}
							if (flag)
							{
								_checks.Add((tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, unscaledTime + 5f, true));
							}
						}
					}
					catch (Exception ex)
					{
						ManualLogSource log3 = Plugin.Log;
						BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(21, 2, ref flag4);
						if (flag4)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[Ascension] P");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(tuple.Item2 + 1);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" check: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
						}
						log3.LogWarning(val3);
					}
				}
			}
		}

		private static bool SetUpAgain(Entity e, int slot, CharactersType hero, CharacterSkinData skin, Ascension a, Component comp)
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			bool flag2 = default(bool);
			try
			{
				PlayerPrefabReferences val = e.PlayerPrefabReference ?? ((Component)e).GetComponentInChildren<PlayerPrefabReferences>();
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(48, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(slot + 1);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(a.Name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": the hero has no model to copy.");
					}
					log.LogWarning(val2);
					return false;
				}
				e.PlayerPrefabReference = val;
				if (string.IsNullOrEmpty(val.SpawnedCharacterSkinId) && skin != null)
				{
					val.SpawnedCharacterSkinId = skin.CharacterSkinID;
				}
				a.SetModel(comp, val);
				PlayerProfileSelectedCharacter selectedCharacter = Global.PlayerProfile.SelectedCharacter;
				CharactersType characterIdAsEnum = selectedCharacter.CharacterIdAsEnum;
				try
				{
					selectedCharacter.CharacterIdAsEnum = hero;
					IEnumerator val3 = a.Routine(comp, e);
					if (val3 == null)
					{
						ManualLogSource log2 = Plugin.Log;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 2, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(slot + 1);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(a.Name);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": nothing to run.");
						}
						log2.LogWarning(val2);
						return false;
					}
					((MonoBehaviour)JobRunner.Instance).StartCoroutine(val3);
				}
				finally
				{
					selectedCharacter.CharacterIdAsEnum = characterIdAsEnum;
				}
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("'s ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(a.Name);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" set up again.");
				}
				log3.LogInfo(val4);
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log4 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(24, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(a.Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" setup: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log4.LogWarning(val2);
				return false;
			}
		}

		internal static void Sync(Entity e, int slot)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)(object)e == (Object)null)
			{
				return;
			}
			_mirroring = true;
			bool flag = default(bool);
			try
			{
				if (_p1 == State.Paused)
				{
					e.PauseAscension();
				}
				else
				{
					e.StartAscension();
				}
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s unique skill ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((_p1 == State.Paused) ? "paused" : "started");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (P1's: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<State>(_p1);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				log.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(20, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Ascension] P");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(slot + 1);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" sync: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				log2.LogWarning(val2);
			}
			finally
			{
				_mirroring = false;
			}
		}
	}
	internal static class CoopBackToTitle
	{
		private static MainMenuState? _state;

		private static float _stateSince;

		private static GameObject _canvas;

		private static GameObject _hint;

		private static GameObject _dialog;

		private static Image _black;

		private static EventSystem _disabledEvents;

		private static GameObject _previousSelected;

		private static bool _asking;

		private static bool _leaving;

		private static float _fade;

		private static float _waitTitleUntil;

		private static float _nextTitleSearch;

		private static OptionsScreenPanel _options;

		private static QuitScreenPanel _quit;

		private static int _phase;

		private static void Info(string msg)
		{
			Plugin.Log.LogInfo((object)("[BackToTitle] " + msg));
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuManager), "OpenState")]
		private static void Opened(MainMenuState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			_state = state;
			_stateSince = Time.unscaledTime;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuManager), "CloseState")]
		private static void Closed(MainMenuState state)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (_state == (MainMenuState?)state)
			{
				_state = null;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(OptionsScreenPanel), "Open")]
		private static void OptionsOpened(OptionsScreenPanel __instance)
		{
			_options = __instance;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuitScreenPanel), "Open")]
		private static void QuitOpened(QuitScreenPanel __instance)
		{
			_quit = __instance;
		}

		private static bool OverlayOpen()
		{
			try
			{
				if ((Object)(object)_options != (Object)null && !((Il2CppObjectBase)_options).WasCollected && (Object)(object)_options.AnimationGroup != (Object)null && _options.AnimationGroup.TargetVisibility > 0.5f)
				{
					return true;
				}
				if ((Object)(object)_quit != (Object)null && !((Il2CppObjectBase)_quit).WasCollected && (Object)(object)_quit.AnimationGroup != (Object)null && _quit.AnimationGroup.TargetVisibility > 0.5f)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameLoop), "LateUpdate")]
		private static void Tick()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			try
			{
				if (_leaving)
				{
					UpdateLeaving();
					return;
				}
				bool flag = _state == (MainMenuState?)0 || ((int)_state.GetValueOrDefault() == 2 && CoopSetup.TurnSlot >= 0);
				if (!(!CoopInput.InMatch() && flag) || OverlayOpen() || !Plugin.BackToTitleButton.Value)
				{
					if (_asking)
					{
						CloseDialog();
					}
					if ((Object)(object)_hint != (Object)null && _hint.activeSelf)
					{
						_hint.SetActive(false);
					}
					return;
				}
				EnsureUi();
				if (_hint.activeSelf == _asking)
				{
					_hint.SetActive(!_asking);
				}
				if (Time.unscaledTime - _stateSince < 0.3f)
				{
					return;
				}
				if (_asking)
				{
					EventSystem current = EventSystem.current;
					if ((Object)(object)current != (Object)null && (Object)(object)current.currentSelectedGameObject != (Object)null)
					{
						current.SetSelectedGameObject((GameObject)null);
					}
					bool num = ConfirmPressed();
					bool flag2 = !num && BackPressed();
					if (num)
					{
						CloseDialog();
						StartLeaving();
					}
					else if (flag2)
					{
						CloseDialog();
						Info("cancelled.");
					}
				}
				else if (BackPressed())
				{
					OpenDialog();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[BackToTitle] " + ex.Message));
			}
		}

		private static bool BackPressed()
		{
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current.backspaceKey).wasPressedThisFrame)
			{
				return true;
			}
			Enumerator<Gamepad> enumerator = Gamepad.all.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Gamepad current2 = enumerator.Current;
				if (current2 != null && current2.buttonEast.wasPressedThisFrame)
				{
					return true;
				}
			}
			return false;
		}

		private static bool ConfirmPressed()
		{
			Keyboard current = Keyboard.current;
			if (current != null && (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame || ((ButtonControl)current.spaceKey).wasPressedThisFrame))
			{
				return true;
			}
			Enumerator<Gamepad> enumerator = Gamepad.all.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Gamepad current2 = enumerator.Current;
				if (current2 != null && (current2.buttonSouth.wasPressedThisFrame || current2.startButton.wasPressedThisFrame))
				{
					return true;
				}
			}
			return false;
		}

		[Conditional("COOP_TESTING")]
		private static void LogPresses(bool confirm, bool back)
		{
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current.anyKey).wasPressedThisFrame)
			{
				Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator();
				while (enumerator.MoveNext())
				{
					KeyControl current2 = enumerator.Current;
					if (current2 != null && ((ButtonControl)current2).wasPressedThisFrame)
					{
						Info($"key {((InputControl)current2).name} pressed (confirm {confirm}, cancel {back}).");
					}
				}
			}
			Enumerator<Gamepad> enumerator2 = Gamepad.all.GetEnumerator();
			while (enumerator2.MoveNext())
			{
				Gamepad current3 = enumerator2.Current;
				if (current3 == null)
				{
					continue;
				}
				ButtonControl[] array = (ButtonControl[])(object)new ButtonControl[6] { current3.buttonSouth, current3.buttonEast, current3.buttonWest, current3.buttonNorth, current3.startButton, current3.selectButton };
				foreach (ButtonControl val in array)
				{
					if (val != null && val.wasPressedThisFrame)
					{
						Info($"'{((InputControl)current3).displayName}' {((InputControl)val).name} pressed (confirm {confirm}, cancel {back}).");
					}
				}
			}
		}

		private static void OpenDialog()
		{
			_asking = true;
			_dialog.SetActive(true);
			EventSystem current = EventSystem.current;
			if ((Object)(object)current != (Object)null)
			{
				_disabledEvents = current;
				_previousSelected = current.currentSelectedGameObject;
				current.SetSelectedGameObject((GameObject)null);
			}
			Info("asked.");
		}

		private static void CloseDialog()
		{
			_asking = false;
			if ((Object)(object)_dialog != (Object)null)
			{
				_dialog.SetActive(false);
			}
			if (!((Object)(object)_disabledEvents != (Object)null))
			{
				return;
			}
			try
			{
				if ((Object)(object)_previousSelected != (Object)null)
				{
					_disabledEvents.SetSelectedGameObject(_previousSelected);
				}
			}
			catch
			{
			}
			_disabledEvents = null;
			_previousSelected = null;
		}

		private static void StartLeaving()
		{
			_leaving = true;
			_fade = 0f;
			if ((Object)(object)_hint != (Object)null)
			{
				_hint.SetActive(false);
			}
			((Component)_black).gameObject.SetActive(true);
			Info("fading out.");
		}

		private static void UpdateLeaving()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			if (_phase == 0)
			{
				_fade = Math.Min(1f, _fade + unscaledDeltaTime / 0.4f);
				SetBlack(_fade);
				if (!(_fade < 1f))
				{
					_phase = 1;
					Global.ClearPlayerProfileOnMenuManagerLoad = true;
					Scene activeScene = SceneManager.GetActiveScene();
					string name = ((Scene)(ref activeScene)).name;
					_state = null;
					_waitTitleUntil = Time.unscaledTime + 10f;
					Info("loading '" + name + "' again (title screen).");
					SceneManager.LoadScene(name);
				}
			}
			else if (_phase == 1)
			{
				if (!(Time.unscaledTime < _nextTitleSearch))
				{
					_nextTitleSearch = Time.unscaledTime + 0.25f;
					SplashScreenPanel val = Object.FindObjectOfType<SplashScreenPanel>();
					if ((!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled) || !(Time.unscaledTime < _waitTitleUntil))
					{
						_phase = 2;
					}
				}
			}
			else
			{
				_fade = Math.Max(0f, _fade - unscaledDeltaTime / 0.5f);
				SetBlack(_fade);
				if (!(_fade > 0f))
				{
					((Component)_black).gameObject.SetActive(false);
					_leaving = false;
					_phase = 0;
					Info("back on the title screen.");
				}
			}
		}

		private static void SetBlack(float a)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_black != (Object)null)
			{
				((Graphic)_black).color = new Color(0f, 0f, 0f, a);
			}
		}

		private static void EnsureUi()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_canvas != (Object)null))
			{
				_canvas = new GameObject("CoopBackToTitle");
				Object.DontDestroyOnLoad((Object)(object)_canvas);
				Canvas obj = _canvas.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 32000;
				CanvasScaler obj2 = _canvas.AddComponent<CanvasScaler>();
				obj2.uiScaleMode = (ScaleMode)1;
				obj2.referenceResolution = new Vector2(1920f, 1080f);
				obj2.matchWidthOrHeight = 0.5f;
				_hint = new GameObject("Hint");
				RectTransform obj3 = _hint.AddComponent<RectTransform>();
				((Transform)obj3).SetParent(_canvas.transform, false);
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0f, 0f);
				obj3.pivot = val;
				Vector2 anchorMin = (obj3.anchorMax = val);
				obj3.anchorMin = anchorMin;
				obj3.anchoredPosition = new Vector2(36f, 30f);
				obj3.sizeDelta = new Vector2(700f, 48f);
				float x = 0f;
				x = Key(obj3, "B", x, 44f, round: true) + 8f;
				x = Text(obj3, "/", x, 20f, 26f, new Color(1f, 1f, 1f, 0.8f)) + 8f;
				Text(x: Key(obj3, "Backspace", x, 140f, round: false) + 14f, parent: obj3, text: Loc.T("Back to the title screen", "Voltar ao menu inicial"), width: 400f, size: 26f, color: Color.white);
				_hint.SetActive(false);
				_dialog = new GameObject("Question");
				RectTransform obj4 = _dialog.AddComponent<RectTransform>();
				((Transform)obj4).SetParent(_canvas.transform, false);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				obj4.pivot = val;
				anchorMin = (obj4.anchorMax = val);
				obj4.anchorMin = anchorMin;
				obj4.sizeDelta = new Vector2(820f, 260f);
				((Graphic)_dialog.AddComponent<Image>()).color = new Color(0.05f, 0.05f, 0.08f, 0.92f);
				((TMP_Text)Label(obj4, Loc.T("Back to the title screen?", "Voltar ao menu inicial?"), new Vector2(0f, 70f), 40f, new Color(1f, 0.85f, 0.4f))).fontStyle = (FontStyles)1;
				Label(obj4, Loc.T("You can redo who joins on the Co-op screen there.", "Lá você pode refazer a entrada dos jogadores no Co-op."), new Vector2(0f, 10f), 24f, new Color(1f, 1f, 1f, 0.85f));
				Label(obj4, Loc.T("[A] / [Enter]  Confirm        [B] / [Backspace]  Cancel", "[A] / [Enter]  Confirmar        [B] / [Backspace]  Cancelar"), new Vector2(0f, -70f), 24f, Color.white);
				_dialog.SetActive(false);
				GameObject val4 = new GameObject("Black");
				RectTransform obj5 = val4.AddComponent<RectTransform>();
				((Transform)obj5).SetParent(_canvas.transform, false);
				obj5.anchorMin = Vector2.zero;
				obj5.anchorMax = Vector2.one;
				anchorMin = (obj5.offsetMax = Vector2.zero);
				obj5.offsetMin = anchorMin;
				_black = val4.AddComponent<Image>();
				((Graphic)_black).raycastTarget = false;
				SetBlack(0f);
				val4.SetActive(false);
			}
		}

		private static float Key(RectTransform parent, string key, float x, float width, bool round)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Key_" + key);
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent((Transform)(object)parent, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0f, 0.5f);
			val2.anchoredPosition = new Vector2(x, 0f);
			val2.sizeDelta = new Vector2(width, 40f);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).color = new Color(0.12f, 0.12f, 0.14f, 0.95f);
			((Graphic)obj).raycastTarget = false;
			Outline obj2 = val.AddComponent<Outline>();
			((Shadow)obj2).effectColor = new Color(1f, 1f, 1f, 0.55f);
			((Shadow)obj2).effectDistance = new Vector2(2f, -2f);
			Text(val2, key, 0f, width, round ? 28f : 22f, Color.white, center: true);
			return x + width;
		}

		private static float Text(RectTransform parent, string text, float x, float width, float size, Color color, bool center = false)
		{
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0.5f);
			obj.anchorMax = val2;
			obj.anchorMin = val2;
			obj.pivot = new Vector2(0f, 0.5f);
			obj.anchoredPosition = new Vector2(x, 0f);
			obj.sizeDelta = new Vector2(width, 44f);
			TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
			Loc.ApplyGameFont((TMP_Text)(object)val3, (FontType)4);
			((TMP_Text)val3).text = text;
			((TMP_Text)val3).fontSize = size;
			((TMP_Text)val3).fontStyle = (FontStyles)1;
			((Graphic)val3).color = color;
			((TMP_Text)val3).alignment = (TextAlignmentOptions)(center ? 514 : 4097);
			((TMP_Text)val3).enableWordWrapping = false;
			((Graphic)val3).raycastTarget = false;
			((TMP_Text)val3).outlineWidth = 0.15f;
			((TMP_Text)val3).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)220);
			if (!center)
			{
				((TMP_Text)val3).ForceMeshUpdate(false, false);
				return x + Math.Min(width, ((TMP_Text)val3).preferredWidth);
			}
			return x + width;
		}

		private static TextMeshProUGUI Label(RectTransform parent, string text, Vector2 pos, float size, Color color)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Label");
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			obj.pivot = val2;
			Vector2 anchorMin = (obj.anchorMax = val2);
			obj.anchorMin = anchorMin;
			obj.anchoredPosition = pos;
			obj.sizeDelta = new Vector2(800f, 50f);
			TextMeshProUGUI obj2 = val.AddComponent<TextMeshProUGUI>();
			Loc.ApplyGameFont((TMP_Text)(object)obj2, (FontType)4);
			((TMP_Text)obj2).text = text;
			((TMP_Text)obj2).fontSize = size;
			((Graphic)obj2).color = color;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)obj2).enableWordWrapping = false;
			((Graphic)obj2).raycastTarget = false;
			return obj2;
		}
	}
	internal static class CoopBosses
	{
		private static readonly Random _rng = new Random();

		private static readonly Queue<Entity> _targets = new Queue<Entity>();

		private static int _inSpawn;

		private static bool _redirecting;

		private static int _queuedBefore;

		private static readonly List<BossPrefabs> _lordBag = new List<BossPrefabs>();

		private static IntPtr _bagOf;

		private static bool _loggedLordList;

		private static readonly string[] _neverTogether = new string[2] { "BossNameMedusa", "BossNamePlaguebringer" };

		private static readonly HashSet<string> _prevSpawn = new HashSet<string>();

		private static readonly Dictionary<IntPtr, int> _objectiveTotals = new Dictionary<IntPtr, int>();

		private static readonly HashSet<IntPtr> _scaledProgress = new HashSet<IntPtr>();

		private static SurvivorsGameManager _survivors;

		private static float _nextProgressCheck;

		private static int _inSpecific;

		private static readonly List<Entity> _finalBosses = new List<Entity>();

		private static bool? _bossRoom;

		private static readonly HashSet<IntPtr> _lords = new HashSet<IntPtr>();

		internal static bool FinalBossFight
		{
			get
			{
				int num = _finalBosses.Count - 1;
				while (num >= 0)
				{
					Entity val = _finalBosses[num];
					if ((Object)(object)val == (Object)null || ((Il2CppObjectBase)val).WasCollected || (Object)(object)val._health == (Object)null || val._health.HasBeenKilled)
					{
						_finalBosses.RemoveAt(num);
						num--;
						continue;
					}
					return true;
				}
				return false;
			}
		}

		private static void Info(string msg)
		{
			Plugin.Log.LogInfo((object)("[Lords] " + msg));
		}

		private static bool LordsMode(BossSpawnProcessor p)
		{
			if (p != null && (Object)(object)p.SurvivorsGameManager != (Object)null && (Object)(object)p.MasteryGameManager == (Object)null && CoopPlayers.CoopEnabled && CoopInput.InMatch())
			{
				return GameManagerUtil.PlayerEntities.Count >= 2;
			}
			return false;
		}

		private static List<Entity> AlivePlayers()
		{
			return CoopPlayers.StandingPlayers();
		}

		private static int Queued(BossSpawnProcessor p)
		{
			try
			{
				return (p.HighPrioritySpawnQueue?.Count ?? 0) + p._pendingBosses;
			}
			catch
			{
				return -1;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(BossSpawnProcessor), "SpawnBosses")]
		private static void SpawnBossesPre(BossSpawnProcessor __instance, ref int additionalBossQuantity)
		{
			_inSpawn++;
			try
			{
				if (!LordsMode(__instance))
				{
					return;
				}
				_queuedBefore = Queued(__instance);
				int count = GameManagerUtil.PlayerEntities.Count;
				int num = 1 + Math.Max(0, additionalBossQuantity);
				int num2 = Math.Min(Math.Max(0, Plugin.MaxExtraLords.Value), Math.Max(0, Plugin.ExtraLordsPerPlayer.Value) * (count - 1));
				additionalBossQuantity += num2;
				int num3 = num + num2;
				ScaleLordObjectives(__instance.SurvivorsGameManager, num, num3);
				ExtendLordList(__instance, num3);
				List<Entity> list = AlivePlayers();
				if (list.Count == 0)
				{
					return;
				}
				List<Entity> list2 = new List<Entity>();
				int num4 = num3 / list.Count;
				int num5 = num3 % list.Count;
				foreach (Entity item in list)
				{
					for (int i = 0; i < num4; i++)
					{
						list2.Add(item);
					}
				}
				List<Entity> list3 = new List<Entity>(list);
				Shuffle(list3);
				for (int j = 0; j < num5; j++)
				{
					list2.Add(list3[j]);
				}
				Shuffle(list2);
				_targets.Clear();
				foreach (Entity item2 in list2)
				{
					_targets.Enqueue(item2);
				}
				Info($"game wanted {num}, co-op adds {num2} -> {num3} ({string.Join(", ", Split(list2))}); queue before={_queuedBefore}");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Lords] " + ex.Message));
			}
		}

		private static void ExtendLordList(BossSpawnProcessor p, int count)
		{
			try
			{
				List<BossPrefabs> bossList = p.BossList;
				if (bossList == null || bossList.Count == 0)
				{
					return;
				}
				List<BossPrefabs> list = new List<BossPrefabs>();
				HashSet<string> hashSet = new HashSet<string>();
				for (int i = 0; i < bossList.Count; i++)
				{
					BossPrefabs val = bossList[i];
					if (val != null && hashSet.Add(val.BossNameId ?? ((Il2CppObjectBase)val).Pointer.ToString()))
					{
						list.Add(val);
					}
				}
				if (!_loggedLordList)
				{
					_loggedLordList = true;
					List<string> list2 = new List<string>();
					for (int j = 0; j < bossList.Count; j++)
					{
						BossPrefabs obj = bossList[j];
						list2.Add(((obj != null) ? obj.BossNameId : null) ?? "-");
					}
					Info($"game's lord list ({bossList.Count}, {list.Count} different): {string.Join(", ", list2)}; lords spawned so far {p.BossesSpawned}.");
				}
				if (_bagOf != ((Il2CppObjectBase)bossList).Pointer)
				{
					_bagOf = ((Il2CppObjectBase)bossList).Pointer;
					_lordBag.Clear();
				}
				int num = Math.Max(0, p.BossesSpawned);
				int num2 = 0;
				while (bossList.Count < num + count && list.Count > 0)
				{
					HashSet<string> inSpawn = new HashSet<string>();
					for (int k = num; k < bossList.Count; k++)
					{
						if (bossList[k] != null)
						{
							inSpawn.Add(bossList[k].BossNameId);
						}
					}
					if (_lordBag.Count == 0)
					{
						RefillBag(list);
					}
					int num3 = _lordBag.FindIndex((BossPrefabs b) => !inSpawn.Contains(b.BossNameId));
					if (num3 < 0)
					{
						RefillBag(list);
						num3 = _lordBag.FindIndex((BossPrefabs b) => !inSpawn.Contains(b.BossNameId));
						if (num3 < 0)
						{
							num3 = 0;
						}
					}
					bossList.Add(_lordBag[num3]);
					_lordBag.RemoveAt(num3);
					num2++;
				}
				SeparatePair(bossList, list, num, count);
				List<string> list3 = new List<string>();
				int num4 = Math.Min(bossList.Count, num + count);
				for (int num5 = Math.Min(num, bossList.Count - 1); num5 < num4; num5++)
				{
					BossPrefabs obj2 = bossList[num5];
					list3.Add(((obj2 != null) ? obj2.BossNameId : null) ?? "-");
				}
				_prevSpawn.Clear();
				foreach (string item in list3)
				{
					_prevSpawn.Add(item);
				}
				if (num2 > 0)
				{
					Info($"lord list extended by {num2} (no repeats): this spawn = {string.Join(", ", list3)}.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Lords] lord list: " + ex.Message));
			}
		}

		private static void SeparatePair(List<BossPrefabs> list, List<BossPrefabs> distinct, int start, int count)
		{
			int num = Math.Min(list.Count, start + count);
			int num2 = -1;
			for (int i = start; i < num; i++)
			{
				BossPrefabs obj = list[i];
				string text = ((obj != null) ? obj.BossNameId : null);
				if (Array.IndexOf(_neverTogether, text) < 0)
				{
					continue;
				}
				if (num2 < 0)
				{
					num2 = i;
					continue;
				}
				BossPrefabs obj2 = list[num2];
				if (((obj2 != null) ? obj2.BossNameId : null) == text)
				{
					continue;
				}
				HashSet<string> inSpawn = new HashSet<string>();
				for (int j = start; j < num; j++)
				{
					if (list[j] != null)
					{
						inSpawn.Add(list[j].BossNameId);
					}
				}
				BossPrefabs val = distinct.Find((BossPrefabs b) => b != null && !inSpawn.Contains(b.BossNameId) && Array.IndexOf(_neverTogether, b.BossNameId) < 0);
				if (val == null)
				{
					val = distinct.Find((BossPrefabs b) => b != null && Array.IndexOf(_neverTogether, b.BossNameId) < 0);
				}
				if (val == null)
				{
					break;
				}
				Info($"{text} would come with {list[num2].BossNameId}: swapped for {val.BossNameId}.");
				list[i] = val;
			}
		}

		private static void RefillBag(List<BossPrefabs> distinct)
		{
			List<BossPrefabs> list = new List<BossPrefabs>();
			List<BossPrefabs> list2 = new List<BossPrefabs>();
			foreach (BossPrefabs item in distinct)
			{
				(_prevSpawn.Contains(item.BossNameId) ? list2 : list).Add(item);
			}
			Shuffle(list);
			Shuffle(list2);
			_lordBag.Clear();
			_lordBag.AddRange(list);
			_lordBag.AddRange(list2);
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(BossSpawnProcessor), "SpawnBosses")]
		private static Exception SpawnBossesFinalizer(BossSpawnProcessor __instance, Exception __exception)
		{
			_inSpawn = Math.Max(0, _inSpawn - 1);
			try
			{
				if (LordsMode(__instance))
				{
					Info($"queue after={Queued(__instance)} (positions still to assign: {_targets.Count})");
				}
			}
			catch
			{
			}
			return __exception;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(_SpawnBossRoutine_d__39), "MoveNext")]
		private static void RoutinePre()
		{
			_inSpawn++;
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(_SpawnBossRoutine_d__39), "MoveNext")]
		private static Exception RoutineFinalizer(Exception __exception)
		{
			_inSpawn = Math.Max(0, _inSpawn - 1);
			return __exception;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameManagerUtil), "GetRandomSpawnPointOutsideOfView")]
		private static void SpawnPointPost(float extraDistanceMultiplier, ref Vector3 __result)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			if (_inSpawn == 0 || _redirecting || _targets.Count == 0)
			{
				return;
			}
			try
			{
				Entity val = _targets.Dequeue();
				Entity val2 = GameManagerUtil.PlayerEntities[0];
				if (!((Object)(object)val == (Object)null) && !((Il2CppObjectBase)val).WasCollected && (!((Object)(object)val2 != (Object)null) || !(((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)val2).Pointer)))
				{
					_redirecting = true;
					Vector3 value = __result;
					__result = GameManagerUtil.GetRandomSpawnPointOutsideOfView(((Component)val).transform.position, extraDistanceMultiplier);
					Info($"lord spawn point moved to {((Object)val).name}: {value} -> {__result}");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Lords] spawn point: " + ex.Message));
			}
			finally
			{
				_redirecting = false;
			}
		}

		private static void ScaleLordObjectives(SurvivorsGameManager gm, int gameCount, int total)
		{
			if ((Object)(object)gm == (Object)null || gameCount <= 0 || total <= gameCount)
			{
				return;
			}
			try
			{
				List<EliminateSpecificEntitiesObjective> eliminationObjectives = gm.EliminationObjectives;
				int num = 0;
				while (eliminationObjectives != null && num < eliminationObjectives.Count)
				{
					EliminateSpecificEntitiesObjective val = eliminationObjectives[num];
					if (val != null)
					{
						if (!_objectiveTotals.TryGetValue(((Il2CppObjectBase)val).Pointer, out var value))
						{
							value = (_objectiveTotals[((Il2CppObjectBase)val).Pointer] = val.Total);
						}
						if (value >= gameCount)
						{
							int num2 = (int)Math.Round((double)value * (double)total / (double)gameCount);
							if (val.Total != num2)
							{
								val.Total = num2;
								Info($"objective '{((ObjectiveBase)val).Id}': {value} -> {num2} lords (waves of {gameCount} -> {total}).");
							}
						}
					}
					num++;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Lords] objective: " + ex.Message));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameLoop), "Update")]
		private static void ScaleProgressObjectives()
		{
			if (Time.unscaledTime < _nextProgressCheck)
			{
				return;
			}
			_nextProgressCheck = Time.unscaledTime + 1f;
			try
			{
				if (!CoopPlayers.CoopEnabled || !CoopInput.InMatch() || GameManagerUtil.PlayerEntities.Count < 2)
				{
					return;
				}
				if ((Object)(object)_survivors == (Object)null || ((Il2CppObjectBase)_survivors).WasCollected)
				{
					GameData gameData = GameManagerUtil.GameData;
					_survivors = ((gameData != null) ? gameData.SurvivorsGameManager : null);
				}
				SurvivorsGameManager survivors = _survivors;
				List<EliminateEnemiesNonCumulativeObjective> val = ((survivors != null) ? survivors.ProgressObjectives : null);
				if (val == null)
				{
					return;
				}
				float num = CoopSpawns.EnemyMultiplier();
				if (num <= 1.001f)
				{
					return;
				}
				for (int i = 0; i < val.Count; i++)
				{
					EliminateEnemiesNonCumulativeObjective val2 = val[i];
					if (val2 != null && _scaledProgress.Add(((Il2CppObjectBase)val2).Pointer) && val2.Total > 0)
					{
						int total = val2.Total;
						val2.Total = Math.Max(100, (int)Math.Round((double)((float)val2.Total * num) / 100.0) * 100);
						Info($"summon objective '{((ObjectiveBase)val2).Id}': total {total} -> {val2.Total} (starting at {val2.Starting}).");
					}
				}
			}
			catch (Exception ex)
			{
				_nextProgressCheck = Time.unscaledTime + 10f;
				Plugin.Log.LogWarning((object)("[Lords] summon objective: " + ex.Message));
			}
		}

		private static void Shuffle<T>(List<T> list)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = _rng.Next(num + 1);
				int index = num;
				int index2 = num2;
				T value = list[num2];
				T value2 = list[num];
				list[index] = value;
				list[index2] = value2;
			}
		}

		private static IEnumerable<string> Split(List<Entity> order)
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (Entity item in order)
			{
				string key = "P" + (CoopPlayers.SlotOf(item) + 1);
				dictionary[key] = ((!dictionary.TryGetValue(key, out var value)) ? 1 : (value + 1));
			}
			foreach (KeyValuePair<string, int> item2 in dictionary)
			{
				yield return $"{item2.Key}={item2.Value}";
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(BossSpawnProcessor), "SpawnSpecificBoss")]
		private static void SpecificPre()
		{
			_inSpecific++;
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(BossSpawnProcessor), "SpawnSpecificBoss")]
		private static Exception SpecificFinalizer(Exception __exception)
		{
			_inSpecific = Math.Max(0, _inSpecific - 1);
			return __exception;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameManagerUtil), "RegisterBossEntity")]
		private static void BossRegistered(Entity entity)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			try
			{
				if (!((Object)(object)entity == (Object)null) && CoopInput.InMatch())
				{
					bool flag = _bossRoom == true;
					if (!_bossRoom.HasValue)
					{
						flag = (Object)(object)Object.FindObjectOfType<SurvivorsBossRoomGameManager>() != (Object)null;
						_bossRoom = flag;
					}
					bool flag2 = _inSpawn > 0 && _inSpecific == 0 && !_bossRoom.Value;
					if (!flag2)
					{
						_finalBosses.Add(entity);
					}
					else
					{
						_lords.Add(((Il2CppObjectBase)entity).Pointer);
					}
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 5, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Bosses] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)entity).name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(flag2 ? "lord" : "final boss");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (spawn routine=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_inSpawn > 0);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", specific=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_inSpecific > 0);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", boss room=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool?>(_bossRoom);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Bosses] " + ex.Message));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameManagerUtil), "StartMatch")]
		private static void ResetForMatch()
		{
			_objectiveTotals.Clear();
			_scaledProgress.Clear();
			_survivors = null;
			_targets.Clear();
			_inSpawn = 0;
			_inSpecific = 0;
			_finalBosses.Clear();
			_lords.Clear();
			_bossRoom = null;
			_lordBag.Clear();
			_bagOf = IntPtr.Zero;
			_prevSpawn.Clear();
			_loggedLordList = false;
		}

		internal static bool IsLord(IntPtr entity)
		{
			return _lords.Contains(entity);
		}
	}
	internal static class CoopBottomBars
	{
		private sealed class Card
		{
			public RectTransform Health;

			public RectTransform Skills;

			public RectTransform Tag;

			public RectTransform HealthFill;

			public RectTransform HealthGreen;

			public TextMeshProUGUI HealthValue;

			public Color Color;

			public bool LoggedOverflow;

			public int Max = 6;

			public readonly List<SkillBarItemReferencesSurvivors> Items = new List<SkillBarItemReferencesSurvivors>();
		}

		private sealed class Pieces
		{
			public readonly List<(RectTransform rt, Vector2 pos, Vector3 scale)> List = new List<(RectTransform, Vector2, Vector3)>();

			public float Center;
		}

		private sealed class Home
		{
			public RectTransform Rt;

			public Vector2 Pos;

			public Vector3 Scale;

			public float Width;
		}

		internal static readonly Color[] Colors = CoopPlayers.Colors;

		private const float CardWidth = 610f;

		private const float Gap = 40f;

		private const float ScreenWidth = 1880f;

		private const float HealthWidth = 530f;

		private const float Lift = 16f;

		private static readonly List<Card> _cards = new List<Card>();

		private static GameplayPanelManager _gpm;

		private static Transform _bottom;

		private static RectTransform _healthSrc;

		private static RectTransform _skillsSrc;

		private static RectTransform _dash;

		private static RectTransform _deathGuard;

		private static RectTransform _ascension;

		private static Vector2 _deathGuardHome;

		private static readonly Dictionary<IntPtr, (Vector2 pos, Vector3 scale)> _ascensionHome = new Dictionary<IntPtr, (Vector2, Vector3)>();

		private static float _nextSkills;

		private static float _nextBuild;

		private static bool _failed;

		private const float DividerWidth = 120f;

		private static float[] _widths = Array.Empty<float>();

		private static float _slotPitch = 86.09f;

		private static float _slotPad = 5f;

		private static int[] _builtMax = Array.Empty<int>();

		private const float BadgeSlot = 74f;

		private const float BadgeDiagonal = 56f;

		private static bool _loggedHealthColors;

		private static RectTransform _autoAim;

		private static Vector2 _autoAimHome;

		private static Vector3 _autoAimScale;

		private static readonly Dictionary<IntPtr, Pieces> _pieces = new Dictionary<IntPtr, Pieces>();

		private static float _nextPieces;

		private static readonly Dictionary<IntPtr, int> _uniqueOwner = new Dictionary<IntPtr, int>();

		private static bool _uniqueDone;

		private static float _nextRunes;

		private static RectTransform _sideButtons;

		private static Vector2 _sideButtonsHome;

		private static bool _loggedSide;

		private static float _nextHudMeasure;

		private static bool _loggedHud;

		private static int _hudPieces;

		private static readonly List<RectTransform> _sideButtonParts = new List<RectTransform>();

		private static readonly Il2CppStructArray<Vector3> _corners = new Il2CppStructArray<Vector3>(4L);

		private static float _nextSide;

		private static Vector2? _sideTarget;

		private static Home _level;

		private static Home _xp;

		private static Home _xpSpikes;

		private static RectTransform _pending;

		private static Vector3 _pendingScale;

		private static bool _loggedPending;

		private static RectTransform _ownPending;

		private static TextMeshProUGUI _ownPendingLabel;

		private static CanvasGroup _pendingHider;

		private static float _nextPendingFx;

		private static bool _loggedPendingFx;

		private static readonly HashSet<IntPtr> _offFx = new HashSet<IntPtr>();

		private static bool _built;

		internal static float HudTop { get; private set; } = 0.14f;

		private static int DividerAfter(int n)
		{
			if (n != 3)
			{
				return (n + 1) / 2;
			}
			return 3;
		}

		private static float W(int i)
		{
			if (i >= _widths.Length)
			{
				return 610f;
			}
			return _widths[i];
		}

		private static float SumW(int n)
		{
			float num = 0f;
			for (int i = 0; i < n; i++)
			{
				num += W(i);
			}
			return num;
		}

		private static float Scale(int n)
		{
			return Mathf.Min(0.85f, (1880f - (float)n * 40f) / (SumW(n) + 120f));
		}

		private static float TotalWidth(int n, float s)
		{
			return s * (SumW(n) + 120f) + (float)n * 40f;
		}

		private static float CardX(int i, int n, float s)
		{
			float num = (0f - TotalWidth(n, s)) * 0.5f;
			for (int j = 0; j < i; j++)
			{
				num += W(j) * s + 40f;
			}
			if (i >= DividerAfter(n))
			{
				num += 120f * s + 40f;
			}
			return num + W(i) * s * 0.5f;
		}

		private static float DividerX(int n, float s)
		{
			float num = (0f - TotalWidth(n, s)) * 0.5f;
			for (int i = 0; i < DividerAfter(n); i++)
			{
				num += W(i) * s + 40f;
			}
			return num + 120f * s * 0.5f;
		}

		private static int MaxSlots(Entity e, out int baseSlots, out int runeChange)
		{
			baseSlots = 6;
			runeChange = 0;
			try
			{
				baseSlots = Global.GameProperties.SurvivorsSkillSlots;
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)e._runes != (Object)null)
				{
					runeChange = e._runes.ChangeNumberOfSkillSlots;
				}
			}
			catch
			{
			}
			int val = 0;
			try
			{
				PlayerSkillSlotsComponent playerSkillSlots = e._playerSkillSlots;
				val = ((playerSkillSlots == null) ? ((int?)null) : playerSkillSlots.Slots?.Count).GetValueOrDefault();
			}
			catch
			{
			}
			return Math.Max(Math.Max(1, baseSlots + runeChange), val);
		}

		private static int MaxSlots(Entity e)
		{
			int baseSlots;
			int runeChange;
			return MaxSlots(e, out baseSlots, out runeChange);
		}

		private static float SkillsWidth(int slots)
		{
			return (float)slots * _slotPitch + _slotPad;
		}

		private static bool SlotsChanged(List<Entity> list)
		{
			if (_builtMax.Length != list.Count)
			{
				return true;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i] != (Object)null && MaxSlots(list[i]) != _builtMax[i])
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameLoop), "LateUpdate")]
		private static void LateUpdate()
		{
			if (_failed || !Plugin.PlayerBottomBars.Value)
			{
				return;
			}
			try
			{
				if (!CoopInput.InMatch() || GameManagerUtil.PlayerEntities.Count < 2)
				{
					if (_built)
					{
						Reset();
					}
					return;
				}
				List<Entity> playerEntities = GameManagerUtil.PlayerEntities;
				float unscaledTime = Time.unscaledTime;
				bool flag = (Object)(object)_gpm == (Object)null || _cards.Count != playerEntities.Count || _cards.Exists((Card c) => (Object)(object)c.Health == (Object)null);
				if (unscaledTime >= _nextBuild && (flag || (unscaledTime >= _nextSkills && SlotsChanged(playerEntities))))
				{
					_nextBuild = unscaledTime + 2f;
					Build(playerEntities.Count);
				}
				else if (flag)
				{
					return;
				}
				if (_cards.Count == 0)
				{
					return;
				}
				int count = playerEntities.Count;
				float s = Scale(count);
				bool flag2 = Time.unscaledTime >= _nextSkills;
				if (flag2)
				{
					_nextSkills = Time.unscaledTime + 0.15f;
				}
				for (int num = 0; num < count; num++)
				{
					Entity val = playerEntities[num];
					Card card = _cards[num];
					if (!((Object)(object)val == (Object)null))
					{
						UpdateHealth(card, val);
						if (flag2)
						{
							UpdateSkills(card, val);
						}
					}
				}
				KeepOriginalsHidden();
				if (CoopPlayers.Extras.Count >= count - 1)
				{
					EnsureUniquePanels(playerEntities);
				}
				PlaceShared(count, s);
				HideRunes();
				RaiseSideButtons();
				MeasureHudTop();
				if (Plugin.MoveLevelUpIndicator.Value)
				{
					UpdateLevelRow();
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				Plugin.Log.LogError((object)("[Bars] error, bottom bars disabled: " + ex));
				Reset();
			}
		}

		private static void Build(int n)
		{
			//IL_00fd: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0754: Expected O, but got Unknown
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Expected O, but got Unknown
			Reset(_uniqueDone);
			_built = true;
			GameplayUIManager gameplayUIManager = GameManagerUtil.GameplayUIManager;
			_gpm = ((gameplayUIManager != null) ? gameplayUIManager.GameplayPanel : null) ?? Object.FindObjectOfType<GameplayPanelManager>();
			if ((Object)(object)_gpm == (Object)null)
			{
				return;
			}
			_bottom = ((Component)_gpm).transform.Find("Bottom-Holder");
			if ((Object)(object)_bottom == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[Bars] Bottom-Holder not found.");
				return;
			}
			_healthSrc = FindRect(_bottom, "Health-Bar-Holder/Health-Bar-Frame");
			_skillsSrc = FindRect(_bottom, "Skill-Bar-Holder");
			_dash = FindRect(_bottom, "Skill-Frame-Dash");
			_deathGuard = FindRect(_bottom, "Skill-Frame-Death-Guard");
			_ascension = FindRect(_bottom, "AscensionUIContainer");
			_autoAim = FindRect(_bottom, "Health-Bar-Holder/Auto-Aim-Toggle");
			if ((Object)(object)_autoAim != (Object)null)
			{
				_autoAimHome = _autoAim.anchoredPosition;
				_autoAimScale = ((Transform)_autoAim).localScale;
			}
			if ((Object)(object)_healthSrc == (Object)null || (Object)(object)_skillsSrc == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[Bars] health/skill bar not found.");
				return;
			}
			if ((Object)(object)_deathGuard != (Object)null)
			{
				_deathGuardHome = _deathGuard.anchoredPosition;
			}
			Il2CppArrayBase<SkillBarItemReferencesSurvivors> componentsInChildren = ((Component)_skillsSrc).GetComponentsInChildren<SkillBarItemReferencesSurvivors>(true);
			int num = 0;
			foreach (SkillBarItemReferencesSurvivors item in componentsInChildren)
			{
				if (((Component)item).gameObject.activeSelf)
				{
					num++;
				}
			}
			if (componentsInChildren.Length >= 2)
			{
				float num2 = Math.Abs(((Component)componentsInChildren[1]).GetComponent<RectTransform>().anchoredPosition.x - ((Component)componentsInChildren[0]).GetComponent<RectTransform>().anchoredPosition.x);
				if (num2 > 10f)
				{
					_slotPitch = num2;
				}
			}
			if (num > 0)
			{
				Rect rect = _skillsSrc.rect;
				_slotPad = Math.Max(0f, ((Rect)(ref rect)).width - (float)num * _slotPitch);
			}
			List<Entity> playerEntities = GameManagerUtil.PlayerEntities;
			_builtMax = new int[n];
			_widths = new float[n];
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2;
			for (int i = 0; i < n; i++)
			{
				Entity val = ((i < playerEntities.Count) ? playerEntities[i] : null);
				int baseSlots = 6;
				int runeChange = 0;
				_builtMax[i] = (((Object)(object)val != (Object)null) ? MaxSlots(val, out baseSlots, out runeChange) : 6);
				_widths[i] = Math.Max(610f, SkillsWidth(_builtMax[i]));
				ManualLogSource log = Plugin.Log;
				val2 = new BepInExInfoLogInterpolatedStringHandler(51, 5, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Bars] P");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(i + 1);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" skill slots: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_builtMax[i]);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (game ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(baseSlots);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", runes ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(runeChange, "+0;-0;0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("), bar width ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(_widths[i], "0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
				}
				log.LogInfo(val2);
			}
			float num3 = Scale(n);
			for (int j = 0; j < n; j++)
			{
				float x = CardX(j, n, num3);
				Card card = new Card
				{
					Color = Colors[j % Colors.Length],
					Max = _builtMax[j]
				};
				card.Health = Copy(_healthSrc, $"CoopHealth_P{j + 1}", x, num3);
				card.HealthFill = FindRect((Transform)(object)card.Health, "Health-Bar");
				card.HealthGreen = FindRect((Transform)(object)card.Health, "Health-Bar-Green");
				Transform obj = ((Transform)card.Health).Find("Health-Bar-Value");
				card.HealthValue = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
				Transform val3 = ((Transform)card.Health).Find("VFX_Heal");
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(false);
				}
				TintHealth(card, j);
				card.Skills = Copy(_skillsSrc, $"CoopSkills_P{j + 1}", x, num3);
				Transform obj2 = ((Transform)card.Skills).Find("Skill-Frame-Survivors-Rune");
				SkillBarItemReferencesSurvivors val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<SkillBarItemReferencesSurvivors>() : null);
				foreach (MonoBehaviour component2 in ((Component)card.Skills).GetComponents<MonoBehaviour>())
				{
					if (((MemberInfo)((Object)component2).GetIl2CppType()).Name == "SkillBarPanelReferencesSurvivors")
					{
						((Behaviour)component2).enabled = false;
					}
				}
				foreach (SkillBarItemReferencesSurvivors componentsInChild in ((Component)card.Skills).GetComponentsInChildren<SkillBarItemReferencesSurvivors>(true))
				{
					if (!((Object)(object)val4 != (Object)null) || !(((Il2CppObjectBase)componentsInChild).Pointer == ((Il2CppObjectBase)val4).Pointer))
					{
						card.Items.Add(componentsInChild);
						componentsInChild.SlotSkill = null;
						componentsInChild.LastSkilLevel = -1;
					}
				}
				if ((Object)(object)val4 != (Object)null)
				{
					card.Items.Add(val4);
					val4.SlotSkill = null;
					val4.LastSkilLevel = -1;
				}
				while (card.Items.Count < card.Max && card.Items.Count > 0)
				{
					SkillBarItemReferencesSurvivors component = Object.Instantiate<GameObject>(((Component)card.Items[0]).gameObject, (Transform)(object)card.Skills, false).GetComponent<SkillBarItemReferencesSurvivors>();
					((Object)component).name = $"CoopSkillSlot_{card.Items.Count + 1}";
					((Component)component).transform.SetAsLastSibling();
					component.SlotSkill = null;
					component.LastSkilLevel = -1;
					card.Items.Add(component);
				}
				for (int k = 0; k < card.Items.Count; k++)
				{
					((Component)card.Items[k]).gameObject.SetActive(k < card.Max);
				}
				foreach (TooltipReferences componentsInChild2 in ((Component)card.Skills).GetComponentsInChildren<TooltipReferences>(true))
				{
					((Behaviour)componentsInChild2).enabled = false;
				}
				foreach (Button componentsInChild3 in ((Component)card.Skills).GetComponentsInChildren<Button>(true))
				{
					((Selectable)componentsInChild3).interactable = false;
				}
				card.Tag = MakeBadge(j, card);
				_cards.Add(card);
			}
			ManualLogSource log2 = Plugin.Log;
			val2 = new BepInExInfoLogInterpolatedStringHandler(35, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Bars] ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(n);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" bottom bars built (scale ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num3, "0.00");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(").");
			}
			log2.LogInfo(val2);
		}

		private static RectTransform Copy(RectTransform src, string name, float x, float s)
		{
			//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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(((Component)src).gameObject, _bottom, false);
			((Object)obj).name = name;
			obj.SetActive(true);
			RectTransform component = obj.GetComponent<RectTransform>();
			Vector2 val = src.anchoredPosition;
			if ((Object)(object)((Transform)src).parent != (Object)(object)_bottom)
			{
				RectTransform val2 = ((Il2CppObjectBase)((Transform)src).parent).TryCast<RectTransform>();
				if ((Object)(object)val2 != (Object)null)
				{
					val += val2.anchoredPosition;
				}
			}
			Vector2 anchorMin = (component.anchorMax = src.anchorMin);
			component.anchorMin = anchorMin;
			component.anchoredPosition = new Vector2(x + val.x * s, val.y * s + 16f);
			((Transform)component).localScale = ((Transform)src).localScale * s;
			return component;
		}

		private static RectTransform MakeBadge(int i, Card card)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			RectTransform health = card.Health;
			Color color = Colors[i % Colors.Length];
			Rect rect = health.rect;
			float num = ((Rect)(ref rect)).width * ((Transform)health).localScale.x;
			rect = health.rect;
			float num2 = ((Rect)(ref rect)).height * ((Transform)health).localScale.y;
			float num3 = 74f * ((Transform)health).localScale.y;
			float num4 = health.anchoredPosition.x - num * health.pivot.x;
			float num5 = health.anchoredPosition.y + (0.5f - health.pivot.y) * num2;
			float num6 = (num - num3) / num;
			((Transform)health).localScale = new Vector3(((Transform)health).localScale.x * num6, ((Transform)health).localScale.y, ((Transform)health).localScale.z);
			health.anchoredPosition = new Vector2(health.anchoredPosition.x + num3 * (1f - health.pivot.x), health.anchoredPosition.y);
			if ((Object)(object)card.HealthValue != (Object)null)
			{
				Vector3 localScale = ((Transform)((TMP_Text)card.HealthValue).rectTransform).localScale;
				((Transform)((TMP_Text)card.HealthValue).rectTransform).localScale = new Vector3(localScale.x / num6, localScale.y, localScale.z);
			}
			Image component = ((Component)health).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = color;
			}
			RectTransform obj = Badge(_bottom, i, $"CoopBarBadge_P{i + 1}");
			Vector2 anchorMin = (obj.anchorMax = health.anchorMin);
			obj.anchorMin = anchorMin;
			obj.anchoredPosition = new Vector2(num4 + num3 * 0.5f, num5);
			((Transform)obj).localScale = Vector3.one * ((Transform)health).localScale.y;
			return obj;
		}

		internal static RectTransform Badge(Transform parent, int i, string name)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			Color val = Colors[i % Colors.Length];
			RectTransform val2 = new GameObject(name).AddComponent<RectTransform>();
			((Transform)val2).SetParent(parent, false);
			val2.sizeDelta = new Vector2(56f, 56f);
			float num = 39.598362f;
			Diamond(val2, "Edge", num, new Color(val.r * 0.2f, val.g * 0.2f, val.b * 0.2f, 1f));
			Diamond(val2, "Fill", num - 5f, val);
			Diamond(val2, "Inner", num - 12f, new Color(0.08f, 0.08f, 0.1f, 0.92f));
			GameObject val3 = new GameObject("Label");
			RectTransform obj = val3.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)val2, false);
			obj.sizeDelta = new Vector2(56f, 56f);
			obj.anchoredPosition = new Vector2(1f, 0f);
			TextMeshProUGUI obj2 = val3.AddComponent<TextMeshProUGUI>();
			Loc.ApplyGameFont((TMP_Text)(object)obj2, (FontType)4);
			((TMP_Text)obj2).text = "P" + (i + 1);
			((TMP_Text)obj2).fontSize = 22f;
			((TMP_Text)obj2).fontStyle = (FontStyles)1;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)4098;
			((TMP_Text)obj2).margin = Vector4.zero;
			((TMP_Text)obj2).enableWordWrapping = false;
			((Graphic)obj2).raycastTarget = false;
			((Graphic)obj2).color = val;
			((TMP_Text)obj2).outlineWidth = 0.15f;
			((TMP_Text)obj2).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);
			return val2;
		}

		private static void Diamond(RectTransform parent, string name, float side, Color color)
		{
			//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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			RectTransform obj = val.AddComponent<RectTransform>();
			((Transform)obj).SetParent((Transform)(object)parent, false);
			obj.sizeDelta = new Vector2(side, side);
			((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, 45f);
			Image obj2 = val.AddComponent<Image>();
			((Graphic)obj2).color = color;
			((Graphic)obj2).raycastTarget = false;
		}

		private static void TintHealth(Card card, int i)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			Color val = Colors[i % Colors.Length];
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(val.r * 0.8f, val.g * 0.8f, val.b * 0.8f, 1f);
			RectTransform[] array = (RectTransform[])(object)new RectTransform[2] { card.HealthFill, card.HealthGreen };
			foreach (RectTransform val3 in array)
			{
				Image val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null);
				if (!((Object)(object)val4 == (Object)null))
				{
					_ = _loggedHealthColors;
					((Graphic)val4).color = new Color(val2.r, val2.g, val2.b, ((Graphic)val4).color.a);
				}
			}
			_loggedHealthColors = true;
		}

		private static void UpdateHealth(Card card, Entity e)
		{
			HealthComponent health = e._health;
			if (!((Object)(object)health == (Object)null))
			{
				float num = CoopPlayers.MaxHealth(e);
				float num2 = (health.HasBeenKilled ? 0f : Mathf.Clamp01(health.CurrentHealth / num));
				if ((Object)(object)card.HealthFill != (Object)null)
				{
					card.HealthFill.SetSizeWithCurrentAnchors((Axis)0, 530f * num2);
				}
				if ((Object)(object)card.HealthGreen != (Object)null)
				{
					card.HealthGreen.SetSizeWithCurrentAnchors((Axis)0, 530f * num2);
				}
				if ((Object)(object)card.HealthValue != (Object)null)
				{
					((TMP_Text)card.HealthValue).text = Mathf.CeilToInt(Math.Max(0f, health.CurrentHealth)).ToString();
				}
			}
		}

		private static void UpdateSkills(Card card, Entity e)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			PlayerSkillSlotsComponent playerSkillSlots = e._playerSkillSlots;
			List<Skill> val = ((playerSkillSlots != null) ? playerSkillSlots.Slots : null);
			if (val != null && val.Count > card.Items.Count && !card.LoggedOverflow)
			{
				card.LoggedOverflow = true;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(40, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[Bars] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)e).name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" skills but the bar has ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(card.Items.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" slots.");
				}
				log.LogWarning(val2);
			}
			for (int i = 0; i < card.Items.Count; i++)
			{
				Skill val3 = ((val != null && i < val.Count) ? val[i] : null);
				SkillBarItemReferencesSurvivors val4 = card.Items[i];
				bool flag2 = i < card.Max || (Object)(object)val3 != (Object)null;
				if (((Component)val4).gameObject.activeSelf != flag2)
				{
					((Component)val4).gameObject.SetActive(flag2);
				}
				TintSlot(val4, card.Color);
				if ((Object)(object)val3 == (Object)null)
				{
					if ((Object)(object)val4.InfoHolder != (Object)null && val4.InfoHolder.activeSelf)
					{
						val4.InfoHolder.SetActive(false);
					}
					val4.SlotSkill = null;
					continue;
				}
				_gpm.SetupSkillSlotSurvivors(val4, val3, (Object)(object)val4.SlotSkill == (Object)null || ((Il2CppObjectBase)val4.SlotSkill).Pointer != ((Il2CppObjectBase)val3).Pointer);
				Image cooldown = val4.Cooldown;
				if ((Object)(object)cooldown != (Object)null)
				{
					float num = Mathf.Clamp01(val3.GetRemainingCooldownPercentage());
					if (Math.Abs(cooldown.fillAmount - num) > 0.002f)
					{
						cooldown.fillAmount = num;
					}
				}
			}
		}

		private static void TintSlot(SkillBarItemReferencesSurvivors item, Color c)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			Image component = ((Component)item).GetComponent<Image>();
			if ((Object)(object)component != (Object)null && ((Graphic)component).color != c)
			{
				((Graphic)component).color = c;
			}
			Transform obj = ((Component)item).transform.Find("Selection");
			Image val = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			if ((Object)(object)val != (Object)null && ((Graphic)val).color != c)
			{
				((Graphic)val).color = c;
			}
		}

		private static void KeepOriginalsHidden()
		{
			if ((Object)(object)_healthSrc != (Object)null && ((Component)_healthSrc).gameObject.activeSelf)
			{
				((Component)_healthSrc).gameObject.SetActive(false);
			}
			if ((Object)(object)_skillsSrc != (Object)null && ((Component)_skillsSrc).gameObject.activeSelf)
			{
				((Component)_skillsSrc).gameObject.SetActive(false);
			}
			if ((Object)(object)_dash != (Object)null && ((Component)_dash).gameObject.activeSelf)
			{
				((Component)_dash).gameObject.SetActive(false);
			}
		}

		private static void PlaceShared(int n, float s)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing referen