Decompiled source of PressYourLuckCrown v1.0.0

PressYourLuckCrown.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("REPOJP")]
[assembly: AssemblyTitle("REPOJP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOJPPressYourLuckCrown
{
	[BepInPlugin("REPOJP.PressYourLuckCrown", "PressYourLuckCrown", "1.0.0")]
	public class PressYourLuckCrownPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ValuableObject), "DollarValueSetLogic")]
		private static class ValuableObject_DollarValueSetLogic_Patch
		{
			private static void Postfix(ValuableObject __instance)
			{
				try
				{
					if (!ModEnabled.Value)
					{
						return;
					}
					ClownTrap component = ((Component)__instance).GetComponent<ClownTrap>();
					if (!((Object)(object)component == (Object)null))
					{
						int minValue = InitialClownValueMin.Value;
						int maxValue = InitialClownValueMax.Value;
						NormalizeMinMax(ref minValue, ref maxValue, 1);
						int num = RollDeterministicInt(component, 5001, minValue, maxValue);
						SetDollarValues(__instance, num, num);
						if (DebugLogEnabled.Value)
						{
							LogSource.LogInfo((object)("[PressYourLuckCrown] InitialValue=$" + num + " Object=" + ((Object)((Component)component).gameObject).name));
						}
					}
				}
				catch (Exception ex)
				{
					LogSource.LogError((object)("[PressYourLuckCrown] ValuableObject_DollarValueSetLogic_Patch failure\n" + ex));
				}
			}
		}

		[HarmonyPatch(typeof(ClownTrap), "Start")]
		private static class ClownTrap_Start_Patch
		{
			private static void Postfix(ClownTrap __instance)
			{
				try
				{
					if (ModEnabled.Value)
					{
						EnsureRequiredPressCountAssigned(__instance);
					}
				}
				catch (Exception ex)
				{
					LogSource.LogError((object)("[PressYourLuckCrown] ClownTrap_Start_Patch failure\n" + ex));
				}
			}
		}

		[HarmonyPatch(typeof(ClownTrap), "TrapActivate")]
		private static class ClownTrap_TrapActivate_Patch
		{
			private static bool Prefix(ClownTrap __instance, out PressContext __state)
			{
				__state = new PressContext();
				try
				{
					if (!ModEnabled.Value)
					{
						return true;
					}
					EnsureRequiredPressCountAssigned(__instance);
					if (((Trap)__instance).trapTriggered)
					{
						return true;
					}
					ClownState orCreateState = GetOrCreateState(__instance);
					if (orCreateState.JackpotTriggered && InstantExplodeAfterJackpotOnNextPress.Value)
					{
						ExecuteRealExplosion(__instance);
						__state.SkipOriginal = true;
						return false;
					}
					__state.ShouldProcess = true;
					__state.PressCount = orCreateState.ValidPressCount + 1;
					__state.OriginalWarningCount = GetWarningCount(__instance);
					__state.WouldHaveBeenFinalPress = __state.OriginalWarningCount <= 0;
					__state.IsJackpot = RollJackpot(__instance, __state.PressCount);
					__state.BonusAmount = CalculatePlannedBonus(__instance, __state.PressCount, __state.IsJackpot);
					if (__state.IsJackpot && __state.WouldHaveBeenFinalPress)
					{
						SetWarningCount(__instance, 1);
						__state.FinalExplosionSuppressedForJackpot = true;
					}
					return true;
				}
				catch (Exception ex)
				{
					LogSource.LogError((object)("[PressYourLuckCrown] ClownTrap_TrapActivate_Patch Prefix failure\n" + ex));
					return true;
				}
			}

			private static void Postfix(ClownTrap __instance, PressContext __state)
			{
				try
				{
					if (ModEnabled.Value && __state != null && __state.ShouldProcess && !__state.SkipOriginal)
					{
						ClownState orCreateState = GetOrCreateState(__instance);
						orCreateState.ValidPressCount = __state.PressCount;
						ApplyPlannedBonus(__instance, __state);
						TryPlayMegaNoise(__instance);
						if (__state.IsJackpot)
						{
							orCreateState.JackpotTriggered = true;
							PlayJackpotFakeExplosion(__instance);
							MakeJackpotClownUltraFragile(__instance);
						}
					}
				}
				catch (Exception ex)
				{
					LogSource.LogError((object)("[PressYourLuckCrown] ClownTrap_TrapActivate_Patch Postfix failure\n" + ex));
				}
			}
		}

		[HarmonyPatch(typeof(ClownTrap), "TrapStop")]
		private static class ClownTrap_TrapStop_Patch
		{
			private static bool Prefix(ClownTrap __instance)
			{
				try
				{
					if (!ModEnabled.Value)
					{
						return true;
					}
					ExecuteRealExplosion(__instance);
					return false;
				}
				catch (Exception ex)
				{
					LogSource.LogError((object)("[PressYourLuckCrown] ClownTrap_TrapStop_Patch Prefix failure\n" + ex));
					return true;
				}
			}
		}

		internal sealed class ClownState
		{
			public int ValidPressCount;

			public bool JackpotTriggered;

			public bool RequiredPressCountAssigned;

			public int RequiredPressCount;
		}

		internal sealed class PressContext
		{
			public bool ShouldProcess;

			public bool SkipOriginal;

			public int PressCount;

			public int OriginalWarningCount;

			public bool WouldHaveBeenFinalPress;

			public bool IsJackpot;

			public float BonusAmount;

			public bool FinalExplosionSuppressedForJackpot;
		}

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

			private object <>2__current;

			public Vector3 position;

			public int pulseCount;

			public float interval;

			public float range;

			public bool pathfindOnly;

			private int <i>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__1 = 0;
					break;
				case 1:
					<>1__state = -1;
					if (!SemiFunc.IsMasterClientOrSingleplayer())
					{
						return false;
					}
					if ((Object)(object)EnemyDirector.instance == (Object)null)
					{
						return false;
					}
					EnemyDirector.instance.SetInvestigate(position, range, pathfindOnly);
					<i>5__1++;
					break;
				}
				if (<i>5__1 < pulseCount)
				{
					<>2__current = (object)new WaitForSeconds(interval);
					<>1__state = 1;
					return true;
				}
				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();
			}
		}

		public const string PluginGuid = "REPOJP.PressYourLuckCrown";

		public const string PluginName = "PressYourLuckCrown";

		public const string PluginVersion = "1.0.0";

		internal static PressYourLuckCrownPlugin Instance;

		internal static ManualLogSource LogSource;

		private Harmony harmony;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<bool> DebugLogEnabled;

		internal static ConfigEntry<int> InitialClownValueMin;

		internal static ConfigEntry<int> InitialClownValueMax;

		internal static ConfigEntry<int> ExplosionPressCountMin;

		internal static ConfigEntry<int> ExplosionPressCountMax;

		internal static ConfigEntry<bool> BonusEnabled;

		internal static ConfigEntry<int> BonusValueMin;

		internal static ConfigEntry<int> BonusValueMax;

		internal static ConfigEntry<bool> RoundBonusToHundreds;

		internal static ConfigEntry<bool> ApplyBonusOnFinalPress;

		internal static ConfigEntry<bool> PressMultiplierEnabled;

		internal static ConfigEntry<float> Press1Multiplier;

		internal static ConfigEntry<float> Press2Multiplier;

		internal static ConfigEntry<float> Press3Multiplier;

		internal static ConfigEntry<bool> JackpotEnabled;

		internal static ConfigEntry<float> JackpotChancePercent;

		internal static ConfigEntry<int> JackpotValueMin;

		internal static ConfigEntry<int> JackpotValueMax;

		internal static ConfigEntry<bool> JackpotUsesMultiplier;

		internal static ConfigEntry<bool> JackpotRoundToHundreds;

		internal static ConfigEntry<bool> InstantExplodeAfterJackpotOnNextPress;

		internal static ConfigEntry<bool> JackpotUltraFragile;

		internal static ConfigEntry<bool> MegaNoiseEnabled;

		internal static ConfigEntry<float> PressSoundVolumeMultiplier;

		internal static ConfigEntry<float> PressSoundFalloffMultiplier;

		internal static ConfigEntry<float> PressSoundOffscreenVolumeMultiplier;

		internal static ConfigEntry<float> PressSoundOffscreenFalloffMultiplier;

		internal static ConfigEntry<float> PressInvestigateRange;

		internal static ConfigEntry<bool> PressInvestigatePathfindOnly;

		internal static ConfigEntry<int> ExtraInvestigatePulses;

		internal static ConfigEntry<float> ExtraInvestigatePulseInterval;

		internal static ConfigEntry<float> ExplosionDamageMultiplier;

		internal static ConfigEntry<float> ExplosionKnockbackMultiplier;

		internal static ConfigEntry<float> ExplosionValuableDamageMultiplier;

		internal static readonly FieldInfo ValuableDollarValueOriginalField = AccessTools.Field(typeof(ValuableObject), "dollarValueOriginal");

		internal static readonly FieldInfo ValuableDollarValueCurrentField = AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent");

		internal static readonly FieldInfo ValuableDollarValueSetField = AccessTools.Field(typeof(ValuableObject), "dollarValueSet");

		internal static readonly FieldInfo ClownWarningCountField = AccessTools.Field(typeof(ClownTrap), "WarningCount");

		internal static readonly FieldInfo ClownCountDownActiveField = AccessTools.Field(typeof(ClownTrap), "CountDownActive");

		internal static readonly FieldInfo ClownPreviousAudioSourceField = AccessTools.Field(typeof(ClownTrap), "previousAudioSource");

		internal static readonly FieldInfo ImpactDetectorIndestructibleSpawnTimerField = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "indestructibleSpawnTimer");

		internal static readonly Dictionary<int, ClownState> ClownStates = new Dictionary<int, ClownState>();

		private void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			try
			{
				Instance = this;
				LogSource = ((BaseUnityPlugin)this).Logger;
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				SetupConfig();
				harmony = new Harmony("REPOJP.PressYourLuckCrown");
				harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[PressYourLuckCrown] Loaded");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[PressYourLuckCrown] Awake failure\n" + ex));
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[PressYourLuckCrown] OnDestroy failure\n" + ex));
			}
		}

		private void SetupConfig()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Expected O, but got Unknown
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Expected O, but got Unknown
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Expected O, but got Unknown
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Expected O, but got Unknown
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Expected O, but got Unknown
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Expected O, but got Unknown
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Expected O, but got Unknown
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Expected O, but got Unknown
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Expected O, but got Unknown
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Expected O, but got Unknown
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Expected O, but got Unknown
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e1: Expected O, but got Unknown
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_061e: Expected O, but got Unknown
			//IL_0651: Unknown result type (might be due to invalid IL or missing references)
			//IL_065b: Expected O, but got Unknown
			//IL_068e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0698: Expected O, but got Unknown
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "ModEnabled", true, "MOD enabled");
			DebugLogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "DebugLogEnabled", false, "Enable debug logging");
			InitialClownValueMin = ((BaseUnityPlugin)this).Config.Bind<int>("2. Initial Value", "InitialClownValueMin", 1, new ConfigDescription("Initial clown value minimum", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000000), Array.Empty<object>()));
			InitialClownValueMax = ((BaseUnityPlugin)this).Config.Bind<int>("2. Initial Value", "InitialClownValueMax", 100, new ConfigDescription("Initial clown value maximum", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000000), Array.Empty<object>()));
			ExplosionPressCountMin = ((BaseUnityPlugin)this).Config.Bind<int>("3. Explosion Press Count", "ExplosionPressCountMin", 1, new ConfigDescription("Minimum required press count before the clown can explode", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			ExplosionPressCountMax = ((BaseUnityPlugin)this).Config.Bind<int>("3. Explosion Press Count", "ExplosionPressCountMax", 10, new ConfigDescription("Maximum required press count before the clown can explode", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			BonusEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Bonus", "BonusEnabled", true, "Enable value bonus on valid clown nose press");
			BonusValueMin = ((BaseUnityPlugin)this).Config.Bind<int>("4. Bonus", "BonusValueMin", 100, new ConfigDescription("Minimum base bonus per press", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>()));
			BonusValueMax = ((BaseUnityPlugin)this).Config.Bind<int>("4. Bonus", "BonusValueMax", 500, new ConfigDescription("Maximum base bonus per press", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>()));
			RoundBonusToHundreds = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Bonus", "RoundBonusToHundreds", true, "Round normal bonus to nearest 100");
			ApplyBonusOnFinalPress = ((BaseUnityPlugin)this).Config.Bind<bool>("4. Bonus", "ApplyBonusOnFinalPress", true, "Apply bonus even on the final press that starts the countdown");
			PressMultiplierEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("5. Multiplier", "PressMultiplierEnabled", true, "Enable multiplier by valid press count");
			Press1Multiplier = ((BaseUnityPlugin)this).Config.Bind<float>("5. Multiplier", "Press1Multiplier", 1f, new ConfigDescription("Multiplier for first valid press", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			Press2Multiplier = ((BaseUnityPlugin)this).Config.Bind<float>("5. Multiplier", "Press2Multiplier", 1.5f, new ConfigDescription("Multiplier for second valid press", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			Press3Multiplier = ((BaseUnityPlugin)this).Config.Bind<float>("5. Multiplier", "Press3Multiplier", 2.25f, new ConfigDescription("Multiplier for third and later valid press", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			JackpotEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Jackpot", "JackpotEnabled", true, "Enable jackpot roll on each valid press");
			JackpotChancePercent = ((BaseUnityPlugin)this).Config.Bind<float>("6. Jackpot", "JackpotChancePercent", 7.5f, new ConfigDescription("Jackpot chance percent", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			JackpotValueMin = ((BaseUnityPlugin)this).Config.Bind<int>("6. Jackpot", "JackpotValueMin", 3000, new ConfigDescription("Minimum jackpot bonus", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>()));
			JackpotValueMax = ((BaseUnityPlugin)this).Config.Bind<int>("6. Jackpot", "JackpotValueMax", 10000, new ConfigDescription("Maximum jackpot bonus", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>()));
			JackpotUsesMultiplier = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Jackpot", "JackpotUsesMultiplier", true, "Apply press multiplier to jackpot value");
			JackpotRoundToHundreds = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Jackpot", "JackpotRoundToHundreds", true, "Round jackpot value to nearest 100");
			InstantExplodeAfterJackpotOnNextPress = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Jackpot", "InstantExplodeAfterJackpotOnNextPress", true, "After jackpot, the next press causes an immediate real explosion without windup");
			JackpotUltraFragile = ((BaseUnityPlugin)this).Config.Bind<bool>("6. Jackpot", "JackpotUltraFragile", true, "After jackpot, make that clown extremely fragile");
			MegaNoiseEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("7. Mega Noise", "MegaNoiseEnabled", true, "Enable mega loud extra clown nose sound and enemy investigate pulse");
			PressSoundVolumeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "PressSoundVolumeMultiplier", 3f, new ConfigDescription("Extra press sound volume multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			PressSoundFalloffMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "PressSoundFalloffMultiplier", 10f, new ConfigDescription("Extra press sound falloff multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			PressSoundOffscreenVolumeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "PressSoundOffscreenVolumeMultiplier", 1f, new ConfigDescription("Extra press sound offscreen volume multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			PressSoundOffscreenFalloffMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "PressSoundOffscreenFalloffMultiplier", 10f, new ConfigDescription("Extra press sound offscreen falloff multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			PressInvestigateRange = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "PressInvestigateRange", 100f, new ConfigDescription("Enemy investigate range on valid press", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 999f), Array.Empty<object>()));
			PressInvestigatePathfindOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("7. Mega Noise", "PressInvestigatePathfindOnly", false, "Use pathfindOnly investigate mode");
			ExtraInvestigatePulses = ((BaseUnityPlugin)this).Config.Bind<int>("7. Mega Noise", "ExtraInvestigatePulses", 2, new ConfigDescription("Additional investigate pulses after the first one", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>()));
			ExtraInvestigatePulseInterval = ((BaseUnityPlugin)this).Config.Bind<float>("7. Mega Noise", "ExtraInvestigatePulseInterval", 0.35f, new ConfigDescription("Interval between additional investigate pulses", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 10f), Array.Empty<object>()));
			ExplosionDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("8. Explosion", "ExplosionDamageMultiplier", 3f, new ConfigDescription("Explosion damage multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
			ExplosionKnockbackMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("8. Explosion", "ExplosionKnockbackMultiplier", 3f, new ConfigDescription("Explosion knockback multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
			ExplosionValuableDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("8. Explosion", "ExplosionValuableDamageMultiplier", 3f, new ConfigDescription("Explosion valuable damage multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
		}

		internal static int GetClownKey(ClownTrap clownTrap)
		{
			PhotonView component = ((Component)clownTrap).GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && component.ViewID != 0)
			{
				return component.ViewID;
			}
			return ((Object)clownTrap).GetInstanceID();
		}

		internal static ClownState GetOrCreateState(ClownTrap clownTrap)
		{
			int clownKey = GetClownKey(clownTrap);
			if (!ClownStates.TryGetValue(clownKey, out ClownState value))
			{
				value = new ClownState();
				ClownStates[clownKey] = value;
			}
			return value;
		}

		internal static void RemoveState(ClownTrap clownTrap)
		{
			ClownStates.Remove(GetClownKey(clownTrap));
		}

		internal static float GetPressMultiplier(int pressCount)
		{
			if (!PressMultiplierEnabled.Value)
			{
				return 1f;
			}
			if (pressCount <= 1)
			{
				return Mathf.Max(0f, Press1Multiplier.Value);
			}
			if (pressCount == 2)
			{
				return Mathf.Max(0f, Press2Multiplier.Value);
			}
			return Mathf.Max(0f, Press3Multiplier.Value);
		}

		internal static void NormalizeMinMax(ref int minValue, ref int maxValue, int clampMin)
		{
			if (minValue < clampMin)
			{
				minValue = clampMin;
			}
			if (maxValue < clampMin)
			{
				maxValue = clampMin;
			}
			if (maxValue < minValue)
			{
				int num = minValue;
				minValue = maxValue;
				maxValue = num;
			}
		}

		internal static int GetStableSeed(ClownTrap clownTrap, int salt)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			int num = 17;
			PhotonView component = ((Component)clownTrap).GetComponent<PhotonView>();
			int num2 = (((Object)(object)component != (Object)null) ? component.ViewID : 0);
			num = num * 31 + num2;
			num = num * 31 + ((Object)((Component)clownTrap).gameObject).name.GetHashCode();
			Vector3 position = ((Component)clownTrap).transform.position;
			num = num * 31 + Mathf.RoundToInt(position.x * 100f);
			num = num * 31 + Mathf.RoundToInt(position.y * 100f);
			num = num * 31 + Mathf.RoundToInt(position.z * 100f);
			return num * 31 + salt;
		}

		internal static Random CreateDeterministicRandom(ClownTrap clownTrap, int salt)
		{
			return new Random(GetStableSeed(clownTrap, salt));
		}

		internal static int RollDeterministicInt(ClownTrap clownTrap, int salt, int minValue, int maxValue)
		{
			NormalizeMinMax(ref minValue, ref maxValue, (minValue > 0) ? 1 : 0);
			if (minValue == maxValue)
			{
				return minValue;
			}
			Random random = CreateDeterministicRandom(clownTrap, salt);
			return random.Next(minValue, maxValue + 1);
		}

		internal static float RollDeterministicPercent01(ClownTrap clownTrap, int salt)
		{
			Random random = CreateDeterministicRandom(clownTrap, salt);
			return (float)random.NextDouble();
		}

		internal static int GetWarningCount(ClownTrap clownTrap)
		{
			if (ClownWarningCountField == null)
			{
				return 2;
			}
			if (!(ClownWarningCountField.GetValue(clownTrap) is int result))
			{
				return 2;
			}
			return result;
		}

		internal static void SetWarningCount(ClownTrap clownTrap, int value)
		{
			if (ClownWarningCountField != null)
			{
				ClownWarningCountField.SetValue(clownTrap, value);
			}
		}

		internal static bool GetCountDownActive(ClownTrap clownTrap)
		{
			if (ClownCountDownActiveField == null)
			{
				return false;
			}
			if (!(ClownCountDownActiveField.GetValue(clownTrap) is bool result))
			{
				return false;
			}
			return result;
		}

		internal static void EnsureRequiredPressCountAssigned(ClownTrap clownTrap)
		{
			try
			{
				ClownState orCreateState = GetOrCreateState(clownTrap);
				if (!orCreateState.RequiredPressCountAssigned)
				{
					int minValue = ExplosionPressCountMin.Value;
					int maxValue = ExplosionPressCountMax.Value;
					NormalizeMinMax(ref minValue, ref maxValue, 1);
					int num = (orCreateState.RequiredPressCount = RollDeterministicInt(clownTrap, 1001, minValue, maxValue));
					orCreateState.RequiredPressCountAssigned = true;
					SetWarningCount(clownTrap, Mathf.Max(0, num - 1));
					if (DebugLogEnabled.Value)
					{
						LogSource.LogInfo((object)("[PressYourLuckCrown] RequiredPressCount=" + num + " Object=" + ((Object)((Component)clownTrap).gameObject).name));
					}
				}
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] EnsureRequiredPressCountAssigned failure\n" + ex));
			}
		}

		internal static float CalculatePlannedBonus(ClownTrap clownTrap, int pressCount, bool jackpot)
		{
			if (!BonusEnabled.Value)
			{
				return 0f;
			}
			int minValue = BonusValueMin.Value;
			int maxValue = BonusValueMax.Value;
			NormalizeMinMax(ref minValue, ref maxValue, 0);
			int minValue2 = JackpotValueMin.Value;
			int maxValue2 = JackpotValueMax.Value;
			NormalizeMinMax(ref minValue2, ref maxValue2, 0);
			float num;
			if (jackpot)
			{
				num = RollDeterministicInt(clownTrap, 2000 + pressCount, minValue2, maxValue2);
				if (JackpotRoundToHundreds.Value)
				{
					num = Mathf.Round(num / 100f) * 100f;
				}
				if (JackpotUsesMultiplier.Value)
				{
					num *= GetPressMultiplier(pressCount);
				}
			}
			else
			{
				num = RollDeterministicInt(clownTrap, 3000 + pressCount, minValue, maxValue);
				if (RoundBonusToHundreds.Value)
				{
					num = Mathf.Round(num / 100f) * 100f;
				}
				num *= GetPressMultiplier(pressCount);
			}
			return Mathf.Max(0f, Mathf.Round(num));
		}

		internal static bool RollJackpot(ClownTrap clownTrap, int pressCount)
		{
			if (!JackpotEnabled.Value)
			{
				return false;
			}
			float num = Mathf.Clamp(JackpotChancePercent.Value, 0f, 100f);
			if (num <= 0f)
			{
				return false;
			}
			float num2 = RollDeterministicPercent01(clownTrap, 4000 + pressCount) * 100f;
			return num2 < num;
		}

		internal static void EnsureDollarValueInitialized(ValuableObject valuableObject)
		{
			if (!GetDollarValueSet(valuableObject))
			{
				valuableObject.DollarValueSetLogic();
			}
		}

		internal static float GetDollarValueCurrent(ValuableObject valuableObject)
		{
			if (ValuableDollarValueCurrentField == null)
			{
				return 0f;
			}
			if (!(ValuableDollarValueCurrentField.GetValue(valuableObject) is float result))
			{
				return 0f;
			}
			return result;
		}

		internal static float GetDollarValueOriginal(ValuableObject valuableObject)
		{
			if (ValuableDollarValueOriginalField == null)
			{
				return 0f;
			}
			if (!(ValuableDollarValueOriginalField.GetValue(valuableObject) is float result))
			{
				return 0f;
			}
			return result;
		}

		internal static bool GetDollarValueSet(ValuableObject valuableObject)
		{
			if (ValuableDollarValueSetField == null)
			{
				return false;
			}
			if (!(ValuableDollarValueSetField.GetValue(valuableObject) is bool result))
			{
				return false;
			}
			return result;
		}

		internal static void SetDollarValues(ValuableObject valuableObject, float originalValue, float currentValue)
		{
			if (ValuableDollarValueOriginalField != null)
			{
				ValuableDollarValueOriginalField.SetValue(valuableObject, originalValue);
			}
			if (ValuableDollarValueCurrentField != null)
			{
				ValuableDollarValueCurrentField.SetValue(valuableObject, currentValue);
			}
			if (ValuableDollarValueSetField != null)
			{
				ValuableDollarValueSetField.SetValue(valuableObject, true);
			}
		}

		internal static void SyncDollarValueToOthers(ValuableObject valuableObject, float newValue)
		{
			if (SemiFunc.IsMultiplayer())
			{
				PhotonView component = ((Component)valuableObject).GetComponent<PhotonView>();
				if (!((Object)(object)component == (Object)null))
				{
					component.RPC("DollarValueSetRPC", (RpcTarget)1, new object[1] { newValue });
				}
			}
		}

		internal static void ApplyPlannedBonus(ClownTrap clownTrap, PressContext context)
		{
			try
			{
				if (!ModEnabled.Value || !SemiFunc.IsMasterClientOrSingleplayer() || context == null || context.BonusAmount <= 0f || (context.WouldHaveBeenFinalPress && !ApplyBonusOnFinalPress.Value))
				{
					return;
				}
				ValuableObject component = ((Component)clownTrap).GetComponent<ValuableObject>();
				if (!((Object)(object)component == (Object)null))
				{
					EnsureDollarValueInitialized(component);
					float dollarValueCurrent = GetDollarValueCurrent(component);
					float dollarValueOriginal = GetDollarValueOriginal(component);
					float originalValue = Mathf.Max(0f, dollarValueOriginal + context.BonusAmount);
					float num = Mathf.Max(0f, dollarValueCurrent + context.BonusAmount);
					SetDollarValues(component, originalValue, num);
					SyncDollarValueToOthers(component, num);
					if (DebugLogEnabled.Value)
					{
						LogSource.LogInfo((object)("[PressYourLuckCrown] Press=" + context.PressCount + " Jackpot=" + context.IsJackpot + " Bonus=$" + context.BonusAmount + " NewValue=$" + num + " WouldFinal=" + context.WouldHaveBeenFinalPress + " Object=" + ((Object)((Component)clownTrap).gameObject).name));
					}
				}
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] ApplyPlannedBonus failure\n" + ex));
			}
		}

		internal static void TryPlayMegaNoise(ClownTrap clownTrap)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!ModEnabled.Value || !MegaNoiseEnabled.Value)
				{
					return;
				}
				Vector3 bestSoundPosition = GetBestSoundPosition(clownTrap);
				if (clownTrap.NoseSqeak != null)
				{
					clownTrap.NoseSqeak.Play(bestSoundPosition, Mathf.Max(0f, PressSoundVolumeMultiplier.Value), Mathf.Max(0.1f, PressSoundFalloffMultiplier.Value), Mathf.Max(0f, PressSoundOffscreenVolumeMultiplier.Value), Mathf.Max(0.1f, PressSoundOffscreenFalloffMultiplier.Value));
				}
				if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)EnemyDirector.instance != (Object)null && PressInvestigateRange.Value > 0f)
				{
					EnemyDirector.instance.SetInvestigate(bestSoundPosition, PressInvestigateRange.Value, PressInvestigatePathfindOnly.Value);
					int num = Mathf.Max(0, ExtraInvestigatePulses.Value);
					if (num > 0 && (Object)(object)Instance != (Object)null)
					{
						((MonoBehaviour)Instance).StartCoroutine(InvestigatePulseCoroutine(bestSoundPosition, num, Mathf.Max(0.05f, ExtraInvestigatePulseInterval.Value), PressInvestigateRange.Value, PressInvestigatePathfindOnly.Value));
					}
				}
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] TryPlayMegaNoise failure\n" + ex));
			}
		}

		[IteratorStateMachine(typeof(<InvestigatePulseCoroutine>d__75))]
		private static IEnumerator InvestigatePulseCoroutine(Vector3 position, int pulseCount, float interval, float range, bool pathfindOnly)
		{
			//IL_0007: 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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InvestigatePulseCoroutine>d__75(0)
			{
				position = position,
				pulseCount = pulseCount,
				interval = interval,
				range = range,
				pathfindOnly = pathfindOnly
			};
		}

		internal static void PlayJackpotFakeExplosion(ClownTrap clownTrap)
		{
			//IL_0038: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ParticleScriptExplosion component = ((Component)clownTrap).GetComponent<ParticleScriptExplosion>();
				if (!((Object)(object)component == (Object)null))
				{
					Vector3 val = (((Object)(object)clownTrap.Center != (Object)null) ? clownTrap.Center.position : ((Component)clownTrap).transform.position);
					component.Spawn(val, 1.5f, 0, 0, 1f, true, false, 1f);
				}
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] PlayJackpotFakeExplosion failure\n" + ex));
			}
		}

		internal static void MakeJackpotClownUltraFragile(ClownTrap clownTrap)
		{
			try
			{
				if (!JackpotUltraFragile.Value)
				{
					return;
				}
				PhysGrabObjectImpactDetector component = ((Component)clownTrap).GetComponent<PhysGrabObjectImpactDetector>();
				if (!((Object)(object)component == (Object)null))
				{
					component.durability = 1f;
					component.fragility = 100f;
					component.fragilityMultiplier = 10f;
					component.destroyDisable = false;
					component.indestructibleBreakEffects = true;
					if (ImpactDetectorIndestructibleSpawnTimerField != null)
					{
						ImpactDetectorIndestructibleSpawnTimerField.SetValue(component, 0f);
					}
				}
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] MakeJackpotClownUltraFragile failure\n" + ex));
			}
		}

		internal static void ExecuteRealExplosion(ClownTrap clownTrap)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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)
			try
			{
				((Trap)clownTrap).trapActive = false;
				AudioSource val = null;
				if (ClownPreviousAudioSourceField != null)
				{
					object? value = ClownPreviousAudioSourceField.GetValue(clownTrap);
					val = (AudioSource)((value is AudioSource) ? value : null);
				}
				if ((Object)(object)val != (Object)null)
				{
					val.Stop();
				}
				ParticleScriptExplosion component = ((Component)clownTrap).GetComponent<ParticleScriptExplosion>();
				PhysGrabObject component2 = ((Component)clownTrap).GetComponent<PhysGrabObject>();
				Vector3 val2 = (((Object)(object)clownTrap.Center != (Object)null) ? clownTrap.Center.position : ((Component)clownTrap).transform.position);
				if ((Object)(object)component != (Object)null)
				{
					int num = Mathf.Max(1, Mathf.RoundToInt(100f * Mathf.Clamp(ExplosionDamageMultiplier.Value, 0.01f, 10f)));
					int num2 = Mathf.Max(1, Mathf.RoundToInt(300f * Mathf.Clamp(ExplosionDamageMultiplier.Value, 0.01f, 10f)));
					ParticlePrefabExplosion val3 = component.Spawn(val2, 1.5f, num, num2, 1f, false, false, 1f);
					if ((Object)(object)val3 != (Object)null && (Object)(object)val3.HurtCollider != (Object)null)
					{
						float num3 = Mathf.Clamp(ExplosionKnockbackMultiplier.Value, 0.01f, 10f);
						float num4 = Mathf.Clamp(ExplosionValuableDamageMultiplier.Value, 0.01f, 10f);
						val3.HurtCollider.playerDamage = num;
						val3.HurtCollider.enemyDamage = num2;
						HurtCollider hurtCollider = val3.HurtCollider;
						hurtCollider.playerHitForce *= num3;
						HurtCollider hurtCollider2 = val3.HurtCollider;
						hurtCollider2.playerTumbleForce *= num3;
						HurtCollider hurtCollider3 = val3.HurtCollider;
						hurtCollider3.playerTumbleTorque *= num3;
						HurtCollider hurtCollider4 = val3.HurtCollider;
						hurtCollider4.enemyHitForce *= num3;
						HurtCollider hurtCollider5 = val3.HurtCollider;
						hurtCollider5.enemyHitTorque *= num3;
						HurtCollider hurtCollider6 = val3.HurtCollider;
						hurtCollider6.physHitForce *= num4;
					}
				}
				if ((Object)(object)component2 != (Object)null)
				{
					component2.dead = true;
				}
				RemoveState(clownTrap);
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[PressYourLuckCrown] ExecuteRealExplosion failure\n" + ex));
			}
		}

		internal static Vector3 GetBestSoundPosition(ClownTrap clownTrap)
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)clownTrap.Center != (Object)null)
			{
				return clownTrap.Center.position;
			}
			PhysGrabObject component = ((Component)clownTrap).GetComponent<PhysGrabObject>();
			if ((Object)(object)component != (Object)null)
			{
				return component.centerPoint;
			}
			return ((Component)clownTrap).transform.position;
		}
	}
}