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(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)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> all; private static readonly Dictionary cache = new Dictionary(); 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>(); 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(text, value)); } } } Debug.Log((object)("[GWYFCustom] FMOD events discovered: " + all.Count)); foreach (KeyValuePair 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 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(); if ((Object)(object)val == (Object)null) { val = sources[i].GetComponentInChildren(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(); if ((Object)(object)val == (Object)null) { val = cardBackObject.GetComponentInChildren(true); } if ((Object)(object)val != (Object)null) { backSprite = val.sprite; } } if ((Object)(object)winText == (Object)null && (Object)(object)winTextObject != (Object)null) { winText = winTextObject.GetComponent(); if ((Object)(object)winText == (Object)null) { winText = winTextObject.GetComponentInChildren(true); } } if ((Object)(object)titleText == (Object)null && (Object)(object)titleTextObject != (Object)null) { titleText = titleTextObject.GetComponent(); if ((Object)(object)titleText == (Object)null) { titleText = titleTextObject.GetComponentInChildren(true); } } if ((Object)(object)rulesText == (Object)null && (Object)(object)rulesPanel != (Object)null) { rulesText = rulesPanel.GetComponentInChildren(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."); } } }