Decompiled source of WillsWackyManagers v1.5.13

WillsWackyManagers.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using CardChoiceSpawnUniqueCardPatch.CustomCategories;
using CardThemeLib;
using ExitGames.Client.Photon;
using HarmonyLib;
using InControl;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ModdingUtils.AIMinion.Extensions;
using ModdingUtils.Extensions;
using ModdingUtils.GameModes;
using ModdingUtils.Patches;
using ModdingUtils.Utils;
using Photon.Pun;
using Photon.Realtime;
using RarityLib.Utils;
using Sirenix.OdinInspector;
using Sonigon;
using Sonigon.Internal;
using TMPro;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using WillsWackyManagers.Cards;
using WillsWackyManagers.Cards.Curses;
using WillsWackyManagers.Extensions;
using WillsWackyManagers.MonoBehaviours;
using WillsWackyManagers.Networking;
using WillsWackyManagers.UI;
using WillsWackyManagers.UnityTools;
using WillsWackyManagers.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class Rarities
{
	public static Rarity Trinket => RarityUtils.GetRarity("Trinket");

	public static Rarity Common => (Rarity)0;

	public static Rarity Scarce => RarityUtils.GetRarity("Scarce");

	public static Rarity Uncommon => (Rarity)1;

	public static Rarity Exotic => RarityUtils.GetRarity("Exotic");

	public static Rarity Rare => (Rarity)2;

	public static Rarity Epic => RarityUtils.GetRarity("Epic");

	public static Rarity Legendary => RarityUtils.GetRarity("Legendary");

	public static Rarity Mythical => RarityUtils.GetRarity("Mythical");

	public static Rarity Divine => RarityUtils.GetRarity("Divine");

	public static Rarity GetRarity(string name)
	{
		//IL_0002: 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)
		return RarityUtils.GetRarity(name);
	}
}
public class SetDirty : MonoBehaviour
{
	public Graphic m_graphic;

	private void Reset()
	{
		m_graphic = ((Component)this).GetComponent<Graphic>();
	}

	private void Update()
	{
		m_graphic.SetVerticesDirty();
	}
}
[AddComponentMenu("UI/Effects/4 Corners Gradient")]
public class UICornersGradient : BaseMeshEffect
{
	public Color m_topLeftColor = Color.white;

	public Color m_topRightColor = Color.white;

	public Color m_bottomRightColor = Color.white;

	public Color m_bottomLeftColor = Color.white;

	public override void ModifyMesh(VertexHelper vh)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_0071: 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_007d: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: 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)
		if (((Behaviour)this).enabled)
		{
			Rect rect = ((BaseMeshEffect)this).graphic.rectTransform.rect;
			UIGradientUtils.Matrix2x3 matrix2x = UIGradientUtils.LocalPositionMatrix(rect, Vector2.right);
			UIVertex val = default(UIVertex);
			for (int i = 0; i < vh.currentVertCount; i++)
			{
				vh.PopulateUIVertex(ref val, i);
				Vector2 t = matrix2x * Vector2.op_Implicit(val.position);
				ref Color32 color = ref val.color;
				color = Color32.op_Implicit(Color32.op_Implicit(color) * UIGradientUtils.Bilerp(m_bottomLeftColor, m_bottomRightColor, m_topLeftColor, m_topRightColor, t));
				vh.SetUIVertex(val, i);
			}
		}
	}
}
[AddComponentMenu("UI/Effects/Gradient")]
public class UIGradient : BaseMeshEffect
{
	public Color m_color1 = Color.white;

	public Color m_color2 = Color.white;

	[Range(-180f, 180f)]
	public float m_angle = 0f;

	public bool m_ignoreRatio = true;

	public override void ModifyMesh(VertexHelper vh)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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_00a7: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		if (((Behaviour)this).enabled)
		{
			Rect rect = ((BaseMeshEffect)this).graphic.rectTransform.rect;
			Vector2 dir = UIGradientUtils.RotationDir(m_angle);
			if (!m_ignoreRatio)
			{
				dir = UIGradientUtils.CompensateAspectRatio(rect, dir);
			}
			UIGradientUtils.Matrix2x3 matrix2x = UIGradientUtils.LocalPositionMatrix(rect, dir);
			UIVertex val = default(UIVertex);
			for (int i = 0; i < vh.currentVertCount; i++)
			{
				vh.PopulateUIVertex(ref val, i);
				Vector2 val2 = matrix2x * Vector2.op_Implicit(val.position);
				ref Color32 color = ref val.color;
				color = Color32.op_Implicit(Color32.op_Implicit(color) * Color.Lerp(m_color2, m_color1, val2.y));
				vh.SetUIVertex(val, i);
			}
		}
	}
}
public static class UIGradientUtils
{
	public struct Matrix2x3
	{
		public float m00;

		public float m01;

		public float m02;

		public float m10;

		public float m11;

		public float m12;

		public Matrix2x3(float m00, float m01, float m02, float m10, float m11, float m12)
		{
			this.m00 = m00;
			this.m01 = m01;
			this.m02 = m02;
			this.m10 = m10;
			this.m11 = m11;
			this.m12 = m12;
		}

		public static Vector2 operator *(Matrix2x3 m, Vector2 v)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0037: 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_004e: 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)
			float num = m.m00 * v.x - m.m01 * v.y + m.m02;
			float num2 = m.m10 * v.x + m.m11 * v.y + m.m12;
			return new Vector2(num, num2);
		}
	}

	private static Vector2[] ms_verticesPositions = (Vector2[])(object)new Vector2[4]
	{
		Vector2.up,
		Vector2.one,
		Vector2.right,
		Vector2.zero
	};

	public static Vector2[] VerticePositions => ms_verticesPositions;

	public static Matrix2x3 LocalPositionMatrix(Rect rect, Vector2 dir)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		float x = dir.x;
		float y = dir.y;
		Vector2 min = ((Rect)(ref rect)).min;
		Vector2 size = ((Rect)(ref rect)).size;
		float num = 0.5f;
		float num2 = min.x / size.x + num;
		float num3 = min.y / size.y + num;
		float m = x / size.x;
		float m2 = y / size.y;
		float m3 = 0f - (num2 * x - num3 * y - num);
		float m4 = y / size.x;
		float m5 = x / size.y;
		float m6 = 0f - (num2 * y + num3 * x - num);
		return new Matrix2x3(m, m2, m3, m4, m5, m6);
	}

	public static Vector2 RotationDir(float angle)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		float num = angle * ((float)Math.PI / 180f);
		float num2 = Mathf.Cos(num);
		float num3 = Mathf.Sin(num);
		return new Vector2(num2, num3);
	}

	public static Vector2 CompensateAspectRatio(Rect rect, Vector2 dir)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		float num = ((Rect)(ref rect)).height / ((Rect)(ref rect)).width;
		dir.x *= num;
		return ((Vector2)(ref dir)).normalized;
	}

	public static float InverseLerp(float a, float b, float v)
	{
		return (a != b) ? ((v - a) / (b - a)) : 0f;
	}

	public static Color Bilerp(Color a1, Color a2, Color b1, Color b2, Vector2 t)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: 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)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		Color val = Color.LerpUnclamped(a1, a2, t.x);
		Color val2 = Color.LerpUnclamped(b1, b2, t.x);
		return Color.LerpUnclamped(val, val2, t.y);
	}

	public static void Lerp(UIVertex a, UIVertex b, float t, ref UIVertex c)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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)
		//IL_0014: 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_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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_0072: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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)
		c.position = Vector3.LerpUnclamped(a.position, b.position, t);
		c.normal = Vector3.LerpUnclamped(a.normal, b.normal, t);
		c.color = Color32.LerpUnclamped(a.color, b.color, t);
		c.tangent = Vector4.op_Implicit(Vector3.LerpUnclamped(Vector4.op_Implicit(a.tangent), Vector4.op_Implicit(b.tangent), t));
		c.uv0 = Vector2.op_Implicit(Vector3.LerpUnclamped(Vector2.op_Implicit(a.uv0), Vector2.op_Implicit(b.uv0), t));
		c.uv1 = Vector2.op_Implicit(Vector3.LerpUnclamped(Vector2.op_Implicit(a.uv1), Vector2.op_Implicit(b.uv1), t));
	}
}
[AddComponentMenu("UI/Effects/Text 4 Corners Gradient")]
public class UITextCornersGradient : BaseMeshEffect
{
	public Color m_topLeftColor = Color.white;

	public Color m_topRightColor = Color.white;

	public Color m_bottomRightColor = Color.white;

	public Color m_bottomLeftColor = Color.white;

	public override void ModifyMesh(VertexHelper vh)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		if (((Behaviour)this).enabled)
		{
			Rect rect = ((BaseMeshEffect)this).graphic.rectTransform.rect;
			UIVertex val = default(UIVertex);
			for (int i = 0; i < vh.currentVertCount; i++)
			{
				vh.PopulateUIVertex(ref val, i);
				Vector2 t = UIGradientUtils.VerticePositions[i % 4];
				ref Color32 color = ref val.color;
				color = Color32.op_Implicit(Color32.op_Implicit(color) * UIGradientUtils.Bilerp(m_bottomLeftColor, m_bottomRightColor, m_topLeftColor, m_topRightColor, t));
				vh.SetUIVertex(val, i);
			}
		}
	}
}
[AddComponentMenu("UI/Effects/Text Gradient")]
public class UITextGradient : BaseMeshEffect
{
	public Color m_color1 = Color.white;

	public Color m_color2 = Color.white;

	[Range(-180f, 180f)]
	public float m_angle = 0f;

	public override void ModifyMesh(VertexHelper vh)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: 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_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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)
		if (((Behaviour)this).enabled)
		{
			Rect rect = ((BaseMeshEffect)this).graphic.rectTransform.rect;
			Vector2 dir = UIGradientUtils.RotationDir(m_angle);
			UIGradientUtils.Matrix2x3 matrix2x = UIGradientUtils.LocalPositionMatrix(new Rect(0f, 0f, 1f, 1f), dir);
			UIVertex val = default(UIVertex);
			for (int i = 0; i < vh.currentVertCount; i++)
			{
				vh.PopulateUIVertex(ref val, i);
				Vector2 val2 = UIGradientUtils.VerticePositions[i % 4];
				Vector2 val3 = matrix2x * val2;
				ref Color32 color = ref val.color;
				color = Color32.op_Implicit(Color32.op_Implicit(color) * Color.Lerp(m_color2, m_color1, val3.y));
				vh.SetUIVertex(val, i);
			}
		}
	}
}
namespace WillsWackyManagers
{
	internal static class RoundsResources
	{
		private static TMP_FontAsset _menuFont;

		private static GameObject _flickeringTextPrefab;

		private static GameObject _popUpMenuTextPrefab;

		private static Dictionary<string, SoundEvent> _soundCache = new Dictionary<string, SoundEvent>();

		public static TMP_FontAsset MenuFont
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_menuFont) && Object.op_Implicit((Object)(object)MainMenuHandler.instance))
				{
					GameObject gameObject = ((Component)((Component)MainMenuHandler.instance).transform.Find("Canvas").Find("ListSelector").Find("Main")
						.Find("Group")
						.Find("Local")).gameObject;
					_menuFont = ((TMP_Text)gameObject.GetComponentInChildren<TextMeshProUGUI>()).font;
				}
				return _menuFont;
			}
		}

		public static GameObject FlickeringTextPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_flickeringTextPrefab))
				{
					GameObject val = GameObject.Find("/Game/UI/UI_Game/Canvas/Join");
					if (Object.op_Implicit((Object)(object)val))
					{
						_flickeringTextPrefab = Object.Instantiate<GameObject>(val);
						((Object)_flickeringTextPrefab).name = "Text";
						GeneralParticleSystem componentInChildren = _flickeringTextPrefab.GetComponentInChildren<GeneralParticleSystem>();
						componentInChildren.loop = true;
						componentInChildren.playOnEnablee = true;
						componentInChildren.playOnAwake = true;
						componentInChildren.StartLooping();
						_flickeringTextPrefab.GetComponent<Mask>().showMaskGraphic = true;
					}
				}
				return _flickeringTextPrefab;
			}
		}

		public static GameObject PopUpMenuText
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_popUpMenuTextPrefab))
				{
					GameObject val = GameObject.Find("Game/UI/UI_Game/Canvas/PopUpHandler/Yes");
					if (Object.op_Implicit((Object)(object)val))
					{
						_popUpMenuTextPrefab = Object.Instantiate<GameObject>(val);
						((Object)_popUpMenuTextPrefab).name = "Text";
						GeneralParticleSystem componentInChildren = _popUpMenuTextPrefab.GetComponentInChildren<GeneralParticleSystem>();
						componentInChildren.loop = true;
						componentInChildren.playOnEnablee = true;
						componentInChildren.playOnAwake = true;
						componentInChildren.StartLooping();
					}
				}
				return _popUpMenuTextPrefab;
			}
		}

		public static SoundEvent GetSound(string name)
		{
			if (!_soundCache.ContainsKey(name))
			{
				GameObject gameObject = ((Component)GameObject.Find("/SonigonSoundEventPool").transform.Find(name)).gameObject;
				SoundEvent value = ((gameObject != null) ? gameObject.GetComponent<InstanceSoundEvent>().soundEvent : null);
				_soundCache.Add(name, value);
			}
			return _soundCache[name];
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.willuwontu.rounds.managers", "Will's Wacky Managers", "1.5.13")]
	[BepInProcess("Rounds.exe")]
	public class WillsWackyManagers : BaseUnityPlugin
	{
		private static class WaitFor
		{
			public static IEnumerator Frames(int frameCount)
			{
				if (frameCount <= 0)
				{
					throw new ArgumentOutOfRangeException("frameCount", "Cannot wait for less that 1 frame");
				}
				while (frameCount > 0)
				{
					frameCount--;
					yield return null;
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__21_0;

			public static Func<bool> <>9__25_0;

			public static Func<bool> <>9__25_1;

			public static Predicate<CardCategory> <>9__26_0;

			public static Predicate<CardCategory> <>9__29_0;

			public static UnityAction<bool> <>9__30_0;

			public static UnityAction<bool> <>9__30_2;

			internal void <Start>b__21_0()
			{
			}

			internal bool <PickEnd>b__25_0()
			{
				return !RerollManager.instance.tableFlipped;
			}

			internal bool <PickEnd>b__25_1()
			{
				return !RerollManager.instance.reroll;
			}

			internal bool <GameStart>b__26_0(CardCategory category)
			{
				return (Object)(object)category == (Object)(object)RerollManager.instance.NoFlip;
			}

			internal bool <PickStart>b__29_0(CardCategory category)
			{
				return (Object)(object)category == (Object)(object)TableFlip.tableFlipCardCategory;
			}

			internal void <NewGUI>b__30_0(bool value)
			{
				enableCurseRemovalConfig.Value = value;
				enableCurseRemoval = value;
			}

			internal void <NewGUI>b__30_2(bool value)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				secondHalfTableFlipConfig.Value = value;
				secondHalfTableFlip = value;
				if (secondHalfTableFlip)
				{
					RerollManager.instance.tableFlipCard.rarity = (Rarity)1;
				}
				else
				{
					RerollManager.instance.tableFlipCard.rarity = (Rarity)2;
				}
			}
		}

		public const string ModId = "com.willuwontu.rounds.managers";

		private const string ModName = "Will's Wacky Managers";

		public const string Version = "1.5.13";

		internal const string ModInitials = "WWM";

		public const string CurseInitials = "Curse";

		public static WillsWackyManagers instance;

		public static bool enableCurseRemoval = false;

		public static bool enableCurseSpawning = true;

		public static ConfigEntry<bool> enableCurseRemovalConfig;

		public static ConfigEntry<bool> enableCurseSpawningConfig;

		public static bool enableTableFlip = true;

		public static bool secondHalfTableFlip = true;

		public static ConfigEntry<bool> enableTableFlipConfig;

		public static ConfigEntry<bool> secondHalfTableFlipConfig;

		public GameObject optionsMenu;

		private const bool debug = false;

		public AssetBundle WWMAssets { get; private set; }

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_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_00cb: 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)
			//IL_00d6: 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)
			instance = this;
			Harmony val = new Harmony("com.willuwontu.rounds.managers");
			val.PatchAll();
			typeof(Unbound).GetField("templateCard", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField).SetValue(null, Resources.Load<GameObject>("0 Cards/0. PlainCard").GetComponent<CardInfo>());
			ExtensionMethods.GetOrAddComponent<RerollManager>(((Component)this).gameObject, false);
			ExtensionMethods.GetOrAddComponent<CurseManager>(((Component)this).gameObject, false);
			((Component)this).gameObject.AddComponent<SettingCoordinator>();
			CardThemeColorType cursedPink = CurseManager.instance.CursedPink;
			cursedPink = CurseManager.instance.CurseGray;
			cursedPink = CurseManager.instance.CorruptedRed;
			cursedPink = CurseManager.instance.FoolsGold;
			cursedPink = CurseManager.instance.FallenPurple;
			cursedPink = CurseManager.instance.ShitBrown;
			cursedPink = CurseManager.instance.FracturedBlue;
			cursedPink = CurseManager.instance.FrozenBlue;
			cursedPink = CurseManager.instance.DefaultWhite;
			cursedPink = CurseManager.instance.ToxicGreen;
			enableCurseSpawningConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("WWM", "CurseSpawning", true, "Cards that give curses can spawn.");
			enableCurseRemovalConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("WWM", "CurseRemoval", false, "Enables curse removal via end of round effects.");
			enableCurseRemoval = enableCurseRemovalConfig.Value;
			enableCurseSpawning = enableCurseSpawningConfig.Value;
			enableTableFlipConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("WWM", "TableFlipAllowed", true, "Enable table flip and reroll.");
			secondHalfTableFlipConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("WWM", "TableFlipSecondHalf", true, "Makes Table Flip an Uncommon and only able to appear in the second half.");
			enableTableFlip = enableTableFlipConfig.Value;
			secondHalfTableFlip = secondHalfTableFlipConfig.Value;
			WWMAssets = AssetUtils.LoadAssetBundleFromResources("wwccards", typeof(WillsWackyManagers).Assembly);
		}

		private void Start()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			object obj = <>c.<>9__21_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
				};
				<>c.<>9__21_0 = val;
				obj = (object)val;
			}
			Unbound.RegisterMenu("Will's Wacky Options", (UnityAction)obj, (Action<GameObject>)NewGUI, (GameObject)null, false);
			GameModeManager.AddHook("PlayerPickStart", (Func<IGameModeHandler, IEnumerator>)PlayerPickStart);
			GameModeManager.AddHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)PlayerPickEnd);
			GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)GameStart);
			GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)PickEnd);
			GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)PickStart);
			GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)GameEnd);
			GameObject val2 = WWMAssets.LoadAsset<GameObject>("WWM CardManager");
			CardBuilder[] componentsInChildren = val2.GetComponentsInChildren<CardBuilder>();
			foreach (CardBuilder cardBuilder in componentsInChildren)
			{
				cardBuilder.BuildCards();
			}
		}

		public void DebugLog(object message)
		{
			bool flag = false;
		}

		private IEnumerator PlayerPickEnd(IGameModeHandler gm)
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			yield return GroupWinnings.ExtraPicks();
		}

		private IEnumerator PlayerPickStart(IGameModeHandler gm)
		{
			yield break;
		}

		private IEnumerator PickEnd(IGameModeHandler gm)
		{
			if (RerollManager.instance.tableFlipped)
			{
				((MonoBehaviour)this).StartCoroutine(RerollManager.instance.IFlipTableNew());
			}
			yield return (object)new WaitUntil((Func<bool>)(() => !RerollManager.instance.tableFlipped));
			if (!PhotonNetwork.OfflineMode)
			{
				Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties;
				customProperties[(object)"Table Flip Sync Stats"] = false;
				PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
			}
			if (RerollManager.instance.reroll)
			{
				((MonoBehaviour)this).StartCoroutine(RerollManager.instance.InitiateRerolls());
			}
			yield return (object)new WaitUntil((Func<bool>)(() => !RerollManager.instance.reroll));
			if (!PhotonNetwork.OfflineMode)
			{
				Hashtable customProperties2 = PhotonNetwork.LocalPlayer.CustomProperties;
				customProperties2[(object)"Reroll Sync Stats"] = false;
				PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties2, (Hashtable)null, (WebFlags)null);
			}
			Player[] mixers = RerollManager.instance.MixUpPlayers.ToArray();
			Player[] array = mixers;
			foreach (Player player in array)
			{
				yield return RerollManager.instance.IMixUpCards(player);
			}
			RerollManager.instance.MixUpPlayers.Clear();
		}

		private IEnumerator GameStart(IGameModeHandler gm)
		{
			foreach (Player player in PlayerManager.instance.players)
			{
				CurseManager.instance.PlayerCanDrawCurses(player, canDraw: false);
				if (!enableTableFlip)
				{
					if (!CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.Contains(RerollManager.instance.NoFlip))
					{
						CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.Add(RerollManager.instance.NoFlip);
					}
				}
				else
				{
					CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.RemoveAll((CardCategory category) => (Object)(object)category == (Object)(object)RerollManager.instance.NoFlip);
				}
			}
			yield break;
		}

		private IEnumerator GameEnd(IGameModeHandler gm)
		{
			DestroyAll<Misfire_Mono>();
			yield break;
		}

		private void DestroyAll<T>() where T : Object
		{
			T[] array = Object.FindObjectsOfType<T>();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				Debug.Log((object)$"Attempting to Destroy {((object)array[num]).GetType().Name} number {num}");
				Object.Destroy((Object)(object)array[num]);
			}
		}

		private IEnumerator PickStart(IGameModeHandler gm)
		{
			if (secondHalfTableFlip)
			{
				RerollManager.instance.tableFlipCard.rarity = (Rarity)1;
				int roundsToWin = (int)gm.Settings["roundsToWinGame"];
				bool pickable = false;
				foreach (Player player2 in PlayerManager.instance.players)
				{
					if (gm.GetTeamScore(player2.teamID).rounds >= roundsToWin / 2 + roundsToWin % 2)
					{
						pickable = true;
					}
				}
				foreach (Player player in PlayerManager.instance.players)
				{
					if (!pickable)
					{
						if (!CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.Contains(TableFlip.tableFlipCardCategory))
						{
							CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.Add(TableFlip.tableFlipCardCategory);
						}
					}
					else
					{
						CharacterStatModifiersExtension.GetAdditionalData(player.data.stats).blacklistedCategories.RemoveAll((CardCategory category) => (Object)(object)category == (Object)(object)TableFlip.tableFlipCardCategory);
					}
				}
			}
			yield return WaitFor.Frames(10);
			Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties[(object)"Table Flip Sync Stats"] = false;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
			yield return WaitFor.Frames(10);
		}

		private static void NewGUI(GameObject menu)
		{
			TextMeshProUGUI val = default(TextMeshProUGUI);
			MenuHandler.CreateText("Will's Wacky Options", menu, ref val, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateText("Curse Manager", menu, ref val, 45, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			GameObject val2 = MenuHandler.CreateToggle(enableCurseSpawningConfig.Value, "Enables curse spawning cards.", menu, (UnityAction<bool>)null, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			GameObject curseRemove = MenuHandler.CreateToggle(enableCurseRemovalConfig.Value, "Enables curse removal between rounds.", menu, (UnityAction<bool>)delegate(bool value)
			{
				enableCurseRemovalConfig.Value = value;
				enableCurseRemoval = value;
			}, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			((UnityEvent<bool>)(object)val2.GetComponent<Toggle>().onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				curseRemove.SetActive(value);
				if (!value)
				{
					curseRemove.GetComponent<Toggle>().isOn = false;
				}
				enableCurseSpawningConfig.Value = value;
				enableCurseSpawning = value;
			});
			MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateText("Reroll Manager", menu, ref val, 45, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			MenuHandler.CreateText(" ", menu, ref val, 30, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			GameObject val3 = MenuHandler.CreateToggle(enableTableFlipConfig.Value, "Enable Table Flip and Reroll", menu, (UnityAction<bool>)null, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			GameObject secondHalf = MenuHandler.CreateToggle(secondHalfTableFlipConfig.Value, "Table Flip becomes uncommon, and can only show up when someone has half the rounds needed to win.", menu, (UnityAction<bool>)delegate(bool value)
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				secondHalfTableFlipConfig.Value = value;
				secondHalfTableFlip = value;
				if (secondHalfTableFlip)
				{
					RerollManager.instance.tableFlipCard.rarity = (Rarity)1;
				}
				else
				{
					RerollManager.instance.tableFlipCard.rarity = (Rarity)2;
				}
			}, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
			Toggle secondHalfToggle = secondHalf.GetComponent<Toggle>();
			((UnityEvent<bool>)(object)val3.GetComponent<Toggle>().onValueChanged).AddListener((UnityAction<bool>)delegate(bool value)
			{
				secondHalf.SetActive(value);
				if (!value)
				{
					secondHalfToggle.isOn = false;
				}
				enableTableFlipConfig.Value = value;
				enableTableFlip = value;
			});
			instance.optionsMenu = menu;
			MenuHandler.CreateText(" ", menu, ref val, 60, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		}

		internal void OnHandShakeCompleted()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				for (int i = 0; i < 1; i++)
				{
					NetworkingManager.RPC(typeof(WillsWackyManagers), "RPCA_SyncSettings", new object[4] { enableCurseSpawningConfig.Value, enableCurseRemovalConfig.Value, enableTableFlipConfig.Value, secondHalfTableFlipConfig.Value });
					RPCA_SyncSettings(enableCurseSpawningConfig.Value, enableCurseRemovalConfig.Value, enableTableFlipConfig.Value, secondHalfTableFlipConfig.Value);
				}
			}
		}

		[UnboundRPC]
		private static void RPCA_SyncSettings(bool curseSpawningEnabled, bool curseRemovalEnabled, bool tableFlipEnabled, bool tableFlipSecondHalf)
		{
			//IL_0072: 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)
			enableCurseSpawningConfig.Value = curseSpawningEnabled;
			enableCurseRemovalConfig.Value = curseRemovalEnabled;
			enableTableFlipConfig.Value = tableFlipEnabled;
			secondHalfTableFlipConfig.Value = tableFlipSecondHalf;
			enableCurseSpawning = curseSpawningEnabled;
			enableCurseRemoval = curseRemovalEnabled;
			enableTableFlip = tableFlipEnabled;
			secondHalfTableFlip = tableFlipSecondHalf;
			if (secondHalfTableFlip)
			{
				RerollManager.instance.tableFlipCard.rarity = (Rarity)1;
			}
			else
			{
				RerollManager.instance.tableFlipCard.rarity = (Rarity)2;
			}
			instance.DebugLog($"[WWM][Settings][Sync]\nEnable Curse Spawning: {curseSpawningEnabled}\nEnable Curse Removal: {curseRemovalEnabled}\nEnable Table Flip: {tableFlipEnabled}\nTable Flip Second Half Only: {tableFlipSecondHalf}");
			Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties[(object)"WWM Settings"] = true;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
		}

		public static IEnumerator ExtraPicks(Dictionary<Player, int> pickers)
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			for (int _ = 0; _ < pickers.Values.ToArray().Max(); _++)
			{
				for (int j = 0; j < pickers.Keys.Count; j++)
				{
					Player player = pickers.Keys.ToArray()[j];
					if (pickers[player] > 0)
					{
						yield return GameModeManager.TriggerHook("PlayerPickStart");
						CardChoiceVisuals.instance.Show((from i2 in Enumerable.Range(0, PlayerManager.instance.players.Count)
							where PlayerManager.instance.players[i2].playerID == player.playerID
							select i2).First(), true);
						yield return CardChoice.instance.DoPick(1, player.playerID, (PickerType)1);
						yield return (object)new WaitForSecondsRealtime(0.1f);
						yield return GameModeManager.TriggerHook("PlayerPickEnd");
						yield return (object)new WaitForSecondsRealtime(0.1f);
						pickers[player]--;
					}
				}
			}
			CardChoiceVisuals.instance.Hide();
		}

		public void InjectUIElements()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("/Game/UI");
			GameObject gameObject = ((Component)val.transform.Find("UI_Game").Find("Canvas")).gameObject;
			if (!Object.op_Implicit((Object)(object)gameObject.transform.Find("PopUpMenuWWM")))
			{
				GameObject val2 = new GameObject("PopUpMenuWWM");
				val2.transform.SetParent(gameObject.transform);
				val2.transform.localScale = Vector3.one;
				val2.AddComponent<PopUpMenu>();
			}
		}
	}
}
namespace WillsWackyManagers.Utils
{
	public class CurseManager : MonoBehaviour
	{
		private static class WaitFor
		{
			public static IEnumerator Frames(int frameCount)
			{
				if (frameCount <= 0)
				{
					throw new ArgumentOutOfRangeException("frameCount", "Cannot wait for less that 1 frame");
				}
				while (frameCount > 0)
				{
					frameCount--;
					yield return null;
				}
			}
		}

		public struct CurseRemovalOption
		{
			public readonly string name;

			public readonly Func<Player, bool> condition;

			public readonly Func<Player, IEnumerator> action;

			public CurseRemovalOption(string optionName, Func<Player, bool> optionCondition, Func<Player, IEnumerator> optionAction)
			{
				name = optionName.ToUpper();
				condition = optionCondition;
				action = optionAction;
			}
		}

		private List<CardInfo> curses = new List<CardInfo>();

		private Random random = new Random();

		private bool deckCustomizationLoaded = false;

		private static bool extremeDebugging;

		private Dictionary<Player, bool> canDrawCurses = new Dictionary<Player, bool>();

		private CurseRemovalOption keepCurse;

		private CurseRemovalOption removeRound;

		private CurseRemovalOption giveExtraPick;

		private CurseRemovalOption removeAllCards;

		private CurseRemovalOption doNotAsk;

		private List<CurseRemovalOption> removalOptions = new List<CurseRemovalOption>();

		private bool playerDeciding = false;

		private bool choseAction = false;

		private Player decidingPlayer;

		private Dictionary<Player, int> curseCount = new Dictionary<Player, int>();

		private List<Player> doNotAskPlayers = new List<Player>();

		public static CurseManager instance { get; private set; }

		private List<CardInfo> ActiveCurses => curses.Intersect((from card in CardManager.cards.Values.ToArray()
			where card.enabled
			select card.cardInfo).ToArray()).ToList();

		public bool CursePick { get; private set; } = false;


		public ReadOnlyCollection<CardInfo> Curses => new ReadOnlyCollection<CardInfo>(curses);

		public CardThemeColorType CurseGray => CardThemeLib.instance.CreateOrGetType("CurseGray", new CardThemeColor
		{
			bgColor = new Color(0.34f, 0f, 0.44f),
			targetColor = new Color(0.24f, 0.24f, 0.24f)
		});

		public CardThemeColorType CorruptedRed => CardThemeLib.instance.CreateOrGetType("CorruptedRed", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)60, (byte)0, (byte)0, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)20, (byte)20, (byte)200))
		});

		public CardThemeColorType CursedPink => CardThemeLib.instance.CreateOrGetType("CursedPink", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)60, (byte)10, (byte)30, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)20, (byte)70, (byte)200))
		});

		public CardThemeColorType FoolsGold => CardThemeLib.instance.CreateOrGetType("FoolsGold", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)50, (byte)50, (byte)10, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)110, (byte)20, (byte)200))
		});

		public CardThemeColorType ToxicGreen => CardThemeLib.instance.CreateOrGetType("ToxicGreen", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)0, (byte)40, (byte)0, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)20, (byte)100, (byte)20, (byte)200))
		});

		public CardThemeColorType FallenPurple => CardThemeLib.instance.CreateOrGetType("FallenPurple", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)50, (byte)10, (byte)50, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)20, (byte)110, (byte)200))
		});

		public CardThemeColorType ShitBrown => CardThemeLib.instance.CreateOrGetType("ShitBrown", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)50, (byte)40, (byte)0, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)90, (byte)20, (byte)200))
		});

		public CardThemeColorType FrozenBlue => CardThemeLib.instance.CreateOrGetType("FrozenBlue", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)0, (byte)40, (byte)50, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)20, (byte)90, (byte)110, (byte)200))
		});

		public CardThemeColorType FracturedBlue => CardThemeLib.instance.CreateOrGetType("FracturedBlue", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)0, (byte)0, (byte)50, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)20, (byte)20, (byte)110, (byte)200))
		});

		public CardThemeColorType ObseleteWhite => CardThemeLib.instance.CreateOrGetType("ObseleteWhite", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32((byte)40, (byte)40, (byte)40, (byte)200)),
			targetColor = Color32.op_Implicit(new Color32((byte)110, (byte)110, (byte)110, (byte)200))
		});

		public CardThemeColorType DefaultWhite => CardThemeLib.instance.CreateOrGetType("DefaultWhite", new CardThemeColor
		{
			bgColor = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)),
			targetColor = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue))
		});

		public CardCategory curseCategory { get; private set; } = CustomCardCategories.instance.CardCategory("Curse");


		public CardCategory kindCurseCategory { get; private set; } = CustomCardCategories.instance.CardCategory("kindCurse");


		public CardCategory countAsCurseCategory { get; private set; } = CustomCardCategories.instance.CardCategory("countAsCurse");


		public CardCategory curseInteractionCategory { get; private set; } = CustomCardCategories.instance.CardCategory("Cursed");


		public CardCategory curseSpawnerCategory { get; private set; } = CustomCardCategories.instance.CardCategory("Grants Curses");


		private static void ExtremeDebugLog(object message)
		{
			if (extremeDebugging)
			{
				Debug.Log(message);
			}
		}

		public void PlayerCanDrawCurses(Player player, bool canDraw = true)
		{
			ExtremeDebugLog(string.Format("[WWM][{0}()] CanDrawCurses for Player {1} is set to {2}.", "PlayerCanDrawCurses", player.playerID, canDraw));
			canDrawCurses[player] = canDraw;
		}

		public bool CanPlayerDrawCurses(Player player)
		{
			if (canDrawCurses.TryGetValue(player, out var value))
			{
				ExtremeDebugLog(string.Format("[WWM][{0}()] Player {1} {2} allowed to draw curses.", "CanPlayerDrawCurses", player.playerID, value ? "is" : "is not"));
				return value;
			}
			return false;
		}

		private bool CursedPickCondition(Player player, CardInfo card)
		{
			if (!CursePick)
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)card))
			{
				return true;
			}
			if (!curses.Contains(card))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)player))
			{
				return true;
			}
			return true;
		}

		private bool CanDrawCursesCondition(Player player, CardInfo card)
		{
			if (!Object.op_Implicit((Object)(object)card))
			{
				return true;
			}
			if (!curses.Contains(card))
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)player))
			{
				return true;
			}
			if (CursePick)
			{
				return true;
			}
			ExtremeDebugLog(string.Format("[WWM][{0}()][{1}] Checking if player {2} is allowed to draw curses.", "CanDrawCursesCondition", card.cardName, player.playerID));
			if (canDrawCurses.TryGetValue(player, out var value))
			{
				Debug.Log((object)string.Format("[WWM][{0}()][{1}] Player {2} {3} allowed to draw curses.", "CanDrawCursesCondition", card.cardName, player.playerID, value ? "is" : "is not"));
				return value;
			}
			ExtremeDebugLog(string.Format("[WWM][{0}()][{1}] Player {2} did not have a value set, defaulting to false.", "CanDrawCursesCondition", card.cardName, player.playerID));
			return false;
		}

		private bool CanDrawCurseInteractionCondition(Player player, CardInfo card)
		{
			if (!card.categories.Contains(curseInteractionCategory))
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)player))
			{
				return true;
			}
			if (!HasCurse(player))
			{
				return false;
			}
			return true;
		}

		private bool CanDrawCurseSpawnerCondition(Player player, CardInfo card)
		{
			if (!card.categories.Contains(curseSpawnerCategory))
			{
				return true;
			}
			if (!WillsWackyManagers.enableCurseSpawning)
			{
				return false;
			}
			return true;
		}

		public void AddCursedPick(Player player)
		{
			Debug.Log((object)$"Adding a cursed pick for Player {player.playerID}.");
			GameModeManager.AddHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)GreedPick);
			IEnumerator GreedPick(IGameModeHandler gm)
			{
				Debug.Log((object)$"Starting a cursed pick for Player {player.playerID}.");
				yield return GameModeManager.TriggerHook("PlayerPickStart");
				CursePick = true;
				CardChoiceVisuals.instance.Show((from i in Enumerable.Range(0, PlayerManager.instance.players.Count)
					where PlayerManager.instance.players[i].playerID == player.playerID
					select i).First(), true);
				yield return CardChoice.instance.DoPick(1, player.playerID, (PickerType)1);
				yield return (object)new WaitForSecondsRealtime(0.1f);
				CursePick = false;
				GameModeManager.RemoveHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)GreedPick);
				yield return GameModeManager.TriggerHook("PlayerPickEnd");
				yield return (object)new WaitForSecondsRealtime(0.1f);
				Debug.Log((object)$"Exiting a cursed pick for Player {player.playerID}.");
			}
		}

		private void Start()
		{
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)CanDrawCursesCondition);
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)CanDrawCurseInteractionCondition);
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)CanDrawCurseSpawnerCondition);
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)CursedPickCondition);
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)this, 50, (Action)delegate
			{
				foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
				{
					if (pluginInfo.Key == "pykess.rounds.plugins.deckcustomization")
					{
						deckCustomizationLoaded = true;
						break;
					}
				}
				if (!deckCustomizationLoaded)
				{
				}
			});
			GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)GameStart);
			GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)OnPickStart);
			keepCurse = new CurseRemovalOption("Keep Curse", (Player player) => true, IKeepCurse);
			removeRound = new CurseRemovalOption("-1 round, -2 curses", CondRemoveRound, IRemoveRound);
			removeAllCards = new CurseRemovalOption("Lose all cards, lose all curses", CondRemoveAllCards, IRemoveAllCards);
			giveExtraPick = new CurseRemovalOption("You: -2 curses, Enemies: +1 Pick", CondGiveExtraPick, IGiveExtraPick);
			doNotAsk = new CurseRemovalOption("Do Not Ask Again", (Player player) => true, IStopAsking);
			RegisterRemovalOption(keepCurse);
			RegisterRemovalOption(giveExtraPick);
			RegisterRemovalOption(removeAllCards);
			RegisterRemovalOption(removeRound);
			RegisterRemovalOption(doNotAsk);
		}

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			else if ((Object)(object)instance != (Object)(object)this)
			{
				Object.DestroyImmediate((Object)(object)this);
			}
		}

		private void CheckCurses()
		{
			List<CardInfo> activeCurses = ActiveCurses;
		}

		public CardInfo RandomCurse()
		{
			CardInfo val = CardChoicePatchGetRanomCard.OrignialGetRanomCard(ActiveCurses.ToArray()).GetComponent<CardInfo>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = FallbackMethod(curses.ToArray());
			}
			return val;
		}

		public CardInfo RandomCurse(Player player)
		{
			return RandomCurse(player, (CardInfo card, Player person) => true);
		}

		public CardInfo RandomCurse(Player player, Func<CardInfo, Player, bool> condition)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return null;
			}
			CheckCurses();
			ExtremeDebugLog(string.Format("[WWM][{0}()] Checking if Player {1} was able to draw curses before.", "RandomCurse", player.playerID));
			bool flag = CanPlayerDrawCurses(player);
			ExtremeDebugLog(string.Format("[WWM][{0}()] Player {1} {2} able to draw curses before.", "RandomCurse", player.playerID, flag ? "was" : "was not"));
			canDrawCurses[player] = true;
			CardInfo[] source = ActiveCurses.Where((CardInfo card) => Cards.instance.PlayerIsAllowedCard(player, card) && condition(card, player)).ToArray();
			CardInfo val = null;
			try
			{
				val = CardChoicePatchGetRanomCard.OrignialGetRanomCard(source.ToArray()).GetComponent<CardInfo>();
			}
			catch (NullReferenceException)
			{
			}
			catch (Exception ex2)
			{
				Debug.LogException(ex2);
			}
			ExtremeDebugLog(string.Format("[WWM][{0}()] Setting the ability for Player {1} to draw curses back to {2} ", "RandomCurse", player.playerID, flag));
			canDrawCurses[player] = flag;
			ExtremeDebugLog(string.Format("[WWM][{0}] canDrawCurses for Player {1} set to {2}.", "RandomCurse", player.playerID, canDrawCurses[player]));
			if (!Object.op_Implicit((Object)(object)val) || !curses.Contains(val))
			{
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] curse didn't exist, getting one now.");
				val = FallbackMethod(source.ToArray());
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = FallbackMethod(ActiveCurses.ToArray());
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = FallbackMethod(curses.ToArray());
				}
			}
			return val;
		}

		public bool PlayerIsAllowedCurse(Player player, CardInfo card)
		{
			if ((Object)(object)player == (Object)null)
			{
				return true;
			}
			if ((Object)(object)card == (Object)null || !curses.Contains(card))
			{
				return false;
			}
			ExtremeDebugLog(string.Format("[WWM][{0}()] Checking if Player {1} is allowed to draw curses.", "PlayerIsAllowedCurse", player.playerID));
			bool flag = instance.CanPlayerDrawCurses(player);
			ExtremeDebugLog(string.Format("[WWM][{0}()] Player {1} {2} able to draw curses.", "PlayerIsAllowedCurse", player.playerID, flag ? "is" : "is not"));
			instance.PlayerCanDrawCurses(player);
			bool flag2 = Cards.instance.PlayerIsAllowedCard(player, card);
			ExtremeDebugLog(string.Format("[WWM][{0}()] {1} {2} allowed for Player {3}. Resetting their canDrawCurses to {4}", "PlayerIsAllowedCurse", card.cardName, flag2 ? "is" : "is not", player.playerID, flag));
			instance.PlayerCanDrawCurses(player, flag);
			ExtremeDebugLog(string.Format("[WWM][{0}()] canDrawCurses for Player {1} set to {2}.", "PlayerIsAllowedCurse", player.playerID, flag));
			return flag2;
		}

		private CardInfo FallbackMethod(CardInfo[] availableChoices)
		{
			//IL_006b: 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)
			CardInfo result = null;
			float num = 0f;
			Dictionary<Rarity, Rarity> dictionary = RarityUtils.Rarities.Values.ToDictionary((Rarity r) => r.value, (Rarity r) => r);
			foreach (CardInfo val in availableChoices)
			{
				if (dictionary.TryGetValue(val.rarity, out var value))
				{
					num += value.relativeRarity * 10f;
				}
			}
			float num2 = Random.Range(0f, num);
			foreach (CardInfo val2 in availableChoices)
			{
				if (dictionary.TryGetValue(val2.rarity, out var value2))
				{
					num2 -= value2.relativeRarity * 10f;
				}
				if (num2 <= 0f)
				{
					result = val2;
					break;
				}
			}
			return result;
		}

		public void CursePlayer(Player player)
		{
			CursePlayer(player, null, null);
		}

		public void CursePlayer(Player player, Action<CardInfo> callback)
		{
			CursePlayer(player, callback, null);
		}

		public void CursePlayer(Player player, Func<CardInfo, Player, bool> condition)
		{
			CursePlayer(player, null, condition);
		}

		public void CursePlayer(Player player, Action<CardInfo> callback, Func<CardInfo, Player, bool> condition)
		{
			CardInfo val = null;
			val = ((condition == null) ? RandomCurse(player) : RandomCurse(player, condition));
			WillsWackyManagers.instance.DebugLog($"[WWM][Curse Manager] Player {player.playerID} cursed with {val.cardName}.");
			Cards.instance.AddCardToPlayer(player, val, false, "", 2f, 2f, true);
			callback?.Invoke(val);
		}

		public void RegisterCurse(CardInfo cardInfo)
		{
			curses.Add(cardInfo);
		}

		public CardInfo[] GetRaw(bool activeOnly = false)
		{
			if (activeOnly)
			{
				return ActiveCurses.ToArray();
			}
			return curses.ToArray();
		}

		public bool HasCurse(Player player)
		{
			bool flag = false;
			return curses.Intersect(player.data.currentCards).Any();
		}

		public bool IsCurse(CardInfo cardInfo)
		{
			return curses.Contains(cardInfo);
		}

		public CardInfo[] GetAllCursesOnPlayer(Player player)
		{
			List<CardInfo> list = new List<CardInfo>();
			foreach (CardInfo currentCard in player.data.currentCards)
			{
				if (IsCurse(currentCard))
				{
					list.Add(currentCard);
				}
			}
			return list.ToArray();
		}

		public void RemoveAllCurses(Player player)
		{
			Action<CardInfo[]> callback = null;
			RemoveAllCurses(player, callback);
		}

		public void RemoveAllCurses(Player player, Action<CardInfo> callback)
		{
			((MonoBehaviour)this).StartCoroutine(IRemoveAllCurses(player, callback));
		}

		public void RemoveAllCurses(Player player, Action<CardInfo[]> callback)
		{
			((MonoBehaviour)this).StartCoroutine(IRemoveAllCurses(player, callback));
		}

		private IEnumerator IRemoveAllCurses(Player player, Action<CardInfo> callback)
		{
			int[] curseIndeces = (from index in Enumerable.Range(0, player.data.currentCards.Count())
				where IsCurse(player.data.currentCards[index])
				select index).ToArray();
			CardInfo[] playerCurses = Cards.instance.RemoveCardsFromPlayer(player, curseIndeces);
			CardInfo[] array = playerCurses;
			foreach (CardInfo curse in array)
			{
				callback?.Invoke(curse);
				yield return WaitFor.Frames(20);
			}
		}

		private IEnumerator IRemoveAllCurses(Player player, Action<CardInfo[]> callback)
		{
			int[] curseIndeces = (from index in Enumerable.Range(0, player.data.currentCards.Count())
				where IsCurse(player.data.currentCards[index])
				select index).ToArray();
			CardInfo[] playerCurses = Cards.instance.RemoveCardsFromPlayer(player, curseIndeces);
			callback?.Invoke(playerCurses);
			yield return WaitFor.Frames(20);
		}

		private IEnumerator IKeepCurse(Player player)
		{
			yield break;
		}

		private bool CondRemoveRound(Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			if (GameModeManager.CurrentHandler.GetTeamScore(player.teamID).rounds > 0 && GetAllCursesOnPlayer(player).Count() > 1)
			{
				result = true;
			}
			return result;
		}

		private IEnumerator IRemoveRound(Player player)
		{
			TeamScore score = GameModeManager.CurrentHandler.GetTeamScore(player.teamID);
			GameModeManager.CurrentHandler.SetTeamScore(player.teamID, new TeamScore(score.points, score.rounds - 1));
			RoundCounter roundCounter = GameObject.Find("/Game/UI/UI_Game/Canvas/RoundCounter").GetComponent<RoundCounter>();
			ExtensionMethods.InvokeMethod((object)roundCounter, "ReDraw", Array.Empty<object>());
			List<int> curseIndices = (from index in Enumerable.Range(0, player.data.currentCards.Count())
				where player.data.currentCards[index].categories.Contains(curseCategory)
				select index).ToList();
			List<int> indicesToRemove = new List<int>();
			for (int i = 0; i < curseIndices.Count(); i++)
			{
				if (Random.Range(0f, 1f) <= 2f / (float)(curseIndices.Count() - i - indicesToRemove.Count()))
				{
					indicesToRemove.Add(curseIndices[i]);
				}
				if (indicesToRemove.Count >= 2)
				{
					break;
				}
			}
			Cards.instance.RemoveCardsFromPlayer(player, indicesToRemove.ToArray());
			yield return (object)new WaitForSecondsRealtime(1f);
		}

		private bool CondGiveExtraPick(Player player)
		{
			bool result = true;
			if (player.data.currentCards.Count() <= PlayerManager.instance.players.Select((Player person) => person.data.currentCards.Count()).ToArray().Min())
			{
				result = false;
			}
			if (GetAllCursesOnPlayer(player).Count() < 2)
			{
				result = false;
			}
			return result;
		}

		private IEnumerator IGiveExtraPick(Player player)
		{
			IEnumerable<Player> enemies = PlayerManager.instance.players.Where((Player person) => person.teamID != player.teamID);
			Dictionary<Player, int> pickers = enemies.ToDictionary((Player person) => person, (Player person) => 1);
			yield return WillsWackyManagers.ExtraPicks(pickers);
			yield return (object)new WaitForSecondsRealtime(1f);
			List<int> curseIndices = (from index in Enumerable.Range(0, player.data.currentCards.Count())
				where player.data.currentCards[index].categories.Contains(curseCategory)
				select index).ToList();
			List<int> indicesToRemove = new List<int>();
			for (int i = 0; i < curseIndices.Count(); i++)
			{
				if (Random.Range(0f, 1f) <= 2f / (float)(curseIndices.Count() - i - indicesToRemove.Count()))
				{
					indicesToRemove.Add(curseIndices[i]);
				}
				if (indicesToRemove.Count >= 2)
				{
					break;
				}
			}
			Cards.instance.RemoveCardsFromPlayer(player, indicesToRemove.ToArray());
			yield return (object)new WaitForSecondsRealtime(1f);
		}

		private bool CondRemoveAllCards(Player player)
		{
			bool result = true;
			if (instance.GetAllCursesOnPlayer(player).Count() <= 4)
			{
				result = false;
			}
			return result;
		}

		private IEnumerator IRemoveAllCards(Player player)
		{
			Cards.instance.RemoveAllCardsFromPlayer(player, true);
			yield break;
		}

		private IEnumerator IStopAsking(Player player)
		{
			doNotAskPlayers.Add(player);
			yield break;
		}

		public void RegisterRemovalOption(string optionName, Func<Player, bool> optionCondition, Func<Player, IEnumerator> optionAction)
		{
			RegisterRemovalOption(new CurseRemovalOption(optionName, optionCondition, optionAction));
		}

		public void RegisterRemovalOption(CurseRemovalOption option)
		{
			if (removalOptions.Select((CurseRemovalOption item) => item.name).Contains(option.name))
			{
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] A curse removal option called '" + option.name + "' already exists.");
			}
			else
			{
				removalOptions.Add(option);
			}
		}

		private IEnumerator GiveCurseRemovalOptions(Player player)
		{
			WillsWackyManagers.instance.DebugLog($"[WWM][Curse Removal] Presenting Curse Removal options for player {player.playerID}.");
			List<CurseRemovalOption> validOptions = removalOptions.Where((CurseRemovalOption option) => option.condition(player)).ToList();
			foreach (CurseRemovalOption option2 in validOptions)
			{
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] '{option2.name}' is a valid curse removal option for player {player.playerID}.");
			}
			List<string> choices = new List<string> { keepCurse.name }.Concat((from option in validOptions
				where option.name != keepCurse.name
				select option.name).ToList()).ToList();
			playerDeciding = true;
			decidingPlayer = player;
			choseAction = false;
			if (player.data.view.IsMine || PhotonNetwork.OfflineMode)
			{
				try
				{
					PopUpMenu.instance.Open(choices, OnRemovalOptionChosen);
				}
				catch (NullReferenceException)
				{
					WillsWackyManagers.instance.DebugLog("[WWM][Debugging] Popup menu doesn't exist.");
					choseAction = true;
					playerDeciding = false;
				}
			}
			else
			{
				string playerName = PhotonNetwork.CurrentRoom.GetPlayer(player.data.view.OwnerActorNr).NickName;
				UIHandler.instance.ShowJoinGameText("WAITING FOR " + playerName, PlayerSkinBank.GetPlayerSkinColors(player.teamID).winText);
			}
			yield return (object)new WaitUntil((Func<bool>)(() => !playerDeciding));
			UIHandler.instance.HideJoinGameText();
		}

		private IEnumerator TimeOut(Player player)
		{
			yield return (object)new WaitForSecondsRealtime(60f);
			if ((Object)(object)decidingPlayer == (Object)(object)player && playerDeciding)
			{
				if (choseAction)
				{
					playerDeciding = false;
					yield break;
				}
				ExtensionMethods.InvokeMethod((object)PopUpMenu.instance, "Choose", Array.Empty<object>());
				yield return (object)new WaitForSecondsRealtime(30f);
			}
		}

		private void OnRemovalOptionChosen(string choice)
		{
			if (!PhotonNetwork.OfflineMode)
			{
				NetworkingManager.RPC(typeof(CurseManager), "RPCA_ExecuteChosenOption", new object[1] { choice });
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(IExecuteChosenOption(choice));
			}
		}

		[UnboundRPC]
		private static void RPCA_ExecuteChosenOption(string choice)
		{
			instance.ExecuteChosenOption(choice);
		}

		private void ExecuteChosenOption(string choice)
		{
			((MonoBehaviour)this).StartCoroutine(IExecuteChosenOption(choice));
		}

		private IEnumerator IExecuteChosenOption(string choice)
		{
			UIHandler.instance.HideJoinGameText();
			WillsWackyManagers.instance.DebugLog($"[WWM][Curse Removal] Player {decidingPlayer.playerID} picked the \"{choice}\" curse removal option. Now executing.");
			choseAction = true;
			Func<Player, IEnumerator> chosenAction = removalOptions.Where((CurseRemovalOption option) => option.name == choice).FirstOrDefault().action;
			yield return chosenAction(decidingPlayer);
			if (!PhotonNetwork.OfflineMode)
			{
				NetworkingManager.RPC(typeof(CurseManager), "RPCA_ExecutionOver", new object[1] { decidingPlayer.playerID });
			}
			else
			{
				playerDeciding = false;
			}
		}

		[UnboundRPC]
		private static void RPCA_ExecutionOver(int playerID)
		{
			if ((Object)(object)instance.decidingPlayer == (Object)(object)PlayerManager.instance.players.Where((Player player) => player.playerID == playerID).First())
			{
				instance.playerDeciding = false;
			}
		}

		private IEnumerator OnPickStart(IGameModeHandler gm)
		{
			if (!WillsWackyManagers.enableCurseRemoval || !SettingCoordinator.instance.Synced)
			{
				yield break;
			}
			WillsWackyManagers.instance.DebugLog("[WWM][Curse Removal] Curse Removal Options are enabled.");
			foreach (Player player2 in PlayerManager.instance.players)
			{
				int currentCurses = GetAllCursesOnPlayer(player2).Count();
				bool presentRemovalOption = false;
				if (curseCount.TryGetValue(player2, out var curses))
				{
					if (GetAllCursesOnPlayer(player2).Count() > curses)
					{
						presentRemovalOption = true;
					}
				}
				else if (currentCurses > 0)
				{
					presentRemovalOption = true;
				}
				if (currentCurses > 0)
				{
					presentRemovalOption = true;
				}
				if (doNotAskPlayers.Contains(player2))
				{
					presentRemovalOption = false;
				}
				if (presentRemovalOption)
				{
					yield return GiveCurseRemovalOptions(player2);
				}
			}
			yield return (object)new WaitForSecondsRealtime(1f);
			curseCount.Clear();
			curseCount = PlayerManager.instance.players.ToDictionary((Player player) => player, (Player player) => GetAllCursesOnPlayer(player).Count());
		}

		private IEnumerator GameStart(IGameModeHandler gm)
		{
			try
			{
				curseCount.Clear();
			}
			catch (NullReferenceException)
			{
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] Clearing curse count caused an error");
			}
			try
			{
				curseCount = PlayerManager.instance.players.ToDictionary((Player player) => player, (Player player) => 0);
			}
			catch (NullReferenceException)
			{
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] Building a dictionary caused an error.");
			}
			canDrawCurses = new Dictionary<Player, bool>();
			yield break;
		}
	}
	public class RerollManager : MonoBehaviour
	{
		private class Rarity
		{
			public Rarity rarity;

			public bool isNull = false;

			public bool isCurse = false;

			public override int GetHashCode()
			{
				int hashCode = ((object)(Rarity)(ref rarity)).GetHashCode();
				int hashCode2 = isNull.GetHashCode();
				int hashCode3 = isCurse.GetHashCode();
				string text = hashCode.ToString() + hashCode3 + hashCode2;
				return text.GetHashCode();
			}

			public override bool Equals(object obj)
			{
				return Equals(obj as Rarity);
			}

			public bool Equals(Rarity rarity)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				if ((object)rarity == null)
				{
					return false;
				}
				if ((object)this == rarity)
				{
					return true;
				}
				if (GetType() != rarity.GetType())
				{
					return false;
				}
				return this.rarity == rarity.rarity && isCurse == rarity.isCurse && isNull == rarity.isNull;
			}

			public static bool operator ==(Rarity r1, Rarity r2)
			{
				if ((object)r1 == null)
				{
					if ((object)r2 == null)
					{
						return true;
					}
					return false;
				}
				return r1.Equals(r2);
			}

			public static bool operator !=(Rarity r1, Rarity r2)
			{
				return !(r1 == r2);
			}

			public override string ToString()
			{
				return ((object)(Rarity)(ref rarity)).ToString() + (isCurse ? " curse" : "") + (isNull ? " null" : "");
			}
		}

		private static class WaitFor
		{
			public static IEnumerator Frames(int frameCount)
			{
				if (frameCount <= 0)
				{
					throw new ArgumentOutOfRangeException("frameCount", "Cannot wait for less that 1 frame");
				}
				while (frameCount > 0)
				{
					frameCount--;
					yield return null;
				}
			}
		}

		public Player flippingPlayer;

		public bool tableFlipped;

		public CardInfo tableFlipCard;

		public List<Player> rerollPlayers = new List<Player>();

		public bool reroll = false;

		public CardInfo rerollCard;

		private Random random = new Random();

		public List<Player> MixUpPlayers = new List<Player>();

		private List<Player> flippedPlayers = new List<Player>();

		private List<Action<Player, CardInfo[]>> playerRerolledActions = new List<Action<Player, CardInfo[]>>();

		public List<CardInfo> cardsSkippedForRerolls = new List<CardInfo>();

		public static RerollManager instance { get; private set; }

		public CardCategory NoFlip { get; private set; } = CustomCardCategories.instance.CardCategory("NoFlip");


		public CardCategory rerollCards { get; private set; } = CustomCardCategories.instance.CardCategory("rerollCards");


		private bool CanDrawFlipCards(Player player, CardInfo card)
		{
			if (!card.categories.Contains(NoFlip))
			{
				return true;
			}
			if (!WillsWackyManagers.enableTableFlip)
			{
				return false;
			}
			return true;
		}

		private void Start()
		{
			Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)CanDrawFlipCards);
		}

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			else if ((Object)(object)instance != (Object)(object)this)
			{
				Object.DestroyImmediate((Object)(object)this);
			}
		}

		[Obsolete("This function is obsolete.", false)]
		internal IEnumerator IMixUpCards(Player player)
		{
			Player[] nonAIPlayers = PlayerManager.instance.players.Where((Player person) => !CharacterDataExtension.GetAdditionalData(person.data).isAIMinion).ToArray();
			Dictionary<Player, CardInfo[]> originalBoard = nonAIPlayers.ToDictionary((Player person) => person, (Player person) => person.data.currentCards.ToArray());
			Dictionary<Player, List<CardInfo>> newBoard = originalBoard.ToDictionary((KeyValuePair<Player, CardInfo[]> kvp) => kvp.Key, (KeyValuePair<Player, CardInfo[]> kvp) => kvp.Value.ToList());
			int i;
			for (i = 0; i < originalBoard[player].Count() - 1; i++)
			{
				yield return WaitFor.Frames(20);
				if (originalBoard[player][i].categories.Contains(NoFlip))
				{
					continue;
				}
				Dictionary<Player, CardInfo> currentOptions = (from kvp in originalBoard.Where((KeyValuePair<Player, CardInfo[]> kvp) => kvp.Value.Length > i).ToDictionary((KeyValuePair<Player, CardInfo[]> kvp) => kvp.Key, (KeyValuePair<Player, CardInfo[]> kvp) => kvp.Value[i])
					where !kvp.Value.categories.Contains(NoFlip) && (Cards.instance.PlayerIsAllowedCard(player, kvp.Value) || (Object)(object)kvp.Key == (Object)(object)player) && (Cards.instance.PlayerIsAllowedCard(kvp.Key, originalBoard[player][i]) || (Object)(object)kvp.Key == (Object)(object)player)
					select kvp).ToDictionary((KeyValuePair<Player, CardInfo> kvp) => kvp.Key, (KeyValuePair<Player, CardInfo> kvp) => kvp.Value);
				if (currentOptions.Count() > 0)
				{
					_ = currentOptions.Keys.ToArray()[Random.Range(0, currentOptions.Keys.ToArray().Count())];
					Player val;
					Player randomSelection = (val = player);
					if (!Object.op_Implicit((Object)(object)val))
					{
						CardInfo replaced = originalBoard[player][i];
						CardInfo replacement = currentOptions[randomSelection];
						newBoard[player][i] = replacement;
						newBoard[randomSelection][i] = replaced;
						Cards.instance.ReplaceCard(player, i, replacement, "", 2f, 2f, true);
						Cards.instance.ReplaceCard(randomSelection, i, replaced, "", 2f, 2f, true);
						Debug.Log((object)string.Format("[{0}][Mix Up][Debugging] Swapped player {1}'s {2} with player {3}'s {4}.", "WWM", player.playerID, replaced.cardName, randomSelection.playerID, replacement.cardName));
					}
				}
			}
		}

		public IEnumerator IFlipTableNew(bool addCard = true)
		{
			List<Player> rerollers = PlayerManager.instance.players.ToList();
			new List<Player>();
			ExtensionMethods.Shuffle<Player>((IList<Player>)rerollers);
			int routinesRunning = 0;
			for (int i = 0; i < rerollers.Count(); i++)
			{
				routinesRunning++;
				((MonoBehaviour)this).StartCoroutine(tableFlipRoutine(rerollers[i], addcard: false, (Object)(object)rerollers[i] != (Object)(object)flippingPlayer));
			}
			float startTime = Time.time;
			yield return (object)new WaitUntil((Func<bool>)(() => routinesRunning <= 0 || Time.time > startTime + 30f));
			if (Object.op_Implicit((Object)(object)flippingPlayer) && Object.op_Implicit((Object)(object)tableFlipCard) && addCard)
			{
				Cards.instance.AddCardToPlayer(flippingPlayer, tableFlipCard, true, "", 2f, 2f, true);
			}
			flippingPlayer = null;
			tableFlipped = false;
			Hashtable customProperties2 = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties2[(object)"Table Flip Sync Stats"] = true;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties2, (Hashtable)null, (WebFlags)null);
			bool inSync = false;
			while (!inSync && !PhotonNetwork.OfflineMode)
			{
				inSync = true;
				foreach (Player player in PhotonNetwork.CurrentRoom.Players.Values)
				{
					if (((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"Table Flip Sync Stats", out object status))
					{
						if (!(bool)status)
						{
							inSync = false;
						}
					}
					else
					{
						inSync = false;
					}
					status = null;
				}
				yield return null;
			}
			yield return WaitFor.Frames(10);
			customProperties2 = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties2[(object)"Table Flip Sync Stats"] = false;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties2, (Hashtable)null, (WebFlags)null);
			yield return WaitFor.Frames(10);
			yield return null;
			IEnumerator tableFlipRoutine(Player person, bool addcard, bool removeCard)
			{
				yield return Reroll(person, addcard, removeCard);
				routinesRunning--;
			}
		}

		[Obsolete("This function is obsolete.", true)]
		public IEnumerator IFlipTable(bool addCard = true)
		{
			Dictionary<Player, List<Rarity>> cardRarities = new Dictionary<Player, List<Rarity>>();
			Dictionary<Player, List<CardInfo>> playerCards = new Dictionary<Player, List<CardInfo>>();
			foreach (Player player3 in PlayerManager.instance.players)
			{
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Getting card rarities for player {player3.playerID}");
				cardRarities.Add(player3, player3.data.currentCards.Select((CardInfo card) => CardRarity(card)).ToList());
				playerCards.Add(player3, player3.data.currentCards.ToList());
				try
				{
					Cards.instance.RemoveAllCardsFromPlayer(player3, true);
				}
				catch (NullReferenceException)
				{
					WillsWackyManagers.instance.DebugLog("[WWM][Debugging] SOMEBODY NEEDS TO FIX THEIR REMOVECARD FUNCTION.");
					cardRarities[player3].Clear();
				}
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] {cardRarities[player3].Count} card rarities found for player {player3.playerID}");
			}
			if (PhotonNetwork.LocalPlayer.IsMasterClient || PhotonNetwork.OfflineMode)
			{
				if (Object.op_Implicit((Object)(object)flippingPlayer) && ((Object.op_Implicit((Object)(object)flippingPlayer) && playerCards[flippingPlayer].Count != 0) ? 1 : 0) > (false ? 1 : 0))
				{
					cardRarities[flippingPlayer].RemoveAt(cardRarities[flippingPlayer].Count - 1);
					playerCards[flippingPlayer].RemoveAt(playerCards[flippingPlayer].Count - 1);
				}
				yield return WaitFor.Frames(5);
				List<CardInfo> allCards = (from cardData in CardManager.cards.Values.ToArray()
					where cardData.enabled && !cardData.cardInfo.categories.Contains(NoFlip) && !cardData.cardInfo.categories.Contains(CustomCardCategories.instance.CardCategory("AIMinion")) && !(cardData.cardInfo.cardName.ToLower() == "shuffle")
					select cardData into card
					select card.cardInfo).ToList();
				allCards.Remove(tableFlipCard);
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] {allCards.Count()} cards are enabled and ready to be swapped out.");
				yield return WaitFor.Frames(20);
				for (int i = 0; i < Mathf.Max(cardRarities.Values.Select((List<Rarity> cards) => cards.Count()).ToArray()); i++)
				{
					WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Initiating round {i + 1} of readding cards to players.");
					foreach (Player player2 in PlayerManager.instance.players)
					{
						bool couldDraw = CurseManager.instance.CanPlayerDrawCurses(player2);
						CurseManager.instance.PlayerCanDrawCurses(player2);
						WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Checking player {player2.playerID} to see if they are able to have a card added.");
						if (i < cardRarities[player2].Count)
						{
							WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player2.playerID} is able to have a card added.");
							Rarity rarity = cardRarities[player2][i];
							WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player2.playerID}'s card was originally {rarity.ToString()}, finding a replacement now.");
							CardInfo[] cardChoices = allCards.Where((CardInfo cardInfo) => CardRarity(cardInfo) == rarity && Cards.instance.PlayerIsAllowedCard(player2, cardInfo)).ToArray();
							WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player2.playerID} is eligible for {cardChoices.Count()} cards");
							if (cardChoices.Count() > 0)
							{
								CardInfo card2 = RandomCard(cardChoices);
								WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player2.playerID} is being given {card2.cardName}");
								Cards.instance.AddCardToPlayer(player2, card2, false, "", 2f, 2f, true);
							}
						}
						CurseManager.instance.PlayerCanDrawCurses(player2, couldDraw);
						yield return WaitFor.Frames(30);
					}
					yield return WaitFor.Frames(30);
				}
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] Finished adding cards to players.");
				if (Object.op_Implicit((Object)(object)flippingPlayer) && Object.op_Implicit((Object)(object)tableFlipCard) && addCard)
				{
					Cards.instance.AddCardToPlayer(flippingPlayer, tableFlipCard, true, "", 2f, 2f, true);
				}
				yield return WaitFor.Frames(20);
			}
			flippingPlayer = null;
			tableFlipped = false;
			Hashtable customProperties = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties[(object)"Table Flip Sync Stats"] = true;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
			bool inSync = false;
			while (!inSync && !PhotonNetwork.OfflineMode)
			{
				inSync = true;
				foreach (Player player in PhotonNetwork.CurrentRoom.Players.Values)
				{
					if (((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"Table Flip Sync Stats", out object status))
					{
						if (!(bool)status)
						{
							inSync = false;
						}
					}
					else
					{
						inSync = false;
					}
					status = null;
				}
				yield return null;
			}
			yield return WaitFor.Frames(20);
			yield return null;
		}

		public IEnumerator InitiateRerolls(bool addCard = true)
		{
			yield return WaitFor.Frames(40);
			Player[] rerollers = rerollPlayers.Distinct().ToArray();
			new List<Player>();
			int routinesRunning = 0;
			for (int i = 0; i < rerollers.Count(); i++)
			{
				routinesRunning++;
				((MonoBehaviour)this).StartCoroutine(rerollRoutine(rerollers[i]));
			}
			float startTime = Time.time;
			yield return (object)new WaitUntil((Func<bool>)(() => routinesRunning <= 0 || Time.time > startTime + 30f));
			rerollPlayers = new List<Player>();
			reroll = false;
			Hashtable customProperties2 = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties2[(object)"Reroll Sync Stats"] = true;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties2, (Hashtable)null, (WebFlags)null);
			bool inSync = false;
			while (!inSync && !PhotonNetwork.OfflineMode)
			{
				inSync = true;
				foreach (Player player in PhotonNetwork.CurrentRoom.Players.Values)
				{
					if (((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"Reroll Sync Stats", out object status))
					{
						if (!(bool)status)
						{
							inSync = false;
						}
					}
					else
					{
						inSync = false;
					}
					status = null;
				}
				yield return null;
			}
			yield return WaitFor.Frames(10);
			customProperties2 = PhotonNetwork.LocalPlayer.CustomProperties;
			customProperties2[(object)"Reroll Sync Stats"] = false;
			PhotonNetwork.LocalPlayer.SetCustomProperties(customProperties2, (Hashtable)null, (WebFlags)null);
			yield return WaitFor.Frames(10);
			yield return null;
			IEnumerator rerollRoutine(Player person)
			{
				yield return Reroll(person);
				routinesRunning--;
			}
		}

		public void RegisterRerollAction(Action<Player, CardInfo[]> rerollAction)
		{
			playerRerolledActions.Add(rerollAction);
		}

		public IEnumerator Reroll(Player player, bool addCard = true, bool noRemove = false, CardInfo cardToGive = null)
		{
			if (Object.op_Implicit((Object)(object)player) && ((Object.op_Implicit((Object)(object)player) && player.data.currentCards.Count != 0) ? 1 : 0) > (false ? 1 : 0))
			{
				new List<CardInfo>();
				new List<Rarity>();
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Getting card rarities for player {player.playerID}");
				List<Rarity> cardRarities = (from c in player.data.currentCards
					where !cardsSkippedForRerolls.Contains(c)
					select c into card
					select CardRarity(card)).ToList();
				List<CardInfo> originalCards = player.data.currentCards.ToList();
				if (cardRarities.Count > 0 && !noRemove)
				{
					cardRarities = (from card in originalCards
						where !((Object)(object)card == (Object)(object)rerollCard) && !((Object)(object)card == (Object)(object)tableFlipCard) && !cardsSkippedForRerolls.Contains(card)
						select CardRarity(card)).ToList();
				}
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] {cardRarities.Count} card rarities found for player {player.playerID}");
				try
				{
					Cards.instance.RemoveAllCardsFromPlayer(player, true);
				}
				catch (NullReferenceException)
				{
					WillsWackyManagers.instance.DebugLog("[WWM][Debugging] SOMEBODY NEEDS TO FIX THEIR REMOVECARD FUNCTION.");
					cardRarities.Clear();
				}
				List<CardInfo> allCards = (from cardData in CardManager.cards.Values.ToArray()
					where cardData.enabled && !cardData.cardInfo.categories.Contains(NoFlip) && !cardData.cardInfo.categories.Contains(CustomCardCategories.instance.CardCategory("AIMinion")) && !(cardData.cardInfo.cardName.ToLower() == "shuffle")
					select cardData into card
					select card.cardInfo).ToList();
				List<CardInfo> hiddenCards = new List<CardInfo>();
				try
				{
					hiddenCards = (List<CardInfo>)ExtensionMethods.GetFieldValue((object)Cards.instance, "hiddenCards");
				}
				catch (Exception e2)
				{
					Debug.Log((object)"Error fetching hidden cards from modding utils.");
					Debug.LogException(e2);
				}
				List<CardInfo> nulls = hiddenCards.Where((CardInfo cardData) => cardData.categories.Contains(CustomCardCategories.instance.CardCategory("nullCard"))).ToList();
				if (nulls.Count() > 0)
				{
					allCards.AddRange(nulls);
				}
				WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] {allCards.Count()} cards are enabled and ready to be swapped out.");
				yield return WaitFor.Frames(20);
				for (int i = 0; i < cardRarities.Count(); i++)
				{
					try
					{
						Rarity rarity = cardRarities[i];
						_ = originalCards[i];
						bool couldDraw = CurseManager.instance.CanPlayerDrawCurses(player);
						CurseManager.instance.PlayerCanDrawCurses(player);
						WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Checking player {player.playerID} to see if they are able to have a card added.");
						WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player.playerID} is able to have a card added.");
						WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player.playerID}'s card was originally {rarity.ToString()}, finding a replacement now.");
						CardInfo[] cardChoices = allCards.Where((CardInfo cardInfo) => CardRarity(cardInfo) == rarity && Cards.instance.PlayerIsAllowedCard(player, cardInfo)).ToArray();
						WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player.playerID} is eligible for {cardChoices.Count()} cards");
						if (cardChoices.Count() > 0)
						{
							CardInfo card2 = RandomCard(cardChoices);
							WillsWackyManagers.instance.DebugLog($"[WWM][Debugging] Player {player.playerID} is being given {card2.cardName}");
							Cards.instance.AddCardToPlayer(player, card2, false, "", 2f, 2f, true);
						}
						CurseManager.instance.PlayerCanDrawCurses(player, couldDraw);
					}
					catch (Exception e)
					{
						Debug.LogException(e);
					}
					yield return WaitFor.Frames(40);
				}
				foreach (Action<Player, CardInfo[]> rerollAction in playerRerolledActions)
				{
					try
					{
						rerollAction(player, originalCards.ToArray());
					}
					catch (Exception e3)
					{
						Debug.Log((object)"Exception thrown by reroll action code.");
						Debug.LogException(e3);
					}
				}
				WillsWackyManagers.instance.DebugLog("[WWM][Debugging] Finished adding cards.");
				if (addCard && (Object.op_Implicit((Object)(object)rerollCard) || Object.op_Implicit((Object)(object)cardToGive)))
				{
					try
					{
						Cards.instance.AddCardToPlayer(player, Object.op_Implicit((Object)(object)cardToGive) ? cardToGive : rerollCard, true, "", 2f, 2f, true);
					}
					catch (Exception ex2)
					{
						Exception e4 = ex2;
						Debug.LogException(e4);
					}
				}
				yield return WaitFor.Frames(40);
			}
			yield return null;
		}

		private string RarityName(Rarity rarity)
		{
			return ((object)(Rarity)(ref rarity.rarity)).ToString() + (rarity.isCurse ? " curse" : "") + (rarity.isNull ? " null" : "");
		}

		private Rarity CardRarity(CardInfo cardInfo)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Rarity rarity = new Rarity();
			if (cardInfo.categories.Contains(CustomCardCategories.instance.CardCategory("nullCard")))
			{
				rarity.isNull = true;
			}
			if (cardInfo.categories.Contains(CurseManager.instance.curseCategory))
			{
				rarity.isCurse = true;
			}
			rarity.rarity = cardInfo.rarity;
			return rarity;
		}

		private CardInfo RandomCard(CardInfo[] cards)
		{
			if (cards.Count() <= 0)
			{
				return null;
			}
			return cards[random.Next(cards.Count())];
		}
	}
}
namespace WillsWackyManagers.UnityTools
{
	[Serializable]
	public abstract class CardBuilder : SerializedMonoBehaviour
	{
		public string modInitials = "WWC";

		public abstract void BuildCards();

		public virtual void StandardCallback(CardInfo card)
		{
			if (((Component)card).GetComponent<ISaveableCard>() != null)
			{
				ISaveableCard component = ((Component)card).GetComponent<ISaveableCard>();
				if (component != null)
				{
					component.Card = card;
				}
			}
			if (((Component)card).GetComponent<IConditionalCard>() != null)
			{
				IConditionalCard component2 = ((Component)card).GetComponent<IConditionalCard>();
				if (component2 != null)
				{
					Cards.instance.AddCardValidationFunction((Func<Player, CardInfo, bool>)component2.Condition);
				}
			}
			if (((Component)card).GetComponent<ICurseCard>() != null)
			{
				CurseManager.instance.RegisterCurse(card);
			}
		}
	}
	public interface IConditionalCard : ISaveableCard
	{
		bool Condition(Player player, CardInfo card);
	}
	public interface ICurseCard
	{
	}
	public interface ISaveableCard
	{
		CardInfo Card { get; set; }
	}
	[Serializable]
	public class NormalCardBuilder : CardBuilder
	{
		[ShowInInspector]
		[Searchable]
		public GameObject[] cardsToRegister;

		public override void BuildCards()
		{
			for (int i = 0; i < cardsToRegister.Length; i++)
			{
				CustomCard component = cardsToRegister[i].GetComponent<CustomCard>();
				if (Object.op_Implicit((Object)(object)component))
				{
					try
					{
						component.block = ExtensionMethods.GetOrAddComponent<Block>(((Component)component).gameObject, false);
						if (component.block.objectsToSpawn == null)
						{
							component.block.objectsToSpawn = new List<GameObject>();
						}
						component.gun = ExtensionMethods.GetOrAddComponent<Gun>(((Component)component).gameObject, false);
						if (component.gun.objectsToSpawn == null)
						{
							component.gun.objectsToSpawn = (ObjectsToSpawn[])(object)new ObjectsToSpawn[0];
						}
						if (component.gun.projectiles == null)
						{
							component.gun.projectiles = (ProjectilesToSpawn[])(object)new ProjectilesToSpawn[0];
						}
						component.statModifiers = ExtensionMethods.GetOrAddComponent<CharacterStatModifiers>(((Component)component).gameObject, false);
					}
					catch (Exception ex)
					{
						Debug.LogException(ex);
					}
					try
					{
						component.BuildUnityCard((Action<CardInfo>)StandardCallback);
					}
					catch (Exception ex2)
					{
						Debug.LogException(ex2);
					}
				}
				else
				{
					CardInfo component2 = cardsToRegister[i].GetComponent<CardInfo>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						CustomCard.RegisterUnityCard(cardsToRegister[i], modInitials, component2.cardName, true, (Action<CardInfo>)StandardCallback);
					}
				}
			}
		}
	}
}
namespace WillsWackyManagers.UI
{
	public class PopUpMenu : MonoBehaviour
	{
		public static PopUpMenu instance;

		private Action<string> callback;

		private int currentChoice;

		private List<string> choices;

		private List<CurveAnimation> choiceAnimations;

		private List<GeneralParticleSystem> choiceParticleSystems;

		private bool isOpen = false;

		public void Awake()
		{
			instance = this;
			VerticalLayoutGroup val = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val).childAlignment = (TextAnchor)4;
			ContentSizeFitter val2 = ((Component)this).gameObject.AddComponent<ContentSizeFitter>();
			val2.horizontalFit = (FitMode)2;
			val2.verticalFit = (FitMode)2;
		}

		public void Open(List<string> choices, Action<string> callback)
		{
			this.callback = callback;
			currentChoice = 0;
			this.choices = choices;
			choiceAnimations = new List<CurveAnimation>();
			choiceParticleSystems = new List<GeneralParticleSystem>();
			isOpen = true;
			while (((Component)this).transform.childCount > 0)
			{
				Object.DestroyImmediate((Object)(object)((Component)((Component)this).transform.GetChild(0)).gameObject);
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)this).gameObject.GetComponent<RectTransform>());
			for (int i = 0; i < this.choices.Count; i++)
			{
				int index = i;
				string text = this.choices[index];
				GameObject val = Object.Instantiate<GameObject>(RoundsResources.PopUpMenuText, ((Component)this).transform);
				((Object)val).name = text;
				TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component).text = text;
				((TMP_Text)component).fontSize = 60f;
				val.AddComponent<VerticalLayoutGroup>();
				ContentSizeFitter val2 = val.AddComponent<ContentSizeFitter>();
				LayoutElement val3 = val.AddComponent<LayoutElement>();
				val2.horizontalFit = (FitMode)2;
				val3.preferredHeight = 92f;
				choiceAnimations.Add(val.GetComponent<CurveAnimation>());
				choiceParticleSystems.Add(val.GetComponentInChildren<GeneralParticleSystem>());
			}
			choiceAnimations[0].PlayIn();
		}

		private void Update()
		{
			if (!isOpen)
			{
				return;
			}
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			if (Input.GetKeyDown((KeyCode)273) || Input.GetKeyDown((KeyCode)119))
			{
				flag = true;
			}
			if (Input.GetKeyDown((KeyCode)274) || Input.GetKeyDown((KeyCode)115))
			{
				flag2 = true;
			}
			if (currentChoice != -1 && Input.GetKeyDown((KeyCode)32))
			{
				flag3 = true;
			}
			foreach (InputDevice activeDevice in InputManager.ActiveDevices)
			{
				if (activeDevice.Direction.Up.WasPressed)
				{
					flag = true;
				}
				if (activeDevice.Direction.Down.WasPressed)
				{
					flag2 = true;
				}
				if (currentChoice != -1 && ((OneAxisInputControl)activeDevice.Action1).IsPressed)
				{
					flag3 = true;
				}
			}
			if (flag && currentChoice > 0)
			{
				SetChoice(currentChoice - 1);
			}
			if (flag2 && currentChoice < choices.Count - 1)
			{
				SetChoice(currentChoice + 1);
			}
			if (flag3)
			{
				Choose();
			}
		}

		private void SetChoice(int newChoice)
		{
			if (newChoice != currentChoice)
			{
				if (currentChoice != -1)
				{
					choiceAnimations[currentChoice].PlayOut();
				}
				if (newChoice != -1)
				{
					choiceAnimations[newChoice].PlayIn();
				}
				currentChoice = newChoice;
			}
		}

		private void Choose()
		{
			isOpen = false;
			foreach (GeneralParticleSystem choiceParticleSystem in choiceParticleSystems)
			{
				choiceParticleSystem.loop = false;
			}
			callback(choices[currentChoice]);
		}
	}
}
namespace WillsWackyManagers.Patches
{
	[HarmonyPatch(typeof(Car