Decompiled source of More Slots v1.2.0

plugins\Games\MoreSlots\MoreSlots.dll

Decompiled 12 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using FMOD.Studio;
using FMODUnity;
using Mirror;
using MoreMountains.Feedbacks;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace GWYFCustom
{
	public abstract class GameCoreBase : GameBase
	{
		protected Random serverRng = new Random(Environment.TickCount * 31 + 17);

		private Coroutine resetRoutine;

		private Coroutine finishRoutine;

		public GameObject rulesPanel;

		private bool infoShown;

		public override bool Weaved()
		{
			return true;
		}

		protected override void OnAwake()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			((GameBase)this).OnAwake();
			base.gameType = (CasinoGameType)12;
			if (string.IsNullOrEmpty(base.gameName))
			{
				base.gameName = ((object)this).GetType().Name;
			}
			MMFloatingTextSpawner componentInChildren = ((Component)this).GetComponentInChildren<MMFloatingTextSpawner>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)componentInChildren);
			}
		}

		protected void BroadcastString(string rpcMethodName, string payload)
		{
			if (NetworkServer.active)
			{
				string text = "System.Void " + ((object)this).GetType().FullName + "::" + rpcMethodName + "(System.String)";
				int stableHashCode = Extensions.GetStableHashCode(text);
				NetworkWriterPooled val = NetworkWriterPool.Get();
				NetworkWriterExtensions.WriteString((NetworkWriter)(object)val, payload);
				((NetworkBehaviour)this).SendRPCInternal(text, stableHashCode, (NetworkWriter)(object)val, 0, true);
				NetworkWriterPool.Return(val);
			}
		}

		protected void FinishRound(float multiplier, float delay)
		{
			if (((NetworkBehaviour)this).isServer)
			{
				if (finishRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(finishRoutine);
				}
				finishRoutine = ((MonoBehaviour)this).StartCoroutine(FinishRoundRoutine(multiplier, delay));
			}
		}

		private IEnumerator FinishRoundRoutine(float multiplier, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			finishRoutine = null;
			base.isPlaying = false;
			((GameBase)this).Payout((double)multiplier, (ChangeType)1, (Dictionary<string, object>)null, (BigNumber?)null);
			resetRoutine = ((MonoBehaviour)this).StartCoroutine(ResetRoundRoutine());
		}

		private IEnumerator ResetRoundRoutine()
		{
			yield return (object)new WaitForSeconds(2f);
			BroadcastString("UserRpcResetVisuals", "reset");
			resetRoutine = null;
			((GameBase)this).ResetGame();
		}

		protected void GuardStuckReset()
		{
			if (resetRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(resetRoutine);
				resetRoutine = null;
				BroadcastString("UserRpcResetVisuals", "reset");
				((GameBase)this).ResetGame();
			}
		}

		public void UserRpcResetVisuals(string networkText)
		{
			if (NetworkClient.active)
			{
				OnClientResetVisuals();
			}
		}

		protected abstract void OnClientResetVisuals();

		[Server]
		public void ToggleInfo(PlayerInteract interact = null)
		{
			if (NetworkServer.active)
			{
				infoShown = !infoShown;
				BroadcastString("UserRpcToggleInfo", infoShown ? "1" : "0");
			}
		}

		public void UserRpcToggleInfo(string networkText)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkClient.active)
			{
				if ((Object)(object)rulesPanel != (Object)null)
				{
					rulesPanel.SetActive(networkText == "1");
				}
				Sfx.Play(((Component)this).transform.position, "KeypadButton", "Button");
			}
		}

		protected int WeightedIndex(int[] weights)
		{
			return PureRng.WeightedIndex(serverRng, weights);
		}

		protected static string F(float v)
		{
			return v.ToString("0.###", CultureInfo.InvariantCulture);
		}

		protected static float PF(string s)
		{
			float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var result);
			return result;
		}

		protected static int PI(string s)
		{
			int.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out var result);
			return result;
		}
	}
	public static class PureRng
	{
		public static int WeightedIndex(Random rng, int[] weights)
		{
			int num = 0;
			for (int i = 0; i < weights.Length; i++)
			{
				num += weights[i];
			}
			int num2 = rng.Next(num);
			for (int j = 0; j < weights.Length; j++)
			{
				num2 -= weights[j];
				if (num2 < 0)
				{
					return j;
				}
			}
			return weights.Length - 1;
		}
	}
	public static class ScratchLogic
	{
		public static float Generate(Random rng, float[] tierMult, double[] tierProb, int[] tierSym, int symbolCount, int[] cells)
		{
			int num = cells.Length;
			double num2 = rng.NextDouble();
			double num3 = 0.0;
			int num4 = 0;
			for (int i = 0; i < tierProb.Length; i++)
			{
				num3 += tierProb[i];
				if (num2 < num3)
				{
					num4 = i;
					break;
				}
				num4 = i;
			}
			float result = tierMult[num4];
			int num5 = tierSym[num4];
			for (int j = 0; j < 200; j++)
			{
				int[] array = new int[symbolCount];
				bool flag = true;
				if (num5 >= 0)
				{
					for (int k = 0; k < num; k++)
					{
						cells[k] = -1;
					}
					int num6 = 0;
					while (num6 < 3)
					{
						int num7 = rng.Next(num);
						if (cells[num7] == -1)
						{
							cells[num7] = num5;
							num6++;
						}
					}
					array[num5] = 3;
					for (int l = 0; l < num; l++)
					{
						if (cells[l] == -1)
						{
							int num8 = PickFiller(rng, array, num5, symbolCount);
							if (num8 < 0)
							{
								flag = false;
								break;
							}
							cells[l] = num8;
							array[num8]++;
						}
					}
				}
				else
				{
					for (int m = 0; m < num; m++)
					{
						int num9 = PickFiller(rng, array, -1, symbolCount);
						if (num9 < 0)
						{
							flag = false;
							break;
						}
						cells[m] = num9;
						array[num9]++;
					}
				}
				if (flag)
				{
					return result;
				}
			}
			for (int n = 0; n < num; n++)
			{
				cells[n] = n % 2;
			}
			return 0f;
		}

		private static int PickFiller(Random rng, int[] counts, int excluded, int symbolCount)
		{
			for (int i = 0; i < 50; i++)
			{
				int num = rng.Next(symbolCount);
				if (num != excluded && counts[num] < 2)
				{
					return num;
				}
			}
			for (int j = 0; j < symbolCount; j++)
			{
				if (j != excluded && counts[j] < 2)
				{
					return j;
				}
			}
			return -1;
		}
	}
	public static class Sfx
	{
		private static List<KeyValuePair<string, EventDescription>> all;

		private static readonly Dictionary<string, EventDescription?> cache = new Dictionary<string, EventDescription?>();

		private static void EnsureLoaded()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0052: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if (all != null)
			{
				return;
			}
			all = new List<KeyValuePair<string, EventDescription>>();
			try
			{
				System studioSystem = RuntimeManager.StudioSystem;
				Bank[] array = default(Bank[]);
				((System)(ref studioSystem)).getBankList(ref array);
				Bank[] array2 = array;
				EventDescription[] array3 = default(EventDescription[]);
				string text = default(string);
				for (int i = 0; i < array2.Length; i++)
				{
					Bank val = array2[i];
					if ((int)((Bank)(ref val)).getEventList(ref array3) != 0 || array3 == null)
					{
						continue;
					}
					EventDescription[] array4 = array3;
					for (int j = 0; j < array4.Length; j++)
					{
						EventDescription value = array4[j];
						if ((int)((EventDescription)(ref value)).getPath(ref text) == 0 && !string.IsNullOrEmpty(text))
						{
							all.Add(new KeyValuePair<string, EventDescription>(text, value));
						}
					}
				}
				Debug.Log((object)("[GWYFCustom] FMOD events discovered: " + all.Count));
				foreach (KeyValuePair<string, EventDescription> item in all)
				{
					string text2 = item.Key.ToLowerInvariant();
					if (text2.Contains("slot") || text2.Contains("casino") || text2.Contains("win") || text2.Contains("button") || text2.Contains("lever") || text2.Contains("cash") || text2.Contains("keypad") || text2.Contains("spin"))
					{
						Debug.Log((object)("[GWYFCustom] FMOD event: " + item.Key));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[GWYFCustom] FMOD enumeration failed: " + ex.Message));
			}
		}

		private static EventDescription? Find(string[] candidates)
		{
			//IL_006d: 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)
			EnsureLoaded();
			string text = string.Join("|", candidates);
			if (cache.TryGetValue(text, out var value))
			{
				return value;
			}
			foreach (string text2 in candidates)
			{
				string value2 = text2.ToLowerInvariant();
				foreach (KeyValuePair<string, EventDescription> item in all)
				{
					if (item.Key.ToLowerInvariant().Contains(value2))
					{
						cache[text] = item.Value;
						Debug.Log((object)("[GWYFCustom] SFX '" + text2 + "' -> " + item.Key));
						return item.Value;
					}
				}
			}
			Debug.LogWarning((object)("[GWYFCustom] no FMOD event matches: " + text));
			cache[text] = null;
			return null;
		}

		public static void Play(Vector3 position, params string[] candidates)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			PlayParam(position, null, 0f, candidates);
		}

		public static void PlayParam(Vector3 position, string paramName, float value, params string[] candidates)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EventDescription? val = Find(candidates);
				if (!val.HasValue)
				{
					return;
				}
				EventDescription value2 = val.Value;
				EventInstance val2 = default(EventInstance);
				if ((int)((EventDescription)(ref value2)).createInstance(ref val2) == 0)
				{
					((EventInstance)(ref val2)).set3DAttributes(RuntimeUtils.To3DAttributes(position));
					if (!string.IsNullOrEmpty(paramName))
					{
						((EventInstance)(ref val2)).setParameterByName(paramName, value, false);
					}
					((EventInstance)(ref val2)).start();
					((EventInstance)(ref val2)).release();
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[GWYFCustom] SFX play failed: " + ex.Message));
			}
		}
	}
}
namespace GWYFCustom.Games
{
	public static class DeepSeaSlotsLogic
	{
		public static float Evaluate(int[] grid, out int cellMask)
		{
			int num = grid[0];
			int num2 = grid[1];
			int num3 = grid[2];
			cellMask = 0;
			if (num == num2 && num2 == num3)
			{
				cellMask = 7;
				return DeepSeaPay.PAY3[num];
			}
			int num4 = 0;
			for (int i = 0; i < 3; i++)
			{
				if (grid[i] == 5)
				{
					num4++;
					cellMask |= 1 << i;
				}
			}
			switch (num4)
			{
			case 1:
				return 1.5f;
			case 2:
				return 6f;
			default:
				cellMask = 0;
				return 0f;
			}
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[3];
			for (int i = 0; i < 3; i++)
			{
				array[i] = PureRng.WeightedIndex(rng, DeepSeaPay.WEIGHTS);
			}
			int cellMask;
			return Evaluate(array, out cellMask);
		}
	}
	public static class DeucesWildLogic
	{
		public const int NONE = 0;

		public const int THREE_KIND = 1;

		public const int STRAIGHT = 2;

		public const int FLUSH = 3;

		public const int FULL_HOUSE = 4;

		public const int FOUR_KIND = 5;

		public const int STRAIGHT_FLUSH = 6;

		public const int FIVE_KIND = 7;

		public const int WILD_ROYAL = 8;

		public const int FOUR_DEUCES = 9;

		public const int NATURAL_ROYAL = 10;

		private static int Rank(int card)
		{
			return card % 13;
		}

		private static int Suit(int card)
		{
			return card / 13;
		}

		private static bool IsWild(int card)
		{
			return card % 13 == 0;
		}

		public static int Evaluate(int[] hand, out int winMask)
		{
			winMask = 31;
			int num = 0;
			int[] array = new int[5];
			int num2 = 0;
			for (int i = 0; i < 5; i++)
			{
				if (IsWild(hand[i]))
				{
					num++;
				}
				else
				{
					array[num2++] = hand[i];
				}
			}
			if (num == 4)
			{
				return 9;
			}
			int[] array2 = new int[13];
			int num3 = 0;
			int num4 = 0;
			bool flag = true;
			bool flag2 = true;
			for (int j = 0; j < num2; j++)
			{
				int num5 = Rank(array[j]);
				array2[num5]++;
				if (array2[num5] == 1)
				{
					num4++;
				}
				if (array2[num5] > num3)
				{
					num3 = array2[num5];
				}
				if (Suit(array[j]) != Suit(array[0]))
				{
					flag = false;
				}
				if (num5 < 8)
				{
					flag2 = false;
				}
			}
			bool flag3 = num3 <= 1;
			if (num == 0 && flag && flag3 && flag2)
			{
				return 10;
			}
			if (num > 0 && flag && flag3 && flag2)
			{
				return 8;
			}
			if (num3 + num >= 5)
			{
				return 7;
			}
			if (flag && flag3 && StraightPossible(array, num2, num))
			{
				return 6;
			}
			if (num3 + num >= 4)
			{
				return 5;
			}
			if (num4 == 2)
			{
				return 4;
			}
			if (flag)
			{
				return 3;
			}
			if (flag3 && StraightPossible(array, num2, num))
			{
				return 2;
			}
			if (num3 + num >= 3)
			{
				return 1;
			}
			winMask = 0;
			return 0;
		}

		private static bool StraightPossible(int[] others, int n, int d)
		{
			for (int i = 0; i <= 8; i++)
			{
				if (AllInWindow(others, n, i, i + 4, aceLow: false))
				{
					return true;
				}
			}
			if (AllInWindow(others, n, 0, 3, aceLow: true))
			{
				return true;
			}
			return false;
		}

		private static bool AllInWindow(int[] others, int n, int lo, int hi, bool aceLow)
		{
			for (int i = 0; i < n; i++)
			{
				int num = others[i] % 13;
				if ((!aceLow || num != 12) && (num < lo || num > hi))
				{
					return false;
				}
			}
			return true;
		}

		public static int HoldMask(int[] hand)
		{
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < 5; i++)
			{
				if (IsWild(hand[i]))
				{
					num |= 1 << i;
					num2++;
				}
			}
			int winMask;
			int num3 = Evaluate(hand, out winMask);
			switch (num2)
			{
			case 4:
				return 31;
			case 3:
				if (num3 == 8 || num3 == 7)
				{
					return 31;
				}
				return num;
			case 2:
			{
				if (num3 >= 6)
				{
					return 31;
				}
				if (num3 == 5)
				{
					return num | MadeRankMask(hand);
				}
				int num12 = SuitedRoyalWith(hand, num, 2);
				if (num12 != 0)
				{
					return num12;
				}
				return num;
			}
			case 1:
				switch (num3)
				{
				case 6:
				case 7:
				case 8:
					return 31;
				case 5:
					return num | MadeRankMask(hand);
				default:
				{
					int num11 = SuitedRoyalWith(hand, num, 3);
					if (num11 != 0)
					{
						return num11;
					}
					if (num3 == 4 || num3 == 3 || num3 == 2)
					{
						return 31;
					}
					num11 = SuitedStraightDrawWith(hand, num, 3);
					if (num11 != 0)
					{
						return num11;
					}
					if (num3 == 1)
					{
						return num | MadeRankMask(hand);
					}
					num11 = SuitedRoyalWith(hand, num, 2);
					if (num11 != 0)
					{
						return num11;
					}
					return num;
				}
				}
			default:
			{
				if (num3 == 10)
				{
					return 31;
				}
				int num4 = SuitedRoyalNatural(hand, 4);
				if (num4 != 0)
				{
					return num4;
				}
				switch (num3)
				{
				case 6:
					return 31;
				case 5:
					return MadeRankMask(hand);
				case 2:
				case 3:
				case 4:
					return 31;
				case 1:
					return MadeRankMask(hand);
				default:
				{
					int num5 = SuitedRoyalNatural(hand, 3);
					if (num5 != 0)
					{
						return num5;
					}
					int num6 = OnePairMask(hand);
					if (num6 != 0)
					{
						return num6;
					}
					int num7 = SuitedStraightDrawNatural(hand, 4);
					if (num7 != 0)
					{
						return num7;
					}
					int num8 = SuitedNatural(hand, 4);
					if (num8 != 0)
					{
						return num8;
					}
					int num9 = OpenStraightDraw(hand);
					if (num9 != 0)
					{
						return num9;
					}
					int num10 = SuitedRoyalNatural(hand, 2);
					if (num10 != 0)
					{
						return num10;
					}
					return 0;
				}
				}
			}
			}
		}

		private static int MadeRankMask(int[] hand)
		{
			int[] array = new int[13];
			for (int i = 0; i < 5; i++)
			{
				if (!IsWild(hand[i]))
				{
					array[Rank(hand[i])]++;
				}
			}
			int num = -1;
			for (int j = 1; j < 13; j++)
			{
				if (num < 0 || array[j] > array[num])
				{
					num = j;
				}
			}
			int num2 = 0;
			for (int k = 0; k < 5; k++)
			{
				if (!IsWild(hand[k]) && Rank(hand[k]) == num)
				{
					num2 |= 1 << k;
				}
			}
			return num2;
		}

		private static int SuitedRoyalWith(int[] hand, int deuceMask, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				bool flag = false;
				for (int j = 0; j < 5; j++)
				{
					if (!IsWild(hand[j]) && Suit(hand[j]) == i && Rank(hand[j]) >= 8)
					{
						if ((num3 & (1 << Rank(hand[j]))) != 0)
						{
							flag = true;
							break;
						}
						num3 |= 1 << Rank(hand[j]);
						num |= 1 << j;
						num2++;
					}
				}
				if (!flag && num2 >= need)
				{
					return deuceMask | num;
				}
			}
			return 0;
		}

		private static int SuitedRoyalNatural(int[] hand, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				bool flag = false;
				int num4 = 13;
				for (int j = 0; j < 5; j++)
				{
					if (!IsWild(hand[j]) && Suit(hand[j]) == i && Rank(hand[j]) >= 8)
					{
						if ((num3 & (1 << Rank(hand[j]))) != 0)
						{
							flag = true;
							break;
						}
						num3 |= 1 << Rank(hand[j]);
						num |= 1 << j;
						num2++;
						if (Rank(hand[j]) < num4)
						{
							num4 = Rank(hand[j]);
						}
					}
				}
				if (!flag && num2 >= need && (need != 2 || num4 >= 9))
				{
					return num;
				}
			}
			return 0;
		}

		private static int SuitedStraightDrawWith(int[] hand, int deuceMask, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int[] array = new int[5];
				int num = 0;
				for (int j = 0; j < 5; j++)
				{
					if (!IsWild(hand[j]) && Suit(hand[j]) == i)
					{
						array[num++] = j;
					}
				}
				if (num < need)
				{
					continue;
				}
				for (int k = 0; k < 1 << num; k++)
				{
					int num2 = 0;
					int num3 = 0;
					int num4 = 0;
					bool flag = false;
					int[] array2 = new int[5];
					int num5 = 0;
					for (int l = 0; l < num; l++)
					{
						if ((k & (1 << l)) != 0)
						{
							int num6 = array[l];
							int num7 = Rank(hand[num6]);
							if ((num4 & (1 << num7)) != 0)
							{
								flag = true;
								break;
							}
							num4 |= 1 << num7;
							num3 |= 1 << num6;
							array2[num5++] = hand[num6];
							num2++;
						}
					}
					if (!flag && num2 == need && StraightPossible(array2, num5, 5 - num5))
					{
						return deuceMask | num3;
					}
				}
			}
			return 0;
		}

		private static int SuitedStraightDrawNatural(int[] hand, int need)
		{
			return SuitedStraightDrawWith(hand, 0, need);
		}

		private static int SuitedNatural(int[] hand, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				for (int j = 0; j < 5; j++)
				{
					if (!IsWild(hand[j]) && Suit(hand[j]) == i)
					{
						num |= 1 << j;
						num2++;
					}
				}
				if (num2 >= need)
				{
					return num;
				}
			}
			return 0;
		}

		private static int OnePairMask(int[] hand)
		{
			int[] array = new int[13];
			for (int i = 0; i < 5; i++)
			{
				if (!IsWild(hand[i]))
				{
					array[Rank(hand[i])]++;
				}
			}
			for (int num = 12; num >= 1; num--)
			{
				if (array[num] == 2)
				{
					int num2 = 0;
					for (int j = 0; j < 5; j++)
					{
						if (!IsWild(hand[j]) && Rank(hand[j]) == num)
						{
							num2 |= 1 << j;
						}
					}
					return num2;
				}
			}
			return 0;
		}

		private static int OpenStraightDraw(int[] hand)
		{
			for (int i = 0; i < 5; i++)
			{
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				bool flag = false;
				bool flag2 = false;
				int[] array = new int[5];
				int n = 0;
				for (int j = 0; j < 5; j++)
				{
					if (j != i)
					{
						if (IsWild(hand[j]))
						{
							flag2 = true;
							break;
						}
						int num4 = Rank(hand[j]);
						if ((num3 & (1 << num4)) != 0)
						{
							flag = true;
							break;
						}
						num3 |= 1 << num4;
						num |= 1 << j;
						array[n++] = hand[j];
						num2++;
					}
				}
				if (!(flag2 || flag) && num2 == 4 && StraightPossible(array, n, 1))
				{
					return num;
				}
			}
			return 0;
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[52];
			VideoPokerLogic.Shuffle(rng, array);
			int[] array2 = new int[5];
			for (int i = 0; i < 5; i++)
			{
				array2[i] = array[i];
			}
			int num = HoldMask(array2);
			int num2 = 5;
			for (int j = 0; j < 5; j++)
			{
				if ((num & (1 << j)) == 0)
				{
					array2[j] = array[num2++];
				}
			}
			int winMask;
			int num3 = Evaluate(array2, out winMask);
			return DeucesPay.PAYS[num3];
		}
	}
	public static class JackpotSevensLogic
	{
		public static float Evaluate(int[] grid, out int cellMask)
		{
			int num = grid[0];
			int num2 = grid[1];
			int num3 = grid[2];
			cellMask = 0;
			if (num == num2 && num2 == num3 && SevensPay.TRIPLE[num] > 0f)
			{
				cellMask = 7;
				return SevensPay.TRIPLE[num];
			}
			if ((num == 4 || num == 5) && (num2 == 4 || num2 == 5) && (num3 == 4 || num3 == 5))
			{
				cellMask = 7;
				return 125f;
			}
			if ((num == 2 || num == 3) && (num2 == 2 || num2 == 3) && (num3 == 2 || num3 == 3))
			{
				cellMask = 7;
				return 11f;
			}
			int num4 = 0;
			for (int i = 0; i < 3; i++)
			{
				if (grid[i] == 1)
				{
					num4++;
					cellMask |= 1 << i;
				}
			}
			if (num4 > 0)
			{
				return SevensPay.CHERRY_PAYS[num4 - 1];
			}
			cellMask = 0;
			return 0f;
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[3];
			for (int i = 0; i < 3; i++)
			{
				array[i] = PureRng.WeightedIndex(rng, SevensPay.WEIGHTS);
			}
			int cellMask;
			return Evaluate(array, out cellMask);
		}
	}
	public static class JokersWildLogic
	{
		public static float Evaluate(int[] grid, out int cellMask)
		{
			cellMask = 0;
			float num = 0f;
			int length = JokersPay.LINES.GetLength(0);
			for (int i = 0; i < length; i++)
			{
				int a = grid[JokersPay.LINES[i, 0]];
				int b = grid[3 + JokersPay.LINES[i, 1]];
				int c = grid[6 + JokersPay.LINES[i, 2]];
				float num2 = EvalLine(a, b, c);
				if (num2 > 0f)
				{
					num += num2;
					cellMask |= 1 << JokersPay.LINES[i, 0];
					cellMask |= 1 << 3 + JokersPay.LINES[i, 1];
					cellMask |= 1 << 6 + JokersPay.LINES[i, 2];
				}
			}
			return num;
		}

		private static float EvalLine(int a, int b, int c)
		{
			int num = 5;
			int num2 = 0;
			int num3 = -1;
			bool flag = true;
			for (int i = 0; i < 3; i++)
			{
				int num4 = i switch
				{
					1 => b, 
					0 => a, 
					_ => c, 
				};
				if (num4 == num)
				{
					num2++;
				}
				else if (num3 < 0)
				{
					num3 = num4;
				}
				else if (num4 != num3)
				{
					flag = false;
				}
			}
			if (num2 == 3)
			{
				return JokersPay.PAY3[num];
			}
			if (!flag)
			{
				return 0f;
			}
			return JokersPay.PAY3[num3];
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[9];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = PureRng.WeightedIndex(rng, JokersPay.WEIGHTS);
			}
			int cellMask;
			return Evaluate(array, out cellMask);
		}
	}
	public class MoreSlots : GameCoreBase
	{
		private const int ModeNeon = 0;

		private const int ModeSevens = 1;

		private const int ModeDeep = 2;

		private const int ModeJokers = 3;

		private const int ModeScratch = 4;

		private const int ModePoker = 5;

		private const int ModeDeuces = 6;

		private const int ModeCount = 7;

		private static readonly int[] CellsAll15 = new int[15]
		{
			0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
			10, 11, 12, 13, 14
		};

		private static readonly int[] CellsMid3 = new int[3] { 4, 7, 10 };

		private static readonly int[] Cells3x3 = new int[9] { 3, 4, 5, 6, 7, 8, 9, 10, 11 };

		private static readonly int[] CellsMid5 = new int[5] { 1, 4, 7, 10, 13 };

		public SpriteRenderer[] cellSymbols;

		public GameObject[] covers;

		public GameObject[] holdMarkers;

		public GameObject[] neonSymbols;

		public GameObject[] sevensSymbols;

		public GameObject[] deepSymbols;

		public GameObject[] jokerSymbols;

		public GameObject[] scratchSymbols;

		public GameObject[] cardSymbols;

		public GameObject cardBackObject;

		public GameObject titleTextObject;

		public GameObject winTextObject;

		private int mode;

		private int[] scratchCard;

		private float scratchMult;

		private bool[] scratchRevealed;

		private int scratchRevealCount;

		private int[] deck = new int[52];

		private int deckPos;

		private int[] hand = new int[5];

		private bool[] held = new bool[5];

		private bool pokerHoldPhase;

		private Coroutine watchdog;

		private int modeClient = -1;

		private bool[] heldClient = new bool[5];

		private int scratchRevealedClient;

		private float scratchMultClient;

		private Coroutine visualRoutine;

		private Coroutine highlightRoutine;

		private Sprite[][] modeSprites;

		private Sprite backSprite;

		private TMP_Text winText;

		private TMP_Text titleText;

		private TMP_Text rulesText;

		private Vector3[] cellBaseScales;

		private Random visualRng = new Random();

		private static int[] ModeCells(int m)
		{
			return m switch
			{
				0 => CellsAll15, 
				1 => CellsMid3, 
				2 => CellsMid3, 
				3 => Cells3x3, 
				4 => Cells3x3, 
				_ => CellsMid5, 
			};
		}

		private static string TitleOf(int m)
		{
			return m switch
			{
				0 => "NEON NIGHTS", 
				1 => "LUCKY 777", 
				2 => "DEEP SEA SPINS", 
				3 => "JOKER'S WILD", 
				4 => "SCRATCH 'N WIN", 
				6 => "DEUCES WILD", 
				_ => "JACKS OR BETTER", 
			};
		}

		private static string RulesOf(int m)
		{
			return m switch
			{
				0 => "5 LINES: ROWS + DIAGONALS\nPAYS 3 / 4 / 5 OF A KIND (x BET)\n\nCHERRY   2.5 / 6 / 25\nLEMON   4 / 10 / 40\nGRAPE   5 / 16 / 65\nMELON   8 / 25 / 100\nBELL   13 / 50 / 200\nSTAR   19 / 80 / 325\nDIAMOND   30 / 125 / 650\nSEVEN   65 / 325 / 8625", 
				1 => "3 ON THE LINE PAYS (x BET)\n\nBAR x3   25\nBAR BAR x3   65\n7 x3   575\nDIAMOND x3   1725\nMIXED BARS   11\nMIXED 7 / DIAMOND   125\nCHERRIES  1=1  2=2.5  3=11", 
				2 => "MATCH 3 TO WIN (x BET)\n\nSHELL   9\nCRAB   16\nFISH   25\nOCTOPUS   45\nANCHOR   125\nPEARL   475\nPEARLS  1=1.5  2=6", 
				3 => "5 LINES: ROWS + DIAGONALS\nJOKER IS WILD\n3 ON A LINE PAYS (x BET)\n\nSPADE   1.5\nHEART   2\nCLUB   2.5\nDIAMOND   3\nCROWN   8\nJOKER   55", 
				4 => "MATCH 3 SYMBOLS TO WIN (x BET)\n\nCOIN   1\nBELL   2\nSHOE   5\nCLOVER   10\nGEM   25\n7   100", 
				6 => "ALL 2s ARE WILD\nDEAL 5 - CLICK CARDS TO HOLD - DRAW\nPAYS (x BET)\n\nNATURAL ROYAL   250\nFOUR DEUCES   200\nWILD ROYAL   25\nFIVE OF A KIND   15\nSTRAIGHT FLUSH   10\n4 OF A KIND   5.5\nFULL HOUSE   3.5\nFLUSH   2.5\nSTRAIGHT   2.5\n3 OF A KIND   1.2", 
				_ => "DEAL 5 - CLICK CARDS TO HOLD - DRAW\nPAYS (x BET)\n\nROYAL FLUSH   250\nSTRAIGHT FLUSH   60\n4 OF A KIND   25\nFULL HOUSE   10\nFLUSH   7\nSTRAIGHT   5\n3 OF A KIND   3\nTWO PAIR   2\nJACKS OR BETTER   1.5", 
			};
		}

		private static bool IsSlotMode(int m)
		{
			if (m != 0 && m != 1 && m != 2)
			{
				return m == 3;
			}
			return true;
		}

		private static bool IsPokerMode(int m)
		{
			if (m != 5)
			{
				return m == 6;
			}
			return true;
		}

		private static int ReelsOf(int m)
		{
			return m switch
			{
				0 => 5, 
				3 => 3, 
				_ => 3, 
			};
		}

		private static int RowsOf(int m)
		{
			return m switch
			{
				0 => 3, 
				3 => 3, 
				_ => 1, 
			};
		}

		private static int[] WeightsOf(int m)
		{
			return m switch
			{
				0 => NeonPay.WEIGHTS, 
				1 => SevensPay.WEIGHTS, 
				2 => DeepSeaPay.WEIGHTS, 
				_ => JokersPay.WEIGHTS, 
			};
		}

		private static float SpinBaseOf(int m)
		{
			return m switch
			{
				0 => 1.2f, 
				1 => 1f, 
				2 => 1f, 
				_ => 1f, 
			};
		}

		private static float SpinStaggerOf(int m)
		{
			return m switch
			{
				0 => 0.35f, 
				1 => 0.5f, 
				2 => 0.45f, 
				_ => 0.45f, 
			};
		}

		private static float EvaluateSlot(int m, int[] grid, out int mask)
		{
			return m switch
			{
				0 => NeonSlotsLogic.Evaluate(grid, out mask), 
				1 => JackpotSevensLogic.Evaluate(grid, out mask), 
				2 => DeepSeaSlotsLogic.Evaluate(grid, out mask), 
				_ => JokersWildLogic.Evaluate(grid, out mask), 
			};
		}

		private void Start()
		{
			CacheVisuals();
			if (modeClient < 0)
			{
				ApplyMode(0);
			}
		}

		private static Sprite[] SpritesFrom(GameObject[] sources)
		{
			if (sources == null)
			{
				return (Sprite[])(object)new Sprite[0];
			}
			Sprite[] array = (Sprite[])(object)new Sprite[sources.Length];
			for (int i = 0; i < sources.Length; i++)
			{
				if (!((Object)(object)sources[i] == (Object)null))
				{
					SpriteRenderer val = sources[i].GetComponent<SpriteRenderer>();
					if ((Object)(object)val == (Object)null)
					{
						val = sources[i].GetComponentInChildren<SpriteRenderer>(true);
					}
					if ((Object)(object)val != (Object)null)
					{
						array[i] = val.sprite;
					}
				}
			}
			return array;
		}

		private void CacheVisuals()
		{
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			if (modeSprites == null)
			{
				modeSprites = new Sprite[7][];
				modeSprites[0] = SpritesFrom(neonSymbols);
				modeSprites[1] = SpritesFrom(sevensSymbols);
				modeSprites[2] = SpritesFrom(deepSymbols);
				modeSprites[3] = SpritesFrom(jokerSymbols);
				modeSprites[4] = SpritesFrom(scratchSymbols);
				modeSprites[5] = SpritesFrom(cardSymbols);
				modeSprites[6] = modeSprites[5];
			}
			if ((Object)(object)backSprite == (Object)null && (Object)(object)cardBackObject != (Object)null)
			{
				SpriteRenderer val = cardBackObject.GetComponent<SpriteRenderer>();
				if ((Object)(object)val == (Object)null)
				{
					val = cardBackObject.GetComponentInChildren<SpriteRenderer>(true);
				}
				if ((Object)(object)val != (Object)null)
				{
					backSprite = val.sprite;
				}
			}
			if ((Object)(object)winText == (Object)null && (Object)(object)winTextObject != (Object)null)
			{
				winText = winTextObject.GetComponent<TMP_Text>();
				if ((Object)(object)winText == (Object)null)
				{
					winText = winTextObject.GetComponentInChildren<TMP_Text>(true);
				}
			}
			if ((Object)(object)titleText == (Object)null && (Object)(object)titleTextObject != (Object)null)
			{
				titleText = titleTextObject.GetComponent<TMP_Text>();
				if ((Object)(object)titleText == (Object)null)
				{
					titleText = titleTextObject.GetComponentInChildren<TMP_Text>(true);
				}
			}
			if ((Object)(object)rulesText == (Object)null && (Object)(object)rulesPanel != (Object)null)
			{
				rulesText = rulesPanel.GetComponentInChildren<TMP_Text>(true);
			}
			if (cellBaseScales == null && cellSymbols != null)
			{
				cellBaseScales = (Vector3[])(object)new Vector3[cellSymbols.Length];
				for (int i = 0; i < cellSymbols.Length; i++)
				{
					cellBaseScales[i] = (((Object)(object)cellSymbols[i] != (Object)null) ? ((Component)cellSymbols[i]).transform.localScale : Vector3.one);
				}
			}
		}

		private void SetWinText(string t)
		{
			if ((Object)(object)winText != (Object)null)
			{
				winText.text = t;
			}
		}

		private GameObject CellRoot(int i)
		{
			if (cellSymbols == null || i >= cellSymbols.Length || (Object)(object)cellSymbols[i] == (Object)null)
			{
				return null;
			}
			Transform parent = ((Component)cellSymbols[i]).transform.parent;
			if (!((Object)(object)parent != (Object)null))
			{
				return ((Component)cellSymbols[i]).gameObject;
			}
			return ((Component)parent).gameObject;
		}

		private void SetHoldMarkers(bool[] state)
		{
			if (holdMarkers == null)
			{
				return;
			}
			for (int i = 0; i < holdMarkers.Length; i++)
			{
				if ((Object)(object)holdMarkers[i] != (Object)null)
				{
					holdMarkers[i].SetActive(state != null && i < state.Length && state[i]);
				}
			}
		}

		private void ApplyMode(int m)
		{
			CacheVisuals();
			modeClient = m;
			StopVisualRoutines();
			if ((Object)(object)titleText != (Object)null)
			{
				titleText.text = TitleOf(m);
			}
			if ((Object)(object)rulesText != (Object)null)
			{
				rulesText.text = TitleOf(m) + "\n\n" + RulesOf(m);
			}
			SetWinText("");
			SetHoldMarkers(null);
			int[] array = ModeCells(m);
			Sprite[] array2 = modeSprites[m];
			for (int i = 0; i < 15; i++)
			{
				GameObject val = CellRoot(i);
				bool active = Array.IndexOf(array, i) >= 0;
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
				if (covers != null && i < covers.Length && (Object)(object)covers[i] != (Object)null)
				{
					covers[i].SetActive(false);
				}
			}
			for (int j = 0; j < array.Length; j++)
			{
				int num = array[j];
				if (cellSymbols == null || (Object)(object)cellSymbols[num] == (Object)null)
				{
					continue;
				}
				if (IsPokerMode(m))
				{
					cellSymbols[num].sprite = backSprite;
				}
				else if (m == 4)
				{
					cellSymbols[num].sprite = null;
					if (covers != null && (Object)(object)covers[num] != (Object)null)
					{
						covers[num].SetActive(true);
					}
				}
				else if (array2.Length != 0)
				{
					cellSymbols[num].sprite = array2[j % array2.Length];
				}
			}
		}

		public override void OnStartServer()
		{
			((GameBase)this).OnStartServer();
			((MonoBehaviour)this).StartCoroutine(ModeHeartbeat());
		}

		private IEnumerator ModeHeartbeat()
		{
			while (true)
			{
				if (NetworkServer.active)
				{
					BroadcastString("UserRpcMode", mode.ToString());
				}
				yield return (object)new WaitForSeconds(5f);
			}
		}

		[Server]
		public void SwapGame(PlayerInteract interact = null)
		{
			if (NetworkServer.active && !((GameBase)this).isPlaying)
			{
				mode = (mode + 1) % 7;
				BroadcastString("UserRpcMode", mode.ToString());
			}
		}

		public void UserRpcMode(string networkText)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkClient.active)
			{
				int num = GameCoreBase.PI(networkText);
				if (num >= 0 && num < 7 && num != modeClient)
				{
					ApplyMode(num);
					Sfx.Play(((Component)this).transform.position, "KeypadButton", "GenericKeypadButton");
				}
			}
		}

		protected override void StartGame()
		{
			GuardStuckReset();
			((GameBase)this).StartGame();
			if (((NetworkBehaviour)this).isServer)
			{
				if (watchdog != null)
				{
					((MonoBehaviour)this).StopCoroutine(watchdog);
					watchdog = null;
				}
				((GameBase)this).isPlaying = true;
				if (IsSlotMode(mode))
				{
					ServerSpin();
				}
				else if (mode == 4)
				{
					ServerScratchStart();
				}
				else
				{
					ServerDeal();
				}
			}
		}

		private void ServerSpin()
		{
			int num = ReelsOf(mode);
			int num2 = RowsOf(mode);
			int num3 = num * num2;
			int[] array = new int[num3];
			for (int i = 0; i < num3; i++)
			{
				array[i] = WeightedIndex(WeightsOf(mode));
			}
			int mask;
			float num4 = EvaluateSlot(mode, array, out mask);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(mode).Append('|');
			for (int j = 0; j < num3; j++)
			{
				if (j > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(array[j]);
			}
			stringBuilder.Append('|').Append(GameCoreBase.F(num4)).Append('|')
				.Append(mask);
			BroadcastString("UserRpcSpin", stringBuilder.ToString());
			float delay = SpinBaseOf(mode) + SpinStaggerOf(mode) * (float)(num - 1) + 1f;
			FinishRound(num4, delay);
		}

		public void UserRpcSpin(string networkText)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				return;
			}
			string[] array = networkText.Split('|');
			if (array.Length < 4)
			{
				return;
			}
			int num = GameCoreBase.PI(array[0]);
			if (!IsSlotMode(num))
			{
				return;
			}
			if (num != modeClient)
			{
				ApplyMode(num);
			}
			int num2 = ReelsOf(num);
			int num3 = RowsOf(num);
			string[] array2 = array[1].Split(',');
			if (array2.Length == num2 * num3)
			{
				int[] array3 = new int[array2.Length];
				for (int i = 0; i < array2.Length; i++)
				{
					array3[i] = GameCoreBase.PI(array2[i]);
				}
				float mult = GameCoreBase.PF(array[2]);
				int mask = GameCoreBase.PI(array[3]);
				((GameBase)this).isPlaying = true;
				StopVisualRoutines();
				SetWinText("GOOD LUCK");
				Sfx.Play(((Component)this).transform.position, "SlotMachinePull", "SlotMachineSpin");
				visualRoutine = ((MonoBehaviour)this).StartCoroutine(SpinAll(num, array3, mult, mask));
			}
		}

		private IEnumerator SpinAll(int m, int[] grid, float mult, int mask)
		{
			int reels = ReelsOf(m);
			int rows = RowsOf(m);
			int[] map = ModeCells(m);
			Sprite[] sprites = modeSprites[m];
			float spinBase = SpinBaseOf(m);
			float stagger = SpinStaggerOf(m);
			float elapsed = 0f;
			float tick = 0f;
			int landed = 0;
			bool[] reelDone = new bool[reels];
			for (int i = 0; i < reels; i++)
			{
				Sfx.PlayParam(((Component)this).transform.position, "spinDuration", (spinBase + stagger * (float)i) * 1000f, "SlotMachineSpin 2");
			}
			while (landed < reels)
			{
				elapsed += Time.deltaTime;
				tick += Time.deltaTime;
				bool flag = tick >= 0.06f;
				if (flag)
				{
					tick = 0f;
				}
				for (int j = 0; j < reels; j++)
				{
					if (reelDone[j])
					{
						continue;
					}
					if (elapsed >= spinBase + stagger * (float)j)
					{
						reelDone[j] = true;
						landed++;
						for (int k = 0; k < rows; k++)
						{
							int num = j * rows + k;
							SpriteRenderer val = cellSymbols[map[num]];
							if ((Object)(object)val != (Object)null && grid[num] >= 0 && grid[num] < sprites.Length)
							{
								val.sprite = sprites[grid[num]];
								((MonoBehaviour)this).StartCoroutine(LandBounce(((Component)val).transform, map[num]));
							}
						}
						Sfx.Play(((Component)this).transform.position, "SlotMachineSpinDone", "GenericKeypadButton");
					}
					else
					{
						if (!flag)
						{
							continue;
						}
						for (int l = 0; l < rows; l++)
						{
							SpriteRenderer val2 = cellSymbols[map[j * rows + l]];
							if ((Object)(object)val2 != (Object)null && sprites.Length != 0)
							{
								val2.sprite = sprites[visualRng.Next(sprites.Length)];
							}
						}
					}
				}
				yield return null;
			}
			yield return (object)new WaitForSeconds(0.25f);
			float value = Mathf.Clamp(mult, 0f, 1000f);
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineMultReveal");
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineCashReveal");
			if (mult > 0f)
			{
				SetWinText("WIN " + GameCoreBase.F(mult) + "x");
				int num2 = 0;
				for (int n = 0; n < map.Length; n++)
				{
					if ((mask & (1 << n)) != 0)
					{
						num2 |= 1 << map[n];
					}
				}
				if (highlightRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(highlightRoutine);
				}
				highlightRoutine = ((MonoBehaviour)this).StartCoroutine(HighlightCells(num2));
			}
			else
			{
				SetWinText("NO WIN");
			}
		}

		private IEnumerator LandBounce(Transform t, int cellIndex)
		{
			Vector3 baseScale = ((cellBaseScales != null) ? cellBaseScales[cellIndex] : t.localScale);
			float dur = 0.18f;
			float e = 0f;
			while (e < dur)
			{
				e += Time.deltaTime;
				float num = 1f + 0.18f * Mathf.Sin(Mathf.Clamp01(e / dur) * (float)Math.PI);
				t.localScale = baseScale * num;
				yield return null;
			}
			t.localScale = baseScale;
		}

		private IEnumerator HighlightCells(int uniMask)
		{
			float e = 0f;
			while (e < 1.8f)
			{
				e += Time.deltaTime;
				float num = 1f + 0.14f * Mathf.Abs(Mathf.Sin(e * 6f));
				for (int i = 0; i < 15; i++)
				{
					if ((uniMask & (1 << i)) != 0 && !((Object)(object)cellSymbols[i] == (Object)null))
					{
						((Component)cellSymbols[i]).transform.localScale = cellBaseScales[i] * num;
					}
				}
				yield return null;
			}
			RestoreCellScales();
		}

		private void RestoreCellScales()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (cellSymbols == null || cellBaseScales == null)
			{
				return;
			}
			for (int i = 0; i < cellSymbols.Length; i++)
			{
				if ((Object)(object)cellSymbols[i] != (Object)null)
				{
					((Component)cellSymbols[i]).transform.localScale = cellBaseScales[i];
				}
			}
		}

		private void ServerScratchStart()
		{
			scratchCard = new int[9];
			scratchMult = ScratchLogic.Generate(serverRng, ScratchPay.TIER_MULT, ScratchPay.TIER_PROB, ScratchPay.TIER_SYM, 6, scratchCard);
			scratchRevealed = new bool[9];
			scratchRevealCount = 0;
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(mode).Append('|');
			for (int i = 0; i < 9; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(scratchCard[i]);
			}
			stringBuilder.Append('|').Append(GameCoreBase.F(scratchMult));
			BroadcastString("UserRpcCard", stringBuilder.ToString());
			watchdog = ((MonoBehaviour)this).StartCoroutine(ScratchWatchdog());
		}

		[Server]
		private void RevealCell(int li)
		{
			if (!NetworkServer.active || !((GameBase)this).isPlaying || mode != 4 || scratchRevealed == null || li < 0 || li >= 9 || scratchRevealed[li])
			{
				return;
			}
			scratchRevealed[li] = true;
			scratchRevealCount++;
			BroadcastString("UserRpcReveal", li.ToString());
			if (scratchRevealCount >= 9)
			{
				if (watchdog != null)
				{
					((MonoBehaviour)this).StopCoroutine(watchdog);
					watchdog = null;
				}
				FinishRound(scratchMult, 1.2f);
			}
		}

		private IEnumerator ScratchWatchdog()
		{
			yield return (object)new WaitForSeconds(45f);
			for (int i = 0; i < 9; i++)
			{
				if (!((GameBase)this).isPlaying)
				{
					yield break;
				}
				if (!scratchRevealed[i])
				{
					RevealCell(i);
					yield return (object)new WaitForSeconds(0.15f);
				}
			}
			watchdog = null;
		}

		public void UserRpcCard(string networkText)
		{
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				return;
			}
			string[] array = networkText.Split('|');
			if (array.Length < 3)
			{
				return;
			}
			int num = GameCoreBase.PI(array[0]);
			if (num != 4)
			{
				return;
			}
			if (num != modeClient)
			{
				ApplyMode(num);
			}
			string[] array2 = array[1].Split(',');
			if (array2.Length != 9)
			{
				return;
			}
			int[] array3 = ModeCells(4);
			Sprite[] array4 = modeSprites[4];
			for (int i = 0; i < 9; i++)
			{
				int num2 = GameCoreBase.PI(array2[i]);
				if ((Object)(object)cellSymbols[array3[i]] != (Object)null && num2 >= 0 && num2 < array4.Length)
				{
					cellSymbols[array3[i]].sprite = array4[num2];
				}
				if (covers != null && (Object)(object)covers[array3[i]] != (Object)null)
				{
					covers[array3[i]].SetActive(true);
				}
			}
			scratchMultClient = GameCoreBase.PF(array[2]);
			scratchRevealedClient = 0;
			((GameBase)this).isPlaying = true;
			SetWinText("SCRATCH!");
			Sfx.Play(((Component)this).transform.position, "CardScannerButton", "GenericKeypadButton");
		}

		public void UserRpcReveal(string networkText)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				return;
			}
			int num = GameCoreBase.PI(networkText);
			int[] array = ModeCells(4);
			if (num < 0 || num >= 9)
			{
				return;
			}
			GameObject val = ((covers != null) ? covers[array[num]] : null);
			if (!((Object)(object)val == (Object)null) && val.activeSelf)
			{
				((MonoBehaviour)this).StartCoroutine(RevealAnim(val));
				Sfx.Play(val.transform.position, "SlotMachineCashReveal", "GenericKeypadButton");
				scratchRevealedClient++;
				if (scratchRevealedClient >= 9)
				{
					((MonoBehaviour)this).StartCoroutine(ScratchResultAfter(0.6f));
				}
			}
		}

		private IEnumerator RevealAnim(GameObject cover)
		{
			Vector3 baseScale = cover.transform.localScale;
			float dur = 0.25f;
			float e = 0f;
			while (e < dur && (Object)(object)cover != (Object)null)
			{
				e += Time.deltaTime;
				float num = 1f - Mathf.Clamp01(e / dur);
				cover.transform.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z);
				yield return null;
			}
			if ((Object)(object)cover != (Object)null)
			{
				cover.SetActive(false);
				cover.transform.localScale = baseScale;
			}
		}

		private IEnumerator ScratchResultAfter(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			float value = Mathf.Clamp(scratchMultClient, 0f, 1000f);
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineMultReveal");
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineCashReveal");
			if (scratchMultClient > 0f)
			{
				SetWinText("WIN " + GameCoreBase.F(scratchMultClient) + "x");
			}
			else
			{
				SetWinText("NO WIN");
			}
		}

		private void ServerDeal()
		{
			VideoPokerLogic.Shuffle(serverRng, deck);
			for (int i = 0; i < 5; i++)
			{
				hand[i] = deck[i];
				held[i] = false;
			}
			deckPos = 5;
			pokerHoldPhase = true;
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(mode).Append('|');
			for (int j = 0; j < 5; j++)
			{
				if (j > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(hand[j]);
			}
			BroadcastString("UserRpcDeal", stringBuilder.ToString());
			watchdog = ((MonoBehaviour)this).StartCoroutine(PokerWatchdog());
		}

		[Server]
		private void ToggleHold(int i)
		{
			if (NetworkServer.active && ((GameBase)this).isPlaying && IsPokerMode(mode) && pokerHoldPhase)
			{
				held[i] = !held[i];
				BroadcastString("UserRpcHold", i + "," + (held[i] ? "1" : "0"));
			}
		}

		[Server]
		public void DoDraw(PlayerInteract interact = null)
		{
			if (!NetworkServer.active || !((GameBase)this).isPlaying || !IsPokerMode(mode) || !pokerHoldPhase)
			{
				return;
			}
			pokerHoldPhase = false;
			if (watchdog != null)
			{
				((MonoBehaviour)this).StopCoroutine(watchdog);
				watchdog = null;
			}
			int num = 0;
			for (int i = 0; i < 5; i++)
			{
				if (held[i])
				{
					num |= 1 << i;
				}
				else
				{
					hand[i] = deck[deckPos++];
				}
			}
			int num2;
			int winMask;
			float num3;
			if (mode == 6)
			{
				num2 = DeucesWildLogic.Evaluate(hand, out winMask);
				num3 = DeucesPay.PAYS[num2];
			}
			else
			{
				num2 = VideoPokerLogic.Evaluate(hand, out winMask);
				num3 = PokerPay.PAYS[num2];
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(mode).Append('|');
			for (int j = 0; j < 5; j++)
			{
				if (j > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append(hand[j]);
			}
			stringBuilder.Append('|').Append(GameCoreBase.F(num3)).Append('|')
				.Append(num2)
				.Append('|')
				.Append(num);
			BroadcastString("UserRpcDraw", stringBuilder.ToString());
			FinishRound(num3, 1.9f);
		}

		private IEnumerator PokerWatchdog()
		{
			yield return (object)new WaitForSeconds(45f);
			watchdog = null;
			if (!((GameBase)this).isPlaying || !pokerHoldPhase)
			{
				yield break;
			}
			int num = ((mode == 6) ? DeucesWildLogic.HoldMask(hand) : VideoPokerLogic.HoldMask(hand));
			for (int i = 0; i < 5; i++)
			{
				bool flag = (num & (1 << i)) != 0;
				if (held[i] != flag)
				{
					ToggleHold(i);
				}
			}
			yield return (object)new WaitForSeconds(0.4f);
			DoDraw();
		}

		public void UserRpcDeal(string networkText)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				return;
			}
			string[] array = networkText.Split('|');
			if (array.Length < 2)
			{
				return;
			}
			int num = GameCoreBase.PI(array[0]);
			if (!IsPokerMode(num))
			{
				return;
			}
			if (num != modeClient)
			{
				ApplyMode(num);
			}
			string[] array2 = array[1].Split(',');
			if (array2.Length == 5)
			{
				((GameBase)this).isPlaying = true;
				for (int i = 0; i < 5; i++)
				{
					heldClient[i] = false;
				}
				SetHoldMarkers(null);
				SetWinText("HOLD CARDS, THEN DRAW");
				Sfx.Play(((Component)this).transform.position, "SlotMachinePull", "GenericKeypadButton");
				if (visualRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(visualRoutine);
				}
				visualRoutine = ((MonoBehaviour)this).StartCoroutine(FlipCards(array2, 31));
			}
		}

		public void UserRpcHold(string networkText)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkClient.active)
			{
				return;
			}
			string[] array = networkText.Split(',');
			if (array.Length != 2)
			{
				return;
			}
			int num = GameCoreBase.PI(array[0]);
			if (num >= 0 && num < 5)
			{
				heldClient[num] = array[1] == "1";
				if (holdMarkers != null && num < holdMarkers.Length && (Object)(object)holdMarkers[num] != (Object)null)
				{
					holdMarkers[num].SetActive(heldClient[num]);
				}
				Sfx.Play(((Component)this).transform.position, "KeypadButton", "GenericKeypadButton");
			}
		}

		public void UserRpcDraw(string networkText)
		{
			if (!NetworkClient.active)
			{
				return;
			}
			string[] array = networkText.Split('|');
			if (array.Length < 5)
			{
				return;
			}
			int num = GameCoreBase.PI(array[0]);
			if (!IsPokerMode(num))
			{
				return;
			}
			if (num != modeClient)
			{
				ApplyMode(num);
			}
			string[] array2 = array[1].Split(',');
			if (array2.Length == 5)
			{
				float mult = GameCoreBase.PF(array[2]);
				int cat = GameCoreBase.PI(array[3]);
				int num2 = GameCoreBase.PI(array[4]);
				if (visualRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(visualRoutine);
				}
				visualRoutine = ((MonoBehaviour)this).StartCoroutine(DrawAndReveal(num, array2, ~num2 & 0x1F, mult, cat));
			}
		}

		private IEnumerator DrawAndReveal(int m, string[] cells, int flipMask, float mult, int cat)
		{
			yield return FlipCards(cells, flipMask);
			yield return (object)new WaitForSeconds(0.25f);
			float value = Mathf.Clamp(mult, 0f, 1000f);
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineMultReveal");
			Sfx.PlayParam(((Component)this).transform.position, "Multiplier", value, "SlotMachineCashReveal");
			string[] array = ((m == 6) ? DeucesPay.NAMES : PokerPay.NAMES);
			if (mult > 0f && cat > 0 && cat < array.Length)
			{
				SetWinText(array[cat] + "  " + GameCoreBase.F(mult) + "x");
			}
			else
			{
				SetWinText("NO WIN");
			}
		}

		private IEnumerator FlipCards(string[] cells, int mask)
		{
			int[] map = ModeCells(5);
			Sprite[] sprites = modeSprites[5];
			for (int i = 0; i < 5; i++)
			{
				if ((mask & (1 << i)) != 0)
				{
					SpriteRenderer val = cellSymbols[map[i]];
					if (!((Object)(object)val == (Object)null))
					{
						int num = GameCoreBase.PI(cells[i]);
						yield return FlipOne(val, map[i], (num >= 0 && num < sprites.Length) ? sprites[num] : null);
						yield return (object)new WaitForSeconds(0.14f);
					}
				}
			}
		}

		private IEnumerator FlipOne(SpriteRenderer sr, int cellIndex, Sprite target)
		{
			Transform t = ((Component)sr).transform;
			Vector3 baseScale = ((cellBaseScales != null) ? cellBaseScales[cellIndex] : t.localScale);
			float dur = 0.09f;
			for (float e = 0f; e < dur; e += Time.deltaTime)
			{
				float num = 1f - Mathf.Clamp01(e / dur);
				t.localScale = new Vector3(baseScale.x * num, baseScale.y, baseScale.z);
				yield return null;
			}
			if ((Object)(object)target != (Object)null)
			{
				sr.sprite = target;
			}
			Sfx.Play(t.position, "SlotMachineSpinDone", "GenericKeypadButton");
			for (float e = 0f; e < dur; e += Time.deltaTime)
			{
				float num2 = Mathf.Clamp01(e / dur);
				t.localScale = new Vector3(baseScale.x * num2, baseScale.y, baseScale.z);
				yield return null;
			}
			t.localScale = baseScale;
		}

		[Server]
		private void CellPressed(int uni)
		{
			if (!NetworkServer.active || !((GameBase)this).isPlaying)
			{
				return;
			}
			if (mode == 4)
			{
				int num = Array.IndexOf(ModeCells(4), uni);
				if (num >= 0)
				{
					RevealCell(num);
				}
			}
			else if (IsPokerMode(mode))
			{
				int num2 = Array.IndexOf(ModeCells(5), uni);
				if (num2 >= 0)
				{
					ToggleHold(num2);
				}
			}
		}

		[Server]
		public void CellPressed0(PlayerInteract interact = null)
		{
			CellPressed(0);
		}

		[Server]
		public void CellPressed1(PlayerInteract interact = null)
		{
			CellPressed(1);
		}

		[Server]
		public void CellPressed2(PlayerInteract interact = null)
		{
			CellPressed(2);
		}

		[Server]
		public void CellPressed3(PlayerInteract interact = null)
		{
			CellPressed(3);
		}

		[Server]
		public void CellPressed4(PlayerInteract interact = null)
		{
			CellPressed(4);
		}

		[Server]
		public void CellPressed5(PlayerInteract interact = null)
		{
			CellPressed(5);
		}

		[Server]
		public void CellPressed6(PlayerInteract interact = null)
		{
			CellPressed(6);
		}

		[Server]
		public void CellPressed7(PlayerInteract interact = null)
		{
			CellPressed(7);
		}

		[Server]
		public void CellPressed8(PlayerInteract interact = null)
		{
			CellPressed(8);
		}

		[Server]
		public void CellPressed9(PlayerInteract interact = null)
		{
			CellPressed(9);
		}

		[Server]
		public void CellPressed10(PlayerInteract interact = null)
		{
			CellPressed(10);
		}

		[Server]
		public void CellPressed11(PlayerInteract interact = null)
		{
			CellPressed(11);
		}

		[Server]
		public void CellPressed12(PlayerInteract interact = null)
		{
			CellPressed(12);
		}

		[Server]
		public void CellPressed13(PlayerInteract interact = null)
		{
			CellPressed(13);
		}

		[Server]
		public void CellPressed14(PlayerInteract interact = null)
		{
			CellPressed(14);
		}

		private void StopVisualRoutines()
		{
			if (visualRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(visualRoutine);
				visualRoutine = null;
			}
			if (highlightRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(highlightRoutine);
				highlightRoutine = null;
			}
			RestoreCellScales();
		}

		protected override void OnClientResetVisuals()
		{
			StopVisualRoutines();
			((GameBase)this).isPlaying = false;
			int m = ((modeClient >= 0) ? modeClient : 0);
			modeClient = -1;
			ApplyMode(m);
		}
	}
	public static class NeonSlotsLogic
	{
		public static float Evaluate(int[] grid, out int cellMask)
		{
			cellMask = 0;
			float num = 0f;
			int length = NeonPay.LINES.GetLength(0);
			for (int i = 0; i < length; i++)
			{
				int num2 = grid[NeonPay.LINES[i, 0]];
				int num3 = 1;
				for (int j = 1; j < 5 && grid[j * 3 + NeonPay.LINES[i, j]] == num2; j++)
				{
					num3++;
				}
				if (num3 >= 3)
				{
					num += num3 switch
					{
						3 => NeonPay.PAY3[num2], 
						4 => NeonPay.PAY4[num2], 
						_ => NeonPay.PAY5[num2], 
					};
					for (int k = 0; k < num3; k++)
					{
						cellMask |= 1 << k * 3 + NeonPay.LINES[i, k];
					}
				}
			}
			return num;
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[15];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = PureRng.WeightedIndex(rng, NeonPay.WEIGHTS);
			}
			int cellMask;
			return Evaluate(array, out cellMask);
		}
	}
	internal static class NeonPay
	{
		public const string TITLE = "NEON NIGHTS";

		public const string RULES = "5 LINES: ROWS + DIAGONALS\nPAYS 3 / 4 / 5 OF A KIND (x BET)\n\nCHERRY   2.5 / 6 / 25\nLEMON   4 / 10 / 40\nGRAPE   5 / 16 / 65\nMELON   8 / 25 / 100\nBELL   13 / 50 / 200\nSTAR   19 / 80 / 325\nDIAMOND   30 / 125 / 650\nSEVEN   65 / 325 / 8625";

		public const int REELS = 5;

		public const int ROWS = 3;

		public const float SPIN_BASE = 1.2f;

		public const float SPIN_STAGGER = 0.35f;

		public static readonly int[] WEIGHTS = new int[8] { 25, 20, 16, 12, 10, 8, 6, 3 };

		public static readonly float[] PAY3 = new float[8] { 2.5f, 4f, 5f, 8f, 13f, 19f, 30f, 65f };

		public static readonly float[] PAY4 = new float[8] { 6f, 10f, 16f, 25f, 50f, 80f, 125f, 325f };

		public static readonly float[] PAY5 = new float[8] { 25f, 40f, 65f, 100f, 200f, 325f, 650f, 8625f };

		public static readonly int[,] LINES = new int[5, 5]
		{
			{ 1, 1, 1, 1, 1 },
			{ 0, 0, 0, 0, 0 },
			{ 2, 2, 2, 2, 2 },
			{ 0, 1, 2, 1, 0 },
			{ 2, 1, 0, 1, 2 }
		};
	}
	internal static class SevensPay
	{
		public const string TITLE = "LUCKY 777";

		public const string RULES = "3 ON THE LINE PAYS (x BET)\n\nBAR x3   25\nBAR BAR x3   65\n7 x3   575\nDIAMOND x3   1725\nMIXED BARS   11\nMIXED 7 / DIAMOND   125\nCHERRIES  1=1  2=2.5  3=11";

		public const float SPIN_BASE = 1f;

		public const float SPIN_STAGGER = 0.5f;

		public static readonly int[] WEIGHTS = new int[6] { 50, 12, 18, 10, 7, 3 };

		public static readonly float[] TRIPLE = new float[6] { 0f, 0f, 25f, 65f, 575f, 1725f };

		public static readonly float[] CHERRY_PAYS = new float[3] { 1f, 2.5f, 11f };

		public const float ANY_BAR = 11f;

		public const float SEVEN_DIAMOND_MIX = 125f;

		public const int CHERRY = 1;

		public const int BAR = 2;

		public const int DBAR = 3;

		public const int SEVEN = 4;

		public const int JDIAMOND = 5;
	}
	internal static class DeepSeaPay
	{
		public const string TITLE = "DEEP SEA SPINS";

		public const string RULES = "MATCH 3 TO WIN (x BET)\n\nSHELL   9\nCRAB   16\nFISH   25\nOCTOPUS   45\nANCHOR   125\nPEARL   475\nPEARLS  1=1.5  2=6";

		public const float SPIN_BASE = 1f;

		public const float SPIN_STAGGER = 0.45f;

		public static readonly int[] WEIGHTS = new int[6] { 30, 25, 20, 12, 9, 4 };

		public static readonly float[] PAY3 = new float[6] { 9f, 16f, 25f, 45f, 125f, 475f };

		public const int PEARL = 5;

		public const float PEARL_1 = 1.5f;

		public const float PEARL_2 = 6f;
	}
	internal static class JokersPay
	{
		public const string TITLE = "JOKER'S WILD";

		public const string RULES = "5 LINES: ROWS + DIAGONALS\nJOKER IS WILD\n3 ON A LINE PAYS (x BET)\n\nSPADE   1.5\nHEART   2\nCLUB   2.5\nDIAMOND   3\nCROWN   8\nJOKER   55";

		public const int REELS = 3;

		public const int ROWS = 3;

		public const float SPIN_BASE = 1f;

		public const float SPIN_STAGGER = 0.45f;

		public static readonly int[] WEIGHTS = new int[6] { 22, 20, 18, 14, 10, 6 };

		public static readonly float[] PAY3 = new float[6] { 1.5f, 2f, 2.5f, 3f, 8f, 55f };

		public const int WILD = 5;

		public static readonly int[,] LINES = new int[5, 3]
		{
			{ 1, 1, 1 },
			{ 0, 0, 0 },
			{ 2, 2, 2 },
			{ 0, 1, 2 },
			{ 2, 1, 0 }
		};
	}
	internal static class ScratchPay
	{
		public const string TITLE = "SCRATCH 'N WIN";

		public const string RULES = "MATCH 3 SYMBOLS TO WIN (x BET)\n\nCOIN   1\nBELL   2\nSHOE   5\nCLOVER   10\nGEM   25\n7   100";

		public const int GRID = 3;

		public const int SYMBOL_COUNT = 6;

		public static readonly float[] TIER_MULT = new float[7] { 0f, 1f, 2f, 5f, 10f, 25f, 100f };

		public static readonly double[] TIER_PROB = new double[7] { 0.78194, 0.08722, 0.05815, 0.03877, 0.02181, 0.00969, 0.00242 };

		public static readonly int[] TIER_SYM = new int[7] { -1, 0, 1, 2, 3, 4, 5 };
	}
	internal static class PokerPay
	{
		public const string TITLE = "JACKS OR BETTER";

		public const string RULES = "DEAL 5 - CLICK CARDS TO HOLD - DRAW\nPAYS (x BET)\n\nROYAL FLUSH   250\nSTRAIGHT FLUSH   60\n4 OF A KIND   25\nFULL HOUSE   10\nFLUSH   7\nSTRAIGHT   5\n3 OF A KIND   3\nTWO PAIR   2\nJACKS OR BETTER   1.5";

		public static readonly float[] PAYS = new float[10] { 0f, 1.5f, 2f, 3f, 5f, 7f, 10f, 25f, 60f, 250f };

		public static readonly string[] NAMES = new string[10] { "", "JACKS OR BETTER", "TWO PAIR", "THREE OF A KIND", "STRAIGHT", "FLUSH", "FULL HOUSE", "FOUR OF A KIND", "STRAIGHT FLUSH", "ROYAL FLUSH" };
	}
	internal static class DeucesPay
	{
		public const string TITLE = "DEUCES WILD";

		public const string RULES = "ALL 2s ARE WILD\nDEAL 5 - CLICK CARDS TO HOLD - DRAW\nPAYS (x BET)\n\nNATURAL ROYAL   250\nFOUR DEUCES   200\nWILD ROYAL   25\nFIVE OF A KIND   15\nSTRAIGHT FLUSH   10\n4 OF A KIND   5.5\nFULL HOUSE   3.5\nFLUSH   2.5\nSTRAIGHT   2.5\n3 OF A KIND   1.2";

		public static readonly float[] PAYS = new float[11]
		{
			0f, 1.2f, 2.5f, 2.5f, 3.5f, 5.5f, 10f, 15f, 25f, 200f,
			250f
		};

		public static readonly string[] NAMES = new string[11]
		{
			"", "THREE OF A KIND", "STRAIGHT", "FLUSH", "FULL HOUSE", "FOUR OF A KIND", "STRAIGHT FLUSH", "FIVE OF A KIND", "WILD ROYAL", "FOUR DEUCES",
			"NATURAL ROYAL"
		};
	}
	public static class ScratchCardLogic
	{
		public static float SpinOnce(Random rng)
		{
			int[] cells = new int[9];
			return ScratchLogic.Generate(rng, ScratchPay.TIER_MULT, ScratchPay.TIER_PROB, ScratchPay.TIER_SYM, 6, cells);
		}
	}
	public static class VideoPokerLogic
	{
		public const int NONE = 0;

		public const int JACKS_OR_BETTER = 1;

		public const int TWO_PAIR = 2;

		public const int THREE_KIND = 3;

		public const int STRAIGHT = 4;

		public const int FLUSH = 5;

		public const int FULL_HOUSE = 6;

		public const int FOUR_KIND = 7;

		public const int STRAIGHT_FLUSH = 8;

		public const int ROYAL_FLUSH = 9;

		public static int Rank(int card)
		{
			return card % 13;
		}

		public static int Suit(int card)
		{
			return card / 13;
		}

		public static int Evaluate(int[] hand, out int winMask)
		{
			int[] array = new int[13];
			for (int i = 0; i < 5; i++)
			{
				array[Rank(hand[i])]++;
			}
			bool flag = true;
			for (int j = 1; j < 5; j++)
			{
				if (Suit(hand[j]) != Suit(hand[0]))
				{
					flag = false;
					break;
				}
			}
			int num = 0;
			int num2 = -1;
			int num3 = -1;
			int num4 = -1;
			int num5 = 0;
			int num6 = 13;
			int num7 = -1;
			for (int k = 0; k < 13; k++)
			{
				if (array[k] == 0)
				{
					continue;
				}
				num5++;
				if (k < num6)
				{
					num6 = k;
				}
				if (k > num7)
				{
					num7 = k;
				}
				if (array[k] == 2)
				{
					num++;
					if (k > num2)
					{
						num2 = k;
					}
				}
				if (array[k] == 3)
				{
					num3 = k;
				}
				if (array[k] == 4)
				{
					num4 = k;
				}
			}
			bool flag2 = false;
			bool flag3 = false;
			if (num5 == 5)
			{
				if (num7 - num6 == 4)
				{
					flag2 = true;
				}
				else if (array[12] == 1 && array[0] == 1 && array[1] == 1 && array[2] == 1 && array[3] == 1)
				{
					flag2 = true;
				}
				flag3 = flag2 && num6 == 8;
			}
			if (flag2 && flag)
			{
				winMask = 31;
				if (!flag3)
				{
					return 8;
				}
				return 9;
			}
			if (num4 >= 0)
			{
				winMask = MaskOfRank(hand, num4);
				return 7;
			}
			if (num3 >= 0 && num == 1)
			{
				winMask = 31;
				return 6;
			}
			if (flag)
			{
				winMask = 31;
				return 5;
			}
			if (flag2)
			{
				winMask = 31;
				return 4;
			}
			if (num3 >= 0)
			{
				winMask = MaskOfRank(hand, num3);
				return 3;
			}
			switch (num)
			{
			case 2:
			{
				winMask = 0;
				for (int l = 0; l < 13; l++)
				{
					if (array[l] == 2)
					{
						winMask |= MaskOfRank(hand, l);
					}
				}
				return 2;
			}
			case 1:
				if (num2 >= 9)
				{
					winMask = MaskOfRank(hand, num2);
					return 1;
				}
				break;
			}
			winMask = 0;
			return 0;
		}

		private static int MaskOfRank(int[] hand, int rank)
		{
			int num = 0;
			for (int i = 0; i < 5; i++)
			{
				if (Rank(hand[i]) == rank)
				{
					num |= 1 << i;
				}
			}
			return num;
		}

		public static int HoldMask(int[] hand)
		{
			int winMask;
			int num = Evaluate(hand, out winMask);
			if (num == 9 || num == 8 || num == 7)
			{
				return 31;
			}
			int num2 = SuitedInRoyalRange(hand, 4);
			if (num2 != 0)
			{
				return num2;
			}
			switch (num)
			{
			case 6:
				return 31;
			case 5:
				return 31;
			case 3:
				return winMask;
			case 4:
				return 31;
			default:
				num2 = FourToStraightFlush(hand);
				if (num2 != 0)
				{
					return num2;
				}
				switch (num)
				{
				case 2:
					return winMask;
				case 1:
					return winMask;
				default:
				{
					num2 = SuitedInRoyalRange(hand, 3);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = SuitedCount(hand, 4);
					if (num2 != 0)
					{
						return num2;
					}
					int num3 = LowPairMask(hand);
					if (num3 != 0)
					{
						return num3;
					}
					num2 = FourToStraight(hand);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = TwoSuitedHigh(hand);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = ThreeToStraightFlush(hand);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = LowestHighCards(hand, 2);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = SuitedTenHonor(hand);
					if (num2 != 0)
					{
						return num2;
					}
					num2 = LowestHighCards(hand, 1);
					if (num2 != 0)
					{
						return num2;
					}
					return 0;
				}
				}
			}
		}

		private static int SuitedInRoyalRange(int[] hand, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				for (int j = 0; j < 5; j++)
				{
					if (Suit(hand[j]) == i && Rank(hand[j]) >= 8)
					{
						num |= 1 << j;
						num2++;
					}
				}
				if (num2 >= need)
				{
					return num;
				}
			}
			return 0;
		}

		private static int SuitedCount(int[] hand, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				for (int j = 0; j < 5; j++)
				{
					if (Suit(hand[j]) == i)
					{
						num |= 1 << j;
						num2++;
					}
				}
				if (num2 >= need)
				{
					return num;
				}
			}
			return 0;
		}

		private static int LowPairMask(int[] hand)
		{
			int[] array = new int[13];
			for (int i = 0; i < 5; i++)
			{
				array[Rank(hand[i])]++;
			}
			for (int j = 0; j < 9; j++)
			{
				if (array[j] != 2)
				{
					continue;
				}
				int num = 0;
				for (int k = 0; k < 5; k++)
				{
					if (Rank(hand[k]) == j)
					{
						num |= 1 << k;
					}
				}
				return num;
			}
			return 0;
		}

		private static int FourToStraight(int[] hand)
		{
			for (int i = 0; i < 5; i++)
			{
				int num = 0;
				int num2 = 0;
				int num3 = 13;
				int num4 = -1;
				bool flag = false;
				int num5 = 0;
				bool flag2 = false;
				bool flag3 = true;
				for (int j = 0; j < 5; j++)
				{
					if (j != i)
					{
						int num6 = Rank(hand[j]);
						if ((num5 & (1 << num6)) != 0)
						{
							flag = true;
							break;
						}
						num5 |= 1 << num6;
						num |= 1 << j;
						num2++;
						if (num6 < num3)
						{
							num3 = num6;
						}
						if (num6 > num4)
						{
							num4 = num6;
						}
						if (num6 == 12)
						{
							flag2 = true;
						}
						else if (num6 > 3)
						{
							flag3 = false;
						}
					}
				}
				if (!flag && num2 == 4)
				{
					if (num4 - num3 <= 4)
					{
						return num;
					}
					if (flag2 && flag3)
					{
						return num;
					}
				}
			}
			return 0;
		}

		private static int FourToStraightFlush(int[] hand)
		{
			return StraightFlushDraw(hand, 4);
		}

		private static int ThreeToStraightFlush(int[] hand)
		{
			return StraightFlushDraw(hand, 3);
		}

		private static int StraightFlushDraw(int[] hand, int need)
		{
			for (int i = 0; i < 4; i++)
			{
				int[] array = new int[5];
				int num = 0;
				for (int j = 0; j < 5; j++)
				{
					if (Suit(hand[j]) == i)
					{
						array[num++] = j;
					}
				}
				if (num < need)
				{
					continue;
				}
				for (int k = 0; k < 1 << num; k++)
				{
					int num2 = 0;
					int num3 = 0;
					int num4 = 13;
					int num5 = -1;
					int num6 = 0;
					bool flag = false;
					bool flag2 = false;
					bool flag3 = true;
					for (int l = 0; l < num; l++)
					{
						if ((k & (1 << l)) != 0)
						{
							num2++;
							int num7 = array[l];
							int num8 = Rank(hand[num7]);
							if ((num6 & (1 << num8)) != 0)
							{
								flag = true;
								break;
							}
							num6 |= 1 << num8;
							num3 |= 1 << num7;
							if (num8 < num4)
							{
								num4 = num8;
							}
							if (num8 > num5)
							{
								num5 = num8;
							}
							if (num8 == 12)
							{
								flag2 = true;
							}
							else if (num8 > 3)
							{
								flag3 = false;
							}
						}
					}
					if (!flag && num2 == need && (num5 - num4 <= 4 || (flag2 && flag3)))
					{
						return num3;
					}
				}
			}
			return 0;
		}

		private static int TwoSuitedHigh(int[] hand)
		{
			for (int i = 0; i < 4; i++)
			{
				int num = 0;
				int num2 = 0;
				for (int j = 0; j < 5; j++)
				{
					if (Suit(hand[j]) == i && Rank(hand[j]) >= 9)
					{
						num |= 1 << j;
						num2++;
					}
				}
				if (num2 >= 2)
				{
					return num;
				}
			}
			return 0;
		}

		private static int SuitedTenHonor(int[] hand)
		{
			for (int i = 0; i < 5; i++)
			{
				if (Rank(hand[i]) != 8)
				{
					continue;
				}
				for (int j = 0; j < 5; j++)
				{
					int num = Rank(hand[j]);
					if (Suit(hand[j]) == Suit(hand[i]) && num >= 9 && num <= 11)
					{
						return (1 << i) | (1 << j);
					}
				}
			}
			return 0;
		}

		private static int LowestHighCards(int[] hand, int want)
		{
			int num = 0;
			int num2 = 0;
			for (int i = 9; i <= 12; i++)
			{
				if (num2 >= want)
				{
					break;
				}
				for (int j = 0; j < 5; j++)
				{
					if (num2 >= want)
					{
						break;
					}
					if (Rank(hand[j]) == i && (num & (1 << j)) == 0)
					{
						num |= 1 << j;
						num2++;
					}
				}
			}
			if (num2 != want)
			{
				return 0;
			}
			return num;
		}

		public static void Shuffle(Random rng, int[] deck)
		{
			for (int i = 0; i < deck.Length; i++)
			{
				deck[i] = i;
			}
			for (int num = deck.Length - 1; num > 0; num--)
			{
				int num2 = rng.Next(num + 1);
				int num3 = deck[num];
				deck[num] = deck[num2];
				deck[num2] = num3;
			}
		}

		public static float SpinOnce(Random rng)
		{
			int[] array = new int[52];
			Shuffle(rng, array);
			int[] array2 = new int[5];
			for (int i = 0; i < 5; i++)
			{
				array2[i] = array[i];
			}
			int num = HoldMask(array2);
			int num2 = 5;
			for (int j = 0; j < 5; j++)
			{
				if ((num & (1 << j)) == 0)
				{
					array2[j] = array[num2++];
				}
			}
			int winMask;
			int num3 = Evaluate(array2, out winMask);
			return PokerPay.PAYS[num3];
		}
	}
}
namespace GWYFCustom.Games.PluginNS
{
	[BepInPlugin("com.willikers.moreslots", "More Slots", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MoreSlotsPlugin : BaseUnityPlugin
	{
		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MoreSlots assembly loaded, waiting for MoreGames base loader.");
		}
	}
}