Decompiled source of PeakRandomizedChaos v1.1.5

PeakRandomizedChaos.dll

Decompiled a week 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.1.5.0")]
[assembly: AssemblyInformationalVersion("1.1.5")]
[assembly: AssemblyProduct("PeakRandomizedChaos")]
[assembly: AssemblyTitle("PeakRandomizedChaos")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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
{
	[BepInPlugin("PeakRandomizedChaos", "Chaos", "1.1.5")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "PeakRandomizedChaos";

		public const string ModName = "Chaos";

		public const string ModVersion = "1.1.5";

		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(AchievementManagerPatch));
			_harmony.PatchAll(typeof(SpecialHeldItemPatch));
			_harmony.PatchAll(typeof(RescueHookDestroyPatch));
			_harmony.PatchAll(typeof(DayNightManagerBootstrapPatch));
			_harmony.PatchAll(typeof(WindChillZonePatch));
			_harmony.PatchAll(typeof(HotSunPatch));
			_harmony.PatchAll(typeof(TornadoCompatibilityPatch));
			_harmony.PatchAll(typeof(ItemOptimizationCompatibilityPatch));
			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();
				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 result2))
				{
					ModConfig.WaitTimeMin.Value = Mathf.Max(1, result2);
					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.MesaSunDurationMin.Value = 10;
			ModConfig.MesaSunDurationMax.Value = 30;
			ModConfig.TropicsRain.Value = 0;
			ModConfig.RootsWindRandom.Value = 0;
			ModConfig.AlpineSnowRandom.Value = 0;
			ModConfig.MesaSunRandom.Value = 0;
			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();
			ClampSunDurationRange();
			((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 ClampSunDurationRange()
		{
			if (ModConfig.MesaSunDurationMin.Value < 1)
			{
				ModConfig.MesaSunDurationMin.Value = 1;
			}
			if (ModConfig.MesaSunDurationMax.Value < ModConfig.MesaSunDurationMin.Value)
			{
				ModConfig.MesaSunDurationMax.Value = ModConfig.MesaSunDurationMin.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 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<int> MesaSunDurationMin { get; private set; }

		public static ConfigEntry<int> MesaSunDurationMax { 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.");
			MesaSunDurationMin = config.Bind<int>("Events.Settings", "MesaSunDurationMin", 10, "Minimum duration in seconds for random global hot sun / sunburn event.");
			MesaSunDurationMax = config.Bind<int>("Events.Settings", "MesaSunDurationMax", 30, "Maximum duration in seconds for random global hot sun / sunburn event.");
			TropicsRain = config.Bind<int>("Events.Weights", "TropicsRain", 0, "Default 0 = disabled unless explicitly enabled.");
			RootsWindRandom = config.Bind<int>("Events.Weights", "RootsWindRandom", 0, "Default 0 = disabled unless explicitly enabled.");
			AlpineSnowRandom = config.Bind<int>("Events.Weights", "AlpineSnowRandom", 0, "Default 0 = disabled unless explicitly enabled.");
			MesaSunRandom = config.Bind<int>("Events.Weights", "MesaSunRandom", 0, "Default 0 = disabled unless explicitly enabled.");
			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 == 35 && RootsWindRandom.Value == 35 && AlpineSnowRandom.Value == 25 && MesaSunRandom.Value == 30)
			{
				TropicsRain.Value = 0;
				RootsWindRandom.Value = 0;
				AlpineSnowRandom.Value = 0;
				MesaSunRandom.Value = 0;
				config.Save();
			}
		}
	}
	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>? _availableAllItemsCache;

		private static Dictionary<ushort, Item>? _availableLootItemsCache;

		private static Dictionary<ushort, Item>? _availableBushItemsCache;

		private static Dictionary<ushort, Item>? _availableEventItemsCache;

		private static bool _availableCachesDirty = true;

		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 void ResetRuntimeState()
		{
			lock (CacheLock)
			{
				SpawnedCountByItemName.Clear();
				_baseFilteredAllCache = null;
				_baseFilteredLootCache = null;
				_baseFilteredBushCache = null;
				_baseFilteredEventCache = 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)
		{
			string itemName2 = itemName;
			if (ExcludedItemNames.Contains(itemName2))
			{
				return true;
			}
			if (ExcludedItemPrefixes.Any((string prefix) => itemName2.StartsWith(prefix)))
			{
				return true;
			}
			if (ExcludedItemSuffixes.Any((string suffix) => itemName2.EndsWith(suffix)))
			{
				return true;
			}
			if (MaxSpawnCountByItemName.TryGetValue(itemName2, 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))
			{
				if (!SpawnedCountByItemName.ContainsKey(itemName))
				{
					SpawnedCountByItemName[itemName] = 0;
				}
				SpawnedCountByItemName[itemName]++;
				_availableCachesDirty = true;
			}
		}

		public static Dictionary<ushort, Item> GetHangingItemsDatabaseFiltered()
		{
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			return 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);
		}

		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 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;
			}
			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;
			}
			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 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--;
			}
		}

		[HarmonyPatch(typeof(LootData), "GetRandomItem")]
		[HarmonyPrefix]
		private static bool PrefixGetRandomItem(SpawnPool spawnPool, ref GameObject __result)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected I4, but got Unknown
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			int num = (int)spawnPool;
			if (num == 131072 || num == 32768 || num == 65536)
			{
				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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			int num = (int)spawnPool;
			if (num == 131072 || num == 32768 || num == 65536)
			{
				return true;
			}
			if (LootData.AllSpawnWeightData == null)
			{
				LootData.PopulateLootData();
			}
			__result = new List<GameObject>(count);
			for (int i = 0; i < count; i++)
			{
				if (CustomLoot.TryGetRandomLootItem(out Item item))
				{
					CustomLoot.MarkSpawned(((Object)item).name);
					__result.Add(((Component)item).gameObject);
				}
			}
			return __result.Count <= 0;
		}

		[HarmonyPatch(typeof(SpawnList), "GetSpawns")]
		[HarmonyPrefix]
		private static bool PrefixSpawnListGetSpawns(int count, bool canRepeat, ref List<GameObject> __result)
		{
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				return true;
			}
			__result = new List<GameObject>(count);
			for (int i = 0; i < count; i++)
			{
				if (CustomLoot.TryGetRandomLootItem(out Item item))
				{
					CustomLoot.MarkSpawned(((Object)item).name);
					__result.Add(((Component)item).gameObject);
				}
			}
			return __result.Count <= 0;
		}

		[HarmonyPatch(typeof(SpawnList), "GetSingleSpawn")]
		[HarmonyPrefix]
		private static bool PrefixSpawnListGetSingleSpawn(ref GameObject __result)
		{
			if (!Plugin.IsGameplayScene())
			{
				return true;
			}
			if (!ModConfig.EnableChaosMaster.Value || !ModConfig.EnableItemRandomization.Value)
			{
				return true;
			}
			if (IsGenericLootRandomizationSuppressed())
			{
				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 i = 0; i < num2 && list2.Count != 0; i++)
			{
				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 AchievementManagerPatch
	{
		[HarmonyPatch(typeof(AchievementManager), "ThrowAchievement")]
		[HarmonyPrefix]
		private static bool Prefix(AchievementManager __instance)
		{
			return false;
		}
	}
	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();
				if (PhotonNetwork.IsMasterClient)
				{
					RandomEventTask.StopTask();
					CustomLoot.ResetRuntimeState();
				}
				break;
			}
			return true;
		}
	}
	public static class PauseMenuMainPagePatch
	{
		[HarmonyPatch(typeof(PauseMenuMainPage), "OnQuitClicked")]
		[HarmonyPrefix]
		public static bool Prefix(PauseMenuMainPage __instance)
		{
			ChaosEnvironmentController.ResetLocalState();
			if (PhotonNetwork.IsMasterClient)
			{
				RandomEventTask.StopTask();
				CustomLoot.ResetRuntimeState();
			}
			return true;
		}
	}
	public static class MountainProgressHandlerPatch
	{
		[HarmonyPatch(typeof(MountainProgressHandler), "TriggerReached")]
		[HarmonyPrefix]
		public static bool Prefix(MountainProgressHandler __instance, ProgressPoint progressPoint)
		{
			ChaosEnvironmentController.ResetLocalState();
			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 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();
			List<string> list = RandomizerEvents.DequeueEvents(1);
			foreach (string name in list)
			{
				try
				{
					(string, ConfigEntry<int>, Action) tuple = RandomizerEvents.Events.FirstOrDefault<(string, ConfigEntry<int>, Action)>(((string name, ConfigEntry<int> weightConfigEntry, Action action) e) => e.name == name);
					if (tuple.Item3 == null)
					{
						Plugin.Log.LogWarning((object)("Unknown or empty random event: " + name));
						continue;
					}
					tuple.Item3();
					RandomizerEvents.CleanupOrphanTemporarySlotsForAll("after " + name);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Error when trying to execute {name}: {arg}");
				}
			}
			List<GameObject> list2 = RandomizerEvents.DequeueDestroy(24);
			foreach (GameObject item in list2)
			{
				try
				{
					if (!((Object)(object)item == (Object)null))
					{
						PhotonView component = item.GetComponent<PhotonView>();
						if ((Object)(object)component == (Object)null)
						{
							Object.Destroy((Object)(object)item);
						}
						else
						{
							PhotonNetwork.Destroy(item);
						}
					}
				}
				catch (Exception arg2)
				{
					Plugin.Log.LogWarning((object)$"Destroy queue error: {arg2}");
				}
			}
			return true;
		}
	}
	public static class TornadoCompatibilityPatch
	{
		[HarmonyPatch]
		private static class TornadoFixedUpdatePatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("Tornado");
				return type != null && AccessTools.Method(type, "FixedUpdate", (Type[])null, (Type[])null) != null;
			}

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

			private static bool Prefix(object __instance)
			{
				if (!NeedsFallbackFixedUpdate())
				{
					return true;
				}
				RunFallbackTornadoFixedUpdate(__instance);
				return false;
			}

			private static Exception? Finalizer(object __instance, Exception? __exception)
			{
				if (IsRemovedFallRpcException(__exception))
				{
					RunFallbackTornadoFixedUpdate(__instance);
					return null;
				}
				return __exception;
			}
		}

		[HarmonyPatch]
		private static class TornadoCapturedCharacterPatch
		{
			private static bool Prepare()
			{
				Type type = AccessTools.TypeByName("Tornado");
				return type != null && AccessTools.Method(type, "CapturedCharacter", (Type[])null, (Type[])null) != null;
			}

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

			private static Exception? Finalizer(object __instance, Exception? __exception)
			{
				if (IsRemovedFallRpcException(__exception))
				{
					RunFallbackTornadoFixedUpdate(__instance);
					return null;
				}
				return __exception;
			}
		}

		private const float FallbackMoveSpeed = 18f;

		private const float FallbackAffectRadius = 24f;

		private const float FallbackFallRadius = 9f;

		private const float FallbackPullImpulse = 26f;

		private const float FallbackLiftImpulse = 34f;

		private const float FallbackSpinImpulse = 22f;

		private const float FallbackFallSeconds = 0.85f;

		private const float FallbackFallCooldown = 0.9f;

		private static readonly Dictionary<int, float> NextFallTimeByViewId = new Dictionary<int, float>();

		private static int _warnedFallbackMode;

		private static int _warnedMissingTarget;

		private static MethodInfo? _characterFallMethod;

		private static MethodInfo? _characterAddForceAtPositionMethod;

		private static MethodInfo? CharacterFallMethod
		{
			get
			{
				if ((object)_characterFallMethod == null)
				{
					_characterFallMethod = AccessTools.Method(typeof(Character), "Fall", new Type[2]
					{
						typeof(float),
						typeof(float)
					}, (Type[])null);
				}
				return _characterFallMethod;
			}
		}

		private static MethodInfo? CharacterAddForceAtPositionMethod
		{
			get
			{
				if ((object)_characterAddForceAtPositionMethod == null)
				{
					_characterAddForceAtPositionMethod = AccessTools.Method(typeof(Character), "AddForceAtPosition", new Type[3]
					{
						typeof(Vector3),
						typeof(Vector3),
						typeof(float)
					}, (Type[])null);
				}
				return _characterAddForceAtPositionMethod;
			}
		}

		public static bool CanUseTornadoEvent()
		{
			return true;
		}

		private static bool HasLegacyFallRpcOverload()
		{
			return AccessTools.Method(typeof(Character), "RPCA_Fall", new Type[2]
			{
				typeof(float),
				typeof(PhotonMessageInfo)
			}, (Type[])null) != null;
		}

		private static bool NeedsFallbackFixedUpdate()
		{
			return !HasLegacyFallRpcOverload();
		}

		private static bool IsRemovedFallRpcException(Exception? exception)
		{
			if (exception == null)
			{
				return false;
			}
			if (exception is MissingMethodException && exception.Message.IndexOf("Character.RPCA_Fall", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			return exception.InnerException != null && IsRemovedFallRpcException(exception.InnerException);
		}

		private static void LogFallbackOnce(string reason)
		{
			if (Interlocked.Exchange(ref _warnedFallbackMode, 1) == 0)
			{
				Plugin.Log.LogWarning((object)("Tornado compatibility mode active: " + reason + ". The Tornado event is still enabled; only the removed RPCA_Fall overload is replaced with the current Character.Fall/RPCA_Fall(float) path."));
			}
		}

		private static Transform? TryGetTargetTransform(object tornado)
		{
			Type type = tornado.GetType();
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(type, "target");
				if (fieldInfo != null)
				{
					object? value = fieldInfo.GetValue(tornado);
					Transform val = (Transform)((value is Transform) ? value : null);
					if (val != null)
					{
						return val;
					}
				}
				PropertyInfo propertyInfo = AccessTools.Property(type, "target");
				if (propertyInfo != null)
				{
					object? value2 = propertyInfo.GetValue(tornado, null);
					Transform val2 = (Transform)((value2 is Transform) ? value2 : null);
					if (val2 != null)
					{
						return val2;
					}
				}
			}
			catch (Exception arg)
			{
				if (Interlocked.Exchange(ref _warnedMissingTarget, 1) == 0)
				{
					Plugin.Log.LogWarning((object)$"Tornado compatibility could not read target transform: {arg}");
				}
			}
			return null;
		}

		private static bool IsFallbackCharacterUsable(Character character)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)((MonoBehaviourPun)character).photonView == (Object)null || (Object)(object)character.view == (Object)null || (Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.items == (Object)null)
			{
				return false;
			}
			if (!character.IsPlayerControlled || character.isBot || character.isZombie || character.isScoutmaster)
			{
				return false;
			}
			if (!character.IsRegisteredToPlayer)
			{
				return false;
			}
			Player player = character.player;
			if ((Object)(object)player == (Object)null || (Object)(object)((MonoBehaviourPun)player).photonView == (Object)null || (Object)(object)player.view == (Object)null || (Object)(object)player.character != (Object)(object)character)
			{
				return false;
			}
			if (character.data.dead || character.data.fullyPassedOut || character.data.isInFog)
			{
				return false;
			}
			return true;
		}

		private static bool TryGetCharacterCenter(Character character, out Vector3 center)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			center = Vector3.zero;
			try
			{
				center = character.Center;
				return true;
			}
			catch
			{
				if ((Object)(object)character != (Object)null && (Object)(object)((Component)character).transform != (Object)null)
				{
					center = ((Component)character).transform.position;
					return true;
				}
			}
			return false;
		}

		private static void ApplyTornadoForce(Character character, Vector3 tornadoPosition, Vector3 characterCenter, float strength)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0031: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = tornadoPosition - characterCenter;
			val.y = 0f;
			Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.zero);
			Vector3 val4;
			if (!(val2 == Vector3.zero))
			{
				Vector3 val3 = Vector3.Cross(Vector3.up, val2);
				val4 = ((Vector3)(ref val3)).normalized;
			}
			else
			{
				val4 = Vector3.zero;
			}
			Vector3 val5 = val4;
			Vector3 val6 = val2 * (26f * strength) + Vector3.up * (34f * strength) + val5 * (22f * strength);
			MethodInfo characterAddForceAtPositionMethod = CharacterAddForceAtPositionMethod;
			if (characterAddForceAtPositionMethod != null)
			{
				try
				{
					characterAddForceAtPositionMethod.Invoke(character, new object[3]
					{
						val6 * Mathf.Max(Time.fixedDeltaTime, 0.015f),
						characterCenter,
						24f
					});
					return;
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"Tornado compatibility AddForceAtPosition failed for {((Object)character).name}: {arg}");
				}
			}
			try
			{
				character.RPCA_AddForceAtPosition(val6 * Mathf.Max(Time.fixedDeltaTime, 0.015f), characterCenter, 24f);
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogWarning((object)$"Tornado compatibility local RPCA_AddForceAtPosition fallback failed for {((Object)character).name}: {arg2}");
			}
		}

		private static void FallCharacterCompat(Character character, float seconds)
		{
			int key = (((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null) ? ((MonoBehaviourPun)character).photonView.ViewID : ((Object)character).GetInstanceID());
			float time = Time.time;
			if (NextFallTimeByViewId.TryGetValue(key, out var value) && time < value)
			{
				return;
			}
			NextFallTimeByViewId[key] = time + 0.9f;
			MethodInfo characterFallMethod = CharacterFallMethod;
			if (characterFallMethod != null)
			{
				try
				{
					characterFallMethod.Invoke(character, new object[2] { seconds, 0f });
					return;
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"Tornado compatibility Character.Fall failed for {((Object)character).name}: {arg}");
				}
			}
			try
			{
				character.refs.view.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { seconds });
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogWarning((object)$"Tornado compatibility RPCA_Fall(float) fallback failed for {((Object)character).name}: {arg2}");
			}
		}

		private static void RunFallbackTornadoFixedUpdate(object tornadoInstance)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0069: 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_006d: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00b5: 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)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			Component val = (Component)((tornadoInstance is Component) ? tornadoInstance : null);
			if (val == null || (Object)(object)val == (Object)null)
			{
				return;
			}
			LogFallbackOnce("Character.RPCA_Fall(float, PhotonMessageInfo) is not present in this game build");
			Transform transform = val.transform;
			Transform val2 = TryGetTargetTransform(tornadoInstance);
			float num = Mathf.Max(Time.fixedDeltaTime, 0.015f);
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 val3 = transform.position;
				Vector3 position = val2.position;
				Vector3 val4 = position - val3;
				val4.y = 0f;
				if (((Vector3)(ref val4)).sqrMagnitude > 0.01f)
				{
					val3 += ((Vector3)(ref val4)).normalized * 18f * num;
				}
				val3.y = Mathf.Lerp(val3.y, position.y, Mathf.Clamp01(num * 2f));
				transform.position = val3;
			}
			transform.Rotate(Vector3.up, 420f * num, (Space)0);
			Character[] array = Character.AllCharacters.ToArray();
			foreach (Character character in array)
			{
				if (!IsFallbackCharacterUsable(character) || !TryGetCharacterCenter(character, out var center))
				{
					continue;
				}
				float num2 = Vector3.Distance(transform.position, center);
				if (!(num2 > 24f))
				{
					float strength = Mathf.Clamp01(1f - num2 / 24f);
					ApplyTornadoForce(character, transform.position, center, strength);
					if (num2 <= 9f)
					{
						FallCharacterCompat(character, 0.85f);
					}
				}
			}
		}
	}
	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);
			}

			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);
			}

			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 RandomEventTask
	{
		[CompilerGenerated]
		private sealed class <RandomEventLoop>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private int <min>5__1;

			private int <max>5__2;

			private int <waitSeconds>5__3;

			private float <remaining>5__4;

			private Random <>s__5;

			private bool <>s__6;

			private Exception <ex>5__7;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Plugin.Log.LogInfo((object)"Starting random event coroutine.");
					goto IL_01bd;
				case 1:
					<>1__state = -1;
					goto IL_015f;
				case 2:
					{
						<>1__state = -1;
						goto IL_01bd;
					}
					IL_01bd:
					if (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) != 0 || !PhotonNetwork.IsMasterClient || !Plugin.IsGameplayScene() || !ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value)
					{
						break;
					}
					<min>5__1 = Mathf.Max(1, ModConfig.WaitTimeMin.Value);
					<max>5__2 = Mathf.Max(<min>5__1, ModConfig.WaitTimeMax.Value);
					<>s__5 = Rng;
					<>s__6 = false;
					try
					{
						Monitor.Enter(<>s__5, ref <>s__6);
						<waitSeconds>5__3 = Rng.Next(<min>5__1, <max>5__2 + 1);
					}
					finally
					{
						if (<>s__6)
						{
							Monitor.Exit(<>s__5);
						}
					}
					<>s__5 = null;
					<remaining>5__4 = <waitSeconds>5__3;
					goto IL_015f;
					IL_015f:
					if (<remaining>5__4 > 0f)
					{
						if (Interlocked.CompareExchange(ref ShouldStopTask, 0, 0) != 0 || !PhotonNetwork.IsMasterClient || !Plugin.IsGameplayScene() || !ModConfig.EnableChaosMaster.Value || !ModConfig.EnableRandomEvents.Value)
						{
							_routine = null;
							RandomizerEvents.ClearPendingQueues();
							return false;
						}
						<remaining>5__4 -= Time.deltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					try
					{
						RandomizerEvents.QueueRandomEvent();
					}
					catch (Exception ex)
					{
						<ex>5__7 = ex;
						Plugin.Log.LogError((object)$"Queue random event error: {<ex>5__7}");
					}
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				_routine = null;
				RandomizerEvents.ClearPendingQueues();
				Plugin.Log.LogInfo((object)"Stopped random event coroutine.");
				return false;
			}

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

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

		private static 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.");
		}

		[IteratorStateMachine(typeof(<RandomEventLoop>d__8))]
		private static IEnumerator RandomEventLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RandomEventLoop>d__8(0);
		}
	}
	public static class SpecialHeldItemPatch
	{
		private static readonly MethodInfo RescueHookLetGoMethod = AccessTools.Method(typeof(RescueHook), "RPCA_LetGo", (Type[])null, (Type[])null);

		private static bool IsRescueHook(Item item)
		{
			return (Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent<RescueHook>() != (Object)null;
		}

		private static bool IsInfiniteRescueHook(Item item)
		{
			return (Object)(object)item != (Object)null && !string.IsNullOrEmpty(((Object)item).name) && ((Object)item).name.Contains("RescueHook_Infinite", StringComparison.OrdinalIgnoreCase);
		}

		private static void SafeReleaseRescueHook(Item item)
		{
			if (!IsRescueHook(item))
			{
				return;
			}
			RescueHook component = ((Component)item).GetComponent<RescueHook>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			try
			{
				if (Traverse.Create((object)component).Field("isPulling").GetValue<bool>())
				{
					RescueHookLetGoMethod?.Invoke(component, null);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"SafeReleaseRescueHook failed: {arg}");
			}
		}

		[HarmonyPatch(typeof(CharacterItems), "DropItemRpc")]
		[HarmonyPrefix]
		private static void PrefixDropItemRpc(CharacterItems __instance)
		{
			object obj;
			if (__instance == null)
			{
				obj = null;
			}
			else
			{
				Character character = __instance.character;
				if (character == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = character.data;
					obj = ((data != null) ? data.currentItem : null);
				}
			}
			Item val = (Item)obj;
			if ((Object)(object)val != (Object)null)
			{
				SafeReleaseRescueHook(val);
			}
		}

		[HarmonyPatch(typeof(CharacterItems), "DestroyHeldItemRpc")]
		[HarmonyPrefix]
		private static void PrefixDestroyHeldItemRpc(CharacterItems __instance)
		{
			object obj;
			if (__instance == null)
			{
				obj = null;
			}
			else
			{
				Character character = __instance.character;
				if (character == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = character.data;
					obj = ((data != null) ? data.currentItem : null);
				}
			}
			Item val = (Item)obj;
			if ((Object)(object)val != (Object)null)
			{
				SafeReleaseRescueHook(val);
			}
		}

		[HarmonyPatch(typeof(CharacterItems), "EquipSlot")]
		[HarmonyPrefix]
		private static bool PrefixEquipSlot(CharacterItems __instance, Optionable<byte> slotID)
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.character == (Object)null)
			{
				return true;
			}
			Item currentItem = __instance.character.data.currentItem;
			if ((Object)(object)currentItem == (Object)null || !IsInfiniteRescueHook(currentItem))
			{
				return true;
			}
			if (!__instance.currentSelectedSlot.IsSome || __instance.currentSelectedSlot.Value != 250)
			{
				return true;
			}
			if (slotID.IsSome && slotID.Value == 250)
			{
				return true;
			}
			Plugin.Log.LogInfo((object)"Blocked switching away from temp-slot RescueHook_Infinite to prevent auto-drop crash.");
			return false;
		}
	}
	public static class RescueHookDestroyPatch
	{
		private static readonly MethodInfo RescueHookLetGoMethod = AccessTools.Method(typeof(RescueHook), "RPCA_LetGo", (Type[])null, (Type[])null);

		[HarmonyPatch(typeof(RescueHook), "OnDestroy")]
		[HarmonyPrefix]
		private static void Prefix(RescueHook __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				if (Traverse.Create((object)__instance).Field("isPulling").GetValue<bool>())
				{
					RescueHookLetGoMethod?.Invoke(__instance, null);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"RescueHook OnDestroy safe release failed: {arg}");
			}
		}
	}
	public class ChaosEnvironmentSync : MonoBehaviourPun
	{
		private static readonly object MagicBeanVineCleanupLock = new object();

		private static readonly List<(Vector3 center, float radius, float cleanupAt)> LocalMagicBeanVineCleanupJobs = new List<(Vector3, float, float)>();

		public static ChaosEnvironmentSync Instance { get; private set; }

		public static bool MesaSunActive { get; private set; }

		public static float MesaSunRemaining { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			MesaSunActive = false;
			MesaSunRemaining = 0f;
			ChaosEnvironmentController.RestoreLocalWeatherOverrides();
			ClearLocalMagicBeanVineCleanupJobs();
		}

		private void Update()
		{
			Ch