Decompiled source of FPSPlus v1.1.3

FramePerSecondPlus.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Managers;
using SoftReferenceableAssets.SceneManagement;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FramePerSecondPlus")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FramePerSecondPlus")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("29e9acb2-0bb6-4c4e-b615-90240624b221")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace FramePerSecondPlus;

[BepInPlugin("vaffle.FramePerSecondPlus", "FramePerSecondPlus", "1.1.3")]
public class FramePerSecondPlus : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ClutterSystem), "Awake")]
	private static class ClutterSystem_Awake_Patch
	{
		private static void Prefix(ClutterSystem __instance)
		{
			__instance.m_grassPatchSize = grassDistance.Value;
		}
	}

	[HarmonyPatch(typeof(SceneLoader), "LoadSceneAsync")]
	private class SceneLoaderPatch
	{
		[CompilerGenerated]
		private sealed class <FastLoadSceneAsync>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SceneLoader instance;

			private string <sceneName>5__1;

			private FieldInfo <sceneField>5__2;

			private SceneReference <scene>5__3;

			private FieldInfo <loadOperationField>5__4;

			private ILoadSceneAsyncOperation <loadOperation>5__5;

			private FieldInfo <budgetRequestField>5__6;

			private float <progress>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<sceneName>5__1 = null;
				<sceneField>5__2 = null;
				<loadOperationField>5__4 = null;
				<loadOperation>5__5 = null;
				<budgetRequestField>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00bf: 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_00e5: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<sceneName>5__1 = AccessTools.Field(typeof(SceneLoader), "m_scene").GetValue(instance)?.ToString() ?? "Unknown";
					Debug.Log((object)("FastSceneLoader: Starting to load scene: " + <sceneName>5__1));
					<sceneField>5__2 = AccessTools.Field(typeof(SceneLoader), "m_scene");
					<scene>5__3 = (SceneReference)<sceneField>5__2.GetValue(instance);
					<loadOperationField>5__4 = AccessTools.Field(typeof(SceneLoader), "_sceneLoadOperation");
					<loadOperation>5__5 = SceneManager.LoadSceneAsync(<scene>5__3, (LoadSceneMode)0);
					<loadOperationField>5__4.SetValue(instance, <loadOperation>5__5);
					<budgetRequestField>5__6 = AccessTools.Field(typeof(SceneLoader), "_currentLoadingBudgetRequest");
					<budgetRequestField>5__6.SetValue(instance, BackgroundLoadingBudgetController.RequestLoadingBudget((ThreadPriority)4));
					<loadOperation>5__5.AllowSceneActivation = true;
					PlatformInitializer.AllowSaveDataInitialization = true;
					goto IL_0173;
				case 1:
					<>1__state = -1;
					goto IL_0173;
				case 2:
					<>1__state = -1;
					goto IL_01e9;
				case 3:
					<>1__state = -1;
					goto IL_021d;
				case 4:
					{
						<>1__state = -1;
						break;
					}
					IL_0173:
					if (!PlatformInitializer.SaveDataInitialized)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					LoadingIndicator.SetVisibility(true);
					goto IL_01e9;
					IL_021d:
					if (PlatformInitializer.WaitingForInputDevice)
					{
						<>2__current = null;
						<>1__state = 3;
						return true;
					}
					LoadingIndicator.SetVisibility(false);
					break;
					IL_01e9:
					if (!<loadOperation>5__5.IsDone)
					{
						<progress>5__7 = <loadOperation>5__5.Progress;
						AccessTools.Field(typeof(SceneLoader), "_fakeProgress").SetValue(instance, <progress>5__7);
						LoadingIndicator.SetProgress(<progress>5__7);
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					PlatformInitializer.InputDeviceRequired = true;
					goto IL_021d;
				}
				if (!LoadingIndicator.IsCompletelyInvisible)
				{
					<>2__current = null;
					<>1__state = 4;
					return true;
				}
				Debug.Log((object)"FastSceneLoader: Scene loading completed.");
				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 bool Prefix(SceneLoader __instance, ref IEnumerator __result)
		{
			__result = FastLoadSceneAsync(__instance);
			return false;
		}

		[IteratorStateMachine(typeof(<FastLoadSceneAsync>d__1))]
		private static IEnumerator FastLoadSceneAsync(SceneLoader instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FastLoadSceneAsync>d__1(0)
			{
				instance = instance
			};
		}
	}

	[HarmonyPatch(typeof(SpawnSystem), "Awake")]
	private class SpawnSystemAwakePatch
	{
		private static void Postfix(SpawnSystem __instance)
		{
			FramePerSecondPlus framePerSecondPlus = Chainloader.PluginInfos["vaffle.FramePerSecondPlus"].Instance as FramePerSecondPlus;
			((MonoBehaviour)__instance).CancelInvoke("UpdateSpawning");
			((MonoBehaviour)__instance).InvokeRepeating("UpdateSpawning", 10f, spawnUpdateInterval.Value);
		}
	}

	[HarmonyPatch(typeof(SpawnPrefab), "Start")]
	private class SpawnPrefabStartPatch
	{
		[CompilerGenerated]
		private sealed class <DelayedSpawn>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SpawnPrefab instance;

			public float delay;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					OptimizedTrySpawn(instance);
					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 bool Prefix(SpawnPrefab __instance)
		{
			__instance.m_nview = ((Component)__instance).GetComponentInParent<ZNetView>();
			if ((Object)(object)__instance.m_nview == (Object)null)
			{
				if (enableLogging.Value)
				{
					ZLog.LogWarning((object)("SpawnerPrefab cant find netview " + ((Object)((Component)__instance).gameObject).name));
				}
				return false;
			}
			float value = spawnDelay.Value;
			if (value <= 0f)
			{
				OptimizedTrySpawn(__instance);
			}
			else
			{
				((MonoBehaviour)__instance).StartCoroutine(DelayedSpawn(__instance, value));
			}
			return false;
		}

		[IteratorStateMachine(typeof(<DelayedSpawn>d__1))]
		private static IEnumerator DelayedSpawn(SpawnPrefab instance, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedSpawn>d__1(0)
			{
				instance = instance,
				delay = delay
			};
		}

		private static void OptimizedTrySpawn(SpawnPrefab instance)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!instance.m_nview.IsValid() || !instance.m_nview.IsOwner())
			{
				return;
			}
			string text = "HasSpawned_" + ((Object)((Component)instance).gameObject).name;
			ZDO zDO = instance.m_nview.GetZDO();
			if (!zDO.GetBool(text, false))
			{
				if (enableLogging.Value)
				{
					ZLog.Log((object)("SpawnPrefab " + ((Object)((Component)instance).gameObject).name + " SPAWNING " + ((Object)instance.m_prefab).name));
				}
				GameObject val = Object.Instantiate<GameObject>(instance.m_prefab, ((Component)instance).transform.position, ((Component)instance).transform.rotation);
				zDO.Set(text, true);
			}
		}
	}

	[HarmonyPatch(typeof(ZoneSystem), "GenerateLocationsTimeSliced", new Type[] { })]
	private class GenerateLocationsTimeSlicedPatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_0
		{
			public ZoneSystem instance;

			public int maxAttempts;

			public ConcurrentDictionary<Vector2i, LocationInstance> newLocations;

			public bool logging;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_1
		{
			public ZoneLocation location;

			public <>c__DisplayClass1_0 CS$<>8__locals1;

			internal int <OptimizedGenerateLocationsTimeSliced>b__2()
			{
				return ProcessLocation(CS$<>8__locals1.instance, location, CS$<>8__locals1.maxAttempts, WorldGenerator.instance.GetSeed(), CS$<>8__locals1.newLocations, CS$<>8__locals1.logging);
			}
		}

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

			private object <>2__current;

			public ZoneSystem instance;

			public float timeBudget;

			public int maxAttempts;

			public bool multithreading;

			public bool logging;

			private <>c__DisplayClass1_0 <>8__1;

			private Stopwatch <stopwatch>5__2;

			private DateTime <startTime>5__3;

			private List<ZoneLocation> <ordered>5__4;

			private ConcurrentBag<Task<int>> <locationTasks>5__5;

			private int <i>5__6;

			private <>c__DisplayClass1_1 <>8__7;

			private int <iterations>5__8;

			private IEnumerator<KeyValuePair<Vector2i, LocationInstance>> <>s__9;

			private KeyValuePair<Vector2i, LocationInstance> <kvp>5__10;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<stopwatch>5__2 = null;
				<ordered>5__4 = null;
				<locationTasks>5__5 = null;
				<>8__7 = null;
				<>s__9 = null;
				<kvp>5__10 = default(KeyValuePair<Vector2i, LocationInstance>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0365: Unknown result type (might be due to invalid IL or missing references)
				//IL_0370: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass1_0();
					<>8__1.instance = instance;
					<>8__1.maxAttempts = maxAttempts;
					<>8__1.logging = logging;
					<>8__1.instance.m_estimatedGenerateLocationsCompletionTime = DateTime.MaxValue;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					LoadingIndicator.SetProgress(0f);
					LoadingIndicator.SetProgressVisibility(true);
					LoadingIndicator.SetText("$menu_generating");
					<stopwatch>5__2 = Stopwatch.StartNew();
					<startTime>5__3 = DateTime.UtcNow;
					<>8__1.instance.ClearNonPlacedLocations();
					<ordered>5__4 = <>8__1.instance.m_locations.OrderByDescending((ZoneLocation a) => a.m_prioritized).ToList();
					<ordered>5__4.RemoveAll((ZoneLocation l) => !l.m_enable || l.m_quantity == 0);
					<locationTasks>5__5 = new ConcurrentBag<Task<int>>();
					<>8__1.newLocations = new ConcurrentDictionary<Vector2i, LocationInstance>();
					<i>5__6 = 0;
					goto IL_02bf;
				case 2:
					<>1__state = -1;
					<stopwatch>5__2.Restart();
					goto IL_0289;
				case 3:
					{
						<>1__state = -1;
						<stopwatch>5__2.Restart();
						goto IL_030f;
					}
					IL_030f:
					if (!<locationTasks>5__5.IsEmpty)
					{
						<>2__current = null;
						<>1__state = 3;
						return true;
					}
					break;
					IL_0289:
					LoadingIndicator.SetProgress((float)(<i>5__6 + 1) / (float)<ordered>5__4.Count);
					<>8__7 = null;
					<i>5__6++;
					goto IL_02bf;
					IL_02bf:
					if (<i>5__6 < <ordered>5__4.Count)
					{
						<>8__7 = new <>c__DisplayClass1_1();
						<>8__7.CS$<>8__locals1 = <>8__1;
						<>8__7.location = <ordered>5__4[<i>5__6];
						if (multithreading)
						{
							<locationTasks>5__5.Add(Task.Run(() => ProcessLocation(<>8__7.CS$<>8__locals1.instance, <>8__7.location, <>8__7.CS$<>8__locals1.maxAttempts, WorldGenerator.instance.GetSeed(), <>8__7.CS$<>8__locals1.newLocations, <>8__7.CS$<>8__locals1.logging)));
						}
						else
						{
							<iterations>5__8 = ProcessLocation(<>8__7.CS$<>8__locals1.instance, <>8__7.location, <>8__7.CS$<>8__locals1.maxAttempts, WorldGenerator.instance.GetSeed(), <>8__7.CS$<>8__locals1.newLocations, <>8__7.CS$<>8__locals1.logging);
						}
						if (<stopwatch>5__2.Elapsed.TotalSeconds >= (double)timeBudget)
						{
							<>2__current = null;
							<>1__state = 2;
							return true;
						}
						goto IL_0289;
					}
					if (!multithreading)
					{
						break;
					}
					goto IL_030f;
				}
				<>s__9 = <>8__1.newLocations.GetEnumerator();
				try
				{
					while (<>s__9.MoveNext())
					{
						<kvp>5__10 = <>s__9.Current;
						<>8__1.instance.m_locationInstances[<kvp>5__10.Key] = <kvp>5__10.Value;
						<kvp>5__10 = default(KeyValuePair<Vector2i, LocationInstance>);
					}
				}
				finally
				{
					if (<>s__9 != null)
					{
						<>s__9.Dispose();
					}
				}
				<>s__9 = null;
				LoadingIndicator.SetProgress(1f);
				LoadingIndicator.SetProgressVisibility(false);
				<>8__1.instance.LocationsGenerated = true;
				if (<>8__1.logging)
				{
					ZLog.Log((object)$"Done generating locations, duration: {(DateTime.UtcNow - <startTime>5__3).TotalMilliseconds} ms");
				}
				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 bool Prefix(ZoneSystem __instance, ref IEnumerator __result)
		{
			float value = generationTimeBudget.Value;
			int value2 = maxLocationAttempts.Value;
			bool value3 = enableMultithreading.Value;
			bool value4 = enableLogging.Value;
			if (value4)
			{
				ZLog.Log((object)"Applying optimized GenerateLocationsTimeSliced patch.");
			}
			__result = OptimizedGenerateLocationsTimeSliced(__instance, value, value2, value3, value4);
			return false;
		}

		[IteratorStateMachine(typeof(<OptimizedGenerateLocationsTimeSliced>d__1))]
		private static IEnumerator OptimizedGenerateLocationsTimeSliced(ZoneSystem instance, float timeBudget, int maxAttempts, bool multithreading, bool logging)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OptimizedGenerateLocationsTimeSliced>d__1(0)
			{
				instance = instance,
				timeBudget = timeBudget,
				maxAttempts = maxAttempts,
				multithreading = multithreading,
				logging = logging
			};
		}

		private static int ProcessLocation(ZoneSystem instance, ZoneLocation location, int maxAttempts, int seed, ConcurrentDictionary<Vector2i, LocationInstance> newLocations, bool logging)
		{
			//IL_0028: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_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_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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Invalid comparison between Unknown and I4
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Invalid comparison between Unknown and I4
			//IL_01c4: 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_026c: 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_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = instance.CountNrOfLocation(location);
			if (location.m_unique && num2 > 0)
			{
				return num;
			}
			State state = Random.state;
			Random.InitState(seed + StringExtensionMethods.GetStableHashCode(location.m_prefab.Name));
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			int num9 = 0;
			int num10 = 0;
			int num11 = 0;
			int num12 = 0;
			float num13 = 10000f;
			if (location.m_centerFirst)
			{
				num13 = location.m_minDistance;
			}
			Color val = default(Color);
			float num15 = default(float);
			Vector3 val2 = default(Vector3);
			Color val4 = default(Color);
			for (int i = 0; i < maxAttempts; i++)
			{
				if (num2 >= location.m_quantity)
				{
					break;
				}
				Vector2i randomZone = ZoneSystem.GetRandomZone(num13);
				if (location.m_centerFirst)
				{
					num13 += 1f;
				}
				if (instance.m_locationInstances.ContainsKey(randomZone) || newLocations.ContainsKey(randomZone))
				{
					num3++;
				}
				else
				{
					if (instance.IsZoneGenerated(randomZone))
					{
						continue;
					}
					Vector3 zonePos = ZoneSystem.GetZonePos(randomZone);
					BiomeArea biomeArea = WorldGenerator.instance.GetBiomeArea(zonePos);
					if ((location.m_biomeArea & biomeArea) == 0)
					{
						num6++;
						continue;
					}
					for (int j = 0; j < 20; j++)
					{
						num++;
						Vector3 randomPointInZone = ZoneSystem.GetRandomPointInZone(randomZone, Mathf.Max(location.m_exteriorRadius, location.m_interiorRadius));
						float magnitude = ((Vector3)(ref randomPointInZone)).magnitude;
						if ((location.m_minDistance != 0f && magnitude < location.m_minDistance) || (location.m_maxDistance != 0f && magnitude > location.m_maxDistance))
						{
							num4++;
							continue;
						}
						Biome biome = WorldGenerator.instance.GetBiome(randomPointInZone);
						if ((location.m_biome & biome) == 0)
						{
							num5++;
							continue;
						}
						randomPointInZone.y = WorldGenerator.instance.GetHeight(randomPointInZone.x, randomPointInZone.z, ref val);
						float num14 = randomPointInZone.y - 30f;
						if (num14 < location.m_minAltitude || num14 > location.m_maxAltitude)
						{
							num7++;
							continue;
						}
						if (location.m_inForest)
						{
							float forestHeight = WorldGenerator.instance.GetForestHeight(randomPointInZone.x, randomPointInZone.y);
							if (forestHeight < location.m_forestTresholdMin || forestHeight > location.m_forestTresholdMax)
							{
								num8++;
								continue;
							}
						}
						WorldGenerator.instance.GetTerrainDelta(randomPointInZone, location.m_exteriorRadius, ref num15, ref val2);
						if (num15 > location.m_maxTerrainDelta || num15 < location.m_minTerrainDelta)
						{
							num11++;
							continue;
						}
						if (location.m_minDistanceFromSimilar > 0f && instance.HaveLocationInRange(location.m_prefab.Name, location.m_group, randomPointInZone, location.m_minDistanceFromSimilar, false))
						{
							num9++;
							continue;
						}
						if (location.m_maxDistanceFromSimilar > 0f && !instance.HaveLocationInRange(location.m_prefabName, location.m_groupMax, randomPointInZone, location.m_maxDistanceFromSimilar, true))
						{
							num10++;
							continue;
						}
						float a = val.a;
						if (location.m_minimumVegetation > 0f && a <= location.m_minimumVegetation)
						{
							num12++;
							continue;
						}
						if (location.m_maximumVegetation < 1f && a >= location.m_maximumVegetation)
						{
							num12++;
							continue;
						}
						if (location.m_surroundCheckVegetation)
						{
							float num16 = 0f;
							for (int k = 0; k < location.m_surroundCheckLayers; k++)
							{
								float num17 = ((float)k + 1f) / (float)location.m_surroundCheckLayers * location.m_surroundCheckDistance;
								for (int l = 0; l < 6; l++)
								{
									float num18 = (float)l / 6f * (float)Math.PI * 2f;
									Vector3 val3 = randomPointInZone + new Vector3(Mathf.Sin(num18) * num17, 0f, Mathf.Cos(num18) * num17);
									WorldGenerator.instance.GetHeight(val3.x, val3.z, ref val4);
									float num19 = (location.m_surroundCheckDistance - num17) / (location.m_surroundCheckDistance * 2f);
									num16 += val4.a * num19;
								}
							}
							instance.s_tempVeg.Add(num16);
							if (instance.s_tempVeg.Count < 10)
							{
								continue;
							}
							float num20 = instance.s_tempVeg.Max();
							float num21 = instance.s_tempVeg.Average();
							float num22 = num21 + (num20 - num21) * location.m_surroundBetterThanAverage;
							if (num16 < num22)
							{
								continue;
							}
						}
						LocationInstance val5 = default(LocationInstance);
						val5.m_location = location;
						val5.m_position = randomPointInZone;
						val5.m_placed = false;
						LocationInstance value = val5;
						newLocations.TryAdd(randomZone, value);
						num2++;
						break;
					}
				}
			}
			if (logging && num2 < location.m_quantity)
			{
				ZLog.LogWarning((object)$"Failed to place all {location.m_prefab.Name}, placed {num2}/{location.m_quantity}");
				ZLog.DevLog((object)$"Errors: LocationInZone={num3}, CenterDistance={num4}, Biome={num5}, BiomeArea={num6}, Alt={num7}, Forest={num8}, Similar={num9}, NotSimilar={num10}, TerrainDelta={num11}, Vegetation={num12}");
			}
			Random.state = state;
			return num;
		}
	}

	[HarmonyPatch(typeof(ZoneSystem), "PlaceVegetation")]
	private class PlaceVegetationPatch
	{
		private static bool Prefix(ZoneSystem __instance, Vector2i zoneID, Vector3 zoneCenterPos, Transform parent, Heightmap hmap, List<ClearArea> clearAreas, SpawnMode mode, List<GameObject> spawnedObjects)
		{
			//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_005f: 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_0088: 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_0166: 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)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0755: 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_01bd: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: 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_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: 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_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Invalid comparison between Unknown and I4
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: 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_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_0638: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_0649: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Invalid comparison between Unknown and I4
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_065b: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Invalid comparison between Unknown and I4
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_0675: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Invalid comparison between Unknown and I4
			bool value = enableHeightmapCaching.Value;
			bool value2 = enableLogging.Value;
			State state = Random.state;
			int seed = WorldGenerator.instance.GetSeed();
			ConcurrentDictionary<Vector3, (float, Biome, BiomeArea)> concurrentDictionary = (value ? new ConcurrentDictionary<Vector3, (float, Biome, BiomeArea)>() : null);
			Vector3 val = default(Vector3);
			Biome item = default(Biome);
			BiomeArea item2 = default(BiomeArea);
			Heightmap val3 = default(Heightmap);
			Vector3 up = default(Vector3);
			float num9 = default(float);
			Vector3 val4 = default(Vector3);
			foreach (ZoneVegetation item3 in __instance.m_vegetation)
			{
				if (!item3.m_enable || !hmap.HaveBiome(item3.m_biome))
				{
					continue;
				}
				Random.InitState(seed + zoneID.x * 4271 + zoneID.y * 9187 + StringExtensionMethods.GetStableHashCode(((Object)item3.m_prefab).name));
				int num = Random.Range((int)item3.m_min, (int)item3.m_max + 1);
				if (item3.m_max < 1f && Random.value > item3.m_max)
				{
					continue;
				}
				bool flag = (Object)(object)item3.m_prefab.GetComponent<ZNetView>() != (Object)null;
				float num2 = Mathf.Cos((float)Math.PI / 180f * item3.m_maxTilt);
				float num3 = Mathf.Cos((float)Math.PI / 180f * item3.m_minTilt);
				float num4 = 32f - item3.m_groupRadius;
				int num5 = 0;
				int num6 = (item3.m_forcePlacement ? (num * 50) : num);
				for (int i = 0; i < num6; i++)
				{
					if (num5 >= num)
					{
						break;
					}
					((Vector3)(ref val))..ctor(Random.Range(zoneCenterPos.x - num4, zoneCenterPos.x + num4), 0f, Random.Range(zoneCenterPos.z - num4, zoneCenterPos.z + num4));
					int num7 = Random.Range(item3.m_groupSizeMin, item3.m_groupSizeMax + 1);
					bool flag2 = false;
					for (int j = 0; j < num7; j++)
					{
						Vector3 val2 = ((j == 0) ? val : __instance.GetRandomPointInRadius(val, item3.m_groupRadius));
						if (item3.m_blockCheck && __instance.IsBlocked(val2))
						{
							continue;
						}
						if (value && concurrentDictionary.TryGetValue(val2, out var value3))
						{
							val2.y = value3.Item1;
							item = value3.Item2;
							item2 = value3.Item3;
							val3 = hmap;
							up = Vector3.up;
						}
						else
						{
							__instance.GetGroundData(ref val2, ref up, ref item, ref item2, ref val3);
							if (value)
							{
								concurrentDictionary.TryAdd(val2, (val2.y, item, item2));
							}
						}
						if ((item3.m_biome & item) == 0 || (item3.m_biomeArea & item2) == 0)
						{
							continue;
						}
						float num8 = val2.y - 30f;
						if (num8 < item3.m_minAltitude || num8 > item3.m_maxAltitude)
						{
							continue;
						}
						if (item3.m_minVegetation != item3.m_maxVegetation)
						{
							float vegetationMask = val3.GetVegetationMask(val2);
							if (vegetationMask < item3.m_minVegetation || vegetationMask > item3.m_maxVegetation)
							{
								continue;
							}
						}
						if (item3.m_minOceanDepth != item3.m_maxOceanDepth)
						{
							float oceanDepth = val3.GetOceanDepth(val2);
							if (oceanDepth < item3.m_minOceanDepth || oceanDepth > item3.m_maxOceanDepth)
							{
								continue;
							}
						}
						if (up.y < num2 || up.y > num3)
						{
							continue;
						}
						if (item3.m_terrainDeltaRadius > 0f)
						{
							__instance.GetTerrainDelta(val2, item3.m_terrainDeltaRadius, ref num9, ref val4);
							if (num9 < item3.m_minTerrainDelta || num9 > item3.m_maxTerrainDelta)
							{
								continue;
							}
						}
						if (item3.m_inForest)
						{
							float forestHeight = WorldGenerator.instance.GetForestHeight(val2.x, val2.y);
							if (forestHeight < item3.m_forestTresholdMin || forestHeight > item3.m_forestTresholdMax)
							{
								continue;
							}
						}
						if (item3.m_surroundCheckVegetation)
						{
							float num10 = 0f;
							int num11 = 4;
							for (int k = 0; k < item3.m_surroundCheckLayers; k++)
							{
								float num12 = ((float)k + 1f) / (float)item3.m_surroundCheckLayers * item3.m_surroundCheckDistance;
								for (int l = 0; l < num11; l++)
								{
									float num13 = (float)l / (float)num11 * (float)Math.PI * 2f;
									Vector3 val5 = val2 + new Vector3(Mathf.Sin(num13) * num12, 0f, Mathf.Cos(num13) * num12);
									float vegetationMask2 = val3.GetVegetationMask(val5);
									float num14 = (item3.m_surroundCheckDistance - num12) / (item3.m_surroundCheckDistance * 2f);
									num10 += vegetationMask2 * num14;
								}
							}
							__instance.s_tempVeg.Add(num10);
							if (__instance.s_tempVeg.Count < 5)
							{
								continue;
							}
							float num15 = __instance.s_tempVeg.Max();
							float num16 = __instance.s_tempVeg.Average();
							float num17 = num16 + (num15 - num16) * item3.m_surroundBetterThanAverage;
							if (num10 < num17)
							{
								continue;
							}
						}
						if (__instance.InsideClearArea(clearAreas, val2))
						{
							continue;
						}
						float num18 = Random.Range(item3.m_scaleMin, item3.m_scaleMax);
						float num19 = Random.Range(0f, 360f);
						float num20 = Random.Range(0f - item3.m_randTilt, item3.m_randTilt);
						float num21 = Random.Range(0f - item3.m_randTilt, item3.m_randTilt);
						if (item3.m_snapToWater)
						{
							val2.y = 30f;
						}
						val2.y += item3.m_groundOffset;
						Quaternion val6 = ((item3.m_chanceToUseGroundTilt > 0f && Random.value <= item3.m_chanceToUseGroundTilt) ? Quaternion.LookRotation(Vector3.Cross(up, Quaternion.Euler(0f, num19, 0f) * Vector3.forward), up) : Quaternion.Euler(num20, num19, num21));
						if (flag && ((int)mode == 0 || (int)mode == 2))
						{
							if ((int)mode == 2)
							{
								ZNetView.StartGhostInit();
							}
							GameObject val7 = Object.Instantiate<GameObject>(item3.m_prefab, val2, val6);
							ZNetView component = val7.GetComponent<ZNetView>();
							component.SetLocalScale(new Vector3(num18, num18, num18));
							if ((int)mode == 2)
							{
								spawnedObjects.Add(val7);
								ZNetView.FinishGhostInit();
							}
						}
						else
						{
							GameObject val8 = Object.Instantiate<GameObject>(item3.m_prefab, val2, val6);
							val8.transform.localScale = new Vector3(num18, num18, num18);
							val8.transform.SetParent(parent, true);
						}
						flag2 = true;
					}
					if (flag2)
					{
						num5++;
					}
				}
				Random.state = state;
				if (value2)
				{
					ZLog.Log((object)$"Placed {num5} vegetation objects in zone {zoneID}");
				}
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(ZoneSystem), "GetGroundHeight", new Type[] { typeof(Vector3) })]
	private class GetGroundHeightPatch
	{
		private static readonly ConcurrentDictionary<Vector3, float> heightCache = new ConcurrentDictionary<Vector3, float>();

		private static bool Prefix(ZoneSystem __instance, Vector3 p, ref float __result)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_008a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			bool value = enableHeightmapCaching.Value;
			if (value && heightCache.TryGetValue(p, out var value2))
			{
				__result = value2;
				return false;
			}
			p.y = 6000f;
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(p, Vector3.down, ref val, 7000f, __instance.m_terrainRayMask))
			{
				__result = ((RaycastHit)(ref val)).point.y;
				if (value)
				{
					heightCache[p] = ((RaycastHit)(ref val)).point.y;
				}
				return false;
			}
			__result = p.y;
			return false;
		}
	}

	[HarmonyPatch(typeof(LightFlicker), "CustomUpdate")]
	private class LightFlicker_Update_Patch : MonoBehaviour
	{
		private static bool Prefix(LightFlicker __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)__instance.m_light))
			{
				return false;
			}
			if (Settings.ReduceFlashingLights)
			{
				if ((int)__instance.m_flashingLightsSetting == 2)
				{
					__instance.m_light.intensity = 0f;
					return false;
				}
				if ((int)__instance.m_flashingLightsSetting == 3)
				{
					__instance.m_light.intensity = 1f;
					return false;
				}
			}
			__instance.m_light.intensity = __instance.m_baseIntensity;
			return false;
		}
	}

	[HarmonyPatch(typeof(SceneLoader), "Start")]
	private class SceneLoaderOff
	{
		private static void Prefix(SceneLoader __instance)
		{
			__instance._showLogos = !skipIntro.Value;
		}
	}

	[HarmonyPatch(typeof(Player), "Start")]
	private class BeforeSpawnPlayer
	{
		private static void Prefix(Player __instance)
		{
			QualitySettings.realtimeReflectionProbes = false;
			QualitySettings.softParticles = false;
			QualitySettings.shadowCascades = 0;
			QualitySettings.shadowNearPlaneOffset = 0f;
			QualitySettings.particleRaycastBudget = particleRaycastBudget.Value;
			QualitySettings.softVegetation = false;
			if (shadowDistanceToggle.Value)
			{
				QualitySettings.shadowDistance = shadowDistance.Value;
			}
			if (terrainTreeDistanceToggle.Value)
			{
				QualitySettings.terrainTreeDistance = terrainTreeDistance.Value;
			}
		}
	}

	[HarmonyPatch(typeof(Smoke), "CustomUpdate")]
	private class SlowUpdaterFix
	{
		private static bool Prefix(Smoke __instance, float deltaTime, float time)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.m_fadeTimer >= 0f)
			{
				__instance.m_fadeTimer += deltaTime;
				if (__instance.m_fadeTimer >= __instance.m_fadetime)
				{
					Object.Destroy((Object)(object)((Component)__instance).gameObject);
				}
				return false;
			}
			__instance.m_time += deltaTime;
			if (__instance.m_time > __instance.m_ttl)
			{
				__instance.StartFadeOut();
				return false;
			}
			float num = 1f - __instance.m_time / __instance.m_ttl;
			float mass = num * num;
			__instance.m_body.mass = mass;
			Vector3 velocity = __instance.m_body.velocity;
			Vector3 vel = __instance.m_vel;
			vel.y *= num;
			Vector3 val = (vel - velocity) * (__instance.m_force * deltaTime);
			__instance.m_body.AddForce(val, (ForceMode)2);
			return false;
		}
	}

	private static ConfigEntry<float> spawnUpdateInterval;

	private static ConfigEntry<bool> enableMultithreading;

	private static ConfigEntry<bool> enableLogging;

	private static ConfigEntry<float> spawnDelay;

	private static ConfigEntry<float> generationTimeBudget;

	private static ConfigEntry<int> maxLocationAttempts;

	private static ConfigEntry<bool> enableHeightmapCaching;

	private static ConfigEntry<float> grassDistance;

	private static ConfigEntry<int> particleRaycastBudget;

	private static ConfigEntry<bool> shadowDistanceToggle;

	private static ConfigEntry<float> shadowDistance;

	private static ConfigEntry<bool> terrainTreeDistanceToggle;

	private static ConfigEntry<float> terrainTreeDistance;

	private static int warningCount;

	private static int errorCount;

	private static ManualLogSource Log;

	private string[] PrefabLightNames = new string[6] { "piece_groundtorch", "piece_groundtorch_blue", "piece_groundtorch_green", "piece_groundtorch_mist", "piece_groundtorch_wood", "piece_walltorch" };

	private static ConfigEntry<bool> skipIntro;

	private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
	{
		return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
	}

	private void AddConfiguration()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		skipIntro = config("General", "SkipIntro", value: true, new ConfigDescription("Skip the game logo to speed up the loading of the game", (AcceptableValueBase)null, Array.Empty<object>()));
	}

	private void Awake()
	{
		spawnUpdateInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnUpdateInterval", 2f, "Interval between spawn updates in seconds");
		enableMultithreading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMultithreading", true, "Enable multithreaded spawn calculations");
		enableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableLogging", false, "Enable logging for spawn events");
		spawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SpawnDelay", 1f, "Delay before spawning in seconds (0 for immediate spawn)");
		generationTimeBudget = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GenerationTimeBudget", 0.1f, "Time budget per frame for location generation (seconds)");
		maxLocationAttempts = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxLocationAttempts", 50000, "Max attempts per location (lower to speed up)");
		enableHeightmapCaching = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableHeightmapCaching", true, "Cache heightmap data for zones");
		grassDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GrassDistance", 20f, "Distance for render grass");
		particleRaycastBudget = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ParticleRaycastBudget", 1024, "Affects the quality of the light emitted by light sources");
		shadowDistanceToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Warning", "ShadowDistance", false, "If enabled, the shadow drawing distance setting will be available for editing.");
		shadowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Warning", "ShadowDistanceToggle", 150f, "Shadow drawing distance");
		terrainTreeDistanceToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Warning", "TerrainTreeDistanceToggle", false, "If enabled, the tree drawing distance setting will be available for editing.");
		terrainTreeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Warning", "TerrainTreeDistance", 5000f, "Trees drawing distance");
		((BaseUnityPlugin)this).Logger.LogInfo((object)spawnUpdateInterval.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)enableMultithreading.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)enableLogging.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)spawnDelay.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)generationTimeBudget.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)maxLocationAttempts.Value);
		((BaseUnityPlugin)this).Logger.LogInfo((object)enableHeightmapCaching.Value);
		((BaseUnityPlugin)this).Logger.LogEvent += OnLogEvent;
		Log = ((BaseUnityPlugin)this).Logger;
		AddConfiguration();
		QualitySettings.realtimeReflectionProbes = false;
		QualitySettings.softParticles = false;
		QualitySettings.shadowCascades = 0;
		QualitySettings.shadowNearPlaneOffset = 0f;
		QualitySettings.particleRaycastBudget = particleRaycastBudget.Value;
		QualitySettings.softVegetation = false;
		if (shadowDistanceToggle.Value)
		{
			QualitySettings.shadowDistance = shadowDistance.Value;
		}
		if (terrainTreeDistanceToggle.Value)
		{
			QualitySettings.terrainTreeDistance = terrainTreeDistance.Value;
		}
		PrefabManager.OnPrefabsRegistered += CustomAwake;
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
	}

	private void CustomAwake()
	{
		for (int i = 0; i < PrefabLightNames.Length; i++)
		{
			TorchParticles(PrefabManager.Instance.GetPrefab(PrefabLightNames[i]));
		}
	}

	private void TorchParticles(GameObject gameObject)
	{
		string text = "fx_Torch_Basic";
		if (((Object)gameObject).name == "piece_groundtorch_blue")
		{
			text = "fx_Torch_Blue";
		}
		else if (((Object)gameObject).name == "piece_groundtorch_green")
		{
			text = "fx_Torch_Green";
		}
		else if (((Object)gameObject).name == "piece_groundtorch_mist")
		{
			text = "sparcs_front";
		}
		ParticleSystem component = ((Component)ExposedGameObjectExtension.FindDeepChild(gameObject, text, (IterativeSearchType)1)).GetComponent<ParticleSystem>();
		component.startLifetime = 0.2f;
		component.gravityModifier = -0.3f;
	}

	private void OnLogEvent(object sender, LogEventArgs eventArgs)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Invalid comparison between Unknown and I4
		LogLevel level = eventArgs.Level;
		LogLevel val = level;
		if ((int)val <= 4)
		{
			if ((int)val != 2)
			{
				if ((int)val == 4)
				{
					warningCount++;
				}
			}
			else
			{
				errorCount++;
			}
		}
		else if ((int)val != 8 && (int)val == 16)
		{
		}
	}

	private void OnDestroy()
	{
		((BaseUnityPlugin)this).Logger.LogEvent -= OnLogEvent;
	}
}