Decompiled source of StageFlux v4.2.2

StagePhysicsEvents.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Codex")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("4.2.2.0")]
[assembly: AssemblyInformationalVersion("4.2.2")]
[assembly: AssemblyProduct("StagePhysicsEvents")]
[assembly: AssemblyTitle("StagePhysicsEvents")]
[assembly: AssemblyVersion("4.2.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 REPOJP.StagePhysicsEvents
{
	[BepInPlugin("REPOJP.StagePhysicsEvents", "Stage Flux", "4.2.2")]
	public sealed class StagePhysicsEventsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "REPOJP.StagePhysicsEvents";

		public const string PluginName = "Stage Flux";

		public const string PluginVersion = "4.2.2";

		private Harmony? _harmony;

		private GameObject? _controllerObject;

		internal static StagePhysicsEventsPlugin Instance { get; private set; }

		internal static ManualLogSource ModLogger { get; private set; }

		internal StagePhysicsConfig Settings { get; private set; }

		internal StagePhysicsEventController Controller { get; private set; }

		private void Awake()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			Instance = this;
			ModLogger = ((BaseUnityPlugin)this).Logger;
			Settings = new StagePhysicsConfig(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			_controllerObject = new GameObject("StagePhysicsEvents_Controller");
			((Object)_controllerObject).hideFlags = (HideFlags)61;
			_controllerObject.transform.SetParent(((Component)this).transform, false);
			_controllerObject.SetActive(false);
			Controller = _controllerObject.AddComponent<StagePhysicsEventController>();
			Controller.Initialize(Settings);
			((Component)this).gameObject.AddComponent<StagePhysicsEventHud>().Initialize(Settings, Controller);
			_harmony = new Harmony("REPOJP.StagePhysicsEvents");
			try
			{
				_harmony.PatchAll(typeof(LifecyclePatches));
				_harmony.PatchAll(typeof(NotificationEnemyReactionPatches));
				_harmony.PatchAll(typeof(EnemySpeedPatches));
				SceneManager.activeSceneChanged += ActiveSceneChanged;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Stage Flux 4.2.2 loaded.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to apply Harmony patches: {arg}");
				_harmony.UnpatchSelf();
				((Behaviour)Controller).enabled = false;
			}
		}

		private void OnDestroy()
		{
			SceneManager.activeSceneChanged -= ActiveSceneChanged;
			Controller?.Shutdown();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			PhysGrabObjectRegistry.Clear();
			if ((Object)(object)_controllerObject != (Object)null)
			{
				Object.Destroy((Object)(object)_controllerObject);
			}
		}

		private void ActiveSceneChanged(Scene previous, Scene current)
		{
			Controller?.StageEnding();
		}
	}
	internal sealed class StagePhysicsConfig
	{
		[Flags]
		private enum EffectRisk
		{
			None = 0,
			ForcedMovement = 1,
			LethalHazard = 2,
			AreaHazard = 4,
			EnemyPressure = 8,
			ValuableRisk = 0x10,
			ControlImpairment = 0x20,
			ValueLossAmplifier = 0x40,
			VisualImpairment = 0x80
		}

		private const int CurrentConfigRevision = 9;

		private static readonly PropertyInfo? OrphanedEntriesProperty = typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);

		private readonly ManualLogSource _logger;

		private string _lastProbabilityWarning = string.Empty;

		private string _lastRangeWarning = string.Empty;

		internal ConfigEntry<bool> Enabled { get; }

		internal ConfigEntry<string> Mode { get; }

		internal ConfigEntry<int> StageActivationChancePercent { get; }

		internal ConfigEntry<int> MaxSimultaneousEffects { get; }

		internal ConfigEntry<bool> AllowDangerousCombinations { get; }

		internal ConfigEntry<int> ValuableProtectionReleaseDelaySeconds { get; }

		internal ConfigEntry<int> IntervalMinSeconds { get; }

		internal ConfigEntry<int> IntervalMaxSeconds { get; }

		internal ConfigEntry<int> EffectDurationMinSeconds { get; }

		internal ConfigEntry<int> EffectDurationMaxSeconds { get; }

		internal ConfigEntry<bool> FeatherEnabled { get; }

		internal ConfigEntry<int> FeatherChance { get; }

		internal ConfigEntry<bool> ZeroGravityEnabled { get; }

		internal ConfigEntry<int> ZeroGravityChance { get; }

		internal ConfigEntry<bool> ZeroGravityProtectValuables { get; }

		internal ConfigEntry<bool> BatteryEnabled { get; }

		internal ConfigEntry<int> BatteryChance { get; }

		internal ConfigEntry<int> BatteryChargeAmount { get; }

		internal ConfigEntry<int> BatteryChargeIntervalSeconds { get; }

		internal ConfigEntry<bool> HealEnabled { get; }

		internal ConfigEntry<int> HealChance { get; }

		internal ConfigEntry<int> HealAmount { get; }

		internal ConfigEntry<int> HealIntervalSeconds { get; }

		internal ConfigEntry<bool> IndestructibleEnabled { get; }

		internal ConfigEntry<int> IndestructibleChance { get; }

		internal ConfigEntry<bool> FragilityEnabled { get; }

		internal ConfigEntry<int> FragilityChance { get; }

		internal ConfigEntry<int> FragilityMultiplierPercent { get; }

		internal ConfigEntry<bool> GumballHypnosisEnabled { get; }

		internal ConfigEntry<int> GumballHypnosisChance { get; }

		internal ConfigEntry<bool> HealingAuraEnabled { get; }

		internal ConfigEntry<int> HealingAuraChance { get; }

		internal ConfigEntry<int> HealingAuraHealthPool { get; }

		internal ConfigEntry<int> HealingAuraSpawnCountMin { get; }

		internal ConfigEntry<int> HealingAuraSpawnCountMax { get; }

		internal ConfigEntry<int> HealingAuraSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> HealingAuraMinimumPlayerDistance { get; }

		internal ConfigEntry<int> HealingAuraMaximumActiveInstances { get; }

		internal ConfigEntry<bool> StarBarrageEnabled { get; }

		internal ConfigEntry<int> StarBarrageChance { get; }

		internal ConfigEntry<bool> StarBarrageProtectValuables { get; }

		internal ConfigEntry<int> StarBarrageProjectileCountMin { get; }

		internal ConfigEntry<int> StarBarrageProjectileCountMax { get; }

		internal ConfigEntry<int> StarBarrageSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> StarBarrageMinimumPlayerDistance { get; }

		internal ConfigEntry<int> StarBarrageMaximumActiveInstances { get; }

		internal ConfigEntry<bool> SpiderScareEnabled { get; }

		internal ConfigEntry<int> SpiderScareChance { get; }

		internal ConfigEntry<int> SpiderScarePlayersPerWaveMin { get; }

		internal ConfigEntry<int> SpiderScarePlayersPerWaveMax { get; }

		internal ConfigEntry<int> SpiderScareSpawnIntervalSeconds { get; }

		internal ConfigEntry<bool> TrafficShockEnabled { get; }

		internal ConfigEntry<int> TrafficShockChance { get; }

		internal ConfigEntry<int> TrafficShockPlayersPerPulseMin { get; }

		internal ConfigEntry<int> TrafficShockPlayersPerPulseMax { get; }

		internal ConfigEntry<int> TrafficShockPulseIntervalSeconds { get; }

		internal ConfigEntry<bool> DangerousValuablesEnabled { get; }

		internal ConfigEntry<int> DangerousValuablesChance { get; }

		internal ConfigEntry<bool> DangerousValuablesProtectValuables { get; }

		internal ConfigEntry<bool> DangerousValuablesIceSawEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesBlenderEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesFlamethrowerEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesEggEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesCarEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesPlaneEnabled { get; }

		internal ConfigEntry<bool> DangerousValuablesBroomEnabled { get; }

		internal ConfigEntry<int> DangerousValuablesActivationCountMin { get; }

		internal ConfigEntry<int> DangerousValuablesActivationCountMax { get; }

		internal ConfigEntry<int> DangerousValuablesReactivationIntervalSeconds { get; }

		internal ConfigEntry<int> DangerousValuablesMaximumActiveInstances { get; }

		internal ConfigEntry<bool> RollEnabled { get; }

		internal ConfigEntry<int> RollChance { get; }

		internal ConfigEntry<bool> RollProtectValuables { get; }

		internal ConfigEntry<bool> VoidEnabled { get; }

		internal ConfigEntry<int> VoidChance { get; }

		internal ConfigEntry<bool> VoidProtectValuables { get; }

		internal ConfigEntry<int> VoidSpawnCountMin { get; }

		internal ConfigEntry<int> VoidSpawnCountMax { get; }

		internal ConfigEntry<int> VoidSpawnIntervalSeconds { get; }

		internal ConfigEntry<bool> LevitationEnabled { get; }

		internal ConfigEntry<int> LevitationChance { get; }

		internal ConfigEntry<bool> LevitationProtectValuables { get; }

		internal ConfigEntry<int> LevitationSpawnCountMin { get; }

		internal ConfigEntry<int> LevitationSpawnCountMax { get; }

		internal ConfigEntry<int> LevitationSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> LevitationMinimumPlayerDistance { get; }

		internal ConfigEntry<int> LevitationMaximumActiveInstances { get; }

		internal ConfigEntry<bool> ShockwaveEnabled { get; }

		internal ConfigEntry<int> ShockwaveChance { get; }

		internal ConfigEntry<bool> ShockwaveProtectValuables { get; }

		internal ConfigEntry<int> ShockwaveSpawnCountMin { get; }

		internal ConfigEntry<int> ShockwaveSpawnCountMax { get; }

		internal ConfigEntry<int> ShockwaveSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> ShockwaveMinimumPlayerDistance { get; }

		internal ConfigEntry<int> ShockwaveMaximumActiveInstances { get; }

		internal ConfigEntry<int> ShockwaveLaunchForceMin { get; }

		internal ConfigEntry<int> ShockwaveLaunchForceMax { get; }

		internal ConfigEntry<bool> StunBlastEnabled { get; }

		internal ConfigEntry<int> StunBlastChance { get; }

		internal ConfigEntry<bool> StunBlastProtectValuables { get; }

		internal ConfigEntry<int> StunBlastSpawnCountMin { get; }

		internal ConfigEntry<int> StunBlastSpawnCountMax { get; }

		internal ConfigEntry<int> StunBlastSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> StunBlastMinimumPlayerDistance { get; }

		internal ConfigEntry<int> StunBlastMaximumActiveInstances { get; }

		internal ConfigEntry<int> StunBlastLaunchForceMin { get; }

		internal ConfigEntry<int> StunBlastLaunchForceMax { get; }

		internal ConfigEntry<bool> ExplosionRainEnabled { get; }

		internal ConfigEntry<int> ExplosionRainChance { get; }

		internal ConfigEntry<bool> ExplosionRainProtectValuables { get; }

		internal ConfigEntry<int> ExplosionRainSpawnCountMin { get; }

		internal ConfigEntry<int> ExplosionRainSpawnCountMax { get; }

		internal ConfigEntry<int> ExplosionRainSpawnIntervalSeconds { get; }

		internal ConfigEntry<int> ExplosionRainMinimumPlayerDistance { get; }

		internal ConfigEntry<int> ExplosionRainMaximumActiveInstances { get; }

		internal ConfigEntry<int> ExplosionRainLaunchForceMin { get; }

		internal ConfigEntry<int> ExplosionRainLaunchForceMax { get; }

		internal ConfigEntry<bool> EnemyWaveEnabled { get; }

		internal ConfigEntry<int> EnemyWaveChance { get; }

		internal ConfigEntry<int> EnemyWaveSpawnCountMin { get; }

		internal ConfigEntry<int> EnemyWaveSpawnCountMax { get; }

		internal ConfigEntry<int> EnemyWaveReplenishIntervalSeconds { get; }

		internal ConfigEntry<int> EnemyWaveMinimumPlayerDistance { get; }

		internal ConfigEntry<bool> EnemyWaveDespawnOnEnd { get; }

		internal ConfigEntry<bool> MinefieldEnabled { get; }

		internal ConfigEntry<int> MinefieldChance { get; }

		internal ConfigEntry<bool> MinefieldProtectValuables { get; }

		internal ConfigEntry<bool> MinefieldExplosiveEnabled { get; }

		internal ConfigEntry<bool> MinefieldShockwaveEnabled { get; }

		internal ConfigEntry<bool> MinefieldStunEnabled { get; }

		internal ConfigEntry<int> MinefieldSpawnCountMin { get; }

		internal ConfigEntry<int> MinefieldSpawnCountMax { get; }

		internal ConfigEntry<int> MinefieldReplenishIntervalSeconds { get; }

		internal ConfigEntry<int> MinefieldMaximumActiveMines { get; }

		internal ConfigEntry<int> MinefieldMinimumPlayerDistance { get; }

		internal ConfigEntry<bool> MinefieldReplenishTriggeredMines { get; }

		internal ConfigEntry<bool> FreezeEnabled { get; }

		internal ConfigEntry<int> FreezeChance { get; }

		internal ConfigEntry<bool> StunEnabled { get; }

		internal ConfigEntry<int> StunChance { get; }

		internal ConfigEntry<bool> EnemyWarpEnabled { get; }

		internal ConfigEntry<int> EnemyWarpChance { get; }

		internal ConfigEntry<int> EnemyWarpIntervalSeconds { get; }

		internal ConfigEntry<int> EnemyWarpEnemiesPerPulse { get; }

		internal ConfigEntry<int> EnemyWarpMinimumPlayerDistance { get; }

		internal ConfigEntry<bool> EnemyHuntEnabled { get; }

		internal ConfigEntry<int> EnemyHuntChance { get; }

		internal ConfigEntry<int> EnemyHuntRetargetIntervalSeconds { get; }

		internal ConfigEntry<bool> EnemySpeedUpEnabled { get; }

		internal ConfigEntry<int> EnemySpeedUpChance { get; }

		internal ConfigEntry<int> EnemySpeedUpPercent { get; }

		internal ConfigEntry<bool> EnemySpeedDownEnabled { get; }

		internal ConfigEntry<int> EnemySpeedDownChance { get; }

		internal ConfigEntry<int> EnemySpeedDownPercent { get; }

		internal ConfigEntry<bool> EnemyRegenEnabled { get; }

		internal ConfigEntry<int> EnemyRegenChance { get; }

		internal ConfigEntry<int> EnemyRegenHealAmount { get; }

		internal ConfigEntry<int> EnemyRegenIntervalSeconds { get; }

		internal ConfigEntry<bool> EnemyPurgeEnabled { get; }

		internal ConfigEntry<int> EnemyPurgeChance { get; }

		internal ConfigEntry<int> EnemyPurgeDamageAmount { get; }

		internal ConfigEntry<int> EnemyPurgeIntervalSeconds { get; }

		internal ConfigEntry<bool> EnemyPurgeCanKill { get; }

		internal ConfigEntry<bool> DamagePulseEnabled { get; }

		internal ConfigEntry<int> DamagePulseChance { get; }

		internal ConfigEntry<int> DamagePulseAmount { get; }

		internal ConfigEntry<int> DamagePulseIntervalSeconds { get; }

		internal ConfigEntry<bool> DamagePulseSavingGrace { get; }

		internal ConfigEntry<bool> SecondChanceEnabled { get; }

		internal ConfigEntry<int> SecondChanceChance { get; }

		internal ConfigEntry<int> SecondChanceCheckIntervalSeconds { get; }

		internal ConfigEntry<int> SecondChanceMaxRevivesPerPlayer { get; }

		internal ConfigEntry<bool> KnockbackEnabled { get; }

		internal ConfigEntry<int> KnockbackChance { get; }

		internal ConfigEntry<int> KnockbackIntervalSeconds { get; }

		internal ConfigEntry<int> KnockbackHorizontalForce { get; }

		internal ConfigEntry<int> KnockbackVerticalForce { get; }

		internal ConfigEntry<bool> FlickerEnabled { get; }

		internal ConfigEntry<int> FlickerChance { get; }

		internal ConfigEntry<int> FlickerIntervalSeconds { get; }

		internal ConfigEntry<int> FlickerIntensityPercent { get; }

		internal ConfigEntry<bool> QuakeEnabled { get; }

		internal ConfigEntry<int> QuakeChance { get; }

		internal ConfigEntry<bool> QuakeProtectValuables { get; }

		internal ConfigEntry<int> QuakeIntervalSeconds { get; }

		internal ConfigEntry<int> QuakeForce { get; }

		internal ConfigEntry<bool> DoorChaosEnabled { get; }

		internal ConfigEntry<int> DoorChaosChance { get; }

		internal ConfigEntry<int> DoorChaosIntervalSeconds { get; }

		internal ConfigEntry<int> DoorChaosAffectedPercent { get; }

		internal ConfigEntry<int> DoorChaosForce { get; }

		internal ConfigEntry<bool> DoorChaosHingedItemsEnabled { get; }

		internal ConfigEntry<bool> ValueSurgeEnabled { get; }

		internal ConfigEntry<int> ValueSurgeChance { get; }

		internal ConfigEntry<int> ValueSurgeMultiplierPercent { get; }

		internal ConfigEntry<bool> ValueSurgeRestoreOnEnd { get; }

		internal ConfigEntry<bool> ValueCrashEnabled { get; }

		internal ConfigEntry<int> ValueCrashChance { get; }

		internal ConfigEntry<int> ValueCrashMultiplierPercent { get; }

		internal ConfigEntry<bool> ValueCrashRestoreOnEnd { get; }

		internal ConfigEntry<bool> TargetValuables { get; }

		internal ConfigEntry<bool> TargetCosmeticBoxes { get; }

		internal ConfigEntry<bool> TargetItems { get; }

		internal ConfigEntry<bool> TargetDoors { get; }

		internal ConfigEntry<bool> TargetWeapons { get; }

		internal ConfigEntry<bool> TargetPlayers { get; }

		internal ConfigEntry<bool> TargetEnemies { get; }

		internal ConfigEntry<bool> HudEnabled { get; }

		internal ConfigEntry<bool> ChatAnnouncementsEnabled { get; }

		internal ConfigEntry<bool> EnemyReactionEnabled { get; }

		internal ConfigEntry<bool> StartCountdownEnabled { get; }

		internal ConfigEntry<bool> EndCountdownEnabled { get; }

		internal ConfigEntry<string> HudStyle { get; }

		internal ConfigEntry<string> HudLayoutDirection { get; }

		internal ConfigEntry<string> HudAnchor { get; }

		internal ConfigEntry<string> HudAlignment { get; }

		internal ConfigEntry<int> HudOffsetX { get; }

		internal ConfigEntry<int> HudOffsetY { get; }

		internal ConfigEntry<int> HudScalePercent { get; }

		internal ConfigEntry<int> HudBackgroundOpacityPercent { get; }

		internal (int Min, int Max) EffectiveIntervalRange => OrderedRange(IntervalMinSeconds.Value, IntervalMaxSeconds.Value, "Interval");

		internal (int Min, int Max) EffectiveDurationRange => OrderedRange(EffectDurationMinSeconds.Value, EffectDurationMaxSeconds.Value, "EffectDuration");

		internal bool HasSelectableEffect
		{
			get
			{
				foreach (StageEffect individualEffect in StageEffectSet.IndividualEffects)
				{
					if (GetChance(individualEffect) > 0)
					{
						return true;
					}
				}
				return false;
			}
		}

		internal bool MinefieldHasEnabledType
		{
			get
			{
				if (!MinefieldExplosiveEnabled.Value && !MinefieldShockwaveEnabled.Value)
				{
					return MinefieldStunEnabled.Value;
				}
				return true;
			}
		}

		internal bool HasGumballTargets
		{
			get
			{
				if (!TargetValuables.Value && !TargetCosmeticBoxes.Value && !TargetItems.Value)
				{
					return TargetWeapons.Value;
				}
				return true;
			}
		}

		internal bool DangerousValuablesHasEnabledType
		{
			get
			{
				if (!DangerousValuablesIceSawEnabled.Value && !DangerousValuablesBlenderEnabled.Value && !DangerousValuablesFlamethrowerEnabled.Value && !DangerousValuablesEggEnabled.Value && !DangerousValuablesCarEnabled.Value && !DangerousValuablesPlaneEnabled.Value)
				{
					return DangerousValuablesBroomEnabled.Value;
				}
				return true;
			}
		}

		internal StagePhysicsConfig(ConfigFile config, ManualLogSource logger)
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Expected O, but got Unknown
			//IL_2077: Unknown result type (might be due to invalid IL or missing references)
			//IL_2081: Expected O, but got Unknown
			//IL_20c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_20ca: Expected O, but got Unknown
			//IL_2276: Unknown result type (might be due to invalid IL or missing references)
			//IL_2280: Expected O, but got Unknown
			//IL_22bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_22c5: Expected O, but got Unknown
			//IL_233b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2345: Expected O, but got Unknown
			//IL_238a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2394: Expected O, but got Unknown
			//IL_255f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2569: Expected O, but got Unknown
			//IL_2571: Unknown result type (might be due to invalid IL or missing references)
			//IL_257b: Expected O, but got Unknown
			//IL_2587: Unknown result type (might be due to invalid IL or missing references)
			//IL_2591: Expected O, but got Unknown
			//IL_259d: Unknown result type (might be due to invalid IL or missing references)
			//IL_25a7: Expected O, but got Unknown
			//IL_25b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_25bd: Expected O, but got Unknown
			//IL_25c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_25d3: Expected O, but got Unknown
			//IL_25df: Unknown result type (might be due to invalid IL or missing references)
			//IL_25e9: Expected O, but got Unknown
			//IL_25f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_25ff: Expected O, but got Unknown
			//IL_260b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2615: Expected O, but got Unknown
			//IL_2621: Unknown result type (might be due to invalid IL or missing references)
			//IL_262b: Expected O, but got Unknown
			//IL_2637: Unknown result type (might be due to invalid IL or missing references)
			//IL_2641: Expected O, but got Unknown
			//IL_264d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2657: Expected O, but got Unknown
			//IL_2663: Unknown result type (might be due to invalid IL or missing references)
			//IL_266d: Expected O, but got Unknown
			//IL_2679: Unknown result type (might be due to invalid IL or missing references)
			//IL_2683: Expected O, but got Unknown
			//IL_268f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2699: Expected O, but got Unknown
			//IL_26a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_26af: Expected O, but got Unknown
			//IL_26bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_26c5: Expected O, but got Unknown
			//IL_26d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_26db: Expected O, but got Unknown
			//IL_26e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_26f1: Expected O, but got Unknown
			//IL_26fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_2707: Expected O, but got Unknown
			//IL_2746: Unknown result type (might be due to invalid IL or missing references)
			//IL_2750: Expected O, but got Unknown
			//IL_277e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2788: Expected O, but got Unknown
			//IL_2794: Unknown result type (might be due to invalid IL or missing references)
			//IL_279e: Expected O, but got Unknown
			//IL_27aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_27b4: Expected O, but got Unknown
			//IL_27c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_27ca: Expected O, but got Unknown
			//IL_27d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_27e0: Expected O, but got Unknown
			//IL_27ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_27f6: Expected O, but got Unknown
			//IL_2802: Unknown result type (might be due to invalid IL or missing references)
			//IL_280c: Expected O, but got Unknown
			//IL_2818: Unknown result type (might be due to invalid IL or missing references)
			//IL_2822: Expected O, but got Unknown
			//IL_282e: Unknown result type (might be due to invalid IL or missing references)
			//IL_2838: Expected O, but got Unknown
			//IL_2844: Unknown result type (might be due to invalid IL or missing references)
			//IL_284e: Expected O, but got Unknown
			//IL_285a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2864: Expected O, but got Unknown
			//IL_2870: Unknown result type (might be due to invalid IL or missing references)
			//IL_287a: Expected O, but got Unknown
			//IL_2886: Unknown result type (might be due to invalid IL or missing references)
			//IL_2890: Expected O, but got Unknown
			//IL_289c: Unknown result type (might be due to invalid IL or missing references)
			//IL_28a6: Expected O, but got Unknown
			//IL_28b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_28bc: Expected O, but got Unknown
			//IL_28c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_28d2: Expected O, but got Unknown
			//IL_28de: Unknown result type (might be due to invalid IL or missing references)
			//IL_28e8: Expected O, but got Unknown
			//IL_28f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_28fe: Expected O, but got Unknown
			//IL_290a: Unknown result type (might be due to invalid IL or missing references)
			//IL_2914: Expected O, but got Unknown
			//IL_2931: Unknown result type (might be due to invalid IL or missing references)
			//IL_293b: Expected O, but got Unknown
			//IL_2947: Unknown result type (might be due to invalid IL or missing references)
			//IL_2951: Expected O, but got Unknown
			//IL_295d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2967: Expected O, but got Unknown
			//IL_2973: Unknown result type (might be due to invalid IL or missing references)
			//IL_297d: Expected O, but got Unknown
			//IL_2989: Unknown result type (might be due to invalid IL or missing references)
			//IL_2993: Expected O, but got Unknown
			//IL_299f: Unknown result type (might be due to invalid IL or missing references)
			//IL_29a9: Expected O, but got Unknown
			//IL_29b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_29bf: Expected O, but got Unknown
			//IL_29cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_29d5: Expected O, but got Unknown
			//IL_29e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_29eb: Expected O, but got Unknown
			//IL_29f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a01: Expected O, but got Unknown
			//IL_2a0d: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a17: Expected O, but got Unknown
			//IL_2a23: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a2d: Expected O, but got Unknown
			//IL_2a39: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a43: Expected O, but got Unknown
			//IL_2a4f: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a59: Expected O, but got Unknown
			//IL_2a65: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a6f: Expected O, but got Unknown
			//IL_2a7b: Unknown result type (might be due to invalid IL or missing references)
			//IL_2a85: Expected O, but got Unknown
			_logger = logger;
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			string text = "Light" + "weight";
			ConfigEntry<bool> val = BindBool(config, text, "Enabled", value: true, "Legacy setting migrated to Feather.");
			ConfigEntry<int> val2 = BindInt(config, text, "ChancePercent", 5, 0, 100, "Legacy setting migrated to Feather.");
			BindBool(config, "Magnet", "Enabled", value: true, "Obsolete setting removed in 4.1.0.");
			BindInt(config, "Magnet", "ChancePercent", 10, 0, 100, "Obsolete setting removed in 4.1.0.");
			ConfigEntry<bool> val3 = BindBool(config, "Torque", "Enabled", value: false, "Legacy Torque setting migrated to Roll.");
			ConfigEntry<int> val4 = BindInt(config, "Torque", "ChancePercent", 5, 0, 100, "Legacy Torque setting migrated to Roll.");
			ConfigEntry<bool> val5 = BindBool(config, "Roll Staff", "Enabled", val3.Value, "Legacy Roll Staff setting migrated to Roll.");
			ConfigEntry<int> val6 = BindInt(config, "Roll Staff", "ChancePercent", val4.Value, 0, 100, "Legacy Roll Staff setting migrated to Roll.");
			BindBool(config, "Boost", "Enabled", value: true, "Obsolete setting removed in 4.1.0.");
			BindInt(config, "Boost", "ChancePercent", 3, 0, 100, "Obsolete setting removed in 4.1.0.");
			ConfigEntry<int> val7 = BindInt(config, "General", "StageEffectChancePercent", 20, 0, 100, "Legacy setting migrated to StageActivationChancePercent.");
			Enabled = BindBool(config, "General", "Enabled", value: true, "Enables the mod. Stage event behavior uses the host's settings.");
			Mode = config.Bind<string>("General", "Mode", "RandomEachEvent", new ConfigDescription("AllMode selects one of the other four modes with equal probability when each stage begins. RandomEachEvent rerolls every event. FixedForStage keeps the stage's first effect combination, duration, and interval. FixedPerExtraction keeps the stage's duration and interval but rerolls the effect combination after each completed extraction. PersistentForStage keeps the selected effect combination active until the stage ends.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "AllMode", "RandomEachEvent", "FixedForStage", "FixedPerExtraction", "PersistentForStage" }), Array.Empty<object>()));
			StageActivationChancePercent = BindInt(config, "General", "StageActivationChancePercent", val7.Value, 0, 100, "Chance that stage events are enabled for a stage. A failed roll disables effects, notifications, and the HUD for that stage.");
			MaxSimultaneousEffects = BindInt(config, "General", "MaxSimultaneousEffects", 3, 1, 5, "Maximum number of effects that can be selected for one event. Successful effects above this limit are reduced randomly.");
			AllowDangerousCombinations = BindBool(config, "Safety", "AllowDangerousCombinations", value: false, "Allows combinations that can greatly increase player death, uncontrolled movement, enemy pressure, visual disruption, or valuable loss.");
			ConfigEntry<int> val8 = BindInt(config, "Safety", "HazardIndestructibleReleaseDelaySeconds", 2, 1, 5, "Legacy setting migrated to ValuableProtectionReleaseDelaySeconds.");
			ValuableProtectionReleaseDelaySeconds = BindInt(config, "Safety", "ValuableProtectionReleaseDelaySeconds", val8.Value, 1, 5, "Seconds to keep targeted valuables Indestructible after a hazard event ends.");
			EffectDurationMinSeconds = BindInt(config, "Timing", "EffectDurationMinSeconds", 15, 10, 300, "Minimum effect duration in seconds.");
			EffectDurationMaxSeconds = BindInt(config, "Timing", "EffectDurationMaxSeconds", 30, 10, 300, "Maximum effect duration in seconds.");
			IntervalMinSeconds = BindInt(config, "Timing", "IntervalMinSeconds", 45, 10, 300, "Minimum number of seconds before the next event roll.");
			IntervalMaxSeconds = BindInt(config, "Timing", "IntervalMaxSeconds", 90, 10, 300, "Maximum number of seconds before the next event roll.");
			FeatherEnabled = BindBool(config, "Feather", "Enabled", val.Value, "Includes Feather in each event's independent rolls.");
			FeatherChance = BindInt(config, "Feather", "ChancePercent", val2.Value, 0, 100, "Independent chance for Feather in each event.");
			ConfigDefinition definition = new ConfigDefinition("Internal", "ConfigRevision");
			int num = ReadConfigRevision(config, definition);
			if (num < 1 && FeatherChance.Value == 30)
			{
				FeatherChance.Value = 15;
				_logger.LogInfo((object)"Migrated the previous default Feather chance from 30% to 15%.");
			}
			ZeroGravityEnabled = BindBool(config, "Zero Gravity", "Enabled", value: true, "Includes Zero Gravity in each event's independent rolls.");
			ZeroGravityChance = BindInt(config, "Zero Gravity", "ChancePercent", 5, 0, 100, "Independent chance for Zero Gravity in each event.");
			ZeroGravityProtectValuables = BindBool(config, "Zero Gravity", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Zero Gravity.");
			int val9 = ((num < 9) ? BindInt(config, "Zero Gravity", "IndestructibleReleaseDelaySeconds", 2, 1, 5, "Legacy setting migrated to Safety.ValuableProtectionReleaseDelaySeconds.").Value : 2);
			ConfigEntry<bool> val10 = BindBool(config, "Battery", "Enabled", value: true, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val11 = BindInt(config, "Battery", "ChancePercent", 5, 0, 100, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val12 = BindInt(config, "Battery", "ChargeAmount", 5, 1, 100, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val13 = BindInt(config, "Battery", "ChargeIntervalSeconds", 4, 1, 300, "Legacy setting migrated to Battery Charge.");
			if (num < 2)
			{
				if (val12.Value == 10)
				{
					val12.Value = 5;
					_logger.LogInfo((object)"Migrated the previous default Battery charge amount from 10 to 5.");
				}
				if (val13.Value == 2)
				{
					val13.Value = 4;
					_logger.LogInfo((object)"Migrated the previous default Battery charge interval from 2 seconds to 4 seconds.");
				}
			}
			ConfigEntry<bool> val14 = BindBool(config, "BatteryCharge", "Enabled", val10.Value, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val15 = BindInt(config, "BatteryCharge", "ChancePercent", val11.Value, 0, 100, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val16 = BindInt(config, "BatteryCharge", "ChargeAmount", val12.Value, 1, 100, "Legacy setting migrated to Battery Charge.");
			ConfigEntry<int> val17 = BindInt(config, "BatteryCharge", "ChargeIntervalSeconds", val13.Value, 1, 300, "Legacy setting migrated to Battery Charge.");
			BatteryEnabled = BindBool(config, "Battery Charge", "Enabled", val14.Value, "Includes Battery Charge in each event's independent rolls.");
			BatteryChance = BindInt(config, "Battery Charge", "ChancePercent", val15.Value, 0, 100, "Independent chance for Battery Charge in each event.");
			BatteryChargeAmount = BindInt(config, "Battery Charge", "ChargeAmount", val16.Value, 1, 100, "Battery percentage points restored to each targeted battery per charge tick.");
			BatteryChargeIntervalSeconds = BindInt(config, "Battery Charge", "ChargeIntervalSeconds", val17.Value, 1, 300, "Seconds between Battery Charge ticks.");
			HealEnabled = BindBool(config, "Heal", "Enabled", value: true, "Includes the Heal Orb effect in each event's independent rolls.");
			HealChance = BindInt(config, "Heal", "ChancePercent", 5, 0, 100, "Independent chance for Heal in each event.");
			HealAmount = BindInt(config, "Heal", "HealAmount", 10, 1, 100, "Health restored to each targeted player per Heal tick.");
			HealIntervalSeconds = BindInt(config, "Heal", "HealIntervalSeconds", 2, 1, 300, "Seconds between Heal ticks.");
			IndestructibleEnabled = BindBool(config, "Indestructible", "Enabled", value: true, "Includes the Indestructible Orb effect in each event's independent rolls.");
			IndestructibleChance = BindInt(config, "Indestructible", "ChancePercent", 5, 0, 100, "Independent chance for Indestructible in each event.");
			FragilityEnabled = BindBool(config, "Fragility", "Enabled", value: true, "Includes the stage-wide valuable Fragility effect in each event's independent rolls.");
			FragilityChance = BindInt(config, "Fragility", "ChancePercent", 5, 0, 100, "Independent chance for Fragility in each event.");
			FragilityMultiplierPercent = BindInt(config, "Fragility", "FragilityMultiplierPercent", 1000, 101, 5000, "Valuable impact-fragility multiplier. 100 is vanilla; this event accepts only values above 100 so valuables always become easier to break.");
			if (num < 3 && FragilityMultiplierPercent.Value == 200)
			{
				FragilityMultiplierPercent.Value = 1000;
				_logger.LogInfo((object)"Migrated the previous default Fragility multiplier from 200% to 1000%.");
			}
			GumballHypnosisEnabled = BindBool(config, "Gumball Hypnosis", "Enabled", value: true, "Includes Gumball Hypnosis in each event's independent rolls.");
			GumballHypnosisChance = BindInt(config, "Gumball Hypnosis", "ChancePercent", 5, 0, 100, "Independent chance for Gumball Hypnosis. Holding an enabled object category applies the vanilla Gumball screen and gaze effect until it is released.");
			HealingAuraEnabled = BindBool(config, "Healing Aura", "Enabled", value: true, "Includes Healing Aura in each event's independent rolls.");
			HealingAuraChance = BindInt(config, "Healing Aura", "ChancePercent", 5, 0, 100, "Independent chance for Healing Aura.");
			HealingAuraHealthPool = BindInt(config, "Healing Aura", "HealthPool", 50, 1, 1000, "Total health available from each spawned Healing Aura.");
			HealingAuraSpawnCountMin = BindInt(config, "Healing Aura", "SpawnCountMin", 1, 1, 30, "Minimum number of Healing Auras created in each wave.");
			HealingAuraSpawnCountMax = BindInt(config, "Healing Aura", "SpawnCountMax", 3, 1, 30, "Maximum number of Healing Auras created in each wave.");
			HealingAuraMaximumActiveInstances = BindInt(config, "Healing Aura", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked Healing Auras.");
			HealingAuraSpawnIntervalSeconds = BindInt(config, "Healing Aura", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Healing Aura spawn waves.");
			HealingAuraMinimumPlayerDistance = BindInt(config, "Healing Aura", "MinimumPlayerDistance", 0, 0, 100, "Minimum distance from a living player when selecting a Healing Aura spawn point.");
			StarBarrageEnabled = BindBool(config, "Star Barrage", "Enabled", value: true, "Includes Star Barrage in each event's independent rolls.");
			StarBarrageChance = BindInt(config, "Star Barrage", "ChancePercent", 5, 0, 100, "Independent chance for Star Barrage.");
			StarBarrageProjectileCountMin = BindInt(config, "Star Barrage", "ProjectileCountMin", 3, 1, 30, "Minimum number of Star Wand projectiles launched in each wave.");
			StarBarrageProjectileCountMax = BindInt(config, "Star Barrage", "ProjectileCountMax", 6, 1, 30, "Maximum number of Star Wand projectiles launched in each wave.");
			StarBarrageMaximumActiveInstances = BindInt(config, "Star Barrage", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked Star Wand projectiles.");
			StarBarrageSpawnIntervalSeconds = BindInt(config, "Star Barrage", "SpawnIntervalSeconds", 2, 1, 300, "Seconds between Star Barrage waves.");
			StarBarrageMinimumPlayerDistance = BindInt(config, "Star Barrage", "MinimumPlayerDistance", 5, 0, 100, "Minimum distance from a living player when selecting a projectile origin.");
			StarBarrageProtectValuables = BindBool(config, "Star Barrage", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Star Barrage.");
			SpiderScareEnabled = BindBool(config, "Spider Scare", "Enabled", value: true, "Includes Spider Scare in each event's independent rolls.");
			SpiderScareChance = BindInt(config, "Spider Scare", "ChancePercent", 5, 0, 100, "Independent chance for Spider Scare.");
			SpiderScarePlayersPerWaveMin = BindInt(config, "Spider Scare", "PlayersPerWaveMin", 1, 1, 30, "Minimum number of random living player positions targeted in each wave.");
			SpiderScarePlayersPerWaveMax = BindInt(config, "Spider Scare", "PlayersPerWaveMax", 3, 1, 30, "Maximum number of random living player positions targeted in each wave.");
			SpiderScareSpawnIntervalSeconds = BindInt(config, "Spider Scare", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Spider Scare waves.");
			TrafficShockEnabled = BindBool(config, "Traffic Shock", "Enabled", value: true, "Includes Traffic Shock in each event's independent rolls.");
			TrafficShockChance = BindInt(config, "Traffic Shock", "ChancePercent", 5, 0, 100, "Independent chance for Traffic Shock.");
			TrafficShockPlayersPerPulseMin = BindInt(config, "Traffic Shock", "PlayersPerPulseMin", 1, 1, 30, "Minimum number of random living players shocked in each pulse.");
			TrafficShockPlayersPerPulseMax = BindInt(config, "Traffic Shock", "PlayersPerPulseMax", 3, 1, 30, "Maximum number of random living players shocked in each pulse.");
			TrafficShockPulseIntervalSeconds = BindInt(config, "Traffic Shock", "PulseIntervalSeconds", 10, 1, 300, "Seconds between Traffic Shock pulses.");
			DangerousValuablesEnabled = BindBool(config, "Dangerous Valuables", "Enabled", value: true, "Includes Dangerous Valuables in each event's independent rolls.");
			DangerousValuablesChance = BindInt(config, "Dangerous Valuables", "ChancePercent", 5, 0, 100, "Independent chance for Dangerous Valuables.");
			ConfigEntry<int> val18 = BindInt(config, "Dangerous Valuables", "SpawnCountMin", 5, 1, 30, "Legacy setting migrated to ActivationCountMin.");
			ConfigEntry<int> val19 = BindInt(config, "Dangerous Valuables", "SpawnCountMax", 10, 1, 30, "Legacy setting migrated to ActivationCountMax.");
			if (num < 5)
			{
				MigrateSpawnCountDefaults(val18, val19, 1, 3, 5, 10, "Dangerous Valuables");
			}
			ConfigEntry<int> val20 = BindInt(config, "Dangerous Valuables", "ReplenishIntervalSeconds", 10, 1, 300, "Legacy setting migrated to ReactivationIntervalSeconds.");
			BindInt(config, "Dangerous Valuables", "MinimumPlayerDistance", 5, 0, 100, "Obsolete spawn setting.");
			BindBool(config, "Dangerous Valuables", "ReplenishDestroyed", value: true, "Obsolete spawn setting.");
			DangerousValuablesActivationCountMin = BindInt(config, "Dangerous Valuables", "ActivationCountMin", val18.Value, 1, 30, "Minimum number of already-placed dangerous valuables activated.");
			DangerousValuablesActivationCountMax = BindInt(config, "Dangerous Valuables", "ActivationCountMax", val19.Value, 1, 30, "Maximum number of already-placed dangerous valuables activated.");
			DangerousValuablesMaximumActiveInstances = BindInt(config, "Dangerous Valuables", "MaximumActiveInstances", 15, 1, 30, "Maximum number of tracked dangerous valuables.");
			DangerousValuablesReactivationIntervalSeconds = BindInt(config, "Dangerous Valuables", "ReactivationIntervalSeconds", val20.Value, 1, 300, "Seconds between reactivation checks for the selected existing valuables.");
			DangerousValuablesBlenderEnabled = BindBool(config, "Dangerous Valuables", "BlenderEnabled", value: true, "Allows already-placed Blender valuables to be activated.");
			DangerousValuablesBroomEnabled = BindBool(config, "Dangerous Valuables", "BroomEnabled", value: true, "Allows already-placed Broom valuables to be activated.");
			DangerousValuablesCarEnabled = BindBool(config, "Dangerous Valuables", "CarEnabled", value: true, "Allows already-placed Car valuables to be activated.");
			DangerousValuablesEggEnabled = BindBool(config, "Dangerous Valuables", "EggEnabled", value: true, "Allows already-placed Egg valuables to be activated.");
			DangerousValuablesFlamethrowerEnabled = BindBool(config, "Dangerous Valuables", "FlamethrowerEnabled", value: true, "Allows already-placed Flamethrower valuables to be activated.");
			DangerousValuablesIceSawEnabled = BindBool(config, "Dangerous Valuables", "IceSawEnabled", value: true, "Allows already-placed Ice Saw valuables to be activated.");
			DangerousValuablesPlaneEnabled = BindBool(config, "Dangerous Valuables", "PlaneEnabled", value: true, "Allows already-placed Plane valuables to be activated.");
			DangerousValuablesProtectValuables = BindBool(config, "Dangerous Valuables", "ProtectValuables", value: false, "Temporarily protects targeted valuables from damage caused by Dangerous Valuables.");
			RollEnabled = BindBool(config, "Roll", "Enabled", val5.Value, "Includes Roll in each event's independent rolls.");
			RollChance = BindInt(config, "Roll", "ChancePercent", val6.Value, 0, 100, "Independent chance for Roll in each event.");
			RollProtectValuables = BindBool(config, "Roll", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Roll.");
			int val21 = ((num < 9) ? BindInt(config, "Roll", "IndestructibleReleaseDelaySeconds", 2, 1, 5, "Legacy setting migrated to Safety.ValuableProtectionReleaseDelaySeconds.").Value : 2);
			VoidEnabled = BindBool(config, "Void", "Enabled", value: false, "Includes the Void Staff effect in each event's independent rolls.");
			VoidChance = BindInt(config, "Void", "ChancePercent", 5, 0, 100, "Independent chance for Void in each event.");
			int val22 = ((num < 9) ? BindInt(config, "Void", "IndestructibleReleaseDelaySeconds", 2, 1, 5, "Legacy setting migrated to Safety.ValuableProtectionReleaseDelaySeconds.").Value : 2);
			VoidSpawnCountMin = BindInt(config, "Void", "SpawnCountMin", 3, 2, 30, "Minimum number of Void effects created at random stage points.");
			VoidSpawnCountMax = BindInt(config, "Void", "SpawnCountMax", 5, 2, 30, "Maximum number of Void effects created at random stage points.");
			VoidSpawnIntervalSeconds = BindInt(config, "Void", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Void effect regeneration waves.");
			VoidProtectValuables = BindBool(config, "Void", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Void.");
			LevitationEnabled = BindBool(config, "Levitation", "Enabled", value: true, "Includes Levitation in each event's independent rolls.");
			LevitationChance = BindInt(config, "Levitation", "ChancePercent", 5, 0, 100, "Independent chance for Levitation in each event.");
			LevitationSpawnCountMin = BindInt(config, "Levitation", "SpawnCountMin", 2, 1, 30, "Minimum number of Levitation effects created in each wave.");
			LevitationSpawnCountMax = BindInt(config, "Levitation", "SpawnCountMax", 5, 1, 30, "Maximum number of Levitation effects created in each wave.");
			LevitationMaximumActiveInstances = BindInt(config, "Levitation", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked Levitation source instances.");
			LevitationSpawnIntervalSeconds = BindInt(config, "Levitation", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Levitation spawn waves.");
			LevitationMinimumPlayerDistance = BindInt(config, "Levitation", "MinimumPlayerDistance", 3, 0, 100, "Minimum distance from a living player when selecting a Levitation spawn point.");
			LevitationProtectValuables = BindBool(config, "Levitation", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Levitation.");
			ShockwaveEnabled = BindBool(config, "Shockwave", "Enabled", value: true, "Includes Shockwave in each event's independent rolls.");
			ShockwaveChance = BindInt(config, "Shockwave", "ChancePercent", 5, 0, 100, "Independent chance for Shockwave in each event.");
			ShockwaveSpawnCountMin = BindInt(config, "Shockwave", "SpawnCountMin", 5, 1, 30, "Minimum number of Shockwave grenades created in each wave.");
			ShockwaveSpawnCountMax = BindInt(config, "Shockwave", "SpawnCountMax", 10, 1, 30, "Maximum number of Shockwave grenades created in each wave.");
			ShockwaveMaximumActiveInstances = BindInt(config, "Shockwave", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked Shockwave grenades.");
			ShockwaveSpawnIntervalSeconds = BindInt(config, "Shockwave", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Shockwave spawn waves.");
			ShockwaveMinimumPlayerDistance = BindInt(config, "Shockwave", "MinimumPlayerDistance", 5, 0, 100, "Minimum distance from a living player when selecting a Shockwave spawn point.");
			ShockwaveLaunchForceMin = BindInt(config, "Shockwave", "LaunchForceMin", 6, 0, 100, "Minimum velocity-change force used to launch each Shockwave grenade in a random upward direction.");
			ShockwaveLaunchForceMax = BindInt(config, "Shockwave", "LaunchForceMax", 12, 0, 100, "Maximum velocity-change force used to launch each Shockwave grenade in a random upward direction.");
			ShockwaveProtectValuables = BindBool(config, "Shockwave", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Shockwave.");
			StunBlastEnabled = BindBool(config, "Stun Blast", "Enabled", value: true, "Includes Stun Blast in each event's independent rolls.");
			StunBlastChance = BindInt(config, "Stun Blast", "ChancePercent", 5, 0, 100, "Independent chance for Stun Blast in each event.");
			StunBlastSpawnCountMin = BindInt(config, "Stun Blast", "SpawnCountMin", 5, 1, 30, "Minimum number of Stun grenades created in each wave.");
			StunBlastSpawnCountMax = BindInt(config, "Stun Blast", "SpawnCountMax", 10, 1, 30, "Maximum number of Stun grenades created in each wave.");
			StunBlastMaximumActiveInstances = BindInt(config, "Stun Blast", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked Stun grenades.");
			StunBlastSpawnIntervalSeconds = BindInt(config, "Stun Blast", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Stun Blast spawn waves.");
			StunBlastMinimumPlayerDistance = BindInt(config, "Stun Blast", "MinimumPlayerDistance", 5, 0, 100, "Minimum distance from a living player when selecting a Stun Blast spawn point.");
			StunBlastLaunchForceMin = BindInt(config, "Stun Blast", "LaunchForceMin", 6, 0, 100, "Minimum velocity-change force used to launch each Stun grenade in a random upward direction.");
			StunBlastLaunchForceMax = BindInt(config, "Stun Blast", "LaunchForceMax", 12, 0, 100, "Maximum velocity-change force used to launch each Stun grenade in a random upward direction.");
			StunBlastProtectValuables = BindBool(config, "Stun Blast", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Stun Blast.");
			ExplosionRainEnabled = BindBool(config, "Explosion Rain", "Enabled", value: true, "Includes Explosion Rain in each event's independent rolls.");
			ExplosionRainChance = BindInt(config, "Explosion Rain", "ChancePercent", 5, 0, 100, "Independent chance for Explosion Rain in each event.");
			ExplosionRainSpawnCountMin = BindInt(config, "Explosion Rain", "SpawnCountMin", 5, 1, 30, "Minimum number of explosive grenades created in each wave.");
			ExplosionRainSpawnCountMax = BindInt(config, "Explosion Rain", "SpawnCountMax", 10, 1, 30, "Maximum number of explosive grenades created in each wave.");
			ExplosionRainMaximumActiveInstances = BindInt(config, "Explosion Rain", "MaximumActiveInstances", 30, 1, 30, "Maximum number of tracked explosive grenades.");
			ExplosionRainSpawnIntervalSeconds = BindInt(config, "Explosion Rain", "SpawnIntervalSeconds", 10, 1, 300, "Seconds between Explosion Rain spawn waves.");
			ExplosionRainMinimumPlayerDistance = BindInt(config, "Explosion Rain", "MinimumPlayerDistance", 10, 0, 100, "Minimum distance from a living player when selecting an Explosion Rain spawn point.");
			ExplosionRainLaunchForceMin = BindInt(config, "Explosion Rain", "LaunchForceMin", 6, 0, 100, "Minimum velocity-change force used to launch each explosive grenade in a random upward direction.");
			ExplosionRainLaunchForceMax = BindInt(config, "Explosion Rain", "LaunchForceMax", 12, 0, 100, "Maximum velocity-change force used to launch each explosive grenade in a random upward direction.");
			ExplosionRainProtectValuables = BindBool(config, "Explosion Rain", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Explosion Rain.");
			EnemyWaveEnabled = BindBool(config, "Enemy Wave", "Enabled", value: true, "Includes Enemy Wave in each event's independent rolls.");
			EnemyWaveChance = BindInt(config, "Enemy Wave", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Wave in each event.");
			EnemyWaveSpawnCountMin = BindInt(config, "Enemy Wave", "SpawnCountMin", 1, 1, 30, "Minimum number of additional enemies kept active.");
			EnemyWaveSpawnCountMax = BindInt(config, "Enemy Wave", "SpawnCountMax", 3, 1, 30, "Maximum number of additional enemies kept active.");
			EnemyWaveMinimumPlayerDistance = BindInt(config, "Enemy Wave", "MinimumPlayerDistance", 10, 0, 100, "Minimum requested distance from players when placing an additional enemy.");
			EnemyWaveReplenishIntervalSeconds = BindInt(config, "Enemy Wave", "ReplenishIntervalSeconds", 10, 1, 300, "Seconds between checks that replenish missing wave enemies.");
			EnemyWaveDespawnOnEnd = BindBool(config, "Enemy Wave", "DespawnOnEnd", value: true, "Despawns surviving enemies activated by the event when it ends.");
			MinefieldEnabled = BindBool(config, "Minefield", "Enabled", value: true, "Includes Minefield in each event's independent rolls.");
			MinefieldChance = BindInt(config, "Minefield", "ChancePercent", 5, 0, 100, "Independent chance for Minefield in each event.");
			MinefieldExplosiveEnabled = BindBool(config, "Minefield", "ExplosiveEnabled", value: true, "Allows explosive mines in Minefield.");
			MinefieldShockwaveEnabled = BindBool(config, "Minefield", "ShockwaveEnabled", value: true, "Allows shockwave mines in Minefield.");
			MinefieldStunEnabled = BindBool(config, "Minefield", "StunEnabled", value: true, "Allows stun mines in Minefield.");
			MinefieldSpawnCountMin = BindInt(config, "Minefield", "SpawnCountMin", 10, 1, 30, "Minimum number of armed mines kept active.");
			MinefieldSpawnCountMax = BindInt(config, "Minefield", "SpawnCountMax", 15, 1, 30, "Maximum number of armed mines kept active.");
			ConfigEntry<int> val23 = BindInt(config, "Minefield", "SpawnIntervalSeconds", 10, 1, 300, "Legacy setting migrated to ReplenishIntervalSeconds.");
			MinefieldMaximumActiveMines = BindInt(config, "Minefield", "MaximumActiveMines", 30, 1, 30, "Maximum number of event-created mines that may remain active.");
			MinefieldReplenishTriggeredMines = BindBool(config, "Minefield", "ReplenishTriggeredMines", value: true, "Replenishes triggered or destroyed event mines while Minefield remains active.");
			MinefieldReplenishIntervalSeconds = BindInt(config, "Minefield", "ReplenishIntervalSeconds", val23.Value, 1, 300, "Seconds between Minefield replenishment checks.");
			MinefieldMinimumPlayerDistance = BindInt(config, "Minefield", "MinimumPlayerDistance", 8, 0, 100, "Minimum distance from a living player when selecting a mine position.");
			MinefieldProtectValuables = BindBool(config, "Minefield", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Minefield.");
			FreezeEnabled = BindBool(config, "Freeze", "Enabled", value: true, "Includes Freeze in each event's independent rolls.");
			FreezeChance = BindInt(config, "Freeze", "ChancePercent", 5, 0, 100, "Independent chance for Freeze in each event.");
			StunEnabled = BindBool(config, "Stun", "Enabled", value: true, "Includes enemy Stun in each event's independent rolls.");
			StunChance = BindInt(config, "Stun", "ChancePercent", 5, 0, 100, "Independent chance for enemy Stun in each event.");
			EnemyWarpEnabled = BindBool(config, "Enemy Warp", "Enabled", value: true, "Includes Enemy Warp in each event's independent rolls.");
			EnemyWarpChance = BindInt(config, "Enemy Warp", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Warp in each event.");
			EnemyWarpEnemiesPerPulse = BindInt(config, "Enemy Warp", "EnemiesPerPulse", 3, 1, 30, "Maximum enemies teleported by each pulse.");
			EnemyWarpMinimumPlayerDistance = BindInt(config, "Enemy Warp", "MinimumPlayerDistance", 10, 0, 100, "Minimum requested distance from players for enemy teleport destinations.");
			EnemyWarpIntervalSeconds = BindInt(config, "Enemy Warp", "IntervalSeconds", 10, 1, 300, "Seconds between Enemy Warp pulses.");
			EnemyHuntEnabled = BindBool(config, "Enemy Hunt", "Enabled", value: true, "Includes Enemy Hunt in each event's independent rolls.");
			EnemyHuntChance = BindInt(config, "Enemy Hunt", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Hunt in each event.");
			EnemyHuntRetargetIntervalSeconds = BindInt(config, "Enemy Hunt", "RetargetIntervalSeconds", 5, 1, 300, "Seconds between synchronized lure sounds in player-occupied rooms after all extractions are complete.");
			EnemySpeedUpEnabled = BindBool(config, "Enemy Speed Up", "Enabled", value: true, "Includes Enemy Speed Up in each event's independent rolls.");
			EnemySpeedUpChance = BindInt(config, "Enemy Speed Up", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Speed Up in each event.");
			EnemySpeedUpPercent = BindInt(config, "Enemy Speed Up", "SpeedPercent", 150, 101, 500, "Enemy navigation speed and acceleration percentage while Enemy Speed Up is active.");
			EnemySpeedDownEnabled = BindBool(config, "Enemy Speed Down", "Enabled", value: true, "Includes Enemy Speed Down in each event's independent rolls.");
			EnemySpeedDownChance = BindInt(config, "Enemy Speed Down", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Speed Down in each event.");
			EnemySpeedDownPercent = BindInt(config, "Enemy Speed Down", "SpeedPercent", 50, 10, 99, "Enemy navigation speed and acceleration percentage while Enemy Speed Down is active.");
			EnemyRegenEnabled = BindBool(config, "Enemy Regen", "Enabled", value: true, "Includes Enemy Regen in each event's independent rolls.");
			EnemyRegenChance = BindInt(config, "Enemy Regen", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Regen in each event.");
			EnemyRegenHealAmount = BindInt(config, "Enemy Regen", "HealAmount", 10, 1, 100, "Health restored to each enemy per pulse.");
			EnemyRegenIntervalSeconds = BindInt(config, "Enemy Regen", "HealIntervalSeconds", 5, 1, 300, "Seconds between Enemy Regen pulses.");
			EnemyPurgeEnabled = BindBool(config, "Enemy Purge", "Enabled", value: true, "Includes Enemy Purge in each event's independent rolls.");
			EnemyPurgeChance = BindInt(config, "Enemy Purge", "ChancePercent", 5, 0, 100, "Independent chance for Enemy Purge in each event.");
			EnemyPurgeDamageAmount = BindInt(config, "Enemy Purge", "DamageAmount", 10, 1, 1000, "Damage dealt to each enemy per pulse.");
			EnemyPurgeCanKill = BindBool(config, "Enemy Purge", "CanKill", value: true, "Allows Enemy Purge to reduce an enemy to zero health.");
			EnemyPurgeIntervalSeconds = BindInt(config, "Enemy Purge", "DamageIntervalSeconds", 5, 1, 300, "Seconds between Enemy Purge pulses.");
			DamagePulseEnabled = BindBool(config, "Damage Pulse", "Enabled", value: true, "Includes Damage Pulse in each event's independent rolls.");
			DamagePulseChance = BindInt(config, "Damage Pulse", "ChancePercent", 5, 0, 100, "Independent chance for Damage Pulse in each event.");
			DamagePulseAmount = BindInt(config, "Damage Pulse", "DamageAmount", 5, 1, 100, "Damage dealt to each living player per pulse.");
			DamagePulseSavingGrace = BindBool(config, "Damage Pulse", "SavingGrace", value: true, "Prevents Damage Pulse alone from reducing a player below one health.");
			DamagePulseIntervalSeconds = BindInt(config, "Damage Pulse", "DamageIntervalSeconds", 5, 1, 300, "Seconds between Damage Pulse pulses.");
			SecondChanceEnabled = BindBool(config, "Second Chance", "Enabled", value: true, "Includes Second Chance in each event's independent rolls.");
			SecondChanceChance = BindInt(config, "Second Chance", "ChancePercent", 5, 0, 100, "Independent chance for Second Chance in each event.");
			SecondChanceMaxRevivesPerPlayer = BindInt(config, "Second Chance", "MaxRevivesPerPlayer", 1, 1, 10, "Maximum in-place revives granted to each player during one event.");
			SecondChanceCheckIntervalSeconds = BindInt(config, "Second Chance", "CheckIntervalSeconds", 2, 1, 300, "Seconds between ordinary death checks. A failed-stage retake is intercepted immediately.");
			KnockbackEnabled = BindBool(config, "Knockback", "Enabled", value: true, "Includes Knockback in each event's independent rolls.");
			KnockbackChance = BindInt(config, "Knockback", "ChancePercent", 5, 0, 100, "Independent chance for Knockback in each event.");
			KnockbackHorizontalForce = BindInt(config, "Knockback", "HorizontalForce", 8, 0, 100, "Horizontal force applied by Knockback.");
			KnockbackVerticalForce = BindInt(config, "Knockback", "VerticalForce", 3, 0, 100, "Upward force applied by Knockback.");
			KnockbackIntervalSeconds = BindInt(config, "Knockback", "IntervalSeconds", 5, 1, 300, "Seconds between Knockback pulses.");
			FlickerEnabled = BindBool(config, "Flicker", "Enabled", value: true, "Includes Flicker in each event's independent rolls.");
			FlickerChance = BindInt(config, "Flicker", "ChancePercent", 5, 0, 100, "Independent chance for Flicker in each event.");
			FlickerIntensityPercent = BindInt(config, "Flicker", "IntensityPercent", 200, 1, 500, "Flicker strength percentage. Higher values repeat more visible vanilla light transitions per pulse.");
			FlickerIntervalSeconds = BindInt(config, "Flicker", "IntervalSeconds", 2, 1, 300, "Seconds between vanilla light flicker pulses.");
			QuakeEnabled = BindBool(config, "Quake", "Enabled", value: true, "Includes Quake in each event's independent rolls.");
			QuakeChance = BindInt(config, "Quake", "ChancePercent", 5, 0, 100, "Independent chance for Quake in each event.");
			QuakeForce = BindInt(config, "Quake", "Force", 8, 0, 100, "Force applied by Quake.");
			QuakeIntervalSeconds = BindInt(config, "Quake", "IntervalSeconds", 5, 1, 300, "Seconds between Quake pulses.");
			QuakeProtectValuables = BindBool(config, "Quake", "ProtectValuables", value: true, "Temporarily protects targeted valuables from damage caused by Quake.");
			DoorChaosEnabled = BindBool(config, "Door Chaos", "Enabled", value: true, "Includes Door Chaos in each event's independent rolls.");
			DoorChaosChance = BindInt(config, "Door Chaos", "ChancePercent", 5, 0, 100, "Independent chance for Door Chaos in each event.");
			DoorChaosHingedItemsEnabled = BindBool(config, "Door Chaos", "HingedItemsEnabled", value: true, "Allows lids and other hinged movable items to be affected.");
			DoorChaosAffectedPercent = BindInt(config, "Door Chaos", "AffectedPercent", 30, 1, 100, "Percentage of eligible hinges changed by each pulse.");
			DoorChaosForce = BindInt(config, "Door Chaos", "Force", 12, 1, 30, "Physical force used to swing doors and hinged objects open or closed.");
			DoorChaosIntervalSeconds = BindInt(config, "Door Chaos", "IntervalSeconds", 2, 1, 300, "Seconds between Door Chaos pulses.");
			BindBool(config, "Trap Frenzy", "Enabled", value: false, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Trap Frenzy", "ChancePercent", 5, 0, 100, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Trap Frenzy", "IntervalSeconds", 10, 1, 300, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Trap Frenzy", "TrapsPerPulse", 3, 1, 30, "Obsolete setting removed in 4.2.0.");
			BindBool(config, "Trap Frenzy", "IncludeExplosiveTraps", value: false, "Obsolete setting removed in 4.2.0.");
			BindBool(config, "Object Shuffle", "Enabled", value: false, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Object Shuffle", "ChancePercent", 5, 0, 100, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Object Shuffle", "IntervalSeconds", 10, 1, 300, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Object Shuffle", "ObjectsPerPulse", 3, 1, 30, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Object Shuffle", "MinimumPlayerDistance", 5, 0, 100, "Obsolete setting removed in 4.2.0.");
			ValueSurgeEnabled = BindBool(config, "Value Surge", "Enabled", value: true, "Includes Value Surge in each event's independent rolls.");
			ValueSurgeChance = BindInt(config, "Value Surge", "ChancePercent", 5, 0, 100, "Independent chance for Value Surge in each event.");
			ValueSurgeMultiplierPercent = BindInt(config, "Value Surge", "MultiplierPercent", 150, 1, 1000, "Temporary multiplier applied to all active valuable prices, including extraction, cart, and truck areas.");
			ValueSurgeRestoreOnEnd = BindBool(config, "Value Surge", "RestoreOnEnd", value: true, "Restores surviving valuables to their saved prices when the event ends.");
			ValueCrashEnabled = BindBool(config, "Value Crash", "Enabled", value: true, "Includes Value Crash in each event's independent rolls.");
			ValueCrashChance = BindInt(config, "Value Crash", "ChancePercent", 5, 0, 100, "Independent chance for Value Crash in each event.");
			ValueCrashMultiplierPercent = BindInt(config, "Value Crash", "MultiplierPercent", 50, 1, 1000, "Temporary multiplier applied to all active valuable prices, including extraction, cart, and truck areas.");
			ValueCrashRestoreOnEnd = BindBool(config, "Value Crash", "RestoreOnEnd", value: true, "Restores surviving valuables to their saved prices when the event ends.");
			BindBool(config, "Music Override", "Enabled", value: false, "Obsolete setting removed in 4.2.0.");
			BindInt(config, "Music Override", "ChancePercent", 5, 0, 100, "Obsolete setting removed in 4.2.0.");
			config.Bind<string>("Music Override", "TrackSelection", "Random", "Obsolete setting removed in 4.2.0.");
			BindBool(config, "Music Override", "RestoreOnEnd", value: true, "Obsolete setting removed in 4.2.0.");
			ConfigEntry<bool> val24 = BindBool(config, "What floats", "Valuables", value: true, "Legacy target setting.");
			ConfigEntry<bool> val25 = BindBool(config, "What floats", "Items", value: true, "Legacy target setting.");
			ConfigEntry<bool> val26 = BindBool(config, "What floats", "Doors", value: false, "Legacy target setting.");
			ConfigEntry<bool> val27 = BindBool(config, "What floats", "Weapons", value: true, "Legacy target setting.");
			ConfigEntry<bool> val28 = BindBool(config, "What floats", "Players", value: true, "Legacy target setting.");
			ConfigEntry<bool> val29 = BindBool(config, "What floats", "Enemies", value: true, "Legacy target setting.");
			TargetPlayers = BindBool(config, "Targets", "Players", val28.Value, "Allows applicable events to target players.");
			TargetEnemies = BindBool(config, "Targets", "Enemies", val29.Value, "Allows applicable events to target enemies.");
			TargetValuables = BindBool(config, "Targets", "Valuables", val24.Value, "Allows applicable events to target valuables and enables automatic valuable protection.");
			TargetCosmeticBoxes = BindBool(config, "Targets", "CosmeticBoxes", value: false, "Allows applicable physics events to target Cosmetic Boxes independently from general items.");
			TargetItems = BindBool(config, "Targets", "Items", val25.Value, "Allows applicable events to target general items, carts, and movable props.");
			TargetWeapons = BindBool(config, "Targets", "Weapons", val27.Value, "Allows applicable events to target weapons.");
			TargetDoors = BindBool(config, "Targets", "Doors", val26.Value, "Allows applicable physics events to target doors, lids, and other hinged objects.");
			ConfigEntry<bool> val30 = BindBool(config, "UI", "Enabled", value: true, "Legacy HUD setting.");
			ConfigEntry<string> val31 = config.Bind<string>("UI", "Anchor", "BottomRight", new ConfigDescription("Legacy HUD setting.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[9] { "TopLeft", "TopCenter", "TopRight", "MiddleLeft", "MiddleCenter", "MiddleRight", "BottomLeft", "BottomCenter", "BottomRight" }), Array.Empty<object>()));
			ConfigEntry<string> val32 = config.Bind<string>("UI", "Alignment", "Right", new ConfigDescription("Legacy HUD setting.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Left", "Center", "Right" }), Array.Empty<object>()));
			ConfigEntry<int> val33 = BindInt(config, "UI", "OffsetX", 0, -3840, 3840, "Legacy HUD setting.");
			ConfigEntry<int> val34 = BindInt(config, "UI", "OffsetY", 0, -2160, 2160, "Legacy HUD setting.");
			ConfigEntry<int> val35 = BindInt(config, "UI", "ScalePercent", 70, 50, 200, "Legacy HUD setting.");
			ConfigEntry<bool> val36 = BindBool(config, "UI", "StageStartChatEnabled", value: true, "Legacy notification setting.");
			ConfigEntry<bool> val37 = BindBool(config, "UI", "CountdownEnabled", value: true, "Legacy countdown setting migrated to the separate start and end settings.");
			ConfigEntry<bool> val38 = BindBool(config, "UI", "StartCountdownEnabled", val37.Value, "Legacy notification setting.");
			ConfigEntry<bool> val39 = BindBool(config, "UI", "EndCountdownEnabled", val37.Value, "Legacy notification setting.");
			ChatAnnouncementsEnabled = BindBool(config, "Notifications", "ChatAnnouncementsEnabled", val36.Value, "Broadcasts the stage summary, effect names, countdowns, and End through vanilla chat.");
			StartCountdownEnabled = BindBool(config, "Notifications", "StartCountdownEnabled", val38.Value, "Enables the five-second countdown during the final five seconds of the interval. When disabled, only the effect name is announced three seconds before the interval ends.");
			EndCountdownEnabled = BindBool(config, "Notifications", "EndCountdownEnabled", val39.Value, "Enables the three-second countdown before an event ends. When disabled, End is announced when the effect ends.");
			EnemyReactionEnabled = BindBool(config, "Notifications", "EnemyReactionEnabled", value: false, "Allows enemies to investigate sounds generated by Stage Flux chat notifications. Ordinary voice chat and other sounds remain detectable.");
			HudEnabled = BindBool(config, "HUD", "Enabled", val30.Value, "Shows the synchronized event HUD on this client.");
			HudStyle = config.Bind<string>("HUD", "Style", "Graphical", new ConfigDescription("Graphical shows the five-slot icon HUD. Classic restores the previous text-only HUD.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Graphical", "Classic" }), Array.Empty<object>()));
			HudLayoutDirection = config.Bind<string>("HUD", "LayoutDirection", "Vertical", new ConfigDescription("Direction used by the Graphical HUD. Slots stop from top to bottom in Vertical mode and from left to right in Horizontal mode.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Vertical", "Horizontal" }), Array.Empty<object>()));
			HudAnchor = config.Bind<string>("HUD", "Anchor", val31.Value, new ConfigDescription("Anchor point used to position the HUD.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[9] { "TopLeft", "TopCenter", "TopRight", "MiddleLeft", "MiddleCenter", "MiddleRight", "BottomLeft", "BottomCenter", "BottomRight" }), Array.Empty<object>()));
			HudAlignment = config.Bind<string>("HUD", "Alignment", val32.Value, new ConfigDescription("Horizontal alignment of the HUD text.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Left", "Center", "Right" }), Array.Empty<object>()));
			HudOffsetX = BindInt(config, "HUD", "OffsetX", val33.Value, -3840, 3840, "Horizontal offset from the anchor in pixels.");
			HudOffsetY = BindInt(config, "HUD", "OffsetY", val34.Value, -2160, 2160, "Vertical offset from the anchor in pixels.");
			HudScalePercent = BindInt(config, "HUD", "ScalePercent", val35.Value, 50, 200, "HUD scale percentage.");
			HudBackgroundOpacityPercent = BindInt(config, "HUD", "BackgroundOpacityPercent", 50, 0, 100, "Graphical HUD background opacity percentage. HUD icons and text remain fully visible.");
			if (num < 4)
			{
				MigrateSpawnCountDefaults(ShockwaveSpawnCountMin, ShockwaveSpawnCountMax, 1, 3, 5, 10, "Shockwave");
				MigrateSpawnCountDefaults(StunBlastSpawnCountMin, StunBlastSpawnCountMax, 1, 3, 5, 10, "Stun Blast");
				MigrateSpawnCountDefaults(ExplosionRainSpawnCountMin, ExplosionRainSpawnCountMax, 1, 3, 5, 10, "Explosion Rain");
				MigrateSpawnCountDefaults(MinefieldSpawnCountMin, MinefieldSpawnCountMax, 3, 6, 10, 15, "Minefield");
			}
			if (num < 7 && DoorChaosIntervalSeconds.Value == 5)
			{
				DoorChaosIntervalSeconds.Value = 2;
				_logger.LogInfo((object)"Migrated the previous default Door Chaos interval from 5 seconds to 2 seconds.");
			}
			if (num < 9)
			{
				int num2 = Math.Max(ValuableProtectionReleaseDelaySeconds.Value, Math.Max(val9, Math.Max(val21, val22)));
				if (ValuableProtectionReleaseDelaySeconds.Value != num2)
				{
					ValuableProtectionReleaseDelaySeconds.Value = num2;
					_logger.LogInfo((object)("Migrated the longest event-specific valuable protection release delay to " + $"Safety.ValuableProtectionReleaseDelaySeconds ({num2} seconds)."));
				}
			}
			if (num < 9)
			{
				WriteConfigRevision(config, definition);
			}
			config.Remove(new ConfigDefinition(text, "Enabled"));
			config.Remove(new ConfigDefinition(text, "ChancePercent"));
			config.Remove(new ConfigDefinition("Magnet", "Enabled"));
			config.Remove(new ConfigDefinition("Magnet", "ChancePercent"));
			config.Remove(new ConfigDefinition("Torque", "Enabled"));
			config.Remove(new ConfigDefinition("Torque", "ChancePercent"));
			config.Remove(new ConfigDefinition("Roll Staff", "Enabled"));
			config.Remove(new ConfigDefinition("Roll Staff", "ChancePercent"));
			config.Remove(new ConfigDefinition("Boost", "Enabled"));
			config.Remove(new ConfigDefinition("Boost", "ChancePercent"));
			config.Remove(new ConfigDefinition("Battery", "Enabled"));
			config.Remove(new ConfigDefinition("Battery", "ChancePercent"));
			config.Remove(new ConfigDefinition("Battery", "ChargeAmount"));
			config.Remove(new ConfigDefinition("Battery", "ChargeIntervalSeconds"));
			config.Remove(new ConfigDefinition("BatteryCharge", "Enabled"));
			config.Remove(new ConfigDefinition("BatteryCharge", "ChancePercent"));
			config.Remove(new ConfigDefinition("BatteryCharge", "ChargeAmount"));
			config.Remove(new ConfigDefinition("BatteryCharge", "ChargeIntervalSeconds"));
			config.Remove(new ConfigDefinition("General", "StageEffectChancePercent"));
			config.Remove(new ConfigDefinition("Safety", "HazardIndestructibleReleaseDelaySeconds"));
			RemoveObsoleteConfigEntry(config, "Zero Gravity", "IndestructibleReleaseDelaySeconds");
			RemoveObsoleteConfigEntry(config, "Roll", "IndestructibleReleaseDelaySeconds");
			RemoveObsoleteConfigEntry(config, "Void", "IndestructibleReleaseDelaySeconds");
			config.Remove(new ConfigDefinition("Minefield", "SpawnIntervalSeconds"));
			RemoveObsoleteConfigEntry(config, "Minefield", "RemoveOnEventEnd");
			RemoveObsoleteConfigEntry(config, "Dangerous Valuables", "RemoveOnEventEnd");
			config.Remove(new ConfigDefinition("Dangerous Valuables", "SpawnCountMin"));
			config.Remove(new ConfigDefinition("Dangerous Valuables", "SpawnCountMax"));
			config.Remove(new ConfigDefinition("Dangerous Valuables", "ReplenishIntervalSeconds"));
			config.Remove(new ConfigDefinition("Dangerous Valuables", "MinimumPlayerDistance"));
			config.Remove(new ConfigDefinition("Dangerous Valuables", "ReplenishDestroyed"));
			config.Remove(new ConfigDefinition("Trap Frenzy", "Enabled"));
			config.Remove(new ConfigDefinition("Trap Frenzy", "ChancePercent"));
			config.Remove(new ConfigDefinition("Trap Frenzy", "IntervalSeconds"));
			config.Remove(new ConfigDefinition("Trap Frenzy", "TrapsPerPulse"));
			config.Remove(new ConfigDefinition("Trap Frenzy", "IncludeExplosiveTraps"));
			config.Remove(new ConfigDefinition("Object Shuffle", "Enabled"));
			config.Remove(new ConfigDefinition("Object Shuffle", "ChancePercent"));
			config.Remove(new ConfigDefinition("Object Shuffle", "IntervalSeconds"));
			config.Remove(new ConfigDefinition("Object Shuffle", "ObjectsPerPulse"));
			config.Remove(new ConfigDefinition("Object Shuffle", "MinimumPlayerDistance"));
			config.Remove(new ConfigDefinition("Music Override", "Enabled"));
			config.Remove(new ConfigDefinition("Music Override", "ChancePercent"));
			config.Remove(new ConfigDefinition("Music Override", "TrackSelection"));
			config.Remove(new ConfigDefinition("Music Override", "RestoreOnEnd"));
			RemoveObsoleteConfigEntry(config, "Door Chaos", "MapDoorsEnabled");
			config.Remove(new ConfigDefinition("What floats", "Valuables"));
			config.Remove(new ConfigDefinition("What floats", "Items"));
			config.Remove(new ConfigDefinition("What floats", "Doors"));
			config.Remove(new ConfigDefinition("What floats", "Weapons"));
			config.Remove(new ConfigDefinition("What floats", "Players"));
			config.Remove(new ConfigDefinition("What floats", "Enemies"));
			config.Remove(new ConfigDefinition("UI", "Enabled"));
			config.Remove(new ConfigDefinition("UI", "StageStartChatEnabled"));
			config.Remove(new ConfigDefinition("UI", "CountdownEnabled"));
			config.Remove(new ConfigDefinition("UI", "StartCountdownEnabled"));
			config.Remove(new ConfigDefinition("UI", "EndCountdownEnabled"));
			config.Remove(new ConfigDefinition("UI", "Anchor"));
			config.Remove(new ConfigDefinition("UI", "Alignment"));
			config.Remove(new ConfigDefinition("UI", "OffsetX"));
			config.Remove(new ConfigDefinition("UI", "OffsetY"));
			config.Remove(new ConfigDefinition("UI", "ScalePercent"));
			config.SaveOnConfigSet = saveOnConfigSet;
			config.Save();
			FeatherEnabled.SettingChanged += ProbabilitySettingChanged;
			FeatherChance.SettingChanged += ProbabilitySettingChanged;
			ZeroGravityEnabled.SettingChanged += ProbabilitySettingChanged;
			ZeroGravityChance.SettingChanged += ProbabilitySettingChanged;
			BatteryEnabled.SettingChanged += ProbabilitySettingChanged;
			BatteryChance.SettingChanged += ProbabilitySettingChanged;
			HealEnabled.SettingChanged += ProbabilitySettingChanged;
			HealChance.SettingChanged += ProbabilitySettingChanged;
			IndestructibleEnabled.SettingChanged += ProbabilitySettingChanged;
			IndestructibleChance.SettingChanged += ProbabilitySettingChanged;
			FragilityEnabled.SettingChanged += ProbabilitySettingChanged;
			FragilityChance.SettingChanged += ProbabilitySettingChanged;
			GumballHypnosisEnabled.SettingChanged += ProbabilitySettingChanged;
			GumballHypnosisChance.SettingChanged += ProbabilitySettingChanged;
			HealingAuraEnabled.SettingChanged += ProbabilitySettingChanged;
			HealingAuraChance.SettingChanged += ProbabilitySettingChanged;
			StarBarrageEnabled.SettingChanged += ProbabilitySettingChanged;
			StarBarrageChance.SettingChanged += ProbabilitySettingChanged;
			SpiderScareEnabled.SettingChanged += ProbabilitySettingChanged;
			SpiderScareChance.SettingChanged += ProbabilitySettingChanged;
			TrafficShockEnabled.SettingChanged += ProbabilitySettingChanged;
			TrafficShockChance.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesChance.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesIceSawEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesBlenderEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesFlamethrowerEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesEggEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesCarEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesPlaneEnabled.SettingChanged += ProbabilitySettingChanged;
			DangerousValuablesBroomEnabled.SettingChanged += ProbabilitySettingChanged;
			RollEnabled.SettingChanged += ProbabilitySettingChanged;
			RollChance.SettingChanged += ProbabilitySettingChanged;
			VoidEnabled.SettingChanged += ProbabilitySettingChanged;
			VoidChance.SettingChanged += ProbabilitySettingChanged;
			LevitationEnabled.SettingChanged += ProbabilitySettingChanged;
			LevitationChance.SettingChanged += ProbabilitySettingChanged;
			ShockwaveEnabled.SettingChanged += ProbabilitySettingChanged;
			ShockwaveChance.SettingChanged += ProbabilitySettingChanged;
			StunBlastEnabled.SettingChanged += ProbabilitySettingChanged;
			StunBlastChance.SettingChanged += ProbabilitySettingChanged;
			ExplosionRainEnabled.SettingChanged += ProbabilitySettingChanged;
			ExplosionRainChance.SettingChanged += ProbabilitySettingChanged;
			EnemyWaveEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemyWaveChance.SettingChanged += ProbabilitySettingChanged;
			MinefieldEnabled.SettingChanged += ProbabilitySettingChanged;
			MinefieldChance.SettingChanged += ProbabilitySettingChanged;
			MinefieldExplosiveEnabled.SettingChanged += ProbabilitySettingChanged;
			MinefieldShockwaveEnabled.SettingChanged += ProbabilitySettingChanged;
			MinefieldStunEnabled.SettingChanged += ProbabilitySettingChanged;
			FreezeEnabled.SettingChanged += ProbabilitySettingChanged;
			FreezeChance.SettingChanged += ProbabilitySettingChanged;
			StunEnabled.SettingChanged += ProbabilitySettingChanged;
			StunChance.SettingChanged += ProbabilitySettingChanged;
			EnemyWarpEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemyWarpChance.SettingChanged += ProbabilitySettingChanged;
			EnemyHuntEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemyHuntChance.SettingChanged += ProbabilitySettingChanged;
			EnemySpeedUpEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemySpeedUpChance.SettingChanged += ProbabilitySettingChanged;
			EnemySpeedDownEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemySpeedDownChance.SettingChanged += ProbabilitySettingChanged;
			EnemyRegenEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemyRegenChance.SettingChanged += ProbabilitySettingChanged;
			EnemyPurgeEnabled.SettingChanged += ProbabilitySettingChanged;
			EnemyPurgeChance.SettingChanged += ProbabilitySettingChanged;
			DamagePulseEnabled.SettingChanged += ProbabilitySettingChanged;
			DamagePulseChance.SettingChanged += ProbabilitySettingChanged;
			SecondChanceEnabled.SettingChanged += ProbabilitySettingChanged;
			SecondChanceChance.SettingChanged += ProbabilitySettingChanged;
			KnockbackEnabled.SettingChanged += ProbabilitySettingChanged;
			KnockbackChance.SettingChanged += ProbabilitySettingChanged;
			FlickerEnabled.SettingChanged += ProbabilitySettingChanged;
			FlickerChance.SettingChanged += ProbabilitySettingChanged;
			QuakeEnabled.SettingChanged += ProbabilitySettingChanged;
			QuakeChance.SettingChanged += ProbabilitySettingChanged;
			DoorChaosEnabled.SettingChanged += ProbabilitySettingChanged;
			DoorChaosChance.SettingChanged += ProbabilitySettingChanged;
			ValueSurgeEnabled.SettingChanged += ProbabilitySettingChanged;
			ValueSurgeChance.SettingChanged += ProbabilitySettingChanged;
			ValueCrashEnabled.SettingChanged += ProbabilitySettingChanged;
			ValueCrashChance.SettingChanged += ProbabilitySettingChanged;
		}

		internal int RollIntervalSeconds()
		{
			var (num, num2) = EffectiveIntervalRange;
			return Random.Range(num, num2 + 1);
		}

		internal int RollDurationSeconds()
		{
			var (num, num2) = EffectiveDurationRange;
			return Random.Range(num, num2 + 1);
		}

		internal int RollVoidSpawnCount()
		{
			var (num, num2) = OrderedRange(VoidSpawnCountMin.Value, VoidSpawnCountMax.Value, "VoidSpawnCount");
			return Random.Range(num, num2 + 1);
		}

		internal int RollLevitationSpawnCount()
		{
			return RollConfiguredCount(LevitationSpawnCountMin, LevitationSpawnCountMax, "LevitationSpawnCount");
		}

		internal int RollShockwaveSpawnCount()
		{
			return RollConfiguredCount(ShockwaveSpawnCountMin, ShockwaveSpawnCountMax, "ShockwaveSpawnCount");
		}

		internal int RollStunBlastSpawnCount()
		{
			return RollConfiguredCount(StunBlastSpawnCountMin, StunBlastSpawnCountMax, "StunBlastSpawnCount");
		}

		internal int RollExplosionRainSpawnCount()
		{
			return RollConfiguredCount(ExplosionRainSpawnCountMin, ExplosionRainSpawnCountMax, "ExplosionRainSpawnCount");
		}

		internal int RollEnemyWaveSpawnCount()
		{
			return RollConfiguredCount(EnemyWaveSpawnCountMin, EnemyWaveSpawnCountMax, "EnemyWaveSpawnCount");
		}

		internal int RollMinefieldSpawnCount()
		{
			return RollConfiguredCount(MinefieldSpawnCountMin, MinefieldSpawnCountMax, "MinefieldSpawnCount");
		}

		internal int RollHealingAuraSpawnCount()
		{
			return RollConfiguredCount(HealingAuraSpawnCountMin, HealingAuraSpawnCountMax, "HealingAuraSpawnCount");
		}

		internal int RollStarBarrageProjectileCount()
		{
			return RollConfiguredCount(StarBarrageProjectileCountMin, StarBarrageProjectileCountMax, "StarBarrageProjectileCount");
		}

		internal int RollSpiderScarePlayerCount()
		{
			return RollConfiguredCount(SpiderScarePlayersPerWaveMin, SpiderScarePlayersPerWaveMax, "SpiderScarePlayersPerWave");
		}

		internal int RollTrafficShockPlayerCount()
		{
			return RollConfiguredCount(TrafficShockPlayersPerPulseMin, TrafficShockPlayersPerPulseMax, "TrafficShockPlayersPerPulse");
		}

		internal int RollDangerousValuableActivationCount()
		{
			return RollConfiguredCount(DangerousValuablesActivationCountMin, DangerousValuablesActivationCountMax, "DangerousValuablesActivationCount");
		}

		internal StageEffect RollEffects(int? maximumOverride = null)
		{
			List<StageEffect> list = new List<StageEffect>();
			foreach (StageEffect individualEffect in StageEffectSet.IndividualEffects)
			{
				int chance = GetChance(individualEffect);
				if (chance >= 100 || (chance > 0 && Random.Range(1, 101) <= chance))
				{
					list.Add(individualEffect);
				}
			}
			Shuffle(list);
			List<StageEffect> list2 = new List<StageEffect>();
			foreach (StageEffect item in list)
			{
				if (HasLogicalConflict(item, list2))
				{
					_logger.LogDebug((object)$"Discarding {item} because it conflicts with an already selected effect.");
				}
				else if (!AllowDangerousCombinations.Value && HasDangerousConflict(item, list2))
				{
					_logger.LogDebug((object)$"Discarding {item} because dangerous combinations are disabled.");
				}
				else
				{
					list2.Add(item);
				}
			}
			int num = Mathf.Clamp(maximumOverride ?? MaxSimultaneousEffects.Value, 1, 5);
			if (list2.Count > num)
			{
				_logger.LogDebug((object)$"Effect roll produced {list2.Count} compatible effects; randomly limiting the event to {num}.");
			}
			StageEffect stageEffect = StageEffect.None;
			int num2 = Mathf.Min(list2.Count, num);
			for (int i = 0; i < num2; i++)
			{
				stageEffect |= list2[i];
			}
			return stageEffect;
		}

		internal bool RollStageEnabled()
		{
			if (StageActivationChancePercent.Value < 100)
			{
				if (StageActivationChancePercent.Value > 0)
				{
					return Random.Range(1, 101) <= StageActivationChancePercent.Value;
				}
				return false;
			}
			return true;
		}

		internal bool IsEffectSelectable(StageEffect effect)
		{
			return GetChance(effect) > 0;
		}

		internal EventMode CaptureMode()
		{
			if (string.Equals(Mode.Value, "AllMode", StringComparison.Ordinal))
			{
				return Random.Range(0, 4) switch
				{
					1 => EventMode.FixedForStage, 
					2 => EventMode.FixedPerExtraction, 
					3 => EventMode.PersistentForStage, 
					_ => EventMode.RandomEachEvent, 
				};
			}
			if (string.Equals(Mode.Value, "FixedForStage", StringComparison.Ordinal))
			{
				return EventMode.FixedForStage;
			}
			if (string.Equals(Mode.Value, "FixedPerExtraction", StringComparison.Ordinal))
			{
				return EventMode.FixedPerExtraction;
			}
			if (string.Equals(Mode.Value, "PersistentForStage", StringComparison.Ordinal))
			{
				return EventMode.PersistentForStage;
			}
			return EventMode.RandomEachEvent;
		}

		internal void LogProbabilityPolicy()
		{
			if (!HasSelectableEffect)
			{
				if (_lastProbabilityWarning != "zero")
				{
					_lastProbabilityWarning = "zero";
					_logger.LogWarning((object)"All enabled effect probabilities are 0%; no stage event can be selected.");
				}
			}
			else
			{
				_lastProbabilityWarning = string.Empty;
			}
		}

		internal TargetFilter CaptureTargetFilter()
		{
			return new TargetFilter(TargetValuables.Value, TargetCosmeticBoxes.Value, TargetItems.Value, TargetDoors.Value, TargetWeapons.Value, TargetPlayers.Value, TargetEnemies.Value);
		}

		private void ProbabilitySettingChanged(object sender, EventArgs eventArgs)
		{
			LogProbabilityPolicy();
		}

		private int GetChance(StageEffect effect)
		{
			if (effect <= StageEffect.EnemyPurge)
			{
				if (effect <= StageEffect.StunBlast)
				{
					if (effect <= StageEffect.Roll)
					{
						if (effect <= StageEffect.Heal)
						{
							StageEffect num = effect - 1;
							if ((ulong)num <= 3uL)
							{
								switch (num)
								{
								case StageEffect.None:
									return FeatherEnabled.Value ? FeatherChance.Value : 0;
								case StageEffect.Feather:
									return ZeroGravityEnabled.Value ? ZeroGravityChance.Value : 0;
								case StageEffect.Feather | StageEffect.ZeroGravity:
									return BatteryEnabled.Value ? BatteryChance.Value : 0;
								case StageEffect.ZeroGravity:
									goto IL_076a;
								}
							}
							if (effect == StageEffect.Heal)
							{
								return HealEnabled.Value ? HealChance.Value : 0;
							}
						}
						else
						{
							switch (effect)
							{
							case StageEffect.Indestructible:
								return IndestructibleEnabled.Value ? IndestructibleChance.Value : 0;
							case StageEffect.Roll:
								return RollEnabled.Value ? RollChance.Value : 0;
							}
						}
					}
					else
					{
						switch (effect)
						{
						case StageEffect.Void:
							return VoidEnabled.Value ? VoidChance.Value : 0;
						case StageEffect.Levitation:
							return LevitationEnabled.Value ? LevitationChance.Value : 0;
						case StageEffect.Shockwave:
							return ShockwaveEnabled.Value ? ShockwaveChance.Value : 0;
						case StageEffect.StunBlast:
							return StunBlastEnabled.Value ? StunBlastChance.Value : 0;
						}
					}
				}
				else
				{
					switch (effect)
					{
					case StageEffect.ExplosionRain:
						return ExplosionRainEnabled.Value ? ExplosionRainChance.Value : 0;
					case StageEffect.EnemyWave:
						return EnemyWaveEnabled.Value ? EnemyWaveChance.Value : 0;
					case StageEffect.Minefield:
						return (MinefieldEnabled.Value && MinefieldHasEnabledType) ? MinefieldChance.Value : 0;
					case StageEffect.Freeze:
						return FreezeEnabled.Value ? FreezeChance.Value : 0;
					case StageEffect.Stun:
						return StunEnabled.Value ? StunChance.Value : 0;
					case StageEffect.EnemyWarp:
						return EnemyWarpEnabled.Value ? EnemyWarpChance.Value : 0;
					case StageEffect.EnemyHunt:
						return EnemyHuntEnabled.Value ? EnemyHuntChance.Value : 0;
					case StageEffect.EnemyRegen:
						return EnemyRegenEnabled.Value ? EnemyRegenChance.Value : 0;
					case StageEffect.EnemyPurge:
						return EnemyPurgeEnabled.Value ? EnemyPurgeChance.Value : 0;
					}
				}
			}
			else
			{
				switch (effect)
				{
				case StageEffect.Fragility:
					return (FragilityEnabled.Value && TargetValuables.Value) ? FragilityChance.Value : 0;
				case StageEffect.GumballHypnosis:
					return (GumballHypnosisEnabled.Value && HasGumballTargets) ? GumballHypnosisChance.Value : 0;
				case StageEffect.HealingAura:
					return (HealingAuraEnabled.Value && TargetPlayers.Value) ? HealingAuraChance.Value : 0;
				case StageEffect.StarBarrage:
					return StarBarrageEnabled.Value ? StarBarrageChance.Value : 0;
				case StageEffect.SpiderScare:
					return (SpiderScareEnabled.Value && TargetPlayers.Value) ? SpiderScareChance.Value : 0;
				case StageEffect.TrafficShock:
					return (TrafficShockEnabled.Value && TargetPlayers.Value) ? TrafficShockChance.Value : 0;
				case StageEffect.DangerousValuables:
					return (DangerousValuablesEnabled.Value && DangerousValuablesHasEnabledType) ? DangerousValuablesChance.Value : 0;
				case StageEffect.EnemySpeedUp:
					return EnemySpeedUpEnabled.Value ? EnemySpeedUpChance.Value : 0;
				case StageEffect.EnemySpeedDown:
					return EnemySpeedDownEnabled.Value ? EnemySpeedDownChance.Value : 0;
				case StageEffect.DamagePulse:
					return DamagePulseEnabled.Value ? DamagePulseChance.Value : 0;
				case StageEffect.SecondChance:
					return SecondChanceEnabled.Value ? SecondChanceChance.Value : 0;
				case StageEffect.Knockback:
					return KnockbackEnabled.Value ? KnockbackChance.Value : 0;
				case StageEffect.Flicker:
					return FlickerEnabled.Value ? FlickerChance.Value : 0;
				case StageEffect.Quake:
					return QuakeEnabled.Value ? QuakeChance.Value : 0;
				case StageEffect.DoorChaos:
					return DoorChaosEnabled.Value ? DoorChaosChance.Value : 0;
				case StageEffect.ValueSurge:
					return ValueSurgeEnabled.Value ? ValueSurgeChance.Value : 0;
				case StageEffect.ValueCrash:
					return ValueCrashEnabled.Value ? ValueCrashChance.Value : 0;
				}
			}
			goto IL_076a;
			IL_076a:
			return 0;
		}

		private int RollConfiguredCount(ConfigEntry<int> minimum, ConfigEntry<int> maximum, string name)
		{
			var (num, num2) = OrderedRange(minimum.Value, maximum.Value, name);
			return Random.Range(num, num2 + 1);
		}

		private static void Shuffle(List<StageEffect> effects)
		{
			for (int i = 0; i < effects.Count; i++)
			{
				int num = Random.Range(i, effects.Count);
				int index = i;
				int index2 = num;
				StageEffect value = effects[num];
				StageEffect value2 = effects[i];
				effects[index] = value;
				effects[index2] = value2;
			}
		}

		private static bool HasLogicalConflict(StageEffect candidate, List<StageEffect> selected)
		{
			foreach (StageEffect item in selected)
			{
				if (IsPair(candidate, item, StageEffect.Freeze, StageEffect.Stun) || IsPair(candidate, item, StageEffect.EnemyRegen, StageEffect.EnemyPurge) || IsPair(candidate, item, StageEffect.EnemySpeedUp, StageEffect.EnemySpeedDown) || IsPair(candidate, item, StageEffect.Indestructible, StageEffect.Fragility) || IsPair(candidate, item, StageEffect.ValueSurge, StageEffect.ValueCrash))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsPair(StageEffect first, StageEffect second, StageEffect left, StageEffect right)
		{
			if (first != left || second != right)
			{
				if (first == right)
				{
					return second == left;
				}
				return false;
			}
			return true;
		}

		private bool HasDangerousConflict(StageEffect candidate, List<StageEffect> selected)
		{
			EffectRisk risk = GetRisk(candidate);
			int num = (((risk & EffectRisk.ValuableRisk) != 0) ? 1 : 0);
			foreach (StageEffect item in selected)
			{
				EffectRisk risk2 = GetRisk(item);
				if ((risk2 & EffectRisk.ValuableRisk) != EffectRisk.None)
				{
					num++;
				}
				if (RiskPairIsDangerous(risk, risk2))
				{
					return true;
				}
			}
			return num >= 3;
		}

		private EffectRisk GetRisk(StageEffect effect)
		{
			EffectRisk effectRisk = effect switch
			{
				StageEffect.ZeroGravity => EffectRisk.ForcedMovement | EffectRisk.ValuableRisk, 
				StageEffect.Roll => EffectRisk.ForcedMovement | EffectRisk.ValuableRisk, 
				StageEffect.Void => EffectRisk.ForcedMovement | EffectRisk.LethalHazard | EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				StageEffect.Levitation => EffectRisk.ForcedMovement | EffectRisk.ValuableRisk, 
				StageEffect.Shockwave => EffectRisk.ForcedMovement | EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				StageEffect.StunBlast => EffectRisk.AreaHazard, 
				StageEffect.ExplosionRain => EffectRisk.LethalHazard | EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				StageEffect.EnemyWave => EffectRisk.EnemyPressure, 
				StageEffect.EnemyWarp => EffectRisk.EnemyPressure, 
				StageEffect.EnemyHunt => EffectRisk.EnemyPressure, 
				StageEffect.EnemySpeedUp => EffectRisk.EnemyPressure, 
				StageEffect.EnemyRegen => EffectRisk.EnemyPressure, 
				StageEffect.DamagePulse => EffectRisk.LethalHazard, 
				StageEffect.Knockback => EffectRisk.ForcedMovement, 
				StageEffect.Quake => EffectRisk.ForcedMovement | EffectRisk.ValuableRisk, 
				StageEffect.DoorChaos => EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				StageEffect.Fragility => EffectRisk.ValuableRisk | EffectRisk.ValueLossAmplifier, 
				StageEffect.ValueCrash => EffectRisk.ValueLossAmplifier, 
				StageEffect.GumballHypnosis => EffectRisk.ControlImpairment | EffectRisk.VisualImpairment, 
				StageEffect.StarBarrage => EffectRisk.LethalHazard | EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				StageEffect.SpiderScare => EffectRisk.ControlImpairment | EffectRisk.VisualImpairment, 
				StageEffect.Flicker => EffectRisk.VisualImpairment, 
				StageEffect.TrafficShock => EffectRisk.ForcedMovement | EffectRisk.LethalHazard, 
				StageEffect.DangerousValuables => EffectRisk.ForcedMovement | EffectRisk.LethalHazard | EffectRisk.AreaHazard | EffectRisk.ValuableRisk, 
				_ => EffectRisk.None, 
			};
			if (effect == StageEffect.Minefield)
			{
				effectRisk = EffectRisk.AreaHazard;
				if (MinefieldExplosiveEnabled.Value)
				{
					effectRisk |= EffectRisk.LethalHazard | EffectRisk.ValuableRisk;
				}
				if (MinefieldShockwaveEnabled.Value)
				{
					effectRisk |= EffectRisk.ForcedMovement | EffectRisk.ValuableRisk;
				}
			}
			return effectRisk;
		}

		private static bool RiskPairIsDangerous(EffectRisk first, EffectRisk second)
		{
			bool flag = (first & EffectRisk.ForcedMovement) != 0;
			bool flag2 = (second & EffectRisk.ForcedMovement) != 0;
			bool flag3 = (first & EffectRisk.LethalHazard) != 0;
			bool flag4 = (second & EffectRisk.LethalHazard) != 0;
			bool flag5 = (first & EffectRisk.AreaHazard) != 0;
			bool flag6 = (second & EffectRisk.AreaHazard) != 0;
			bool flag7 = (first & EffectRisk.EnemyPressure) != 0;
			bool flag8 = (second & EffectRisk.EnemyPressure) != 0;
			bool flag9 = (first & EffectRisk.ControlImpairment) != 0;
			bool flag10 = (second & EffectRisk.ControlImpairment) != 0;
			bool flag11 = (first & EffectRisk.VisualImpairment) != 0;
			bool flag12 = (second & EffectRisk.VisualImpairment) != 0;
			bool flag13 = (first & EffectRisk.ValueLossAmplifier) != 0;
			bool flag14 = (second & EffectRisk.ValueLossAmplifier) != 0;
			bool flag15 = (first & EffectRisk.ValuableRisk) != 0;
			bool flag16 = (second & EffectRisk.ValuableRisk) != 0;
			if (!(flag && flag2) && !(flag3 && flag4) && (!flag || !(flag4 || flag6)) && (!flag2 || !(flag3 || flag5)) && !(flag7 && flag8) && !(flag3 && flag8) && !(flag4 && flag7) && !(flag9 && flag10) && (!flag9 || !(flag2 || flag4 || flag6 || flag8)) && (!flag10 || !(flag || flag3 || flag5 || flag7)) && !(flag11 && flag12) && !(flag13 && flag16))
			{
				return flag14 && flag15;
			}
			return true;
		}

		private (int Min, int Max) OrderedRange(int first, int second, string name)
		{
			if (first <= second)
			{
				return (Min: first, Max: second);
			}
			string text = $"{name}:{first}:{second}";
			if (_lastRangeWarning != text)
			{
				_lastRangeWarning = text;
				_logger.LogWarning((object)$"{name} minimum ({first}) exceeds maximum ({second}); using {second}..{first} without rewriting config.");
			}
			return (Min: second, Max: first);
		}

		private static ConfigEntry<bool> BindBool(ConfigFile file, string section, string key, bool value, string description)
		{
			return file.Bind<bool>(section, key, value, description);
		}

		private static ConfigEntry<int> BindInt(ConfigFile file, string section, string key, int value, int min, int max, string description)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return file.Bind<int>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), Array.Empty<object>()));
		}

		private void MigrateSpawnCountDefaults(ConfigEntry<int> minimum, ConfigEntry<int> maximum, int previousMinimum, int previousMaximum, int newMinimum, int newMaximum, string eventName)
		{
			if (minimum.Value == previousMinimum && maximum.Value == previousMaximum)
			{
				minimum.Value = newMinimum;
				maximum.Value = newMaximum;
				_logger.LogInfo((object)("Migrated the previous default " + eventName + " spawn count from " + $"{previousMinimum}-{previousMaximum} to {newMinimum}-{newMaximum}."));
			}
		}

		private int ReadConfigRevision(ConfigFile config, ConfigDefinition definition)
		{
			try
			{
				IDictionary<ConfigDefinition, string> orphanedEntries = GetOrphanedEntries(config);
				if (orphanedEntries != null && orphanedEntries.TryGetValue(definition, out var value) && int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
				{
					return result;
				}
			}
			catch (Exception ex)
			{
				_logger.LogWarning((object)("Could not read the internal configuration revision: " + ex.Message));
			}
			return 0;
		}

		private void WriteConfigRevision(ConfigFile config, ConfigDefinition definition)
		{
			try
			{
				IDictionary<ConfigDefinition, string> orphanedEntries = GetOrphanedEntries(config);
				if (orphanedEntries != null)
				{
					orphanedEntries[definition] = 9.ToString(CultureInfo.InvariantCulture);
					return;
				}
			}
			catch (Exception ex)
			{
				_logger.LogWarning((object)("Could not write the internal configuration rev