Decompiled source of Too Many Balls v1.0.0

LotsOfBalls.dll

Decompiled 4 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 HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LotsOfBalls")]
[assembly: AssemblyTitle("LotsOfBalls")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LotsOfBalls
{
	[BepInPlugin("Omniscye.LotsOfBalls", "LotsOfBalls", "1.0")]
	public class LotsOfBalls : BaseUnityPlugin
	{
		internal static LotsOfBalls Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}
namespace EmpressMods.SphereFlood
{
	[BepInPlugin("com.omniscye.levelpointspheres", "Level Point Sphere Flood", "2.1.0")]
	public class LevelPointSphereFlood : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static LevelPointSphereFlood I;

		public static ConfigEntry<int> CFG_SphereCount;

		public static ConfigEntry<float> CFG_SphereScale;

		public static ConfigEntry<bool> CFG_GridMode;

		public static ConfigEntry<float> CFG_GridGapMeters;

		public static ConfigEntry<bool> CFG_SnapToGround;

		public static ConfigEntry<int> CFG_SnapEveryNth;

		public static ConfigEntry<float> CFG_RB_Mass;

		public static ConfigEntry<float> CFG_RB_Drag;

		public static ConfigEntry<float> CFG_RB_AngularDrag;

		public static ConfigEntry<float> CFG_RB_SleepThreshold;

		public static ConfigEntry<float> CFG_CellSize;

		public static ConfigEntry<int> CFG_ActiveCellRadius;

		public static ConfigEntry<float> CFG_CullRefreshInterval;

		public static ConfigEntry<int> CFG_ToggleBudgetPerFrame;

		public static ConfigEntry<bool> CFG_HideRendererWhenCulled;

		public static ConfigEntry<int> CFG_MaxActiveCount;

		public static ConfigEntry<int> CFG_SpheresPerPoint;

		public static ConfigEntry<float> CFG_PerPointJitterRadius;

		public static ConfigEntry<bool> CFG_PerPointSpiral;

		public static ConfigEntry<bool> CFG_AddImpactDetector;

		public static ConfigEntry<bool> CFG_AddDetectorOnlyIfCompatible;

		internal static int GenSerialCounter = 0;

		internal static int LastSpawnedGenSerial = -1;

		internal static Level LastSpawnedLevelRef = null;

		internal static bool SpawnedThisLevel = false;

		private void Awake()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Expected O, but got Unknown
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Expected O, but got Unknown
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Expected O, but got Unknown
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Expected O, but got Unknown
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Expected O, but got Unknown
			I = this;
			CFG_SphereCount = ((BaseUnityPlugin)this).Config.Bind<int>("SphereFlood", "SphereCount", 10000, new ConfigDescription("Total spheres to spawn (grid mode).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20000), Array.Empty<object>()));
			CFG_SphereScale = ((BaseUnityPlugin)this).Config.Bind<float>("SphereFlood", "SphereScale", 0.3f, new ConfigDescription("Uniform local scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>()));
			CFG_GridMode = ((BaseUnityPlugin)this).Config.Bind<bool>("SphereFlood", "GridMode", false, "When true, spawn a grid centered on one discovered anchor (nearest level point). When false, spawn at ALL discovered level points.");
			CFG_GridGapMeters = ((BaseUnityPlugin)this).Config.Bind<float>("SphereFlood", "GridGapMeters", 0.02f, new ConfigDescription("Extra gap beyond diameter to avoid initial overlaps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.25f), Array.Empty<object>()));
			CFG_SnapToGround = ((BaseUnityPlugin)this).Config.Bind<bool>("SphereFlood", "SnapToGround", false, "Raycast down to place on ground (expensive at high counts).");
			CFG_SnapEveryNth = ((BaseUnityPlugin)this).Config.Bind<int>("SphereFlood", "SnapEveryNth", 0, new ConfigDescription("If >0, only snap every Nth sphere (amortize raycasts).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5000), Array.Empty<object>()));
			CFG_RB_Mass = ((BaseUnityPlugin)this).Config.Bind<float>("Rigidbody", "Mass", 0.05f, new ConfigDescription("Rigidbody mass.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 5f), Array.Empty<object>()));
			CFG_RB_Drag = ((BaseUnityPlugin)this).Config.Bind<float>("Rigidbody", "Drag", 0f, new ConfigDescription("Linear drag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			CFG_RB_AngularDrag = ((BaseUnityPlugin)this).Config.Bind<float>("Rigidbody", "AngularDrag", 0.05f, new ConfigDescription("Angular drag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			CFG_RB_SleepThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Rigidbody", "SleepThreshold", 0.1f, new ConfigDescription("Higher = sleeps more aggressively.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.0001f, 1f), Array.Empty<object>()));
			CFG_CellSize = ((BaseUnityPlugin)this).Config.Bind<float>("Culling", "CellSize", 20f, new ConfigDescription("Meters per culling cell (XZ).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), Array.Empty<object>()));
			CFG_ActiveCellRadius = ((BaseUnityPlugin)this).Config.Bind<int>("Culling", "ActiveCellRadius", 1, new ConfigDescription("Cells active around player (square radius).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
			CFG_CullRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Culling", "CullRefreshInterval", 0.25f, new ConfigDescription("Seconds between culling region updates.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>()));
			CFG_ToggleBudgetPerFrame = ((BaseUnityPlugin)this).Config.Bind<int>("Culling", "ToggleBudgetPerFrame", 600, new ConfigDescription("Max enable/disable ops per frame to avoid spikes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 5000), Array.Empty<object>()));
			CFG_HideRendererWhenCulled = ((BaseUnityPlugin)this).Config.Bind<bool>("Culling", "HideRendererWhenCulled", true, "Also disable MeshRenderer for culled spheres.");
			CFG_MaxActiveCount = ((BaseUnityPlugin)this).Config.Bind<int>("Culling", "MaxActiveCount", 800, new ConfigDescription("Hard cap on concurrently active (enabled) spheres; nearest to player win.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 20000), Array.Empty<object>()));
			CFG_SpheresPerPoint = ((BaseUnityPlugin)this).Config.Bind<int>("PerPoint", "SpheresPerPoint", 100, new ConfigDescription("Number of spheres to spawn at each discovered level point.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000), Array.Empty<object>()));
			CFG_PerPointJitterRadius = ((BaseUnityPlugin)this).Config.Bind<float>("PerPoint", "PerPointJitterRadius", 1.5f, new ConfigDescription("Max horizontal jitter radius per point (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			CFG_PerPointSpiral = ((BaseUnityPlugin)this).Config.Bind<bool>("PerPoint", "UseSpiralDistribution", true, "Use golden-angle spiral distribution per point.");
			CFG_AddImpactDetector = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "AddImpactDetector", false, "Attach PhysGrabObjectImpactDetector (not recommended for thousands). Defaults OFF.");
			CFG_AddDetectorOnlyIfCompatible = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "AddDetectorOnlyIfCompatible", true, "Only add detector if PhysGrabObject already exists.");
			CFG_SpheresPerPoint.Value = 100;
			CFG_MaxActiveCount.Value = 800;
			CFG_ActiveCellRadius.Value = 1;
			CFG_CellSize.Value = 20f;
			_harmony = new Harmony("com.omniscye.levelpointspheres");
			_harmony.PatchAll();
			SphereSpawnWatchdog.Ensure();
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[SphereFlood] v2.1.0 loaded. Grid={CFG_GridMode.Value}, Count={CFG_SphereCount.Value}, Scale={CFG_SphereScale.Value}");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
			SphereManager.ClearAll();
			GridCuller.Reset();
		}

		internal static void Log(string msg)
		{
			if ((Object)(object)I != (Object)null)
			{
				((BaseUnityPlugin)I).Logger.LogInfo((object)msg);
			}
			else
			{
				Debug.Log((object)msg);
			}
		}

		internal static void LogWarn(string msg)
		{
			if ((Object)(object)I != (Object)null)
			{
				((BaseUnityPlugin)I).Logger.LogWarning((object)msg);
			}
			else
			{
				Debug.LogWarning((object)msg);
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Generate")]
	public static class Patch_LevelGenerator_Generate
	{
		[CompilerGenerated]
		private sealed class <CoSpawnAfterGen>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public int genSerial;

			private LevelGenerator <lg>5__1;

			private float <timeout>5__2;

			private List<Transform> <points>5__3;

			private Vector3 <anchor>5__4;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<lg>5__1 = null;
				<points>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_012d: 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_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0174: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					goto IL_0059;
				case 1:
					<>1__state = -1;
					goto IL_0059;
				case 2:
					<>1__state = -1;
					goto IL_00c2;
				case 3:
					<>1__state = -1;
					break;
				case 4:
					{
						<>1__state = -1;
						break;
					}
					IL_0059:
					if (LooksLikeMenuOrSplash())
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					<lg>5__1 = null;
					<timeout>5__2 = Time.time + 30f;
					goto IL_00c2;
					IL_00c2:
					if (Time.time < <timeout>5__2)
					{
						<lg>5__1 = LevelGenerator.Instance;
						if (!((Object)(object)<lg>5__1 != (Object)null) || !<lg>5__1.Generated)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
					}
					if ((Object)(object)<lg>5__1 == (Object)null || !<lg>5__1.Generated)
					{
						LevelPointSphereFlood.LogWarn("[SphereFlood] Timeout waiting for LevelGenerator.Generated");
						return false;
					}
					if (LevelPointSphereFlood.LastSpawnedGenSerial == genSerial)
					{
						return false;
					}
					<points>5__3 = LevelPoints.FindLikelyLevelPoints_CurrentWorld();
					<anchor>5__4 = AnchorChooser.ChooseAnchor(<points>5__3);
					LevelPointSphereFlood.Log($"[SphereFlood] Candidate points: {<points>5__3.Count}. Anchor at {<anchor>5__4}");
					if (LevelPointSphereFlood.CFG_GridMode.Value)
					{
						<>2__current = SphereManager.CoSpawnGrid(<anchor>5__4);
						<>1__state = 3;
						return true;
					}
					<>2__current = SphereManager.CoSpawnOnePerPoint(<points>5__3);
					<>1__state = 4;
					return true;
				}
				GridCuller.Ensure();
				LevelPointSphereFlood.LastSpawnedGenSerial = genSerial;
				LevelPointSphereFlood.LastSpawnedLevelRef = <lg>5__1.Level;
				LevelPointSphereFlood.SpawnedThisLevel = 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();
			}
		}

		private static void Prefix(LevelGenerator __instance)
		{
			LevelPointSphereFlood.GenSerialCounter++;
		}

		public static void Postfix(LevelGenerator __instance)
		{
			int genSerialCounter = LevelPointSphereFlood.GenSerialCounter;
			if ((Object)(object)LevelPointSphereFlood.I != (Object)null)
			{
				((MonoBehaviour)LevelPointSphereFlood.I).StartCoroutine(CoSpawnAfterGen(genSerialCounter));
			}
		}

		[IteratorStateMachine(typeof(<CoSpawnAfterGen>d__2))]
		private static IEnumerator CoSpawnAfterGen(int genSerial)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoSpawnAfterGen>d__2(0)
			{
				genSerial = genSerial
			};
		}

		private static bool LooksLikeMenuOrSplash()
		{
			//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 text = ((Scene)(ref activeScene)).name ?? string.Empty;
			if (text.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (text.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (text.IndexOf("Title", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (text.IndexOf("Splash", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	public static class Patch_RunManager_ChangeLevel
	{
		private static void Postfix()
		{
			LevelPointSphereFlood.SpawnedThisLevel = false;
			LevelPointSphereFlood.LastSpawnedLevelRef = null;
			LevelPointSphereFlood.LastSpawnedGenSerial = -1;
			SphereManager.ClearAll();
			GridCuller.Reset();
		}
	}
	public class SphereSpawnWatchdog : MonoBehaviour
	{
		private static SphereSpawnWatchdog _i;

		private float _next;

		public static void Ensure()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_i != (Object)null))
			{
				GameObject val = new GameObject("[SphereFlood] Watchdog");
				Object.DontDestroyOnLoad((Object)(object)val);
				_i = val.AddComponent<SphereSpawnWatchdog>();
			}
		}

		private void Update()
		{
			if (!(Time.time < _next))
			{
				_next = Time.time + 1f;
				int genSerialCounter = LevelPointSphereFlood.GenSerialCounter;
				LevelGenerator instance = LevelGenerator.Instance;
				if (!((Object)(object)instance == (Object)null) && instance.Generated && LevelPointSphereFlood.LastSpawnedGenSerial != genSerialCounter)
				{
					Patch_LevelGenerator_Generate.Postfix(instance);
				}
			}
		}
	}
	public static class LevelPoints
	{
		private static readonly string[] NEEDLES = new string[15]
		{
			"levelpoint", "level spawn", "levelspawn", "enemyspawn", "spawnpoint", "spawn point", "aispawn", "respawnpoint", "respawn", "wavespawn",
			"spawner", "ghostspawn", "eventspawn", "huntspawn", "ghostpoint"
		};

		private static bool LooksLikeSpawnType(string typeNameLower)
		{
			for (int i = 0; i < NEEDLES.Length; i++)
			{
				if (typeNameLower.Contains(NEEDLES[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static bool LooksLikeSpawnName(string nameLower)
		{
			for (int i = 0; i < NEEDLES.Length; i++)
			{
				if (nameLower.Contains(NEEDLES[i]))
				{
					return true;
				}
			}
			return false;
		}

		public static List<Transform> FindLikelyLevelPoints_CurrentWorld()
		{
			List<Transform> list = new List<Transform>(256);
			MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>(true);
			foreach (MonoBehaviour val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				if (Object.op_Implicit((Object)(object)gameObject) && gameObject.activeInHierarchy && !((Object)gameObject).name.StartsWith("[SphereFlood]"))
				{
					string typeNameLower = ((object)val).GetType().Name.ToLowerInvariant();
					if (LooksLikeSpawnType(typeNameLower))
					{
						list.Add(((Component)val).transform);
					}
				}
			}
			Transform[] array2 = Object.FindObjectsOfType<Transform>(true);
			foreach (Transform val2 in array2)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				GameObject gameObject2 = ((Component)val2).gameObject;
				if (Object.op_Implicit((Object)(object)gameObject2) && gameObject2.activeInHierarchy && !((Object)gameObject2).name.StartsWith("[SphereFlood]"))
				{
					string nameLower = ((Object)val2).name.ToLowerInvariant();
					if (LooksLikeSpawnName(nameLower))
					{
						list.Add(val2);
					}
				}
			}
			return list.Distinct().ToList();
		}
	}
	public static class AnchorChooser
	{
		public static Vector3 ChooseAnchor(List<Transform> points)
		{
			//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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0111: 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_00f4: 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_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_0115: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = FindLocalPlayer();
			Transform val2 = null;
			if (points != null && points.Count > 0)
			{
				if ((Object)(object)val != (Object)null)
				{
					Vector3 position = ((Component)val).transform.position;
					float num = float.MaxValue;
					for (int i = 0; i < points.Count; i++)
					{
						Transform val3 = points[i];
						if (Object.op_Implicit((Object)(object)val3))
						{
							Vector3 val4 = val3.position - position;
							float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
							if (sqrMagnitude < num)
							{
								num = sqrMagnitude;
								val2 = val3;
							}
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)val2))
				{
					val2 = points[0];
				}
			}
			if (Object.op_Implicit((Object)(object)val2))
			{
				return val2.position;
			}
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).transform.position + ((Component)val).transform.forward * 2f;
			}
			return Vector3.zero;
		}

		private static PlayerAvatar FindLocalPlayer()
		{
			try
			{
				PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(true);
				foreach (PlayerAvatar val in array)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Type type = ((object)val).GetType();
					try
					{
						FieldInfo field = type.GetField("isLocal", BindingFlags.Instance | BindingFlags.NonPublic);
						if (field != null && field.FieldType == typeof(bool) && (bool)field.GetValue(val))
						{
							return val;
						}
					}
					catch
					{
					}
					try
					{
						PropertyInfo property = type.GetProperty("IsLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null && property.PropertyType == typeof(bool) && (bool)property.GetValue(val))
						{
							return val;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	public static class SphereManager
	{
		public struct SphereRec
		{
			public GameObject go;

			public Rigidbody rb;

			public Collider col;

			public MeshRenderer mr;

			public Vector2Int cell;

			public bool active;
		}

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

			private object <>2__current;

			public Vector3 anchor;

			private int <target>5__1;

			private float <r>5__2;

			private float <diameter>5__3;

			private float <spacing>5__4;

			private int <gridX>5__5;

			private int <gridZ>5__6;

			private int <halfX>5__7;

			private int <halfZ>5__8;

			private int <snapStride>5__9;

			private bool <doSnap>5__10;

			private int <spawned>5__11;

			private int <yieldBudget>5__12;

			private int <iz>5__13;

			private int <ix>5__14;

			private Vector3 <pos>5__15;

			private Vector3 <origin>5__16;

			private RaycastHit <rh>5__17;

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

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

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

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

			private bool MoveNext()
			{
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0251: Unknown result type (might be due to invalid IL or missing references)
				//IL_0256: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Unknown result type (might be due to invalid IL or missing references)
				//IL_020a: Unknown result type (might be due to invalid IL or missing references)
				//IL_020f: 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_0236: Unknown result type (might be due to invalid IL or missing references)
				//IL_0240: Unknown result type (might be due to invalid IL or missing references)
				//IL_0245: Unknown result type (might be due to invalid IL or missing references)
				//IL_024a: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_02a6;
				}
				<>1__state = -1;
				ClearAll();
				EnsureRoot();
				EnsureMaterial();
				<target>5__1 = Mathf.Max(1, LevelPointSphereFlood.CFG_SphereCount.Value);
				<r>5__2 = Mathf.Max(0.01f, LevelPointSphereFlood.CFG_SphereScale.Value);
				<diameter>5__3 = <r>5__2 * 2f;
				<spacing>5__4 = <diameter>5__3 + Mathf.Max(0f, LevelPointSphereFlood.CFG_GridGapMeters.Value);
				<gridX>5__5 = Mathf.CeilToInt(Mathf.Sqrt((float)<target>5__1));
				<gridZ>5__6 = Mathf.CeilToInt((float)<target>5__1 / (float)<gridX>5__5);
				<halfX>5__7 = <gridX>5__5 / 2;
				<halfZ>5__8 = <gridZ>5__6 / 2;
				<snapStride>5__9 = Mathf.Max(0, LevelPointSphereFlood.CFG_SnapEveryNth.Value);
				<doSnap>5__10 = LevelPointSphereFlood.CFG_SnapToGround.Value && (<snapStride>5__9 == 0 || <snapStride>5__9 >= 1);
				<spawned>5__11 = 0;
				<yieldBudget>5__12 = Mathf.Max(64, LevelPointSphereFlood.CFG_ToggleBudgetPerFrame.Value);
				<iz>5__13 = 0;
				goto IL_02e3;
				IL_02e3:
				if (<iz>5__13 < <gridZ>5__6)
				{
					<ix>5__14 = 0;
					goto IL_02b9;
				}
				LevelPointSphereFlood.Log($"[SphereFlood] Grid spawn complete. {<spawned>5__11} spheres. Grid {<gridX>5__5}x{<gridZ>5__6}, spacing={<spacing>5__4:0.###}m");
				return false;
				IL_02b9:
				if (<ix>5__14 < <gridX>5__5 && <spawned>5__11 < <target>5__1)
				{
					<pos>5__15 = anchor + new Vector3((float)(<ix>5__14 - <halfX>5__7) * <spacing>5__4, 0f, (float)(<iz>5__13 - <halfZ>5__8) * <spacing>5__4);
					if (<doSnap>5__10 && (<snapStride>5__9 == 0 || <spawned>5__11 % <snapStride>5__9 == 0))
					{
						<origin>5__16 = <pos>5__15 + Vector3.up * 2f;
						if (Physics.Raycast(<origin>5__16, Vector3.down, ref <rh>5__17, 6f, -1, (QueryTriggerInteraction)1))
						{
							<pos>5__15 = ((RaycastHit)(ref <rh>5__17)).point + Vector3.up * 0.02f;
						}
					}
					SpawnOne(<pos>5__15, Quaternion.identity, <r>5__2);
					<spawned>5__11++;
					if (<spawned>5__11 % <yieldBudget>5__12 == 0)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_02a6;
				}
				<iz>5__13++;
				goto IL_02e3;
				IL_02a6:
				<ix>5__14++;
				goto IL_02b9;
			}

			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 <CoSpawnOnePerPoint>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public List<Transform> points;

			private int <perPoint>5__1;

			private float <jitter>5__2;

			private bool <spiral>5__3;

			private float <r>5__4;

			private int <snapStride>5__5;

			private bool <doSnap>5__6;

			private long <totalPlanned>5__7;

			private int <spawned>5__8;

			private int <yieldBudget>5__9;

			private int <i>5__10;

			private int <j>5__11;

			private int <i>5__12;

			private Transform <p>5__13;

			private Vector3 <basePos>5__14;

			private Quaternion <rot>5__15;

			private int <j>5__16;

			private Vector3 <pos>5__17;

			private Vector3 <origin>5__18;

			private RaycastHit <rh>5__19;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0273: Unknown result type (might be due to invalid IL or missing references)
				//IL_0290: Unknown result type (might be due to invalid IL or missing references)
				//IL_0295: Unknown result type (might be due to invalid IL or missing references)
				//IL_029a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0336: Unknown result type (might be due to invalid IL or missing references)
				//IL_033c: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0316: Unknown result type (might be due to invalid IL or missing references)
				//IL_031b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0325: Unknown result type (might be due to invalid IL or missing references)
				//IL_032a: Unknown result type (might be due to invalid IL or missing references)
				//IL_032f: 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_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_038c;
				}
				<>1__state = -1;
				ClearAll();
				EnsureRoot();
				EnsureMaterial();
				if (points == null || points.Count == 0)
				{
					return false;
				}
				<i>5__10 = 0;
				while (<i>5__10 < points.Count)
				{
					<j>5__11 = Random.Range(<i>5__10, points.Count);
					List<Transform> list = points;
					int index = <i>5__10;
					List<Transform> list2 = points;
					int index2 = <j>5__11;
					Transform value = points[<j>5__11];
					Transform value2 = points[<i>5__10];
					list[index] = value;
					list2[index2] = value2;
					<i>5__10++;
				}
				<perPoint>5__1 = Mathf.Max(1, LevelPointSphereFlood.CFG_SpheresPerPoint.Value);
				<jitter>5__2 = Mathf.Max(0f, LevelPointSphereFlood.CFG_PerPointJitterRadius.Value);
				<spiral>5__3 = LevelPointSphereFlood.CFG_PerPointSpiral.Value;
				<r>5__4 = Mathf.Max(0.01f, LevelPointSphereFlood.CFG_SphereScale.Value);
				<snapStride>5__5 = Mathf.Max(0, LevelPointSphereFlood.CFG_SnapEveryNth.Value);
				<doSnap>5__6 = LevelPointSphereFlood.CFG_SnapToGround.Value && (<snapStride>5__5 == 0 || <snapStride>5__5 >= 1);
				<totalPlanned>5__7 = (long)points.Count * (long)<perPoint>5__1;
				if (<totalPlanned>5__7 > 200000)
				{
					LevelPointSphereFlood.LogWarn($"[SphereFlood] Warning: planning to spawn {<totalPlanned>5__7:N0} objects. This will be heavy; culling will cap actives but spawn time/memory will grow.");
				}
				<spawned>5__8 = 0;
				<yieldBudget>5__9 = Mathf.Max(64, LevelPointSphereFlood.CFG_ToggleBudgetPerFrame.Value);
				<i>5__12 = 0;
				goto IL_03d0;
				IL_038c:
				<j>5__16++;
				goto IL_039f;
				IL_03d0:
				if (<i>5__12 < points.Count)
				{
					<p>5__13 = points[<i>5__12];
					if (!Object.op_Implicit((Object)(object)<p>5__13))
					{
						goto IL_03be;
					}
					<basePos>5__14 = <p>5__13.position;
					<rot>5__15 = <p>5__13.rotation;
					<j>5__16 = 0;
					goto IL_039f;
				}
				LevelPointSphereFlood.Log($"[SphereFlood] Per-point spawn complete: {<spawned>5__8} spheres across {points.Count} points (per point={<perPoint>5__1}).");
				return false;
				IL_039f:
				if (<j>5__16 < <perPoint>5__1)
				{
					<pos>5__17 = <basePos>5__14 + JitterOffset(<j>5__16, <perPoint>5__1, <jitter>5__2, <spiral>5__3);
					if (<doSnap>5__6 && (<snapStride>5__5 == 0 || <spawned>5__8 % <snapStride>5__5 == 0))
					{
						<origin>5__18 = <pos>5__17 + Vector3.up * 2f;
						if (Physics.Raycast(<origin>5__18, Vector3.down, ref <rh>5__19, 6f, -1, (QueryTriggerInteraction)1))
						{
							<pos>5__17 = ((RaycastHit)(ref <rh>5__19)).point + Vector3.up * 0.02f;
						}
					}
					SpawnOne(<pos>5__17, <rot>5__15, <r>5__4);
					<spawned>5__8++;
					if (<spawned>5__8 % <yieldBudget>5__9 == 0)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_038c;
				}
				<p>5__13 = null;
				goto IL_03be;
				IL_03be:
				<i>5__12++;
				goto IL_03d0;
			}

			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 readonly List<SphereRec> _spheres = new List<SphereRec>(16384);

		private static readonly Dictionary<Vector2Int, List<int>> _cellToIndices = new Dictionary<Vector2Int, List<int>>(1024);

		private static readonly List<int> _scratch = new List<int>(2048);

		private static GameObject _root;

		private static Material _matRed;

		public static int Count => _spheres.Count;

		public static void ClearAll()
		{
			for (int num = _spheres.Count - 1; num >= 0; num--)
			{
				SphereRec sphereRec = _spheres[num];
				if (Object.op_Implicit((Object)(object)sphereRec.go))
				{
					Object.Destroy((Object)(object)sphereRec.go);
				}
			}
			_spheres.Clear();
			_cellToIndices.Clear();
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
				_root = null;
			}
		}

		private static void EnsureRoot()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_root))
			{
				_root = new GameObject("[SphereFlood] Root");
				Object.DontDestroyOnLoad((Object)(object)_root);
			}
		}

		private static void EnsureMaterial()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_matRed))
			{
				_matRed = new Material(Shader.Find("Standard"));
				_matRed.color = Color.red;
				_matRed.enableInstancing = true;
			}
		}

		[IteratorStateMachine(typeof(<CoSpawnGrid>d__11))]
		public static IEnumerator CoSpawnGrid(Vector3 anchor)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoSpawnGrid>d__11(0)
			{
				anchor = anchor
			};
		}

		[IteratorStateMachine(typeof(<CoSpawnOnePerPoint>d__12))]
		public static IEnumerator CoSpawnOnePerPoint(List<Transform> points)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoSpawnOnePerPoint>d__12(0)
			{
				points = points
			};
		}

		private static Vector3 JitterOffset(int j, int perPoint, float radius, bool spiral)
		{
			//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_0024: 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_002f: 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_003d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			if (radius <= 0f)
			{
				return Vector3.zero;
			}
			if (!spiral)
			{
				Vector2 val = Random.insideUnitCircle * radius;
				return new Vector3(val.x, 0f, val.y);
			}
			float num = ((perPoint <= 1) ? 0f : (((float)j + 0.5f) / (float)perPoint));
			float num2 = Mathf.Sqrt(num) * radius;
			float num3 = 2.3999631f * (float)j;
			return new Vector3(Mathf.Cos(num3) * num2, 0f, Mathf.Sin(num3) * num2);
		}

		private static void SpawnOne(Vector3 position, Quaternion rotation, float radius)
		{
			//IL_0031: 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_004b: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val).name = "LP_Sphere";
			val.transform.SetParent(_root.transform, false);
			val.transform.position = position;
			val.transform.rotation = rotation;
			val.transform.localScale = Vector3.one * Mathf.Max(0.01f, radius);
			Collider component = val.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				component.isTrigger = false;
			}
			Rigidbody val2 = val.GetComponent<Rigidbody>() ?? val.AddComponent<Rigidbody>();
			val2.useGravity = true;
			val2.collisionDetectionMode = (CollisionDetectionMode)0;
			val2.interpolation = (RigidbodyInterpolation)0;
			val2.mass = Mathf.Max(0.001f, LevelPointSphereFlood.CFG_RB_Mass.Value);
			val2.drag = Mathf.Max(0f, LevelPointSphereFlood.CFG_RB_Drag.Value);
			val2.angularDrag = Mathf.Max(0f, LevelPointSphereFlood.CFG_RB_AngularDrag.Value);
			val2.sleepThreshold = Mathf.Clamp(LevelPointSphereFlood.CFG_RB_SleepThreshold.Value, 0.0001f, 1f);
			MeshRenderer component2 = val.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).sharedMaterial = _matRed;
				((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component2).receiveShadows = false;
			}
			if (LevelPointSphereFlood.CFG_AddImpactDetector.Value)
			{
				bool flag = (Object)(object)val.GetComponent<PhysGrabObject>() != (Object)null;
				if (!LevelPointSphereFlood.CFG_AddDetectorOnlyIfCompatible.Value || flag)
				{
					try
					{
						PhysGrabObjectImpactDetector val3 = val.AddComponent<PhysGrabObjectImpactDetector>();
						if (!flag)
						{
							((Behaviour)val3).enabled = false;
						}
					}
					catch (Exception ex)
					{
						LevelPointSphereFlood.LogWarn("[SphereFlood] ImpactDetector add failed: " + ex.Message);
					}
				}
			}
			Vector2Int val4 = ToCell(position);
			int count = _spheres.Count;
			if (!_cellToIndices.TryGetValue(val4, out List<int> value))
			{
				value = new List<int>(32);
				_cellToIndices[val4] = value;
			}
			value.Add(count);
			_spheres.Add(new SphereRec
			{
				go = val,
				rb = val2,
				col = component,
				mr = component2,
				cell = val4,
				active = true
			});
		}

		public static Vector2Int ToCell(Vector3 pos)
		{
			//IL_0016: 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)
			//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_003c: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(1f, LevelPointSphereFlood.CFG_CellSize.Value);
			int num2 = Mathf.FloorToInt(pos.x / num);
			int num3 = Mathf.FloorToInt(pos.z / num);
			return new Vector2Int(num2, num3);
		}

		internal static void CollectIndicesInCells(HashSet<Vector2Int> cells, List<int> outIndices)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			outIndices.Clear();
			foreach (Vector2Int cell in cells)
			{
				if (_cellToIndices.TryGetValue(cell, out List<int> value))
				{
					outIndices.AddRange(value);
				}
			}
		}

		internal static bool TryGetPosition(int idx, out Vector3 pos)
		{
			//IL_0002: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			pos = default(Vector3);
			if ((uint)idx >= (uint)_spheres.Count)
			{
				return false;
			}
			SphereRec sphereRec = _spheres[idx];
			if (!Object.op_Implicit((Object)(object)sphereRec.go))
			{
				return false;
			}
			pos = sphereRec.go.transform.position;
			return true;
		}

		internal static void EnableIndex(int i)
		{
			if ((uint)i >= (uint)_spheres.Count)
			{
				return;
			}
			SphereRec value = _spheres[i];
			if (Object.op_Implicit((Object)(object)value.go) && !value.active)
			{
				if (Object.op_Implicit((Object)(object)value.col))
				{
					value.col.enabled = true;
				}
				if (Object.op_Implicit((Object)(object)value.rb))
				{
					value.rb.isKinematic = false;
					value.rb.WakeUp();
				}
				if (LevelPointSphereFlood.CFG_HideRendererWhenCulled.Value && Object.op_Implicit((Object)(object)value.mr))
				{
					((Renderer)value.mr).enabled = true;
				}
				value.active = true;
				_spheres[i] = value;
			}
		}

		internal static void DisableIndex(int i)
		{
			if ((uint)i >= (uint)_spheres.Count)
			{
				return;
			}
			SphereRec value = _spheres[i];
			if (Object.op_Implicit((Object)(object)value.go) && value.active)
			{
				if (Object.op_Implicit((Object)(object)value.rb))
				{
					value.rb.isKinematic = true;
					value.rb.Sleep();
				}
				if (Object.op_Implicit((Object)(object)value.col))
				{
					value.col.enabled = false;
				}
				if (LevelPointSphereFlood.CFG_HideRendererWhenCulled.Value && Object.op_Implicit((Object)(object)value.mr))
				{
					((Renderer)value.mr).enabled = false;
				}
				value.active = false;
				_spheres[i] = value;
			}
		}
	}
	public class GridCuller : MonoBehaviour
	{
		private struct Scored
		{
			public int idx;

			public float d2;
		}

		private static GridCuller _i;

		private float _nextAt = 0f;

		private readonly HashSet<Vector2Int> _activeCells = new HashSet<Vector2Int>();

		private readonly HashSet<int> _targetEnabled = new HashSet<int>();

		private readonly HashSet<int> _currentlyEnabled = new HashSet<int>();

		private readonly List<int> _work = new List<int>(4096);

		private static readonly List<int> _scratchIndices = new List<int>(8192);

		private static readonly List<Scored> _scored = new List<Scored>(8192);

		public static void Ensure()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)_i == (Object)null)
			{
				GameObject val = new GameObject("[SphereFlood] GridCuller");
				Object.DontDestroyOnLoad((Object)(object)val);
				_i = val.AddComponent<GridCuller>();
			}
			_i._nextAt = 0f;
		}

		public static void Reset()
		{
			if ((Object)(object)_i != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_i).gameObject);
				_i = null;
			}
		}

		private void Update()
		{
			//IL_0055: 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_0067: 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_006d: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			if (time < _nextAt)
			{
				return;
			}
			_nextAt = time + Mathf.Max(0.05f, LevelPointSphereFlood.CFG_CullRefreshInterval.Value);
			PlayerAvatar val = FindLocalPlayer();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)val).transform.position;
			_activeCells.Clear();
			Vector2Int val2 = SphereManager.ToCell(position);
			int num = Mathf.Max(1, LevelPointSphereFlood.CFG_ActiveCellRadius.Value);
			for (int i = -num; i <= num; i++)
			{
				for (int j = -num; j <= num; j++)
				{
					_activeCells.Add(new Vector2Int(((Vector2Int)(ref val2)).x + j, ((Vector2Int)(ref val2)).y + i));
				}
			}
			_targetEnabled.Clear();
			SphereManager.CollectIndicesInCells(_activeCells, _scratchIndices);
			for (int k = 0; k < _scratchIndices.Count; k++)
			{
				_targetEnabled.Add(_scratchIndices[k]);
			}
			int num2 = Mathf.Max(100, LevelPointSphereFlood.CFG_MaxActiveCount.Value);
			if (_targetEnabled.Count > num2)
			{
				_scored.Clear();
				foreach (int item in _targetEnabled)
				{
					if (SphereManager.TryGetPosition(item, out var pos))
					{
						Vector3 val3 = pos - position;
						float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
						_scored.Add(new Scored
						{
							idx = item,
							d2 = sqrMagnitude
						});
					}
				}
				_scored.Sort((Scored a, Scored b) => a.d2.CompareTo(b.d2));
				_targetEnabled.Clear();
				for (int l = 0; l < _scored.Count && l < num2; l++)
				{
					_targetEnabled.Add(_scored[l].idx);
				}
			}
			int num3 = Mathf.Max(1, LevelPointSphereFlood.CFG_ToggleBudgetPerFrame.Value);
			int num4 = 0;
			if (_currentlyEnabled.Count > 0)
			{
				_work.Clear();
				_work.AddRange(_currentlyEnabled);
				for (int m = 0; m < _work.Count; m++)
				{
					if (num4 >= num3)
					{
						break;
					}
					int num5 = _work[m];
					if (!_targetEnabled.Contains(num5))
					{
						SphereManager.DisableIndex(num5);
						_currentlyEnabled.Remove(num5);
						num4++;
					}
				}
			}
			if (num4 >= num3)
			{
				return;
			}
			foreach (int item2 in _targetEnabled)
			{
				if (num4 >= num3)
				{
					break;
				}
				if (!_currentlyEnabled.Contains(item2))
				{
					SphereManager.EnableIndex(item2);
					_currentlyEnabled.Add(item2);
					num4++;
				}
			}
		}

		private static PlayerAvatar FindLocalPlayer()
		{
			try
			{
				PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>(true);
				foreach (PlayerAvatar val in array)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					Type type = ((object)val).GetType();
					try
					{
						FieldInfo field = type.GetField("isLocal", BindingFlags.Instance | BindingFlags.NonPublic);
						if (field != null && field.FieldType == typeof(bool) && (bool)field.GetValue(val))
						{
							return val;
						}
					}
					catch
					{
					}
					try
					{
						PropertyInfo property = type.GetProperty("IsLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null && property.PropertyType == typeof(bool) && (bool)property.GetValue(val))
						{
							return val;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
}