Decompiled source of HazardChaos v0.1.12

plugins/HazardChaos.dll

Decompiled 2 days 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace 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 HazardChaos
{
	[BepInPlugin("com.hazardchaos.mod", "HazardChaos", "0.1.12")]
	public class Plugin : BaseUnityPlugin
	{
		private enum Corner
		{
			TopLeft,
			TopRight,
			BottomLeft,
			BottomRight
		}

		private enum AnchorMode
		{
			HostOnly,
			RandomPlayer,
			RoundRobin,
			NearestToHostCamera
		}

		private enum HazardKind
		{
			Dynamite,
			Tornado,
			Tumbleweed
		}

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

			private object <>2__current;

			public float seconds;

			public GameObject go;

			public Plugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(seconds);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if ((Object)(object)go != (Object)null)
					{
						PhotonView component = go.GetComponent<PhotonView>();
						if ((Object)(object)component != (Object)null && component.IsMine)
						{
							PhotonNetwork.Destroy(go);
						}
						else
						{
							Object.Destroy((Object)(object)go);
						}
					}
					if ((Object)(object)go != (Object)null && plugin._kindOf.TryGetValue(go, out var value))
					{
						if (value == HazardKind.Dynamite)
						{
							plugin.liveDyn.Remove(go);
						}
						if (value == HazardKind.Tornado)
						{
							plugin.liveTor.Remove(go);
						}
						if (value == HazardKind.Tumbleweed)
						{
							plugin.liveTum.Remove(go);
						}
						plugin._kindOf.Remove(go);
					}
					plugin.liveAll.Remove(go);
					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();
			}
		}

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

			private object <>2__current;

			public float totalSpreadSec;

			public int count;

			public Plugin <>4__this;

			public HazardKind kind;

			private float <step>5__2;

			private int <i>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_01b8: 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_0251: Expected O, but got Unknown
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<step>5__2 = ((totalSpreadSec > 0f && count > 1) ? (totalSpreadSec / (float)(count - 1)) : 0f);
					<i>5__3 = 0;
					break;
				case 1:
					<>1__state = -1;
					goto IL_027a;
				case 2:
					{
						<>1__state = -1;
						goto IL_027a;
					}
					IL_027a:
					<i>5__3++;
					break;
				}
				if (<i>5__3 < count)
				{
					int num2 = ((PhotonNetwork.CurrentRoom == null) ? 1 : PhotonNetwork.CurrentRoom.PlayerCount);
					int num3 = Math.Max(0, num2 - 1) * Math.Max(0, plugin.mpPerPlayerExtraSlots.Value);
					int num4 = plugin.maxSimultaneousGlobal.Value + num3;
					int num5 = plugin.maxDynamite.Value + num3;
					int num6 = plugin.maxTornado.Value + num3;
					int num7 = plugin.maxTumbleweed.Value + num3;
					if (plugin.liveAll.Count >= num4)
					{
						return false;
					}
					if (kind == HazardKind.Dynamite && plugin.liveDyn.Count >= num5)
					{
						return false;
					}
					if (kind == HazardKind.Tornado && plugin.liveTor.Count >= num6)
					{
						return false;
					}
					if (kind == HazardKind.Tumbleweed && plugin.liveTum.Count >= num7)
					{
						return false;
					}
					Vector3? val = null;
					for (int i = 0; i < 3; i++)
					{
						if (val.HasValue)
						{
							break;
						}
						Transform anchor = plugin.PickAnchorByMode();
						float minDist = ((kind == HazardKind.Tornado) ? 10f : 8f);
						float maxDist = ((kind == HazardKind.Tornado) ? 22f : 18f);
						val = plugin.PickSpawnPosNear(anchor, minDist, maxDist, plugin.requireLineOfSight.Value);
					}
					if (val.HasValue)
					{
						GameObject val2 = plugin.Spawn(kind, val.Value);
						if ((Object)(object)val2 != (Object)null)
						{
							plugin.liveAll.Add(val2);
							plugin._kindOf[val2] = kind;
							if (kind == HazardKind.Dynamite)
							{
								plugin.liveDyn.Add(val2);
							}
							if (kind == HazardKind.Tornado)
							{
								plugin.liveTor.Add(val2);
							}
							if (kind == HazardKind.Tumbleweed)
							{
								plugin.liveTum.Add(val2);
							}
						}
					}
					if (<step>5__2 > 0f)
					{
						<>2__current = (object)new WaitForSeconds(<step>5__2);
						<>1__state = 1;
						return true;
					}
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				return false;
			}

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

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

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

			private object <>2__current;

			public Plugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Expected O, but got Unknown
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Expected O, but got Unknown
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Expected O, but got Unknown
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Expected O, but got Unknown
				//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f8: Expected O, but got Unknown
				//IL_023f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0249: Expected O, but got Unknown
				//IL_0594: Unknown result type (might be due to invalid IL or missing references)
				//IL_059e: Expected O, but got Unknown
				int num = <>1__state;
				Plugin plugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					float time = Time.time;
					if (plugin._nextDynaAt < 0f)
					{
						plugin._nextDynaAt = time + Random.Range(0.4f, 1.2f) * plugin.intervalDynamiteSec.Value;
					}
					if (plugin._nextTornAt < 0f)
					{
						plugin._nextTornAt = time + Random.Range(0.4f, 1.2f) * plugin.intervalTornadoSec.Value;
					}
					if (plugin._nextTumbAt < 0f)
					{
						plugin._nextTumbAt = time + Random.Range(0.4f, 1.2f) * plugin.intervalTumbleweedSec.Value;
					}
					break;
				}
				case 2:
					<>1__state = -1;
					break;
				case 3:
					<>1__state = -1;
					break;
				case 4:
					<>1__state = -1;
					break;
				case 5:
					<>1__state = -1;
					break;
				case 6:
					<>1__state = -1;
					break;
				case 7:
					<>1__state = -1;
					break;
				case 8:
					<>1__state = -1;
					break;
				}
				plugin._blockReason = "";
				if (!ShouldRunInScene(plugin._currentScene))
				{
					plugin._blockReason = "Scene blocked";
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 2;
					return true;
				}
				if (!PhotonNetwork.InRoom)
				{
					plugin._blockReason = "Not in room";
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 3;
					return true;
				}
				if (!PhotonNetwork.IsMasterClient)
				{
					plugin._blockReason = "Only host spawns";
					<>2__current = (object)new WaitForSeconds(0.25f);
					<>1__state = 4;
					return true;
				}
				float num2 = Mathf.Max(0f, plugin._sceneEnteredAt + plugin.startProtectionSec.Value - Time.time);
				if (num2 > 0f)
				{
					plugin._blockReason = $"Protection {num2:0.0}s";
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 5;
					return true;
				}
				if (plugin.worldRoot == null)
				{
					plugin.worldRoot = plugin.FindWorldRoot();
				}
				if (!Object.op_Implicit((Object)(object)plugin.worldRoot))
				{
					plugin._blockReason = "WorldRoot missing";
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 6;
					return true;
				}
				plugin.liveAll.RemoveWhere((GameObject g) => (Object)(object)g == (Object)null);
				plugin.liveDyn.RemoveWhere((GameObject g) => (Object)(object)g == (Object)null);
				plugin.liveTor.RemoveWhere((GameObject g) => (Object)(object)g == (Object)null);
				plugin.liveTum.RemoveWhere((GameObject g) => (Object)(object)g == (Object)null);
				int num3 = ((PhotonNetwork.CurrentRoom == null) ? 1 : PhotonNetwork.CurrentRoom.PlayerCount);
				int num4 = Math.Max(0, num3 - 1) * Math.Max(0, plugin.mpPerPlayerExtraSlots.Value);
				int num5 = plugin.maxSimultaneousGlobal.Value + num4;
				int num6 = plugin.maxDynamite.Value + num4;
				int num7 = plugin.maxTornado.Value + num4;
				int num8 = plugin.maxTumbleweed.Value + num4;
				float time2 = Time.time;
				bool flag = false;
				if (time2 >= plugin._nextDynaAt)
				{
					int num9 = Mathf.Max(0, num5 - plugin.liveAll.Count);
					int num10 = Mathf.Max(0, num6 - plugin.liveDyn.Count);
					int num11 = Mathf.Min(new int[3]
					{
						plugin.burstDynamite.Value,
						num9,
						num10
					});
					if (num11 > 0)
					{
						((MonoBehaviour)plugin).StartCoroutine(plugin.SpawnBurst(HazardKind.Dynamite, num11, plugin.burstSpreadSeconds.Value));
						plugin._nextDynaAt = time2 + plugin.intervalDynamiteSec.Value;
						flag = true;
					}
				}
				if (time2 >= plugin._nextTornAt)
				{
					int num12 = Mathf.Max(0, num5 - plugin.liveAll.Count);
					int num13 = Mathf.Max(0, num7 - plugin.liveTor.Count);
					if (num12 > 0 && num13 > 0)
					{
						int num14 = ((!plugin.moreTornados.Value) ? 1 : Mathf.Clamp(plugin.burstTornado.Value, 1, 5));
						num14 = Mathf.Min(new int[3] { num14, num12, num13 });
						if (num14 > 0)
						{
							float totalSpreadSec = (plugin.moreTornados.Value ? plugin.burstSpreadSeconds.Value : 0f);
							((MonoBehaviour)plugin).StartCoroutine(plugin.SpawnBurst(HazardKind.Tornado, num14, totalSpreadSec));
							plugin._nextTornAt = time2 + plugin.intervalTornadoSec.Value;
							flag = true;
						}
					}
				}
				if (time2 >= plugin._nextTumbAt)
				{
					int num15 = Mathf.Max(0, num5 - plugin.liveAll.Count);
					int num16 = Mathf.Max(0, num8 - plugin.liveTum.Count);
					int num17 = Mathf.Min(new int[3]
					{
						plugin.burstTumbleweed.Value,
						num15,
						num16
					});
					if (num17 > 0)
					{
						((MonoBehaviour)plugin).StartCoroutine(plugin.SpawnBurst(HazardKind.Tumbleweed, num17, plugin.burstSpreadSeconds.Value));
						plugin._nextTumbAt = time2 + plugin.intervalTumbleweedSec.Value;
						flag = true;
					}
				}
				if (flag)
				{
					<>2__current = (object)new WaitForSeconds(0.03f);
					<>1__state = 7;
					return true;
				}
				<>2__current = null;
				<>1__state = 8;
				return true;
			}

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

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

		public const string PLUGIN_GUID = "com.hazardchaos.mod";

		public const string PLUGIN_NAME = "HazardChaos";

		public const string PLUGIN_VERSION = "0.1.12";

		private ConfigEntry<float> intervalDynamiteSec;

		private ConfigEntry<float> intervalTornadoSec;

		private ConfigEntry<float> intervalTumbleweedSec;

		private ConfigEntry<int> maxSimultaneousGlobal;

		private ConfigEntry<int> maxDynamite;

		private ConfigEntry<int> maxTornado;

		private ConfigEntry<int> maxTumbleweed;

		private ConfigEntry<int> burstDynamite;

		private ConfigEntry<int> burstTumbleweed;

		private ConfigEntry<float> burstSpreadSeconds;

		private ConfigEntry<bool> moreTornados;

		private ConfigEntry<int> burstTornado;

		private ConfigEntry<float> ttlDynamite;

		private ConfigEntry<float> ttlTornado;

		private ConfigEntry<float> ttlTumbleweed;

		private ConfigEntry<float> tornadoSpeed;

		private ConfigEntry<float> tornadoRetargetSec;

		private ConfigEntry<bool> tornadoUseVanillaAIWhenAvailable;

		private ConfigEntry<bool> tornadoForceModMover;

		private ConfigEntry<bool> requireLineOfSight;

		private ConfigEntry<float> startProtectionSec;

		private ConfigEntry<bool> uiEnabled;

		private ConfigEntry<KeyboardShortcut> uiToggleKey;

		private ConfigEntry<bool> uiVersionWatermarkEnabled;

		private ConfigEntry<KeyboardShortcut> uiVersionToggleKey;

		private ConfigEntry<Corner> uiVersionCorner;

		private ConfigEntry<int> uiVersionFontSize;

		private ConfigEntry<float> uiVersionAlpha;

		private ConfigEntry<int> uiVersionMargin;

		private ConfigEntry<AnchorMode> mpAnchorMode;

		private ConfigEntry<int> mpPerPlayerExtraSlots;

		private const string TORNADO_PREFAB_NAME = "Tornado";

		private const string TUMBLEWEED_PREFAB_NAME = "TumbleWeed";

		private const string DYNAMITE_ITEM_NAME = "Dynamite";

		private ConfigEntry<KeyboardShortcut> keyTornado;

		private ConfigEntry<KeyboardShortcut> keyDynamite;

		private ConfigEntry<KeyboardShortcut> keyTumbleweed;

		private Transform worldRoot;

		private readonly HashSet<GameObject> liveAll = new HashSet<GameObject>();

		private readonly HashSet<GameObject> liveDyn = new HashSet<GameObject>();

		private readonly HashSet<GameObject> liveTor = new HashSet<GameObject>();

		private readonly HashSet<GameObject> liveTum = new HashSet<GameObject>();

		private readonly Dictionary<GameObject, HazardKind> _kindOf = new Dictionary<GameObject, HazardKind>();

		private Coroutine _loop;

		private string _currentScene = "";

		private string _blockReason = "";

		private readonly List<Transform> _cachedAnchors = new List<Transform>();

		private float _lastAnchorRefreshAt = -999f;

		private int _lastKnownPlayerCount = -1;

		private int _roundRobinIndex;

		private float _nextDynaAt = -1f;

		private float _nextTornAt = -1f;

		private float _nextTumbAt = -1f;

		private float _sceneEnteredAt;

		private ConfigEntry<KeyboardShortcut> uiSettingsKey;

		private bool _showSettings;

		private Rect _settingsRect = new Rect(80f, 80f, 560f, 560f);

		private Vector2 _settingsScroll;

		private readonly Dictionary<string, bool> _fold = new Dictionary<string, bool>();

		private ConfigEntry<float> settingsDimAlpha;

		internal static ManualLogSource Log { get; private set; }

		private void RefreshAnchorsIfNeeded()
		{
			//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)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			int num = ((PhotonNetwork.CurrentRoom == null) ? 1 : PhotonNetwork.CurrentRoom.PlayerCount);
			if (Time.time - _lastAnchorRefreshAt < 1f && num == _lastKnownPlayerCount && _cachedAnchors.Count > 0)
			{
				return;
			}
			_cachedAnchors.Clear();
			Scene activeScene = SceneManager.GetActiveScene();
			MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>();
			MonoBehaviour[] array2 = array;
			foreach (MonoBehaviour val in array2)
			{
				if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy && !(((Component)val).gameObject.scene != activeScene) && !(((object)val).GetType().Name != "Character"))
				{
					_cachedAnchors.Add(((Component)val).transform);
				}
			}
			Camera main = Camera.main;
			if (Object.op_Implicit((Object)(object)main) && ((Component)main).gameObject.activeInHierarchy && ((Component)main).gameObject.scene == activeScene && !_cachedAnchors.Contains(((Component)main).transform))
			{
				_cachedAnchors.Add(((Component)main).transform);
			}
			_lastAnchorRefreshAt = Time.time;
			_lastKnownPlayerCount = num;
			if (_roundRobinIndex >= _cachedAnchors.Count)
			{
				_roundRobinIndex = 0;
			}
		}

		private Transform PickAnchorByMode()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			RefreshAnchorsIfNeeded();
			switch (mpAnchorMode.Value)
			{
			case AnchorMode.HostOnly:
				return LocalCam() ?? _cachedAnchors.FirstOrDefault();
			case AnchorMode.RandomPlayer:
				if (_cachedAnchors.Count == 0)
				{
					return LocalCam();
				}
				return _cachedAnchors[Random.Range(0, _cachedAnchors.Count)];
			case AnchorMode.RoundRobin:
			{
				if (_cachedAnchors.Count == 0)
				{
					return LocalCam();
				}
				Transform result2 = _cachedAnchors[_roundRobinIndex];
				_roundRobinIndex = (_roundRobinIndex + 1) % _cachedAnchors.Count;
				return result2;
			}
			default:
			{
				Transform val = LocalCam();
				if (!Object.op_Implicit((Object)(object)val) || _cachedAnchors.Count == 0)
				{
					return val;
				}
				float num = float.MaxValue;
				Transform result = val;
				{
					foreach (Transform cachedAnchor in _cachedAnchors)
					{
						if (Object.op_Implicit((Object)(object)cachedAnchor))
						{
							Vector3 val2 = cachedAnchor.position - val.position;
							float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
							if (sqrMagnitude < num)
							{
								num = sqrMagnitude;
								result = cachedAnchor;
							}
						}
					}
					return result;
				}
			}
			}
			static Transform LocalCam()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				Scene activeScene = SceneManager.GetActiveScene();
				Camera main = Camera.main;
				if (!Object.op_Implicit((Object)(object)main) || !((Component)main).gameObject.activeInHierarchy || !(((Component)main).gameObject.scene == activeScene))
				{
					return null;
				}
				return ((Component)main).transform;
			}
		}

		public Vector3? PickSpawnPosNear(Transform anchor, float minDist = 8f, float maxDist = 18f, bool requireLOS = true)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)anchor))
			{
				return null;
			}
			Vector3 val = anchor.position + Vector3.up * 1.6f;
			Vector3 forward = anchor.forward;
			bool flag = ((Vector3)(ref forward)).sqrMagnitude > 0.05f;
			Vector3 val3;
			RaycastHit val5 = default(RaycastHit);
			RaycastHit val8 = default(RaycastHit);
			for (int i = 0; i < 28; i++)
			{
				float num = (flag ? Random.Range(-90f, 90f) : Random.Range(-180f, 180f));
				Vector3 val2 = (flag ? (Quaternion.Euler(0f, num, 0f) * forward) : (Quaternion.Euler(0f, num, 0f) * Vector3.forward));
				float num2 = Random.Range(minDist, maxDist);
				Vector3 position = anchor.position;
				val3 = new Vector3(val2.x, 0f, val2.z);
				Vector3 val4 = position + ((Vector3)(ref val3)).normalized * num2;
				if (!Physics.Raycast(val4 + Vector3.up * 60f, Vector3.down, ref val5, 200f, -1, (QueryTriggerInteraction)1))
				{
					continue;
				}
				Vector3 val6 = ((RaycastHit)(ref val5)).point + Vector3.up * 0.1f;
				if (Physics.CheckSphere(val6 + Vector3.up * 0.5f, 0.35f, -1, (QueryTriggerInteraction)1))
				{
					continue;
				}
				if (requireLOS)
				{
					Vector3 val7 = val6 - val;
					float magnitude = ((Vector3)(ref val7)).magnitude;
					if (magnitude > 0.5f && Physics.Raycast(val, ((Vector3)(ref val7)).normalized, ref val8, magnitude - 0.5f, -1, (QueryTriggerInteraction)1))
					{
						continue;
					}
				}
				return val6;
			}
			RaycastHit val11 = default(RaycastHit);
			for (int j = 0; j < 10; j++)
			{
				float num3 = Random.Range(-180f, 180f);
				Vector3 val9 = Quaternion.Euler(0f, num3, 0f) * Vector3.forward;
				float num4 = Random.Range(minDist, maxDist);
				Vector3 position2 = anchor.position;
				val3 = new Vector3(val9.x, 0f, val9.z);
				Vector3 val10 = position2 + ((Vector3)(ref val3)).normalized * num4;
				if (Physics.Raycast(val10 + Vector3.up * 60f, Vector3.down, ref val11, 200f, -1, (QueryTriggerInteraction)1))
				{
					return ((RaycastHit)(ref val11)).point + Vector3.up * 0.1f;
				}
			}
			return null;
		}

		public Vector3? PickSpawnPosNearPlayer(float minDist = 10f, float maxDist = 22f, bool requireLOS = false)
		{
			Transform anchor = (Object.op_Implicit((Object)(object)Camera.main) ? ((Component)Camera.main).transform : PickAnchorByMode());
			return PickSpawnPosNear(anchor, minDist, maxDist, requireLOS);
		}

		private Transform FindWorldRoot()
		{
			//IL_0066: 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)
			string[] array = new string[6] { "WorldRoot", "DynamicRoot", "LevelRoot", "Environment", "Hazards", "Map" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				GameObject val = GameObject.Find(text);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val.transform;
				}
			}
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			GameObject? obj = ((IEnumerable<GameObject>)rootGameObjects).FirstOrDefault((Func<GameObject, bool>)((GameObject r) => r.activeInHierarchy && !Object.op_Implicit((Object)(object)r.GetComponentInChildren<Canvas>())));
			if (obj == null)
			{
				return null;
			}
			return obj.transform;
		}

		private void Awake()
		{
			//IL_0303: 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_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			intervalDynamiteSec = ((BaseUnityPlugin)this).Config.Bind<float>("Intervals", "IntervalDynamiteSec", 15f, "Spawn interval for Dynamite (seconds)");
			intervalTornadoSec = ((BaseUnityPlugin)this).Config.Bind<float>("Intervals", "IntervalTornadoSec", 90f, "Spawn interval for Tornado (seconds)");
			intervalTumbleweedSec = ((BaseUnityPlugin)this).Config.Bind<float>("Intervals", "IntervalTumbleweedSec", 12f, "Spawn interval for Tumbleweed (seconds)");
			maxSimultaneousGlobal = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxSimultaneousGlobal", 6, "Global cap across all hazards");
			maxDynamite = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxDynamite", 2, "Max simultaneous Dynamite");
			maxTornado = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxTornado", 1, "Max simultaneous Tornado");
			maxTumbleweed = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxTumbleweed", 3, "Max simultaneous Tumbleweed");
			burstDynamite = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "BurstDynamite", 2, "How many Dynamite to spawn per tick");
			burstTumbleweed = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "BurstTumbleweed", 3, "How many Tumbleweeds to spawn per tick");
			burstSpreadSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "BurstSpreadSeconds", 3f, "Distribute a burst across this duration (0 = spawn instantly)");
			requireLineOfSight = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "RequireLineOfSight", false, "Require LoS from anchor to spawn point");
			startProtectionSec = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "StartProtectionSec", 60f, "Protection window after level load (seconds)");
			ttlDynamite = ((BaseUnityPlugin)this).Config.Bind<float>("TTL", "DynamiteDespawn", 10f, "Lifetime Dynamite (s)");
			ttlTornado = ((BaseUnityPlugin)this).Config.Bind<float>("TTL", "TornadoDespawn", 20f, "Lifetime Tornado (s)");
			ttlTumbleweed = ((BaseUnityPlugin)this).Config.Bind<float>("TTL", "TumbleweedDespawn", 10f, "Lifetime Tumbleweed (s)");
			tornadoSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Tornado", "MoveSpeed", 10f, "Tornado speed (m/s)");
			tornadoRetargetSec = ((BaseUnityPlugin)this).Config.Bind<float>("Tornado", "RetargetSeconds", 3f, "Seconds until new target");
			tornadoUseVanillaAIWhenAvailable = ((BaseUnityPlugin)this).Config.Bind<bool>("Tornado", "UseVanillaWhenAvailable", true, "If a TornadoSpawner exists and can init, use the game's AI");
			tornadoForceModMover = ((BaseUnityPlugin)this).Config.Bind<bool>("Tornado", "ForceModMover", false, "Force using mod's mover even if Vanilla AI is available");
			moreTornados = ((BaseUnityPlugin)this).Config.Bind<bool>("Tornado", "MoreTornados", false, "If ON, Tornado spawns can use burst logic (up to 5 per tick, subject to caps). If OFF, only one per tick.");
			burstTornado = ((BaseUnityPlugin)this).Config.Bind<int>("Tornado", "BurstTornado", 1, "How many Tornados to spawn per tick when MoreTornados is ON (1..5).");
			uiToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Overlay", "HotkeyOverlay", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Toggle UI");
			uiEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Overlay", "SpawnTimerUI", false, "Show per-hazard timers UI");
			uiSettingsKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Overlay", "HotkeySettings", new KeyboardShortcut((KeyCode)292, Array.Empty<KeyCode>()), "Open/close the in-game HazardChaos settings window");
			settingsDimAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("Overlay", "SettingsDimAlpha", 0.55f, "Background dim alpha when settings are open (0..1)");
			uiVersionToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Version", "HotkeyVersion", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Toggle version watermark");
			uiVersionWatermarkEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Version", "WatermarkEnabled", false, "Show version watermark in all scenes");
			uiVersionCorner = ((BaseUnityPlugin)this).Config.Bind<Corner>("Version", "Corner", Corner.TopRight, "Corner for version watermark");
			uiVersionFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Version", "FontSize", 10, "Font size of version watermark");
			uiVersionAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("Version", "Alpha", 0.65f, "Background alpha (0..1) of version watermark");
			uiVersionMargin = ((BaseUnityPlugin)this).Config.Bind<int>("Version", "Margin", 8, "Margin to screen edges (px)");
			mpAnchorMode = ((BaseUnityPlugin)this).Config.Bind<AnchorMode>("Multiplayer", "AnchorMode", AnchorMode.RandomPlayer, "How to pick player anchors");
			mpPerPlayerExtraSlots = ((BaseUnityPlugin)this).Config.Bind<int>("Multiplayer", "PerPlayerExtraSlots", 1, "Extra concurrent slots per additional player (applied to all caps)");
			keyTornado = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "HotkeyTornado", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Spawn Tornado (Host)");
			keyDynamite = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "HotkeyDynamite", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Spawn Dynamite (Host)");
			keyTumbleweed = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "HotkeyTumbleweed", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Spawn Tumbleweed (Host)");
			SceneManager.sceneLoaded += OnSceneLoaded;
			Log.LogInfo((object)"HazardChaos loaded (v0.1.12).");
		}

		private static bool ShouldRunInScene(string sceneName)
		{
			if (string.IsNullOrEmpty(sceneName))
			{
				return false;
			}
			if (sceneName.IndexOf("Airport", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (sceneName.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (sceneName.IndexOf("Pretitle", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (sceneName.StartsWith("Level_", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return false;
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = uiToggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				uiEnabled.Value = !uiEnabled.Value;
			}
			value = uiVersionToggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				uiVersionWatermarkEnabled.Value = !uiVersionWatermarkEnabled.Value;
			}
			value = uiSettingsKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				_showSettings = !_showSettings;
			}
			if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
			{
				value = keyTornado.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Hotkey(HazardKind.Tornado);
				}
				value = keyDynamite.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Hotkey(HazardKind.Dynamite);
				}
				value = keyTumbleweed.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Hotkey(HazardKind.Tumbleweed);
				}
			}
			void Hotkey(HazardKind kind)
			{
				int count = 1;
				float totalSpreadSec = 0f;
				if (kind == HazardKind.Dynamite)
				{
					count = Mathf.Max(1, burstDynamite.Value);
					totalSpreadSec = burstSpreadSeconds.Value;
				}
				if (kind == HazardKind.Tumbleweed)
				{
					count = Mathf.Max(1, burstTumbleweed.Value);
					totalSpreadSec = burstSpreadSeconds.Value;
				}
				if (kind == HazardKind.Tornado)
				{
					if (moreTornados.Value)
					{
						count = Mathf.Clamp(burstTornado.Value, 1, 5);
						totalSpreadSec = burstSpreadSeconds.Value;
					}
					else
					{
						count = 1;
						totalSpreadSec = 0f;
					}
				}
				((MonoBehaviour)this).StartCoroutine(SpawnBurst(kind, count, totalSpreadSec));
				float time = Time.time;
				if (kind == HazardKind.Dynamite)
				{
					_nextDynaAt = time + intervalDynamiteSec.Value;
				}
				if (kind == HazardKind.Tornado)
				{
					_nextTornAt = time + intervalTornadoSec.Value;
				}
				if (kind == HazardKind.Tumbleweed)
				{
					_nextTumbAt = time + intervalTumbleweedSec.Value;
				}
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode mode)
		{
			_currentScene = ((Scene)(ref s)).name ?? "";
			_sceneEnteredAt = Time.time;
			worldRoot = FindWorldRoot();
			_cachedAnchors.Clear();
			_lastKnownPlayerCount = -1;
			_lastAnchorRefreshAt = -999f;
			_roundRobinIndex = 0;
			liveAll.Clear();
			liveDyn.Clear();
			liveTor.Clear();
			liveTum.Clear();
			_kindOf.Clear();
			_nextDynaAt = (_nextTornAt = (_nextTumbAt = -1f));
			Log.LogInfo((object)("WorldRoot: " + (Object.op_Implicit((Object)(object)worldRoot) ? ((Object)worldRoot).name : "<null>") + " (Scene: " + _currentScene + ")"));
			if (_loop != null)
			{
				((MonoBehaviour)this).StopCoroutine(_loop);
				_loop = null;
			}
			if (ShouldRunInScene(_currentScene))
			{
				_loop = ((MonoBehaviour)this).StartCoroutine(SpawnerLoop());
			}
			else
			{
				_blockReason = "Scene blocked";
			}
		}

		private GameObject Spawn(HazardKind kind, Vector3 pos)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			return (GameObject)(kind switch
			{
				HazardKind.Dynamite => SpawnDynamite(pos), 
				HazardKind.Tornado => SpawnTornado(pos), 
				HazardKind.Tumbleweed => SpawnTumbleweed(pos), 
				_ => null, 
			});
		}

		private GameObject SpawnDynamite(Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			try
			{
				val = PhotonNetwork.InstantiateItemRoom("Dynamite", pos + Vector3.up * 0.1f, Quaternion.identity);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("InstantiateItemRoom 'Dynamite' failed: " + ex.Message));
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"Dynamite spawn failed.");
				return null;
			}
			MonoBehaviour val2 = ((IEnumerable<MonoBehaviour>)val.GetComponents<MonoBehaviour>()).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour c) => ((object)c).GetType().Name == "Dynamite"));
			if ((Object)(object)val2 != (Object)null)
			{
				((object)val2).GetType().GetMethod("LightFlare", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(val2, null);
				((MonoBehaviour)this).StartCoroutine(DespawnAfter(val, ttlDynamite.Value));
			}
			Log.LogInfo((object)$"[HazardChaos] Spawned Dynamite @ {pos} (TTL={ttlDynamite.Value}s)");
			return val;
		}

		private GameObject SpawnTumbleweed(Vector3 pos)
		{
			//IL_0022: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			string[] array = new string[2] { "TumbleWeed", "Tumbleweed" };
			foreach (string text in array)
			{
				try
				{
					val = PhotonNetwork.Instantiate(text, pos, Quaternion.identity, (byte)0, (object[])null);
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Instantiate '" + text + "' failed: " + ex.Message));
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"Tumbleweed spawn failed.");
				return null;
			}
			((MonoBehaviour)this).StartCoroutine(DespawnAfter(val, ttlTumbleweed.Value));
			Log.LogInfo((object)$"[HazardChaos] Spawned Tumbleweed @ {pos} (TTL={ttlTumbleweed.Value}s)");
			return val;
		}

		private GameObject SpawnTornado(Vector3 pos)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			try
			{
				val = PhotonNetwork.Instantiate("Tornado", pos, Quaternion.identity, (byte)0, (object[])null);
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Instantiate 'Tornado' failed: " + ex.Message));
			}
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"Tornado spawn failed.");
				return null;
			}
			PhotonView component = val.GetComponent<PhotonView>();
			if ((Object)(object)component != (Object)null && PhotonNetwork.IsMasterClient && !component.IsMine)
			{
				try
				{
					component.TransferOwnership(PhotonNetwork.LocalPlayer);
				}
				catch
				{
				}
			}
			bool flag = false;
			MonoBehaviour val2 = ((!tornadoForceModMover.Value && tornadoUseVanillaAIWhenAvailable.Value) ? ((IEnumerable<MonoBehaviour>)Object.FindObjectsOfType<MonoBehaviour>()).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour m) => ((object)m).GetType().Name == "TornadoSpawner")) : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)component != (Object)null && !tornadoForceModMover.Value)
			{
				try
				{
					PhotonView component2 = ((Component)val2).GetComponent<PhotonView>();
					if ((Object)(object)component2 != (Object)null)
					{
						component.RPC("RPCA_InitTornado", (RpcTarget)0, new object[1] { component2.ViewID });
						flag = true;
						Log.LogInfo((object)"[HazardChaos] Tornado initialized via Vanilla TornadoSpawner (AI takeover).");
					}
				}
				catch (Exception ex2)
				{
					Log.LogWarning((object)("Vanilla Tornado init failed, falling back to mod mover: " + ex2.Message));
					flag = false;
				}
			}
			if (!flag)
			{
				TryDisableVanillaMovement(val);
				Transform val3 = SetupTornadoFallback(val);
				ModTornadoMover modTornadoMover = val.AddComponent<ModTornadoMover>();
				modTornadoMover.plugin = this;
				modTornadoMover.speed = tornadoSpeed.Value;
				modTornadoMover.retargetSec = tornadoRetargetSec.Value;
				modTornadoMover.drive = (((Object)(object)val3 != (Object)null) ? val3 : val.transform);
				Log.LogInfo((object)("[HazardChaos] Tornado using ModTornadoMover (fallback). Drive=" + (Object.op_Implicit((Object)(object)val3) ? ((Object)val3).name : "<self>")));
			}
			EnsureTransformSync(component);
			((MonoBehaviour)this).StartCoroutine(DespawnAfter(val, ttlTornado.Value));
			MonoBehaviour val4 = ((IEnumerable<MonoBehaviour>)val.GetComponents<MonoBehaviour>()).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour c) => ((object)c).GetType().Name == "Tornado"));
			if ((Object)(object)val4 != (Object)null)
			{
				TrySetPrivateField(val4, "lifeTime", ttlTornado.Value);
			}
			Log.LogInfo((object)$"[HazardChaos] Spawned Tornado @ {pos} TTL={ttlTornado.Value}s (speed={tornadoSpeed.Value} m/s)");
			return val;
		}

		private void TryDisableVanillaMovement(GameObject go)
		{
			//IL_004a: 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)
			try
			{
				NavMeshAgent component = go.GetComponent<NavMeshAgent>();
				if (Object.op_Implicit((Object)(object)component))
				{
					((Behaviour)component).enabled = false;
				}
				CharacterController component2 = go.GetComponent<CharacterController>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					((Collider)component2).enabled = false;
				}
				Rigidbody component3 = go.GetComponent<Rigidbody>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					component3.isKinematic = true;
					component3.useGravity = false;
					component3.velocity = Vector3.zero;
					component3.angularVelocity = Vector3.zero;
				}
				MonoBehaviour[] components = go.GetComponents<MonoBehaviour>();
				foreach (MonoBehaviour val in components)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					string name = ((object)val).GetType().Name;
					if (name.Contains("TornadoAI") || name.Contains("TornadoMover") || name.Contains("TornadoController"))
					{
						Behaviour val2 = (Behaviour)(object)val;
						if (val2 != null)
						{
							val2.enabled = false;
						}
						Log.LogInfo((object)("[HazardChaos] Disabled vanilla mover component: " + name));
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("TryDisableVanillaMovement: " + ex.Message));
			}
		}

		private void EnsureTransformSync(PhotonView pv)
		{
			if ((Object)(object)pv == (Object)null)
			{
				return;
			}
			try
			{
				if ((pv.ObservedComponents == null || !pv.ObservedComponents.Any((Component c) => (Object)(object)c != (Object)null && c is PhotonTransformViewClassic)) && !((Object)(object)((Component)pv).GetComponent<PhotonTransformViewClassic>() != (Object)null))
				{
					PhotonTransformViewClassic item = ((Component)pv).gameObject.AddComponent<PhotonTransformViewClassic>();
					List<Component> list = pv.ObservedComponents ?? new List<Component>();
					list.Add((Component)(object)item);
					pv.ObservedComponents = list;
					Log.LogInfo((object)"[HazardChaos] Added PhotonTransformViewClassic for Tornado transform sync.");
				}
			}
			catch
			{
			}
		}

		private Transform SetupTornadoFallback(GameObject tornadoGO)
		{
			//IL_0005: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject("Mod_TornadoTargetParent").transform;
			if (Object.op_Implicit((Object)(object)worldRoot))
			{
				transform.SetParent(worldRoot, false);
			}
			transform.position = tornadoGO.transform.position;
			Transform transform2 = new GameObject("TornadoPoints").transform;
			transform2.SetParent(transform, false);
			int num = 10;
			float num2 = 45f;
			for (int i = 0; i < num; i++)
			{
				float num3 = (float)Math.PI * 2f * ((float)i / (float)num);
				Transform transform3 = new GameObject($"Point_{i}").transform;
				transform3.SetParent(transform2, false);
				transform3.localPosition = new Vector3(Mathf.Cos(num3) * num2, 0f, Mathf.Sin(num3) * num2);
			}
			MonoBehaviour val = ((IEnumerable<MonoBehaviour>)tornadoGO.GetComponents<MonoBehaviour>()).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour c) => ((object)c).GetType().Name == "Tornado"));
			if ((Object)(object)val != (Object)null)
			{
				TrySetPrivateField(val, "targetParent", transform);
			}
			tornadoGO.transform.SetParent(transform, true);
			return transform;
		}

		private static void TrySetPrivateField(object obj, string fieldName, object value)
		{
			if (obj != null)
			{
				FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
				if (field == null)
				{
					Log.LogWarning((object)("Private field '" + fieldName + "' not found on " + obj.GetType().Name));
				}
				else
				{
					field.SetValue(obj, value);
				}
			}
		}

		[IteratorStateMachine(typeof(<DespawnAfter>d__88))]
		private IEnumerator DespawnAfter(GameObject go, float seconds)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DespawnAfter>d__88(0)
			{
				<>4__this = this,
				go = go,
				seconds = seconds
			};
		}

		[IteratorStateMachine(typeof(<SpawnBurst>d__89))]
		private IEnumerator SpawnBurst(HazardKind kind, int count, float totalSpreadSec)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnBurst>d__89(0)
			{
				<>4__this = this,
				kind = kind,
				count = count,
				totalSpreadSec = totalSpreadSec
			};
		}

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

		private void OnGUI()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_064b: Unknown result type (might be due to invalid IL or missing references)
			if (uiVersionWatermarkEnabled.Value)
			{
				DrawVersionWatermark();
			}
			if (_showSettings)
			{
				Color color = GUI.color;
				GUI.color = new Color(0f, 0f, 0f, Mathf.Clamp01(settingsDimAlpha.Value));
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.blackTexture);
				GUI.color = color;
				_settingsRect = GUI.ModalWindow(321987, _settingsRect, new WindowFunction(SettingsWindow), "HazardChaos — Settings");
				GUI.BringWindowToFront(321987);
			}
			if (uiEnabled.Value && ShouldRunInScene(_currentScene))
			{
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(12f, 12f, 640f, 168f);
				GUI.depth = 0;
				Color color2 = default(Color);
				((Color)(ref color2))..ctor(0f, 0f, 0f, 0.45f);
				Color color3 = GUI.color;
				GUI.color = color2;
				GUI.Box(val, GUIContent.none);
				GUI.color = color3;
				float num = 8f;
				Rect val2 = default(Rect);
				((Rect)(ref val2))..ctor(((Rect)(ref val)).x + num, ((Rect)(ref val)).y + num, ((Rect)(ref val)).width - num * 2f, ((Rect)(ref val)).height - num * 2f);
				int num2 = ((PhotonNetwork.CurrentRoom == null) ? 1 : PhotonNetwork.CurrentRoom.PlayerCount);
				int num3 = Math.Max(0, num2 - 1) * Math.Max(0, mpPerPlayerExtraSlots.Value);
				int num4 = maxSimultaneousGlobal.Value + num3;
				int num5 = maxDynamite.Value + num3;
				int num6 = maxTornado.Value + num3;
				int num7 = maxTumbleweed.Value + num3;
				float v2 = Mathf.Max(0f, _nextDynaAt - Time.time);
				float v3 = Mathf.Max(0f, _nextTornAt - Time.time);
				float v4 = Mathf.Max(0f, _nextTumbAt - Time.time);
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					wordWrap = false
				};
				float num8 = Mathf.Max(0f, _sceneEnteredAt + startProtectionSec.Value - Time.time);
				string text = ((num8 > 0f) ? $" | Protection: {num8:0.0}s" : "");
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y, ((Rect)(ref val2)).width, 22f), "HazardChaos — Per-Hazard Timers", val3);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 22f, ((Rect)(ref val2)).width, 20f), $"Live total: {liveAll.Count}/{num4}   Players: {num2}   Mode: {mpAnchorMode.Value}{text}", val4);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 42f, ((Rect)(ref val2)).width, 20f), $"Dynamite: {T(v2)}   Live: {liveDyn.Count}/{num5}   Interval: {intervalDynamiteSec.Value:0.0}s   TTL: {ttlDynamite.Value:0.0}s   Burst: {burstDynamite.Value}", val4);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 62f, ((Rect)(ref val2)).width, 20f), $"Tornado:  {T(v3)}   Live: {liveTor.Count}/{num6}   Interval: {intervalTornadoSec.Value:0.0}s   TTL: {ttlTornado.Value:0.0}s   " + string.Format("Multi: {0}   Burst: {1}   ", moreTornados.Value ? "ON" : "OFF", (!moreTornados.Value) ? 1 : Mathf.Clamp(burstTornado.Value, 1, 5)) + "AI: " + (tornadoForceModMover.Value ? "Mod" : (tornadoUseVanillaAIWhenAvailable.Value ? "Vanilla if available" : "Mod")), val4);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 82f, ((Rect)(ref val2)).width, 20f), $"Tumbleweed: {T(v4)} Live: {liveTum.Count}/{num7}   Interval: {intervalTumbleweedSec.Value:0.0}s   TTL: {ttlTumbleweed.Value:0.0}s   Burst: {burstTumbleweed.Value}", val4);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 104f, ((Rect)(ref val2)).width, 20f), "Spread: " + ((burstSpreadSeconds.Value > 0f) ? $"{burstSpreadSeconds.Value:0.00}s" : "off") + "   LoS: " + (requireLineOfSight.Value ? "ON" : "OFF"), val4);
				string text2 = (string.IsNullOrEmpty(_blockReason) ? "OK" : _blockReason);
				GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 124f, ((Rect)(ref val2)).width, 20f), "Status: " + text2, val4);
			}
			static string T(float v)
			{
				if (!(v <= 0.01f))
				{
					return $"{v:0.0}s";
				}
				return "Ready";
			}
		}

		private void DrawVersionWatermark()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//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_0052: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			string text = "HazardChaos v0.1.12";
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = Mathf.Max(10, uiVersionFontSize.Value),
				fontStyle = (FontStyle)0,
				alignment = (TextAnchor)3
			};
			GUIContent val2 = new GUIContent(text);
			Vector2 val3 = val.CalcSize(val2);
			float num = 6f;
			float num2 = val3.x + num * 2f;
			float num3 = val3.y + num * 1.5f;
			int num4 = Mathf.Max(0, uiVersionMargin.Value);
			float num5 = num4;
			float num6 = num4;
			switch (uiVersionCorner.Value)
			{
			case Corner.TopLeft:
				num5 = num4;
				num6 = num4;
				break;
			case Corner.TopRight:
				num5 = (float)(Screen.width - num4) - num2;
				num6 = num4;
				break;
			case Corner.BottomLeft:
				num5 = num4;
				num6 = (float)(Screen.height - num4) - num3;
				break;
			case Corner.BottomRight:
				num5 = (float)(Screen.width - num4) - num2;
				num6 = (float)(Screen.height - num4) - num3;
				break;
			}
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(num5, num6, num2, num3);
			Color color = GUI.color;
			GUI.color = new Color(0f, 0f, 0f, Mathf.Clamp01(uiVersionAlpha.Value));
			GUI.Box(val4, GUIContent.none);
			GUI.color = color;
			GUIStyle val5 = new GUIStyle(val);
			Color color2 = GUI.color;
			GUI.color = new Color(0f, 0f, 0f, 0.8f);
			GUI.Label(new Rect(((Rect)(ref val4)).x + num + 1f, ((Rect)(ref val4)).y + (num3 - val3.y) * 0.5f + 1f, val3.x, val3.y), val2, val5);
			GUI.color = color2;
			GUI.Label(new Rect(((Rect)(ref val4)).x + num, ((Rect)(ref val4)).y + (num3 - val3.y) * 0.5f, val3.x, val3.y), val2, val);
		}

		private void SettingsWindow(int id)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			KeyboardShortcut value = uiSettingsKey.Value;
			GUILayout.Label("Hotkey: " + ((object)(KeyboardShortcut)(ref value)).ToString(), Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Save", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
			{
				_showSettings = false;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(6f);
			_settingsScroll = GUILayout.BeginScrollView(_settingsScroll, Array.Empty<GUILayoutOption>());
			Fold("Intervals", "Intervals", delegate
			{
				DrawFloatSlider("Dynamite Interval (s)", intervalDynamiteSec, 2f, 120f, "0.##");
				DrawFloatSlider("Tornado Interval (s)", intervalTornadoSec, 5f, 180f, "0.##");
				DrawFloatSlider("Tumbleweed Interval (s)", intervalTumbleweedSec, 3f, 120f, "0.##");
			});
			Fold("TTL", "TTLs", delegate
			{
				DrawFloatSlider("Dynamite Despawn (s)", ttlDynamite, 5f, 60f, "0.##");
				DrawFloatSlider("Tornado Despawn (s)", ttlTornado, 5f, 60f, "0.##");
				DrawFloatSlider("Tumbleweed Despawn (s)", ttlTumbleweed, 5f, 60f, "0.##");
			});
			Fold("Spawning", "Spawning & Caps", delegate
			{
				DrawIntSlider("Global Cap", maxSimultaneousGlobal, 0, 30);
				DrawIntSlider("Max Dynamite", maxDynamite, 0, 10);
				DrawIntSlider("Max Tornado", maxTornado, 0, 10);
				DrawIntSlider("Max Tumbleweed", maxTumbleweed, 0, 10);
				GUILayout.Space(4f);
				DrawIntSlider("Burst Dynamite", burstDynamite, 1, 10);
				DrawIntSlider("Burst Tumbleweed", burstTumbleweed, 1, 10);
				DrawFloatSlider("Burst Spread (s)", burstSpreadSeconds, 0f, 5f, "0.##");
				GUILayout.Space(4f);
				DrawToggle("Require Line of Sight", requireLineOfSight);
				DrawFloatSlider("Start Protection (s)", startProtectionSec, 0f, 180f, "0.##");
			});
			Fold("Tornado", "Tornado", delegate
			{
				DrawFloatSlider("Move Speed (m/s)", tornadoSpeed, 2f, 25f, "0.##");
				DrawFloatSlider("Retarget Seconds", tornadoRetargetSec, 0.5f, 10f, "0.##");
				DrawToggle("Use Vanilla When Available", tornadoUseVanillaAIWhenAvailable);
				DrawToggle("Force Mod Mover", tornadoForceModMover);
				GUILayout.Space(4f);
				DrawToggle("More Tornados (burst)", moreTornados);
				if (burstTornado.Value < 1)
				{
					burstTornado.Value = 1;
				}
				if (burstTornado.Value > 5)
				{
					burstTornado.Value = 5;
				}
				DrawIntSlider("Burst Tornado (1–5)", burstTornado, 1, 5);
			});
			Fold("Overlay", "Overlay", delegate
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				DrawToggle("Spawn Timer UI (F9)", uiEnabled);
				KeyboardShortcut value3 = uiToggleKey.Value;
				GUILayout.Label("Overlay Hotkey: " + ((object)(KeyboardShortcut)(ref value3)).ToString(), Array.Empty<GUILayoutOption>());
				DrawFloatSlider("Settings Alpha", settingsDimAlpha, 0f, 1f, "0.00");
			});
			Fold("Version", "Version watermark", delegate
			{
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				DrawToggle("Watermark Enabled (F10)", uiVersionWatermarkEnabled);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Corner: " + uiVersionCorner.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
				{
					uiVersionCorner.Value = PrevEnum(uiVersionCorner.Value);
				}
				if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
				{
					uiVersionCorner.Value = NextEnum(uiVersionCorner.Value);
				}
				GUILayout.EndHorizontal();
				DrawIntSlider("Font Size", uiVersionFontSize, 8, 32);
				DrawFloatSlider("Background Alpha", uiVersionAlpha, 0f, 1f, "0.##");
				DrawIntSlider("Margin (px)", uiVersionMargin, 0, 48);
				KeyboardShortcut value2 = uiVersionToggleKey.Value;
				GUILayout.Label("Version Hotkey: " + ((object)(KeyboardShortcut)(ref value2)).ToString(), Array.Empty<GUILayoutOption>());
			});
			Fold("Multiplayer", "Multiplayer", delegate
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Anchor Mode: " + mpAnchorMode.Value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (GUILayout.Button("<", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
				{
					mpAnchorMode.Value = PrevEnum(mpAnchorMode.Value);
				}
				if (GUILayout.Button(">", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }))
				{
					mpAnchorMode.Value = NextEnum(mpAnchorMode.Value);
				}
				GUILayout.EndHorizontal();
				DrawIntSlider("Per-Player Extra Slots", mpPerPlayerExtraSlots, 0, 5);
			});
			Fold("Debug", "Debug & Hotkeys", delegate
			{
				//IL_000b: 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_0053: Unknown result type (might be due to invalid IL or missing references)
				GUILayout.Label($"Tornado Hotkey:  {keyTornado.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Dynamite Hotkey: {keyDynamite.Value}", Array.Empty<GUILayoutOption>());
				GUILayout.Label($"Tumbleweed Hotkey: {keyTumbleweed.Value}", Array.Empty<GUILayoutOption>());
			});
			GUILayout.EndScrollView();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void Fold(string key, string title, Action content)
		{
			if (!_fold.TryGetValue(key, out var value))
			{
				value = true;
			}
			string text = (value ? "▾ " : "▸ ") + title;
			if (GUILayout.Button(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				value = !value;
			}
			_fold[key] = value;
			if (value)
			{
				GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
				content?.Invoke();
				GUILayout.EndVertical();
			}
		}

		private void DrawToggle(string label, ConfigEntry<bool> entry)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			bool flag = GUILayout.Toggle(entry.Value, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(360f) });
			if (flag != entry.Value)
			{
				entry.Value = flag;
			}
			if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
			{
				entry.Value = (bool)((ConfigEntryBase)entry).DefaultValue;
			}
			GUILayout.EndHorizontal();
		}

		private void DrawFloatSlider(string label, ConfigEntry<float> entry, float min, float max, string fmt)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(label + "  (" + entry.Value.ToString(fmt) + ")", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(280f) });
			float num = GUILayout.HorizontalSlider(entry.Value, min, max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
			if (Mathf.Abs(num - entry.Value) > 0.0001f)
			{
				entry.Value = num;
			}
			if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
			{
				entry.Value = (float)((ConfigEntryBase)entry).DefaultValue;
			}
			GUILayout.EndHorizontal();
		}

		private void DrawIntSlider(string label, ConfigEntry<int> entry, int min, int max)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"{label}  ({entry.Value})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(280f) });
			int num = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)entry.Value, (float)min, (float)max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }));
			if (num != entry.Value)
			{
				entry.Value = num;
			}
			if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
			{
				entry.Value = (int)((ConfigEntryBase)entry).DefaultValue;
			}
			GUILayout.EndHorizontal();
		}

		private static T PrevEnum<T>(T current) where T : struct, Enum
		{
			T[] array = (T[])Enum.GetValues(typeof(T));
			int num = Array.IndexOf(array, current);
			num = (num - 1 + array.Length) % array.Length;
			return array[num];
		}

		private static T NextEnum<T>(T current) where T : struct, Enum
		{
			T[] array = (T[])Enum.GetValues(typeof(T));
			int num = Array.IndexOf(array, current);
			num = (num + 1) % array.Length;
			return array[num];
		}
	}
	[DefaultExecutionOrder(10000)]
	public class ModTornadoMover : MonoBehaviour
	{
		public Plugin plugin;

		public float speed = 6f;

		public float retargetSec = 3f;

		public Transform drive;

		private Vector3 target;

		private float timer;

		private PhotonView pv;

		private void Awake()
		{
			pv = ((Component)this).GetComponent<PhotonView>();
			if (!Object.op_Implicit((Object)(object)drive))
			{
				drive = ((Component)this).transform;
			}
		}

		private void OnEnable()
		{
			timer = 0f;
		}

		private Vector3 ProjectToGround(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_002a: 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_0042: 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)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(pos + Vector3.up * 80f, Vector3.down, ref val, 200f, -1, (QueryTriggerInteraction)1))
			{
				return new Vector3(pos.x, ((RaycastHit)(ref val)).point.y + 0.1f, pos.z);
			}
			return pos;
		}

		private void Retarget()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (Object.op_Implicit((Object)(object)drive) ? drive.position : ((Component)this).transform.position);
			target = (Vector3)(((??)(((Object)(object)plugin != (Object)null) ? plugin.PickSpawnPosNearPlayer() : null)) ?? (val + Random.insideUnitSphere * 6f));
			target = ProjectToGround(new Vector3(target.x, val.y, target.z));
			timer = Mathf.Max(0.5f, retargetSec);
		}

		private void LateUpdate()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pv != (Object)null && !pv.IsMine)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)drive))
			{
				drive = ((Component)this).transform;
			}
			timer -= Time.deltaTime;
			if (timer <= 0f)
			{
				Retarget();
			}
			Vector3 position = drive.position;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(target.x, position.y, target.z);
			Vector3 val2 = val - position;
			float num = Mathf.Max(0.01f, speed) * Time.deltaTime;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				RaycastHit val3 = default(RaycastHit);
				if (Physics.SphereCast(position + Vector3.up * 0.5f, 0.6f, ((Vector3)(ref val2)).normalized, ref val3, Mathf.Min(num * 2f, 2f), -1, (QueryTriggerInteraction)1))
				{
					Vector3 val4 = Vector3.Cross(Vector3.up, val2);
					Vector3 normalized = ((Vector3)(ref val4)).normalized;
					val2 += normalized * 0.5f;
				}
				Vector3 pos = position + Vector3.ClampMagnitude(val2, num);
				drive.position = ProjectToGround(pos);
			}
			else
			{
				drive.position = ProjectToGround(position);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}