Decompiled source of DuckRaceTweaks v1.1.6

DuckRaceTweaks.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Extensions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DuckRaceTweaks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DuckRaceTweaks")]
[assembly: AssemblyTitle("DuckRaceTweaks")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace DuckRaceTweaks
{
	[BepInPlugin("com.Spoopylocal.duckracetweaks", "DuckRaceTweaks", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.Spoopylocal.duckracetweaks";

		public const string PluginName = "DuckRaceTweaks";

		public const string PluginVersion = "1.0.0";

		internal static Plugin Instance;

		private Harmony harmony = null;

		private bool menuOpen;

		private ConfigEntry<KeyboardShortcut> primaryMenuShortcut = null;

		private ConfigEntry<KeyboardShortcut> secondaryMenuShortcut = null;

		public static bool MenuOpen => (Object)(object)Instance != (Object)null && Instance.menuOpen;

		internal static string MenuShortcutLabel
		{
			get
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Instance == (Object)null)
				{
					return "Insert / F1";
				}
				string text = FormatShortcut(Instance.primaryMenuShortcut.Value);
				string text2 = FormatShortcut(Instance.secondaryMenuShortcut.Value);
				if (string.IsNullOrWhiteSpace(text))
				{
					return string.IsNullOrWhiteSpace(text2) ? "Unbound" : text2;
				}
				return string.IsNullOrWhiteSpace(text2) ? text : (text + " / " + text2);
			}
		}

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			Instance = this;
			primaryMenuShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Primary menu toggle key", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Primary shortcut that opens or closes the DuckRaceTweaks menu. This can be edited from Thunderstore Mod Manager/r2modman after the game creates the config file.");
			secondaryMenuShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "Secondary menu toggle key", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Secondary shortcut that opens or closes the DuckRaceTweaks menu. Set this to None in Thunderstore Mod Manager/r2modman to disable the second key.");
			harmony = new Harmony("com.Spoopylocal.duckracetweaks");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DuckRaceTweaks loaded.");
		}

		private void Update()
		{
			if (IsShortcutDown(primaryMenuShortcut) || IsShortcutDown(secondaryMenuShortcut))
			{
				menuOpen = !menuOpen;
			}
		}

		private void OnGUI()
		{
			if (menuOpen)
			{
				DuckRaceUi.Draw();
				GameWorldLabels.Draw();
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private static bool IsShortcutDown(ConfigEntry<KeyboardShortcut> shortcut)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			int result;
			if (shortcut != null)
			{
				KeyboardShortcut value = shortcut.Value;
				if ((int)((KeyboardShortcut)(ref value)).MainKey != 0)
				{
					value = shortcut.Value;
					result = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
					goto IL_0025;
				}
			}
			result = 0;
			goto IL_0025;
			IL_0025:
			return (byte)result != 0;
		}

		private static string FormatShortcut(KeyboardShortcut shortcut)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) ? string.Empty : ((object)(KeyboardShortcut)(ref shortcut)).ToString();
		}
	}
	internal static class DuckRaceState
	{
		private static readonly Dictionary<DuckRace, int> forcedWinners = new Dictionary<DuckRace, int>();

		private static readonly List<DuckRace> tables = new List<DuckRace>();

		private static int selectedTableIndex;

		private static bool dropdownOpen;

		public static IReadOnlyList<DuckRace> Tables => tables;

		public static int SelectedTableIndex
		{
			get
			{
				return selectedTableIndex;
			}
			set
			{
				selectedTableIndex = value;
			}
		}

		public static bool DropdownOpen
		{
			get
			{
				return dropdownOpen;
			}
			set
			{
				dropdownOpen = value;
			}
		}

		public static void Register(DuckRace race)
		{
			if (!((Object)(object)race == (Object)null) && !tables.Contains(race))
			{
				tables.Add(race);
			}
		}

		public static void Unregister(DuckRace race)
		{
			if (!((Object)(object)race == (Object)null))
			{
				tables.Remove(race);
				forcedWinners.Remove(race);
				if (selectedTableIndex >= tables.Count)
				{
					selectedTableIndex = Mathf.Max(0, tables.Count - 1);
				}
			}
		}

		public static DuckRace GetSelectedTable()
		{
			CleanupTables();
			if (tables.Count <= 0)
			{
				return null;
			}
			if (selectedTableIndex < 0)
			{
				selectedTableIndex = 0;
			}
			if (selectedTableIndex >= tables.Count)
			{
				selectedTableIndex = tables.Count - 1;
			}
			return tables[selectedTableIndex];
		}

		public static int GetForcedWinner(DuckRace race)
		{
			if ((Object)(object)race == (Object)null)
			{
				return -1;
			}
			int value;
			return forcedWinners.TryGetValue(race, out value) ? value : (-1);
		}

		public static void SetForcedWinner(DuckRace race, int index)
		{
			if (!((Object)(object)race == (Object)null))
			{
				List<DuckRaceDuck> ducks = DuckRaceReflection.GetDucks(race);
				if (index < 0 || index >= ducks.Count)
				{
					ClearForcedWinner(race);
					return;
				}
				forcedWinners[race] = index;
				DuckRaceReflection.SetWinningDuckIndex(race, index);
				Debug.Log((object)("[DuckRaceTweaks] Forced duck winner set to duck index: " + index));
			}
		}

		public static void ClearForcedWinner(DuckRace race)
		{
			if (!((Object)(object)race == (Object)null))
			{
				forcedWinners.Remove(race);
				DuckRaceReflection.SetWinningDuckIndex(race, -1);
				Debug.Log((object)"[DuckRaceTweaks] Forced duck winner cleared.");
			}
		}

		public static int GetDuckIndex(DuckRace race, DuckRaceDuck duck)
		{
			if ((Object)(object)race == (Object)null || (Object)(object)duck == (Object)null)
			{
				return -1;
			}
			return DuckRaceReflection.GetDucks(race).IndexOf(duck);
		}

		public static DuckRace GetDuckRace(DuckRaceDuck duck)
		{
			return DuckRaceDuckReflection.GetDuckRace(duck);
		}

		private static void CleanupTables()
		{
			for (int num = tables.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)tables[num] == (Object)null)
				{
					tables.RemoveAt(num);
				}
			}
			if (selectedTableIndex >= tables.Count)
			{
				selectedTableIndex = Mathf.Max(0, tables.Count - 1);
			}
		}
	}
	internal static class WheelState
	{
		private static readonly Dictionary<Wheel, int> forcedResults = new Dictionary<Wheel, int>();

		private static readonly List<Wheel> cachedWheels = new List<Wheel>();

		private const float WheelRefreshInterval = 1f;

		private static int selectedWheelIndex;

		private static bool dropdownOpen;

		private static float nextWheelRefreshTime;

		public static int SelectedWheelIndex
		{
			get
			{
				return selectedWheelIndex;
			}
			set
			{
				selectedWheelIndex = value;
			}
		}

		public static bool DropdownOpen
		{
			get
			{
				return dropdownOpen;
			}
			set
			{
				dropdownOpen = value;
			}
		}

		public static List<Wheel> GetWheels()
		{
			RefreshWheels(force: false);
			return cachedWheels;
		}

		private static void RefreshWheels(bool force)
		{
			float unscaledTime = Time.unscaledTime;
			if (!force && cachedWheels.Count > 0 && unscaledTime < nextWheelRefreshTime)
			{
				for (int num = cachedWheels.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)cachedWheels[num] == (Object)null)
					{
						cachedWheels.RemoveAt(num);
					}
				}
				return;
			}
			nextWheelRefreshTime = unscaledTime + 1f;
			cachedWheels.Clear();
			Wheel[] source = Object.FindObjectsByType<Wheel>((FindObjectsSortMode)0);
			cachedWheels.AddRange(from wheel in source
				where (Object)(object)wheel != (Object)null
				orderby ((Component)wheel).transform.position.x, ((Component)wheel).transform.position.z
				select wheel);
			if (selectedWheelIndex >= cachedWheels.Count)
			{
				selectedWheelIndex = Mathf.Max(0, cachedWheels.Count - 1);
			}
		}

		public static Wheel GetSelectedWheel()
		{
			List<Wheel> wheels = GetWheels();
			if (wheels.Count <= 0)
			{
				return null;
			}
			if (selectedWheelIndex < 0)
			{
				selectedWheelIndex = 0;
			}
			if (selectedWheelIndex >= wheels.Count)
			{
				selectedWheelIndex = wheels.Count - 1;
			}
			return wheels[selectedWheelIndex];
		}

		public static int GetForcedResult(Wheel wheel)
		{
			if ((Object)(object)wheel == (Object)null)
			{
				return -1;
			}
			int value;
			return forcedResults.TryGetValue(wheel, out value) ? value : (-1);
		}

		public static void SetForcedResult(Wheel wheel, int index)
		{
			if (!((Object)(object)wheel == (Object)null))
			{
				WheelResult[] results = WheelReflection.GetResults(wheel);
				if (index < 0 || index >= results.Length)
				{
					ClearForcedResult(wheel);
					return;
				}
				forcedResults[wheel] = index;
				Debug.Log((object)("[DuckRaceTweaks] Forced wheel result set to index: " + index + " / " + results[index].result));
			}
		}

		public static void ClearForcedResult(Wheel wheel)
		{
			if (!((Object)(object)wheel == (Object)null))
			{
				forcedResults.Remove(wheel);
				Debug.Log((object)"[DuckRaceTweaks] Forced wheel result cleared.");
			}
		}

		public static void ConsumeForcedResult(Wheel wheel)
		{
			if (!((Object)(object)wheel == (Object)null))
			{
				forcedResults.Remove(wheel);
			}
		}
	}
	internal static class SlotsState
	{
		private static readonly Dictionary<Slots, int> forcedSymbols = new Dictionary<Slots, int>();

		private static readonly List<Slots> cachedSlots = new List<Slots>();

		private const float SlotsRefreshInterval = 1f;

		private static int selectedSlotsIndex;

		private static bool dropdownOpen;

		private static Vector2 symbolScroll;

		private static float nextSlotsRefreshTime;

		public static int SelectedSlotsIndex
		{
			get
			{
				return selectedSlotsIndex;
			}
			set
			{
				selectedSlotsIndex = value;
			}
		}

		public static bool DropdownOpen
		{
			get
			{
				return dropdownOpen;
			}
			set
			{
				dropdownOpen = value;
			}
		}

		public static Vector2 SymbolScroll
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return symbolScroll;
			}
			set
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				symbolScroll = value;
			}
		}

		public static List<Slots> GetSlotsMachines()
		{
			RefreshSlots(force: false);
			return cachedSlots;
		}

		public static Slots GetSelectedSlots()
		{
			List<Slots> slotsMachines = GetSlotsMachines();
			if (slotsMachines.Count <= 0)
			{
				return null;
			}
			if (selectedSlotsIndex < 0)
			{
				selectedSlotsIndex = 0;
			}
			if (selectedSlotsIndex >= slotsMachines.Count)
			{
				selectedSlotsIndex = slotsMachines.Count - 1;
			}
			return slotsMachines[selectedSlotsIndex];
		}

		public static int GetForcedSymbol(Slots slots)
		{
			if ((Object)(object)slots == (Object)null)
			{
				return -1;
			}
			int value;
			return forcedSymbols.TryGetValue(slots, out value) ? value : (-1);
		}

		public static void SetForcedSymbol(Slots slots, int symbolIndex)
		{
			if (!((Object)(object)slots == (Object)null))
			{
				int symbolCount = SlotsReflection.GetSymbolCount(slots);
				if (symbolIndex < 0 || symbolIndex >= symbolCount)
				{
					ClearForcedSymbol(slots);
					return;
				}
				forcedSymbols[slots] = symbolIndex;
				Debug.Log((object)("[DuckRaceTweaks] Forced slots symbol set to index: " + symbolIndex));
			}
		}

		public static void ClearForcedSymbol(Slots slots)
		{
			if (!((Object)(object)slots == (Object)null))
			{
				forcedSymbols.Remove(slots);
				Debug.Log((object)"[DuckRaceTweaks] Forced slots symbol cleared.");
			}
		}

		public static Slots GetSlotsForReel(SlotReel reel)
		{
			if ((Object)(object)reel == (Object)null)
			{
				return null;
			}
			List<Slots> slotsMachines = GetSlotsMachines();
			foreach (Slots item in slotsMachines)
			{
				List<SlotReel> reels = SlotsReflection.GetReels(item);
				if (reels.Contains(reel))
				{
					return item;
				}
			}
			return null;
		}

		private static void RefreshSlots(bool force)
		{
			float unscaledTime = Time.unscaledTime;
			if (!force && cachedSlots.Count > 0 && unscaledTime < nextSlotsRefreshTime)
			{
				for (int num = cachedSlots.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)cachedSlots[num] == (Object)null)
					{
						cachedSlots.RemoveAt(num);
					}
				}
				return;
			}
			nextSlotsRefreshTime = unscaledTime + 1f;
			cachedSlots.Clear();
			Slots[] source = Object.FindObjectsByType<Slots>((FindObjectsSortMode)0);
			cachedSlots.AddRange(from slots in source
				where (Object)(object)slots != (Object)null
				orderby ((Component)slots).transform.position.x, ((Component)slots).transform.position.z
				select slots);
			if (selectedSlotsIndex >= cachedSlots.Count)
			{
				selectedSlotsIndex = Mathf.Max(0, cachedSlots.Count - 1);
			}
		}
	}
	internal static class CrashState
	{
		private static readonly Dictionary<Crash, float> forcedMultipliers = new Dictionary<Crash, float>();

		private static readonly List<Crash> cachedCrashes = new List<Crash>();

		private const float CrashRefreshInterval = 1f;

		private static int selectedCrashIndex;

		private static bool dropdownOpen;

		private static float nextCrashRefreshTime;

		public static int SelectedCrashIndex
		{
			get
			{
				return selectedCrashIndex;
			}
			set
			{
				selectedCrashIndex = value;
			}
		}

		public static bool DropdownOpen
		{
			get
			{
				return dropdownOpen;
			}
			set
			{
				dropdownOpen = value;
			}
		}

		public static List<Crash> GetCrashes()
		{
			RefreshCrashes(force: false);
			return cachedCrashes;
		}

		public static Crash GetSelectedCrash()
		{
			List<Crash> crashes = GetCrashes();
			if (crashes.Count <= 0)
			{
				return null;
			}
			if (selectedCrashIndex < 0)
			{
				selectedCrashIndex = 0;
			}
			if (selectedCrashIndex >= crashes.Count)
			{
				selectedCrashIndex = crashes.Count - 1;
			}
			return crashes[selectedCrashIndex];
		}

		public static bool TryGetForcedMultiplier(Crash crash, out float multiplier)
		{
			if ((Object)(object)crash == (Object)null)
			{
				multiplier = 0f;
				return false;
			}
			return forcedMultipliers.TryGetValue(crash, out multiplier);
		}

		public static void SetForcedMultiplier(Crash crash, float multiplier)
		{
			if (!((Object)(object)crash == (Object)null))
			{
				multiplier = Mathf.Max(1.01f, multiplier);
				forcedMultipliers[crash] = multiplier;
				Debug.Log((object)("[DuckRaceTweaks] Forced crash multiplier set to: " + multiplier.ToString("0.00") + "x"));
			}
		}

		public static void ClearForcedMultiplier(Crash crash)
		{
			if (!((Object)(object)crash == (Object)null))
			{
				forcedMultipliers.Remove(crash);
				Debug.Log((object)"[DuckRaceTweaks] Forced crash multiplier cleared.");
			}
		}

		public static bool TryConsumeForcedMultiplier(Crash crash, out float multiplier)
		{
			if (!TryGetForcedMultiplier(crash, out multiplier))
			{
				return false;
			}
			forcedMultipliers.Remove(crash);
			return true;
		}

		private static void RefreshCrashes(bool force)
		{
			float unscaledTime = Time.unscaledTime;
			if (!force && cachedCrashes.Count > 0 && unscaledTime < nextCrashRefreshTime)
			{
				for (int num = cachedCrashes.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)cachedCrashes[num] == (Object)null)
					{
						cachedCrashes.RemoveAt(num);
					}
				}
				return;
			}
			nextCrashRefreshTime = unscaledTime + 1f;
			cachedCrashes.Clear();
			Crash[] source = Object.FindObjectsByType<Crash>((FindObjectsSortMode)0);
			cachedCrashes.AddRange(from crash in source
				where (Object)(object)crash != (Object)null
				orderby ((Component)crash).transform.position.x, ((Component)crash).transform.position.z
				select crash);
			if (selectedCrashIndex >= cachedCrashes.Count)
			{
				selectedCrashIndex = Mathf.Max(0, cachedCrashes.Count - 1);
			}
		}
	}
	internal static class KenoState
	{
		private static readonly Dictionary<Keno, List<int>> diamondButtonIndices = new Dictionary<Keno, List<int>>();

		public static IReadOnlyList<int> GetOrCreateDiamondButtonIndices(Keno keno)
		{
			if ((Object)(object)keno == (Object)null)
			{
				return Array.Empty<int>();
			}
			if (diamondButtonIndices.TryGetValue(keno, out List<int> value))
			{
				return value;
			}
			KenoButton[] buttons = KenoReflection.GetButtons(keno);
			int diamondCount = KenoReflection.GetDiamondCount(keno);
			if (buttons.Length == 0 || diamondCount <= 0)
			{
				return Array.Empty<int>();
			}
			value = FathF.GetUniqueRandomNumbers(diamondCount, 0, buttons.Length - 1, true);
			diamondButtonIndices[keno] = value;
			return value;
		}

		public static void SetDiamondButtonIndices(Keno keno, List<int> indices)
		{
			if (!((Object)(object)keno == (Object)null))
			{
				diamondButtonIndices[keno] = indices ?? new List<int>();
			}
		}

		public static IReadOnlyList<int> GetDiamondButtonIndices(Keno keno)
		{
			if ((Object)(object)keno == (Object)null)
			{
				return Array.Empty<int>();
			}
			if (diamondButtonIndices.TryGetValue(keno, out List<int> value))
			{
				return value;
			}
			return Array.Empty<int>();
		}

		public static void Clear(Keno keno)
		{
			if (!((Object)(object)keno == (Object)null))
			{
				diamondButtonIndices.Remove(keno);
			}
		}
	}
	internal static class MinesweeperState
	{
		private sealed class MinePreview
		{
			public int MineCount;

			public int TileCount;

			public List<int> Indices = new List<int>();
		}

		private static readonly Dictionary<Minesweeper, MinePreview> minePreviews = new Dictionary<Minesweeper, MinePreview>();

		public static IReadOnlyList<int> GetOrCreateMineIndices(Minesweeper minesweeper)
		{
			if ((Object)(object)minesweeper == (Object)null)
			{
				return Array.Empty<int>();
			}
			List<MinesweeperTile> tiles = MinesweeperReflection.GetTiles(minesweeper);
			int count = tiles.Count;
			int num = Mathf.Clamp(MinesweeperReflection.GetCurrentMineCount(minesweeper), 1, Mathf.Max(1, count - 1));
			if (count <= 0)
			{
				return Array.Empty<int>();
			}
			if (minePreviews.TryGetValue(minesweeper, out MinePreview value) && value.TileCount == count && value.MineCount == num)
			{
				return value.Indices;
			}
			value = new MinePreview
			{
				TileCount = count,
				MineCount = num,
				Indices = CreateMineIndices(count, num)
			};
			minePreviews[minesweeper] = value;
			return value.Indices;
		}

		public static List<int> ConsumeMineIndices(Minesweeper minesweeper)
		{
			return GetOrCreateMineIndices(minesweeper).ToList();
		}

		public static void Clear(Minesweeper minesweeper)
		{
			if (!((Object)(object)minesweeper == (Object)null))
			{
				minePreviews.Remove(minesweeper);
			}
		}

		private static List<int> CreateMineIndices(int tileCount, int mineCount)
		{
			List<int> list = Enumerable.Range(0, tileCount).ToList();
			List<int> list2 = new List<int>(mineCount);
			for (int i = 0; i < mineCount; i++)
			{
				if (list.Count <= 0)
				{
					break;
				}
				int index = Random.Range(0, list.Count);
				list2.Add(list[index]);
				list.RemoveAt(index);
			}
			return list2;
		}
	}
	internal static class ItemSpawnerState
	{
		private static readonly List<SpawnableSO> cachedSpawnables = new List<SpawnableSO>();

		private static readonly List<string> cachedSpawnableNames = new List<string>();

		private static readonly List<string> cachedSpawnableButtonLabels = new List<string>();

		private const float SpawnCooldown = 0.15f;

		private const float AimSpawnDistance = 4f;

		private const float AimRaycastDistance = 50f;

		private const float SurfaceSpawnOffset = 0.35f;

		public const int ItemsPerPage = 16;

		private static int selectedSpawnableIndex;

		private static int spawnablePage;

		private static Vector2 spawnableScroll;

		private static bool spawnablesLoaded;

		private static float nextSpawnTime;

		public static int SelectedSpawnableIndex
		{
			get
			{
				return selectedSpawnableIndex;
			}
			set
			{
				selectedSpawnableIndex = value;
			}
		}

		public static Vector2 SpawnableScroll
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return spawnableScroll;
			}
			set
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				spawnableScroll = value;
			}
		}

		public static int SpawnablePage
		{
			get
			{
				return spawnablePage;
			}
			set
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				int num = Mathf.Clamp(value, 0, Mathf.Max(0, GetPageCount() - 1));
				if (num != spawnablePage)
				{
					spawnableScroll = Vector2.zero;
				}
				spawnablePage = num;
			}
		}

		public static List<SpawnableSO> GetSpawnables()
		{
			EnsureSpawnablesLoaded();
			return cachedSpawnables;
		}

		public static void RefreshSpawnables()
		{
			LoadSpawnables();
		}

		public static SpawnableSO GetSelectedSpawnable()
		{
			List<SpawnableSO> spawnables = GetSpawnables();
			if (spawnables.Count <= 0)
			{
				return null;
			}
			if (selectedSpawnableIndex < 0)
			{
				selectedSpawnableIndex = 0;
			}
			if (selectedSpawnableIndex >= spawnables.Count)
			{
				selectedSpawnableIndex = spawnables.Count - 1;
			}
			return spawnables[selectedSpawnableIndex];
		}

		public static bool SpawnSelected()
		{
			SpawnableSO selectedSpawnable = GetSelectedSpawnable();
			return Spawn(selectedSpawnable);
		}

		public static bool Spawn(SpawnableSO spawnable)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextSpawnTime)
			{
				return false;
			}
			if (!NetworkServer.active || (Object)(object)spawnable == (Object)null || (Object)(object)spawnable.prefab == (Object)null)
			{
				return false;
			}
			nextSpawnTime = Time.unscaledTime + 0.15f;
			Vector3 spawnPosition = GetSpawnPosition();
			Quaternion identity = Quaternion.identity;
			GameObject val = Object.Instantiate<GameObject>(spawnable.prefab, spawnPosition, identity);
			Item val2 = val.GetComponent<Item>() ?? val.GetComponentInChildren<Item>();
			if ((Object)(object)val2 != (Object)null)
			{
				val2.spawnableSo = spawnable;
			}
			NetworkServer.Spawn(val, (NetworkConnectionToClient)null);
			ItemManager instance = NetworkSingleton<ItemManager>.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.ServerAddItem(spawnable);
				ConsumableItem item = default(ConsumableItem);
				if (val.TryGetComponent<ConsumableItem>(ref item) && !instance.spawnedItemInstances.Contains(item))
				{
					instance.spawnedItemInstances.Add(item);
				}
			}
			Debug.Log((object)("[DuckRaceTweaks] Spawned item: " + GetSpawnableName(spawnable)));
			return true;
		}

		public static string GetSpawnableName(SpawnableSO spawnable)
		{
			if ((Object)(object)spawnable == (Object)null)
			{
				return "Unknown Item";
			}
			if (!string.IsNullOrWhiteSpace(spawnable.spawnableName))
			{
				return spawnable.spawnableName;
			}
			return ((Object)spawnable).name;
		}

		public static string GetSpawnableButtonLabel(int index)
		{
			if (index < 0 || index >= cachedSpawnableButtonLabels.Count)
			{
				return "Unknown Item";
			}
			return cachedSpawnableButtonLabels[index];
		}

		public static int GetPageCount()
		{
			EnsureSpawnablesLoaded();
			return Mathf.Max(1, Mathf.CeilToInt((float)cachedSpawnables.Count / 16f));
		}

		public static int GetPageStartIndex()
		{
			return Mathf.Clamp(spawnablePage, 0, GetPageCount() - 1) * 16;
		}

		public static int GetPageEndIndex()
		{
			return Mathf.Min(GetPageStartIndex() + 16, cachedSpawnables.Count);
		}

		private static void EnsureSpawnablesLoaded()
		{
			if (!spawnablesLoaded)
			{
				LoadSpawnables();
			}
		}

		private static void LoadSpawnables()
		{
			spawnablesLoaded = true;
			cachedSpawnables.Clear();
			cachedSpawnableNames.Clear();
			cachedSpawnableButtonLabels.Clear();
			SpawnableSettings[] array = Resources.LoadAll<SpawnableSettings>(string.Empty);
			SpawnableSettings[] array2 = array;
			foreach (SpawnableSettings val in array2)
			{
				if ((Object)(object)val == (Object)null || val.spawnables == null)
				{
					continue;
				}
				foreach (SpawnableSO spawnable2 in val.spawnables)
				{
					if ((Object)(object)spawnable2 != (Object)null && (Object)(object)spawnable2.prefab != (Object)null && !cachedSpawnables.Contains(spawnable2))
					{
						cachedSpawnables.Add(spawnable2);
					}
				}
			}
			cachedSpawnables.Sort((SpawnableSO left, SpawnableSO right) => string.Compare(GetSpawnableName(left), GetSpawnableName(right), StringComparison.OrdinalIgnoreCase));
			for (int j = 0; j < cachedSpawnables.Count; j++)
			{
				SpawnableSO spawnable = cachedSpawnables[j];
				string spawnableName = GetSpawnableName(spawnable);
				cachedSpawnableNames.Add(spawnableName);
				cachedSpawnableButtonLabels.Add(spawnableName);
			}
			if (selectedSpawnableIndex >= cachedSpawnables.Count)
			{
				selectedSpawnableIndex = Mathf.Max(0, cachedSpawnables.Count - 1);
			}
			spawnablePage = Mathf.Clamp(spawnablePage, 0, Mathf.Max(0, GetPageCount() - 1));
		}

		private static Vector3 GetSpawnPosition()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0025: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Ray aimRay = GetAimRay();
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(aimRay, ref val, 50f, -5, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.35f;
			}
			Vector3 origin = ((Ray)(ref aimRay)).origin;
			Vector3 direction = ((Ray)(ref aimRay)).direction;
			return origin + ((Vector3)(ref direction)).normalized * 4f;
		}

		private static Ray GetAimRay()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				return main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
			}
			if ((Object)(object)NetworkClient.localPlayer != (Object)null)
			{
				Transform transform = ((Component)NetworkClient.localPlayer).transform;
				return new Ray(transform.position + Vector3.up * 1.5f, transform.forward);
			}
			return new Ray(Vector3.up, Vector3.forward);
		}
	}
	internal static class DuckRaceUi
	{
		private enum ModTab
		{
			DuckRace,
			SpinWheel,
			Slots,
			Crash,
			Items
		}

		private static ModTab selectedTab;

		private static Vector2 wheelDropdownScroll;

		private static Vector2 wheelResultScroll;

		private static Vector2 crashDropdownScroll;

		private static string crashMultiplierInput = "2.00";

		public static void Draw()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && NetworkClient.active)
			{
				float num = 330f;
				float num2 = 520f;
				float num3 = 20f;
				float num4 = 120f;
				GUILayout.BeginArea(new Rect(num3, num4, num, num2), GUI.skin.box);
				GUILayout.Label("DuckRaceTweaks", Array.Empty<GUILayoutOption>());
				GUILayout.Label(Plugin.MenuShortcutLabel + " = Toggle Menu", Array.Empty<GUILayoutOption>());
				GUILayout.Space(6f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Duck Race", Array.Empty<GUILayoutOption>()))
				{
					selectedTab = ModTab.DuckRace;
				}
				if (GUILayout.Button("Spin Wheel", Array.Empty<GUILayoutOption>()))
				{
					selectedTab = ModTab.SpinWheel;
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Slots", Array.Empty<GUILayoutOption>()))
				{
					selectedTab = ModTab.Slots;
				}
				if (GUILayout.Button("Crash", Array.Empty<GUILayoutOption>()))
				{
					selectedTab = ModTab.Crash;
				}
				GUILayout.EndHorizontal();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Items", Array.Empty<GUILayoutOption>()))
				{
					selectedTab = ModTab.Items;
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(8f);
				if (selectedTab == ModTab.DuckRace)
				{
					DrawDuckRaceTab();
				}
				else if (selectedTab == ModTab.SpinWheel)
				{
					DrawSpinWheelTab();
				}
				else if (selectedTab == ModTab.Slots)
				{
					DrawSlotsTab();
				}
				else if (selectedTab == ModTab.Crash)
				{
					DrawCrashTab();
				}
				else
				{
					DrawItemsTab();
				}
				GUILayout.EndArea();
			}
		}

		private static void DrawDuckRaceTab()
		{
			if (DuckRaceState.Tables.Count <= 0)
			{
				GUILayout.Label("No Duck Race tables found.", Array.Empty<GUILayoutOption>());
				return;
			}
			DuckRace selectedTable = DuckRaceState.GetSelectedTable();
			if ((Object)(object)selectedTable == (Object)null)
			{
				GUILayout.Label("No selected Duck Race table.", Array.Empty<GUILayoutOption>());
				return;
			}
			if (((GameBase)selectedTable).isPlaying || selectedTable.hasEnded)
			{
				GUILayout.Label("Duck Race is currently running.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Duck Race Winner Picker", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			string text = "Table " + (DuckRaceState.SelectedTableIndex + 1);
			if (GUILayout.Button("Selected Table: " + text, Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.DropdownOpen = !DuckRaceState.DropdownOpen;
			}
			if (DuckRaceState.DropdownOpen)
			{
				for (int i = 0; i < DuckRaceState.Tables.Count; i++)
				{
					DuckRace val = DuckRaceState.Tables[i];
					if (!((Object)(object)val == (Object)null))
					{
						string text2 = "Table " + (i + 1);
						if (i == DuckRaceState.SelectedTableIndex)
						{
							text2 += " ✓";
						}
						if (GUILayout.Button(text2, Array.Empty<GUILayoutOption>()))
						{
							DuckRaceState.SelectedTableIndex = i;
							DuckRaceState.DropdownOpen = false;
						}
					}
				}
			}
			GUILayout.Space(8f);
			int forcedWinner = DuckRaceState.GetForcedWinner(selectedTable);
			if (forcedWinner >= 0)
			{
				GUILayout.Label("Chosen Duck: Duck " + (forcedWinner + 1), Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Chosen Duck: None", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			if (GUILayout.Button("Pick Duck 1", Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.SetForcedWinner(selectedTable, 0);
			}
			if (GUILayout.Button("Pick Duck 2", Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.SetForcedWinner(selectedTable, 1);
			}
			if (GUILayout.Button("Pick Duck 3", Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.SetForcedWinner(selectedTable, 2);
			}
			if (GUILayout.Button("Pick Duck 4", Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.SetForcedWinner(selectedTable, 3);
			}
			GUILayout.Space(8f);
			if (GUILayout.Button("Clear Forced Winner", Array.Empty<GUILayoutOption>()))
			{
				DuckRaceState.ClearForcedWinner(selectedTable);
			}
		}

		private static void DrawSpinWheelTab()
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			List<Wheel> wheels = WheelState.GetWheels();
			if (wheels.Count <= 0)
			{
				GUILayout.Label("No server wheels found.", Array.Empty<GUILayoutOption>());
				return;
			}
			Wheel selectedWheel = WheelState.GetSelectedWheel();
			if ((Object)(object)selectedWheel == (Object)null)
			{
				GUILayout.Label("No selected wheel.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Spin Wheel Result Picker", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			string text = "Wheel " + (WheelState.SelectedWheelIndex + 1);
			if (GUILayout.Button("Selected Wheel: " + text, Array.Empty<GUILayoutOption>()))
			{
				WheelState.DropdownOpen = !WheelState.DropdownOpen;
			}
			if (WheelState.DropdownOpen)
			{
				wheelDropdownScroll = GUILayout.BeginScrollView(wheelDropdownScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) });
				for (int i = 0; i < wheels.Count; i++)
				{
					string text2 = "Wheel " + (i + 1);
					if (i == WheelState.SelectedWheelIndex)
					{
						text2 += " ✓";
					}
					if (GUILayout.Button(text2, Array.Empty<GUILayoutOption>()))
					{
						WheelState.SelectedWheelIndex = i;
						WheelState.DropdownOpen = false;
					}
				}
				GUILayout.EndScrollView();
			}
			GUILayout.Space(8f);
			WheelResult[] results = WheelReflection.GetResults(selectedWheel);
			int forcedResult = WheelState.GetForcedResult(selectedWheel);
			if (forcedResult >= 0 && forcedResult < results.Length)
			{
				GUILayout.Label("Next Result: " + results[forcedResult].result, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Next Result: Random", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			if (results.Length == 0)
			{
				GUILayout.Label("No results found on this wheel.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Rewards:", Array.Empty<GUILayoutOption>());
			wheelResultScroll = GUILayout.BeginScrollView(wheelResultScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(245f) });
			for (int j = 0; j < results.Length; j++)
			{
				string text3 = (string.IsNullOrWhiteSpace(results[j].result) ? ("Result " + (j + 1)) : results[j].result);
				if (j == forcedResult)
				{
					text3 += " ✓";
				}
				if (GUILayout.Button(text3, Array.Empty<GUILayoutOption>()))
				{
					WheelState.SetForcedResult(selectedWheel, j);
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(8f);
			if (GUILayout.Button("Clear Forced Wheel Result", Array.Empty<GUILayoutOption>()))
			{
				WheelState.ClearForcedResult(selectedWheel);
			}
		}

		private static void DrawSlotsTab()
		{
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			List<Slots> slotsMachines = SlotsState.GetSlotsMachines();
			if (slotsMachines.Count <= 0)
			{
				GUILayout.Label("No slot machines found.", Array.Empty<GUILayoutOption>());
				return;
			}
			Slots selectedSlots = SlotsState.GetSelectedSlots();
			if ((Object)(object)selectedSlots == (Object)null)
			{
				GUILayout.Label("No selected slot machine.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Slot Machine Result Picker", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			string text = "Slots " + (SlotsState.SelectedSlotsIndex + 1);
			if (GUILayout.Button("Selected Machine: " + text, Array.Empty<GUILayoutOption>()))
			{
				SlotsState.DropdownOpen = !SlotsState.DropdownOpen;
			}
			if (SlotsState.DropdownOpen)
			{
				for (int i = 0; i < slotsMachines.Count; i++)
				{
					string text2 = "Slots " + (i + 1);
					if (i == SlotsState.SelectedSlotsIndex)
					{
						text2 += " ✓";
					}
					if (GUILayout.Button(text2, Array.Empty<GUILayoutOption>()))
					{
						SlotsState.SelectedSlotsIndex = i;
						SlotsState.DropdownOpen = false;
					}
				}
			}
			GUILayout.Space(8f);
			int forcedSymbol = SlotsState.GetForcedSymbol(selectedSlots);
			if (forcedSymbol >= 0)
			{
				GUILayout.Label("Next Spin: Symbol " + forcedSymbol + " on every reel", Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Next Spin: Random", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			int symbolCount = SlotsReflection.GetSymbolCount(selectedSlots);
			if (symbolCount <= 0)
			{
				GUILayout.Label("No slot symbols found.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Symbols:", Array.Empty<GUILayoutOption>());
			SlotsState.SymbolScroll = GUILayout.BeginScrollView(SlotsState.SymbolScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(245f) });
			for (int j = 0; j < symbolCount; j++)
			{
				string text3 = "Force Symbol " + j;
				if (j == forcedSymbol)
				{
					text3 += " ✓";
				}
				if (GUILayout.Button(text3, Array.Empty<GUILayoutOption>()))
				{
					SlotsState.SetForcedSymbol(selectedSlots, j);
				}
			}
			GUILayout.EndScrollView();
			GUILayout.Space(8f);
			if (GUILayout.Button("Clear Forced Slots Result", Array.Empty<GUILayoutOption>()))
			{
				SlotsState.ClearForcedSymbol(selectedSlots);
			}
		}

		private static void DrawCrashTab()
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			List<Crash> crashes = CrashState.GetCrashes();
			if (crashes.Count <= 0)
			{
				GUILayout.Label("No Crash machines found.", Array.Empty<GUILayoutOption>());
				return;
			}
			Crash selectedCrash = CrashState.GetSelectedCrash();
			if ((Object)(object)selectedCrash == (Object)null)
			{
				GUILayout.Label("No selected Crash machine.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Crash Multiplier Picker", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			string text = "Crash " + (CrashState.SelectedCrashIndex + 1);
			if (GUILayout.Button("Selected Machine: " + text, Array.Empty<GUILayoutOption>()))
			{
				CrashState.DropdownOpen = !CrashState.DropdownOpen;
			}
			if (CrashState.DropdownOpen)
			{
				crashDropdownScroll = GUILayout.BeginScrollView(crashDropdownScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) });
				for (int i = 0; i < crashes.Count; i++)
				{
					string text2 = "Crash " + (i + 1);
					if (i == CrashState.SelectedCrashIndex)
					{
						text2 += " ✓";
					}
					if (GUILayout.Button(text2, Array.Empty<GUILayoutOption>()))
					{
						CrashState.SelectedCrashIndex = i;
						CrashState.DropdownOpen = false;
					}
				}
				GUILayout.EndScrollView();
			}
			GUILayout.Space(8f);
			if (CrashState.TryGetForcedMultiplier(selectedCrash, out var multiplier))
			{
				GUILayout.Label("Next Crash: " + multiplier.ToString("0.00") + "x", Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Next Crash: Random", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Multiplier", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
			crashMultiplierInput = GUILayout.TextField(crashMultiplierInput, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.EndHorizontal();
			if (GUILayout.Button("Set Next Crash Multiplier", Array.Empty<GUILayoutOption>()))
			{
				if (float.TryParse(crashMultiplierInput, out var result))
				{
					CrashState.SetForcedMultiplier(selectedCrash, result);
				}
				else
				{
					Debug.Log((object)("[DuckRaceTweaks] Invalid crash multiplier: " + crashMultiplierInput));
				}
			}
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("1.25x", Array.Empty<GUILayoutOption>()))
			{
				crashMultiplierInput = "1.25";
				CrashState.SetForcedMultiplier(selectedCrash, 1.25f);
			}
			if (GUILayout.Button("2.00x", Array.Empty<GUILayoutOption>()))
			{
				crashMultiplierInput = "2.00";
				CrashState.SetForcedMultiplier(selectedCrash, 2f);
			}
			if (GUILayout.Button("5.00x", Array.Empty<GUILayoutOption>()))
			{
				crashMultiplierInput = "5.00";
				CrashState.SetForcedMultiplier(selectedCrash, 5f);
			}
			GUILayout.EndHorizontal();
			if (GUILayout.Button("Clear Forced Crash Multiplier", Array.Empty<GUILayoutOption>()))
			{
				CrashState.ClearForcedMultiplier(selectedCrash);
			}
		}

		private static void DrawItemsTab()
		{
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			List<SpawnableSO> spawnables = ItemSpawnerState.GetSpawnables();
			if (spawnables.Count <= 0)
			{
				GUILayout.Label("No spawnable items found.", Array.Empty<GUILayoutOption>());
				return;
			}
			SpawnableSO selectedSpawnable = ItemSpawnerState.GetSelectedSpawnable();
			if ((Object)(object)selectedSpawnable == (Object)null)
			{
				GUILayout.Label("No selected item.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Item Spawner", Array.Empty<GUILayoutOption>());
			GUILayout.Space(6f);
			GUILayout.Label("Selected: " + ItemSpawnerState.GetSpawnableName(selectedSpawnable), Array.Empty<GUILayoutOption>());
			GUILayout.Label("ID: " + selectedSpawnable.spawnableID, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Spawn Selected Item", Array.Empty<GUILayoutOption>()))
			{
				ItemSpawnerState.SpawnSelected();
			}
			if (GUILayout.Button("Refresh Item List", Array.Empty<GUILayoutOption>()))
			{
				ItemSpawnerState.RefreshSpawnables();
			}
			GUILayout.Space(8f);
			GUILayout.Label("Items:", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("<", Array.Empty<GUILayoutOption>()))
			{
				ItemSpawnerState.SpawnablePage--;
			}
			GUILayout.Label("Page " + (ItemSpawnerState.SpawnablePage + 1) + " / " + ItemSpawnerState.GetPageCount(), Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(">", Array.Empty<GUILayoutOption>()))
			{
				ItemSpawnerState.SpawnablePage++;
			}
			GUILayout.EndHorizontal();
			ItemSpawnerState.SpawnableScroll = GUILayout.BeginScrollView(ItemSpawnerState.SpawnableScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(260f) });
			int pageStartIndex = ItemSpawnerState.GetPageStartIndex();
			int pageEndIndex = ItemSpawnerState.GetPageEndIndex();
			for (int i = pageStartIndex; i < pageEndIndex; i++)
			{
				SpawnableSO val = spawnables[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = ItemSpawnerState.GetSpawnableButtonLabel(i);
					if (i == ItemSpawnerState.SelectedSpawnableIndex)
					{
						text += " ✓";
					}
					if (GUILayout.Button(text, Array.Empty<GUILayoutOption>()))
					{
						ItemSpawnerState.SelectedSpawnableIndex = i;
					}
				}
			}
			GUILayout.EndScrollView();
		}
	}
	internal static class GameWorldLabels
	{
		public static void Draw()
		{
			if (NetworkServer.active && NetworkClient.active)
			{
				Camera main = Camera.main;
				if (!((Object)(object)main == (Object)null))
				{
					DrawDuckRaceLabels(main);
					DrawWheelLabels(main);
					DrawSlotsLabels(main);
					DrawCrashLabels(main);
					DrawKenoDiamondLabels(main);
					DrawMinesweeperMineLabels(main);
				}
			}
		}

		private static void DrawDuckRaceLabels(Camera camera)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<DuckRace> tables = DuckRaceState.Tables;
			for (int i = 0; i < tables.Count; i++)
			{
				DuckRace val = tables[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = "Duck Race " + (i + 1);
					if (i == DuckRaceState.SelectedTableIndex)
					{
						text += " ✓";
					}
					DrawLabel(camera, ((Component)val).transform.position + Vector3.up * 2.25f, text, 118f);
				}
			}
		}

		private static void DrawWheelLabels(Camera camera)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			List<Wheel> wheels = WheelState.GetWheels();
			if (wheels.Count <= 0)
			{
				return;
			}
			for (int i = 0; i < wheels.Count; i++)
			{
				Wheel val = wheels[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = "Wheel " + (i + 1);
					if (i == WheelState.SelectedWheelIndex)
					{
						text += " ✓";
					}
					DrawLabel(camera, ((Component)val).transform.position + Vector3.up * 2.25f, text, 90f);
				}
			}
		}

		private static void DrawSlotsLabels(Camera camera)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			List<Slots> slotsMachines = SlotsState.GetSlotsMachines();
			for (int i = 0; i < slotsMachines.Count; i++)
			{
				Slots val = slotsMachines[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = "Slots " + (i + 1);
					if (i == SlotsState.SelectedSlotsIndex)
					{
						text += " ✓";
					}
					DrawLabel(camera, ((Component)val).transform.position + Vector3.up * 2.25f, text, 90f);
				}
			}
		}

		private static void DrawCrashLabels(Camera camera)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			List<Crash> crashes = CrashState.GetCrashes();
			for (int i = 0; i < crashes.Count; i++)
			{
				Crash val = crashes[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = "Crash " + (i + 1);
					if (i == CrashState.SelectedCrashIndex)
					{
						text += " ✓";
					}
					DrawLabel(camera, ((Component)val).transform.position + Vector3.up * 2.25f, text, 90f);
				}
			}
		}

		private static void DrawKenoDiamondLabels(Camera camera)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			Keno[] array = Object.FindObjectsByType<Keno>((FindObjectsSortMode)0);
			Keno[] array2 = array;
			foreach (Keno val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				IReadOnlyList<int> orCreateDiamondButtonIndices = KenoState.GetOrCreateDiamondButtonIndices(val);
				if (orCreateDiamondButtonIndices.Count <= 0)
				{
					continue;
				}
				KenoButton[] buttons = KenoReflection.GetButtons(val);
				for (int j = 0; j < orCreateDiamondButtonIndices.Count; j++)
				{
					int num = orCreateDiamondButtonIndices[j];
					if (num >= 0 && num < buttons.Length && !((Object)(object)buttons[num] == (Object)null))
					{
						DrawLabel(camera, ((Component)buttons[num]).transform.position + Vector3.up * 0.35f, "Diamond " + (j + 1), 100f);
					}
				}
			}
		}

		private static void DrawMinesweeperMineLabels(Camera camera)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			Minesweeper[] array = Object.FindObjectsByType<Minesweeper>((FindObjectsSortMode)0);
			Minesweeper[] array2 = array;
			foreach (Minesweeper val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				IReadOnlyList<int> orCreateMineIndices = MinesweeperState.GetOrCreateMineIndices(val);
				if (orCreateMineIndices.Count <= 0)
				{
					continue;
				}
				List<MinesweeperTile> tiles = MinesweeperReflection.GetTiles(val);
				for (int j = 0; j < orCreateMineIndices.Count; j++)
				{
					int num = orCreateMineIndices[j];
					if (num >= 0 && num < tiles.Count && !((Object)(object)tiles[num] == (Object)null))
					{
						DrawLabel(camera, ((Component)tiles[num]).transform.position + Vector3.up * 0.35f, "Mine " + (j + 1), 78f);
					}
				}
			}
		}

		private static void DrawLabel(Camera camera, Vector3 worldPosition, string label, float width)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = camera.WorldToScreenPoint(worldPosition);
			if (!(val.z <= 0f))
			{
				float num = 24f;
				float num2 = val.x - width / 2f;
				float num3 = (float)Screen.height - val.y - num / 2f;
				GUI.Label(new Rect(num2, num3, width, num), label, GUI.skin.box);
			}
		}
	}
	internal static class DuckRaceReflection
	{
		private static readonly FieldInfo ducksField = AccessTools.Field(typeof(DuckRace), "ducks");

		private static readonly FieldInfo placedBetIndexField = AccessTools.Field(typeof(DuckRace), "_placedBetIndex");

		private static readonly PropertyInfo networkWinningDuckIndexProperty = AccessTools.Property(typeof(DuckRace), "Network_winningDuckIndex");

		private static readonly MethodInfo rpcPlaceBetFeedbackMethod = AccessTools.Method(typeof(DuckRace), "RpcPlaceBetFeedback", (Type[])null, (Type[])null);

		public static List<DuckRaceDuck> GetDucks(DuckRace race)
		{
			if ((Object)(object)race == (Object)null || ducksField == null)
			{
				return new List<DuckRaceDuck>();
			}
			return (ducksField.GetValue(race) as List<DuckRaceDuck>) ?? new List<DuckRaceDuck>();
		}

		public static void SetPlacedBetIndex(DuckRace race, int index)
		{
			placedBetIndexField?.SetValue(race, index);
		}

		public static void SetWinningDuckIndex(DuckRace race, int index)
		{
			networkWinningDuckIndexProperty?.SetValue(race, index, null);
		}

		public static void CallRpcPlaceBetFeedback(DuckRace race, int index)
		{
			rpcPlaceBetFeedbackMethod?.Invoke(race, new object[1] { index });
		}
	}
	internal static class CrashReflection
	{
		private static readonly MethodInfo raiseRoutineMethod = AccessTools.Method(typeof(Crash), "RaiseRoutine", (Type[])null, (Type[])null);

		public static bool StartRaiseRoutine(Crash crash, float crashPoint)
		{
			if ((Object)(object)crash == (Object)null || raiseRoutineMethod == null)
			{
				return false;
			}
			IEnumerator enumerator = (raiseRoutineMethod.Invoke(crash, new object[1] { crashPoint }) as IEnumerator) ?? null;
			if (enumerator == null)
			{
				return false;
			}
			((MonoBehaviour)crash).StartCoroutine(enumerator);
			return true;
		}
	}
	internal static class KenoReflection
	{
		private static readonly PropertyInfo buttonsProperty = AccessTools.Property(typeof(Keno), "Buttons");

		private static readonly FieldInfo diamondCountField = AccessTools.Field(typeof(Keno), "diamondCount");

		private static readonly FieldInfo revealDelayField = AccessTools.Field(typeof(Keno), "revealDelay");

		private static readonly FieldInfo selectedButtonsField = AccessTools.Field(typeof(Keno), "_selectedButtons");

		private static readonly MethodInfo getMultiplierMethod = AccessTools.Method(typeof(Keno), "GetMultiplier", (Type[])null, (Type[])null);

		private static readonly MethodInfo rpcDiamondRevealFeedbackMethod = AccessTools.Method(typeof(Keno), "RpcDiamondRevealFeedback", (Type[])null, (Type[])null);

		private static readonly MethodInfo endGameMethod = AccessTools.Method(typeof(Keno), "EndGame", (Type[])null, (Type[])null);

		public static bool CanMirrorGameRoutine => buttonsProperty != null && diamondCountField != null && revealDelayField != null && selectedButtonsField != null && getMultiplierMethod != null && rpcDiamondRevealFeedbackMethod != null && endGameMethod != null;

		public static KenoButton[] GetButtons(Keno keno)
		{
			if ((Object)(object)keno == (Object)null || buttonsProperty == null)
			{
				return Array.Empty<KenoButton>();
			}
			return (buttonsProperty.GetValue(keno, null) as KenoButton[]) ?? Array.Empty<KenoButton>();
		}

		public static int GetDiamondCount(Keno keno)
		{
			if ((Object)(object)keno == (Object)null || diamondCountField == null)
			{
				return 0;
			}
			return (diamondCountField.GetValue(keno) is int num) ? num : 0;
		}

		public static float GetRevealDelay(Keno keno)
		{
			if ((Object)(object)keno == (Object)null || revealDelayField == null)
			{
				return 0.1f;
			}
			return (revealDelayField.GetValue(keno) is float num) ? num : 0.1f;
		}

		public static List<KenoButton> GetSelectedButtons(Keno keno)
		{
			if ((Object)(object)keno == (Object)null || selectedButtonsField == null)
			{
				return new List<KenoButton>();
			}
			return (selectedButtonsField.GetValue(keno) as List<KenoButton>) ?? new List<KenoButton>();
		}

		public static double GetMultiplier(Keno keno, int hitCount)
		{
			if ((Object)(object)keno == (Object)null || getMultiplierMethod == null)
			{
				return 0.0;
			}
			return (getMultiplierMethod.Invoke(keno, new object[1] { hitCount }) is double num) ? num : 0.0;
		}

		public static void CallDiamondRevealFeedback(Keno keno, bool isHit, Vector3 position, int index)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			rpcDiamondRevealFeedbackMethod?.Invoke(keno, new object[3] { isHit, position, index });
		}

		public static void CallEndGame(Keno keno)
		{
			endGameMethod?.Invoke(keno, Array.Empty<object>());
		}
	}
	internal static class MinesweeperReflection
	{
		private static readonly FieldInfo tilesField = AccessTools.Field(typeof(Minesweeper), "tiles");

		private static readonly FieldInfo mineIndexesField = AccessTools.Field(typeof(Minesweeper), "_mineIndexes");

		private static readonly FieldInfo currentMineCountField = AccessTools.Field(typeof(Minesweeper), "_currentMineCount");

		public static bool CanSetMines => tilesField != null && mineIndexesField != null && currentMineCountField != null;

		public static List<MinesweeperTile> GetTiles(Minesweeper minesweeper)
		{
			if ((Object)(object)minesweeper == (Object)null || tilesField == null)
			{
				return new List<MinesweeperTile>();
			}
			return (tilesField.GetValue(minesweeper) as List<MinesweeperTile>) ?? new List<MinesweeperTile>();
		}

		public static int GetCurrentMineCount(Minesweeper minesweeper)
		{
			if ((Object)(object)minesweeper == (Object)null || currentMineCountField == null)
			{
				return 0;
			}
			return (currentMineCountField.GetValue(minesweeper) is int num) ? num : 0;
		}

		public static void SetMineIndexes(Minesweeper minesweeper, IEnumerable<int> mineIndexes)
		{
			if ((Object)(object)minesweeper == (Object)null || mineIndexesField == null)
			{
				return;
			}
			HashSet<int> hashSet = mineIndexesField.GetValue(minesweeper) as HashSet<int>;
			if (hashSet == null)
			{
				hashSet = new HashSet<int>();
				mineIndexesField.SetValue(minesweeper, hashSet);
			}
			hashSet.Clear();
			foreach (int mineIndex in mineIndexes)
			{
				hashSet.Add(mineIndex);
			}
		}
	}
	internal static class DuckRaceDuckReflection
	{
		private static readonly FieldInfo duckRaceField = AccessTools.Field(typeof(DuckRaceDuck), "duckRace");

		private static readonly FieldInfo minStepDelayField = AccessTools.Field(typeof(DuckRaceDuck), "minStepDelay");

		private static readonly FieldInfo maxStepDelayField = AccessTools.Field(typeof(DuckRaceDuck), "maxStepDelay");

		private static readonly FieldInfo minStepDistanceField = AccessTools.Field(typeof(DuckRaceDuck), "minStepDistance");

		private static readonly FieldInfo maxStepDistanceField = AccessTools.Field(typeof(DuckRaceDuck), "maxStepDistance");

		private static readonly FieldInfo stepTweenDurationField = AccessTools.Field(typeof(DuckRaceDuck), "stepTweenDuration");

		private static readonly MethodInfo rpcSetRunningAnimationMethod = AccessTools.Method(typeof(DuckRaceDuck), "RpcSetRunningAnimation", (Type[])null, (Type[])null);

		private static readonly MethodInfo rpcStepMethod = AccessTools.Method(typeof(DuckRaceDuck), "RpcStep", (Type[])null, (Type[])null);

		private static readonly MethodInfo rpcWinFeedbackMethod = AccessTools.Method(typeof(DuckRaceDuck), "RpcWinFeedback", (Type[])null, (Type[])null);

		public static DuckRace GetDuckRace(DuckRaceDuck duck)
		{
			if ((Object)(object)duck == (Object)null || duckRaceField == null)
			{
				return null;
			}
			object? value = duckRaceField.GetValue(duck);
			return (DuckRace)(((value is DuckRace) ? value : null) ?? null);
		}

		public static float GetMinStepDelay(DuckRaceDuck duck)
		{
			return GetFloat(minStepDelayField, duck, 0.5f);
		}

		public static float GetMaxStepDelay(DuckRaceDuck duck)
		{
			return GetFloat(maxStepDelayField, duck, 1f);
		}

		public static float GetMinStepDistance(DuckRaceDuck duck)
		{
			return GetFloat(minStepDistanceField, duck, 0.25f);
		}

		public static float GetMaxStepDistance(DuckRaceDuck duck)
		{
			return GetFloat(maxStepDistanceField, duck, 1f);
		}

		public static float GetStepTweenDuration(DuckRaceDuck duck)
		{
			return GetFloat(stepTweenDurationField, duck, 0.4f);
		}

		public static void CallRpcSetRunningAnimation(DuckRaceDuck duck, bool running)
		{
			rpcSetRunningAnimationMethod?.Invoke(duck, new object[1] { running });
		}

		public static void CallRpcStep(DuckRaceDuck duck, float targetZ)
		{
			rpcStepMethod?.Invoke(duck, new object[1] { targetZ });
		}

		public static void CallRpcWinFeedback(DuckRaceDuck duck)
		{
			rpcWinFeedbackMethod?.Invoke(duck, Array.Empty<object>());
		}

		private static float GetFloat(FieldInfo field, DuckRaceDuck duck, float fallback)
		{
			if (field == null || (Object)(object)duck == (Object)null)
			{
				return fallback;
			}
			if (field.GetValue(duck) is float result)
			{
				return result;
			}
			return fallback;
		}
	}
	internal static class SlotsReflection
	{
		private static readonly FieldInfo reelsField = AccessTools.Field(typeof(Slots), "reels");

		private static readonly FieldInfo spinDurationField = AccessTools.Field(typeof(Slots), "spinDuration");

		private static readonly FieldInfo delayBetweenReelsField = AccessTools.Field(typeof(Slots), "delayBetweenReels");

		public static List<SlotReel> GetReels(Slots slots)
		{
			if ((Object)(object)slots == (Object)null || reelsField == null)
			{
				return new List<SlotReel>();
			}
			return (reelsField.GetValue(slots) as List<SlotReel>) ?? new List<SlotReel>();
		}

		public static int GetSymbolCount(Slots slots)
		{
			List<SlotReel> reels = GetReels(slots);
			foreach (SlotReel item in reels)
			{
				if ((Object)(object)item != (Object)null && item.atlas != null)
				{
					return item.atlas.Length;
				}
			}
			return 0;
		}

		public static float GetSpinDuration(Slots slots)
		{
			return GetFloat(spinDurationField, slots, 5f);
		}

		public static float GetDelayBetweenReels(Slots slots)
		{
			return GetFloat(delayBetweenReelsField, slots, 1f);
		}

		public static int GetReelIndex(Slots slots, SlotReel reel)
		{
			return GetReels(slots).IndexOf(reel);
		}

		public static List<int> BuildForcedReelResult(SlotReel reel, int symbolIndex)
		{
			int visibleSymbolCount = GetVisibleSymbolCount(reel);
			List<int> list = new List<int>(visibleSymbolCount);
			for (int i = 0; i < visibleSymbolCount; i++)
			{
				list.Add(symbolIndex);
			}
			return list;
		}

		public static void ApplyForcedVisibleSymbols(SlotReel reel, int symbolIndex)
		{
			if (!((Object)(object)reel == (Object)null) && reel.symbols != null && reel.atlas != null && symbolIndex >= 0 && symbolIndex < reel.atlas.Length)
			{
				reel.symbols = (from symbol in reel.symbols
					where (Object)(object)symbol != (Object)null
					orderby ((Graphic)symbol).rectTransform.anchoredPosition.y descending
					select symbol).ToArray();
				int visibleSymbolCount = GetVisibleSymbolCount(reel);
				for (int i = 0; i < visibleSymbolCount; i++)
				{
					reel.symbols[i].sprite = reel.atlas[symbolIndex];
				}
			}
		}

		private static int GetVisibleSymbolCount(SlotReel reel)
		{
			if ((Object)(object)reel == (Object)null || reel.symbols == null)
			{
				return 0;
			}
			return Mathf.Max(0, reel.symbols.Length - 1);
		}

		private static float GetFloat(FieldInfo field, Slots slots, float fallback)
		{
			if (field == null || (Object)(object)slots == (Object)null)
			{
				return fallback;
			}
			if (field.GetValue(slots) is float result)
			{
				return result;
			}
			return fallback;
		}
	}
	internal static class WheelReflection
	{
		private static readonly PropertyInfo resultsProperty = AccessTools.Property(typeof(Wheel), "Results");

		private static readonly FieldInfo spinDurationField = AccessTools.Field(typeof(Wheel), "spinDuration");

		private static readonly FieldInfo minTurnAmountField = AccessTools.Field(typeof(Wheel), "minTurnAmount");

		private static readonly FieldInfo spinDirectionField = AccessTools.Field(typeof(Wheel), "spinDirection");

		private static readonly FieldInfo isSpinningField = AccessTools.Field(typeof(Wheel), "_isSpinning");

		private static readonly FieldInfo wheelTransformField = AccessTools.Field(typeof(Wheel), "wheelTransform");

		private static readonly FieldInfo resultSelectorField = AccessTools.Field(typeof(Wheel), "resultSelector");

		private static readonly FieldInfo rouletteBallWheelField = AccessTools.Field(typeof(RouletteWheel), "ballWheel");

		private static readonly MethodInfo rpcSpinWheelMethod = AccessTools.Method(typeof(Wheel), "RpcSpinWheel", (Type[])null, (Type[])null);

		private static readonly MethodInfo rpcResultFeedbackMethod = AccessTools.Method(typeof(Wheel), "RpcResultFeedback", (Type[])null, (Type[])null);

		private static readonly MethodInfo waitAndStopMethod = AccessTools.Method(typeof(Wheel), "WaitAndStop", (Type[])null, (Type[])null);

		private static readonly MethodInfo rouletteRpcSpinBallWheelMethod = AccessTools.Method(typeof(RouletteWheel), "RpcSpinBallWheel", (Type[])null, (Type[])null);

		public static WheelResult[] GetResults(Wheel wheel)
		{
			if ((Object)(object)wheel == (Object)null || resultsProperty == null)
			{
				return Array.Empty<WheelResult>();
			}
			return (resultsProperty.GetValue(wheel, null) as WheelResult[]) ?? Array.Empty<WheelResult>();
		}

		public static float GetSpinDuration(Wheel wheel)
		{
			return GetFloat(spinDurationField, wheel, 3f);
		}

		public static int GetMinTurnAmount(Wheel wheel)
		{
			if ((Object)(object)wheel == (Object)null || minTurnAmountField == null)
			{
				return 3;
			}
			if (minTurnAmountField.GetValue(wheel) is int result)
			{
				return result;
			}
			return 3;
		}

		public static bool GetSpinDirection(Wheel wheel)
		{
			if ((Object)(object)wheel == (Object)null || spinDirectionField == null)
			{
				return false;
			}
			if (spinDirectionField.GetValue(wheel) is bool result)
			{
				return result;
			}
			return false;
		}

		public static bool GetIsSpinning(Wheel wheel)
		{
			if ((Object)(object)wheel == (Object)null || isSpinningField == null)
			{
				return false;
			}
			if (isSpinningField.GetValue(wheel) is bool result)
			{
				return result;
			}
			return false;
		}

		public static void SetIsSpinning(Wheel wheel, bool value)
		{
			isSpinningField?.SetValue(wheel, value);
		}

		public static Transform GetWheelTransform(Wheel wheel)
		{
			object? obj = wheelTransformField?.GetValue(wheel);
			return (Transform)(((obj is Transform) ? obj : null) ?? null);
		}

		public static Transform GetResultSelector(Wheel wheel)
		{
			object? obj = resultSelectorField?.GetValue(wheel);
			return (Transform)(((obj is Transform) ? obj : null) ?? null);
		}

		public static Transform GetRouletteBallWheel(Wheel wheel)
		{
			object? obj = rouletteBallWheelField?.GetValue(wheel);
			return (Transform)(((obj is Transform) ? obj : null) ?? null);
		}

		public static void CallRpcSpinWheel(Wheel wheel, float finalAngle, float duration)
		{
			rpcSpinWheelMethod?.Invoke(wheel, new object[2] { finalAngle, duration });
		}

		public static void CallRpcSpinBallWheel(Wheel wheel, float finalAngle, float duration)
		{
			if (wheel is RouletteWheel)
			{
				rouletteRpcSpinBallWheelMethod?.Invoke(wheel, new object[2] { finalAngle, duration });
			}
		}

		public static void CallRpcResultFeedback(Wheel wheel, int index)
		{
			rpcResultFeedbackMethod?.Invoke(wheel, new object[1] { index });
		}

		public static IEnumerator CallWaitAndStop(Wheel wheel)
		{
			if (waitAndStopMethod == null)
			{
				return null;
			}
			return (waitAndStopMethod.Invoke(wheel, Array.Empty<object>()) as IEnumerator) ?? null;
		}

		public static float ComputeForcedFinalAngle(Wheel wheel, int resultIndex)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			Transform wheelTransform = GetWheelTransform(wheel);
			Transform resultSelector = GetResultSelector(wheel);
			WheelResult[] results = GetResults(wheel);
			if ((Object)(object)wheelTransform == (Object)null || (Object)(object)resultSelector == (Object)null || resultIndex < 0 || resultIndex >= results.Length)
			{
				return Random.Range(0f, 360f);
			}
			Vector3 val = wheelTransform.InverseTransformPoint(((Component)results[resultIndex]).transform.position);
			Vector3 val2 = ((!((Object)(object)wheelTransform.parent != (Object)null)) ? (resultSelector.position - wheelTransform.position) : (wheelTransform.parent.InverseTransformPoint(resultSelector.position) - wheelTransform.localPosition));
			float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
			float num2 = Mathf.Atan2(val2.y, val2.x) * 57.29578f;
			float num3 = Mathf.DeltaAngle(0f, num2 - num);
			float num4 = Mathf.DeltaAngle(0f, wheelTransform.localEulerAngles.z);
			int minTurnAmount = GetMinTurnAmount(wheel);
			bool spinDirection = GetSpinDirection(wheel);
			float num5 = num3;
			if (spinDirection)
			{
				for (; num5 <= num4; num5 += 360f)
				{
				}
				num5 += (float)minTurnAmount * 360f;
			}
			else
			{
				while (num5 >= num4)
				{
					num5 -= 360f;
				}
				num5 -= (float)minTurnAmount * 360f;
			}
			return 0f - num5;
		}

		public static float ComputeRouletteBallFinalAngle(Wheel wheel, int resultIndex, float wheelFinalAngle)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			Transform wheelTransform = GetWheelTransform(wheel);
			Transform rouletteBallWheel = GetRouletteBallWheel(wheel);
			WheelResult[] results = GetResults(wheel);
			if ((Object)(object)wheelTransform == (Object)null || (Object)(object)rouletteBallWheel == (Object)null || resultIndex < 0 || resultIndex >= results.Length)
			{
				return wheelFinalAngle;
			}
			Vector3 val = wheelTransform.InverseTransformPoint(((Component)results[resultIndex]).transform.position);
			float num = 0f - wheelFinalAngle;
			Matrix4x4 val2 = Matrix4x4.TRS(wheelTransform.localPosition, Quaternion.Euler(0f, 0f, num), wheelTransform.localScale);
			Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val);
			Vector3 val4 = (((Object)(object)wheelTransform.parent != (Object)null) ? wheelTransform.parent.TransformPoint(val3) : val3);
			Vector3 val5 = (((Object)(object)rouletteBallWheel.parent != (Object)null) ? (rouletteBallWheel.parent.InverseTransformPoint(val4) - rouletteBallWheel.localPosition) : (val4 - rouletteBallWheel.position));
			float num2 = Mathf.Atan2(val5.y, val5.x) * 57.29578f;
			float num3 = Mathf.DeltaAngle(0f, num2 - 90f);
			float num4 = Mathf.DeltaAngle(0f, rouletteBallWheel.localEulerAngles.z);
			float num5;
			for (num5 = num3; num5 >= num4; num5 -= 360f)
			{
			}
			num5 -= (float)GetMinTurnAmount(wheel) * 360f;
			return 0f - num5;
		}

		private static float GetFloat(FieldInfo field, Wheel wheel, float fallback)
		{
			if (field == null || (Object)(object)wheel == (Object)null)
			{
				return fallback;
			}
			if (field.GetValue(wheel) is float result)
			{
				return result;
			}
			return fallback;
		}
	}
	[HarmonyPatch(typeof(DuckRace), "OnAwake")]
	internal static class DuckRaceOnAwakePatch
	{
		private static void Postfix(DuckRace __instance)
		{
			DuckRaceState.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(DuckRace), "ResetGame")]
	internal static class DuckRaceResetGamePatch
	{
		private static void Postfix(DuckRace __instance)
		{
			DuckRaceState.ClearForcedWinner(__instance);
		}
	}
	[HarmonyPatch(typeof(Slots), "ResetGame")]
	internal static class SlotsResetGamePatch
	{
		private static void Postfix(Slots __instance)
		{
			SlotsState.ClearForcedSymbol(__instance);
		}
	}
	[HarmonyPatch(typeof(Keno), "ResetGame")]
	internal static class KenoResetGamePatch
	{
		private static void Postfix(Keno __instance)
		{
			KenoState.Clear(__instance);
		}
	}
	[HarmonyPatch(typeof(Minesweeper), "ResetGame")]
	internal static class MinesweeperResetGamePatch
	{
		private static void Postfix(Minesweeper __instance)
		{
			MinesweeperState.Clear(__instance);
		}
	}
	[HarmonyPatch(typeof(Minesweeper), "SetMines")]
	internal static class MinesweeperSetMinesPatch
	{
		private static bool Prefix(Minesweeper __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			if (!MinesweeperReflection.CanSetMines)
			{
				return true;
			}
			List<MinesweeperTile> tiles = MinesweeperReflection.GetTiles(__instance);
			if (tiles.Count <= 1)
			{
				return true;
			}
			int num2 = (__instance.Network_currentMineCount = Mathf.Clamp(MinesweeperReflection.GetCurrentMineCount(__instance), 1, tiles.Count - 1));
			List<int> list = (from index in MinesweeperState.ConsumeMineIndices(__instance)
				where index >= 0 && index < tiles.Count
				select index).Take(num2).ToList();
			if (list.Count < num2)
			{
				return true;
			}
			MinesweeperReflection.SetMineIndexes(__instance, list);
			Debug.Log((object)("[DuckRaceTweaks] Previewed Minesweeper mines applied: " + string.Join(", ", list)));
			return false;
		}
	}
	[HarmonyPatch(typeof(Keno), "GameRoutine")]
	internal static class KenoGameRoutinePatch
	{
		[CompilerGenerated]
		private sealed class <MirroredGameRoutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Keno keno;

			private KenoButton[] <buttons>5__1;

			private List<int> <selectedNumbers>5__2;

			private List<KenoButton> <selectedButtons>5__3;

			private int <hitCount>5__4;

			private int <i>5__5;

			private int <buttonIndex>5__6;

			private KenoButton <button>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<buttons>5__1 = null;
				<selectedNumbers>5__2 = null;
				<selectedButtons>5__3 = null;
				<button>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0180: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					<button>5__7 = null;
					goto IL_01c0;
				}
				<>1__state = -1;
				<buttons>5__1 = KenoReflection.GetButtons(keno);
				if (<buttons>5__1.Length == 0)
				{
					return false;
				}
				<selectedNumbers>5__2 = KenoState.GetOrCreateDiamondButtonIndices(keno).ToList();
				KenoState.SetDiamondButtonIndices(keno, <selectedNumbers>5__2);
				<selectedButtons>5__3 = KenoReflection.GetSelectedButtons(keno);
				<hitCount>5__4 = 0;
				<i>5__5 = 0;
				goto IL_01d2;
				IL_01c0:
				<i>5__5++;
				goto IL_01d2;
				IL_01d2:
				if (<i>5__5 < <selectedNumbers>5__2.Count)
				{
					<buttonIndex>5__6 = <selectedNumbers>5__2[<i>5__5];
					if (<buttonIndex>5__6 < 0 || <buttonIndex>5__6 >= <buttons>5__1.Length || (Object)(object)<buttons>5__1[<buttonIndex>5__6] == (Object)null)
					{
						goto IL_01c0;
					}
					<button>5__7 = <buttons>5__1[<buttonIndex>5__6];
					<button>5__7.ServerRevealDiamond(true);
					if (<selectedButtons>5__3.Contains(<button>5__7))
					{
						<hitCount>5__4++;
						keno.Network_currentMultiplier = KenoReflection.GetMultiplier(keno, <hitCount>5__4);
						KenoReflection.CallDiamondRevealFeedback(keno, isHit: true, ((Component)<button>5__7).transform.position, <i>5__5);
					}
					else
					{
						KenoReflection.CallDiamondRevealFeedback(keno, isHit: false, ((Component)<button>5__7).transform.position, <i>5__5);
					}
					<>2__current = (object)new WaitForSeconds(KenoReflection.GetRevealDelay(keno));
					<>1__state = 1;
					return true;
				}
				KenoReflection.CallEndGame(keno);
				return false;
			}

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

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

		private static bool Prefix(Keno __instance, ref IEnumerator __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			if (!KenoReflection.CanMirrorGameRoutine)
			{
				return true;
			}
			__result = MirroredGameRoutine(__instance);
			return false;
		}

		[IteratorStateMachine(typeof(<MirroredGameRoutine>d__1))]
		private static IEnumerator MirroredGameRoutine(Keno keno)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <MirroredGameRoutine>d__1(0)
			{
				keno = keno
			};
		}
	}
	[HarmonyPatch(typeof(Crash), "SetCrashPoint")]
	internal static class CrashSetCrashPointPatch
	{
		private static bool Prefix(Crash __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			if (!CrashState.TryConsumeForcedMultiplier(__instance, out var multiplier))
			{
				return true;
			}
			multiplier = Mathf.Max(1.01f, multiplier);
			if (!CrashReflection.StartRaiseRoutine(__instance, multiplier))
			{
				return true;
			}
			__instance.Network_hasStarted = true;
			Debug.Log((object)("[DuckRaceTweaks] Forced crash point started at: " + multiplier.ToString("0.00") + "x"));
			return false;
		}
	}
	[HarmonyPatch(typeof(Wheel), "SpinTheWheel")]
	internal static class WheelSpinTheWheelPatch
	{
		private static bool Prefix(Wheel __instance, Random rng)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			int forcedResult = WheelState.GetForcedResult(__instance);
			if (forcedResult < 0)
			{
				return true;
			}
			if (WheelReflection.GetIsSpinning(__instance))
			{
				return false;
			}
			WheelResult[] results = WheelReflection.GetResults(__instance);
			if (forcedResult < 0 || forcedResult >= results.Length)
			{
				WheelState.ClearForcedResult(__instance);
				return true;
			}
			WheelReflection.SetIsSpinning(__instance, value: true);
			float finalAngle = WheelReflection.ComputeForcedFinalAngle(__instance, forcedResult);
			float spinDuration = WheelReflection.GetSpinDuration(__instance);
			WheelReflection.CallRpcSpinWheel(__instance, finalAngle, spinDuration);
			IEnumerator enumerator = WheelReflection.CallWaitAndStop(__instance);
			if (enumerator != null)
			{
				((MonoBehaviour)__instance).StartCoroutine(enumerator);
			}
			Debug.Log((object)("[DuckRaceTweaks] Forced wheel spin started. Result: " + results[forcedResult].result));
			return false;
		}
	}
	[HarmonyPatch(typeof(RouletteWheel), "SpinTheWheel")]
	internal static class RouletteWheelSpinTheWheelPatch
	{
		private static bool Prefix(RouletteWheel __instance, Random rng)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			int forcedResult = WheelState.GetForcedResult((Wheel)(object)__instance);
			if (forcedResult < 0)
			{
				return true;
			}
			if (WheelReflection.GetIsSpinning((Wheel)(object)__instance))
			{
				return false;
			}
			WheelResult[] results = WheelReflection.GetResults((Wheel)(object)__instance);
			if (forcedResult < 0 || forcedResult >= results.Length)
			{
				WheelState.ClearForcedResult((Wheel)(object)__instance);
				return true;
			}
			WheelReflection.SetIsSpinning((Wheel)(object)__instance, value: true);
			float num = WheelReflection.ComputeForcedFinalAngle((Wheel)(object)__instance, forcedResult);
			float finalAngle = WheelReflection.ComputeRouletteBallFinalAngle((Wheel)(object)__instance, forcedResult, num);
			float spinDuration = WheelReflection.GetSpinDuration((Wheel)(object)__instance);
			WheelReflection.CallRpcSpinWheel((Wheel)(object)__instance, num, spinDuration);
			WheelReflection.CallRpcSpinBallWheel((Wheel)(object)__instance, finalAngle, spinDuration);
			IEnumerator enumerator = WheelReflection.CallWaitAndStop((Wheel)(object)__instance);
			if (enumerator != null)
			{
				((MonoBehaviour)__instance).StartCoroutine(enumerator);
			}
			Debug.Log((object)("[DuckRaceTweaks] Forced roulette spin started. Result: " + results[forcedResult].result));
			return false;
		}
	}
	[HarmonyPatch(typeof(Wheel), "FindResult")]
	internal static class WheelFindResultPatch
	{
		private static bool Prefix(Wheel __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!NetworkServer.active)
			{
				return true;
			}
			int forcedResult = WheelState.GetForcedResult(__instance);
			if (forcedResult < 0)
			{
				return true;
			}
			WheelResult[] results = WheelReflection.GetResults(__instance);
			if (forcedResult < 0 || forcedResult >= results.Length)
			{
				WheelState.ClearForcedResult(__instance);
				return true;
			}
			WheelReflection.CallRpcResultFeedback(__instance, forcedResult);
			__result = (string.IsNullOrWhiteSpace(results[forcedResult].result) ? "Unknown" : results[forcedResult].result);
			WheelState.ConsumeForcedResult(__instance);
			Debug.Log((object)("[DuckRaceTweaks] Forced wheel result returned: " + __result));
			return false;
		}
	}
	[HarmonyPatch(typeof(SlotReel), "GetResult")]
	internal static class SlotReelGetResultPatch
	{
		private static bool Prefix(SlotReel __instance, ref List<int> __result)
		{
			Slots slotsForReel = SlotsState.GetSlotsForReel(__instance);
			if ((Object)(object)slotsForReel == (Object)null)
			{
				return true;
			}
			int forcedSymbol = SlotsState.GetForcedSymbol(slotsForReel);
			if (forcedSymbol < 0)
			{
				return true;
			}
			__result = SlotsReflection.BuildForcedReelResult(__instance, forcedSymbol);
			return false;
		}
	}
	[HarmonyPatch(typeof(SlotReel), "UserCode_RpcStartScrolling__Single__Int32__Int32")]
	internal static class SlotReelStartScrollingPatch
	{
		[CompilerGenerated]
		private sealed class <ApplyForcedVisualsAfterSpin>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SlotReel reel;

			public int forcedSymbol;

			public float duration;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(duration);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					SlotsReflection.ApplyForcedVisibleSymbols(reel, forcedSymbol);
					return false;
				}
			}

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

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

		private static void Postfix(SlotReel __instance, float duration, int turnCount, int seed)
		{
			Slots slotsForReel = SlotsState.GetSlotsForReel(__instance);
			if (!((Object)(object)slotsForReel == (Object)null))
			{
				int forcedSymbol = SlotsState.GetForcedSymbol(slotsForReel);
				if (forcedSymbol >= 0)
				{
					((MonoBehaviour)__instance).StartCoroutine(ApplyForcedVisualsAfterSpin(__instance, forcedSymbol, duration));
				}
			}
		}

		[IteratorStateMachine(typeof(<ApplyForcedVisualsAfterSpin>d__1))]
		private static IEnumerator ApplyForcedVisualsAfterSpin(SlotReel reel, int forcedSymbol, float duration)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyForcedVisualsAfterSpin>d__1(0)
			{
				reel = reel,
				forcedSymbol = forcedSymbol,
				duration = duration
			};
		}
	}
	[HarmonyPatch(typeof(DuckRace), "UserCode_ServerPlaceBet__Int32")]
	internal static class DuckRaceServerPlaceBetPatch
	{
		private static bool Prefix(DuckRace __instance, int duckIndex)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (((GameBase)__instance).isPlaying)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(DuckRaceDuck), "DuckRaceRoutine")]
	internal static class DuckRaceDuckRoutinePatch
	{
		[CompilerGenerated]
		private sealed class <ForcedDuckRaceRoutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public DuckRaceDuck duck;

			public Random rng;

			private DuckRace <race>5__1;

			private int <forcedWinningDuckIndex>5__2;

			private int <myDuckIndex>5__3;

			private bool <hasForcedWinner>5__4;

			private bool <iAmForcedWinner>5__5;

			private float <endZ>5__6;

			private float <currentZ>5__7;

			private float <minStepDistance>5__8;

			private float <maxStepDistance>5__9;

			private float <stepTweenDuration>5__10;

			private float <stepDistance>5__11;

			private float <targetZ>5__12;

			private float <minStepDelay>5__13;

			private float <maxStepDelay>5__14;

			private float <seconds>5__15;

			private float <blockedFinishZ>5__16;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0314: Unknown result type (might be due to invalid IL or missing references)
				//IL_031e: Expected O, but got Unknown
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Unknown result type (might be due to invalid IL or missing references)
				//IL_0213: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<race>5__1 = DuckRaceDuckReflection.GetDuckRace(duck);
					if ((Object)(object)<race>5__1 == (Object)null)
					{
						return false;
					}
					DuckRaceDuckReflection.CallRpcSetRunningAnimation(duck, running: true);
					break;
				case 1:
					<>1__state = -1;
					if (Mathf.Approximately(<targetZ>5__12, <endZ>5__6) && (!<hasForcedWinner>5__4 | <iAmForcedWinner>5__5))
					{
						if (<race>5__1.OnDuckFinish(duck))
						{
							DuckRaceDuckReflection.CallRpcWinFeedback(duck);
						}
						DuckRaceDuckReflection.CallRpcSetRunningAnimation(duck, running: false);
						return false;
					}
					<minStepDelay>5__13 = DuckRaceDuckReflection.GetMinStepDelay(duck);
					<maxStepDelay>5__14 = DuckRaceDuckReflection.GetMaxStepDelay(duck);
					<seconds>5__15 = Mathf.Lerp(<minStepDelay>5__13, <maxStepDelay>5__14, (float)rng.NextDouble());
					if (<hasForcedWinner>5__4)
					{
						if (<iAmForcedWinner>5__5)
						{
							<seconds>5__15 *= 0.85f;
						}
						else
						{
							<seconds>5__15 *= 1.05f;
						}
					}
					<>2__current = (object)new WaitForSeconds(<seconds>5__15);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					break;
				}
				if (!<race>5__1.hasEnded)
				{
					<forcedWinningDuckIndex>5__2 = DuckRaceState.GetForcedWinner(<race>5__1);
					<myDuckIndex>5__3 = DuckRaceState.GetDuckIndex(<race>5__1, duck);
					<hasForcedWinner>5__4 = <forcedWinningDuckIndex>5__2 >= 0;
					<iAmForcedWinner>5__5 = <hasForcedWinner>5__4 && <myDuckIndex>5__3 == <forcedWinningDuckIndex>5__2;
					<endZ>5__6 = <race>5__1.endPoint.localPosition.z;
					<currentZ>5__7 = ((Component)duck).transform.localPosition.z;
					<minStepDistance>5__8 = DuckRaceDuckReflection.GetMinStepDistance(duck);
					<maxStepDistance>5__9 = DuckRaceDuckReflection.GetMaxStepDistance(duck);
					<stepTweenDuration>5__10 = DuckRaceDuckReflection.GetStepTweenDuration(duck);
					<stepDistance>5__11 = Mathf.Lerp(<minStepDistance>5__8, <maxStepDistance>5__9, (float)rng.NextDouble());
					if (<hasForcedWinner>5__4)
					{
						if (<iAmForcedWinner>5__5)
						{
							<stepDistance>5__11 *= 1.2f;
						}
						else
						{
							<stepDistance>5__11 *= 0.9f;
						}
					}
					<targetZ>5__12 = Mathf.Min(<currentZ>5__7 + <stepDistance>5__11, <endZ>5__6);
					if (<hasForcedWinner>5__4 && !<iAmForcedWinner>5__5)
					{
						<blockedFinishZ>5__16 = <endZ>5__6 - 0.75f;
						<targetZ>5__12 = Mathf.Min(<targetZ>5__12, <blockedFinishZ>5__16);
					}
					DuckRaceDuckReflection.CallRpcStep(duck, <targetZ>5__12);
					<>2__current = (object)new WaitForSeconds(<stepTweenDuration>5__10);
					<>1__state = 1;
					return true;
				}
				DuckRaceDuckReflection.CallRpcSetRunningAnimation(duck, running: false);
				return false;
			}

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

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

		private static bool Prefix(DuckRaceDuck __instance, Random rng, ref IEnumerator __result)
		{
			__result = ForcedDuckRaceRoutine(__instance, rng);
			return false;
		}

		[IteratorStateMachine(typeof(<ForcedDuckRaceRoutine>d__1))]
		private static IEnumerator ForcedDuckRaceRoutine(DuckRaceDuck duck, Random rng)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ForcedDuckRaceRoutine>d__1(0)
			{
				duck = duck,
				rng = rng
			};
		}
	}
}