Decompiled source of Spawn That v1.2.17

Valheim.SpawnThat.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CreatureLevelControl;
using EpicLoot;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RagnarsRokare.MobAI;
using SpawnThat.Caches;
using SpawnThat.Configuration;
using SpawnThat.Configuration.Sync;
using SpawnThat.ConsoleCommands;
using SpawnThat.Core;
using SpawnThat.Core.Cache;
using SpawnThat.Core.Configuration;
using SpawnThat.Core.Network;
using SpawnThat.Core.Toml;
using SpawnThat.Core.Toml.Parsers;
using SpawnThat.Core.Toml.Writers;
using SpawnThat.Debugging;
using SpawnThat.Integrations;
using SpawnThat.Integrations.CLLC.Conditions;
using SpawnThat.Integrations.CLLC.Models;
using SpawnThat.Integrations.CLLC.Modifiers;
using SpawnThat.Integrations.EpicLoot.Conditions;
using SpawnThat.Integrations.EpicLoot.Models;
using SpawnThat.Integrations.MobAi.Modifiers;
using SpawnThat.Lifecycle;
using SpawnThat.Options.Conditions;
using SpawnThat.Options.Identifiers;
using SpawnThat.Options.Modifiers;
using SpawnThat.Options.PositionConditions;
using SpawnThat.Spawners;
using SpawnThat.Spawners.Contexts;
using SpawnThat.Spawners.LocalSpawner;
using SpawnThat.Spawners.LocalSpawner.Caches;
using SpawnThat.Spawners.LocalSpawner.Configuration;
using SpawnThat.Spawners.LocalSpawner.Configuration.BepInEx;
using SpawnThat.Spawners.LocalSpawner.Managers;
using SpawnThat.Spawners.LocalSpawner.Models;
using SpawnThat.Spawners.LocalSpawner.Services;
using SpawnThat.Spawners.LocalSpawner.Startup;
using SpawnThat.Spawners.LocalSpawner.Sync;
using SpawnThat.Spawners.SpawnAreaSpawner;
using SpawnThat.Spawners.SpawnAreaSpawner.Configuration;
using SpawnThat.Spawners.SpawnAreaSpawner.Configuration.BepInEx;
using SpawnThat.Spawners.SpawnAreaSpawner.Debug;
using SpawnThat.Spawners.SpawnAreaSpawner.Managers;
using SpawnThat.Spawners.SpawnAreaSpawner.Models;
using SpawnThat.Spawners.SpawnAreaSpawner.Services;
using SpawnThat.Spawners.SpawnAreaSpawner.Startup;
using SpawnThat.Spawners.SpawnAreaSpawner.Sync;
using SpawnThat.Spawners.WorldSpawner;
using SpawnThat.Spawners.WorldSpawner.Configurations;
using SpawnThat.Spawners.WorldSpawner.Configurations.BepInEx;
using SpawnThat.Spawners.WorldSpawner.Debug;
using SpawnThat.Spawners.WorldSpawner.Managers;
using SpawnThat.Spawners.WorldSpawner.Services;
using SpawnThat.Spawners.WorldSpawner.Startup;
using SpawnThat.Spawners.WorldSpawner.Sync;
using SpawnThat.Utilities;
using SpawnThat.Utilities.Enums;
using SpawnThat.Utilities.Extensions;
using SpawnThat.Utilities.Spatial;
using SpawnThat.World.Dungeons;
using SpawnThat.World.Locations;
using SpawnThat.World.Maps;
using SpawnThat.World.Maps.Area;
using SpawnThat.World.Queries;
using SpawnThat.World.Zone;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("SpawnThat.Tests")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("A Sharp Pen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim mod and tool for configuring spawners.")]
[assembly: AssemblyFileVersion("1.2.17.0")]
[assembly: AssemblyInformationalVersion("1.2.17+fba3978ae42510e12b7937eb0ad5905a359a6322")]
[assembly: AssemblyProduct("Valheim.SpawnThat")]
[assembly: AssemblyTitle("Valheim.SpawnThat")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ASharpPen/Valheim.SpawnThat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.17.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SpawnThat
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("asharppen.valheim.spawn_that", "Spawn That!", "1.2.17")]
	public class SpawnThatPlugin : BaseUnityPlugin
	{
		public const string ModId = "asharppen.valheim.spawn_that";

		public const string PluginName = "Spawn That!";

		public const string Version = "1.2.17";

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Log.Logger = ((BaseUnityPlugin)this).Logger;
			ConfigurationManager.GeneralConfig = ConfigurationManager.LoadGeneral();
			Startup.SetupServices();
			new Harmony("asharppen.valheim.spawn_that").PatchAll();
		}
	}
	internal static class Startup
	{
		public static void SetupServices()
		{
			GeneralConfigurationSetup.SetupMainConfiguration();
			LocalSpawnerSetup.SetupLocalSpawners();
			WorldSpawnerSetup.SetupWorldSpawners();
			SpawnAreaSpawnerSetup.SetupSpawnAreaSpawners();
			LifecycleManager.OnLateInit += InitConfiguration;
			ZoneSystemSyncSetup.Configure();
			RegisterCommands();
		}

		private static void InitConfiguration()
		{
			if (LifecycleManager.GameState == GameState.Singleplayer || LifecycleManager.GameState == GameState.DedicatedServer)
			{
				SpawnerConfigurationManager.BuildConfigurations();
			}
		}

		private static void RegisterCommands()
		{
			AreaCommand.Register();
			AreaRollCommand.Register();
			AreaRollHeatmapCommand.Register();
			RoomCommand.Register();
			WhereDoesItSpawnCommand.Register();
		}
	}
}
namespace SpawnThat.World
{
	internal class ZoneHeightmap : IZone
	{
		private Heightmap Heightmap { get; }

		public int Width { get; }

		public Biome Biome { get; }

		public Vector2i ZoneId { get; }

		public Vector3 ZonePos { get; }

		public Biome[] BiomeCorners { get; }

		public BiomeArea BiomeArea { get; }

		public ZoneHeightmap(Heightmap heightmap)
		{
			//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)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Heightmap = heightmap;
			ZonePos = ((Component)heightmap).transform.position;
			ZoneId = ZonePos.GetZoneId();
			Width = heightmap.m_width;
			Biome = heightmap.GetBiome(ZonePos, 0.02f, false);
			BiomeCorners = heightmap.m_cornerBiomes.ToArray();
			BiomeArea = heightmap.GetBiomeArea();
		}

		public bool HasBiome(Biome biome)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Heightmap.HaveBiome(biome);
		}

		public Biome GetBiome(Vector3 pos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return Heightmap.GetBiome(pos, 0.02f, false);
		}

		public float Height(Vector3 worldCoordinate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float result = default(float);
			Heightmap.GetHeight(worldCoordinate, ref result);
			return result;
		}

		public float Height(Vector2i zoneLocalCoordinate)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return Heightmap.GetHeight(zoneLocalCoordinate.x, zoneLocalCoordinate.y);
		}

		public float OceanDepth(Vector3 worldCoordinate)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Heightmap.GetOceanDepth(worldCoordinate);
		}

		public float OceanDepth(Vector2i zoneLocalCoordinate)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Vector3 worldCoordinate = Heightmap.CalcVertex(zoneLocalCoordinate.x, zoneLocalCoordinate.y);
			return OceanDepth(worldCoordinate);
		}

		public float Tilt(Vector3 worldCoordinate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003f: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(worldCoordinate + Vector3.up * 5000f, Vector3.down, ref val, 10000f, ZoneSystem.instance.m_terrainRayMask))
			{
				Vector3 normal = ((RaycastHit)(ref val)).normal;
				return 90f - Mathf.Asin(normal.y) * 57.29578f;
			}
			return 0f;
		}

		public Vector2i WorldToZoneCoordinate(Vector3 worldCoordinate)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			int num2 = default(int);
			Heightmap.WorldToVertex(worldCoordinate, ref num, ref num2);
			return new Vector2i(num, num2);
		}
	}
	internal class ZoneSimulated : IZone
	{
		private BiomeArea? _biomeArea;

		private float[] _oceanDepthCorners;

		public int Width { get; } = 64;


		public Biome Biome { get; }

		public Vector2i ZoneId { get; }

		public Vector3 ZonePos { get; }

		public Biome[] BiomeCorners { get; }

		public BiomeArea BiomeArea
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				BiomeArea valueOrDefault = _biomeArea.GetValueOrDefault();
				if (!_biomeArea.HasValue)
				{
					valueOrDefault = (BiomeArea)((!BiomeCorners.All((Biome x) => (int)BiomeCorners[0] == (int)x)) ? 1 : 2);
					_biomeArea = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		private float[] OceanDepthCorners => _oceanDepthCorners ?? (_oceanDepthCorners = CalculateOceanDepths());

		private static Vector2i North { get; } = new Vector2i(0, 1);


		private static Vector2i South { get; } = new Vector2i(0, -1);


		private static Vector2i West { get; } = new Vector2i(-1, 0);


		private static Vector2i East { get; } = new Vector2i(1, 0);


		public ZoneSimulated(Vector2i zoneId)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0084: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Invalid comparison between Unknown and I4
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			ZoneId = zoneId;
			if (((Object)(object)ZoneSystem.instance).IsNotNull())
			{
				ZonePos = ZoneSystem.GetZonePos(ZoneId);
			}
			else
			{
				ZonePos = new Vector3((float)(zoneId.x * Width), 0f, (float)(zoneId.y * Width));
			}
			BiomeCorners = CalculateCornerBiomes(ZonePos);
			Biome val = BiomeCorners[0];
			if ((int)val == (int)BiomeCorners[1] && (int)val == (int)BiomeCorners[2] && (int)val == (int)BiomeCorners[3])
			{
				Biome = val;
			}
			else
			{
				Biome = GetBiome(ZonePos);
			}
		}

		public bool HasBiome(Biome biome)
		{
			//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)
			return BiomeCorners.Any((Biome x) => (x & biome) > 0);
		}

		public Vector2i WorldToZoneCoordinate(Vector3 worldCoordinate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = worldCoordinate - ZonePos;
			int num = Mathf.FloorToInt(val.x + 0.5f) + Width / 2;
			int num2 = Mathf.FloorToInt(val.z + 0.5f) + Width / 2;
			return new Vector2i(num, num2);
		}

		public float Height(Vector3 worldCoordinate)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return Height(WorldToZoneCoordinate(worldCoordinate));
		}

		public float Height(Vector2i zoneLocalCoordinate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Invalid comparison between Unknown and I4
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Invalid comparison between Unknown and I4
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			int y = zoneLocalCoordinate.y;
			int x = zoneLocalCoordinate.x;
			Vector3 val = ZonePos + new Vector3((float)Width * -0.5f, 0f, (float)Width * -0.5f);
			float num = val.z + (float)y;
			float num2 = Mathf.SmoothStep(0f, 1f, (float)y / (float)Width);
			float num3 = val.x + (float)x;
			float num4 = Mathf.SmoothStep(0f, 1f, (float)x / (float)Width);
			WorldGenerator instance = WorldGenerator.instance;
			Biome val2 = BiomeCorners[0];
			Color val3 = default(Color);
			if ((int)val2 == (int)BiomeCorners[1] && (int)val2 == (int)BiomeCorners[2] && (int)val2 == (int)BiomeCorners[3])
			{
				return instance.GetBiomeHeight(val2, num3, num, ref val3, false);
			}
			float biomeHeight = instance.GetBiomeHeight(val2, num3, num, ref val3, false);
			float biomeHeight2 = instance.GetBiomeHeight(BiomeCorners[1], num3, num, ref val3, false);
			float biomeHeight3 = instance.GetBiomeHeight(BiomeCorners[2], num3, num, ref val3, false);
			float biomeHeight4 = instance.GetBiomeHeight(BiomeCorners[3], num3, num, ref val3, false);
			float num5 = Mathf.Lerp(biomeHeight, biomeHeight2, num4);
			float num6 = Mathf.Lerp(biomeHeight3, biomeHeight4, num4);
			return Mathf.Lerp(num5, num6, num2);
		}

		public float OceanDepth(Vector3 worldCoordinate)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return OceanDepth(WorldToZoneCoordinate(worldCoordinate));
		}

		public float OceanDepth(Vector2i zoneLocalCoordinate)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)zoneLocalCoordinate.x / (float)Width;
			float num2 = (float)zoneLocalCoordinate.y / (float)Width;
			float num3 = Mathf.Lerp(OceanDepthCorners[3], OceanDepthCorners[2], num);
			float num4 = Mathf.Lerp(OceanDepthCorners[0], OceanDepthCorners[1], num);
			return Mathf.Lerp(num3, num4, num2);
		}

		private Biome[] CalculateCornerBiomes(Vector3 pos)
		{
			//IL_0000: 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)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected I4, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected I4, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected I4, but got Unknown
			Vector3 val = pos + new Vector3((float)Width * -0.5f, 0f, (float)Width * -0.5f);
			WorldGenerator instance = WorldGenerator.instance;
			return (Biome[])(object)new Biome[4]
			{
				(Biome)(int)instance.GetBiome(val.x, val.z, 0.02f, false),
				(Biome)(int)instance.GetBiome(val.x + (float)Width, val.z, 0.02f, false),
				(Biome)(int)instance.GetBiome(val.x, val.z + (float)Width, 0.02f, false),
				(Biome)(int)instance.GetBiome(val.x + (float)Width, val.z + (float)Width, 0.02f, false)
			};
		}

		private float[] CalculateOceanDepths()
		{
			//IL_0034: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[4];
			float num = (Object.op_Implicit((Object)(object)ZoneSystem.instance) ? ZoneSystem.instance.m_waterLevel : 30f);
			array[0] = Mathf.Max(0f, num - this.Height(new Vector2i(0, Width)));
			array[1] = Mathf.Max(0f, num - this.Height(new Vector2i(Width, Width)));
			array[2] = Mathf.Max(0f, num - this.Height(new Vector2i(Width, 0)));
			array[3] = Mathf.Max(0f, num - this.Height(new Vector2i(0, 0)));
			return array;
		}

		public float Tilt(Vector3 worldCoordinate)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0079: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_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_0113: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			Vector2i val = WorldToZoneCoordinate(worldCoordinate);
			Vector2i zoneLocalCoordinate = val + North;
			Vector2i zoneLocalCoordinate2 = val + South;
			Vector2i zoneLocalCoordinate3 = val + West;
			Vector2i zoneLocalCoordinate4 = val + East;
			float num = Height(val);
			float num2 = Height(zoneLocalCoordinate);
			float num3 = Height(zoneLocalCoordinate2);
			float num4 = Height(zoneLocalCoordinate3);
			float num5 = Height(zoneLocalCoordinate4);
			Vector3 normalized = default(Vector3);
			((Vector3)(ref normalized))..ctor((float)North.x, num2 - num, (float)North.y);
			Vector3 normalized2 = default(Vector3);
			((Vector3)(ref normalized2))..ctor((float)South.x, num3 - num, (float)South.y);
			Vector3 normalized3 = default(Vector3);
			((Vector3)(ref normalized3))..ctor((float)West.x, num4 - num, (float)West.y);
			Vector3 normalized4 = default(Vector3);
			((Vector3)(ref normalized4))..ctor((float)East.x, num5 - num, (float)East.y);
			normalized = ((Vector3)(ref normalized)).normalized;
			normalized2 = ((Vector3)(ref normalized2)).normalized;
			normalized3 = ((Vector3)(ref normalized3)).normalized;
			normalized4 = ((Vector3)(ref normalized4)).normalized;
			float num6 = AngleByCross(normalized, normalized4);
			float num7 = AngleByCross(normalized4, normalized2);
			float num8 = AngleByCross(normalized2, normalized3);
			float num9 = AngleByCross(normalized3, normalized);
			return (num6 + num8 + num9 + num7) / 4f;
			static float AngleByCross(Vector3 p1, Vector3 p2)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = Vector3.Cross(p1, p2);
				return Mathf.Abs(Vector3.Angle(Vector2.op_Implicit(Vector2.up), val2));
			}
		}

		public Biome GetBiome(Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			(float x, float z) tuple = WorldCoordToNormalizedZoneCoord(pos);
			float item = tuple.x;
			float item2 = tuple.z;
			Dictionary<Biome, float> dictionary = new Dictionary<Biome, float>(4);
			AddWeight(dictionary, BiomeCorners[0], Distance(item, item2, 0f, 0f));
			AddWeight(dictionary, BiomeCorners[1], Distance(item, item2, 1f, 0f));
			AddWeight(dictionary, BiomeCorners[2], Distance(item, item2, 0f, 1f));
			AddWeight(dictionary, BiomeCorners[3], Distance(item, item2, 1f, 1f));
			return dictionary.OrderBy((KeyValuePair<Biome, float> v) => v.Value).First().Key;
			static void AddWeight(Dictionary<Biome, float> weights, Biome key, float weight)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				if (weights.TryGetValue(key, out var value))
				{
					weights[key] = value + weight;
				}
				else
				{
					weights[key] = weight;
				}
			}
			static float Distance(float x1, float z1, float x2, float z2)
			{
				float num = x1 - x2;
				float num2 = z1 - z2;
				return Mathf.Sqrt(num * num + num2 * num2);
			}
		}

		private (float x, float z) WorldCoordToNormalizedZoneCoord(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = pos - ZonePos;
			float item = val.x / (float)Width + 0.5f;
			float item2 = val.z / (float)Width + 0.5f;
			return (item, item2);
		}
	}
}
namespace SpawnThat.World.Zone
{
	public interface IZone
	{
		int Width { get; }

		Biome Biome { get; }

		Vector2i ZoneId { get; }

		Vector3 ZonePos { get; }

		Biome[] BiomeCorners { get; }

		BiomeArea BiomeArea { get; }

		bool HasBiome(Biome biome);

		Biome GetBiome(Vector3 pos);

		Vector2i WorldToZoneCoordinate(Vector3 worldCoordinate);

		float Height(Vector3 worldCoordinate);

		float Height(Vector2i zoneLocalCoordinate);

		float OceanDepth(Vector3 worldCoordinate);

		float OceanDepth(Vector2i zoneLocalCoordinate);

		float Tilt(Vector3 worldCoordinate);
	}
	public static class ZoneManager
	{
		[HarmonyPatch]
		private static class PatchHeightmap
		{
			[HarmonyPatch(typeof(Heightmap), "Regenerate")]
			[HarmonyPostfix]
			private static void Record(Heightmap __instance)
			{
				//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_001e: 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)
				if (__instance.m_isDistantLod)
				{
					Vector2i zoneId = ((Component)__instance).gameObject.transform.position.GetZoneId();
					HeightmapsLoaded[zoneId] = new ZoneHeightmap(__instance);
				}
			}

			[HarmonyPatch(typeof(Heightmap), "OnDestroy")]
			[HarmonyPostfix]
			private static void RemoveRecord(Heightmap __instance)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				Vector2i zoneId = ((Component)__instance).gameObject.transform.position.GetZoneId();
				HeightmapsLoaded.Remove(zoneId);
			}
		}

		private static Dictionary<Vector2i, ZoneHeightmap> HeightmapsLoaded;

		private static Dictionary<Vector2i, ZoneSimulated> SimulatedCache;

		static ZoneManager()
		{
			HeightmapsLoaded = new Dictionary<Vector2i, ZoneHeightmap>();
			SimulatedCache = new Dictionary<Vector2i, ZoneSimulated>();
			LifecycleManager.SubscribeToWorldInit(delegate
			{
				HeightmapsLoaded = new Dictionary<Vector2i, ZoneHeightmap>();
				SimulatedCache = new Dictionary<Vector2i, ZoneSimulated>();
			});
		}

		public static IZone GetZone(Vector2i zoneId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (HeightmapsLoaded.TryGetValue(zoneId, out var value))
			{
				return value;
			}
			if (SimulatedCache.TryGetValue(zoneId, out var value2))
			{
				return value2;
			}
			return SimulatedCache[zoneId] = new ZoneSimulated(zoneId);
		}
	}
	public static class ZoneUtils
	{
		public static List<Vector2i> GetZonesInSquare(int minX, int minZ, int maxX, int maxZ)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2i> list = new List<Vector2i>();
			int num = Zonify(minX);
			int num2 = Zonify(maxX);
			int num3 = Zonify(minZ);
			int num4 = Zonify(maxZ);
			for (int i = num; i <= num2; i++)
			{
				for (int j = num3; j <= num4; j++)
				{
					list.Add(new Vector2i(i, j));
				}
			}
			return list;
		}

		public static Vector2i GetZone(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return ZoneSystem.GetZone(pos);
		}

		public static Vector2i GetZone(int x, int z)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2i(Zonify(x), Zonify(z));
		}

		public static int GetZoneIndex(Vector2i zone)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return ZDOMan.instance.SectorToIndex(zone);
		}

		public static int Zonify(int coordinate)
		{
			return Mathf.FloorToInt((float)(coordinate + 32) / 64f);
		}
	}
}
namespace SpawnThat.World.Queries
{
	public abstract class BaseZdoQuery
	{
		private bool initialized;

		protected Vector3 Center { get; }

		protected int Range { get; }

		protected List<Vector2i> ZoneIds { get; private set; }

		protected List<ZDO> Zdos { get; private set; }

		protected int MinX { get; private set; }

		protected int MinZ { get; private set; }

		protected int MaxX { get; private set; }

		protected int MaxZ { get; private set; }

		protected BaseZdoQuery(Vector3 center, int range)
		{
			//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)
			Center = center;
			Range = range;
			Initialize();
		}

		protected virtual void Initialize()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				return;
			}
			(int, int) range = GetRange((int)Center.x, Range);
			MinX = range.Item1;
			MaxX = range.Item2;
			range = GetRange((int)Center.z, Range);
			MinZ = range.Item1;
			MaxZ = range.Item2;
			ZoneIds = ZoneUtils.GetZonesInSquare(MinX, MinZ, MaxX, MaxZ);
			Zdos = new List<ZDO>();
			foreach (Vector2i zoneId in ZoneIds)
			{
				ZDOMan.instance.FindObjects(zoneId, Zdos);
			}
			initialized = true;
		}

		protected static (int min, int max) GetRange(int center, int range)
		{
			return (center - range, center + range);
		}

		protected bool IsWithinRangeManhattan(ZDO zdo)
		{
			if (zdo.m_position.x < (float)MinX || zdo.m_position.x > (float)MaxX)
			{
				return false;
			}
			if (zdo.m_position.z < (float)MinZ || zdo.m_position.z > (float)MaxZ)
			{
				return false;
			}
			return true;
		}

		protected bool IsWithinRange(ZDO zdo)
		{
			//IL_0055: 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)
			if (zdo.m_position.x < (float)MinX || zdo.m_position.x > (float)MaxX)
			{
				return false;
			}
			if (zdo.m_position.z < (float)MinZ || zdo.m_position.z > (float)MaxZ)
			{
				return false;
			}
			return zdo.m_position.WithinHorizontalDistance(Center, Range);
		}
	}
	public class ZdoPrefabQuery : BaseZdoQuery
	{
		private Dictionary<int, int> CachedPrefabResults = new Dictionary<int, int>();

		public ZdoPrefabQuery(Vector3 center, int range)
			: base(center, range)
		{
		}//IL_000c: Unknown result type (might be due to invalid IL or missing references)


		public int CountEntities(int prefabHash, Predicate<ZDO> condition = null)
		{
			Initialize();
			if (CachedPrefabResults.TryGetValue(prefabHash, out var value))
			{
				return value;
			}
			int num = 0;
			num = ((condition != null) ? base.Zdos.Count((ZDO x) => IsWithinRange(x, prefabHash) && condition(x)) : base.Zdos.Count((ZDO x) => IsWithinRange(x, prefabHash)));
			CachedPrefabResults[prefabHash] = num;
			return num;
		}

		public bool HasAny(int prefabHash)
		{
			Initialize();
			if (CachedPrefabResults.TryGetValue(prefabHash, out var value))
			{
				return value > 0;
			}
			return base.Zdos.Any((ZDO x) => IsWithinRange(x, prefabHash));
		}

		private bool IsWithinRange(ZDO zdo, int prefabId)
		{
			if (zdo.m_prefab != prefabId)
			{
				return false;
			}
			return IsWithinRange(zdo);
		}
	}
}
namespace SpawnThat.World.Maps
{
	public static class MapManager
	{
		internal static AreaMap AreaMap { get; set; }

		private static int Seed { get; set; }

		public static void Initialize()
		{
			Seed = WorldGenerator.instance.GetSeed();
			AreaMap = AreaMapBuilder.BiomeMap(10500).CompileMap();
		}

		public static int GetAreaId(Vector3 position)
		{
			//IL_0010: 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)
			int num = Math.Min(AreaMap.MapWidth, Math.Max(0, AreaMap.CoordinateToIndex((int)position.x)));
			int num2 = Math.Min(AreaMap.MapWidth, Math.Max(0, AreaMap.CoordinateToIndex((int)position.z)));
			return AreaMap.AreaIds[num][num2];
		}

		public static float GetAreaChance(Vector3 position, int modifier = 0)
		{
			//IL_0010: 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)
			int num = Math.Min(AreaMap.MapWidth, Math.Max(0, AreaMap.CoordinateToIndex((int)position.x)));
			int num2 = Math.Min(AreaMap.MapWidth, Math.Max(0, AreaMap.CoordinateToIndex((int)position.z)));
			return (float)new Random(AreaMap.AreaIds[num][num2] + Seed + modifier).NextDouble();
		}

		public static float[][] GetTemplateAreaChanceMap(int templateIndex, int scaling = 1)
		{
			float[][] array = new float[AreaMap.MapWidth][];
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			for (int i = 0; i < AreaMap.MapWidth; i++)
			{
				array[i] = new float[AreaMap.MapWidth];
				for (int j = 0; j < AreaMap.MapWidth; j++)
				{
					int num = AreaMap.AreaIds[i][j];
					if (dictionary.ContainsKey(num))
					{
						array[i][j] = dictionary[num];
						continue;
					}
					Random random = new Random(num + Seed + templateIndex);
					dictionary[num] = (float)random.NextDouble() * (float)scaling;
				}
			}
			return array;
		}
	}
}
namespace SpawnThat.World.Maps.Patches
{
	[HarmonyPatch(typeof(Game))]
	internal class Patch_Game_FindSpawnPoint_PrintMaps
	{
		private static bool FirstTime;

		static Patch_Game_FindSpawnPoint_PrintMaps()
		{
			FirstTime = true;
			LifecycleManager.SubscribeToWorldInit(delegate
			{
				FirstTime = true;
			});
		}

		[HarmonyPatch("FindSpawnPoint")]
		[HarmonyPostfix]
		private static void PrintMaps()
		{
			try
			{
				if (!FirstTime)
				{
					return;
				}
				FirstTime = false;
				GeneralConfiguration generalConfig = ConfigurationManager.GeneralConfig;
				if (generalConfig != null && (generalConfig.PrintAreaMap?.Value).GetValueOrDefault())
				{
					ImageBuilder.SetIds(MapManager.AreaMap).Print("area_ids_map");
				}
				GeneralConfiguration generalConfig2 = ConfigurationManager.GeneralConfig;
				if (generalConfig2 != null && (generalConfig2.PrintBiomeMap?.Value).GetValueOrDefault())
				{
					ImageBuilder.SetBiomes(MapManager.AreaMap).Print("biome_map");
				}
				GeneralConfiguration generalConfig3 = ConfigurationManager.GeneralConfig;
				if (generalConfig3 == null || !(generalConfig3.PrintFantasticBeastsAndWhereToKillThem?.Value).GetValueOrDefault())
				{
					return;
				}
				foreach (var template in WorldSpawnTemplateManager.GetTemplates())
				{
					if (template.template.Enabled)
					{
						int[][] mapOfTemplatesActiveAreas = WorldSpawnerSpawnMapService.GetMapOfTemplatesActiveAreas(template.id);
						if (mapOfTemplatesActiveAreas != null)
						{
							ImageBuilder.SetGrayscaleBiomes(MapManager.AreaMap).AddHeatZones(mapOfTemplatesActiveAreas).Print($"spawn_map_{template.id}_{template.template.PrefabName ?? template.template.TemplateName ?? string.Empty}");
						}
					}
				}
			}
			catch (Exception e)
			{
				Log.LogWarning("Error while attempting to print spawn area maps. Skipping map printing.", e);
			}
		}
	}
	[HarmonyPatch(typeof(ZNet))]
	internal static class Patch_ZNet_Awake_ScanWorld
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void ScanWorld()
		{
			if (WorldGenerator.instance != null)
			{
				Log.LogDebug("Scanning map for biomes..");
				DateTimeOffset utcNow = DateTimeOffset.UtcNow;
				MapManager.Initialize();
				DateTimeOffset utcNow2 = DateTimeOffset.UtcNow;
				Log.LogDebug("Scanning map and assigning id's to areas took: " + (utcNow2 - utcNow));
			}
		}

		[HarmonyPatch("RPC_PeerInfo")]
		[HarmonyPostfix]
		private static void ScanJoinedWorld()
		{
			if (WorldGenerator.instance != null)
			{
				Log.LogDebug("Scanning map for biomes..");
				DateTimeOffset utcNow = DateTimeOffset.UtcNow;
				MapManager.Initialize();
				DateTimeOffset utcNow2 = DateTimeOffset.UtcNow;
				Log.LogDebug("Scanning map and assigning id's to areas took: " + (utcNow2 - utcNow));
			}
		}
	}
}
namespace SpawnThat.World.Maps.Area
{
	internal class AreaMap
	{
		public const int ZoneSize = 64;

		public const int ZoneSizeOffset = 32;

		public int[][] Biomes { get; private set; }

		public int[][] AreaIds { get; private set; }

		public int ZoneOffset { get; private set; }

		public int MapWidth { get; private set; }

		public int IndexStartCoordinate { get; private set; }

		public AreaMap(int mapRadius)
		{
			ZoneOffset = (int)Math.Ceiling((double)mapRadius / 64.0);
			IndexStartCoordinate = -(ZoneOffset * 64);
			MapWidth = ZoneOffset * 2;
			Biomes = new int[MapWidth][];
			AreaIds = new int[MapWidth][];
			for (int i = 0; i < MapWidth; i++)
			{
				Biomes[i] = new int[MapWidth];
				AreaIds[i] = new int[MapWidth];
			}
		}

		public int IndexToCoordinate(int index)
		{
			return IndexStartCoordinate + index * 64;
		}

		public int CoordinateToIndex(int coordinate)
		{
			return coordinate / 64 + ZoneOffset;
		}
	}
	internal class AreaMapBuilder
	{
		private class Label
		{
			public int Id { get; set; }

			public int Area { get; set; }
		}

		private IAreaProvider AreaProvider { get; set; }

		private AreaMap AreaMap { get; }

		private Label[][] LabelGrid { get; }

		private Dictionary<int, int> MergeTable { get; } = new Dictionary<int, int>();


		private int Size => AreaMap.MapWidth;

		private AreaMapBuilder(IAreaProvider areaProvider, int mapRadius)
		{
			AreaProvider = areaProvider;
			AreaMap = new AreaMap(mapRadius);
			LabelGrid = new Label[Size][];
			for (int i = 0; i < Size; i++)
			{
				LabelGrid[i] = new Label[Size];
			}
		}

		public static AreaMapBuilder BiomeMap(int mapRadius)
		{
			return new AreaMapBuilder(new WorldGeneratorAreaProvider(), mapRadius);
		}

		public AreaMapBuilder UseAreaProvider(IAreaProvider areaProvider)
		{
			AreaProvider = areaProvider;
			return this;
		}

		public AreaMap CompileMap()
		{
			ScanAreas();
			MergeLabels();
			Build();
			return AreaMap;
		}

		private void ScanAreas()
		{
			int num = 0;
			for (int i = 0; i < AreaMap.Biomes.Length; i++)
			{
				Label[] array = ((i == 0) ? null : LabelGrid[i - 1]);
				Label label = ((i == 0) ? null : array[0]);
				int[] array2 = ((i == 0) ? null : AreaMap.Biomes[i - 1]);
				int num2 = ((i == 0) ? (-1) : array2[0]);
				for (int j = 0; j < AreaMap.Biomes.Length; j++)
				{
					int area = GetArea(i, j);
					AreaMap.Biomes[i][j] = area;
					if (num2 != area)
					{
						if (i > 0 && array2[j] == area)
						{
							label = array[j];
						}
						else
						{
							label = new Label
							{
								Id = num++,
								Area = area
							};
							MergeTable[label.Id] = label.Id;
						}
					}
					LabelGrid[i][j] = label;
					num2 = area;
				}
			}
		}

		private int GetArea(int x, int y)
		{
			return AreaProvider.GetArea(AreaMap.IndexToCoordinate(x), AreaMap.IndexToCoordinate(y));
		}

		private void MergeLabels()
		{
			for (int i = 0; i < LabelGrid.Length; i++)
			{
				for (int j = 0; j < LabelGrid.Length; j++)
				{
					Label label3 = LabelGrid[i][j];
					if (j > 0)
					{
						Label label4 = LabelGrid[i][j - 1];
						_ = label3.Area;
						_ = label4.Area;
						if (MergeLabels(label4, label3, out var result2))
						{
							LabelGrid[i][j] = result2;
							continue;
						}
					}
					if (i > 0)
					{
						Label label5 = LabelGrid[i - 1][j];
						if (MergeLabels(label5, label3, out var result3))
						{
							LabelGrid[i][j] = result3;
							continue;
						}
					}
					if (j + 1 < LabelGrid.Length)
					{
						Label label6 = LabelGrid[i][j + 1];
						if (MergeLabels(label6, label3, out var result4))
						{
							LabelGrid[i][j] = result4;
							continue;
						}
					}
					if (i + 1 < LabelGrid.Length)
					{
						Label label7 = LabelGrid[i + 1][j];
						if (MergeLabels(label7, label3, out var result5))
						{
							LabelGrid[i][j] = result5;
						}
					}
				}
			}
			bool MergeLabels(Label label1, Label label2, out Label result)
			{
				result = null;
				if (label1.Area == label2.Area && label1.Id != label2.Id)
				{
					if (label1.Id > label2.Id)
					{
						if (MergeTable[label1.Id] > label2.Id)
						{
							MergeTable[label1.Id] = label2.Id;
						}
						result = label2;
						label1.Id = label2.Id;
					}
					else
					{
						if (MergeTable[label2.Id] > label1.Id)
						{
							MergeTable[label2.Id] = label1.Id;
						}
						result = label1;
						label2.Id = label1.Id;
					}
					return true;
				}
				return false;
			}
		}

		private void Build()
		{
			for (int i = 0; i < LabelGrid.Length; i++)
			{
				for (int j = 0; j < LabelGrid.Length; j++)
				{
					int id = LabelGrid[i][j].Id;
					int num = MergeTable[id];
					while (MergeTable[num] < num)
					{
						num = MergeTable[num];
						MergeTable[id] = num;
					}
					AreaMap.AreaIds[i][j] = num;
				}
			}
		}
	}
	internal static class ColourMapper
	{
		public static (int r, int g, int b) IntegerToColor255(int value)
		{
			int item;
			if (value > 255)
			{
				item = 255;
				value -= 255;
				int item2;
				if (value > 255)
				{
					item2 = 255;
					value -= 255;
					int item3 = ((value <= 255) ? value : 255);
					return (item3, item2, item);
				}
				item2 = value;
				return (0, item2, item);
			}
			item = value;
			return (0, 0, item);
		}

		public static (int r, int g, int b) IntegerToColour3Byte(int value)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			return (bytes[2], bytes[1], bytes[0]);
		}

		public static (float r, float g, float b) IntegerToColor(int value)
		{
			var (num, num2, num3) = IntegerToColour3Byte(value);
			return (num / 255, num2 / 255, num3 / 255);
		}

		public static (float r, float g, float b) Rainbow255(int id)
		{
			float num = (float)new Random(id).NextDouble();
			int num2 = (int)(num * 6f);
			int num3 = (int)(num * 255f);
			int num4 = 1 - num3;
			return num2 switch
			{
				0 => (255f, num3, 0f), 
				1 => (num4, 255f, 0f), 
				2 => (0f, 255f, num3), 
				3 => (0f, num4, 255f), 
				4 => (num3, 0f, 255f), 
				_ => (255f, 0f, num4), 
			};
		}

		public static (float r, float g, float b) Rainbow(int id)
		{
			float num = (float)new Random(id).NextDouble();
			int num2 = (int)(num * 6f);
			float num3 = num;
			float num4 = 1f - num3;
			return num2 switch
			{
				0 => (1f, num3, 0f), 
				1 => (num4, 1f, 0f), 
				2 => (0f, 1f, num3), 
				3 => (0f, num4, 1f), 
				4 => (num3, 0f, 1f), 
				_ => (1f, 0f, num4), 
			};
		}

		public static (int r, int g, int b) ToBiomeColour255(int biome)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			Biome val = (Biome)biome;
			if ((int)val <= 32)
			{
				switch ((int)val)
				{
				default:
					if ((int)val != 16)
					{
						if ((int)val != 32)
						{
							break;
						}
						return (255, 0, 0);
					}
					return (255, 255, 0);
				case 0:
					return (0, 0, 0);
				case 1:
					return (0, 255, 0);
				case 2:
					return (128, 0, 0);
				case 4:
					return (255, 255, 255);
				case 8:
					return (0, 128, 0);
				case 3:
				case 5:
				case 6:
				case 7:
					break;
				}
			}
			else
			{
				if ((int)val == 64)
				{
					return (0, 255, 255);
				}
				if ((int)val == 256)
				{
					return (0, 0, 255);
				}
				if ((int)val == 512)
				{
					return (128, 128, 128);
				}
			}
			return (0, 0, 0);
		}

		public static (float r, float g, float b) ToBiomeColour(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			if ((int)biome <= 32)
			{
				switch ((int)biome)
				{
				default:
					if ((int)biome != 16)
					{
						if ((int)biome != 32)
						{
							break;
						}
						return (1f, 0f, 0f);
					}
					return (1f, 1f, 0f);
				case 0:
					return (0f, 0f, 0f);
				case 1:
					return (0f, 1f, 0f);
				case 2:
					return (0.5f, 0f, 0f);
				case 4:
					return (1f, 1f, 1f);
				case 8:
					return (0f, 0.5f, 0f);
				case 3:
				case 5:
				case 6:
				case 7:
					break;
				}
			}
			else
			{
				if ((int)biome == 64)
				{
					return (0f, 1f, 1f);
				}
				if ((int)biome == 256)
				{
					return (0f, 0f, 1f);
				}
				if ((int)biome == 512)
				{
					return (0.5f, 0.5f, 0.5f);
				}
			}
			return (0f, 0f, 0f);
		}

		public static (float r, float g, float b) ToBiomeColourGrayscale(int biome)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			Biome val = (Biome)biome;
			(int, int, int) tuple;
			if ((int)val <= 32)
			{
				switch ((int)val)
				{
				case 0:
					goto IL_0069;
				case 1:
					goto IL_0083;
				case 2:
					goto IL_0094;
				case 4:
					goto IL_00ae;
				case 8:
					goto IL_00c8;
				case 3:
				case 5:
				case 6:
				case 7:
					goto IL_0155;
				}
				if ((int)val != 16)
				{
					if ((int)val != 32)
					{
						goto IL_0155;
					}
					tuple = (220, 220, 220);
				}
				else
				{
					tuple = (200, 200, 200);
				}
			}
			else if ((int)val != 64)
			{
				if ((int)val != 256)
				{
					if ((int)val != 512)
					{
						goto IL_0155;
					}
					tuple = (130, 130, 130);
				}
				else
				{
					tuple = (255, 255, 255);
				}
			}
			else
			{
				tuple = (240, 240, 240);
			}
			goto IL_016a;
			IL_0094:
			tuple = (140, 140, 140);
			goto IL_016a;
			IL_0069:
			tuple = (255, 255, 255);
			goto IL_016a;
			IL_0083:
			tuple = (120, 120, 120);
			goto IL_016a;
			IL_016a:
			(int, int, int) tuple2 = tuple;
			return (tuple2.Item1, tuple2.Item2, tuple2.Item3);
			IL_0155:
			tuple = (255, 255, 255);
			goto IL_016a;
			IL_00c8:
			tuple = (180, 180, 180);
			goto IL_016a;
			IL_00ae:
			tuple = (160, 160, 160);
			goto IL_016a;
		}
	}
	internal interface IAreaProvider
	{
		int GetArea(int x, int y);
	}
	internal class ImageBuilder
	{
		private AreaMap areaMap;

		private Texture2D image;

		private ImageBuilder(AreaMap areaMap)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			this.areaMap = areaMap;
			image = new Texture2D(this.areaMap.MapWidth, this.areaMap.MapWidth, (TextureFormat)4, true);
		}

		public static ImageBuilder Init(AreaMap areaMap)
		{
			return new ImageBuilder(areaMap);
		}

		public static ImageBuilder SetBiomes(AreaMap areaMap)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			ImageBuilder imageBuilder = new ImageBuilder(areaMap);
			for (int i = 0; i < areaMap.MapWidth; i++)
			{
				for (int j = 0; j < areaMap.MapWidth; j++)
				{
					var (num, num2, num3) = ColourMapper.ToBiomeColour((Biome)areaMap.Biomes[i][j]);
					imageBuilder.image.SetPixel(i, j, new Color(num, num2, num3));
				}
			}
			return imageBuilder;
		}

		public static ImageBuilder SetGrayscaleBiomes(AreaMap areaMap)
		{
			//IL_0049: 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)
			ImageBuilder imageBuilder = new ImageBuilder(areaMap);
			for (int i = 0; i < areaMap.MapWidth; i++)
			{
				for (int j = 0; j < areaMap.MapWidth; j++)
				{
					var (num, num2, num3) = ColourMapper.ToBiomeColourGrayscale(areaMap.Biomes[i][j]);
					imageBuilder.image.SetPixel(i, j, Color32.op_Implicit(new Color32((byte)num, (byte)num2, (byte)num3, byte.MaxValue)));
				}
			}
			return imageBuilder;
		}

		public static ImageBuilder SetIds(AreaMap areaMap)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			ImageBuilder imageBuilder = new ImageBuilder(areaMap);
			Color32 val = default(Color32);
			for (int i = 0; i < areaMap.MapWidth; i++)
			{
				for (int j = 0; j < areaMap.MapWidth; j++)
				{
					var (num, num2, num3) = ColourMapper.IntegerToColour3Byte(areaMap.AreaIds[i][j]);
					((Color32)(ref val))..ctor((byte)num, (byte)num2, (byte)num3, byte.MaxValue);
					imageBuilder.image.SetPixel(i, j, Color32.op_Implicit(val));
				}
			}
			return imageBuilder;
		}

		public static ImageBuilder SetRainbowIds(AreaMap areaMap)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			ImageBuilder imageBuilder = new ImageBuilder(areaMap);
			Color32 val = default(Color32);
			for (int i = 0; i < areaMap.MapWidth; i++)
			{
				for (int j = 0; j < areaMap.MapWidth; j++)
				{
					var (num, num2, num3) = ColourMapper.Rainbow255(areaMap.AreaIds[i][j]);
					((Color32)(ref val))..ctor((byte)num, (byte)num2, (byte)num3, byte.MaxValue);
					imageBuilder.image.SetPixel(i, j, Color32.op_Implicit(val));
				}
			}
			return imageBuilder;
		}

		public ImageBuilder AddHeatZones(int[][] heatZones, bool ignoreZero = true)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < heatZones.Length; i++)
			{
				for (int j = 0; j < heatZones.Length; j++)
				{
					int num = heatZones[i][j];
					if (!ignoreZero || num != 0)
					{
						image.SetPixel(i, j, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)(255 - num), (byte)(255 - num), byte.MaxValue)));
					}
				}
			}
			return this;
		}

		public void Print(string filename, string description = null)
		{
			image.Apply();
			DebugFileWriter.WriteFile(ImageConversion.EncodeToPNG(image), filename + ".png", description ?? "map");
		}
	}
	internal class WorldGeneratorAreaProvider : IAreaProvider
	{
		private WorldGenerator _instance;

		private WorldGenerator World => _instance ?? (_instance = WorldGenerator.instance);

		public int GetArea(int x, int y)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected I4, but got Unknown
			return (int)World.GetBiome((float)x, (float)y, 0.02f, false);
		}
	}
}
namespace SpawnThat.World.Locations
{
	public static class LocationManager
	{
		private static Dictionary<Vector2i, SimpleLocation> _simpleLocationsByZone { get; set; }

		static LocationManager()
		{
			LifecycleManager.SubscribeToWorldInit(delegate
			{
				_simpleLocationsByZone = null;
			});
		}

		public static Dictionary<Vector2i, SimpleLocation> GetLocations()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (_simpleLocationsByZone != null)
			{
				return new Dictionary<Vector2i, SimpleLocation>(_simpleLocationsByZone);
			}
			if (((Object)(object)ZoneSystem.instance).IsNotNull() && ZoneSystem.instance.m_locationInstances != null)
			{
				Dictionary<Vector2i, SimpleLocation> dictionary = new Dictionary<Vector2i, SimpleLocation>();
				foreach (KeyValuePair<Vector2i, LocationInstance> locationInstance in ZoneSystem.instance.m_locationInstances)
				{
					dictionary[locationInstance.Key] = new SimpleLocation
					{
						LocationName = (locationInstance.Value.m_location?.m_prefabName ?? ""),
						Position = locationInstance.Value.m_position,
						ZonePosition = locationInstance.Key
					};
				}
				_simpleLocationsByZone = dictionary;
				return dictionary;
			}
			return null;
		}

		public static SimpleLocation GetLocation(Vector3 position)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			ZoneSystem instance = ZoneSystem.instance;
			if (!Object.op_Implicit((Object)(object)instance) || instance == null)
			{
				Log.LogWarning("Attempting to retrieve location before ZoneSystem is initialized.");
				return null;
			}
			Vector2i zoneId = position.GetZoneId();
			if ((instance.m_locationInstances?.Count ?? 0) > 0 && instance.m_locationInstances.TryGetValue(zoneId, out var value))
			{
				return new SimpleLocation
				{
					LocationName = (value.m_location?.m_prefabName ?? ""),
					Position = value.m_position,
					ZonePosition = zoneId
				};
			}
			if (_simpleLocationsByZone != null && _simpleLocationsByZone.TryGetValue(zoneId, out var value2))
			{
				return value2;
			}
			return null;
		}

		internal static void SetLocations(IEnumerable<SimpleLocation> locations)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (_simpleLocationsByZone == null)
			{
				_simpleLocationsByZone = new Dictionary<Vector2i, SimpleLocation>();
			}
			foreach (SimpleLocation location in locations)
			{
				_simpleLocationsByZone[location.ZonePosition] = location;
			}
		}
	}
	public class SimpleLocation
	{
		public Vector3 Position;

		public Vector2i ZonePosition;

		public string LocationName;
	}
	internal class SimpleLocationPackage : CompressedPackage
	{
		public string[] LocationNames;

		public SimpleLocationDTO[] Locations;

		protected override void BeforePack()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Vector2i, LocationInstance> obj = (((Object)(object)ZoneSystem.instance).IsNotNull() ? ZoneSystem.instance.m_locationInstances : null);
			Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
			List<string> list = new List<string>();
			List<SimpleLocationDTO> list2 = new List<SimpleLocationDTO>();
			foreach (KeyValuePair<Vector2i, LocationInstance> item in obj)
			{
				string prefabName = item.Value.m_location.m_prefabName;
				ushort num;
				if (dictionary.TryGetValue(item.Value.m_location.m_prefabName, out var value))
				{
					num = value;
				}
				else
				{
					list.Add(prefabName);
					num = (ushort)(list.Count - 1);
					dictionary.Add(prefabName, num);
				}
				list2.Add(new SimpleLocationDTO(item.Key, num));
			}
			LocationNames = list.ToArray();
			Locations = list2.ToArray();
			string[] locationNames = LocationNames;
			Log.LogDebug($"Packaged locations: {((locationNames != null) ? locationNames.Length : 0)}");
		}

		protected override void AfterUnpack(object obj)
		{
			//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)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (obj is SimpleLocationPackage simpleLocationPackage)
			{
				Log.LogDebug("Received and deserialized location package");
				List<SimpleLocation> list = new List<SimpleLocation>(simpleLocationPackage.Locations.Length);
				SimpleLocationDTO[] locations = simpleLocationPackage.Locations;
				Vector2i val = default(Vector2i);
				for (int i = 0; i < locations.Length; i++)
				{
					SimpleLocationDTO simpleLocationDTO = locations[i];
					((Vector2i)(ref val))..ctor(simpleLocationDTO.X, simpleLocationDTO.Y);
					list.Add(new SimpleLocation
					{
						LocationName = simpleLocationPackage.LocationNames[simpleLocationDTO.L],
						Position = ZoneSystem.GetZonePos(val),
						ZonePosition = val
					});
				}
				LocationManager.SetLocations(list);
				Log.LogInfo($"Successfully unpacked locations: {list?.Count ?? 0}");
			}
			else
			{
				Log.LogWarning("Received bad location package. Unable to load.");
			}
		}
	}
	[Serializable]
	public struct SimpleLocationDTO
	{
		public int X;

		public int Y;

		public ushort L;

		public SimpleLocationDTO(Vector2i pos, ushort location)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			X = pos.x;
			Y = pos.y;
			L = location;
		}
	}
	internal static class ZoneSystemSyncSetup
	{
		public static void Configure()
		{
			SyncManager.RegisterSyncHandlers("RPC_ReceiveLocationsSpawnThat", GeneratePackage, RPC_ReceiveLocationsSpawnThat);
		}

		private static ZPackage GeneratePackage()
		{
			return new SimpleLocationPackage().Pack();
		}

		private static void RPC_ReceiveLocationsSpawnThat(ZRpc rpc, ZPackage pkg)
		{
			Log.LogInfo("Received locations package.");
			try
			{
				CompressedPackage.Unpack<SimpleLocationPackage>(pkg);
			}
			catch (Exception e)
			{
				Log.LogError("Error while attempting to read received locations package.", e);
			}
		}
	}
}
namespace SpawnThat.World.Dungeons
{
	public sealed class RoomData : IPoint, IHaveVector3, IBox, IManagedValue
	{
		private Vector3 _pos;

		public string Name;

		private Vector2[] RotatedRectangle { get; set; }

		public Vector3Int Size { get; set; }

		public Vector3 Pos
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _pos;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				_pos = value;
				X = value.x;
				Y = value.z;
			}
		}

		public float X { get; set; }

		public float Y { get; set; }

		public Quaternion Rotation { get; set; }

		public void OnCreate()
		{
		}

		public void OnDestroy()
		{
			RoomManager.RemoveRoom(this);
		}

		public bool Contains(Vector3 pos)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (RotatedRectangle == null)
			{
				Vector2[] array2 = (RotatedRectangle = SearchSpatial.CreateRectangle(this));
			}
			return SearchSpatial.Contains(this, pos);
		}
	}
	public static class RoomManager
	{
		[HarmonyPatch(typeof(DungeonGenerator))]
		private static class DungeonGeneratorPatch
		{
			[HarmonyPatch("PlaceRoom", new Type[]
			{
				typeof(RoomData),
				typeof(Vector3),
				typeof(Quaternion),
				typeof(RoomConnection),
				typeof(SpawnMode)
			})]
			[HarmonyPostfix]
			private static void GetRoomObject(Room __result)
			{
				CacheRoom(__result);
			}

			private static void CacheRoom(Room component)
			{
				AddRoom(component);
			}
		}

		private static ManagedCache<RoomData> RoomTable;

		private static HashSet<Vector3> HasAdded;

		private static List<RoomData> RoomList;

		static RoomManager()
		{
			RoomTable = new ManagedCache<RoomData>();
			HasAdded = new HashSet<Vector3>();
			RoomList = new List<RoomData>();
			LifecycleManager.SubscribeToWorldInit(delegate
			{
				HasAdded = new HashSet<Vector3>();
				RoomList = new List<RoomData>();
			});
		}

		public static RoomData GetContainingRoom(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return FindClosestRoom(pos);
		}

		private static RoomData FindClosestRoom(Vector3 pos)
		{
			//IL_0022: 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_005f: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			List<RoomData> roomList = RoomList;
			if (roomList == null || roomList.Count == 0)
			{
				return null;
			}
			RoomData result = null;
			float num = float.MaxValue;
			int num2 = RoomList.IndexLeft(pos.x - 20f);
			int num3 = RoomList.IndexRight(pos.x + 20f);
			for (int i = num2; i < num3; i++)
			{
				RoomData roomData = RoomList[i];
				if (!(Math.Abs(roomData.Pos.y - pos.y) > 100f) && roomData.Contains(pos))
				{
					float value = pos.x - roomData.Pos.x;
					float value2 = pos.z - roomData.Pos.z;
					float value3 = pos.y - roomData.Pos.y;
					float num4 = Math.Abs(value) + Math.Abs(value2) + Math.Abs(value3);
					if (num4 < num)
					{
						result = roomData;
						num = num4;
					}
				}
			}
			return result;
		}

		internal static void AddRoom(Room room)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			RoomData orCreate = RoomTable.GetOrCreate((Object)(object)room);
			Vector3 position = ((Component)room).transform.position;
			if (HasAdded.Add(position))
			{
				orCreate.Name = ((Object)(object)room).GetCleanedName();
				orCreate.Pos = position;
				int num = ((((Vector3Int)(ref room.m_size)).x == 0) ? 10 : ((Vector3Int)(ref room.m_size)).x);
				int num2 = ((((Vector3Int)(ref room.m_size)).y == 0) ? 10 : ((Vector3Int)(ref room.m_size)).y);
				int num3 = ((((Vector3Int)(ref room.m_size)).z == 0) ? 10 : ((Vector3Int)(ref room.m_size)).z);
				orCreate.Size = new Vector3Int(num * 2, num2 * 2, num3 * 2);
				orCreate.Rotation = ((Component)room).transform.rotation;
				RoomList.Insert(orCreate);
			}
		}

		internal static void RemoveRoom(RoomData room)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			RoomList.Remove(room);
			HasAdded.Remove(room.Pos);
		}
	}
}
namespace SpawnThat.Utilities
{
	internal enum Separator
	{
		Comma,
		Slash,
		Dot,
		Newline
	}
	public static class StringExtensions
	{
		private static readonly char[] Comma = new char[1] { ',' };

		private static readonly char[] Slash = new char[2] { '/', '\\' };

		private static readonly char[] Dot = new char[1] { '.' };

		private static readonly char[] Newline = new char[1] { '\n' };

		internal static List<string> SplitBy(this string value, Separator separator, bool toUpper = false)
		{
			return value.SplitBy(separator switch
			{
				Separator.Comma => Comma, 
				Separator.Slash => Slash, 
				Separator.Dot => Dot, 
				Separator.Newline => Newline, 
				_ => throw new NotSupportedException("Separator"), 
			}, toUpper).ToList();
		}

		public static List<string> SplitByComma(this string value, bool toUpper = false)
		{
			return value.SplitBy(Comma, toUpper).ToList();
		}

		internal static string[] SplitBySlash(this string value, bool toUpper = false)
		{
			return value.SplitBy(Slash, toUpper).ToArray();
		}

		public static IEnumerable<string> SplitBy(this string value, char[] chars, bool toUpper = false)
		{
			if (value == null)
			{
				return Enumerable.Empty<string>();
			}
			string[] array = value.Trim().Split(chars, StringSplitOptions.RemoveEmptyEntries);
			if (array == null || array.Length == 0)
			{
				return Enumerable.Empty<string>();
			}
			return array.Select(Clean);
			string Clean(string x)
			{
				string text = x.Trim();
				if (toUpper)
				{
					return text.ToUpperInvariant();
				}
				return text;
			}
		}

		public static bool IsEmpty(this string s)
		{
			return string.IsNullOrWhiteSpace(s);
		}

		public static bool IsNotEmpty(this string s)
		{
			if (string.IsNullOrWhiteSpace(s))
			{
				return false;
			}
			return true;
		}
	}
	public static class FileUtils
	{
		public static void EnsureDirectoryExistsForFile(string filePath)
		{
			string directoryName = Path.GetDirectoryName(filePath);
			if (!Directory.Exists(directoryName))
			{
				Log.LogTrace("Creating missing folders in path.");
				Directory.CreateDirectory(directoryName);
			}
		}
	}
	internal static class HeightmapUtils
	{
		public static Biome ParseBiomeMask(IEnumerable<string> biomeNames)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Biome val = (Biome)0;
			if (biomeNames == null || !biomeNames.Any())
			{
				return val;
			}
			foreach (string biomeName in biomeNames)
			{
				if (Enum.TryParse<Biome>(biomeName, ignoreCase: true, out Biome result))
				{
					val |= result;
				}
				else
				{
					Log.LogWarning("Unable to parse biome '" + biomeName + "'. Check spelling.");
				}
			}
			return val;
		}

		public static List<Biome> ParseBiomes(IEnumerable<string> biomeNames)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			List<Biome> list = new List<Biome>();
			if (biomeNames == null || !biomeNames.Any())
			{
				return list;
			}
			foreach (string biomeName in biomeNames)
			{
				if (Enum.TryParse<Biome>(biomeName, ignoreCase: true, out Biome result))
				{
					list.Add(result);
				}
				else
				{
					Log.LogWarning("Unable to parse biome '" + biomeName + "'. Check spelling.");
				}
			}
			return list;
		}

		public static string GetNames(Biome biome)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			List<string> list = new List<string>();
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				Biome val = value;
				if ((int)val != 0 && (biome & val) > 0)
				{
					list.Add(((object)(Biome)(ref val)).ToString());
				}
			}
			return string.Join(", ", list);
		}
	}
	public static class PlayerUtils
	{
		public static List<Player> GetPlayersInRadius(Vector3 point, float range)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			List<Player> list = new List<Player>();
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (Utils.DistanceXZ(((Component)allPlayer).transform.position, point) < range)
				{
					list.Add(allPlayer);
				}
			}
			return list;
		}

		public static List<ZDO> GetPlayerZdosInRadius(Vector3 point, float range)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO> list = new List<ZDO>();
			foreach (ZDO allCharacterZDO in ZNet.instance.GetAllCharacterZDOS())
			{
				if (Utils.DistanceXZ(allCharacterZDO.GetPosition(), point) < range)
				{
					list.Add(allCharacterZDO);
				}
			}
			return list;
		}
	}
	internal static class ReflectionUtils
	{
		private static MethodInfo InstantiateGameObject;

		public static MethodInfo InstantiateGameObjectMethod => InstantiateGameObject ?? (InstantiateGameObject = (from x in typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public)
			where x.Name.Equals("Instantiate")
			select x into m
			where m.IsGenericMethod
			select m).First((MethodInfo m) => m.ContainsGenericParameters && m.GetParameters().Length == 3 && m.GetParameters()[2].ParameterType == typeof(Quaternion)).GetGenericMethodDefinition().MakeGenericMethod(typeof(GameObject)));
	}
}
namespace SpawnThat.Utilities.Spatial
{
	internal interface IBox
	{
		Vector3 Pos { get; }

		Quaternion Rotation { get; }

		Vector3Int Size { get; }
	}
	internal interface IHaveVector3
	{
		Vector3 Pos { get; }
	}
	internal interface IPoint
	{
		float X { get; set; }

		float Y { get; set; }
	}
	internal static class SearchSpatial
	{
		public static T FindClosest<T>(this IList<T> points, Vector3 pos) where T : class, IHaveVector3, IPoint
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (points == null || points.Count == 0)
			{
				return null;
			}
			T result = null;
			float num = float.MaxValue;
			int num2 = points.IndexLeft(pos.x - 20f);
			int num3 = points.IndexRight(pos.x + 20f);
			for (int i = num2; i <= num3 && i < points.Count; i++)
			{
				T val = points[i];
				if (!(Math.Abs(val.Pos.y - pos.y) > 100f))
				{
					float value = pos.x - val.Pos.x;
					float value2 = pos.z - val.Pos.z;
					float num4 = Math.Abs(value) + Math.Abs(value2);
					if (num4 < num)
					{
						result = val;
						num = num4;
					}
				}
			}
			return result;
		}

		public static bool Contains(IBox box, Vector3 pos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Contains(CreateRectangle(box), pos);
		}

		public static bool Contains(Vector2[] rectangle, Vector3 pos)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001f: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = rectangle[0];
			Vector2 val2 = rectangle[1];
			Vector2 val3 = rectangle[3];
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(pos.x, pos.z);
			Vector2 val5 = val2 - val;
			Vector2 val6 = val3 - val;
			Vector2 val7 = val4 - val;
			float num = Vector2.Dot(val7, val5);
			float num2 = Vector2.Dot(val5, val5);
			float num3 = Vector2.Dot(val7, val6);
			float num4 = Vector2.Dot(val6, val6);
			if (0f < num && num < num2 && 0f < num3 && num3 < num4)
			{
				return true;
			}
			return false;
		}

		public static Vector2[] CreateRectangle(IBox box)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			float x = box.Pos.x;
			Vector3Int size = box.Size;
			float num = x - (float)((Vector3Int)(ref size)).x;
			float z = box.Pos.z;
			size = box.Size;
			float num2 = z + (float)((Vector3Int)(ref size)).z;
			float x2 = box.Pos.x;
			size = box.Size;
			float num3 = x2 + (float)((Vector3Int)(ref size)).x;
			float z2 = box.Pos.z;
			size = box.Size;
			float num4 = z2 + (float)((Vector3Int)(ref size)).z;
			float x3 = box.Pos.x;
			size = box.Size;
			float num5 = x3 + (float)((Vector3Int)(ref size)).x;
			float z3 = box.Pos.z;
			size = box.Size;
			float num6 = z3 - (float)((Vector3Int)(ref size)).z;
			float x4 = box.Pos.x;
			size = box.Size;
			float num7 = x4 - (float)((Vector3Int)(ref size)).x;
			float z4 = box.Pos.z;
			size = box.Size;
			float num8 = z4 - (float)((Vector3Int)(ref size)).z;
			Vector2 point2 = default(Vector2);
			((Vector2)(ref point2))..ctor(num, num2);
			Vector2 point3 = default(Vector2);
			((Vector2)(ref point3))..ctor(num3, num4);
			Vector2 point4 = default(Vector2);
			((Vector2)(ref point4))..ctor(num5, num6);
			Vector2 point5 = default(Vector2);
			((Vector2)(ref point5))..ctor(num7, num8);
			return (Vector2[])(object)new Vector2[4]
			{
				Pivot(point2),
				Pivot(point3),
				Pivot(point4),
				Pivot(point5)
			};
			Vector2 Pivot(Vector2 point)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: 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_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: 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_003d: 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_0049: 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)
				//IL_0054: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = new Vector3(point.x, box.Pos.y, point.y) - box.Pos;
				Vector3 val2 = box.Rotation * val + box.Pos;
				return new Vector2(val2.x, val2.z);
			}
		}
	}
	internal static class SpatialListExtensions
	{
		public static void Insert<T>(this List<T> points, T point) where T : IPoint
		{
			int num = points.IndexLeft(point.X) + 1;
			for (int i = num; i < points.Count; i++)
			{
				T val = points[i];
				if (val.X > point.X || val.Y > point.Y)
				{
					break;
				}
				num = i;
			}
			if (num >= points.Count)
			{
				points.Add(point);
			}
			else
			{
				points.Insert(num, point);
			}
		}

		public static int IndexLeft<T>(this IList<T> points, T point) where T : IPoint
		{
			return points.IndexLeft(point.X);
		}

		public static int IndexLeft<T>(this IList<T> points, float x) where T : IPoint
		{
			int count = points.Count;
			int num = 0;
			int num2 = count;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				float x2 = points[num3].X;
				float x3 = points[Math.Min(num3 + 1, count - 1)].X;
				if (x2 < x)
				{
					if (x3 > x)
					{
						return num3;
					}
					num = num3 + 1;
				}
				else
				{
					num2 = num3;
				}
			}
			return num;
		}

		public static int IndexRight<T>(this IList<T> points, T point) where T : IPoint
		{
			return points.IndexRight(point.X);
		}

		public static int IndexRight<T>(this IList<T> points, float x) where T : IPoint
		{
			int count = points.Count;
			int num = 0;
			int num2 = count;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				float x2 = points[num3].X;
				float x3 = points[Math.Max(num3 - 1, 0)].X;
				if (x2 > x)
				{
					if (x3 < x)
					{
						return num3;
					}
					num2 = num3;
				}
				else
				{
					num = num3 + 1;
				}
			}
			return num2 - 1;
		}

		public static int IndexUp<T>(this IList<T> points, int xLower, int xUpper, T point) where T : IPoint
		{
			return points.IndexUp(xLower, xUpper, point.Y);
		}

		public static int IndexUp<T>(this IList<T> points, int xLower, int xUpper, float y) where T : IPoint
		{
			int count = points.Count;
			int num = xLower;
			int num2 = xUpper;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				float y2 = points[num3].Y;
				float y3 = points[Math.Min(num3 + 1, count - 1)].Y;
				if (y2 < y)
				{
					if (y3 > y)
					{
						return num3;
					}
					num = num3 + 1;
				}
				else
				{
					num2 = num3;
				}
			}
			return num;
		}

		public static int IndexDown<T>(this IList<T> points, int xIndex, T point) where T : IPoint
		{
			return points.IndexDown(xIndex, point.Y);
		}

		public static int IndexDown<T>(this IList<T> points, int xIndex, float y) where T : IPoint
		{
			if (xIndex >= points.Count)
			{
				return xIndex;
			}
			float x = points[xIndex].X;
			int num = xIndex;
			int num2 = points.Count;
			while (num < num2)
			{
				int num3 = (num + num2) / 2;
				if (points[num3].X > x)
				{
					return num3 - 1;
				}
				if (points[num3].Y > y)
				{
					num2 = num3;
				}
				else
				{
					num = num3 + 1;
				}
			}
			return num2 - 1;
		}
	}
}
namespace SpawnThat.Utilities.Extensions
{
	internal static class CodeInstructionExtensions
	{
		public static CodeInstruction GetLdlocFromStLoc(this CodeInstruction instruction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (instruction.opcode == OpCodes.Stloc_0)
			{
				return new CodeInstruction(OpCodes.Ldloc_0, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_1)
			{
				return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_2)
			{
				return new CodeInstruction(OpCodes.Ldloc_2, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_3)
			{
				return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_S)
			{
				return new CodeInstruction(OpCodes.Ldloca_S, instruction.operand);
			}
			if (instruction.opcode == OpCodes.Stloc)
			{
				return new CodeInstruction(OpCodes.Ldloc, instruction.operand);
			}
			throw new ArgumentException($"Unexpected instruction '{instruction}' encountered. Expected an {OpCodes.Stloc}.");
		}

		public static CodeInstruction GetStlocFromLdloc(this CodeInstruction instruction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (instruction.opcode == OpCodes.Ldloc_0)
			{
				return new CodeInstruction(OpCodes.Stloc_0, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_1)
			{
				return new CodeInstruction(OpCodes.Stloc_1, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_2)
			{
				return new CodeInstruction(OpCodes.Stloc_2, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_3)
			{
				return new CodeInstruction(OpCodes.Stloc_3, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloca_S)
			{
				return new CodeInstruction(OpCodes.Stloc_S, instruction.operand);
			}
			if (instruction.opcode == OpCodes.Ldloc)
			{
				return new CodeInstruction(OpCodes.Stloc, instruction.operand);
			}
			throw new ArgumentException($"Unexpected instruction '{instruction}' encountered. Expected an {OpCodes.Ldloc}.");
		}
	}
	public static class CodeMatcherExtensions
	{
		public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position)
		{
			position = codeMatcher.Pos;
			return codeMatcher;
		}

		public static CodeMatcher InsertAndAdvance(this CodeMatcher codeMatcher, OpCode opcode)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			codeMatcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(opcode, (object)null)
			});
			return codeMatcher;
		}

		public static CodeMatcher InsertAndAdvance(this CodeMatcher codeMatcher, MethodInfo method)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			codeMatcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)method)
			});
			return codeMatcher;
		}

		public static CodeMatcher InsertAndAdvance<T>(this CodeMatcher codeMatcher, string methodName)
		{
			return codeMatcher.InsertAndAdvance(AccessTools.Method(typeof(T), methodName, (Type[])null, (Type[])null));
		}

		public static CodeMatcher GetOpcode(this CodeMatcher codeMatcher, out OpCode opcode)
		{
			opcode = codeMatcher.Opcode;
			return codeMatcher;
		}

		public static CodeMatcher GetInstruction(this CodeMatcher codeMatcher, out CodeInstruction instruction)
		{
			instruction = codeMatcher.Instruction;
			return codeMatcher;
		}

		public static CodeMatcher GetOperand(this CodeMatcher codeMatcher, out object operand)
		{
			operand = codeMatcher.Operand;
			return codeMatcher;
		}

		internal static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after)
		{
			return codeMatcher;
		}
	}
	internal static class EnumExtensions
	{
		public static List<TEnum> Split<TEnum>(this TEnum enumVal) where TEnum : struct, Enum
		{
			int num = Convert.ToInt32(enumVal);
			List<TEnum> list = new List<TEnum>();
			foreach (TEnum value in Enum.GetValues(typeof(TEnum)))
			{
				if ((num & Convert.ToInt32(value)) > 0)
				{
					list.Add(value);
				}
			}
			return list;
		}

		public static List<Biome> Split(this Biome biomeMask)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			List<Biome> list = new List<Biome>();
			foreach (Biome value in Enum.GetValues(typeof(Biome)))
			{
				if ((int)value == 895)
				{
					if ((int)biomeMask == 895)
					{
						list.Add(value);
					}
				}
				else if ((biomeMask & value) > 0)
				{
					list.Add(value);
				}
			}
			return list;
		}
	}
	internal static class ICollectionExtensions
	{
		public static void AddNullSafe<T>(this ICollection<T> collection, T newEntry) where T : class
		{
			if (collection != null && newEntry != null)
			{
				Object val = (Object)(object)((newEntry is Object) ? newEntry : n