Decompiled source of ItemShops v0.0.2

ItemShops.dll

Decompiled 7 months ago
using System;
using System.ArrayExtensions;
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.Runtime.Versioning;
using BepInEx;
using ExitGames.Client.Photon;
using HarmonyLib;
using InControl;
using ItemShops.Extensions;
using ItemShops.Interfaces;
using ItemShops.Monobehaviours;
using ItemShops.Utils;
using Jotunn.Utils;
using ModdingUtils.Utils;
using Photon.Realtime;
using Sonigon;
using TMPro;
using UnboundLib;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ItemShops")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ItemShops")]
[assembly: AssemblyTitle("ItemShops")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BetterChat.Patches
{
	[HarmonyPatch(typeof(GeneralInput))]
	internal class GeneralInput_Patch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool BlockPlayerInput(GeneralInput __instance)
		{
			return !ShopManager.isLockingInput;
		}
	}
}
namespace ItemShops
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.willuwontu.rounds.itemshops", "Item Shops", "0.0.2")]
	[BepInProcess("Rounds.exe")]
	public class ItemShops : BaseUnityPlugin
	{
		private const string ModId = "com.willuwontu.rounds.itemshops";

		private const string ModName = "Item Shops";

		public const string Version = "0.0.2";

		public List<AudioClip> click;

		public List<AudioClip> hover;

		public List<SoundEvent> clickSounds = new List<SoundEvent>();

		public List<SoundEvent> hoverSounds = new List<SoundEvent>();

		public static ItemShops instance { get; private set; }

		public AssetBundle assets { get; private set; }

		private void Awake()
		{
		}

		private void Start()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			instance = this;
			Harmony val = new Harmony("com.willuwontu.rounds.itemshops");
			val.PatchAll();
			assets = AssetUtils.LoadAssetBundleFromResources("shopuiassets", typeof(ItemShops).Assembly);
			click = (from clip in assets.LoadAllAssets<AudioClip>().ToList()
				where ((Object)clip).name.Contains("UI_Button_Click")
				select clip).ToList();
			hover = (from clip in assets.LoadAllAssets<AudioClip>().ToList()
				where ((Object)clip).name.Contains("UI_Button_Hover")
				select clip).ToList();
			try
			{
				foreach (AudioClip item in click)
				{
					SoundContainer val2 = ScriptableObject.CreateInstance<SoundContainer>();
					val2.setting.volumeIntensityEnable = true;
					val2.setting.volumeDecibel = 10f;
					val2.audioClip[0] = item;
					SoundEvent val3 = ScriptableObject.CreateInstance<SoundEvent>();
					val3.soundContainerArray[0] = val2;
					clickSounds.Add(val3);
				}
				foreach (AudioClip item2 in hover)
				{
					SoundContainer val4 = ScriptableObject.CreateInstance<SoundContainer>();
					val4.setting.volumeIntensityEnable = true;
					val4.setting.volumeDecibel = 10f;
					val4.audioClip[0] = item2;
					SoundEvent val5 = ScriptableObject.CreateInstance<SoundEvent>();
					val5.soundContainerArray[0] = val4;
					hoverSounds.Add(val5);
				}
			}
			catch (Exception ex)
			{
				Debug.LogException(ex);
			}
			((Component)this).gameObject.AddComponent<InterfaceGameModeHooksManager>();
			((Component)this).gameObject.AddComponent<ShopManager>();
			((Component)this).gameObject.AddComponent<CurrencyManager>();
			GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)OnPointEnd);
		}

		private IEnumerator OnPointEnd(IGameModeHandler gm)
		{
			foreach (Shop shop in ShopManager.instance.Shops.Values)
			{
				shop.Hide();
			}
			yield break;
		}

		private IEnumerator OnGameStart(IGameModeHandler gm)
		{
			foreach (Player player in PlayerManager.instance.players)
			{
				player.GetAdditionalData().bankAccount.RemoveAllMoney();
			}
			yield break;
		}
	}
}
namespace ItemShops.Utils
{
	public class BankAccount
	{
		private Dictionary<string, int> money = new Dictionary<string, int>();

		public ReadOnlyDictionary<string, int> Money => new ReadOnlyDictionary<string, int>(money);

		public void Deposit(string currency, int amount)
		{
			if (money.ContainsKey(currency))
			{
				money[currency] += amount;
			}
			else
			{
				money.Add(currency, amount);
			}
		}

		public void Deposit(Dictionary<string, int> money)
		{
			foreach (KeyValuePair<string, int> item in money)
			{
				Deposit(item.Key, item.Value);
			}
		}

		public bool Withdraw(string currency, int amount)
		{
			if (money.TryGetValue(currency, out var value) && value >= amount)
			{
				money[currency] -= amount;
				return true;
			}
			return false;
		}

		public bool Withdraw(Dictionary<string, int> money)
		{
			int value;
			bool flag = money.All((KeyValuePair<string, int> resource) => this.money.TryGetValue(resource.Key, out value) && value >= resource.Value);
			if (flag)
			{
				foreach (KeyValuePair<string, int> item in money)
				{
					this.money[item.Key] -= item.Value;
				}
			}
			return flag;
		}

		public bool HasFunds(Dictionary<string, int> money)
		{
			int value;
			return money.All((KeyValuePair<string, int> resource) => this.money.TryGetValue(resource.Key, out value) && value >= resource.Value);
		}

		public void RemoveAllMoney()
		{
			money.Clear();
		}
	}
	internal class CostItem : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private Shop shop;

		private UnityEvent mouseEnter = new UnityEvent();

		private UnityEvent mouseExit = new UnityEvent();

		private Image _icon = null;

		private TextMeshProUGUI _text = null;

		private GUIStyle guiStyleFore;

		private bool inBounds = false;

		public string Currency { get; internal set; }

		public Image Image
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_icon))
				{
					_icon = ((Component)((Component)this).gameObject.transform.Find("Cost Icon")).GetComponent<Image>();
				}
				return _icon;
			}
		}

		public TextMeshProUGUI Text
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_text))
				{
					_text = ((Component)((Component)this).gameObject.transform.Find("Cost Text")).GetComponent<TextMeshProUGUI>();
				}
				return _text;
			}
		}

		private void Start()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			guiStyleFore = new GUIStyle();
			guiStyleFore.richText = true;
			guiStyleFore.normal.textColor = Color.white;
			guiStyleFore.alignment = (TextAnchor)0;
			guiStyleFore.wordWrap = false;
			guiStyleFore.stretchWidth = true;
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, Color.gray);
			val.Apply();
			guiStyleFore.normal.background = val;
			shop = ((Component)this).gameObject.GetComponentInParent<Shop>();
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			UnityEvent obj = mouseEnter;
			if (obj != null)
			{
				obj.Invoke();
			}
			inBounds = true;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			UnityEvent obj = mouseExit;
			if (obj != null)
			{
				obj.Invoke();
			}
			inBounds = false;
		}

		private void OnGUI()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//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_0045: 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_006c: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			if (inBounds)
			{
				string currency = Currency;
				if (currency != null && currency.Trim().Length > 0)
				{
					Vector2 val = guiStyleFore.CalcSize(new GUIContent(Currency));
					GUILayout.BeginArea(new Rect(Input.mousePosition.x + 25f, (float)Screen.height - Input.mousePosition.y + 25f, val.x + 10f, val.y + 10f));
					GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
					GUILayout.Label(Currency, guiStyleFore, Array.Empty<GUILayoutOption>());
					GUILayout.EndVertical();
					GUILayout.EndArea();
				}
			}
		}
	}
	public class CurrencyManager : MonoBehaviour
	{
		private Dictionary<string, Action<Image>> CurrencyImageActions = new Dictionary<string, Action<Image>>();

		private Action<Image> defaultImageAction = delegate(Image image)
		{
			//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)
			image.sprite = ItemShops.instance.assets.LoadAsset<Sprite>("dollar-sign");
			((Graphic)image).color = Color32.op_Implicit(new Color32((byte)118, (byte)117, (byte)35, byte.MaxValue));
		};

		public static CurrencyManager instance;

		public bool RegisterCurrencyIcon(string currency, Action<Image> imageAction)
		{
			if (CurrencyImageActions.ContainsKey(currency))
			{
				return false;
			}
			CurrencyImageActions.Add(currency, imageAction);
			return true;
		}

		public Action<Image> CurrencyImageAction(string currency)
		{
			Action<Image> action = null;
			if (CurrencyImageActions.TryGetValue(currency, out var value))
			{
				return value;
			}
			return defaultImageAction;
		}

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

		private void Start()
		{
		}
	}
	public abstract class Purchasable
	{
		public abstract string Name { get; }

		public abstract Dictionary<string, int> Cost { get; }

		public abstract Tag[] Tags { get; }

		public abstract GameObject CreateItem(GameObject parent);

		public abstract void OnPurchase(Player player, Purchasable item);

		public abstract bool CanPurchase(Player player);
	}
	public class PurchasableCard : Purchasable
	{
		private CardInfo _card;

		private Dictionary<string, int> _cost;

		private Tag[] _tags;

		private string _name;

		public CardInfo Card => _card;

		public override Dictionary<string, int> Cost => _cost;

		public override Tag[] Tags => _tags;

		public override string Name => _name;

		public PurchasableCard(CardInfo card, Dictionary<string, int> cost, Tag[] tags)
		{
			_card = card;
			_cost = cost;
			_tags = tags;
			_name = card.cardName.ToUpper();
		}

		public PurchasableCard(CardInfo card, Dictionary<string, int> cost, Tag[] tags, string name)
		{
			_card = card;
			_cost = cost;
			_tags = tags;
			_name = name;
		}

		public override void OnPurchase(Player player, Purchasable item)
		{
			CardInfo card = ((PurchasableCard)item)._card;
			Cards.instance.AddCardToPlayer(player, card, false, "", 2f, 2f);
			((MonoBehaviour)ItemShops.instance).StartCoroutine(ShowCard(player, card));
		}

		public override bool CanPurchase(Player player)
		{
			return Cards.instance.PlayerIsAllowedCard(player, Card);
		}

		public override GameObject CreateItem(GameObject parent)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			GameObject val2 = null;
			try
			{
				val = Object.Instantiate<GameObject>(ItemShops.instance.assets.LoadAsset<GameObject>("Card Container"));
			}
			catch (Exception)
			{
				Debug.Log((object)"Issue with creating the card container");
			}
			try
			{
				val2 = ((Component)val.transform.Find("Card Holder")).gameObject;
			}
			catch (Exception)
			{
				Debug.Log((object)"Issue with getting the Card Holder");
				val2 = ((Component)val.transform.GetChild(0)).gameObject;
			}
			val2.transform.localPosition = new Vector3(0f, -100f, 0f);
			val2.transform.localScale = new Vector3(0.125f, 0.125f, 1f);
			val2.transform.Rotate(0f, 180f, 0f);
			GameObject val3 = null;
			try
			{
				val3 = GetCardVisuals(_card, val2);
			}
			catch (Exception ex3)
			{
				Debug.Log((object)"Issue with getting card visuals");
				Debug.LogError((object)ex3);
			}
			val.transform.SetParent(parent.transform);
			return val;
		}

		public static IEnumerator ShowCard(Player player, CardInfo card)
		{
			yield return CardBarUtils.instance.ShowImmediate(player, card, (float?)2f);
		}

		private GameObject GetCardVisuals(CardInfo card, GameObject parent)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_007d: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			GameObject cardObj = Object.Instantiate<GameObject>(((Component)card).gameObject, parent.gameObject.transform);
			cardObj.SetActive(true);
			cardObj.GetComponentInChildren<CardVisuals>().firstValueToSet = true;
			RectTransform orAddComponent = ExtensionMethods.GetOrAddComponent<RectTransform>(cardObj, false);
			((Transform)orAddComponent).localScale = 100f * Vector3.one;
			orAddComponent.anchorMin = Vector2.zero;
			orAddComponent.anchorMax = Vector2.one;
			orAddComponent.offsetMin = Vector2.zero;
			orAddComponent.offsetMax = Vector2.zero;
			orAddComponent.pivot = new Vector2(0.5f, 0.5f);
			GameObject val = FindObjectInChildren(cardObj, "Back");
			try
			{
				Object.Destroy((Object)(object)val);
			}
			catch
			{
			}
			GameObject obj2 = FindObjectInChildren(cardObj, "BlockFront");
			if (obj2 != null)
			{
				obj2.SetActive(false);
			}
			CanvasGroup[] componentsInChildren = cardObj.GetComponentsInChildren<CanvasGroup>();
			CanvasGroup[] array = componentsInChildren;
			foreach (CanvasGroup val2 in array)
			{
				val2.alpha = 1f;
			}
			ExtensionMethods.ExecuteAfterSeconds((MonoBehaviour)(object)ItemShops.instance, 0.2f, (Action)delegate
			{
				//IL_004e: 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_0072: 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)
				CardRarityColor[] componentsInChildren2 = cardObj.GetComponentsInChildren<CardRarityColor>();
				CardRarityColor[] array2 = componentsInChildren2;
				foreach (CardRarityColor val3 in array2)
				{
					try
					{
						val3.Toggle(true);
					}
					catch
					{
					}
				}
				TextMeshProUGUI component = FindObjectInChildren(cardObj, "Text_Name").GetComponent<TextMeshProUGUI>();
				if (((Graphic)component).color.r < 0.18f && ((Graphic)component).color.g < 0.18f && ((Graphic)component).color.b < 0.18f)
				{
					((Graphic)component).color = Color32.op_Implicit(new Color32((byte)200, (byte)200, (byte)200, byte.MaxValue));
				}
			});
			return cardObj;
		}

		private static GameObject FindObjectInChildren(GameObject gameObject, string gameObjectName)
		{
			Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>(true);
			return (from item in componentsInChildren
				where ((Object)item).name == gameObjectName
				select ((Component)item).gameObject).FirstOrDefault();
		}
	}
	public struct PurchaseLimit
	{
		public readonly int global;

		public readonly int perPlayer;

		public PurchaseLimit(int global = 0, int perPlayer = 0)
		{
			this.global = global;
			this.perPlayer = perPlayer;
		}

		public PurchaseLimit(PurchaseLimit purchaseLimit)
		{
			global = purchaseLimit.global;
			perPlayer = purchaseLimit.perPlayer;
		}
	}
	public class Shop : MonoBehaviour
	{
		private class FilterHandler : MonoBehaviour, ISelectHandler, IEventSystemHandler, IDeselectHandler
		{
			public Shop shop = null;

			public void OnDeselect(BaseEventData data)
			{
				ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)this, 1, (Action)delegate
				{
					shop.filterSelected = false;
				});
			}

			public void OnSelect(BaseEventData data)
			{
				shop.filterSelected = true;
			}
		}

		private string _name;

		private Dictionary<string, ShopItem> _items = new Dictionary<string, ShopItem>();

		private ShopItem currentPurchase = null;

		internal ShopItem highlightedItem = null;

		private Player currentPlayer = null;

		private TextMeshProUGUI _title = null;

		private GameObject _tagContainer = null;

		private TMP_InputField _filter = null;

		private GameObject _itemContainer = null;

		private GameObject _purchaseItemObject = null;

		private GameObject _purchaseCostContainer = null;

		private Button _purchaseButton = null;

		private GameObject _purchaseHighlight = null;

		private GameObject _moneyContainer = null;

		private TextMeshProUGUI _moneyText = null;

		public Action<Player, ShopItem> itemPurchasedAction = null;

		internal bool filterSelected = false;

		private ScrollRect _scrollRect = null;

		private int[] selectedRow = new int[3];

		private int selectedColumn = 1;

		private GameObject selectedItem;

		private float timeHeld = 0f;

		private float delay = 0.5f;

		private float spacing = 1f / 30f;

		private bool finishedDelay = false;

		private Vector2 lastDirection = Vector2.zero;

		internal string ID;

		public bool IsOpen => ((Component)this).gameObject.activeSelf;

		public string DisplayName => _name;

		public bool HideInvalidItems { get; set; } = false;


		public ShopItem CurrentPurchase => currentPurchase;

		public Player CurrentPlayer => currentPlayer;

		internal TextMeshProUGUI Title
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_title))
				{
					_title = ((Component)((Component)this).gameObject.transform.Find("Titlebar/Title")).GetComponent<TextMeshProUGUI>();
				}
				return _title;
			}
		}

		internal GameObject TagContainer
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_tagContainer))
				{
					_tagContainer = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Filter Section/Tag View/Viewport/Content")).gameObject;
				}
				return _tagContainer;
			}
		}

		internal TMP_InputField Filter
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_filter))
				{
					_filter = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Filter Section/Item Filter")).GetComponent<TMP_InputField>();
					FilterHandler filterHandler = ((Component)_filter).gameObject.AddComponent<FilterHandler>();
					filterHandler.shop = this;
				}
				return _filter;
			}
		}

		internal GameObject ItemContainer
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_itemContainer))
				{
					_itemContainer = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Item Section/Item Area/Item Selection/Viewport/Content")).gameObject;
				}
				return _itemContainer;
			}
		}

		internal GameObject PurchaseItemObject
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_purchaseItemObject))
				{
					_purchaseItemObject = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Item Section/Item Area/Item Info/Item Container/Item Holder")).gameObject;
				}
				return _purchaseItemObject;
			}
		}

		internal GameObject PurchaseCostContainer
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_purchaseCostContainer))
				{
					_purchaseCostContainer = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Item Section/Item Area/Item Info/Item Container/Cost View/Viewport/Content")).gameObject;
				}
				return _purchaseCostContainer;
			}
		}

		internal Button PurchaseButton
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_purchaseButton))
				{
					_purchaseButton = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Item Section/Item Area/Item Info/Item Container/Purchase Button")).GetComponent<Button>();
				}
				return _purchaseButton;
			}
		}

		internal GameObject PurchaseHighlight
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_purchaseHighlight))
				{
					_purchaseHighlight = ((Component)((Component)PurchaseButton).transform.Find("Highlight")).gameObject;
				}
				return _purchaseHighlight;
			}
		}

		internal GameObject MoneyContainer
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_moneyContainer))
				{
					_moneyContainer = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Money Section/Money View/Viewport/Content")).gameObject;
				}
				return _moneyContainer;
			}
		}

		internal TextMeshProUGUI MoneyText
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_moneyText))
				{
					_moneyText = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Money Section/Money Text")).gameObject.GetComponent<TextMeshProUGUI>();
				}
				return _moneyText;
			}
		}

		internal ScrollRect Scroll
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_scrollRect))
				{
					_scrollRect = ((Component)((Component)this).gameObject.transform.Find("Shop Sections/Item Section/Item Area/Item Selection")).GetComponent<ScrollRect>();
				}
				return _scrollRect;
			}
		}

		public ReadOnlyDictionary<string, ShopItem> ShopItems => new ReadOnlyDictionary<string, ShopItem>(_items);

		public void UpdateTitle(string name)
		{
			_name = name;
			((TMP_Text)Title).text = name;
		}

		public void UpdateMoneyColumnName(string name)
		{
			((TMP_Text)MoneyText).text = name;
		}

		private ShopItem AddItem(string itemID, Purchasable item, PurchaseLimit purchaseLimit, bool update)
		{
			ShopItem shopItem = null;
			try
			{
				if (_items.ContainsKey(itemID))
				{
					throw new ArgumentException("'ShopItem::AddItem(string itemID, Purchasable item, PurchaseLimit purchaseLimit, bool update)' The itemID must be unique.");
				}
				shopItem = CreateItem(item, purchaseLimit);
				shopItem.Purchasable = item;
				shopItem.ID = itemID;
				_items.Add(itemID, shopItem);
				if (update)
				{
					ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)ShopManager.instance, 2, (Action)UpdateItems);
				}
			}
			catch (Exception ex)
			{
				Debug.LogException(ex);
			}
			return shopItem;
		}

		public ShopItem AddItem(string itemID, Purchasable item, PurchaseLimit purchaseLimit)
		{
			return AddItem(itemID, item, purchaseLimit, update: true);
		}

		public ShopItem AddItem(string itemID, Purchasable item)
		{
			return AddItem(itemID, item, new PurchaseLimit(0, 0), update: true);
		}

		public ShopItem AddItem(Purchasable item, PurchaseLimit purchaseLimit)
		{
			return AddItem(item.Name, item, purchaseLimit);
		}

		public ShopItem AddItem(Purchasable item)
		{
			return AddItem(item.Name, item);
		}

		public ShopItem[] AddItems(string[] itemIDs, Purchasable[] items)
		{
			if (items.Length != itemIDs.Length)
			{
				throw new ArgumentException("'Shop::AddItems(string[] itemIDs, Purchasable[] items)' expects 2 arrays of equal length.");
			}
			List<ShopItem> list = new List<ShopItem>();
			for (int i = 0; i < items.Length; i++)
			{
				list.Add(AddItem(itemIDs[i], items[i], new PurchaseLimit(0, 0), update: false));
			}
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)ShopManager.instance, 2, (Action)UpdateItems);
			return list.ToArray();
		}

		public ShopItem[] AddItems(string[] itemIDs, Purchasable[] items, PurchaseLimit purchaseLimit)
		{
			if (items.Length != itemIDs.Length)
			{
				throw new ArgumentException("'Shop::AddItems(string[] itemIDs, Purchasable[] items, PurchaseLimit purchaseLimit)' The itemIDs and items arrays must be of equal length.");
			}
			List<ShopItem> list = new List<ShopItem>();
			for (int i = 0; i < items.Length; i++)
			{
				list.Add(AddItem(itemIDs[i], items[i], new PurchaseLimit(purchaseLimit), update: false));
			}
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)ShopManager.instance, 2, (Action)UpdateItems);
			return list.ToArray();
		}

		public ShopItem[] AddItems(string[] itemIDs, Purchasable[] items, PurchaseLimit[] purchaseLimits)
		{
			if (items.Length != purchaseLimits.Length || items.Length != itemIDs.Length)
			{
				throw new ArgumentException("'Shop::AddItems(string[] itemIDs, Purchasable[] items, PurchaseLimit[] purchaseLimits)' expects 3 arrays of equal length.");
			}
			List<ShopItem> list = new List<ShopItem>();
			for (int i = 0; i < items.Length; i++)
			{
				list.Add(AddItem(itemIDs[i], items[i], new PurchaseLimit(purchaseLimits[i]), update: false));
			}
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)ShopManager.instance, 2, (Action)UpdateItems);
			return list.ToArray();
		}

		public ShopItem[] AddItems(Purchasable[] items)
		{
			return AddItems(items.Select((Purchasable i) => i.Name).ToArray(), items);
		}

		public ShopItem[] AddItems(Purchasable[] items, PurchaseLimit purchaseLimit)
		{
			return AddItems(items.Select((Purchasable i) => i.Name).ToArray(), items, purchaseLimit);
		}

		public ShopItem[] AddItems(Purchasable[] items, PurchaseLimit[] purchaseLimits)
		{
			return AddItems(items.Select((Purchasable i) => i.Name).ToArray(), items, purchaseLimits);
		}

		public void RemoveItem(string itemId)
		{
			if (_items.TryGetValue(itemId, out var value))
			{
				Object.Destroy((Object)(object)((Component)value).gameObject);
				_items.Remove(itemId);
			}
			ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)ShopManager.instance, 2, (Action)UpdateItems);
		}

		public void RemoveAllItems()
		{
			KeyValuePair<string, ShopItem>[] array = ShopItems.ToArray();
			KeyValuePair<string, ShopItem>[] array2 = array;
			foreach (KeyValuePair<string, ShopItem> keyValuePair in array2)
			{
				Object.Destroy((Object)(object)((Component)keyValuePair.Value).gameObject);
			}
			_items.Clear();
			UpdateItems();
		}

		private ShopItem CreateItem(Purchasable item, PurchaseLimit purchaseLimit)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(ShopManager.instance.shopItemTemplate, ItemContainer.transform);
			((Transform)val.GetComponent<RectTransform>()).localScale = Vector3.one;
			ButtonInteraction buttonInteraction = val.AddComponent<ButtonInteraction>();
			ShopItem shopItem = val.AddComponent<ShopItem>();
			shopItem.Purchasable = item;
			shopItem.PurchaseLimit = purchaseLimit;
			shopItem.UpdateDisplayName(item.Name);
			return shopItem;
		}

		private void DisableItemAnimations(GameObject item, ButtonInteraction interact)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			Animator[] animators = (Animator[])(object)new Animator[0];
			PositionNoise[] noises = (PositionNoise[])(object)new PositionNoise[0];
			animators = item.GetComponentsInChildren<Animator>();
			noises = item.GetComponentsInChildren<PositionNoise>();
			Animator[] array = animators;
			foreach (Animator val in array)
			{
				((Behaviour)val).enabled = false;
			}
			PositionNoise[] array2 = noises;
			foreach (PositionNoise val2 in array2)
			{
				((Behaviour)val2).enabled = false;
			}
			interact.mouseEnter.AddListener((UnityAction)delegate
			{
				Animator[] array5 = animators;
				foreach (Animator val5 in array5)
				{
					((Behaviour)val5).enabled = true;
				}
				PositionNoise[] array6 = noises;
				foreach (PositionNoise val6 in array6)
				{
					((Behaviour)val6).enabled = true;
				}
			});
			interact.mouseExit.AddListener((UnityAction)delegate
			{
				Animator[] array3 = animators;
				foreach (Animator val3 in array3)
				{
					((Behaviour)val3).enabled = false;
				}
				PositionNoise[] array4 = noises;
				foreach (PositionNoise val4 in array4)
				{
					((Behaviour)val4).enabled = false;
				}
			});
		}

		private GameObject CreateCostItem(GameObject parent, string currency, int amount)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(ShopManager.instance.costObjectTemplate, parent.transform);
			((Transform)val.GetComponent<RectTransform>()).localScale = Vector3.one;
			CostItem costItem = val.AddComponent<CostItem>();
			((TMP_Text)costItem.Text).text = $"{amount}";
			costItem.Currency = currency;
			CurrencyManager.instance.CurrencyImageAction(currency)(costItem.Image);
			return val;
		}

		public void Show(Player player)
		{
			if (player.data.view.IsMine)
			{
				ShopManager.instance.HideAllShops();
				currentPlayer = player;
				UpdateMoney();
				UpdateFilters();
				((Component)this).gameObject.SetActive(true);
				ShopManager.instance.CurrentShop = this;
				Hashtable customProperties = player.data.view.Owner.CustomProperties;
				customProperties[(object)"ItemShops-InShop"] = true;
				player.data.view.Owner.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
			}
		}

		public void Hide()
		{
			if (((Component)this).gameObject.activeSelf)
			{
				if ((Object)(object)currentPlayer != (Object)null && currentPlayer.data.view.IsMine)
				{
					Hashtable customProperties = currentPlayer.data.view.Owner.CustomProperties;
					customProperties[(object)"ItemShops-InShop"] = false;
					currentPlayer.data.view.Owner.SetCustomProperties(customProperties, (Hashtable)null, (WebFlags)null);
				}
				currentPlayer = null;
				currentPurchase = null;
				ClearPurchaseArea();
				((Component)this).gameObject.SetActive(false);
				ShopManager.instance.CurrentShop = null;
				selectedItem = null;
				selectedRow = new int[3];
			}
		}

		private void UpdateMoney()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			foreach (Transform item in MoneyContainer.transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			if (!Object.op_Implicit((Object)(object)currentPlayer))
			{
				return;
			}
			foreach (KeyValuePair<string, int> item2 in currentPlayer.GetAdditionalData().bankAccount.Money)
			{
				CreateCostItem(MoneyContainer, item2.Key, item2.Value);
			}
		}

		public void UpdateItems()
		{
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			TagItem[] componentsInChildren = ((Component)this).GetComponentsInChildren<TagItem>();
			string[] existingTags = componentsInChildren.Select((TagItem tag) => tag.Tag.name).ToArray();
			List<string> itemTags = new List<string>();
			foreach (ShopItem value in ShopItems.Values)
			{
				itemTags.AddRange(value.Purchasable.Tags.Select((Tag tag) => tag.name));
			}
			string[] ghostTags = existingTags.Where((string tag) => !itemTags.Contains(tag)).ToArray();
			itemTags = (from tag in itemTags.Distinct()
				where !existingTags.Contains(tag)
				select tag).ToList();
			foreach (string item in itemTags)
			{
				GameObject val = Object.Instantiate<GameObject>(ShopManager.instance.tagObjectTemplate, TagContainer.transform);
				((Transform)val.GetComponent<RectTransform>()).localScale = Vector3.one;
				((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).text = item;
				val.AddComponent<ButtonInteraction>();
				TagItem tagItem = val.AddComponent<TagItem>();
				tagItem.Tag = new Tag(item);
			}
			foreach (TagItem item2 in componentsInChildren.Where((TagItem item) => ghostTags.Contains(item.Tag.name)))
			{
				Object.Destroy((Object)(object)((Component)item2).gameObject);
			}
			componentsInChildren = ((Component)this).GetComponentsInChildren<TagItem>();
			UpdateFilters();
		}

		internal void UpdateFilters()
		{
			TagItem[] componentsInChildren = ((Component)this).GetComponentsInChildren<TagItem>();
			string[] excludedTags = (from tag in (from tagItem in componentsInChildren
					where tagItem.FilterState == FilterState.Excluded
					select tagItem.Tag).ToArray()
				select tag.name).ToArray();
			string[] requiredTags = (from tag in (from tagItem in componentsInChildren
					where tagItem.FilterState == FilterState.Required
					select tagItem.Tag).ToArray()
				select tag.name).ToArray();
			ShopItem[] source = _items.Values.Where((ShopItem item) => excludedTags.Intersect(item.Purchasable.Tags.Select((Tag tag) => tag.name).ToArray()).ToArray().Length == 0 && requiredTags.Intersect(item.Purchasable.Tags.Select((Tag tag) => tag.name).ToArray()).ToArray().Length == requiredTags.Length).ToArray();
			if (Filter.text.Trim().Length > 0)
			{
				source = source.Where((ShopItem item) => (from tmp in ((Component)item).gameObject.GetComponentsInChildren<TextMeshProUGUI>()
					select ((TMP_Text)tmp).text.ToLower()).Any((string text) => text.Contains(Filter.text.Trim().ToLower()))).ToArray();
			}
			foreach (ShopItem value in ShopItems.Values)
			{
				((Component)value).gameObject.SetActive(source.Contains(value));
			}
			source = source.Where((ShopItem item) => item.IsItemPurchasable(currentPlayer)).ToArray();
			foreach (ShopItem value2 in ShopItems.Values)
			{
				((Selectable)((Component)value2).gameObject.GetComponent<Button>()).interactable = source.Contains(value2);
				value2.Darken.SetActive(!source.Contains(value2));
				if (HideInvalidItems && !source.Contains(value2))
				{
					((Component)value2).gameObject.SetActive(false);
				}
			}
			componentsInChildren = (from item in ((Component)this).GetComponentsInChildren<TagItem>()
				orderby item.Tag.name
				select item).ToArray();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).transform.SetSiblingIndex(i);
			}
			UpdateMoney();
		}

		private void ClearFilters()
		{
			TagItem[] componentsInChildren = ((Component)this).GetComponentsInChildren<TagItem>();
			TagItem[] array = componentsInChildren;
			foreach (TagItem tagItem in array)
			{
				tagItem.SetState(FilterState.Allowed);
			}
			UpdateFilters();
		}

		internal void OnItemClicked(ShopItem item)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_011f: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			ClearPurchaseArea();
			try
			{
				GameObject val = item.Purchasable.CreateItem(PurchaseItemObject);
				((Transform)ExtensionMethods.GetOrAddComponent<RectTransform>(val, false)).localScale = Vector3.one;
				((Transform)ExtensionMethods.GetOrAddComponent<RectTransform>(val, false)).localPosition = Vector3.zero;
			}
			catch (Exception ex)
			{
				Debug.LogException(ex);
			}
			foreach (KeyValuePair<string, int> item2 in item.Purchasable.Cost)
			{
				CostItem component = CreateCostItem(PurchaseCostContainer, item2.Key, item2.Value).GetComponent<CostItem>();
				if (Object.op_Implicit((Object)(object)currentPlayer) && currentPlayer.GetAdditionalData().bankAccount.Money.TryGetValue(item2.Key, out var value))
				{
					if (value < item2.Value)
					{
						((Graphic)component.Text).color = Color32.op_Implicit(new Color32((byte)235, (byte)10, (byte)10, byte.MaxValue));
					}
					else
					{
						((Graphic)component.Text).color = Color32.op_Implicit(new Color32((byte)225, (byte)225, (byte)225, byte.MaxValue));
					}
				}
				else
				{
					((Graphic)component.Text).color = Color32.op_Implicit(new Color32((byte)235, (byte)10, (byte)10, byte.MaxValue));
				}
			}
			currentPurchase = item;
			if (Object.op_Implicit((Object)(object)selectedItem))
			{
				((Component)selectedItem.transform.Find("Highlight")).gameObject.SetActive(false);
			}
			selectedItem = ((Component)item).gameObject;
			selectedRow[1] = selectedItem.transform.GetSiblingIndex();
			((Component)selectedItem.transform.Find("Highlight")).gameObject.SetActive(true);
		}

		public void ClearPurchaseArea()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			foreach (Transform item in PurchaseItemObject.transform)
			{
				Transform val = item;
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			foreach (Transform item2 in PurchaseCostContainer.transform)
			{
				Transform val2 = item2;
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
			currentPurchase = null;
		}

		private void OnPurchaseClicked()
		{
			OnPurchaseClicked(currentPlayer);
		}

		internal void OnPurchaseClicked(Player player)
		{
			if ((Object)(object)currentPurchase != (Object)null && player.GetAdditionalData().bankAccount.HasFunds(currentPurchase.Purchasable.Cost) && currentPurchase.IsItemPurchasable(currentPlayer))
			{
				NetworkingManager.RPC(typeof(Shop), "URPCA_Purchase", new object[3] { ID, player.playerID, currentPurchase.ID });
				currentPurchase = null;
				ClearPurchaseArea();
			}
		}

		[UnboundRPC]
		private static void URPCA_Purchase(string shopID, int playerId, string purchase)
		{
			Player playerWithID = PlayerManager.instance.GetPlayerWithID(playerId);
			Shop shop = ShopManager.instance.Shops[shopID];
			ShopItem shopItem = shop._items[purchase];
			playerWithID.GetAdditionalData().bankAccount.Withdraw(shopItem.Purchasable.Cost);
			shop.UpdateMoney();
			shopItem.OnPurchase(playerWithID);
			if (shop.itemPurchasedAction != null)
			{
				try
				{
					shop.itemPurchasedAction(playerWithID, shopItem);
				}
				catch (Exception ex)
				{
					Debug.LogException(ex);
				}
			}
			shop.UpdateItems();
		}

		private void Start()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			((UnityEvent<string>)(object)Filter.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				UpdateFilters();
			});
			ButtonInteraction buttonInteraction = ((Component)PurchaseButton).gameObject.AddComponent<ButtonInteraction>();
			buttonInteraction.mouseClick.AddListener(new UnityAction(OnPurchaseClicked));
		}

		private int GetColumnMax(int column)
		{
			int result = 0;
			switch (column)
			{
			case 0:
			{
				TagItem[] source2 = (from item in TagContainer.GetComponentsInChildren<TagItem>()
					where ((Component)item).gameObject.activeSelf
					select item).ToArray();
				result = source2.Count();
				break;
			}
			case 1:
			{
				ShopItem[] source = (from item in ItemContainer.GetComponentsInChildren<ShopItem>()
					where ((Component)item).gameObject.activeSelf
					select item).ToArray();
				result = source.Count() - 1;
				break;
			}
			}
			return result;
		}

		private bool ActionWasPressed(PlayerActions playerActions)
		{
			//IL_0018: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (((TwoAxisInputControl)playerActions.Move).WasPressed)
			{
				lastDirection = new Vector2(((TwoAxisInputControl)playerActions.Move).Value.x, ((TwoAxisInputControl)playerActions.Move).Value.y * -1f);
			}
			return ((TwoAxisInputControl)playerActions.Move).WasPressed || ((OneAxisInputControl)playerActions.Jump).WasPressed;
		}

		private bool ActionHeldDown(PlayerActions playerActions)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_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)
			if (((TwoAxisInputControl)playerActions.Move).IsPressed && !((TwoAxisInputControl)playerActions.Move).WasPressed)
			{
				timeHeld += TimeHandler.deltaTime;
				if ((!finishedDelay && timeHeld > delay) || (finishedDelay && timeHeld > spacing))
				{
					timeHeld = 0f;
					finishedDelay = true;
					lastDirection = new Vector2(((TwoAxisInputControl)playerActions.Move).Value.x, ((TwoAxisInputControl)playerActions.Move).Value.y * -1f);
					return true;
				}
				lastDirection = Vector2.zero;
			}
			return false;
		}

		private void CheckForReleasedActions(PlayerActions playerActions)
		{
			//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)
			if (((TwoAxisInputControl)playerActions.Move).WasReleased)
			{
				finishedDelay = false;
				lastDirection = Vector2.zero;
			}
		}

		private GameObject GetSelectedItem()
		{
			GameObject val = null;
			switch (selectedColumn)
			{
			case 0:
			{
				if (selectedRow[selectedColumn] == 0)
				{
					val = ((Component)Filter).gameObject;
					break;
				}
				TagItem[] array2 = (from item in TagContainer.GetComponentsInChildren<TagItem>()
					where ((Component)item).gameObject.activeSelf
					select item).ToArray();
				val = ((Component)array2[selectedRow[selectedColumn] - 1]).gameObject;
				((Component)TagContainer.transform.parent.parent).gameObject.GetComponent<ScrollRect>().VerticalScrollToChild(val);
				break;
			}
			case 1:
			{
				ShopItem[] array = (from item in ItemContainer.GetComponentsInChildren<ShopItem>()
					where ((Component)item).gameObject.activeSelf
					select item).ToArray();
				val = ((Component)array[selectedRow[selectedColumn]]).gameObject;
				((Component)ItemContainer.transform.parent.parent).gameObject.GetComponent<ScrollRect>().VerticalScrollToChild(val);
				break;
			}
			case 2:
				val = ((Component)PurchaseButton).gameObject;
				break;
			}
			return val;
		}

		private void HandleControllerMovement(Player player)
		{
			PlayerActions playerActions = player.data.playerActions;
			CheckForReleasedActions(playerActions);
			if ((!ActionWasPressed(playerActions) && !ActionHeldDown(playerActions)) || Filter.isFocused)
			{
				return;
			}
			if ((Object)(object)selectedItem != (Object)null)
			{
				int num = Mathf.Clamp((int)(lastDirection.x * 10f), -1, 1);
				int num2 = Mathf.Clamp((int)(lastDirection.y * 10f), -1, 1);
				selectedColumn += num;
				selectedColumn = Mathf.Clamp(selectedColumn, 0, 2);
				selectedRow[selectedColumn] += num2;
				selectedRow[selectedColumn] = Mathf.Clamp(selectedRow[selectedColumn], 0, GetColumnMax(selectedColumn));
			}
			GameObject val = GetSelectedItem();
			if ((Object)(object)val != (Object)null && (Object)(object)selectedItem != (Object)null && (Object)(object)val != (Object)(object)selectedItem)
			{
				((Component)selectedItem.transform.Find("Highlight")).gameObject.SetActive(false);
				selectedItem = null;
				EventSystem.current.SetSelectedGameObject((GameObject)null);
			}
			selectedItem = val;
			((Component)selectedItem.transform.Find("Highlight")).gameObject.SetActive(true);
			if (!((OneAxisInputControl)playerActions.Jump).WasPressed)
			{
				return;
			}
			switch (selectedColumn)
			{
			case 0:
			{
				if (selectedRow[selectedColumn] == 0)
				{
					((Selectable)Filter).Select();
					Filter.ActivateInputField();
					break;
				}
				UnityEvent mouseClick2 = selectedItem.GetComponent<ButtonInteraction>().mouseClick;
				if (mouseClick2 != null)
				{
					mouseClick2.Invoke();
				}
				break;
			}
			case 1:
			{
				UnityEvent mouseClick3 = selectedItem.GetComponent<ButtonInteraction>().mouseClick;
				if (mouseClick3 != null)
				{
					mouseClick3.Invoke();
				}
				break;
			}
			case 2:
			{
				UnityEvent mouseClick = selectedItem.GetComponent<ButtonInteraction>().mouseClick;
				if (mouseClick != null)
				{
					mouseClick.Invoke();
				}
				break;
			}
			}
		}

		private void Update()
		{
			if ((Object)(object)currentPlayer != (Object)null)
			{
				HandleControllerMovement(currentPlayer);
			}
		}
	}
	public class ShopItem : MonoBehaviour
	{
		private ButtonInteraction interact;

		private Shop shop;

		private TextMeshProUGUI _text;

		private GameObject _highlight = null;

		private GameObject _darken = null;

		internal int _timesPurchased = 0;

		internal Dictionary<Player, int> _timesPlayerPurchased = new Dictionary<Player, int>();

		internal string ID;

		internal TextMeshProUGUI Text
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_text))
				{
					_text = ((Component)((Component)this).gameObject.transform.Find("Name")).GetComponent<TextMeshProUGUI>();
				}
				return _text;
			}
		}

		internal GameObject Highlight
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_highlight))
				{
					_highlight = ((Component)((Component)this).transform.Find("Highlight")).gameObject;
				}
				return _highlight;
			}
		}

		internal GameObject Darken
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_darken))
				{
					_darken = ((Component)((Component)this).transform.Find("Darken")).gameObject;
				}
				return _darken;
			}
		}

		public Purchasable Purchasable { get; internal set; }

		public PurchaseLimit PurchaseLimit { get; internal set; }

		public int TimesPurchased => _timesPurchased;

		public ReadOnlyDictionary<Player, int> TimesPlayerPurchased => new ReadOnlyDictionary<Player, int>(_timesPlayerPurchased);

		internal void OnPurchase(Player player)
		{
			_timesPurchased++;
			if (_timesPlayerPurchased.TryGetValue(player, out var value))
			{
				_timesPlayerPurchased[player] = value + 1;
			}
			else
			{
				_timesPlayerPurchased.Add(player, 1);
			}
			Purchasable.OnPurchase(player, Purchasable);
		}

		public bool IsItemPurchasable(Player player = null)
		{
			bool result = Purchasable.CanPurchase(player);
			if (Object.op_Implicit((Object)(object)player) && PurchaseLimit.perPlayer > 0 && TimesPlayerPurchased.TryGetValue(player, out var value) && value >= PurchaseLimit.perPlayer)
			{
				result = false;
			}
			if (PurchaseLimit.global > 0 && TimesPurchased >= PurchaseLimit.global)
			{
				result = false;
			}
			return result;
		}

		public void UpdateDisplayName(string name)
		{
			((TMP_Text)Text).text = name;
		}

		public void ResetPurchases()
		{
			_timesPurchased = 0;
			_timesPlayerPurchased.Clear();
		}

		private void Start()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			interact = ((Component)this).gameObject.GetComponent<ButtonInteraction>();
			shop = ((Component)this).gameObject.GetComponentInParent<Shop>();
			if (!Object.op_Implicit((Object)(object)interact) || !Object.op_Implicit((Object)(object)shop))
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				interact.mouseClick.AddListener(new UnityAction(OnClick));
			}
		}

		private void OnClick()
		{
			shop.OnItemClicked(this);
		}
	}
	public class ShopManager : MonoBehaviour
	{
		public static ShopManager instance;

		internal Dictionary<string, Shop> _shops = new Dictionary<string, Shop>();

		internal GameObject shopCanvas;

		private GameObject shopTemplate;

		internal GameObject shopItemTemplate;

		internal GameObject tagObjectTemplate;

		internal GameObject costObjectTemplate;

		internal GameObject cardContainerTemplate;

		internal Sprite checkmark;

		internal Sprite xmark;

		public static bool isLockingInput
		{
			get
			{
				if ((Object)(object)instance == (Object)null || instance.Shops.Count() <= 0)
				{
					return false;
				}
				return instance.Shops.Values.Any((Shop shop) => ((Component)shop).gameObject.activeSelf);
			}
		}

		public ReadOnlyDictionary<string, Shop> Shops => new ReadOnlyDictionary<string, Shop>(_shops);

		public Shop CurrentShop { get; internal set; }

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

		private void Start()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			shopCanvas = Object.Instantiate<GameObject>(ItemShops.instance.assets.LoadAsset<GameObject>("ShopCanvas"));
			Object.DontDestroyOnLoad((Object)(object)shopCanvas);
			RectTransform orAddComponent = ExtensionMethods.GetOrAddComponent<RectTransform>(shopCanvas, false);
			((Transform)orAddComponent).localScale = Vector3.one;
			shopCanvas.GetComponent<Canvas>().worldCamera = Camera.current;
			shopTemplate = ItemShops.instance.assets.LoadAsset<GameObject>("Shop");
			tagObjectTemplate = ItemShops.instance.assets.LoadAsset<GameObject>("Tag Object");
			costObjectTemplate = ItemShops.instance.assets.LoadAsset<GameObject>("Cost Object");
			shopItemTemplate = ItemShops.instance.assets.LoadAsset<GameObject>("Shop Item");
			cardContainerTemplate = ItemShops.instance.assets.LoadAsset<GameObject>("Card Container");
			checkmark = ItemShops.instance.assets.LoadAsset<Sprite>("checkmark");
			xmark = ItemShops.instance.assets.LoadAsset<Sprite>("xmark");
		}

		public Shop CreateShop(string id)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (_shops.ContainsKey(id))
			{
				throw new ArgumentException("ShopManager::CreateShop(string id) expects a unique id.");
			}
			Shop shop = null;
			GameObject val = Object.Instantiate<GameObject>(shopTemplate, shopCanvas.transform);
			((Transform)ExtensionMethods.GetOrAddComponent<RectTransform>(val, false)).localScale = Vector3.one;
			shop = val.AddComponent<Shop>();
			shop.UpdateTitle(id);
			shop.ID = id;
			_shops.Add(id, shop);
			shop.Hide();
			return shop;
		}

		public void RemoveShop(Shop shop)
		{
			_shops.Remove(shop.ID);
			Object.Destroy((Object)(object)((Component)shop).gameObject);
		}

		public void DestroyAllShops()
		{
			Shop[] array = Shops.Values.ToArray();
			_shops.Clear();
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				Object.Destroy((Object)(object)((Component)shop).gameObject);
			}
		}

		public void HideAllShops()
		{
			foreach (Shop value in Shops.Values)
			{
				value.Hide();
			}
		}

		public void HideAllShops(Player player)
		{
			foreach (Shop value in Shops.Values)
			{
				if ((Object)(object)value.CurrentPlayer == (Object)(object)player)
				{
					value.Hide();
				}
			}
		}

		public bool PlayerIsInShop(Player player)
		{
			Hashtable customProperties = player.data.view.Owner.CustomProperties;
			if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"ItemShops-InShop", out object value))
			{
				return (bool)value;
			}
			return false;
		}

		private Dictionary<string, int> GetLocalPlayersInShops()
		{
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			KeyValuePair<string, Shop>[] array = Shops.ToArray();
			KeyValuePair<string, Shop>[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				KeyValuePair<string, Shop> keyValuePair = array2[i];
				if (((Component)keyValuePair.Value).gameObject.activeSelf && Object.op_Implicit((Object)(object)keyValuePair.Value.CurrentPlayer) && keyValuePair.Value.CurrentPlayer.data.view.IsMine)
				{
					dictionary.Add(keyValuePair.Key, keyValuePair.Value.CurrentPlayer.playerID);
				}
			}
			return dictionary;
		}
	}
	public struct Tag
	{
		public readonly string name;

		public Tag(string name)
		{
			this.name = name.ToUpper();
		}
	}
	internal class TagItem : MonoBehaviour
	{
		public Tag Tag;

		private ButtonInteraction interact;

		private Shop shop;

		private Image stateImage;

		private FilterState _currentState = FilterState.Allowed;

		private GameObject _highlight = null;

		public FilterState FilterState => _currentState;

		internal GameObject Highlight
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_highlight))
				{
					_highlight = ((Component)((Component)this).transform.Find("Highlight")).gameObject;
				}
				return _highlight;
			}
		}

		private void Start()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			interact = ((Component)this).gameObject.GetComponent<ButtonInteraction>();
			shop = ((Component)this).gameObject.GetComponentInParent<Shop>();
			if (!Object.op_Implicit((Object)(object)interact) || !Object.op_Implicit((Object)(object)shop))
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			interact.mouseClick.AddListener(new UnityAction(OnClick));
			stateImage = ((Component)((Component)this).transform.Find("Tag Container/State Image")).gameObject.GetComponent<Image>();
			((Graphic)stateImage).color = Color.clear;
		}

		private void OnDestroy()
		{
		}

		private void OnClick()
		{
			//IL_003b: 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_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_00ca: Unknown result type (might be due to invalid IL or missing references)
			switch (_currentState)
			{
			case FilterState.Allowed:
				_currentState = FilterState.Required;
				((Graphic)stateImage).color = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)10, (byte)176));
				stateImage.sprite = ShopManager.instance.checkmark;
				shop.UpdateFilters();
				break;
			case FilterState.Required:
				_currentState = FilterState.Excluded;
				((Graphic)stateImage).color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)31, (byte)0, (byte)176));
				stateImage.sprite = ShopManager.instance.xmark;
				shop.UpdateFilters();
				break;
			case FilterState.Excluded:
				_currentState = FilterState.Allowed;
				((Graphic)stateImage).color = Color.clear;
				shop.UpdateFilters();
				break;
			}
		}

		internal void SetState(FilterState state)
		{
			//IL_0036: 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_007b: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			switch (state)
			{
			case FilterState.Allowed:
				_currentState = FilterState.Required;
				((Graphic)stateImage).color = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)10, (byte)176));
				stateImage.sprite = ShopManager.instance.checkmark;
				break;
			case FilterState.Required:
				_currentState = FilterState.Required;
				((Graphic)stateImage).color = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)10, (byte)176));
				stateImage.sprite = ShopManager.instance.checkmark;
				break;
			case FilterState.Excluded:
				_currentState = FilterState.Excluded;
				((Graphic)stateImage).color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)31, (byte)0, (byte)176));
				stateImage.sprite = ShopManager.instance.xmark;
				break;
			}
		}
	}
	public enum FilterState
	{
		Allowed,
		Required,
		Excluded
	}
}
namespace ItemShops.Patches
{
	[HarmonyPatch(typeof(CardChoice))]
	internal class CardChoice_Patch
	{
		[HarmonyPatch("DoPlayerSelect")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix()
		{
			return !ShopManager.isLockingInput;
		}
	}
	[HarmonyPatch(typeof(CardRarityColor))]
	internal class CardRarityColor_Patch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static bool CheckOnAwake(CardRarityColor __instance)
		{
			CardVisuals componentInParent = ((Component)__instance).GetComponentInParent<CardVisuals>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				componentInParent.toggleSelectionAction = (Action<bool>)Delegate.Combine(componentInParent.toggleSelectionAction, new Action<bool>(__instance.Toggle));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EscapeMenuHandler))]
	internal class EscMenu_Patch
	{
		[HarmonyPrefix]
		[HarmonyPatch("ToggleEsc")]
		private static bool CheckShopStatus()
		{
			bool isLockingInput = ShopManager.isLockingInput;
			if (isLockingInput)
			{
				if (Object.op_Implicit((Object)(object)ShopManager.instance.CurrentShop) && ShopManager.instance.CurrentShop.filterSelected)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				else
				{
					ShopManager.instance.HideAllShops();
				}
			}
			return !isLockingInput;
		}
	}
}
namespace ItemShops.Monobehaviours
{
	public class ButtonInteraction : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler
	{
		public UnityEvent mouseClick = new UnityEvent();

		public UnityEvent mouseEnter = new UnityEvent();

		public UnityEvent mouseExit = new UnityEvent();

		public Selectable button;

		public AudioSource source;

		private Random random = new Random();

		private void Start()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			button = (Selectable)(object)((Component)this).gameObject.GetComponent<Button>();
			source = ExtensionMethods.GetOrAddComponent<AudioSource>(((Component)this).gameObject, false);
			mouseEnter.AddListener(new UnityAction(OnEnter));
			mouseExit.AddListener(new UnityAction(OnExit));
			mouseClick.AddListener(new UnityAction(OnClick));
		}

		public void OnEnter()
		{
			if (button.interactable)
			{
				source.PlayOneShot(ItemShops.instance.hover[random.Next(ItemShops.instance.hover.Count)]);
			}
		}

		public void OnExit()
		{
			if (button.interactable)
			{
				source.PlayOneShot(ItemShops.instance.hover[random.Next(ItemShops.instance.hover.Count)]);
			}
		}

		public void OnClick()
		{
			if (button.interactable)
			{
				source.PlayOneShot(ItemShops.instance.click[random.Next(ItemShops.instance.click.Count)]);
				EventSystem.current.SetSelectedGameObject((GameObject)null);
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (button.interactable)
			{
				UnityEvent obj = mouseEnter;
				if (obj != null)
				{
					obj.Invoke();
				}
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			if (button.interactable)
			{
				UnityEvent obj = mouseExit;
				if (obj != null)
				{
					obj.Invoke();
				}
			}
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			if (button.interactable)
			{
				UnityEvent obj = mouseClick;
				if (obj != null)
				{
					obj.Invoke();
				}
			}
		}
	}
}
namespace ItemShops.Interfaces
{
	public class InterfaceGameModeHooksManager : MonoBehaviour
	{
		private List<IGameStartHookHandler> gameStartHooks = new List<IGameStartHookHandler>();

		private List<IGameEndHookHandler> gameEndHooks = new List<IGameEndHookHandler>();

		private List<IPlayerPickEndHookHandler> playerPickEndHooks = new List<IPlayerPickEndHookHandler>();

		private List<IPlayerPickStartHookHandler> playerPickStartHooks = new List<IPlayerPickStartHookHandler>();

		private List<IPickStartHookHandler> pickStartHooks = new List<IPickStartHookHandler>();

		private List<IPickEndHookHandler> pickEndHooks = new List<IPickEndHookHandler>();

		private List<IPointStartHookHandler> pointStartHooks = new List<IPointStartHookHandler>();

		private List<IPointEndHookHandler> pointEndHooks = new List<IPointEndHookHandler>();

		private List<IRoundStartHookHandler> roundStartHooks = new List<IRoundStartHookHandler>();

		private List<IRoundEndHookHandler> roundEndHooks = new List<IRoundEndHookHandler>();

		private List<IBattleStartHookHandler> battleStartHooks = new List<IBattleStartHookHandler>();

		public static InterfaceGameModeHooksManager instance { get; private set; }

		private void Start()
		{
			if ((Object)(object)instance != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)this);
				return;
			}
			instance = this;
			GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)GameEnd);
			GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)GameStart);
			GameModeManager.AddHook("BattleStart", (Func<IGameModeHandler, IEnumerator>)BattleStart);
			GameModeManager.AddHook("PlayerPickStart", (Func<IGameModeHandler, IEnumerator>)PlayerPickStart);
			GameModeManager.AddHook("PlayerPickEnd", (Func<IGameModeHandler, IEnumerator>)PlayerPickEnd);
			GameModeManager.AddHook("PointStart", (Func<IGameModeHandler, IEnumerator>)PointStart);
			GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)PointEnd);
			GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)PickStart);
			GameModeManager.AddHook("PickEnd", (Func<IGameModeHandler, IEnumerator>)PickEnd);
			GameModeManager.AddHook("RoundStart", (Func<IGameModeHandler, IEnumerator>)RoundStart);
			GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)RoundEnd);
		}

		public void RegisterHooks(object obj)
		{
			if (obj is IGameEndHookHandler item)
			{
				gameEndHooks.Add(item);
			}
			if (obj is IGameStartHookHandler item2)
			{
				gameStartHooks.Add(item2);
			}
			if (obj is IRoundEndHookHandler item3)
			{
				roundEndHooks.Add(item3);
			}
			if (obj is IRoundStartHookHandler item4)
			{
				roundStartHooks.Add(item4);
			}
			if (obj is IPointStartHookHandler item5)
			{
				pointStartHooks.Add(item5);
			}
			if (obj is IPointEndHookHandler item6)
			{
				pointEndHooks.Add(item6);
			}
			if (obj is IBattleStartHookHandler item7)
			{
				battleStartHooks.Add(item7);
			}
			if (obj is IPickStartHookHandler item8)
			{
				pickStartHooks.Add(item8);
			}
			if (obj is IPickEndHookHandler item9)
			{
				pickEndHooks.Add(item9);
			}
			if (obj is IPlayerPickStartHookHandler item10)
			{
				playerPickStartHooks.Add(item10);
			}
			if (obj is IPlayerPickEndHookHandler item11)
			{
				playerPickEndHooks.Add(item11);
			}
		}

		public void RemoveHooks(object obj)
		{
			if (obj is IGameEndHookHandler item)
			{
				gameEndHooks.Remove(item);
			}
			if (obj is IGameStartHookHandler item2)
			{
				gameStartHooks.Remove(item2);
			}
			if (obj is IRoundEndHookHandler item3)
			{
				roundEndHooks.Remove(item3);
			}
			if (obj is IRoundStartHookHandler item4)
			{
				roundStartHooks.Remove(item4);
			}
			if (obj is IPointStartHookHandler item5)
			{
				pointStartHooks.Remove(item5);
			}
			if (obj is IPointEndHookHandler item6)
			{
				pointEndHooks.Remove(item6);
			}
			if (obj is IBattleStartHookHandler item7)
			{
				battleStartHooks.Remove(item7);
			}
			if (obj is IPickStartHookHandler item8)
			{
				pickStartHooks.Remove(item8);
			}
			if (obj is IPickEndHookHandler item9)
			{
				pickEndHooks.Remove(item9);
			}
			if (obj is IPlayerPickStartHookHandler item10)
			{
				playerPickStartHooks.Remove(item10);
			}
			if (obj is IPlayerPickEndHookHandler item11)
			{
				playerPickEndHooks.Remove(item11);
			}
		}

		private IEnumerator GameStart(IGameModeHandler gm)
		{
			foreach (IGameStartHookHandler hook in gameStartHooks)
			{
				hook.OnGameStart();
			}
			yield break;
		}

		private IEnumerator GameEnd(IGameModeHandler gm)
		{
			foreach (IGameEndHookHandler hook in gameEndHooks)
			{
				hook.OnGameEnd();
			}
			yield break;
		}

		private IEnumerator RoundStart(IGameModeHandler gm)
		{
			foreach (IRoundStartHookHandler hook in roundStartHooks)
			{
				hook.OnRoundStart();
			}
			yield break;
		}

		private IEnumerator RoundEnd(IGameModeHandler gm)
		{
			foreach (IRoundEndHookHandler hook in roundEndHooks)
			{
				hook.OnRoundEnd();
			}
			yield break;
		}

		private IEnumerator PointStart(IGameModeHandler gm)
		{
			foreach (IPointStartHookHandler hook in pointStartHooks)
			{
				hook.OnPointStart();
			}
			yield break;
		}

		private IEnumerator PointEnd(IGameModeHandler gm)
		{
			foreach (IPointEndHookHandler hook in pointEndHooks)
			{
				hook.OnPointEnd();
			}
			yield break;
		}

		private IEnumerator BattleStart(IGameModeHandler gm)
		{
			foreach (IBattleStartHookHandler hook in battleStartHooks)
			{
				hook.OnBattleStart();
			}
			yield break;
		}

		private IEnumerator PickStart(IGameModeHandler gm)
		{
			foreach (IPickStartHookHandler hook in pickStartHooks)
			{
				hook.OnPickStart();
			}
			yield break;
		}

		private IEnumerator PickEnd(IGameModeHandler gm)
		{
			foreach (IPickEndHookHandler hook in pickEndHooks)
			{
				hook.OnPickEnd();
			}
			yield break;
		}

		private IEnumerator PlayerPickStart(IGameModeHandler gm)
		{
			foreach (IPlayerPickStartHookHandler hook in playerPickStartHooks)
			{
				hook.OnPlayerPickStart();
			}
			yield break;
		}

		private IEnumerator PlayerPickEnd(IGameModeHandler gm)
		{
			foreach (IPlayerPickEndHookHandler hook in playerPickEndHooks)
			{
				hook.OnPlayerPickEnd();
			}
			yield break;
		}
	}
	internal interface IGameStartHookHandler
	{
		void OnGameStart();
	}
	internal interface IGameEndHookHandler
	{
		void OnGameEnd();
	}
	internal interface IPlayerPickStartHookHandler
	{
		void OnPlayerPickStart();
	}
	internal interface IPlayerPickEndHookHandler
	{
		void OnPlayerPickEnd();
	}
	internal interface IPointEndHookHandler
	{
		void OnPointEnd();
	}
	internal interface IPointStartHookHandler
	{
		void OnPointStart();
	}
	internal interface IRoundEndHookHandler
	{
		void OnRoundEnd();
	}
	internal interface IRoundStartHookHandler
	{
		void OnRoundStart();
	}
	internal interface IPickStartHookHandler
	{
		void OnPickStart();
	}
	internal interface IPickEndHookHandler
	{
		void OnPickEnd();
	}
	internal interface IBattleStartHookHandler
	{
		void OnBattleStart();
	}
}
namespace ItemShops.Extensions
{
	[Serializable]
	public class PlayerAdditionalData
	{
		public BankAccount bankAccount;

		public PlayerAdditionalData()
		{
			bankAccount = new BankAccount();
		}
	}
	public static class PlayerExtension
	{
		public static readonly ConditionalWeakTable<Player, PlayerAdditionalData> data = new ConditionalWeakTable<Player, PlayerAdditionalData>();

		public static PlayerAdditionalData GetAdditionalData(this Player player)
		{
			return data.GetOrCreateValue(player);
		}

		public static void AddData(this Player player, PlayerAdditionalData value)
		{
			try
			{
				data.Add(player, value);
			}
			catch (Exception)
			{
			}
		}
	}
	public static class PlayerManagerExtension
	{
		public static Player GetRandomEnemy(this PlayerManager playerManager, Player player)
		{
			if (playerManager.players.Count == 1)
			{
				return null;
			}
			List<Player> list = new List<Player>(playerManager.players);
			Player[] playersInTeam = playerManager.GetPlayersInTeam(player.teamID);
			foreach (Player item in playersInTeam)
			{
				list.Remove(item);
			}
			return list[Random.Range(0, list.Count)];
		}

		public static Player GetPlayerWithID(this PlayerManager playerManager, int playerID)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			return (Player)typeof(PlayerManager).InvokeMember("GetPlayerWithID", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, playerManager, new object[1] { playerID });
		}
	}
	public static class ScrollRectExtension
	{
		public static void VerticalScrollToChild(this ScrollRect scrollRect, GameObject child)
		{
			//IL_000e: 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_0030: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = child.GetComponent<RectTransform>();
			float y = ((Component)scrollRect).GetComponent<RectTransform>().sizeDelta.y;
			float num = Mathf.Abs(component.anchoredPosition.y);
			float num2 = 1f - component.pivot.y;
			float y2 = component.sizeDelta.y;
			float y3 = scrollRect.content.sizeDelta.y;
			float num3 = num - (0.5f - num2) * y2;
			float num4 = y3 - y;
			float value = 1f - (num3 / num4 - y / 2f / num4);
			scrollRect.verticalScrollbar.value = value;
		}
	}
}
namespace System
{
	public static class ObjectExtensions
	{
		private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);

		public static bool IsPrimitive(this Type type)
		{
			if (type == typeof(string))
			{
				return true;
			}
			return type.IsValueType & type.IsPrimitive;
		}

		public static object Copy(this object originalObject)
		{
			return InternalCopy(originalObject, new Dictionary<object, object>(new ReferenceEqualityComparer()));
		}

		private static object InternalCopy(object originalObject, IDictionary<object, object> visited)
		{
			if (originalObject == null)
			{
				return null;
			}
			Type type = originalObject.GetType();
			if (type.IsPrimitive())
			{
				return originalObject;
			}
			if (visited.ContainsKey(originalObject))
			{
				return visited[originalObject];
			}
			if (typeof(Delegate).IsAssignableFrom(type))
			{
				return null;
			}
			object obj = CloneMethod.Invoke(originalObject, null);
			if (type.IsArray)
			{
				Type elementType = type.GetElementType();
				if (!elementType.IsPrimitive())
				{
					Array clonedArray = (Array)obj;
					clonedArray.ForEach(delegate(Array array, int[] indices)
					{
						array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices);
					});
				}
			}
			visited.Add(originalObject, obj);
			CopyFields(originalObject, visited, obj, type);
			RecursiveCopyBaseTypePrivateFields(originalObject, visited, obj, type);
			return obj;
		}

		private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary<object, object> visited, object cloneObject, Type typeToReflect)
		{
			if (typeToReflect.BaseType != null)
			{
				RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
				CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, (FieldInfo info) => info.IsPrivate);
			}
		}

		private static void CopyFields(object originalObject, IDictionary<object, object> visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy, Func<FieldInfo, bool> filter = null)
		{
			FieldInfo[] fields = typeToReflect.GetFields(bindingFlags);
			foreach (FieldInfo fieldInfo in fields)
			{
				if ((filter == null || filter(fieldInfo)) && !fieldInfo.FieldType.IsPrimitive())
				{
					object value = fieldInfo.GetValue(originalObject);
					object value2 = InternalCopy(value, visited);
					fieldInfo.SetValue(cloneObject, value2);
				}
			}
		}

		public static T Copy<T>(this T original)
		{
			return (T)((object)original).Copy();
		}
	}
	public class ReferenceEqualityComparer : EqualityComparer<object>
	{
		public override bool Equals(object x, object y)
		{
			return x == y;
		}

		public override int GetHashCode(object obj)
		{
			return obj?.GetHashCode() ?? 0;
		}
	}
}
namespace System.ArrayExtensions
{
	public static class ArrayExtensions
	{
		public static void ForEach(this Array array, Action<Array, int[]> action)
		{
			if (array.LongLength != 0)
			{
				ArrayTraverse arrayTraverse = new ArrayTraverse(array);
				do
				{
					action(array, arrayTraverse.Position);
				}
				while (arrayTraverse.Step());
			}
		}
	}
	internal class ArrayTraverse
	{
		public int[] Position;

		private int[] maxLengths;

		public ArrayTraverse(Array array)
		{
			maxLengths = new int[array.Rank];
			for (int i = 0; i < array.Rank; i++)
			{
				maxLengths[i] = array.GetLength(i) - 1;
			}
			Position = new int[array.Rank];
		}

		public bool Step()
		{
			for (int i = 0; i < Position.Length; i++)
			{
				if (Position[i] < maxLengths[i])
				{
					Position[i]++;
					for (int j = 0; j < i; j++)
					{
						Position[j] = 0;
					}
					return true;
				}
			}
			return false;
		}
	}
}