Decompiled source of PeakRandomizedChaos v1.1.7

PeakRandomizedChaos.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;
using Zorro.Core.Serizalization;
using pworld.Scripts.Extensions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakRandomizedChaos")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.8.0")]
[assembly: AssemblyInformationalVersion("1.3.8")]
[assembly: AssemblyProduct("PeakRandomizedChaos")]
[assembly: AssemblyTitle("PeakRandomizedChaos")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.8.0")]
[module: UnverifiableCode]
[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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace PeakRandomizedChaos
{
	public static class AchievementManagerPatch
	{
	}
	public static class ChaosEnvironmentController
	{
		private sealed class WeatherZoneCache
		{
			public float BuiltAt = -9999f;

			public readonly List<WindChillZone> All = new List<WindChillZone>();

			public readonly List<WindChillZone> Wind = new List<WindChillZone>();
		}

		private const float WeatherZoneCacheSeconds = 10f;

		private static readonly WeatherZoneCache CachedWeatherZones = new WeatherZoneCache();

		public static void ResetLocalState()
		{
			CachedWeatherZones.All.Clear();
			CachedWeatherZones.Wind.Clear();
			CachedWeatherZones.BuiltAt = -9999f;
		}

		public static bool TryTriggerVanillaWindBurst()
		{
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			RefreshWeatherZoneCache(force: false);
			for (int i = 0; i < CachedWeatherZones.All.Count; i++)
			{
				WindChillZone val = CachedWeatherZones.All[i];
				if ((Object)(object)val != (Object)null && val.windActive)
				{
					return false;
				}
			}
			List<WindChillZone> list = ((CachedWeatherZones.Wind.Count > 0) ? CachedWeatherZones.Wind : CachedWeatherZones.All);
			if (list.Count == 0)
			{
				Plugin.Log.LogWarning((object)"WindBurst skipped: no usable WindChillZone found in scene.");
				return false;
			}
			WindChillZone val2 = list[Random.Range(0, list.Count)];
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			PhotonView component = ((Component)val2).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogWarning((object)"WindBurst skipped: selected WindChillZone has no PhotonView.");
				return false;
			}
			Vector3 val3 = RandomWindDirection();
			float num = Random.Range(15f, 35f);
			try
			{
				component.RPC("RPCA_ToggleWind", (RpcTarget)0, new object[3] { true, val3, num });
				Plugin.Log.LogInfo((object)$"WindBurst triggered via vanilla RPCA_ToggleWind on {((Object)val2).name}, dir={val3}, duration={num:0.0}s.");
				return true;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"WindBurst RPCA_ToggleWind failed on {((Object)val2).name}: {arg}");
				return false;
			}
		}

		private static void RefreshWeatherZoneCache(bool force)
		{
			if (!force && Time.time - CachedWeatherZones.BuiltAt < 10f)
			{
				CachedWeatherZones.All.RemoveAll((WindChillZone zone) => !CanUseWeatherZone(zone));
				CachedWeatherZones.Wind.RemoveAll((WindChillZone zone) => !CanUseWeatherZone(zone));
				if (CachedWeatherZones.All.Count > 0)
				{
					return;
				}
			}
			CachedWeatherZones.All.Clear();
			CachedWeatherZones.Wind.Clear();
			CachedWeatherZones.BuiltAt = Time.time;
			WindChillZone[] array = Object.FindObjectsByType<WindChillZone>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (WindChillZone val in array)
			{
				if (CanUseWeatherZone(val))
				{
					AddUnique(CachedWeatherZones.All, val);
					string text = GetTransformPath(((Component)val).transform).ToLowerInvariant();
					if (text.Contains("wind") || text.Contains("root") || IsRootsWindZone(val))
					{
						AddUnique(CachedWeatherZones.Wind, val);
					}
				}
			}
			if (CachedWeatherZones.Wind.Count != 0)
			{
				return;
			}
			foreach (WindChillZone item in CachedWeatherZones.All)
			{
				CachedWeatherZones.Wind.Add(item);
			}
		}

		private static bool IsRootsWindZone(WindChillZone zone)
		{
			Type type = AccessTools.TypeByName("RootsWind");
			if (type == null)
			{
				return false;
			}
			object obj = AccessTools.Field(type, "instance")?.GetValue(null) ?? AccessTools.Property(type, "instance")?.GetValue(null, null);
			if (obj == null)
			{
				return false;
			}
			object memberValue = GetMemberValue(obj, "windZone");
			return memberValue == zone;
		}

		private static bool CanUseWeatherZone(WindChillZone zone)
		{
			return (Object)(object)zone != (Object)null && (Object)(object)((Component)zone).gameObject != (Object)null && ((Behaviour)zone).isActiveAndEnabled && ((Component)zone).gameObject.activeInHierarchy && (Object)(object)((Component)zone).GetComponent<PhotonView>() != (Object)null;
		}

		private static void AddUnique(List<WindChillZone> list, WindChillZone zone)
		{
			if ((Object)(object)zone == (Object)null)
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if ((Object)(object)list[i] == (Object)(object)zone)
				{
					return;
				}
			}
			list.Add(zone);
		}

		private static Vector3 RandomWindDirection()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Lerp(Vector3.right * ((Random.value > 0.5f) ? 1f : (-1f)), Vector3.forward, 0.2f);
			return ((Vector3)(ref val)).normalized;
		}

		private static string GetTransformPath(Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(128);
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Insert(0, "/");
				}
				stringBuilder.Insert(0, ((Object)val).name);
				val = val.parent;
			}
			return stringBuilder.ToString();
		}

		private static object? GetMemberValue(object? obj, string name)
		{
			if (obj == null || string.IsNullOrWhiteSpace(name))
			{
				return null;
			}
			Type type = obj.GetType();
			FieldInfo fieldInfo = AccessTools.Field(type, name);
			if (fieldInfo != null)
			{
				return fieldInfo.GetValue(obj);
			}
			PropertyInfo propertyInfo = AccessTools.Property(type, name);
			if (propertyInfo != null)
			{
				return propertyInfo.GetValue(obj, null);
			}
			return null;
		}
	}
	public sealed class ChaosEnvironmentSync : MonoBehaviour
	{
		public static ChaosEnvironmentSync? Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public static void EnsureExists(GameObject host)
		{
		}

		public static void BroadcastMagicBeanVineCleanupForAllClients(Vector3 center, float radius, float delaySeconds)
		{
		}

		public static void ResetLocalStateOnly()
		{
		}
	}
	public static class CustomLoot
	{
		public static readonly HashSet<string> ExcludedItemNames = new HashSet<string> { "Cheat Compass", "ScoutCookies_Vanilla", "ClimbingChalk", "Skull", "Warp Compass", "AncientIdol", "Passport" };

		public static readonly HashSet<string> ExcludedItemPrefixes = new HashSet<string> { "C_", "Guidebook" };

		public static readonly HashSet<string> ExcludedItemSuffixes = new HashSet<string> { "_Prop", "_Prop Variant", "_TEMP", "Spawn", "Placed" };

		public static readonly HashSet<string> UnsafeForRandomLootNames = new HashSet<string>
		{
			"BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "Anti-Rope Spool",
			"RopeShooterAnti", "RopeShooter", "VineShooter", "VineShooter Variant", "BananaPeel", "Banana Peel"
		};

		public static readonly HashSet<string> UnsafeForRandomEventItemNames = new HashSet<string>
		{
			"Backpack", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed", "MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn",
			"Anti-Rope Spool", "RopeShooterAnti", "RopeShooter", "VineShooter", "VineShooter Variant", "BananaPeel", "Banana Peel"
		};

		public static readonly HashSet<string> UnsafeForBushLootNames = new HashSet<string>
		{
			"Dynamite", "CactusBall", "Mandrake", "Scorpion", "MagicBean", "PandorasBox", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed",
			"MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "Backpack", "Anti-Rope Spool", "RopeShooterAnti", "BalloonBunch", "ChainShooter",
			"Flag_Plantable_Checkpoint"
		};

		public static readonly HashSet<string> TrollItems = new HashSet<string> { "CactusBall", "Mandrake", "Dynamite", "Scorpion" };

		public static readonly Dictionary<string, int> MaxSpawnCountByItemName = new Dictionary<string, int> { { "RescueHook_Infinite", 1 } };

		private static readonly HashSet<string> GoodItemsBasic = new HashSet<string> { "Lantern_Faerie", "ChainShooter", "Cure-All", "FirstAidKit", "Glizzy", "Winterberry Yellow", "PandorasBox", "EggTurkey", "Napberry", "Flag_Plantable_Checkpoint" };

		private static readonly HashSet<string> GoodItemsMultiplayer = new HashSet<string> { "Bugle_Magic", "ScoutEffigy", "HealingDart Variant" };

		private static readonly HashSet<string> GoodItemsFloaty = new HashSet<string> { "BalloonBunch" };

		private static readonly Dictionary<string, int> SpawnedCountByItemName = new Dictionary<string, int>();

		private static readonly object CacheLock = new object();

		private static Dictionary<ushort, Item>? _baseFilteredAllCache;

		private static Dictionary<ushort, Item>? _baseFilteredLootCache;

		private static Dictionary<ushort, Item>? _baseFilteredBushCache;

		private static Dictionary<ushort, Item>? _baseFilteredEventCache;

		private static Dictionary<ushort, Item>? _baseFilteredHangingCache;

		private static Dictionary<ushort, Item>? _availableAllItemsCache;

		private static Dictionary<ushort, Item>? _availableLootItemsCache;

		private static Dictionary<ushort, Item>? _availableBushItemsCache;

		private static Dictionary<ushort, Item>? _availableEventItemsCache;

		private static bool _availableCachesDirty = true;

		private static readonly string[] GoodItemsSinglePlayer = GoodItemsBasic.ToArray();

		private static readonly string[] GoodItemsMultiplayerCombined = GoodItemsBasic.Concat(GoodItemsMultiplayer).Distinct().ToArray();

		private static readonly string[] GoodBackpackSinglePlayer = GoodItemsBasic.Concat(GoodItemsFloaty).Distinct().ToArray();

		private static readonly string[] GoodBackpackMultiplayer = GoodItemsBasic.Concat(GoodItemsMultiplayer).Concat(GoodItemsFloaty).Distinct()
			.ToArray();

		public static readonly HashSet<string> UnsafeForHangingLootNames = new HashSet<string>
		{
			"Dynamite", "CactusBall", "Mandrake", "Scorpion", "MagicBean", "PandorasBox", "BingBong", "BugfixOnYou", "BeeSwarm", "TumbleWeed",
			"MushroomZombie", "RopeAnchorForRopeShooterAnti", "BounceShroomSpawn", "HealingPuffShroomSpawn", "ShelfShroomSpawn", "BalloonBunch", "Anti-Rope Spool", "RopeShooterAnti", "ChainShooter", "Flag_Plantable_Checkpoint",
			"Backpack"
		};

		public static HashSet<string> GoodItems
		{
			get
			{
				IEnumerable<string> enumerable = new HashSet<string>().Concat(GoodItemsBasic);
				if (Character.AllCharacters.Count((Character c) => (Object)(object)c != (Object)null && !c.isBot) > 1)
				{
					enumerable = enumerable.Concat(GoodItemsMultiplayer);
				}
				return enumerable.ToHashSet();
			}
		}

		public static HashSet<string> GoodItemsBackpack
		{
			get
			{
				IEnumerable<string> first = new HashSet<string>().Concat(GoodItemsBasic);
				if (Character.AllCharacters.Count((Character c) => (Object)(object)c != (Object)null && !c.isBot) > 1)
				{
					first = first.Concat(GoodItemsMultiplayer);
				}
				first = first.Concat(GoodItemsFloaty);
				return first.ToHashSet();
			}
		}

		public static bool TryGetRandomGoodItem(bool includeBackpackOnlyItems, out string itemName)
		{
			int num = 0;
			List<Character> allCharacters = Character.AllCharacters;
			for (int i = 0; i < allCharacters.Count; i++)
			{
				if (num >= 2)
				{
					break;
				}
				Character val = allCharacters[i];
				if ((Object)(object)val != (Object)null && !val.isBot)
				{
					num++;
				}
			}
			bool flag = num > 1;
			string[] array = ((!includeBackpackOnlyItems) ? (flag ? GoodItemsMultiplayerCombined : GoodItemsSinglePlayer) : (flag ? GoodBackpackMultiplayer : GoodBackpackSinglePlayer));
			if (array.Length == 0)
			{
				itemName = string.Empty;
				return false;
			}
			itemName = array[Random.Range(0, array.Length)];
			return true;
		}

		public static void ResetRuntimeState()
		{
			lock (CacheLock)
			{
				SpawnedCountByItemName.Clear();
				_baseFilteredAllCache = null;
				_baseFilteredLootCache = null;
				_baseFilteredBushCache = null;
				_baseFilteredEventCache = null;
				_baseFilteredHangingCache = null;
				_availableAllItemsCache = null;
				_availableLootItemsCache = null;
				_availableBushItemsCache = null;
				_availableEventItemsCache = null;
				_availableCachesDirty = true;
			}
		}

		public static void NotifyFiltersChanged()
		{
			lock (CacheLock)
			{
				_availableAllItemsCache = null;
				_availableLootItemsCache = null;
				_availableBushItemsCache = null;
				_availableEventItemsCache = null;
				_availableCachesDirty = true;
			}
		}

		private static bool IsHardExcluded(string itemName)
		{
			if (ExcludedItemNames.Contains(itemName))
			{
				return true;
			}
			if (ExcludedItemPrefixes.Any((string prefix) => itemName.StartsWith(prefix)))
			{
				return true;
			}
			if (ExcludedItemSuffixes.Any((string suffix) => itemName.EndsWith(suffix)))
			{
				return true;
			}
			if (MaxSpawnCountByItemName.TryGetValue(itemName, out var value) && value <= 0)
			{
				return true;
			}
			return false;
		}

		private static bool IsBlockedBySpawnLimit(string itemName)
		{
			if (!MaxSpawnCountByItemName.TryGetValue(itemName, out var value))
			{
				return false;
			}
			int value2;
			int num = (SpawnedCountByItemName.TryGetValue(itemName, out value2) ? value2 : 0);
			return num >= value;
		}

		public static void MarkSpawned(string itemName)
		{
			if (!MaxSpawnCountByItemName.ContainsKey(itemName))
			{
				return;
			}
			lock (CacheLock)
			{
				if (!SpawnedCountByItemName.ContainsKey(itemName))
				{
					SpawnedCountByItemName[itemName] = 0;
				}
				SpawnedCountByItemName[itemName]++;
				_availableCachesDirty = true;
			}
		}

		public static Dictionary<ushort, Item> GetHangingItemsDatabaseFiltered()
		{
			lock (CacheLock)
			{
				if (_baseFilteredHangingCache != null)
				{
					return _baseFilteredHangingCache;
				}
				ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
				_baseFilteredHangingCache = instance.itemLookup.Where((KeyValuePair<ushort, Item> pair) => (Object)(object)pair.Value != (Object)null && !IsHardExcluded(((Object)pair.Value).name) && !UnsafeForRandomLootNames.Contains(((Object)pair.Value).name) && !UnsafeForHangingLootNames.Contains(((Object)pair.Value).name) && pair.Value.IsValidToSpawn() && pair.Value.UIData != null && pair.Value.UIData.canPocket && pair.Value.UIData.canDrop).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value);
				return _baseFilteredHangingCache;
			}
		}

		public static bool TryGetRandomHangingLootItem(out Item item)
		{
			item = null;
			Dictionary<ushort, Item> hangingItemsDatabaseFiltered = GetHangingItemsDatabaseFiltered();
			if (hangingItemsDatabaseFiltered.Count == 0)
			{
				return false;
			}
			item = hangingItemsDatabaseFiltered.ElementAt(Random.Range(0, hangingItemsDatabaseFiltered.Count)).Value;
			return (Object)(object)item != (Object)null;
		}

		private static bool HasUnsafeRuntimeComponent(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return true;
			}
			try
			{
				return (Object)(object)((Component)item).GetComponent<BananaPeel>() != (Object)null || ((Component)item).GetComponentsInChildren<BananaPeel>(true).Length != 0;
			}
			catch
			{
				return true;
			}
		}

		private static bool IsSafeInventoryItem(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			if (!item.IsValidToSpawn())
			{
				return false;
			}
			if (item.UIData == null)
			{
				return false;
			}
			if (!item.UIData.canPocket)
			{
				return false;
			}
			if (!item.UIData.canDrop)
			{
				return false;
			}
			if (HasUnsafeRuntimeComponent(item))
			{
				return false;
			}
			return true;
		}

		private static bool IsSafeRandomEventItem(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			if (!item.IsValidToSpawn())
			{
				return false;
			}
			if (item.UIData == null)
			{
				return false;
			}
			if (!item.UIData.canDrop)
			{
				return false;
			}
			if (UnsafeForRandomLootNames.Contains(((Object)item).name) || UnsafeForRandomEventItemNames.Contains(((Object)item).name))
			{
				return false;
			}
			if (HasUnsafeRuntimeComponent(item))
			{
				return false;
			}
			return true;
		}

		private static bool IsSafeBushItem(Item item)
		{
			if (!IsSafeInventoryItem(item))
			{
				return false;
			}
			return !UnsafeForBushLootNames.Contains(((Object)item).name);
		}

		private static Dictionary<ushort, Item> BuildBaseFiltered(bool lootOnly, bool bushOnly, bool eventOnly = false)
		{
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			return instance.itemLookup.Where((KeyValuePair<ushort, Item> pair) => (Object)(object)pair.Value != (Object)null && (eventOnly ? IsSafeRandomEventItem(pair.Value) : IsSafeInventoryItem(pair.Value)) && !IsHardExcluded(((Object)pair.Value).name) && (!lootOnly || !UnsafeForRandomLootNames.Contains(((Object)pair.Value).name)) && (!bushOnly || IsSafeBushItem(pair.Value))).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value);
		}

		private static Dictionary<ushort, Item> BuildAvailableFromBase(Dictionary<ushort, Item> baseCache)
		{
			return baseCache.Where<KeyValuePair<ushort, Item>>((KeyValuePair<ushort, Item> pair) => !IsBlockedBySpawnLimit(((Object)pair.Value).name)).ToDictionary((KeyValuePair<ushort, Item> pair) => pair.Key, (KeyValuePair<ushort, Item> pair) => pair.Value);
		}

		private static void EnsureAvailableCaches()
		{
			lock (CacheLock)
			{
				if (_baseFilteredAllCache == null)
				{
					_baseFilteredAllCache = BuildBaseFiltered(lootOnly: false, bushOnly: false);
				}
				if (_baseFilteredLootCache == null)
				{
					_baseFilteredLootCache = BuildBaseFiltered(lootOnly: true, bushOnly: false);
				}
				if (_baseFilteredBushCache == null)
				{
					_baseFilteredBushCache = BuildBaseFiltered(lootOnly: true, bushOnly: true);
				}
				if (_baseFilteredEventCache == null)
				{
					_baseFilteredEventCache = BuildBaseFiltered(lootOnly: false, bushOnly: false, eventOnly: true);
				}
				if (_availableCachesDirty || _availableAllItemsCache == null || _availableLootItemsCache == null || _availableBushItemsCache == null || _availableEventItemsCache == null)
				{
					_availableAllItemsCache = BuildAvailableFromBase(_baseFilteredAllCache);
					_availableLootItemsCache = BuildAvailableFromBase(_baseFilteredLootCache);
					_availableBushItemsCache = BuildAvailableFromBase(_baseFilteredBushCache);
					_availableEventItemsCache = BuildAvailableFromBase(_baseFilteredEventCache);
					_availableCachesDirty = false;
				}
			}
		}

		public static ushort GetRandomId()
		{
			EnsureAvailableCaches();
			Dictionary<ushort, Item> availableEventItemsCache = _availableEventItemsCache;
			if (availableEventItemsCache.Count == 0)
			{
				return 0;
			}
			Dictionary<ushort, Item>.KeyCollection keys = availableEventItemsCache.Keys;
			return keys.ElementAt(Random.Range(0, keys.Count));
		}

		public static Dictionary<ushort, Item> GetItemsDatabaseFiltered()
		{
			EnsureAvailableCaches();
			return _availableAllItemsCache;
		}

		public static Dictionary<ushort, Item> GetEventItemsDatabaseFiltered()
		{
			EnsureAvailableCaches();
			return _availableEventItemsCache;
		}

		public static Dictionary<ushort, Item> GetLootItemsDatabaseFiltered()
		{
			EnsureAvailableCaches();
			return _availableLootItemsCache;
		}

		public static Dictionary<ushort, Item> GetBushItemsDatabaseFiltered()
		{
			EnsureAvailableCaches();
			return _availableBushItemsCache;
		}

		public static bool TryGetRandomItem(out Item item)
		{
			item = null;
			Dictionary<ushort, Item> itemsDatabaseFiltered = GetItemsDatabaseFiltered();
			if (itemsDatabaseFiltered.Count == 0)
			{
				return false;
			}
			item = itemsDatabaseFiltered.ElementAt(Random.Range(0, itemsDatabaseFiltered.Count)).Value;
			return (Object)(object)item != (Object)null;
		}

		public static bool TryGetRandomEventItem(out Item item)
		{
			item = null;
			Dictionary<ushort, Item> eventItemsDatabaseFiltered = GetEventItemsDatabaseFiltered();
			if (eventItemsDatabaseFiltered.Count == 0)
			{
				return false;
			}
			item = eventItemsDatabaseFiltered.ElementAt(Random.Range(0, eventItemsDatabaseFiltered.Count)).Value;
			return (Object)(object)item != (Object)null;
		}

		public static bool TryGetRandomLootItem(out Item item)
		{
			item = null;
			Dictionary<ushort, Item> lootItemsDatabaseFiltered = GetLootItemsDatabaseFiltered();
			if (lootItemsDatabaseFiltered.Count == 0)
			{
				return false;
			}
			item = lootItemsDatabaseFiltered.ElementAt(Random.Range(0, lootItemsDatabaseFiltered.Count)).Value;
			return (Object)(object)item != (Object)null;
		}

		public static bool TryGetRandomBushLootItem(out Item item)
		{
			item = null;
			Dictionary<ushort, Item> bushItemsDatabaseFiltered = GetBushItemsDatabaseFiltered();
			if (bushItemsDatabaseFiltered.Count == 0)
			{
				return false;
			}
			item = bushItemsDatabaseFiltered.ElementAt(Random.Range(0, bushItemsDatabaseFiltered.Count)).Value;
			return (Object)(object)item != (Object)null;
		}
	}
	public static class DayNightManagerBootstrapPatch
	{
	}
	public static class GameHandlerPatch
	{
		private const int MaxEventsPerFrame = 1;

		private const int MaxDestroyPerFrame = 24;

		[HarmonyPatch(typeof(GameHandler), "Update")]
		[HarmonyPrefix]
		private static bool Prefix(GameHandler __instance)
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (ModConfig.EnableChaosMaster.Value && ModConfig.EnableRandomEvents.Value)
			{
				RandomEventTask.EnsureStarted();
			}
			RandomizerEvents.FlushScheduledWork();
			for (int i = 0; i < 1; i++)
			{
				if (!RandomizerEvents.TryDequeueEvent(out string eventName))
				{
					break;
				}
				try
				{
					if (!RandomizerEvents.TryGetEventAction(eventName, out Action action))
					{
						Plugin.Log.LogWarning((object)("Unknown or empty random event: " + eventName));
						continue;
					}
					action();
					RandomizerEvents.CleanupOrphanTemporarySlotsForAll("after " + eventName);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Error when trying to execute {eventName}: {arg}");
				}
			}
			for (int j = 0; j < 24; j++)
			{
				if (!RandomizerEvents.TryDequeueDestroy(out GameObject obj))
				{
					break;
				}
				try
				{
					if (!((Object)(object)obj == (Object)null))
					{
						PhotonView component = obj.GetComponent<PhotonView>();
						if ((Object)(object)component == (Object)null)
						{
							Object.Destroy((Object)(object)obj);
						}
						else
						{
							PhotonNetwork.Destroy(obj);
						}
					}
				}
				catch (Exception arg2)
				{
					Plugin.Log.LogWarning((object)$"Destroy queue error: {arg2}");
				}
			}
			return true;
		}
	}
	public static class HotSunPatch
	{
	}
	public static class ItemOptimizationCompatibilityPatch
	{
		[HarmonyPatch]
		private static class DeregisterItemPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("Peak.ItemOptimizationManager");
				return type != null && AccessTools.Method(type, "DeregisterItem", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(AccessTools.TypeByName("Peak.ItemOptimizationManager"), "DeregisterItem", (Type[])null, (Type[])null);
			}

			[HarmonyFinalizer]
			private static Exception? Finalizer(Exception? __exception)
			{
				return SwallowNullKeyDeregister(__exception, "DeregisterItem");
			}
		}

		[HarmonyPatch]
		private static class ItemOptimizerOnDisablePatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("Peak.ItemOptimizer");
				return type != null && AccessTools.Method(type, "OnDisable", (Type[])null, (Type[])null) != null;
			}

			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(AccessTools.TypeByName("Peak.ItemOptimizer"), "OnDisable", (Type[])null, (Type[])null);
			}

			[HarmonyFinalizer]
			private static Exception? Finalizer(Exception? __exception)
			{
				return SwallowNullKeyDeregister(__exception, "ItemOptimizer.OnDisable");
			}
		}

		private static int _warned;

		private static bool IsNullKeyDeregisterException(Exception? exception)
		{
			if (exception == null)
			{
				return false;
			}
			if (exception is ArgumentNullException ex && string.Equals(ex.ParamName, "key", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return exception.InnerException != null && IsNullKeyDeregisterException(exception.InnerException);
		}

		private static Exception? SwallowNullKeyDeregister(Exception? exception, string source)
		{
			if (!IsNullKeyDeregisterException(exception))
			{
				return exception;
			}
			if (Interlocked.Exchange(ref _warned, 1) == 0)
			{
				Plugin.Log.LogWarning((object)("Suppressed ItemOptimizationManager null-key deregister exception from " + source + ". Rich loot remains enabled; this only prevents isolated null-key optimizer errors from spamming the log."));
			}
			return null;
		}
	}
	public static class LoadingScreenHandlerPatch
	{
		[HarmonyPatch(typeof(LoadingScreenHandler), "LoadSceneProcess")]
		[HarmonyPrefix]
		public static bool Prefix(LoadingScreenHandler __instance, string sceneName, bool networked, bool yieldForCharacterSpawn, float extraYieldTimeOnEnd, ref IEnumerator __result)
		{
			switch ((sceneName ?? string.Empty).ToLowerInvariant())
			{
			case "airport":
			case "mainmenu":
			case "title":
			case "pretitle":
			case "wilisland":
				ChaosEnvironmentController.ResetLocalState();
				TornadoCompatibilityPatch.ResetRuntimeState();
				if (PhotonNetwork.IsMasterClient)
				{
					RandomEventTask.StopTask();
					CustomLoot.ResetRuntimeState();
				}
				break;
			}
			return true;
		}
	}
	public static class LootTablePatch
	{
		[ThreadStatic]
		private static int _suppressGenericLootRandomizationDepth;

		private static readonly int TerrainMask = LayerMask.GetMask(new string[2] { "Terrain", "Map" });

		private static bool IsGenericLootRandomizationSuppressed()
		{
			return _suppressGenericLootRandomizationDepth > 0;
		}

		private static void PushGenericLootRandomizationSuppression()
		{
			_suppressGenericLootRandomizationDepth++;
		}

		private static void PopGenericLootRandomizationSuppression()
		{
			if (_suppressGenericLootRandomizationDepth > 0)
			{
				_suppressGenericLootRandomizationDepth--;
			}
		}

		private static bool IsExcludedVanillaSpecialPool(SpawnPool spawnPool)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			return (int)spawnPool == 32768 || (int)spawnPool == 65536 || (int)spawnPool == 131072;
		}

		private static bool IsItemOnlySpawnList(SpawnList spawnList)
		{
			if ((Object)(object)spawnList == (Object)null || spawnList.items == null || spawnList.items.Count == 0)
			{
				return false;
			}
			bool result = false;
			for (int i = 0; i < spawnList.items.Count; i++)
			{
				SpawnEntry val = spawnList.items[i];
				if (val != null && !((Object)(object)val.prefab == (Object)null))
				{
					result = true;
					if ((Object)(object)val.prefab.GetComponent<Item>() == (Object)null)
					{
						return false;
					}
				}
			}
			return result;
		}

		private static List<GameObject> BuildRandomLootResult(int count, bool canRepeat)
		{
			List<GameObject> list = new List<GameObject>(Mathf.Max(0, count));
			if (count <= 0)
			{
				return list;
			}
			HashSet<string> hashSet = (canRepeat ? null : new HashSet<string>(StringComparer.Ordinal));
			int num = Mathf.Max(16, count * 8);
			Item item;
			while (list.Count < count && num-- > 0 && CustomLoot.TryGetRandomLootItem(out item) && !((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).gameObject == (Object)null))
			{
				if (hashSet == null || hashSet.Add(((Object)item).name))
				{
					list.Add(((Component)item).gameObject);
					CustomLoot.MarkSpawned(((Object)item).name);
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(LootData), "GetRandomItem")]
		[HarmonyPrefix]
		private static bool PrefixGetRandomItem(SpawnPool spawnPool, ref GameObject __result)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			if (IsExcludedVanillaSpecialPool(spawnPool))
			{
				return true;
			}
			if (LootData.AllSpawnWeightData == null)
			{
				LootData.PopulateLootData();
			}
			if (CustomLoot.TryGetRandomLootItem(out Item item))
			{
				CustomLoot.MarkSpawned(((Object)item).name);
				__result = ((Component)item).gameObject;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(LootData), "GetRandomItems")]
		[HarmonyPrefix]
		private static bool PrefixGetRandomItems(SpawnPool spawnPool, int count, bool canRepeat, ref List<GameObject> __result)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			if (IsExcludedVanillaSpecialPool(spawnPool))
			{
				return true;
			}
			if (LootData.AllSpawnWeightData == null)
			{
				LootData.PopulateLootData();
			}
			__result = BuildRandomLootResult(count, canRepeat);
			return __result.Count == 0;
		}

		[HarmonyPatch(typeof(SpawnList), "GetSpawns")]
		[HarmonyPrefix]
		private static bool PrefixSpawnListGetSpawns(SpawnList __instance, int count, bool canRepeat, ref List<GameObject> __result)
		{
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			if (!IsItemOnlySpawnList(__instance))
			{
				return true;
			}
			__result = BuildRandomLootResult(count, canRepeat);
			return __result.Count == 0;
		}

		[HarmonyPatch(typeof(SpawnList), "GetSingleSpawn")]
		[HarmonyPrefix]
		private static bool PrefixSpawnListGetSingleSpawn(SpawnList __instance, ref GameObject __result)
		{
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			if (!IsItemOnlySpawnList(__instance))
			{
				return true;
			}
			if (CustomLoot.TryGetRandomLootItem(out Item item))
			{
				CustomLoot.MarkSpawned(((Object)item).name);
				__result = ((Component)item).gameObject;
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(BerryBush), "SpawnItems")]
		[HarmonyPrefix]
		private static bool PrefixBerryBushSpawnItems(BerryBush __instance, List<Transform> spawnSpots, ref List<PhotonView> __result)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Invalid comparison between Unknown and I4
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			List<PhotonView> list = (__result = new List<PhotonView>());
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			if ((Object)(object)__instance == (Object)null || spawnSpots == null || spawnSpots.Count == 0)
			{
				return false;
			}
			List<Transform> list2 = spawnSpots.Where((Transform s) => (Object)(object)s != (Object)null).ToList();
			if (list2.Count == 0)
			{
				return false;
			}
			float num = Mathf.Pow(Random.value, __instance.randomPow);
			int num2 = Mathf.RoundToInt(Mathf.Lerp(__instance.possibleBerries.x, __instance.possibleBerries.y, num));
			num2 = Mathf.Clamp(num2, 0, list2.Count);
			for (int num3 = 0; num3 < num2 && list2.Count != 0; num3++)
			{
				int index = Random.Range(0, list2.Count);
				Transform val = list2[index];
				list2.RemoveAt(index);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				GameObject val2 = null;
				Item item;
				if ((int)((Spawner)__instance).spawnMode == 0)
				{
					val2 = ((Spawner)__instance).spawnedObjectPrefab;
				}
				else if (CustomLoot.TryGetRandomBushLootItem(out item) && (Object)(object)item != (Object)null)
				{
					CustomLoot.MarkSpawned(((Object)item).name);
					val2 = ((Component)item).gameObject;
				}
				if ((Object)(object)val2 == (Object)null || string.IsNullOrEmpty(((Object)val2).name))
				{
					continue;
				}
				GameObject val3;
				try
				{
					val3 = PhotonNetwork.InstantiateItemRoom(((Object)val2).name, val.position, Quaternion.identity);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"BerryBush spawn failed: {((Object)val2).name}, {arg}");
					continue;
				}
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Item component = val3.GetComponent<Item>();
				PhotonView component2 = val3.GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
				{
					Plugin.Log.LogWarning((object)("BerryBush spawned invalid object: " + ((Object)val2).name));
					try
					{
						PhotonNetwork.Destroy(val3);
					}
					catch
					{
					}
					continue;
				}
				list.Add(component2);
				if (Object.op_Implicit((Object)(object)((Spawner)__instance).spawnUpTowardsTarget) && (Object)(object)((Spawner)__instance).spawnUpTowardsTarget != (Object)null)
				{
					Vector3 val4 = ((Spawner)__instance).spawnUpTowardsTarget.position - ((Component)component).transform.position;
					if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f)
					{
						((Component)component).transform.up = ((Vector3)(ref val4)).normalized;
						((Component)component).transform.Rotate(Vector3.up, Random.Range(0f, 360f), (Space)1);
					}
				}
				if (((Spawner)__instance).spawnTransformIsSpawnerTransform)
				{
					((Component)component).transform.rotation = val.rotation;
					((Component)component).transform.Rotate(Vector3.up, Random.Range(0f, 360f), (Space)1);
				}
				try
				{
					component2.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
					{
						true,
						((Component)component).transform.position,
						((Component)component).transform.rotation
					});
				}
				catch (Exception arg2)
				{
					Plugin.Log.LogWarning((object)$"BerryBush SetKinematicRPC failed: {arg2}");
				}
			}
			__result = list;
			return false;
		}

		[HarmonyPatch(typeof(Spawner), "SpawnItems")]
		[HarmonyPrefix]
		private static void PrefixSpawnerSpawnItems(List<Transform> spawnSpots)
		{
			if (Plugin.IsGameplayScene() && ModConfig.EnableChaosMaster.Value && ModConfig.EnableItemRandomization.Value && spawnSpots != null && spawnSpots.Count != 0 && HasAnyHangingSpot(spawnSpots))
			{
				PushGenericLootRandomizationSuppression();
			}
		}

		[HarmonyPatch(typeof(Spawner), "SpawnItems")]
		[HarmonyFinalizer]
		private static Exception? FinalizerSpawnerSpawnItems(List<Transform> spawnSpots, Exception? __exception)
		{
			if (Plugin.IsGameplayScene() && ModConfig.EnableChaosMaster.Value && ModConfig.EnableItemRandomization.Value && spawnSpots != null && spawnSpots.Count > 0 && HasAnyHangingSpot(spawnSpots))
			{
				PopGenericLootRandomizationSuppression();
			}
			return __exception;
		}

		private static string GetTransformPath(Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(128);
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Insert(0, "/");
				}
				stringBuilder.Insert(0, ((Object)val).name);
				val = val.parent;
			}
			return stringBuilder.ToString();
		}

		private static bool IsHangingSpawnSpot(Transform spot)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)spot == (Object)null)
			{
				return false;
			}
			string text = GetTransformPath(spot).ToLowerInvariant();
			if (text.Contains("vine") || text.Contains("junglevine") || text.Contains("tree") || text.Contains("branch") || text.Contains("root") || text.Contains("mushroom") || text.Contains("shroom") || text.Contains("hang"))
			{
				return true;
			}
			Vector3 val = spot.position + Vector3.up * 0.15f;
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val, Vector3.down, ref val2, 1.35f, TerrainMask, (QueryTriggerInteraction)1))
			{
				return true;
			}
			if (Vector3.Angle(((RaycastHit)(ref val2)).normal, Vector3.up) > 42f)
			{
				return true;
			}
			return false;
		}

		private static bool HasAnyHangingSpot(List<Transform> spawnSpots)
		{
			if (spawnSpots == null || spawnSpots.Count == 0)
			{
				return false;
			}
			for (int i = 0; i < spawnSpots.Count; i++)
			{
				if (IsHangingSpawnSpot(spawnSpots[i]))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class ModConfig
	{
		public static ConfigEntry<bool> EnableChaosMaster { get; private set; }

		public static ConfigEntry<int> WaitTimeMin { get; private set; }

		public static ConfigEntry<int> WaitTimeMax { get; private set; }

		public static ConfigEntry<bool> EnableItemRandomization { get; private set; }

		public static ConfigEntry<bool> EnableRandomEvents { get; private set; }

		public static ConfigEntry<int> TropicsRain { get; private set; }

		public static ConfigEntry<int> RootsWindRandom { get; private set; }

		public static ConfigEntry<int> AlpineSnowRandom { get; private set; }

		public static ConfigEntry<int> MesaSunRandom { get; private set; }

		public static ConfigEntry<bool> ShowSettingsButton { get; private set; }

		public static ConfigEntry<float> SettingsButtonTopOffset { get; private set; }

		public static ConfigEntry<KeyCode> ToggleGuiKey { get; private set; }

		public static ConfigEntry<int> Tornado { get; private set; }

		public static ConfigEntry<int> Tick { get; private set; }

		public static ConfigEntry<int> Bees { get; private set; }

		public static ConfigEntry<int> Tumbleweed { get; private set; }

		public static ConfigEntry<int> Dynamite { get; private set; }

		public static ConfigEntry<int> Zombie { get; private set; }

		public static ConfigEntry<int> Mandrake { get; private set; }

		public static ConfigEntry<int> Cactus { get; private set; }

		public static ConfigEntry<int> RandomItem { get; private set; }

		public static ConfigEntry<int> RandomGoodItem { get; private set; }

		public static ConfigEntry<int> RandomGoodItemRain { get; private set; }

		public static ConfigEntry<int> BingBongRain { get; private set; }

		public static ConfigEntry<int> CureAll { get; private set; }

		public static ConfigEntry<int> Pandora { get; private set; }

		public static ConfigEntry<int> SwapPlayers { get; private set; }

		public static ConfigEntry<int> WarpToLastPlayer { get; private set; }

		public static ConfigEntry<int> SwapPlayerItems { get; private set; }

		public static ConfigEntry<int> SwapPlayerStatuses { get; private set; }

		public static ConfigEntry<int> ReviveOne { get; private set; }

		public static ConfigEntry<int> ReviveAll { get; private set; }

		public static ConfigEntry<int> HealShroom { get; private set; }

		public static ConfigEntry<int> BounceShroom { get; private set; }

		public static ConfigEntry<int> MoraleBoost { get; private set; }

		public static ConfigEntry<int> Scorpion { get; private set; }

		public static ConfigEntry<int> RandomBackpackGood { get; private set; }

		public static ConfigEntry<int> RandomBackpack { get; private set; }

		public static ConfigEntry<int> Beanstalk { get; private set; }

		public static ConfigEntry<int> BeanstalkSpam { get; private set; }

		public static ConfigEntry<int> EnergyDrink { get; private set; }

		public static ConfigEntry<int> Lollipop { get; private set; }

		public static ConfigEntry<int> Milk { get; private set; }

		public static ConfigEntry<int> UnlimitedPower { get; private set; }

		public static ConfigEntry<int> TwoAtOnce { get; private set; }

		public static ConfigEntry<int> Skeleton { get; private set; }

		public static ConfigEntry<int> TieBalloon { get; private set; }

		public static ConfigEntry<int> TieThreeBalloons { get; private set; }

		public static ConfigEntry<int> Web { get; private set; }

		public static ConfigEntry<int> Antirope { get; private set; }

		public static ConfigEntry<int> PitonPatch { get; private set; }

		public static ConfigEntry<int> ChainCache { get; private set; }

		public static ConfigEntry<int> ToxicBounceShroom { get; private set; }

		public static ConfigEntry<int> LowGravityShroom { get; private set; }

		public static ConfigEntry<int> SleepySpores { get; private set; }

		public static ConfigEntry<int> FungusCloud { get; private set; }

		public static ConfigEntry<int> DayNight { get; private set; }

		public static ConfigEntry<int> Eruption { get; private set; }

		public static ConfigEntry<bool> EnableTornadoAtKiln { get; private set; }

		public static ConfigEntry<float> ExtendedDynamiteChance { get; private set; }

		public static ConfigEntry<float> BoobyTrappedBackpacksChance { get; private set; }

		public static void Startup(ConfigFile config)
		{
			EnableChaosMaster = config.Bind<bool>("General", "EnableChaosMaster", true, "Master switch. OFF = disable random loot and random events.");
			EnableItemRandomization = config.Bind<bool>("General", "EnableItemRandomization", true, "Enable randomized item spawns.");
			EnableRandomEvents = config.Bind<bool>("General", "EnableRandomEvents", true, "Enable random events.");
			WaitTimeMin = config.Bind<int>("Events.Timer", "WaitTimeMin", 30, "Minimum seconds between random events.");
			WaitTimeMax = config.Bind<int>("Events.Timer", "WaitTimeMax", 60, "Maximum seconds between random events.");
			ShowSettingsButton = config.Bind<bool>("GUI", "ShowSettingsButton", true, "Show the in-game settings button.");
			SettingsButtonTopOffset = config.Bind<float>("GUI", "SettingsButtonTopOffset", 66f, "Top offset of the settings button.");
			ToggleGuiKey = config.Bind<KeyCode>("GUI", "ToggleGuiKey", (KeyCode)289, "Keyboard key to open/close the chaos settings window.");
			EnableTornadoAtKiln = config.Bind<bool>("Events.Settings", "EnableTornadoAtKiln", false, "Enable Tornado at Kiln.");
			ExtendedDynamiteChance = config.Bind<float>("Events.Settings", "ExtendedDynamiteChance", 0.1f, "Chance for extended dynamite.");
			BoobyTrappedBackpacksChance = config.Bind<float>("Events.Settings", "BoobyTrappedBackpacksChance", 0.1f, "Chance for troll backpack.");
			TropicsRain = config.Bind<int>("Events.Weights", "TropicsRain", 18, "SporeBurst: spawn spore cloud near a random player. Poison+Spores doubled, no Drowsy.");
			RootsWindRandom = config.Bind<int>("Events.Weights", "RootsWindRandom", 25, "WindBurst: activate a vanilla WindChillZone via native RPCA_ToggleWind for 15-35s. Works for unmodded clients.");
			AlpineSnowRandom = config.Bind<int>("Events.Weights", "AlpineSnowRandom", 22, "ColdSnap: apply vanilla Cold status to 1-4 random players via native RPC.");
			MesaSunRandom = config.Bind<int>("Events.Weights", "MesaSunRandom", 20, "HeatWave: apply vanilla Hot status to 2-5 random players + AloeVera after 25s.");
			Tornado = config.Bind<int>("Events.Weights", "Tornado", 50, "");
			Tick = config.Bind<int>("Events.Weights", "Tick", 70, "");
			Bees = config.Bind<int>("Events.Weights", "Bees", 10, "");
			Tumbleweed = config.Bind<int>("Events.Weights", "Tumbleweed", 100, "");
			Dynamite = config.Bind<int>("Events.Weights", "Dynamite", 20, "");
			Zombie = config.Bind<int>("Events.Weights", "Zombie", 60, "");
			Mandrake = config.Bind<int>("Events.Weights", "Mandrake", 90, "");
			Cactus = config.Bind<int>("Events.Weights", "Cactus", 100, "");
			RandomItem = config.Bind<int>("Events.Weights", "RandomItem", 100, "");
			RandomGoodItem = config.Bind<int>("Events.Weights", "RandomGoodItem", 20, "");
			RandomGoodItemRain = config.Bind<int>("Events.Weights", "RandomGoodItemRain", 10, "");
			BingBongRain = config.Bind<int>("Events.Weights", "BingBongRain", 15, "");
			CureAll = config.Bind<int>("Events.Weights", "CureAll", 20, "");
			Pandora = config.Bind<int>("Events.Weights", "Pandora", 50, "");
			SwapPlayers = config.Bind<int>("Events.Weights", "SwapPlayers", 60, "");
			WarpToLastPlayer = config.Bind<int>("Events.Weights", "WarpToLowestPlayer", 10, "");
			SwapPlayerItems = config.Bind<int>("Events.Weights", "SwapPlayerItems", 50, "");
			SwapPlayerStatuses = config.Bind<int>("Events.Weights", "SwapPlayerStatuses", 45, "Swap part or all of player statuses except backpack weight.");
			ReviveOne = config.Bind<int>("Events.Weights", "ReviveOne", 20, "");
			ReviveAll = config.Bind<int>("Events.Weights", "ReviveAll", 10, "");
			HealShroom = config.Bind<int>("Events.Weights", "HealShroom", 40, "");
			BounceShroom = config.Bind<int>("Events.Weights", "BounceShroom", 80, "");
			MoraleBoost = config.Bind<int>("Events.Weights", "MoraleBoost", 50, "");
			Scorpion = config.Bind<int>("Events.Weights", "Scorpion", 60, "");
			RandomBackpack = config.Bind<int>("Events.Weights", "RandomBackpack", 60, "");
			RandomBackpackGood = config.Bind<int>("Events.Weights", "RandomBackpackGood", 10, "");
			Beanstalk = config.Bind<int>("Events.Weights", "Beanstalk", 40, "");
			BeanstalkSpam = config.Bind<int>("Events.Weights", "BeanstalkSpam", 10, "");
			EnergyDrink = config.Bind<int>("Events.Weights", "EnergyDrink", 30, "");
			Lollipop = config.Bind<int>("Events.Weights", "Lollipop", 30, "");
			Milk = config.Bind<int>("Events.Weights", "Milk", 30, "");
			UnlimitedPower = config.Bind<int>("Events.Weights", "UnlimitedPower", 10, "");
			TwoAtOnce = config.Bind<int>("Events.Weights", "TwoAtOnce", 20, "");
			Skeleton = config.Bind<int>("Events.Weights", "Skeleton", 10, "");
			TieBalloon = config.Bind<int>("Events.Weights", "TieBalloon", 30, "");
			TieThreeBalloons = config.Bind<int>("Events.Weights", "TieThreeBalloons", 10, "");
			Web = config.Bind<int>("Events.Weights", "Web", 58, "");
			Antirope = config.Bind<int>("Events.Weights", "Antirope", 20, "");
			PitonPatch = config.Bind<int>("Events.Weights", "PitonPatch", 35, "Place 1-3 vanilla pitons on nearby walls, roughly 2-4m above random players. Host only chooses placement; spawned pitons are vanilla network objects.");
			ChainCache = config.Bind<int>("Events.Weights", "ChainCache", 22, "Place vanilla ChainShooter chains from near player feet toward a valid TerrainMap point 5-30m away; falls back to giving the item if no safe placement is found.");
			ToxicBounceShroom = config.Bind<int>("Events.Weights", "ToxicBounceShroom", 28, "Spawn small vanilla bounce-shroom traps and apply light poison/spores to selected players.");
			LowGravityShroom = config.Bind<int>("Events.Weights", "LowGravityShroom", 18, "Feed a vanilla mushroom whose current run effect is low gravity, when one can be found.");
			SleepySpores = config.Bind<int>("Events.Weights", "SleepySpores", 12, "Light drowsy/spore effect for a few random players. Lower weight and lower intensity because it is negative.");
			FungusCloud = config.Bind<int>("Events.Weights", "FungusCloud", 14, "Small vanilla spore-cloud burst around one player, affecting only nearby players.");
			DayNight = config.Bind<int>("Events.Weights", "DayNightSwap", 30, "");
			Eruption = config.Bind<int>("Events.Weights", "Eruption", 70, "");
			if (TropicsRain.Value == 0 && RootsWindRandom.Value == 0 && AlpineSnowRandom.Value == 0 && MesaSunRandom.Value == 0)
			{
				TropicsRain.Value = 18;
				RootsWindRandom.Value = 25;
				AlpineSnowRandom.Value = 22;
				MesaSunRandom.Value = 20;
				config.Save();
			}
		}
	}
	public static class MountainProgressHandlerPatch
	{
		[HarmonyPatch(typeof(MountainProgressHandler), "TriggerReached")]
		[HarmonyPrefix]
		public static bool Prefix(MountainProgressHandler __instance, ProgressPoint progressPoint)
		{
			ChaosEnvironmentController.ResetLocalState();
			TornadoCompatibilityPatch.ResetRuntimeState();
			if (PhotonNetwork.IsMasterClient)
			{
				if (Singleton<MapHandler>.Instance.currentSegment == 0)
				{
					CustomLoot.ResetRuntimeState();
					RandomizerEvents.ClearPendingQueues();
					RandomEventTask.StartTask();
				}
				else
				{
					RandomizerEvents.ClearPendingQueues();
					QueueGarbageForCleanup();
				}
			}
			return true;
		}

		private static void CollectGarbageOf<T>(List<GameObject> results) where T : MonoBehaviour
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (results == null)
			{
				return;
			}
			MapHandler instance = Singleton<MapHandler>.Instance;
			if ((Object)(object)instance == (Object)null || instance.currentSegment <= 0 || instance.segments == null)
			{
				return;
			}
			int num = instance.currentSegment - 1;
			if (num < 0 || num >= instance.segments.Length)
			{
				return;
			}
			GameObject segmentCampfire = instance.segments[num].segmentCampfire;
			if ((Object)(object)segmentCampfire == (Object)null)
			{
				return;
			}
			T[] array = Object.FindObjectsByType<T>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			T[] array2 = array;
			foreach (T val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)(object)val).gameObject == (Object)null) && segmentCampfire.transform.position.z - ((Component)(object)val).transform.position.z > 20f)
				{
					results.Add(((Component)(object)val).gameObject);
				}
			}
		}

		public static void QueueGarbageForCleanup()
		{
			List<GameObject> list = new List<GameObject>();
			CollectGarbageOf<Item>(list);
			CollectGarbageOf<Luggage>(list);
			CollectGarbageOf<RopeAnchorProjectile>(list);
			CollectGarbageOf<RopeAnchorWithRope>(list);
			CollectGarbageOf<Rope>(list);
			CollectGarbageOf<JungleVine>(list);
			CollectGarbageOf<CheckpointFlag>(list);
			CollectGarbageOf<ClimbingSpikeComponent>(list);
			CollectGarbageOf<ShittyPiton>(list);
			CollectGarbageOf<ScoutCannon>(list);
			if (list.Count == 0)
			{
				return;
			}
			foreach (GameObject item in list.Distinct())
			{
				RandomizerEvents.RemoveObjectAfterTime(item, 0f);
			}
		}
	}
	public static class PauseMenuMainPagePatch
	{
		[HarmonyPatch(typeof(PauseMenuMainPage), "OnQuitClicked")]
		[HarmonyPrefix]
		public static bool Prefix(PauseMenuMainPage __instance)
		{
			ChaosEnvironmentController.ResetLocalState();
			TornadoCompatibilityPatch.ResetRuntimeState();
			if (PhotonNetwork.IsMasterClient)
			{
				RandomEventTask.StopTask();
				CustomLoot.ResetRuntimeState();
			}
			return true;
		}
	}
	[BepInPlugin("PeakRandomizedChaos", "Chaos", "1.3.8")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "PeakRandomizedChaos";

		public const string ModName = "Chaos";

		public const string ModVersion = "1.3.8";

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private Harmony _harmony = null;

		private bool _showSettingsGUI;

		private Rect _settingsWindowRect = new Rect(0f, 0f, 540f, 620f);

		private Vector2 _scrollPosition;

		private string _tempWaitTimeMin = "";

		private string _tempWaitTimeMax = "";

		private GUIStyle _buttonStyle = null;

		private GUIStyle _windowStyle = null;

		private GUIStyle _labelStyle = null;

		private GUIStyle _titleStyle = null;

		private GUIStyle _sectionStyle = null;

		private GUIStyle _textFieldStyle = null;

		private GUIStyle _textFieldHoverStyle = null;

		private GUIStyle _switchOnStyle = null;

		private GUIStyle _switchOffStyle = null;

		private GUIStyle _closeStyle = null;

		private GUIStyle _hintStyle = null;

		private Texture2D _btnTex = null;

		private Texture2D _btnHoverTex = null;

		private Texture2D _windowTex = null;

		private Texture2D _fieldTex = null;

		private Texture2D _accentTex = null;

		private Texture2D _rowTex = null;

		private Texture2D _switchOnTex = null;

		private Texture2D _switchOnHoverTex = null;

		private Texture2D _switchOffTex = null;

		private Texture2D _switchOffHoverTex = null;

		private Texture2D _dimTex = null;

		private bool _lastChaosMasterState;

		private bool _lastRandomEventsState;

		private void Awake()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Startup(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("PeakRandomizedChaos");
			_harmony.PatchAll(typeof(LootTablePatch));
			_harmony.PatchAll(typeof(GameHandlerPatch));
			_harmony.PatchAll(typeof(MountainProgressHandlerPatch));
			_harmony.PatchAll(typeof(LoadingScreenHandlerPatch));
			_harmony.PatchAll(typeof(PauseMenuMainPagePatch));
			_harmony.PatchAll(typeof(SpecialHeldItemPatch));
			_harmony.PatchAll(typeof(RescueHookDestroyPatch));
			_harmony.PatchAll(typeof(WindChillZonePatch));
			_harmony.PatchAll(typeof(HotSunPatch));
			_harmony.PatchAll(typeof(TornadoCompatibilityPatch));
			_harmony.PatchAll(typeof(ItemOptimizationCompatibilityPatch));
			_harmony.PatchAll(typeof(RuntimeSafetyPatch));
			SyncTempValuesFromConfig();
			_lastChaosMasterState = ModConfig.EnableChaosMaster.Value;
			_lastRandomEventsState = ModConfig.EnableRandomEvents.Value;
			Log.LogInfo((object)"Chaos loaded.");
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(ModConfig.ToggleGuiKey.Value))
			{
				_showSettingsGUI = !_showSettingsGUI;
				if (_showSettingsGUI)
				{
					SyncTempValuesFromConfig();
				}
			}
			bool value = ModConfig.EnableChaosMaster.Value;
			bool value2 = ModConfig.EnableRandomEvents.Value;
			if (_lastChaosMasterState == value && _lastRandomEventsState == value2)
			{
				return;
			}
			_lastChaosMasterState = value;
			_lastRandomEventsState = value2;
			if (PhotonNetwork.IsMasterClient)
			{
				if (!value || !value2)
				{
					RandomEventTask.StopTask();
					RandomizerEvents.ClearPendingQueues();
				}
				else
				{
					RandomEventTask.StartTask();
				}
			}
		}

		private void OnGUI()
		{
			EnsureGuiStyles();
			DrawSettingsButton();
			if (_showSettingsGUI)
			{
				DrawSettingsWindow();
			}
		}

		private void OnDestroy()
		{
			try
			{
				ChaosEnvironmentController.ResetLocalState();
				TornadoCompatibilityPatch.ResetRuntimeState();
				if (PhotonNetwork.IsMasterClient)
				{
					RandomEventTask.StopTask();
					RandomizerEvents.ClearPendingQueues();
				}
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
			SafeDestroy(ref _btnTex);
			SafeDestroy(ref _btnHoverTex);
			SafeDestroy(ref _windowTex);
			SafeDestroy(ref _fieldTex);
			SafeDestroy(ref _accentTex);
			SafeDestroy(ref _rowTex);
			SafeDestroy(ref _switchOnTex);
			SafeDestroy(ref _switchOnHoverTex);
			SafeDestroy(ref _switchOffTex);
			SafeDestroy(ref _switchOffHoverTex);
			SafeDestroy(ref _dimTex);
		}

		private static bool IsNonGameplayScene(string sceneName)
		{
			if (string.IsNullOrWhiteSpace(sceneName))
			{
				return true;
			}
			switch (sceneName.ToLowerInvariant())
			{
			case "airport":
			case "mainmenu":
			case "title":
			case "pretitle":
			case "wilisland":
				return true;
			default:
				return false;
			}
		}

		public static bool IsGameplayScene()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			return !IsNonGameplayScene(name);
		}

		private void DrawSettingsButton()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.ShowSettingsButton.Value)
			{
				return;
			}
			float num = 40f;
			float num2 = (float)Screen.width - num - 14f;
			float num3 = Mathf.Max(10f, ModConfig.SettingsButtonTopOffset.Value);
			if (GUI.Button(new Rect(num2, num3, num, num), "⚙", _buttonStyle))
			{
				_showSettingsGUI = !_showSettingsGUI;
				if (_showSettingsGUI)
				{
					SyncTempValuesFromConfig();
					((Rect)(ref _settingsWindowRect)).x = Mathf.Max(10f, num2 - 486f);
					((Rect)(ref _settingsWindowRect)).y = Mathf.Min((float)Screen.height - ((Rect)(ref _settingsWindowRect)).height - 10f, num3 + 48f);
				}
			}
		}

		private void DrawSettingsWindow()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_dimTex);
			_settingsWindowRect = GUI.Window(987654, _settingsWindowRect, new WindowFunction(DrawSettingsWindowContents), "", _windowStyle);
		}

		private void DrawSettingsWindowContents(int id)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			float width = ((Rect)(ref _settingsWindowRect)).width;
			float height = ((Rect)(ref _settingsWindowRect)).height;
			GUI.DrawTexture(new Rect(0f, 0f, width, height), (Texture)(object)_windowTex);
			GUI.DrawTexture(new Rect(0f, 0f, width, 52f), (Texture)(object)_accentTex);
			GUI.Label(new Rect(16f, 11f, 360f, 30f), "Chaos Settings", _titleStyle);
			if (GUI.Button(new Rect(width - 46f, 11f, 30f, 30f), "X", _closeStyle))
			{
				_showSettingsGUI = false;
			}
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(14f, 64f, width - 28f, height - 122f);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width - 18f, 660f);
			_scrollPosition = GUI.BeginScrollView(val, _scrollPosition, val2);
			float y = 0f;
			DrawSectionLabel("界面", ref y, ((Rect)(ref val2)).width);
			DrawToggleRow("显示右上角设置按钮", ref y, ((Rect)(ref val2)).width, ModConfig.ShowSettingsButton);
			DrawSectionLabel("主开关", ref y, ((Rect)(ref val2)).width);
			DrawToggleRow("Chaos Mod 总开关", ref y, ((Rect)(ref val2)).width, ModConfig.EnableChaosMaster);
			DrawSectionLabel("随机内容", ref y, ((Rect)(ref val2)).width);
			DrawToggleRow("随机箱子 / 随机掉落", ref y, ((Rect)(ref val2)).width, ModConfig.EnableItemRandomization);
			DrawToggleRow("随机事件", ref y, ((Rect)(ref val2)).width, ModConfig.EnableRandomEvents);
			DrawSectionLabel("随机事件时间范围", ref y, ((Rect)(ref val2)).width);
			DrawTextFieldRow("最小时间(秒)", ref y, ((Rect)(ref val2)).width, ref _tempWaitTimeMin, delegate(string value)
			{
				if (int.TryParse(value, out var result))
				{
					ModConfig.WaitTimeMin.Value = Mathf.Max(1, result);
					ClampTimeRange();
					((BaseUnityPlugin)this).Config.Save();
					SyncTempValuesFromConfig();
				}
			}, delegate(int delta)
			{
				ModConfig.WaitTimeMin.Value = Mathf.Max(1, ModConfig.WaitTimeMin.Value + delta);
				ClampTimeRange();
				((BaseUnityPlugin)this).Config.Save();
				SyncTempValuesFromConfig();
			});
			DrawTextFieldRow("最大时间(秒)", ref y, ((Rect)(ref val2)).width, ref _tempWaitTimeMax, delegate(string value)
			{
				if (int.TryParse(value, out var result))
				{
					ModConfig.WaitTimeMax.Value = Mathf.Max(1, result);
					ClampTimeRange();
					((BaseUnityPlugin)this).Config.Save();
					SyncTempValuesFromConfig();
				}
			}, delegate(int delta)
			{
				ModConfig.WaitTimeMax.Value = Mathf.Max(1, ModConfig.WaitTimeMax.Value + delta);
				ClampTimeRange();
				((BaseUnityPlugin)this).Config.Save();
				SyncTempValuesFromConfig();
			});
			GUI.DrawTexture(new Rect(12f, y, ((Rect)(ref val2)).width - 24f, 44f), (Texture)(object)_rowTex);
			GUI.Label(new Rect(24f, y + 11f, ((Rect)(ref val2)).width - 48f, 24f), $"当前范围:{ModConfig.WaitTimeMin.Value}s ~ {ModConfig.WaitTimeMax.Value}s", _labelStyle);
			y += 56f;
			DrawToggleRow("最后一关熔炉允许龙卷风", ref y, ((Rect)(ref val2)).width, ModConfig.EnableTornadoAtKiln);
			GUI.Label(new Rect(12f, y, ((Rect)(ref val2)).width - 24f, 78f), $"GUI 热键:{ModConfig.ToggleGuiKey.Value}\n" + "关闭总开关后,随机箱子和随机事件都会停止。\n关闭“随机箱子”只影响掉落;关闭“随机事件”只影响事件。\n晒伤 / 烈日持续时间已从界面隐藏,只保留在配置文件中。", _hintStyle);
			GUI.EndScrollView();
			if (GUI.Button(new Rect(16f, height - 44f, 120f, 30f), "恢复默认", _buttonStyle))
			{
				ResetSimpleDefaults();
				SyncTempValuesFromConfig();
			}
			if (GUI.Button(new Rect(width - 116f, height - 44f, 100f, 30f), "关闭", _buttonStyle))
			{
				_showSettingsGUI = false;
			}
			GUI.DragWindow(new Rect(0f, 0f, width, 52f));
		}

		private void DrawSectionLabel(string text, ref float y, float width)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect(12f, y, width - 24f, 26f), text, _sectionStyle);
			y += 32f;
		}

		private void DrawToggleRow(string label, ref float y, float width, ConfigEntry<bool> entry)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(12f, y, width - 24f, 42f), (Texture)(object)_rowTex);
			GUI.Label(new Rect(24f, y + 9f, width - 160f, 24f), label, _labelStyle);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(width - 118f, y + 5f, 82f, 32f);
			GUIStyle val2 = (entry.Value ? _switchOnStyle : _switchOffStyle);
			string text = (entry.Value ? "ON" : "OFF");
			if (GUI.Button(val, text, val2))
			{
				entry.Value = !entry.Value;
				((BaseUnityPlugin)this).Config.Save();
			}
			y += 50f;
		}

		private void DrawTextFieldRow(string label, ref float y, float width, ref string tempValue, Action<string> onChanged, Action<int> onStep, int step = 5)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(12f, y, width - 24f, 42f), (Texture)(object)_rowTex);
			GUI.Label(new Rect(24f, y + 9f, width - 230f, 24f), label, _labelStyle);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(width - 196f, y + 6f, 32f, 28f);
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(width - 158f, y + 6f, 94f, 28f);
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(width - 58f, y + 6f, 32f, 28f);
			if (GUI.Button(val, "-", _buttonStyle))
			{
				onStep(-Mathf.Abs(step));
				GUI.FocusControl((string)null);
			}
			GUIStyle val4 = (((Rect)(ref val2)).Contains(Event.current.mousePosition) ? _textFieldHoverStyle : _textFieldStyle);
			string text = GUI.TextField(val2, tempValue, val4);
			if (text != tempValue)
			{
				tempValue = text;
				onChanged(text);
			}
			if (GUI.Button(val3, "+", _buttonStyle))
			{
				onStep(Mathf.Abs(step));
				GUI.FocusControl((string)null);
			}
			y += 50f;
		}

		private void SyncTempValuesFromConfig()
		{
			_tempWaitTimeMin = ModConfig.WaitTimeMin.Value.ToString();
			_tempWaitTimeMax = ModConfig.WaitTimeMax.Value.ToString();
		}

		private void ResetSimpleDefaults()
		{
			ModConfig.ShowSettingsButton.Value = true;
			ModConfig.EnableChaosMaster.Value = true;
			ModConfig.EnableItemRandomization.Value = true;
			ModConfig.EnableRandomEvents.Value = true;
			ModConfig.EnableTornadoAtKiln.Value = false;
			ModConfig.WaitTimeMin.Value = 30;
			ModConfig.WaitTimeMax.Value = 60;
			ModConfig.TropicsRain.Value = 18;
			ModConfig.RootsWindRandom.Value = 25;
			ModConfig.AlpineSnowRandom.Value = 22;
			ModConfig.MesaSunRandom.Value = 20;
			ModConfig.PitonPatch.Value = 35;
			ModConfig.ChainCache.Value = 22;
			ModConfig.ToxicBounceShroom.Value = 28;
			ModConfig.LowGravityShroom.Value = 18;
			ModConfig.SleepySpores.Value = 12;
			ModConfig.FungusCloud.Value = 14;
			ClampTimeRange();
			((BaseUnityPlugin)this).Config.Save();
		}

		private void ClampTimeRange()
		{
			if (ModConfig.WaitTimeMin.Value < 1)
			{
				ModConfig.WaitTimeMin.Value = 1;
			}
			if (ModConfig.WaitTimeMax.Value < ModConfig.WaitTimeMin.Value)
			{
				ModConfig.WaitTimeMax.Value = ModConfig.WaitTimeMin.Value;
			}
		}

		private void EnsureGuiStyles()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Expected O, but got Unknown
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Expected O, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Expected O, but got Unknown
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Expected O, but got Unknown
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Expected O, but got Unknown
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Expected O, but got Unknown
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0623: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Expected O, but got Unknown
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Expected O, but got Unknown
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d8: Expected O, but got Unknown
			//IL_07b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07da: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0810: Unknown result type (might be due to invalid IL or missing references)
			//IL_0822: Unknown result type (might be due to invalid IL or missing references)
			//IL_0834: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_0850: Expected O, but got Unknown
			//IL_08a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0909: Unknown result type (might be due to invalid IL or missing references)
			//IL_0913: Expected O, but got Unknown
			//IL_091f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0929: Expected O, but got Unknown
			//IL_0979: Unknown result type (might be due to invalid IL or missing references)
			//IL_098f: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ec: Expected O, but got Unknown
			//IL_09f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a02: Expected O, but got Unknown
			//IL_0a52: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a68: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a7e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0abb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac5: Expected O, but got Unknown
			if (_buttonStyle == null)
			{
				_btnTex = MakeTexture(2, 2, new Color(0.16f, 0.45f, 0.86f, 1f));
				_btnHoverTex = MakeTexture(2, 2, new Color(0.1f, 0.35f, 0.75f, 1f));
				_windowTex = MakeTexture(2, 2, new Color(0.97f, 0.98f, 1f, 1f));
				_fieldTex = MakeTexture(2, 2, new Color(1f, 1f, 1f, 1f));
				_accentTex = MakeTexture(2, 2, new Color(0.1f, 0.3f, 0.62f, 1f));
				_rowTex = MakeTexture(2, 2, new Color(0.9f, 0.94f, 0.99f, 1f));
				_switchOnTex = MakeTexture(2, 2, new Color(0.12f, 0.62f, 0.29f, 1f));
				_switchOnHoverTex = MakeTexture(2, 2, new Color(0.08f, 0.54f, 0.24f, 1f));
				_switchOffTex = MakeTexture(2, 2, new Color(0.42f, 0.48f, 0.56f, 1f));
				_switchOffHoverTex = MakeTexture(2, 2, new Color(0.34f, 0.4f, 0.48f, 1f));
				_dimTex = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.42f));
				_buttonStyle = new GUIStyle(GUI.skin.button);
				_buttonStyle.normal.background = _btnTex;
				_buttonStyle.hover.background = _btnHoverTex;
				_buttonStyle.active.background = _btnHoverTex;
				_buttonStyle.normal.textColor = Color.white;
				_buttonStyle.hover.textColor = Color.white;
				_buttonStyle.active.textColor = Color.white;
				_buttonStyle.fontSize = 15;
				_buttonStyle.fontStyle = (FontStyle)1;
				_buttonStyle.alignment = (TextAnchor)4;
				_buttonStyle.border = new RectOffset(0, 0, 0, 0);
				_buttonStyle.padding = new RectOffset(8, 8, 4, 4);
				_windowStyle = new GUIStyle(GUI.skin.window);
				_windowStyle.normal.background = _windowTex;
				_windowStyle.onNormal.background = _windowTex;
				_windowStyle.border = new RectOffset(0, 0, 0, 0);
				_windowStyle.padding = new RectOffset(0, 0, 0, 0);
				_titleStyle = new GUIStyle(GUI.skin.label);
				_titleStyle.fontSize = 19;
				_titleStyle.fontStyle = (FontStyle)1;
				_titleStyle.normal.textColor = Color.white;
				_titleStyle.alignment = (TextAnchor)3;
				_sectionStyle = new GUIStyle(GUI.skin.label);
				_sectionStyle.fontSize = 16;
				_sectionStyle.fontStyle = (FontStyle)1;
				_sectionStyle.normal.textColor = new Color(0.08f, 0.24f, 0.48f, 1f);
				_labelStyle = new GUIStyle(GUI.skin.label);
				_labelStyle.fontSize = 15;
				_labelStyle.normal.textColor = new Color(0.12f, 0.18f, 0.26f, 1f);
				_labelStyle.alignment = (TextAnchor)3;
				_hintStyle = new GUIStyle(GUI.skin.label);
				_hintStyle.fontSize = 13;
				_hintStyle.normal.textColor = new Color(0.22f, 0.28f, 0.36f, 1f);
				_textFieldStyle = new GUIStyle(GUI.skin.textField);
				_textFieldStyle.normal.background = _fieldTex;
				_textFieldStyle.hover.background = _fieldTex;
				_textFieldStyle.focused.background = _fieldTex;
				_textFieldStyle.active.background = _fieldTex;
				_textFieldStyle.onNormal.background = _fieldTex;
				_textFieldStyle.onHover.background = _fieldTex;
				_textFieldStyle.onFocused.background = _fieldTex;
				_textFieldStyle.onActive.background = _fieldTex;
				_textFieldStyle.normal.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.hover.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.focused.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.active.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.onNormal.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.onHover.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.onFocused.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.onActive.textColor = new Color(0.1f, 0.14f, 0.2f, 1f);
				_textFieldStyle.fontSize = 15;
				_textFieldStyle.alignment = (TextAnchor)4;
				_textFieldStyle.border = new RectOffset(0, 0, 0, 0);
				_textFieldStyle.padding = new RectOffset(6, 6, 4, 4);
				_textFieldHoverStyle = new GUIStyle(_textFieldStyle);
				Color textColor = default(Color);
				((Color)(ref textColor))..ctor(0.07f, 0.26f, 0.64f, 1f);
				_textFieldHoverStyle.normal.background = _fieldTex;
				_textFieldHoverStyle.hover.background = _fieldTex;
				_textFieldHoverStyle.focused.background = _fieldTex;
				_textFieldHoverStyle.active.background = _fieldTex;
				_textFieldHoverStyle.onNormal.background = _fieldTex;
				_textFieldHoverStyle.onHover.background = _fieldTex;
				_textFieldHoverStyle.onFocused.background = _fieldTex;
				_textFieldHoverStyle.onActive.background = _fieldTex;
				_textFieldHoverStyle.normal.textColor = textColor;
				_textFieldHoverStyle.hover.textColor = textColor;
				_textFieldHoverStyle.focused.textColor = textColor;
				_textFieldHoverStyle.active.textColor = textColor;
				_textFieldHoverStyle.onNormal.textColor = textColor;
				_textFieldHoverStyle.onHover.textColor = textColor;
				_textFieldHoverStyle.onFocused.textColor = textColor;
				_textFieldHoverStyle.onActive.textColor = textColor;
				_switchOnStyle = new GUIStyle(GUI.skin.button);
				_switchOnStyle.normal.background = _switchOnTex;
				_switchOnStyle.hover.background = _switchOnHoverTex;
				_switchOnStyle.active.background = _switchOnHoverTex;
				_switchOnStyle.normal.textColor = Color.white;
				_switchOnStyle.hover.textColor = Color.white;
				_switchOnStyle.active.textColor = Color.white;
				_switchOnStyle.fontSize = 15;
				_switchOnStyle.fontStyle = (FontStyle)1;
				_switchOnStyle.alignment = (TextAnchor)4;
				_switchOnStyle.border = new RectOffset(0, 0, 0, 0);
				_switchOffStyle = new GUIStyle(GUI.skin.button);
				_switchOffStyle.normal.background = _switchOffTex;
				_switchOffStyle.hover.background = _switchOffHoverTex;
				_switchOffStyle.active.background = _switchOffHoverTex;
				_switchOffStyle.normal.textColor = Color.white;
				_switchOffStyle.hover.textColor = Color.white;
				_switchOffStyle.active.textColor = Color.white;
				_switchOffStyle.fontSize = 15;
				_switchOffStyle.fontStyle = (FontStyle)1;
				_switchOffStyle.alignment = (TextAnchor)4;
				_switchOffStyle.border = new RectOffset(0, 0, 0, 0);
				_closeStyle = new GUIStyle(GUI.skin.button);
				_closeStyle.normal.background = _btnTex;
				_closeStyle.hover.background = _btnHoverTex;
				_closeStyle.active.background = _btnHoverTex;
				_closeStyle.normal.textColor = Color.white;
				_closeStyle.hover.textColor = Color.white;
				_closeStyle.active.textColor = Color.white;
				_closeStyle.fontSize = 14;
				_closeStyle.fontStyle = (FontStyle)1;
				_closeStyle.alignment = (TextAnchor)4;
				_closeStyle.border = new RectOffset(0, 0, 0, 0);
			}
		}

		private static Texture2D MakeTexture(int width, int height, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height, (TextureFormat)5, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = color;
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private static void SafeDestroy(ref Texture2D tex)
		{
			if ((Object)(object)tex != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)tex);
				tex = null;
			}
		}
	}
	public static class RandomEventTask
	{
		private static Coroutine? _routine;

		private static readonly Random Rng = new Random();

		public static int ShouldStopTask = 1;

		public static bool IsRunning => _routine != null;

		public static void EnsureStarted()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value)
				{
					StopTask();
				}
				else if (_routine == null)
				{
					StartTask();
				}
			}
		}

		public static void StartTask()
		{
			if (PhotonNetwork.IsMasterClient && ModConfig.EnableChaosMaster.Value && ModConfig.EnableRandomEvents.Value && !((Object)(object)Plugin.Instance == (Object)null) && _routine == null)
			{
				Interlocked.Exchange(ref ShouldStopTask, 0);
				RandomizerEvents.SkeletonEventActive = false;
				_routine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(RandomEventLoop());
			}
		}

		public static void StopTask()
		{
			Interlocked.Exchange(ref ShouldStopTask, 1);
			if (_routine != null && (Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StopCoroutine(_routine);
			}
			_routine = null;
			RandomizerEvents.ClearPendingQueues();
			Plugin.Log.LogInfo((object)"Stopped random event coroutine.");
		}

		private static IEnumerator RandomEventLoop()
		{
			Plugin.Log.LogInfo((object)"Starting random event coroutine.");
			while (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) == 0 && PhotonNetwork.IsMasterClient && Plugin.IsGameplayScene() && ModConfig.EnableChaosMaster.Value && ModConfig.EnableRandomEvents.Value)
			{
				int min = Mathf.Max(1, ModConfig.WaitTimeMin.Value);
				int max = Mathf.Max(min, ModConfig.WaitTimeMax.Value);
				int waitSeconds;
				lock (Rng)
				{
					waitSeconds = Rng.Next(min, max + 1);
				}
				float remaining = waitSeconds;
				while (remaining > 0f)
				{
					if (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) != 0 || !PhotonNetwork.IsMasterClient || !Plugin.IsGameplayScene() || !ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value)
					{
						_routine = null;
						RandomizerEvents.ClearPendingQueues();
						yield break;
					}
					int currentMax = Mathf.Max(1, ModConfig.WaitTimeMax.Value);
					if (remaining > (float)currentMax)
					{
						remaining = currentMax;
					}
					remaining -= Time.deltaTime;
					yield return null;
				}
				try
				{
					RandomizerEvents.QueueRandomEvent();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Queue random event error: {arg}");
				}
				yield return null;
			}
			_routine = null;
			RandomizerEvents.ClearPendingQueues();
			Plugin.Log.LogInfo((object)"Stopped random event coroutine.");
		}
	}
	public static class RandomizerEvents
	{
		internal static class BP
		{
			public const BodypartType Torso = (BodypartType)2;

			public const BodypartType Head = (BodypartType)4;

			public const BodypartType LeftFoot = (BodypartType)13;

			public const BodypartType LeftHand = (BodypartType)14;

			public const BodypartType RightFoot = (BodypartType)16;
		}

		private const int MaxPendingEvents = 128;

		private const int MaxPendingDestroy = 2048;

		private static readonly object EventQueueLock = new object();

		private static readonly Queue<string> EventQueue = new Queue<string>();

		private static readonly object DestroyQueueLock = new object();

		private static readonly Queue<GameObject> DestroyQueue = new Queue<GameObject>();

		private static float _nextScheduledFlushAt;

		public static bool SkeletonEventActive = false;

		public static Vector3 OutOfSight = new Vector3(0f, -9999f, 0f);

		private static readonly object ScheduleLock = new object();

		private static readonly List<(string eventName, DateTime dueUtc)> ScheduledEvents = new List<(string, DateTime)>();

		private static readonly List<(GameObject obj, DateTime dueUtc)> ScheduledDestroy = new List<(GameObject, DateTime)>();

		private static int _currentImmediateEventDepth = 0;

		private const int MaxImmediateEventDepth = 4;

		private static ClimbingSpikeComponent? _cachedClimbingSpikeComponent;

		private static RopeShooter? _cachedRopeShooterTemplate;

		private static string _cachedChainShooterItemName = string.Empty;

		private static int _roundRobinCursor = 0;

		public static readonly List<(string name, ConfigEntry<int>? weightConfigEntry, Action action)> Events = new List<(string, ConfigEntry<int>, Action)>
		{
			("Tornado", ModConfig.Tornado, delegate
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Expected O, but got Unknown
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0110: Expected O, but got Unknown
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Expected O, but got Unknown
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < 10; i++)
				{
					if (!TryGetRandomCharacter(out Character character))
					{
						return;
					}
					Vector3 center = character.Center;
					int num = ((Random.Range(0, 2) == 0) ? 1 : (-1));
					center += new Vector3((float)(num * Random.Range(100, 600)), 0f, (float)(num * Random.Range(100, 600)));
					if (Physics.CheckSphere(center, 50f))
					{
						GameObject val = SafeInstantiateNetwork("Tornado", center, Quaternion.identity);
						if ((Object)(object)val != (Object)null)
						{
							Tornado component = val.GetComponent<Tornado>();
							if ((Object)(object)component == (Object)null)
							{
								Plugin.Log.LogWarning((object)"Tornado skipped: Tornado component missing.");
								RemoveObjectAfterTime(val, 0f);
							}
							else
							{
								GameObject val2 = new GameObject("ChaosTornadoTarget");
								Object.Destroy((Object)(object)val2, 300f);
								val2.transform.position = character.Center;
								GameObject val3 = new GameObject("ChaosTornadoPoints");
								Object.Destroy((Object)(object)val3, 300f);
								val3.transform.position = character.Center;
								for (int j = 0; j < 8; j++)
								{
									float num2 = (float)j * MathF.PI * 2f / 8f;
									GameObject val4 = new GameObject($"Point_{j}");
									val4.transform.SetParent(val3.transform, false);
									val4.transform.localPosition = new Vector3(Mathf.Cos(num2) * 18f, 0f, Mathf.Sin(num2) * 18f);
								}
								component.target = val2.transform;
								try
								{
									AccessTools.Field(typeof(Tornado), "targetParent")?.SetValue(component, val3.transform);
								}
								catch (Exception arg)
								{
									Plugin.Log.LogWarning((object)$"Tornado targetParent init failed; RuntimeSafetyPatch will guard PickTarget: {arg}");
								}
								RemoveObjectAfterTime(val, 60f);
							}
							return;
						}
					}
				}
				ForceEvent("Pandora");
			}),
			("Tick", ModConfig.Tick, delegate
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				List<Character> list = PickRandomHumans(1, 4);
				if (list.Count == 0)
				{
					return;
				}
				foreach (Character item2 in list)
				{
					GameObject val = SafeInstantiateNetwork("BugfixOnYou", Vector3.zero, Quaternion.identity);
					PhotonView val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<PhotonView>() : null);
					if ((Object)(object)val2 != (Object)null && (Object)(object)((MonoBehaviourPun)item2).photonView != (Object)null)
					{
						val2.RPC("AttachBug", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)item2).photonView.ViewID });
					}
					else if ((Object)(object)val != (Object)null)
					{
						RemoveObjectAfterTime(val, 0f);
					}
				}
			}),
			("Bees", ModConfig.Bees, delegate
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				foreach (Character rotatingHuman in GetRotatingHumans())
				{
					int num = RandomCountInclusive(3);
					for (int i = 0; i < num; i++)
					{
						Vector3 position = GetCharacterTransform(rotatingHuman, (BodypartType)4).position + new Vector3(Random.Range(-0.8f, 0.8f), Random.Range(0.2f, 1.2f), Random.Range(-0.8f, 0.8f));
						GameObject val = SafeInstantiateNetwork("BeeSwarm", position, Quaternion.identity);
						BeeSwarm val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<BeeSwarm>() : null);
						if ((Object)(object)val2 != (Object)null && (Object)(object)((MonoBehaviourPun)val2).photonView != (Object)null)
						{
							((MonoBehaviourPun)val2).photonView.RPC("SetBeesAngryRPC", (RpcTarget)3, new object[1] { true });
							RemoveObjectAfterTime(val, 3f);
						}
						else if ((Object)(object)val != (Object)null)
						{
							RemoveObjectAfterTime(val, 0f);
						}
					}
				}
			}),
			("Tumbleweed", ModConfig.Tumbleweed, delegate
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				foreach (Character rotatingHuman2 in GetRotatingHumans())
				{
					Vector3 val = GetCharacterTransform(rotatingHuman2, (BodypartType)14).position;
					int num = RandomCountFromOriginalRange(2, 5);
					for (int i = 0; i < num; i++)
					{
						int num2 = ((Random.Range(0, 2) == 0) ? 1 : (-1));
						int num3 = ((Random.Range(0, 2) == 0) ? 1 : (-1));
						val += new Vector3((float)(num2 * Random.Range(1, 10)), 0f, (float)(num3 * Random.Range(1, 10)));
						if (Physics.CheckSphere(val, 10f))
						{
							GameObject obj = SafeInstantiateNetwork("TumbleWeed", val, Quaternion.identity);
							RemoveObjectAfterTime(obj, 15f);
						}
					}
				}
			}),
			("Dynamite", ModConfig.Dynamite, delegate
			{
				List<Character> list = (from x in PickRandomHumans(1, 4)
					where CanReceiveSpawnedItems(x)
					select x).ToList();
				if (list.Count == 0)
				{
					return;
				}
				bool extendedFuse = Random.Range(0f, 1f) < Mathf.Clamp(ModConfig.ExtendedDynamiteChance.Value, 0f, 1f);
				foreach (Character item3 in list)
				{
					GiveDynamiteToCharacter(item3, extendedFuse);
				}
			}),
			("Zombie", ModConfig.Zombie, delegate
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				if (TryGetRandomCharacter(out Character character))
				{
					Vector3 pos = GetCharacterTransform(character, (BodypartType)2).position;
					MushroomZombie[] source = Object.FindObjectsByType<MushroomZombie>((FindObjectsSortMode)0);
					if (!source.Any((MushroomZombie z) => (Object)(object)z != (Object)null && Vector3.Distance(((Component)z).transform.position, pos) <= 30f) && Physics.CheckSphere(pos, 5f))
					{
						GameObject obj = SafeInstantiateNetwork("MushroomZombie", pos, Quaternion.identity);
						RemoveObjectAfterTime(obj, 25f);
					}
				}
			}),
			("Mandrake", ModConfig.Mandrake, delegate
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				List<Character> list = PickRandomHumans(1, 4);
				if (list.Count == 0)
				{
					return;
				}
				Mandrake[] source = Object.FindObjectsByType<Mandrake>((FindObjectsSortMode)0);
				List<Vector3> list2 = new List<Vector3>();
				foreach (Character item4 in list)
				{
					if (TryGetCharacterTransform(item4, (BodypartType)4, out Transform transform))
					{
						Vector3 pos = transform.position;
						if (!source.Any((Mandrake m) => (Object)(object)m != (Object)null && Vector3.Distance(((Component)