Decompiled source of HousePersistentDeck v1.1.0

HousePersistentDeck.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HousePersistentDeck")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fa6bc2bd0384d671c71712b67fafdeea462fc7c9")]
[assembly: AssemblyProduct("HousePersistentDeck")]
[assembly: AssemblyTitle("HousePersistentDeck")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HousePersistentDeck
{
	internal sealed class CardFeedUI : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <AnimateNewest>d__32 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CardFeedUI <>4__this;

			private int <slotIdx>5__2;

			private Color <orig>5__3;

			private Color <flash>5__4;

			private float <t>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AnimateNewest>d__32(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: 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_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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				CardFeedUI cardFeedUI = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<slotIdx>5__2 = Mathf.Min(cardFeedUI._history.Count - 1, 5);
					if (<slotIdx>5__2 < 0)
					{
						return false;
					}
					<orig>5__3 = ((Graphic)cardFeedUI._slotBg[<slotIdx>5__2]).color;
					<flash>5__4 = Color.Lerp(<orig>5__3, Color.white, 0.45f);
					<t>5__5 = 0f;
					goto IL_00e5;
				case 1:
					<>1__state = -1;
					goto IL_00e5;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_00e5:
					if (<t>5__5 < 0.12f)
					{
						((Graphic)cardFeedUI._slotBg[<slotIdx>5__2]).color = Color.Lerp(<orig>5__3, <flash>5__4, <t>5__5 / 0.12f);
						<t>5__5 += Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<t>5__5 = 0f;
					break;
				}
				if (<t>5__5 < 0.18f)
				{
					((Graphic)cardFeedUI._slotBg[<slotIdx>5__2]).color = Color.Lerp(<flash>5__4, <orig>5__3, <t>5__5 / 0.18f);
					<t>5__5 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				((Graphic)cardFeedUI._slotBg[<slotIdx>5__2]).color = <orig>5__3;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static bool Enabled = true;

		public static string Position = "bottom-left";

		public static float Opacity = 0.82f;

		public static float Scale = 1f;

		public static readonly Dictionary<int, Sprite> CardSprites = new Dictionary<int, Sprite>();

		public static readonly Dictionary<int, (string shortName, Color color)> CardColors = new Dictionary<int, (string, Color)>();

		private const int FeedSize = 6;

		private const float SlotW = 54f;

		private const float SlotH = 72f;

		private const float SlotGap = 5f;

		private const float PanelPad = 8f;

		private readonly List<(int id, string name)> _history = new List<(int, string)>(6);

		private Canvas? _canvas;

		private RectTransform? _panelRect;

		private readonly Image[] _slotBg = (Image[])(object)new Image[6];

		private readonly Image[] _slotIcon = (Image[])(object)new Image[6];

		private readonly Text[] _slotText = (Text[])(object)new Text[6];

		private readonly CanvasGroup[] _slotGroup = (CanvasGroup[])(object)new CanvasGroup[6];

		public static CardFeedUI? Instance { get; private set; }

		public static void AddCard(int cardId, string displayName)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance.PushCard(cardId, displayName);
			}
		}

		public static void ClearFeed()
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance._history.Clear();
				Instance.RefreshSlots();
			}
		}

		public static void SetVisible(bool visible)
		{
			if (!((Object)(object)Instance == (Object)null) && (Object)(object)Instance._panelRect != (Object)null)
			{
				((Component)Instance._panelRect).gameObject.SetActive(visible);
			}
		}

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			BuildCanvas();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void BuildCanvas()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 55;
			_canvas.pixelPerfect = true;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.screenMatchMode = (ScreenMatchMode)0;
			obj.matchWidthOrHeight = 0.5f;
			((Component)this).gameObject.AddComponent<GraphicRaycaster>();
			GameObject val = new GameObject("CardFeedPanel");
			val.transform.SetParent(((Component)this).transform, false);
			_panelRect = val.AddComponent<RectTransform>();
			ApplyAnchorPosition(_panelRect);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.04f, 0.06f, 0.1f, 0.88f);
			CanvasGroup obj2 = val.AddComponent<CanvasGroup>();
			obj2.alpha = Opacity;
			obj2.interactable = false;
			obj2.blocksRaycasts = false;
			float num = 365f;
			float num2 = 88f;
			_panelRect.sizeDelta = new Vector2(num, num2);
			GameObject val2 = new GameObject("Accent");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj3 = val2.AddComponent<RectTransform>();
			obj3.anchorMin = new Vector2(0f, 1f);
			obj3.anchorMax = new Vector2(1f, 1f);
			obj3.pivot = new Vector2(0.5f, 1f);
			obj3.offsetMin = Vector2.zero;
			obj3.offsetMax = Vector2.zero;
			obj3.sizeDelta = new Vector2(0f, 2f);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.39f, 0.71f, 0.85f, 0.7f);
			for (int i = 0; i < 6; i++)
			{
				float cx = 8f + (float)i * 59f + 27f;
				BuildSlot(val.transform, i, cx, 0f);
			}
			RefreshSlots();
			((Component)_panelRect).gameObject.SetActive(false);
		}

		private void BuildSlot(Transform parent, int index, float cx, float cy)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0034: 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_005e: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"Slot{index}");
			val.transform.SetParent(parent, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0f, 0.5f);
			obj.anchorMax = new Vector2(0f, 0.5f);
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.anchoredPosition = new Vector2(cx, cy);
			obj.sizeDelta = new Vector2(54f, 72f);
			CanvasGroup val2 = val.AddComponent<CanvasGroup>();
			val2.alpha = 0f;
			_slotGroup[index] = val2;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.15f, 0.18f, 0.22f, 1f);
			_slotBg[index] = val3;
			GameObject val4 = new GameObject("Icon");
			val4.transform.SetParent(val.transform, false);
			RectTransform obj2 = val4.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(2f, 2f);
			obj2.offsetMax = new Vector2(-2f, -2f);
			Image val5 = val4.AddComponent<Image>();
			val5.preserveAspect = true;
			((Behaviour)val5).enabled = false;
			_slotIcon[index] = val5;
			GameObject val6 = new GameObject("Text");
			val6.transform.SetParent(val.transform, false);
			RectTransform obj3 = val6.AddComponent<RectTransform>();
			obj3.anchorMin = Vector2.zero;
			obj3.anchorMax = Vector2.one;
			obj3.offsetMin = new Vector2(3f, 4f);
			obj3.offsetMax = new Vector2(-3f, -4f);
			Text val7 = val6.AddComponent<Text>();
			val7.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			val7.fontSize = 9;
			val7.fontStyle = (FontStyle)1;
			val7.alignment = (TextAnchor)4;
			((Graphic)val7).color = Color.white;
			val7.horizontalOverflow = (HorizontalWrapMode)0;
			val7.verticalOverflow = (VerticalWrapMode)1;
			val7.lineSpacing = 1.1f;
			_slotText[index] = val7;
			GameObject val8 = new GameObject("Border");
			val8.transform.SetParent(val.transform, false);
			RectTransform obj4 = val8.AddComponent<RectTransform>();
			obj4.anchorMin = Vector2.zero;
			obj4.anchorMax = Vector2.one;
			obj4.offsetMin = Vector2.zero;
			obj4.offsetMax = Vector2.zero;
			Image obj5 = val8.AddComponent<Image>();
			((Graphic)obj5).color = new Color(1f, 1f, 1f, 0.18f);
			obj5.fillCenter = false;
		}

		private void ApplyAnchorPosition(RectTransform rt)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			float num = 365f;
			float num2 = 88f;
			Vector2 val = default(Vector2);
			switch (Position)
			{
			case "top-right":
				((Vector2)(ref val))..ctor(1f, 1f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(1f, 1f);
				rt.anchoredPosition = new Vector2(-12f, -12f);
				break;
			case "top-left":
				((Vector2)(ref val))..ctor(0f, 1f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0f, 1f);
				rt.anchoredPosition = new Vector2(12f, -12f);
				break;
			case "bottom-right":
				((Vector2)(ref val))..ctor(1f, 0f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(1f, 0f);
				rt.anchoredPosition = new Vector2(-12f, 12f);
				break;
			case "bottom-center":
				((Vector2)(ref val))..ctor(0.5f, 0f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0.5f, 0f);
				rt.anchoredPosition = new Vector2(0f, 2f);
				break;
			default:
				((Vector2)(ref val))..ctor(0f, 0f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0f, 0f);
				rt.anchoredPosition = new Vector2(12f, 12f);
				break;
			}
			rt.sizeDelta = new Vector2(num, num2);
		}

		private void PushCard(int cardId, string displayName)
		{
			_history.Add((cardId, displayName));
			if (_history.Count > 6)
			{
				_history.RemoveAt(0);
			}
			RefreshSlots();
			((MonoBehaviour)this).StartCoroutine(AnimateNewest());
		}

		private void RefreshSlots()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 6; i++)
			{
				int num = _history.Count - (6 - i);
				if (num < 0)
				{
					_slotGroup[i].alpha = 0f;
					continue;
				}
				(int id, string name) tuple = _history[num];
				int item = tuple.id;
				string item2 = tuple.name;
				int num2 = 5 - i;
				((Graphic)_slotBg[i]).color = GetSlotColor(item);
				if (CardSprites.TryGetValue(item, out Sprite value) && (Object)(object)value != (Object)null)
				{
					_slotIcon[i].sprite = value;
					((Behaviour)_slotIcon[i]).enabled = true;
					((Behaviour)_slotText[i]).enabled = false;
				}
				else
				{
					((Behaviour)_slotIcon[i]).enabled = false;
					_slotText[i].text = FormatName(item2);
					((Behaviour)_slotText[i]).enabled = true;
				}
				_slotGroup[i].alpha = Mathf.Lerp(1f, 0.38f, (float)num2 / 5f);
			}
		}

		[IteratorStateMachine(typeof(<AnimateNewest>d__32))]
		private IEnumerator AnimateNewest()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AnimateNewest>d__32(0)
			{
				<>4__this = this
			};
		}

		private static Color GetSlotColor(int cardId)
		{
			//IL_003a: 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)
			if (CardColors.TryGetValue(cardId, out (string, Color) value))
			{
				return value.Item2;
			}
			return Color.HSVToRGB(((float)cardId * 0.618034f % 1f + 1f) % 1f, 0.45f, 0.55f);
		}

		private static string FormatName(string rawName)
		{
			if (string.IsNullOrEmpty(rawName) || rawName == "?")
			{
				return "?";
			}
			string text = rawName.Replace("The ", "").Replace(" of ", "\n").Trim();
			string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0)
			{
				return rawName;
			}
			if (array.Length <= 2)
			{
				return text;
			}
			return array[0] + "\n" + array[1];
		}
	}
	internal sealed class DeckDisplayUI : MonoBehaviour
	{
		private const int MaxSlots = 60;

		private const float SlotW = 28f;

		private const float SlotH = 37f;

		private const float SlotGap = 3f;

		private const float ColGap = 4f;

		private const float PanelPad = 6f;

		private const int NumCols = 2;

		private static readonly Color BgHand = new Color(0.28f, 0.22f, 0.06f, 1f);

		private static readonly Color BgNormal = new Color(0.12f, 0.14f, 0.18f, 1f);

		private Canvas? _canvas;

		private RectTransform? _panelRect;

		private CanvasGroup? _panelGroup;

		private bool _refreshPending;

		private readonly RectTransform[] _slotRt = (RectTransform[])(object)new RectTransform[60];

		private readonly Image[] _slotBg = (Image[])(object)new Image[60];

		private readonly Image[] _slotIcon = (Image[])(object)new Image[60];

		public static DeckDisplayUI? Instance { get; private set; }

		public static void RequestRefresh()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Instance._refreshPending = true;
			}
		}

		public static void Refresh(int[] hand, List<int> drawPile, List<int> discard)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance.DoRefresh(hand, drawPile, discard);
			}
		}

		public static void SetVisible(bool v)
		{
			if (!((Object)(object)Instance == (Object)null) && (Object)(object)Instance._panelRect != (Object)null)
			{
				((Component)Instance._panelRect).gameObject.SetActive(v);
			}
		}

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			BuildCanvas();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LateUpdate()
		{
			if (_refreshPending)
			{
				_refreshPending = false;
				DoRefresh(Plugin.GetCurrentHand(), Plugin.GetCurrentDeck(), Plugin.GetCurrentDiscard());
			}
		}

		private void BuildCanvas()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 54;
			_canvas.pixelPerfect = true;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.screenMatchMode = (ScreenMatchMode)0;
			obj.matchWidthOrHeight = 0.5f;
			((Component)this).gameObject.AddComponent<GraphicRaycaster>();
			GameObject val = new GameObject("DeckDisplayPanel");
			val.transform.SetParent(((Component)this).transform, false);
			_panelRect = val.AddComponent<RectTransform>();
			_panelRect.anchorMin = new Vector2(0f, 0.5f);
			_panelRect.anchorMax = new Vector2(0f, 0.5f);
			_panelRect.pivot = new Vector2(0f, 0.5f);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.04f, 0.06f, 0.1f, 0.88f);
			_panelGroup = val.AddComponent<CanvasGroup>();
			_panelGroup.alpha = CardFeedUI.Opacity;
			_panelGroup.interactable = false;
			_panelGroup.blocksRaycasts = false;
			GameObject val2 = new GameObject("Accent");
			val2.transform.SetParent(val.transform, false);
			RectTransform obj2 = val2.AddComponent<RectTransform>();
			obj2.anchorMin = new Vector2(1f, 0f);
			obj2.anchorMax = new Vector2(1f, 1f);
			obj2.pivot = new Vector2(1f, 0.5f);
			obj2.offsetMin = Vector2.zero;
			obj2.offsetMax = Vector2.zero;
			obj2.sizeDelta = new Vector2(2f, 0f);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.39f, 0.71f, 0.85f, 0.5f);
			for (int i = 0; i < 60; i++)
			{
				BuildSlot(val.transform, i);
			}
			((Component)_panelRect).gameObject.SetActive(false);
		}

		private void BuildSlot(Transform parent, int index)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0035: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"DeckSlot{index}");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 0.5f);
			val2.anchorMax = new Vector2(0f, 0.5f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(28f, 37f);
			_slotRt[index] = val2;
			val.SetActive(false);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = BgNormal;
			_slotBg[index] = val3;
			GameObject val4 = new GameObject("Icon");
			val4.transform.SetParent(val.transform, false);
			RectTransform obj = val4.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = new Vector2(2f, 2f);
			obj.offsetMax = new Vector2(-2f, -2f);
			Image val5 = val4.AddComponent<Image>();
			val5.preserveAspect = true;
			((Behaviour)val5).enabled = false;
			_slotIcon[index] = val5;
		}

		private void DoRefresh(int[] hand, List<int> drawPile, List<int> discard)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panelRect == (Object)null)
			{
				return;
			}
			if ((Object)(object)_panelGroup != (Object)null)
			{
				_panelGroup.alpha = CardFeedUI.Opacity;
			}
			List<int> list = new List<int>();
			if (hand != null)
			{
				list.AddRange(hand);
			}
			if (drawPile != null)
			{
				list.AddRange(drawPile);
			}
			if (discard != null)
			{
				list.AddRange(discard);
			}
			list.Sort();
			int num = Math.Min(list.Count, 60);
			for (int i = num; i < 60; i++)
			{
				((Component)_slotRt[i]).gameObject.SetActive(false);
			}
			if (num == 0)
			{
				((Component)_panelRect).gameObject.SetActive(false);
				return;
			}
			int num2 = (num + 2 - 1) / 2;
			float num3 = 72f;
			float num4 = (float)num2 * 40f - 3f + 12f;
			_panelRect.sizeDelta = new Vector2(num3, num4);
			_panelRect.anchoredPosition = new Vector2(2f, 0f);
			List<int> list2 = ((hand != null) ? new List<int>(hand) : new List<int>());
			for (int j = 0; j < num; j++)
			{
				int num5 = list[j];
				int num6 = list2.IndexOf(num5);
				bool flag = num6 >= 0;
				if (flag)
				{
					list2.RemoveAt(num6);
				}
				int num7 = j % 2;
				int num8 = j / 2;
				float num9 = 6f + (float)num7 * 32f + 14f;
				float num10 = num4 * 0.5f - 6f - (float)num8 * 40f - 18.5f;
				_slotRt[j].anchoredPosition = new Vector2(num9, num10);
				((Component)_slotRt[j]).gameObject.SetActive(true);
				if (CardFeedUI.CardSprites.TryGetValue(num5, out Sprite value) && (Object)(object)value != (Object)null)
				{
					_slotIcon[j].sprite = value;
					((Graphic)_slotIcon[j]).color = Color.white;
					((Behaviour)_slotIcon[j]).enabled = true;
					((Graphic)_slotBg[j]).color = (flag ? BgHand : BgNormal);
				}
				else
				{
					((Behaviour)_slotIcon[j]).enabled = false;
					(string, Color) value2;
					Color val = ((!CardFeedUI.CardColors.TryGetValue(num5, out value2)) ? Color.HSVToRGB(((float)num5 * 0.618034f % 1f + 1f) % 1f, 0.45f, 0.55f) : value2.Item2);
					((Graphic)_slotBg[j]).color = (flag ? Color.Lerp(val, new Color(0.6f, 0.45f, 0.1f), 0.5f) : val);
				}
			}
			((Component)_panelRect).gameObject.SetActive(true);
		}
	}
	[BepInPlugin("com.fae.housepersistentdeck", "House Persistent Deck", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class DeckState
		{
			public int[] GameDeck { get; }

			public int[] DiscardPile { get; }

			public int[] HandCards { get; }

			public DeckState(int[] gameDeck, int[] discardPile, int[] handCards)
			{
				GameDeck = gameDeck;
				DiscardPile = discardPile;
				HandCards = handCards;
			}
		}

		public const string PluginGuid = "com.fae.housepersistentdeck";

		public const string PluginName = "House Persistent Deck";

		public const string PluginVersion = "1.1.0";

		private static readonly Dictionary<object, DeckState> SavedDecks = new Dictionary<object, DeckState>();

		private static readonly HashSet<object> InitialisingManagers = new HashSet<object>();

		private static readonly HashSet<object> RestoringManagers = new HashSet<object>();

		private static Type? _managerType;

		private static Type? _hudType;

		private static FieldInfo? _characterBodyField;

		private static FieldInfo? _gameDeckField;

		private static FieldInfo? _discardPileField;

		private static FieldInfo? _handCardsField;

		private static FieldInfo? _initialisedField;

		private static FieldInfo? _isAuthorityField;

		private static FieldInfo? _hudPassiveManagerField;

		private static FieldInfo? _hudInstanceField;

		private static FieldInfo? _hudCardArtsField;

		private static MethodInfo? _hudNewHandMethod;

		private static MethodInfo? _hudUpdateCardDisplayMethod;

		private static int[]? _handSnapshot;

		private static List<int>? _discardSnapshot;

		private static object? _activeManager;

		private static bool _cardPushedViaButton;

		private static int _nextHandDepth;

		private static bool _inNextHand;

		private static bool _debugDumped;

		private static ManualLogSource? _log;

		private static MethodInfo? _directCardPlayMethod;

		private static ConfigEntry<bool>? _feedEnabled;

		private static ConfigEntry<string>? _feedPosition;

		private static ConfigEntry<float>? _feedOpacity;

		private static ConfigEntry<float>? _feedScale;

		private Harmony? _harmony;

		private static Dictionary<string, (string abbr, Color color)>? _knownCardStyles;

		private void Awake()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			_managerType = AccessTools.TypeByName("HouseMod.SkillStates.House.HousePassiveManager");
			_hudType = AccessTools.TypeByName("HouseMod.SkillStates.House.HouseHUDManager");
			if (_managerType == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not find HousePassiveManager. Is TheHouse 2.3.2 loaded?");
				return;
			}
			InitConfig();
			CacheReflection();
			DiscoverCardNames();
			_harmony = new Harmony("com.fae.housepersistentdeck");
			TryPatchDirectCardPlay();
			Patch(_managerType, "Initialise", "InitialisePrefix", "InitialisePostfix");
			Patch(_managerType, "NextHand", "NextHandPrefix", "NextHandPostfix");
			Patch(_managerType, "HandleScepterCard", null, "SavePostfix");
			Patch(_managerType, "OnDestroy", "SavePrefix");
			if (_hudNewHandMethod != null)
			{
				try
				{
					_harmony.Patch((MethodBase)_hudNewHandMethod, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "HudNewHandPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to patch HouseHUDManager.NewHand: " + ex.Message));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"House deck persistence + card feed patches installed.");
		}

		private void InitConfig()
		{
			_feedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("CardFeed", "Enabled", true, "Show the card play history feed on the HUD.");
			_feedPosition = ((BaseUnityPlugin)this).Config.Bind<string>("CardFeed", "Position", "bottom-center", "Feed position. Values: bottom-left | bottom-right | top-left | top-right | bottom-center");
			_feedOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("CardFeed", "Opacity", 0.82f, "Background opacity of the feed panel (0 = transparent, 1 = opaque).");
			_feedScale = ((BaseUnityPlugin)this).Config.Bind<float>("CardFeed", "Scale", 1f, "UI scale multiplier for the card feed.");
			ApplyFeedConfig();
			_feedEnabled.SettingChanged += delegate
			{
				ApplyFeedConfig();
			};
			_feedPosition.SettingChanged += delegate
			{
				ApplyFeedConfig();
			};
			_feedOpacity.SettingChanged += delegate
			{
				ApplyFeedConfig();
			};
			_feedScale.SettingChanged += delegate
			{
				ApplyFeedConfig();
			};
		}

		private static void ApplyFeedConfig()
		{
			CardFeedUI.Enabled = _feedEnabled?.Value ?? true;
			CardFeedUI.Position = _feedPosition?.Value ?? "bottom-center";
			CardFeedUI.Opacity = _feedOpacity?.Value ?? 0.82f;
			CardFeedUI.Scale = _feedScale?.Value ?? 1f;
		}

		private void CacheReflection()
		{
			_characterBodyField = AccessTools.Field(_managerType, "characterBody");
			_gameDeckField = AccessTools.Field(_managerType, "gameDeck");
			_discardPileField = AccessTools.Field(_managerType, "gameDeckDiscardPile");
			_handCardsField = AccessTools.Field(_managerType, "handCards");
			_initialisedField = AccessTools.Field(_managerType, "Initialised");
			_isAuthorityField = AccessTools.Field(_managerType, "isAuthority");
			if (!(_hudType == null))
			{
				_hudPassiveManagerField = AccessTools.Field(_hudType, "passiveManager");
				_hudInstanceField = AccessTools.Field(_hudType, "instance");
				_hudCardArtsField = AccessTools.Field(_hudType, "CardArts");
				_hudNewHandMethod = AccessTools.Method(_hudType, "NewHand", new Type[2]
				{
					typeof(int[]),
					typeof(string)
				}, (Type[])null);
				_hudUpdateCardDisplayMethod = AccessTools.Method(_hudType, "UpdateCardDisplay", (Type[])null, (Type[])null);
			}
		}

		private static void DiscoverCardNames()
		{
			//IL_0024: 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_0076: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			_knownCardStyles = new Dictionary<string, (string, Color)>(StringComparer.OrdinalIgnoreCase)
			{
				["king"] = ("King\n♠Wands", new Color(0.94f, 0.67f, 0.13f)),
				["queen"] = ("Queen\n♣Cups", new Color(0.26f, 0.52f, 0.95f)),
				["knight"] = ("Knight\n♦Swords", new Color(0.63f, 0.75f, 0.8f)),
				["page"] = ("Page\n♦Pents", new Color(0.25f, 0.72f, 0.45f)),
				["jack"] = ("Jack\n♦Diams", new Color(0.25f, 0.82f, 0.91f)),
				["ace"] = ("Ace\n♠Spades", new Color(0.25f, 0.35f, 0.55f)),
				["three"] = ("3 of\nKind", new Color(0.6f, 0.22f, 0.8f)),
				["ante"] = ("Up the\nAnte!", new Color(0.25f, 0.78f, 0.3f)),
				["bust"] = ("Bust", new Color(0.83f, 0.18f, 0.18f)),
				["snake"] = ("Snake\nEyes", new Color(0.83f, 0.4f, 0.14f)),
				["pick"] = ("Pick-Up\n52", new Color(0.25f, 0.65f, 0.9f)),
				["sun"] = ("The Sun", new Color(0.97f, 0.91f, 0.14f)),
				["moon"] = ("The Moon", new Color(0.44f, 0.55f, 0.82f)),
				["star"] = ("The Star", new Color(0.14f, 0.84f, 0.8f)),
				["world"] = ("The World", new Color(0.92f, 0.92f, 0.95f)),
				["judgement"] = ("Judge-\nment", new Color(0.82f, 0.35f, 0.1f)),
				["judgment"] = ("Judge-\nment", new Color(0.82f, 0.35f, 0.1f))
			};
		}

		private static void PopulateCardColorsFromDeck(object manager)
		{
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			if (CardFeedUI.CardColors.Count > 0)
			{
				return;
			}
			List<int> list = ReadList(_gameDeckField, manager);
			if (list == null || _knownCardStyles == null)
			{
				return;
			}
			MethodInfo methodInfo = null;
			if (_hudType != null)
			{
				methodInfo = AccessTools.Method(_hudType, "GetCardName", new Type[1] { typeof(int) }, (Type[])null) ?? AccessTools.Method(_hudType, "GetName", new Type[1] { typeof(int) }, (Type[])null) ?? AccessTools.Method(_hudType, "CardName", new Type[1] { typeof(int) }, (Type[])null);
			}
			if (methodInfo == null && _managerType != null)
			{
				methodInfo = AccessTools.Method(_managerType, "GetCardName", new Type[1] { typeof(int) }, (Type[])null) ?? AccessTools.Method(_managerType, "CardName", new Type[1] { typeof(int) }, (Type[])null);
			}
			foreach (int item in list.Distinct())
			{
				string text = null;
				if (methodInfo != null)
				{
					try
					{
						text = methodInfo.Invoke(null, new object[1] { item }) as string;
					}
					catch
					{
					}
				}
				if (text == null)
				{
					continue;
				}
				foreach (var (value, tuple2) in _knownCardStyles)
				{
					if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						CardFeedUI.CardColors[item] = (tuple2.Item1, tuple2.Item2);
						break;
					}
				}
				if (!CardFeedUI.CardColors.ContainsKey(item))
				{
					float num = ((float)item * 0.618034f % 1f + 1f) % 1f;
					CardFeedUI.CardColors[item] = (text, Color.HSVToRGB(num, 0.55f, 0.72f));
				}
			}
		}

		private void TryPatchDirectCardPlay()
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			if (_managerType == null)
			{
				return;
			}
			string[] array = new string[6] { "UseCard", "SelectCard", "PlayCard", "HandleCard", "ActivateCard", "OnCardSelected" };
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.Method(_managerType, text, (Type[])null, (Type[])null);
				if (!(methodInfo == null))
				{
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length == 1 && !(parameters[0].ParameterType != typeof(int)))
					{
						_directCardPlayMethod = methodInfo;
						((BaseUnityPlugin)this).Logger.LogInfo((object)("[CardFeed] Found direct card play method: " + text + "(int)"));
						_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "DirectPlayPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						return;
					}
				}
			}
			if (_hudType != null)
			{
				array = new string[5] { "OnCardClick", "CardButtonPressed", "HandleCardButton", "OnCardSelected", "CardClicked" };
				foreach (string text2 in array)
				{
					MethodInfo methodInfo2 = AccessTools.Method(_hudType, text2, (Type[])null, (Type[])null);
					if (!(methodInfo2 == null))
					{
						ParameterInfo[] parameters2 = methodInfo2.GetParameters();
						if (parameters2.Length == 1 && !(parameters2[0].ParameterType != typeof(int)))
						{
							_directCardPlayMethod = methodInfo2;
							((BaseUnityPlugin)this).Logger.LogInfo((object)("[CardFeed] Found HUD card click method: " + text2 + "(int)"));
							_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "DirectPlayPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							return;
						}
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[CardFeed] No direct play method found; will use discard-diff fallback.");
		}

		private static void ClearRunState()
		{
			SavedDecks.Clear();
			InitialisingManagers.Clear();
			RestoringManagers.Clear();
			CardFeedUI.ClearFeed();
		}

		private static void EnsureFeedUIExists()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntry<bool>? feedEnabled = _feedEnabled;
			if ((feedEnabled == null || feedEnabled.Value) && !((Object)(object)CardFeedUI.Instance != (Object)null))
			{
				new GameObject("[HousePersistentDeck] CardFeed").AddComponent<CardFeedUI>();
				EnsureDeckDisplayExists();
			}
		}

		private static void EnsureDeckDisplayExists()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)DeckDisplayUI.Instance != (Object)null))
			{
				new GameObject("[HousePersistentDeck] DeckDisplay").AddComponent<DeckDisplayUI>();
			}
		}

		private static void HudNewHandPostfix(object __instance, int[] __0)
		{
			if (_inNextHand || __0 == null || __0.Length == 0 || !(_hudCardArtsField?.GetValue(null) is Image[] array))
			{
				return;
			}
			for (int i = 0; i < __0.Length && i < array.Length; i++)
			{
				Image obj = array[i];
				if ((Object)(object)((obj != null) ? obj.sprite : null) != (Object)null)
				{
					CardFeedUI.CardSprites[__0[i]] = array[i].sprite;
				}
			}
		}

		private static void InitialisePrefix(object __instance)
		{
			if (!GetBool(_initialisedField, __instance))
			{
				InitialisingManagers.Add(__instance);
			}
		}

		private static void InitialisePostfix(object __instance)
		{
			if (!InitialisingManagers.Remove(__instance) || !GetBool(_initialisedField, __instance))
			{
				return;
			}
			_activeManager = __instance;
			PopulateCardColorsFromDeck(__instance);
			EnsureFeedUIExists();
			EnsureDeckDisplayExists();
			CardFeedUI.SetVisible(visible: true);
			DeckDisplayUI.SetVisible(v: true);
			object deckKey = GetDeckKey(__instance);
			if (deckKey != null)
			{
				if (SavedDecks.TryGetValue(deckKey, out DeckState value))
				{
					RestoreState(__instance, value);
					UpdateHud(__instance);
				}
				else
				{
					CardFeedUI.ClearFeed();
					SaveState(__instance);
				}
				RefreshDeckDisplay(__instance);
				if (!_debugDumped)
				{
					_debugDumped = true;
					DumpDebugInfo(__instance);
				}
			}
		}

		private static void SavePrefix(object __instance)
		{
			SaveState(__instance);
			_activeManager = null;
			_inNextHand = false;
			_nextHandDepth = 0;
			CardFeedUI.SetVisible(visible: false);
			DeckDisplayUI.SetVisible(v: false);
		}

		private static void SavePostfix(object __instance)
		{
			if (!InitialisingManagers.Contains(__instance) && !RestoringManagers.Contains(__instance))
			{
				SaveState(__instance);
			}
		}

		private static void NextHandPrefix(object __instance, string __0)
		{
			ConfigEntry<bool>? feedEnabled = _feedEnabled;
			if (feedEnabled == null || !feedEnabled.Value || _directCardPlayMethod != null)
			{
				return;
			}
			_nextHandDepth++;
			_inNextHand = true;
			int[] array = ReadArray(_handCardsField, __instance);
			Image[] array2 = _hudCardArtsField?.GetValue(null) as Image[];
			if (_nextHandDepth == 1 && array != null && array2 != null)
			{
				for (int i = 0; i < array.Length && i < array2.Length; i++)
				{
					Image obj = array2[i];
					if ((Object)(object)((obj != null) ? obj.sprite : null) != (Object)null)
					{
						CardFeedUI.CardSprites[array[i]] = array2[i].sprite;
					}
				}
			}
			if (_nextHandDepth == 1 && int.TryParse(__0, out var result) && array != null && result >= 0 && result < array.Length)
			{
				_cardPushedViaButton = true;
				PushCardToFeed(array[result]);
			}
		}

		private static void NextHandPostfix(object __instance)
		{
			_nextHandDepth = Math.Max(0, _nextHandDepth - 1);
			_inNextHand = _nextHandDepth > 0;
			if (!InitialisingManagers.Contains(__instance) && !RestoringManagers.Contains(__instance))
			{
				SaveState(__instance);
			}
			if (_nextHandDepth == 0)
			{
				_cardPushedViaButton = false;
				_handSnapshot = null;
				_discardSnapshot = null;
				RefreshDeckDisplay(__instance);
			}
		}

		private static void DirectPlayPrefix(object __instance, int __0)
		{
			ConfigEntry<bool>? feedEnabled = _feedEnabled;
			if (feedEnabled != null && feedEnabled.Value)
			{
				int[] array = ReadArray(_handCardsField, __instance);
				if (array != null && array.Contains(__0))
				{
					PushCardToFeed(__0);
				}
				else if (array != null && __0 >= 0 && __0 < array.Length)
				{
					PushCardToFeed(array[__0]);
				}
			}
		}

		internal static int[] GetCurrentHand()
		{
			return ReadArray(_handCardsField, _activeManager) ?? Array.Empty<int>();
		}

		internal static List<int> GetCurrentDeck()
		{
			return ReadList(_gameDeckField, _activeManager) ?? new List<int>();
		}

		internal static List<int> GetCurrentDiscard()
		{
			return ReadList(_discardPileField, _activeManager) ?? new List<int>();
		}

		private static void RefreshDeckDisplay(object _)
		{
			DeckDisplayUI.RequestRefresh();
		}

		private static void DumpDebugInfo(object manager)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("=== HousePersistentDeck DEBUG DUMP ===");
			stringBuilder.AppendLine("\n[HousePassiveManager fields] (" + _managerType?.FullName + ")");
			if (_managerType != null)
			{
				FieldInfo[] fields = _managerType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					string text = "?";
					try
					{
						text = fieldInfo.GetValue(manager)?.ToString() ?? "null";
					}
					catch
					{
					}
					stringBuilder.AppendLine("  " + (fieldInfo.IsStatic ? "static " : "") + fieldInfo.FieldType.Name + " " + fieldInfo.Name + " = " + text);
				}
			}
			stringBuilder.AppendLine("\n[HousePassiveManager methods]");
			if (_managerType != null)
			{
				foreach (MethodInfo item in from m in _managerType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					orderby m.Name
					select m)
				{
					stringBuilder.AppendLine("  " + (item.IsStatic ? "static " : "") + item.ReturnType.Name + " " + item.Name + "(" + string.Join(", ", from p in item.GetParameters()
						select p.ParameterType.Name + " " + p.Name) + ")");
				}
			}
			stringBuilder.AppendLine("\n[HouseHUDManager fields] (" + _hudType?.FullName + ")");
			if (_hudType != null)
			{
				FieldInfo[] fields = _hudType.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo2 in fields)
				{
					stringBuilder.AppendLine("  " + (fieldInfo2.IsStatic ? "static " : "") + fieldInfo2.FieldType.Name + " " + fieldInfo2.Name);
				}
			}
			stringBuilder.AppendLine("\n[HouseHUDManager methods]");
			if (_hudType != null)
			{
				foreach (MethodInfo item2 in from m in _hudType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
					orderby m.Name
					select m)
				{
					stringBuilder.AppendLine("  " + (item2.IsStatic ? "static " : "") + item2.ReturnType.Name + " " + item2.Name + "(" + string.Join(", ", from p in item2.GetParameters()
						select p.ParameterType.Name + " " + p.Name) + ")");
				}
			}
			int[] array = ReadArray(_handCardsField, manager);
			List<int> list = ReadList(_gameDeckField, manager);
			List<int> list2 = ReadList(_discardPileField, manager);
			stringBuilder.AppendLine("\n[Deck state] hand=[" + ((array != null) ? string.Join(",", array) : "NULL") + "]");
			stringBuilder.AppendLine(string.Format("  drawPile (count={0}): [{1}]", list?.Count ?? (-1), (list != null) ? string.Join(",", list) : "NULL"));
			stringBuilder.AppendLine(string.Format("  discard  (count={0}): [{1}]", list2?.Count ?? (-1), (list2 != null) ? string.Join(",", list2) : "NULL"));
			stringBuilder.AppendLine("\n[Patch status]");
			stringBuilder.AppendLine($"  _gameDeckField found: {_gameDeckField != null}");
			stringBuilder.AppendLine($"  _discardPileField found: {_discardPileField != null}");
			stringBuilder.AppendLine($"  _handCardsField found: {_handCardsField != null}");
			stringBuilder.AppendLine($"  _hudNewHandMethod found: {_hudNewHandMethod != null}");
			stringBuilder.AppendLine("  _directCardPlayMethod: " + (_directCardPlayMethod?.Name ?? "none"));
			stringBuilder.AppendLine($"  _inNextHand: {_inNextHand}");
			stringBuilder.AppendLine($"  CardSprites cached: {CardFeedUI.CardSprites.Count}");
			stringBuilder.AppendLine($"  CardColors cached: {CardFeedUI.CardColors.Count}");
			stringBuilder.AppendLine("=== END DEBUG DUMP ===");
			ManualLogSource? log = _log;
			if (log != null)
			{
				log.LogInfo((object)stringBuilder.ToString());
			}
		}

		private static void PushCardToFeed(int cardId)
		{
			EnsureFeedUIExists();
			string cardDisplayName = GetCardDisplayName(cardId);
			CardFeedUI.AddCard(cardId, cardDisplayName);
		}

		private static string GetCardDisplayName(int cardId)
		{
			if (CardFeedUI.CardColors.TryGetValue(cardId, out (string, Color) value))
			{
				return value.Item1;
			}
			return $"#{cardId}";
		}

		private static int FindRemovedCard(int[] before, int[] after)
		{
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			int[] array = after;
			foreach (int key in array)
			{
				dictionary[key] = dictionary.GetValueOrDefault(key, 0) + 1;
			}
			int result = -1;
			int num = 0;
			array = before;
			foreach (int num2 in array)
			{
				int num4 = (dictionary[num2] = dictionary.GetValueOrDefault(num2, 0) - 1);
				if (num4 < 0)
				{
					result = num2;
					num++;
				}
			}
			if (num != 1)
			{
				return -1;
			}
			return result;
		}

		private static bool HandsEquivalent(int[] a, int[] b)
		{
			if (a.Length != b.Length)
			{
				return false;
			}
			return a.OrderBy((int x) => x).SequenceEqual(b.OrderBy((int x) => x));
		}

		private static int FindAddedCard(List<int> before, List<int> after)
		{
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			foreach (int item in before)
			{
				dictionary[item] = dictionary.GetValueOrDefault(item, 0) + 1;
			}
			int result = -1;
			int num = 0;
			foreach (int item2 in after)
			{
				dictionary[item2] = dictionary.GetValueOrDefault(item2, 0) - 1;
			}
			foreach (var (num4, num5) in dictionary)
			{
				if (num5 < 0)
				{
					result = num4;
					num++;
				}
			}
			if (num != 1)
			{
				return -1;
			}
			return result;
		}

		private static void SaveState(object manager)
		{
			object deckKey = GetDeckKey(manager);
			if (deckKey != null)
			{
				List<int> list = ReadList(_gameDeckField, manager);
				List<int> list2 = ReadList(_discardPileField, manager);
				int[] array = ReadArray(_handCardsField, manager);
				if (list != null && list2 != null && array != null)
				{
					SavedDecks[deckKey] = new DeckState(list.ToArray(), list2.ToArray(), array.ToArray());
				}
			}
		}

		private static void RestoreState(object manager, DeckState state)
		{
			RestoringManagers.Add(manager);
			try
			{
				_gameDeckField?.SetValue(manager, state.GameDeck.ToList());
				_discardPileField?.SetValue(manager, state.DiscardPile.ToList());
				_handCardsField?.SetValue(manager, state.HandCards.ToArray());
			}
			finally
			{
				RestoringManagers.Remove(manager);
			}
		}

		private static void UpdateHud(object manager)
		{
			if (!GetBool(_isAuthorityField, manager))
			{
				return;
			}
			int[] array = ReadArray(_handCardsField, manager);
			if (array != null)
			{
				_hudPassiveManagerField?.SetValue(null, manager);
				object obj = _hudInstanceField?.GetValue(null);
				if (obj != null)
				{
					_hudNewHandMethod?.Invoke(obj, new object[2]
					{
						array.ToArray(),
						"Default"
					});
					_hudUpdateCardDisplayMethod?.Invoke(obj, null);
				}
			}
		}

		private static object? GetDeckKey(object manager)
		{
			object obj = _characterBodyField?.GetValue(manager);
			if (obj == null)
			{
				return null;
			}
			return (AccessTools.Property(obj.GetType(), "master")?.GetValue(obj) ?? AccessTools.Field(obj.GetType(), "master")?.GetValue(obj)) ?? obj;
		}

		private void Patch(Type type, string methodName, string? prefix = null, string? postfix = null)
		{
			//IL_006d: 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)
			MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch " + type.FullName + "." + methodName + ": method not found."));
				return;
			}
			Type typeFromHandle = typeof(Plugin);
			try
			{
				_harmony.Patch((MethodBase)methodInfo, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeFromHandle, prefix, (Type[])null, (Type[])null)), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(AccessTools.Method(typeFromHandle, postfix, (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failed to patch " + type.FullName + "." + methodName + ": " + ex.Message));
			}
		}

		private static bool GetBool(FieldInfo? field, object instance)
		{
			object obj = field?.GetValue(instance);
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static List<int>? ReadList(FieldInfo? field, object instance)
		{
			return field?.GetValue(instance) as List<int>;
		}

		private static int[]? ReadArray(FieldInfo? field, object instance)
		{
			return field?.GetValue(instance) as int[];
		}
	}
}