Decompiled source of BossmanJack Mod v0.1.1

BepInEx/plugins/BossmanJackMod.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BossmanJackMod.State;
using BossmanJackMod.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BossmanJack Mod")]
[assembly: AssemblyDescription("A custom mod for CloverPit that adds BossmanJack Audios.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BossmanJack Mod")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("12345678-1234-1234-1234-123456789abc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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 BossmanJackMod
{
	[BepInPlugin("com.riggedchips.cloverpit.bossmanjackmod", "BossmanJack Mod", "1.0.0")]
	public class BossmanJackModPlugin : BaseUnityPlugin
	{
		private const string PluginGUID = "com.riggedchips.cloverpit.bossmanjackmod";

		private const string PluginName = "BossmanJack Mod";

		private const string PluginVersion = "1.0.0";

		public static ConfigEntry<bool> EnableBloom = null;

		public static ConfigEntry<float> BloomIntensity = null;

		public static ConfigEntry<Color> BloomColor = null;

		public static ConfigEntry<bool> DisableMotionBlur = null;

		public static ConfigEntry<bool> DisableVignette = null;

		public static ConfigEntry<bool> EnableVSync = null;

		public static ConfigEntry<int> TargetFPS = null;

		public static ConfigEntry<float> TimeScale = null;

		public static ConfigEntry<bool> EnableCustomSlotImage = null;

		public static ConfigEntry<string> CustomSlotImagePath = null;

		public static ConfigEntry<bool> EnableCustomNoSpinsImage = null;

		public static ConfigEntry<string> CustomNoSpinsImagePath = null;

		public static ConfigEntry<bool> EnableNoSpinsFlash = null;

		public static ConfigEntry<float> NoSpinsFlashSpeed = null;

		public static ConfigEntry<float> NoSpinsFlashMinAlpha = null;

		public static ConfigEntry<bool> EnableNoSpinsSound = null;

		public static ConfigEntry<string> NoSpinsSoundFolder = null;

		public static ConfigEntry<float> NoSpinsSoundVolume = null;

		public static ConfigEntry<bool> EnableDeadlineSound = null;

		public static ConfigEntry<string> DeadlineSoundFolder = null;

		public static ConfigEntry<float> DeadlineSoundVolume = null;

		public static ConfigEntry<bool> EnableJackpotSound = null;

		public static ConfigEntry<string> JackpotSoundFolder = null;

		public static ConfigEntry<float> JackpotSoundVolume = null;

		public static ConfigEntry<bool> ForceJackpotTest = null;

		public static ConfigEntry<bool> Force666Test = null;

		public static ConfigEntry<bool> Enable666Sound = null;

		public static ConfigEntry<string> Sound666Folder = null;

		public static ConfigEntry<float> Sound666Volume = null;

		public static ManualLogSource Log { get; private set; } = null;


		internal static Assembly ModAssembly { get; private set; } = null;


		internal static string AssetRoot { get; private set; } = string.Empty;


		private void Awake()
		{
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"BossmanJack Mod v1.0.0 is loading...");
			string text = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
			Log.LogDebug((object)("Resolved plugin directory: " + text));
			string text3 = (AssetRoot = DetermineAssetRoot(text));
			ModAssembly = typeof(BossmanJackModPlugin).Assembly;
			Log.LogDebug((object)("Resolved asset root: " + text3));
			EnableVSync = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableVSync", true, "Enable vertical sync");
			TargetFPS = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TargetFPS", 60, "Target FPS (0 for unlimited)");
			TimeScale = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "TimeScale", 1f, "Game time scale");
			EnableCustomSlotImage = ((BaseUnityPlugin)this).Config.Bind<bool>("SlotMachine", "EnableCustomTitleImage", true, "Enable custom image on Slot Machine title/intro screen and Devil Horns powerup");
			CustomSlotImagePath = ((BaseUnityPlugin)this).Config.Bind<string>("SlotMachine", "CustomTitleImagePath", Path.Combine(text3, "custom_logo.png"), "Full path to custom title screen image (PNG, JPG supported)");
			EnableCustomNoSpinsImage = ((BaseUnityPlugin)this).Config.Bind<bool>("SlotMachine", "EnableCustomNoSpinsImage", true, "Enable custom image on 'No Spins Left' screen (replaces devil icon)");
			CustomNoSpinsImagePath = ((BaseUnityPlugin)this).Config.Bind<string>("SlotMachine", "CustomNoSpinsImagePath", Path.Combine(text3, "no_spins_devil.png"), "Full path to custom 'No Spins Left' screen image (PNG, JPG supported)");
			EnableNoSpinsFlash = ((BaseUnityPlugin)this).Config.Bind<bool>("SlotMachine", "EnableNoSpinsFlash", true, "Enable flashing/fading animation on 'No Spins Left' image");
			NoSpinsFlashSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("SlotMachine", "NoSpinsFlashSpeed", 5f, "Speed of the flash animation (higher = faster)");
			NoSpinsFlashMinAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("SlotMachine", "NoSpinsFlashMinAlpha", 0.3f, "Minimum transparency during flash (0 = invisible, 1 = fully visible)");
			EnableNoSpinsSound = ((BaseUnityPlugin)this).Config.Bind<bool>("NoSpinsSound", "EnableSound", true, "Enable random sound playback when 'No Spins Left' screen appears");
			NoSpinsSoundFolder = ((BaseUnityPlugin)this).Config.Bind<string>("NoSpinsSound", "SoundFolder", Path.Combine(text3, "no_spin_sounds"), "Folder containing sound files to play randomly (supports .wav, .ogg, .mp3)");
			NoSpinsSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("NoSpinsSound", "Volume", 0.8f, "Volume of the 'No Spins' sound (0.0 to 1.0)");
			EnableDeadlineSound = ((BaseUnityPlugin)this).Config.Bind<bool>("DeadlineSound", "EnableSound", true, "Enable distance-based sound triggers for deadline requirements (closer to deadline = different sounds)");
			DeadlineSoundFolder = ((BaseUnityPlugin)this).Config.Bind<string>("DeadlineSound", "SoundFolder", Path.Combine(text3, "deadline_sounds"), "Base folder with subfolders: 'far' (>50% remaining), 'medium' (25-50%), 'close' (10-25%), 'critical' (<10%)");
			DeadlineSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("DeadlineSound", "Volume", 0.7f, "Volume of deadline sounds (0.0 to 1.0)");
			EnableJackpotSound = ((BaseUnityPlugin)this).Config.Bind<bool>("JackpotSound", "EnableSound", true, "Enable sound playback on jackpot or coin wins");
			JackpotSoundFolder = ((BaseUnityPlugin)this).Config.Bind<string>("JackpotSound", "SoundFolder", Path.Combine(text3, "jackpot_sounds"), "Folder containing jackpot/win sound files (supports .wav, .ogg, .mp3)");
			JackpotSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("JackpotSound", "Volume", 0.9f, "Volume of jackpot/win sounds (0.0 to 1.0)");
			ForceJackpotTest = ((BaseUnityPlugin)this).Config.Bind<bool>("DEBUG", "ForceJackpot", false, "TESTING ONLY: Force every spin to be a jackpot (all symbols the same)");
			Force666Test = ((BaseUnityPlugin)this).Config.Bind<bool>("DEBUG", "Force666", false, "TESTING ONLY: Force every spin to have three sixes in a horizontal line");
			Enable666Sound = ((BaseUnityPlugin)this).Config.Bind<bool>("666Sound", "EnableSound", true, "Enable sound playback when three sixes appear in a horizontal line");
			Sound666Folder = ((BaseUnityPlugin)this).Config.Bind<string>("666Sound", "SoundFolder", Path.Combine(text3, "666_sounds"), "Folder containing 666 sound files (supports .wav, .ogg, .mp3)");
			Sound666Volume = ((BaseUnityPlugin)this).Config.Bind<float>("666Sound", "Volume", 1f, "Volume of the 666 sound (0.0 to 1.0)");
			MigrateAssetPath(CustomSlotImagePath, text3, "custom_logo.png", isFolder: false);
			MigrateAssetPath(CustomNoSpinsImagePath, text3, "no_spins_devil.png", isFolder: false);
			MigrateAssetPath(NoSpinsSoundFolder, text3, "no_spin_sounds", isFolder: true);
			MigrateAssetPath(DeadlineSoundFolder, text3, "deadline_sounds", isFolder: true);
			MigrateAssetPath(JackpotSoundFolder, text3, "jackpot_sounds", isFolder: true);
			MigrateAssetPath(Sound666Folder, text3, "666_sounds", isFolder: true);
			Log.LogDebug((object)("Attempting to provision custom_logo.png to: " + CustomSlotImagePath.Value));
			DefaultAssetProvisioner.EnsureAssetFile(CustomSlotImagePath, "custom_logo.png");
			Log.LogDebug((object)("Attempting to provision no_spins_devil.png to: " + CustomNoSpinsImagePath.Value));
			DefaultAssetProvisioner.EnsureAssetFile(CustomNoSpinsImagePath, "no_spins_devil.png");
			if (File.Exists(CustomSlotImagePath.Value))
			{
				Log.LogInfo((object)("✓ custom_logo.png exists at: " + CustomSlotImagePath.Value));
			}
			else
			{
				Log.LogWarning((object)("✗ custom_logo.png NOT FOUND at: " + CustomSlotImagePath.Value));
			}
			if (File.Exists(CustomNoSpinsImagePath.Value))
			{
				Log.LogInfo((object)("✓ no_spins_devil.png exists at: " + CustomNoSpinsImagePath.Value));
			}
			else
			{
				Log.LogWarning((object)("✗ no_spins_devil.png NOT FOUND at: " + CustomNoSpinsImagePath.Value));
			}
			ApplyPerformanceSettings();
			try
			{
				new Harmony("com.riggedchips.cloverpit.bossmanjackmod").PatchAll();
				Log.LogInfo((object)"BossmanJack Mod patched successfully!");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to apply patches: {arg}");
			}
			if (EnableNoSpinsSound.Value)
			{
				try
				{
					SoundManager.Instance.LoadSoundsFromFolder(NoSpinsSoundFolder.Value);
					Log.LogInfo((object)"SoundManager initialized for No Spins sounds");
				}
				catch (Exception arg2)
				{
					Log.LogError((object)$"Failed to initialize SoundManager: {arg2}");
				}
			}
			Log.LogInfo((object)"BossmanJack Mod loaded successfully!");
		}

		private void ApplyPerformanceSettings()
		{
			QualitySettings.vSyncCount = (EnableVSync.Value ? 1 : 0);
			Application.targetFrameRate = TargetFPS.Value;
			Time.timeScale = TimeScale.Value;
			Log.LogInfo((object)$"Performance settings applied - VSync: {EnableVSync.Value}, Target FPS: {TargetFPS.Value}, Time Scale: {TimeScale.Value}");
		}

		private void Update()
		{
			if (Input.GetKey((KeyCode)306) && Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)114))
			{
				Log.LogInfo((object)"Reloading settings...");
				ApplyPerformanceSettings();
			}
		}

		private static string DetermineAssetRoot(string pluginDirectory)
		{
			string text = Path.Combine(pluginDirectory, "BossmanJackMod");
			if (!Directory.Exists(text))
			{
				return pluginDirectory;
			}
			return text;
		}

		private static void MigrateAssetPath(ConfigEntry<string> entry, string assetRoot, string relativeName, bool isFolder)
		{
			try
			{
				string value = entry.Value;
				if (string.IsNullOrWhiteSpace(value))
				{
					entry.Value = Path.Combine(assetRoot, relativeName);
				}
				else if (!(isFolder ? Directory.Exists(value) : File.Exists(value)))
				{
					string text = Path.Combine(assetRoot, relativeName);
					if (isFolder ? Directory.Exists(text) : File.Exists(text))
					{
						entry.Value = text;
						Log.LogInfo((object)("Updated config entry '" + ((ConfigEntryBase)entry).Definition.Key + "' to new plugin asset path: " + text));
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to migrate config entry '" + ((ConfigEntryBase)entry).Definition.Key + "': " + ex.Message));
			}
		}
	}
	internal static class DefaultAssetProvisioner
	{
		public static void EnsureAssetFile(ConfigEntry<string> configEntry, string embeddedResourceName)
		{
			string embeddedResourceName2 = embeddedResourceName;
			try
			{
				string value = configEntry.Value;
				if (string.IsNullOrWhiteSpace(value) || File.Exists(value))
				{
					return;
				}
				string directoryName = Path.GetDirectoryName(value);
				if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				Assembly modAssembly = BossmanJackModPlugin.ModAssembly;
				string[] manifestResourceNames = modAssembly.GetManifestResourceNames();
				BossmanJackModPlugin.Log.LogDebug((object)("Available embedded resources: " + string.Join(", ", manifestResourceNames)));
				string text = manifestResourceNames.FirstOrDefault((string n) => n.EndsWith("." + embeddedResourceName2, StringComparison.OrdinalIgnoreCase)) ?? manifestResourceNames.FirstOrDefault((string n) => n.Equals(embeddedResourceName2, StringComparison.OrdinalIgnoreCase)) ?? manifestResourceNames.FirstOrDefault((string n) => n.IndexOf(embeddedResourceName2, StringComparison.OrdinalIgnoreCase) >= 0);
				if (text == null)
				{
					BossmanJackModPlugin.Log.LogWarning((object)("Embedded asset '" + embeddedResourceName2 + "' was not found in resources. Available resources: [" + string.Join(", ", manifestResourceNames) + "]. Cannot provision " + value + "."));
					return;
				}
				BossmanJackModPlugin.Log.LogDebug((object)("Found matching resource: '" + text + "' for '" + embeddedResourceName2 + "'"));
				using Stream stream = modAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					BossmanJackModPlugin.Log.LogWarning((object)("Embedded asset '" + embeddedResourceName2 + "' was not found in resources. Cannot provision " + value + "."));
					return;
				}
				using FileStream destination = File.Create(value);
				stream.CopyTo(destination);
				BossmanJackModPlugin.Log.LogInfo((object)("Provisioned default asset '" + embeddedResourceName2 + "' to " + value));
			}
			catch (Exception ex)
			{
				BossmanJackModPlugin.Log.LogWarning((object)("Failed to provision default asset '" + embeddedResourceName2 + "' for " + ((ConfigEntryBase)configEntry).Definition.Key + ": " + ex.Message));
			}
		}
	}
	public class ImageFlasher : MonoBehaviour
	{
		private RawImage rawImage;

		private Image image;

		private CanvasGroup canvasGroup;

		private float timer;

		public float flashSpeed = 2f;

		public float minAlpha = 0.3f;

		public float maxAlpha = 1f;

		private void Awake()
		{
			rawImage = ((Component)this).GetComponent<RawImage>();
			image = ((Component)this).GetComponent<Image>();
			if ((Object)(object)rawImage == (Object)null && (Object)(object)image == (Object)null)
			{
				canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			}
		}

		private void Update()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			timer += Time.deltaTime * flashSpeed;
			float num = Mathf.Lerp(minAlpha, maxAlpha, (Mathf.Sin(timer) + 1f) / 2f);
			if ((Object)(object)rawImage != (Object)null)
			{
				Color color = ((Graphic)rawImage).color;
				color.a = num;
				((Graphic)rawImage).color = color;
			}
			else if ((Object)(object)image != (Object)null)
			{
				Color color2 = ((Graphic)image).color;
				color2.a = num;
				((Graphic)image).color = color2;
			}
			else if ((Object)(object)canvasGroup != (Object)null)
			{
				canvasGroup.alpha = num;
			}
		}
	}
	internal static class DeadlineSoundCoordinator
	{
		[CompilerGenerated]
		private sealed class <PlayAfterSmallDelay>d__11 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			private (int coins, int total, float volume) <request>5__2;

			private SoundManager <manager>5__3;

			private float <timeout>5__4;

			private float <elapsed>5__5;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					isProcessing = true;
					if (!pendingRequest.HasValue)
					{
						activeRoutine = null;
						isProcessing = false;
						return false;
					}
					<request>5__2 = pendingRequest.Value;
					pendingRequest = null;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<manager>5__3 = SoundManager.GetInstance("Deadline");
					<manager>5__3.LoadSoundsForRoundCoins(BossmanJackModPlugin.DeadlineSoundFolder.Value, <request>5__2.coins);
					Log.LogInfo((object)$"Coin-based sound triggered: earned {<request>5__2.coins} coins this round (total: {<request>5__2.total})");
					<timeout>5__4 = 5f;
					<elapsed>5__5 = 0f;
					break;
				case 2:
					<>1__state = -1;
					<elapsed>5__5 += 0.05f;
					break;
				}
				if (!<manager>5__3.IsInitialized() && <manager>5__3.IsLoading() && <elapsed>5__5 < <timeout>5__4)
				{
					<>2__current = (object)new WaitForSeconds(0.05f);
					<>1__state = 2;
					return true;
				}
				if (<manager>5__3.IsInitialized())
				{
					<manager>5__3.PlayRandomSound(<request>5__2.volume);
				}
				else
				{
					Log.LogWarning((object)$"Deadline sound manager failed to initialize after {<elapsed>5__5}s");
				}
				activeRoutine = null;
				isProcessing = 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 jackpotActive;

		private static (int coins, int total, float volume)? pendingRequest;

		private static Coroutine activeRoutine;

		private static bool isProcessing;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		static DeadlineSoundCoordinator()
		{
			SlotMachineUnifiedUpdatePatch.JackpotStarted += OnJackpotStarted;
			SlotMachineUnifiedUpdatePatch.JackpotEnded += OnJackpotEnded;
		}

		private static void OnJackpotStarted()
		{
			jackpotActive = true;
			Log.LogDebug((object)"Jackpot started - deadline sounds will wait");
		}

		private static void OnJackpotEnded()
		{
			jackpotActive = false;
			Log.LogDebug((object)"Jackpot ended - checking for pending deadline sound");
			if (pendingRequest.HasValue)
			{
				StartOrRestartRoutine((MonoBehaviour)(object)SoundManager.GetInstance("Deadline"));
			}
		}

		public static void Request(int coinsEarned, int totalCoins, float volume)
		{
			pendingRequest = (coinsEarned, totalCoins, volume);
			Log.LogDebug((object)$"Deadline sound requested: {coinsEarned} coins (jackpot active: {jackpotActive}, processing: {isProcessing})");
			if (jackpotActive)
			{
				Log.LogDebug((object)"Jackpot is active - deadline sound will wait");
				return;
			}
			if (isProcessing)
			{
				Log.LogDebug((object)"Already processing a deadline sound request - will restart");
			}
			StartOrRestartRoutine((MonoBehaviour)(object)SoundManager.GetInstance("Deadline"));
		}

		private static void StartOrRestartRoutine(MonoBehaviour runner)
		{
			if (activeRoutine != null)
			{
				runner.StopCoroutine(activeRoutine);
				activeRoutine = null;
				Log.LogDebug((object)"Stopped previous deadline sound routine");
			}
			activeRoutine = runner.StartCoroutine(PlayAfterSmallDelay());
		}

		[IteratorStateMachine(typeof(<PlayAfterSmallDelay>d__11))]
		private static IEnumerator PlayAfterSmallDelay()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PlayAfterSmallDelay>d__11(0);
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Set_NoMoreSpins")]
	public class SlotMachineNoSpinsUnifiedPatch
	{
		private static Texture2D customImage;

		private static Sprite customSprite;

		private static bool attemptedLoad;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPrefix]
		private static void Prefix()
		{
		}

		[HarmonyPostfix]
		private static void Postfix(SlotMachineScript __instance)
		{
			if (BossmanJackModPlugin.EnableDeadlineSound.Value)
			{
				try
				{
					int coinsEarned = (int)GameplayData.RoundEarnedCoinsGet();
					int totalCoins = (int)GameplayData.CoinsGet();
					DeadlineSoundCoordinator.Request(coinsEarned, totalCoins, BossmanJackModPlugin.DeadlineSoundVolume.Value);
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Error playing coin-based sound: {arg}");
				}
			}
			else if (BossmanJackModPlugin.EnableNoSpinsSound.Value)
			{
				try
				{
					SoundManager instance = SoundManager.Instance;
					if (instance.IsInitialized())
					{
						instance.PlayRandomSound(BossmanJackModPlugin.NoSpinsSoundVolume.Value);
					}
					else
					{
						Log.LogWarning((object)"SoundManager not initialized - cannot play No Spins sound");
					}
				}
				catch (Exception arg2)
				{
					Log.LogError((object)$"Error playing No Spins sound: {arg2}");
				}
			}
			if (BossmanJackModPlugin.EnableDeadlineSound.Value)
			{
				try
				{
					Type type = Type.GetType("Sound, Assembly-CSharp");
					if (type != null)
					{
						MethodInfo method = type.GetMethod("Stop", new Type[1] { typeof(string) });
						if (method != null)
						{
							method.Invoke(null, new object[1] { "SoundSlotNoMoreCoins" });
							Log.LogDebug((object)"Stopped original 'SoundSlotNoMoreCoins' (using deadline sound instead)");
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Could not stop original no-coins sound: " + ex.Message));
				}
			}
			if (!BossmanJackModPlugin.EnableCustomNoSpinsImage.Value)
			{
				return;
			}
			if ((Object)(object)customImage == (Object)null && !attemptedLoad)
			{
				attemptedLoad = true;
				customImage = TextureLoader.LoadTexture(BossmanJackModPlugin.CustomNoSpinsImagePath.Value);
				if (!((Object)(object)customImage != (Object)null))
				{
					Log.LogWarning((object)"Failed to load custom No Spins image. Using original.");
					return;
				}
				customSprite = TextureLoader.CreateSprite(customImage);
				Log.LogInfo((object)$"Custom No Spins image loaded successfully! Size: {((Texture)customImage).width}x{((Texture)customImage).height}");
			}
			if ((Object)(object)customImage != (Object)null && (Object)(object)__instance.noMoreSpinsScreenHolder != (Object)null)
			{
				RawImage[] componentsInChildren = __instance.noMoreSpinsScreenHolder.GetComponentsInChildren<RawImage>(true);
				if (componentsInChildren.Length != 0)
				{
					Log.LogInfo((object)$"Found {componentsInChildren.Length} RawImage component(s) in noMoreSpinsScreenHolder");
					RawImage[] array = componentsInChildren;
					foreach (RawImage val in array)
					{
						val.texture = (Texture)(object)customImage;
						Log.LogInfo((object)("Custom image applied to RawImage: " + ((Object)val).name));
						if (BossmanJackModPlugin.EnableNoSpinsFlash.Value)
						{
							AddVisibilityToggle(((Component)val).gameObject);
						}
					}
					return;
				}
				Image[] componentsInChildren2 = __instance.noMoreSpinsScreenHolder.GetComponentsInChildren<Image>(true);
				if (componentsInChildren2.Length != 0)
				{
					Log.LogInfo((object)$"Found {componentsInChildren2.Length} Image component(s) in noMoreSpinsScreenHolder");
					Image[] array2 = componentsInChildren2;
					foreach (Image val2 in array2)
					{
						val2.sprite = customSprite;
						Log.LogInfo((object)("Custom image applied to Image: " + ((Object)val2).name));
						if (BossmanJackModPlugin.EnableNoSpinsFlash.Value)
						{
							AddVisibilityToggle(((Component)val2).gameObject);
						}
					}
				}
				else
				{
					Log.LogWarning((object)"Could not find any Image or RawImage components in noMoreSpinsScreenHolder");
				}
			}
			else if ((Object)(object)__instance.noMoreSpinsScreenHolder == (Object)null)
			{
				Log.LogWarning((object)"noMoreSpinsScreenHolder is null - cannot replace image");
			}
		}

		private static void AddVisibilityToggle(GameObject target)
		{
			if ((Object)(object)target.GetComponent<VisibilityToggler>() != (Object)null)
			{
				Log.LogDebug((object)("VisibilityToggler already exists on " + ((Object)target).name));
				return;
			}
			VisibilityToggler visibilityToggler = target.AddComponent<VisibilityToggler>();
			visibilityToggler.toggleInterval = 1f / BossmanJackModPlugin.NoSpinsFlashSpeed.Value;
			Log.LogInfo((object)$"Added VisibilityToggler to {((Object)target).name} (Speed: {BossmanJackModPlugin.NoSpinsFlashSpeed.Value}, Interval: {visibilityToggler.toggleInterval})");
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Start")]
	public class SlotMachineTitleImagePatch
	{
		private static Texture2D customTitleTexture;

		private static bool attemptedLoad;

		private static bool loadFailed;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPostfix]
		private static void Postfix(SlotMachineScript __instance)
		{
			if (!BossmanJackModPlugin.EnableCustomSlotImage.Value || loadFailed)
			{
				return;
			}
			if (!attemptedLoad)
			{
				attemptedLoad = true;
				customTitleTexture = TextureLoader.LoadTexture(BossmanJackModPlugin.CustomSlotImagePath.Value);
				if (!((Object)(object)customTitleTexture != (Object)null))
				{
					Log.LogWarning((object)"Failed to load custom title screen texture. Using original.");
					loadFailed = true;
					return;
				}
				Log.LogInfo((object)$"Custom title screen texture loaded! Size: {((Texture)customTitleTexture).width}x{((Texture)customTitleTexture).height}");
			}
			if ((Object)(object)customTitleTexture != (Object)null && (Object)(object)__instance.titleScreenRawImage != (Object)null)
			{
				__instance.titleScreenRawImage.texture = (Texture)(object)customTitleTexture;
				Log.LogInfo((object)"Custom title screen image applied!");
			}
			else if ((Object)(object)__instance.titleScreenRawImage == (Object)null)
			{
				Log.LogWarning((object)"titleScreenRawImage is null - cannot replace texture");
			}
		}
	}
	[HarmonyPatch(typeof(PowerupScript), "GetPrefab")]
	public class PowerupDevilHornPrefabPatch
	{
		private static Texture2D customHornTexture;

		private static Sprite customHornSprite;

		private static bool attemptedLoad;

		private static bool loadFailed;

		private static GameObject cachedModifiedPrefab;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPostfix]
		private static void Postfix(Identifier identifier, ref GameObject __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)identifier != 94 || !BossmanJackModPlugin.EnableCustomSlotImage.Value || (Object)(object)__result == (Object)null || loadFailed)
			{
				return;
			}
			if (!attemptedLoad)
			{
				attemptedLoad = true;
				customHornTexture = TextureLoader.LoadTexture(BossmanJackModPlugin.CustomSlotImagePath.Value);
				if ((Object)(object)customHornTexture != (Object)null)
				{
					customHornSprite = TextureLoader.CreateSprite(customHornTexture);
					Log.LogInfo((object)"Custom devil horn texture loaded!");
				}
				else
				{
					Log.LogWarning((object)"Failed to load custom devil horn texture. Using original.");
					loadFailed = true;
				}
			}
			if ((Object)(object)customHornTexture == (Object)null)
			{
				return;
			}
			if ((Object)(object)cachedModifiedPrefab == (Object)null)
			{
				cachedModifiedPrefab = Object.Instantiate<GameObject>(__result);
				RawImage[] componentsInChildren = cachedModifiedPrefab.GetComponentsInChildren<RawImage>(true);
				foreach (RawImage val in componentsInChildren)
				{
					val.texture = (Texture)(object)customHornTexture;
					Log.LogDebug((object)("Replaced RawImage in devil horn prefab: " + ((Object)val).name));
				}
				Image[] componentsInChildren2 = cachedModifiedPrefab.GetComponentsInChildren<Image>(true);
				foreach (Image val2 in componentsInChildren2)
				{
					val2.sprite = customHornSprite;
					Log.LogDebug((object)("Replaced Image sprite in devil horn prefab: " + ((Object)val2).name));
				}
				Log.LogInfo((object)"Devil horn prefab modified and cached!");
			}
			__result = cachedModifiedPrefab;
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Spin")]
	public class ForceJackpotTestPatch
	{
		[CompilerGenerated]
		private sealed class <ForceJackpotAfterDelay>d__3 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SlotMachineScript instance;

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

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

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

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

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//IL_00b0: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Expected I4, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Log.LogWarning((object)"=== FORCE JACKPOT TEST MODE: Forcing symbols ===");
					try
					{
						FieldInfo field = typeof(SlotMachineScript).GetField("lines", BindingFlags.Instance | BindingFlags.NonPublic);
						if ((object)field == null)
						{
							Log.LogError((object)"Could not find 'lines' field!");
							return false;
						}
						if (!(field.GetValue(instance) is Kind[][] array) || array.Length == 0 || array[0].Length == 0)
						{
							Log.LogError((object)"Lines array is null or empty!");
							return false;
						}
						Kind val = array[0][0];
						for (int i = 0; i < array.Length; i++)
						{
							for (int j = 0; j < array[i].Length; j++)
							{
								array[i][j] = (Kind)(int)val;
							}
						}
						Log.LogWarning((object)$"FORCED JACKPOT: All symbols set to {val}");
						Log.LogWarning((object)$"HasJackpot() = {SlotMachineScript.HasJackpot()}");
					}
					catch (Exception arg)
					{
						Log.LogError((object)$"Error forcing jackpot symbols: {arg}");
					}
					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 ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPostfix]
		private static void Postfix(SlotMachineScript __instance)
		{
			if (BossmanJackModPlugin.ForceJackpotTest.Value)
			{
				((MonoBehaviour)__instance).StartCoroutine(ForceJackpotAfterDelay(__instance));
			}
		}

		[IteratorStateMachine(typeof(<ForceJackpotAfterDelay>d__3))]
		private static IEnumerator ForceJackpotAfterDelay(SlotMachineScript instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ForceJackpotAfterDelay>d__3(0)
			{
				instance = instance
			};
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Update")]
	public class SlotMachineUnifiedUpdatePatch
	{
		private static bool wasJackpot;

		private static bool jackpotSoundPlayed;

		private static float jackpotSoundLoadTimer;

		private static bool wasSixPattern;

		private static bool sixSoundPlayed;

		private static float sixSoundLoadTimer;

		private static bool previousSpinning;

		private static bool sixPlayedThisSpinSession;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		public static event Action JackpotStarted;

		public static event Action JackpotEnded;

		public static bool IsJackpotActive()
		{
			return wasJackpot;
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			ProcessJackpotDetection();
		}

		private static void ProcessJackpotDetection()
		{
			bool flag = SlotMachineScript.HasJackpot();
			bool flag2 = SlotMachineScript.IsSpinning();
			CheckSpecialPatterns(out var has, out var _);
			if (flag && !wasJackpot)
			{
				wasJackpot = true;
				jackpotSoundPlayed = false;
				jackpotSoundLoadTimer = 0f;
				SlotMachineUnifiedUpdatePatch.JackpotStarted?.Invoke();
				try
				{
					SoundManager.GetInstance("Jackpot").LoadSoundsFromFolder(BossmanJackModPlugin.JackpotSoundFolder.Value);
					Log.LogInfo((object)"Jackpot sounds loading started...");
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Error loading jackpot sounds: {arg}");
				}
			}
			if (!flag && wasJackpot)
			{
				wasJackpot = false;
				SlotMachineUnifiedUpdatePatch.JackpotEnded?.Invoke();
			}
			if (flag && !jackpotSoundPlayed)
			{
				jackpotSoundLoadTimer += Time.deltaTime;
				if (jackpotSoundLoadTimer >= 1f)
				{
					try
					{
						SoundManager instance = SoundManager.GetInstance("Jackpot");
						if (instance.IsInitialized() && !instance.IsLoading())
						{
							jackpotSoundPlayed = true;
							instance.PlayRandomSound(BossmanJackModPlugin.JackpotSoundVolume.Value);
							Log.LogInfo((object)"Jackpot sound played!");
						}
						else if (jackpotSoundLoadTimer >= 5f)
						{
							jackpotSoundPlayed = true;
							Log.LogWarning((object)$"Jackpot sound timeout - initialized: {instance.IsInitialized()}, loading: {instance.IsLoading()}");
						}
					}
					catch (Exception arg2)
					{
						Log.LogError((object)$"Error playing jackpot sound: {arg2}");
						jackpotSoundPlayed = true;
					}
				}
			}
			if (BossmanJackModPlugin.Enable666Sound.Value && has && !sixPlayedThisSpinSession)
			{
				if (!wasSixPattern)
				{
					wasSixPattern = true;
					sixSoundPlayed = false;
					sixSoundLoadTimer = 0f;
					try
					{
						SoundManager.GetInstance("SixSixSix").LoadSoundsFromFolder(BossmanJackModPlugin.Sound666Folder.Value);
					}
					catch (Exception arg3)
					{
						Log.LogError((object)$"Error loading 666 sounds: {arg3}");
						sixSoundPlayed = true;
						sixPlayedThisSpinSession = true;
					}
				}
				if (!sixSoundPlayed)
				{
					sixSoundLoadTimer += Time.deltaTime;
					if (sixSoundLoadTimer >= 0.5f)
					{
						try
						{
							SoundManager instance2 = SoundManager.GetInstance("SixSixSix");
							if (instance2.IsInitialized() && !instance2.IsLoading())
							{
								sixSoundPlayed = true;
								sixPlayedThisSpinSession = true;
								instance2.PlayRandomSound(BossmanJackModPlugin.Sound666Volume.Value);
							}
							else if (sixSoundLoadTimer >= 3f)
							{
								sixSoundPlayed = true;
								sixPlayedThisSpinSession = true;
							}
						}
						catch (Exception arg4)
						{
							Log.LogError((object)$"Error playing 666 sound: {arg4}");
							sixSoundPlayed = true;
							sixPlayedThisSpinSession = true;
						}
					}
				}
			}
			else if (!has && wasSixPattern)
			{
				wasSixPattern = false;
				sixSoundPlayed = false;
				sixSoundLoadTimer = 0f;
			}
			if (!flag2 && previousSpinning)
			{
				sixPlayedThisSpinSession = false;
				wasSixPattern = false;
				sixSoundPlayed = false;
				sixSoundLoadTimer = 0f;
			}
			previousSpinning = flag2;
		}

		private static void CheckSpecialPatterns(out bool has666, out bool has999)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			has666 = false;
			has999 = false;
			try
			{
				if ((Object)(object)SlotMachineScript.instance == (Object)null)
				{
					return;
				}
				List<PatternInfos> patternsEnabled = SlotMachineScript.instance.GetPatternsEnabled();
				if (patternsEnabled == null || patternsEnabled.Count == 0)
				{
					return;
				}
				for (int i = 0; i < patternsEnabled.Count; i++)
				{
					PatternInfos val = patternsEnabled[i];
					if ((int)val.patternKind == 2)
					{
						if ((int)val.symbolKind == 7)
						{
							has666 = true;
						}
						else if ((int)val.symbolKind == 8)
						{
							has999 = true;
						}
						if (has666 & has999)
						{
							break;
						}
					}
				}
				if (has999 && (BossmanJackModPlugin.Enable666Sound.Value || BossmanJackModPlugin.EnableJackpotSound.Value))
				{
					Log.LogWarning((object)"!!! 999 PATTERN DETECTED !!!");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error checking 666/999 pattern: " + ex.Message));
			}
		}
	}
	public class SoundManager : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <LoadAudioFilesCoroutine>d__15 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public List<string> filePaths;

			public SoundManager <>4__this;

			private int <successCount>5__2;

			private List<string>.Enumerator <>7__wrap2;

			private string <filePath>5__4;

			private UnityWebRequest <www>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 1)
				{
					try
					{
						if (num == -4 || num == 1)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = default(List<string>.Enumerator);
				<filePath>5__4 = null;
				<www>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Invalid comparison between Unknown and I4
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					int num = <>1__state;
					SoundManager soundManager = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<successCount>5__2 = 0;
						Log.LogDebug((object)$"Starting async load of {filePaths.Count} audio file(s).");
						<>7__wrap2 = filePaths.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -4;
						if ((int)<www>5__5.result == 1)
						{
							AudioClip content = DownloadHandlerAudioClip.GetContent(<www>5__5);
							if ((Object)(object)content != (Object)null)
							{
								((Object)content).name = Path.GetFileName(<filePath>5__4);
								soundManager.loadedClips.Add(content);
								<successCount>5__2++;
								Log.LogInfo((object)("Loaded audio: " + ((Object)content).name));
							}
							else
							{
								Log.LogWarning((object)("Download handler returned null clip for " + <filePath>5__4 + " despite success result."));
							}
						}
						else
						{
							Log.LogError((object)$"Failed to load audio file {<filePath>5__4}. Result={<www>5__5.result}, Error={<www>5__5.error}");
						}
						<>m__Finally2();
						<www>5__5 = null;
						<filePath>5__4 = null;
						break;
					}
					while (<>7__wrap2.MoveNext())
					{
						<filePath>5__4 = <>7__wrap2.Current;
						AudioType audioType = soundManager.GetAudioType(<filePath>5__4);
						if ((int)audioType == 0)
						{
							Log.LogWarning((object)("Unsupported audio type for file " + <filePath>5__4 + ". Skipping."));
							continue;
						}
						string text = "file:///" + <filePath>5__4.Replace("\\", "/");
						<www>5__5 = UnityWebRequestMultimedia.GetAudioClip(text, audioType);
						<>1__state = -4;
						<>2__current = <www>5__5.SendWebRequest();
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap2 = default(List<string>.Enumerator);
					Log.LogInfo((object)$"Successfully loaded {<successCount>5__2}/{filePaths.Count} audio files");
					lock (soundManager.loadingLock)
					{
						soundManager.isInitialized = <successCount>5__2 > 0;
						soundManager.isLoading = false;
					}
					Log.LogInfo((object)$"SoundManager initialization state: {soundManager.isInitialized} (clip count={soundManager.loadedClips.Count})");
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap2).Dispose();
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<www>5__5 != null)
				{
					((IDisposable)<www>5__5).Dispose();
				}
			}

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

		[CompilerGenerated]
		private sealed class <WaitAndPlayCoroutine>d__26 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SoundManager <>4__this;

			public float volume;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				SoundManager soundManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				if (!soundManager.isInitialized)
				{
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				soundManager.PlayRandomSound(volume);
				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 Dictionary<string, SoundManager> _instances = new Dictionary<string, SoundManager>();

		private AudioSource audioSource;

		private List<AudioClip> loadedClips = new List<AudioClip>();

		private bool isInitialized;

		private bool isLoading;

		private readonly object loadingLock = new object();

		public int[] coinTiers = new int[3] { 10, 50, 100 };

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		public static SoundManager Instance => GetInstance("Default");

		public static SoundManager GetInstance(string name)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (!_instances.ContainsKey(name))
			{
				GameObject val = new GameObject("SoundManager_" + name);
				Object.DontDestroyOnLoad((Object)val);
				SoundManager value = val.AddComponent<SoundManager>();
				_instances[name] = value;
				Log.LogInfo((object)("Created SoundManager instance: " + name));
			}
			return _instances[name];
		}

		private void Awake()
		{
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			audioSource.playOnAwake = false;
			audioSource.spatialBlend = 0f;
		}

		private void OnDestroy()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, SoundManager> instance in _instances)
			{
				if ((Object)(object)instance.Value == (Object)(object)this)
				{
					list.Add(instance.Key);
				}
			}
			foreach (string item in list)
			{
				_instances.Remove(item);
			}
		}

		public void LoadSoundsFromFolder(string folderPath)
		{
			Log.LogInfo((object)("LoadSoundsFromFolder invoked with path: " + folderPath));
			lock (loadingLock)
			{
				if (isLoading)
				{
					Log.LogWarning((object)("Already loading sounds, ignoring request for: " + folderPath));
					return;
				}
				if (!Directory.Exists(folderPath))
				{
					Log.LogWarning((object)("Sound folder does not exist: " + folderPath));
					return;
				}
				isLoading = true;
				loadedClips.Clear();
				isInitialized = false;
				Log.LogDebug((object)"Cleared previously loaded audio clips. Awaiting new load.");
				string[] obj = new string[3] { "*.wav", "*.ogg", "*.mp3" };
				List<string> list = new List<string>();
				string[] array = obj;
				foreach (string searchPattern in array)
				{
					list.AddRange(Directory.GetFiles(folderPath, searchPattern, SearchOption.TopDirectoryOnly));
				}
				if (list.Count == 0)
				{
					Log.LogWarning((object)("No audio files found in " + folderPath));
					isLoading = false;
				}
				else
				{
					Log.LogInfo((object)$"Found {list.Count} audio file(s) in {folderPath}");
					((MonoBehaviour)this).StartCoroutine(LoadAudioFilesCoroutine(list));
				}
			}
		}

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

		private AudioType GetAudioType(string filePath)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			return (AudioType)(Path.GetExtension(filePath).ToLower() switch
			{
				".wav" => 20, 
				".ogg" => 14, 
				".mp3" => 13, 
				_ => 0, 
			});
		}

		public void PlayRandomSound(float volume = 1f)
		{
			if (!isInitialized || loadedClips.Count == 0)
			{
				Log.LogWarning((object)$"Cannot play sound - initialized={isInitialized}, clipCount={loadedClips.Count}");
				return;
			}
			int index = Random.Range(0, loadedClips.Count);
			AudioClip val = loadedClips[index];
			audioSource.volume = Mathf.Clamp01(volume);
			audioSource.PlayOneShot(val);
			Log.LogInfo((object)$"Playing random sound: {((Object)val).name} (Volume: {audioSource.volume})");
		}

		public int GetLoadedClipCount()
		{
			return loadedClips.Count;
		}

		public bool IsInitialized()
		{
			return isInitialized;
		}

		public bool IsLoading()
		{
			lock (loadingLock)
			{
				return isLoading;
			}
		}

		public string GetDeadlineDistanceTier(int roundsPlayed, int roundsTotal)
		{
			if (roundsTotal <= 0)
			{
				return "far";
			}
			float num = (float)(roundsTotal - roundsPlayed) / (float)roundsTotal * 100f;
			if (num > 50f)
			{
				return "far";
			}
			if (num > 25f)
			{
				return "medium";
			}
			if (num > 10f)
			{
				return "close";
			}
			return "critical";
		}

		public void LoadSoundsForDeadlineDistance(string baseFolderPath, int roundsPlayed, int roundsTotal)
		{
			string deadlineDistanceTier = GetDeadlineDistanceTier(roundsPlayed, roundsTotal);
			string folderPath = Path.Combine(baseFolderPath, deadlineDistanceTier);
			float num = ((roundsTotal > 0) ? ((float)(roundsTotal - roundsPlayed) / (float)roundsTotal * 100f) : 100f);
			Log.LogInfo((object)$"Loading deadline sounds for {roundsPlayed}/{roundsTotal} rounds ({num:F1}% remaining) from tier: {deadlineDistanceTier}");
			LoadSoundsFromFolder(folderPath);
		}

		public string GetCoinTierFolder(int coinsEarnedThisRound)
		{
			if (coinsEarnedThisRound <= coinTiers[0])
			{
				return $"0-{coinTiers[0]}";
			}
			for (int i = 0; i < coinTiers.Length - 1; i++)
			{
				if (coinsEarnedThisRound <= coinTiers[i + 1])
				{
					return $"{coinTiers[i] + 1}-{coinTiers[i + 1]}";
				}
			}
			return $"{coinTiers[coinTiers.Length - 1]}+";
		}

		public void LoadSoundsForRoundCoins(string baseFolderPath, int coinsEarnedThisRound)
		{
			string coinTierFolder = GetCoinTierFolder(coinsEarnedThisRound);
			string folderPath = Path.Combine(baseFolderPath, coinTierFolder);
			Log.LogInfo((object)$"Loading sounds for {coinsEarnedThisRound} coins earned this round from tier: {coinTierFolder}");
			LoadSoundsFromFolder(folderPath);
		}

		public void LoadAndPlayForRoundCoins(string baseFolderPath, int coinsEarnedThisRound, float volume = 1f)
		{
			LoadSoundsForRoundCoins(baseFolderPath, coinsEarnedThisRound);
			((MonoBehaviour)this).StartCoroutine(WaitAndPlayCoroutine(volume));
		}

		[IteratorStateMachine(typeof(<WaitAndPlayCoroutine>d__26))]
		private IEnumerator WaitAndPlayCoroutine(float volume)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitAndPlayCoroutine>d__26(0)
			{
				<>4__this = this,
				volume = volume
			};
		}
	}
	public static class TextureLoader
	{
		private static readonly MethodInfo? LoadImageMethod;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		static TextureLoader()
		{
			try
			{
				LoadImageMethod = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "UnityEngine.ImageConversionModule", StringComparison.Ordinal))?.GetType("UnityEngine.ImageConversion")?.GetMethod("LoadImage", new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				});
				if (LoadImageMethod == null)
				{
					Log.LogWarning((object)"UnityEngine.ImageConversion.LoadImage could not be located. Texture loading may fail.");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to initialize texture loader reflection: " + ex.Message));
			}
		}

		public static Texture2D? LoadTexture(string filePath)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			try
			{
				if (!File.Exists(filePath))
				{
					Log.LogError((object)("Texture file not found: " + filePath));
					return null;
				}
				byte[] array = File.ReadAllBytes(filePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				bool flag = false;
				if (LoadImageMethod != null)
				{
					try
					{
						flag = (bool)LoadImageMethod.Invoke(null, new object[3] { val, array, false });
					}
					catch (Exception ex)
					{
						Log.LogWarning((object)("Reflection LoadImage invoke failed: " + ex.Message));
					}
				}
				else
				{
					Log.LogWarning((object)"LoadImage method unavailable. Texture loading will fail.");
				}
				if (flag)
				{
					Log.LogInfo((object)$"Successfully loaded texture: {filePath} ({((Texture)val).width}x{((Texture)val).height})");
					return val;
				}
				Log.LogError((object)("Failed to load image data from: " + filePath));
				Object.Destroy((Object)(object)val);
				return null;
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("Error loading texture from " + filePath + ": " + ex2.Message));
				return null;
			}
		}

		public static Texture2D LoadTextureFromPluginFolder(string fileName)
		{
			return LoadTexture(Path.Combine(Path.GetDirectoryName(typeof(TextureLoader).Assembly.Location), fileName));
		}

		public static Sprite? CreateSprite(Texture2D? texture)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)texture == (Object)null)
			{
				Log.LogError((object)"Cannot create sprite from null texture");
				return null;
			}
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f);
		}
	}
	public class VisibilityToggler : MonoBehaviour
	{
		[Tooltip("Time in seconds between visibility toggles")]
		public float toggleInterval = 0.2f;

		private float nextToggleTime;

		private bool isVisible = true;

		private Renderer[] renderers;

		private Graphic[] uiGraphics;

		private void OnEnable()
		{
			nextToggleTime = Time.time + toggleInterval;
			renderers = ((Component)this).GetComponentsInChildren<Renderer>();
			uiGraphics = ((Component)this).GetComponentsInChildren<Graphic>();
			SetVisibility(enabled: true);
		}

		private void Update()
		{
			if (Time.time >= nextToggleTime)
			{
				isVisible = !isVisible;
				SetVisibility(isVisible);
				nextToggleTime = Time.time + toggleInterval;
			}
		}

		private void SetVisibility(bool enabled)
		{
			Renderer[] array = renderers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].enabled = enabled;
			}
			Graphic[] array2 = uiGraphics;
			for (int i = 0; i < array2.Length; i++)
			{
				((Behaviour)array2[i]).enabled = enabled;
			}
		}
	}
}
namespace BossmanJackMod.UI
{
	public class PromptService : MonoBehaviour
	{
		private static PromptService instance;

		private Canvas canvas;

		private CanvasGroup canvasGroup;

		private GameObject panel;

		private Text headerText;

		private Button yesButton;

		private Button noButton;

		private Text yesButtonText;

		private Text noButtonText;

		private Action currentOnYes;

		private Action currentOnNo;

		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		public static PromptService Instance => instance;

		public static void EnsureCreated()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)instance != (Object)null))
			{
				GameObject val = new GameObject("ModPromptService");
				Object.DontDestroyOnLoad((Object)val);
				instance = val.AddComponent<PromptService>();
				instance.BuildUI();
				Log.LogInfo((object)"PromptService created and initialized");
			}
		}

		public static void ShowYesNo(string header, Action onYes, Action onNo)
		{
			EnsureCreated();
			instance.ShowPrompt(header, onYes, onNo);
		}

		private void BuildUI()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Expected O, but got Unknown
			canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			canvas.renderMode = (RenderMode)0;
			canvas.sortingOrder = 999;
			((Component)this).gameObject.AddComponent<CanvasScaler>();
			((Component)this).gameObject.AddComponent<GraphicRaycaster>();
			canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			canvasGroup.alpha = 0f;
			canvasGroup.interactable = false;
			canvasGroup.blocksRaycasts = false;
			panel = new GameObject("PromptPanel");
			panel.transform.SetParent(((Component)this).transform, false);
			RectTransform obj = panel.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.5f, 0.5f);
			obj.anchorMax = new Vector2(0.5f, 0.5f);
			obj.sizeDelta = new Vector2(400f, 200f);
			((Graphic)panel.AddComponent<Image>()).color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
			GameObject val = new GameObject("HeaderText");
			val.transform.SetParent(panel.transform, false);
			RectTransform obj2 = val.AddComponent<RectTransform>();
			obj2.anchorMin = new Vector2(0.5f, 0.7f);
			obj2.anchorMax = new Vector2(0.5f, 0.7f);
			obj2.sizeDelta = new Vector2(350f, 60f);
			headerText = val.AddComponent<Text>();
			headerText.text = "Prompt";
			headerText.fontSize = 24;
			((Graphic)headerText).color = Color.white;
			CreateButton(ref yesButton, ref yesButtonText, "YesButton", "YES", new Vector2(-60f, -30f), new UnityAction(OnYesClicked));
			CreateButton(ref noButton, ref noButtonText, "NoButton", "NO", new Vector2(60f, -30f), new UnityAction(OnNoClicked));
			Log.LogInfo((object)"PromptService UI built successfully");
		}

		private void CreateButton(ref Button button, ref Text buttonText, string name, string text, Vector2 position, UnityAction onClick)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0086: 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)
			//IL_00cc: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(panel.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.5f, 0.5f);
			obj.anchorMax = new Vector2(0.5f, 0.5f);
			obj.anchoredPosition = position;
			obj.sizeDelta = new Vector2(100f, 40f);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.3f, 0.3f, 0.3f, 1f);
			button = val.AddComponent<Button>();
			((Selectable)button).targetGraphic = (Graphic)(object)val2;
			((UnityEvent)button.onClick).AddListener(onClick);
			ColorBlock colors = ((Selectable)button).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.5f, 0.5f, 0.5f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.2f, 0.2f, 0.2f, 1f);
			((Selectable)button).colors = colors;
			GameObject val3 = new GameObject("Text");
			val3.transform.SetParent(val.transform, false);
			RectTransform obj2 = val3.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = Vector2.zero;
			obj2.offsetMax = Vector2.zero;
			buttonText = val3.AddComponent<Text>();
			buttonText.text = text;
			buttonText.fontSize = 18;
			((Graphic)buttonText).color = Color.white;
		}

		private void ShowPrompt(string header, Action onYes, Action onNo)
		{
			if ((Object)(object)headerText != (Object)null)
			{
				headerText.text = header;
			}
			currentOnYes = onYes;
			currentOnNo = onNo;
			canvasGroup.alpha = 1f;
			canvasGroup.interactable = true;
			canvasGroup.blocksRaycasts = true;
			SlotPauseManager.Pause();
			Log.LogInfo((object)("Prompt shown: " + header));
		}

		private void HidePrompt()
		{
			canvasGroup.alpha = 0f;
			canvasGroup.interactable = false;
			canvasGroup.blocksRaycasts = false;
			currentOnYes = null;
			currentOnNo = null;
			SlotPauseManager.Resume();
			Log.LogInfo((object)"Prompt hidden");
		}

		private void OnYesClicked()
		{
			Log.LogInfo((object)"YES button clicked");
			Action action = currentOnYes;
			HidePrompt();
			action?.Invoke();
		}

		private void OnNoClicked()
		{
			Log.LogInfo((object)"NO button clicked");
			Action action = currentOnNo;
			HidePrompt();
			action?.Invoke();
		}
	}
}
namespace BossmanJackMod.State
{
	public static class SlotPauseManager
	{
		public static bool IsPaused { get; set; }

		public static void Pause()
		{
			IsPaused = true;
		}

		public static void Resume()
		{
			IsPaused = false;
		}
	}
}
namespace BossmanJackMod.Patches
{
	[HarmonyPatch(typeof(SlotMachineScript), "Start")]
	public class SlotMachine_InitializeModSystems
	{
		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				PromptService.EnsureCreated();
				Log.LogInfo((object)"Mod systems initialized");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error initializing mod systems: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Update")]
	public class SlotMachine_PauseWhilePromptActive
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			if (SlotPauseManager.IsPaused)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SlotMachineScript), "Spin")]
	public class SlotMachine_BlockSpinWhilePaused
	{
		private static ManualLogSource Log => BossmanJackModPlugin.Log;

		[HarmonyPrefix]
		private static bool Prefix()
		{
			if (SlotPauseManager.IsPaused)
			{
				Log.LogDebug((object)"Blocked spin while paused");
				return false;
			}
			return true;
		}
	}
}