Decompiled source of LivingWorld v0.19.0

plugins/LivingWorld.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using ValheimDynasty.Camps;
using ValheimDynasty.Core;
using ValheimDynasty.DebugTools;
using ValheimDynasty.Needs;
using ValheimDynasty.Net;
using ValheimDynasty.Quests;
using ValheimDynasty.Raids;
using ValheimDynasty.Recruitment;
using ValheimDynasty.Seasons;
using ValheimDynasty.Villagers;
using ValheimDynasty.Villages;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("LivingWorld")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.10.0.0")]
[assembly: AssemblyInformationalVersion("0.10.0")]
[assembly: AssemblyProduct("LivingWorld")]
[assembly: AssemblyTitle("LivingWorld")]
[assembly: AssemblyVersion("0.10.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[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 ValheimDynasty
{
	[BepInPlugin("com.firstphase.livingworld", "Living World", "0.19.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class DynastyPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.firstphase.livingworld";

		public const string ModName = "Living World";

		public const string ModVersion = "0.19.0";

		private Harmony _harmony;

		private ModuleHost _modules;

		internal static bool HideOwnUi;

		internal static DynastyPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static bool VerboseOn
		{
			get
			{
				if (ModConfig.VerboseLog != null)
				{
					return ModConfig.VerboseLog.Value;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			NeedsConfig.Bind(((BaseUnityPlugin)this).Config);
			SeasonsConfig.Bind(((BaseUnityPlugin)this).Config);
			VillagersConfig.Bind(((BaseUnityPlugin)this).Config);
			VillagesConfig.Bind(((BaseUnityPlugin)this).Config);
			RecruitConfig.Bind(((BaseUnityPlugin)this).Config);
			CampConfig.Bind(((BaseUnityPlugin)this).Config);
			QuestConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.firstphase.livingworld");
			GamePatches.Apply(_harmony);
			SeasonPatches.Apply(_harmony);
			DevCommandFile.Apply(_harmony);
			VillageScreen.Apply(_harmony);
			CampDeathPatch.Apply(_harmony);
			CampWar.Apply(_harmony);
			NetSync.Init();
			DebugCommands.Register();
			NeedsItems.Register();
			VillagerPrefab.Register();
			BanditPrefab.Register();
			VillageTotemPiece.Register();
			_modules = new ModuleHost();
			_modules.Register(new GameCalendar());
			_modules.Register(new NeedsModule());
			_modules.Register(new SeasonsModule());
			_modules.InitAll();
			Log.LogInfo((object)"Living World 0.19.0 loaded. This is an unofficial mod, not supported by Iron Gate.");
		}

		private void Update()
		{
			float deltaTime = Time.deltaTime;
			Perf.Frame();
			Safe.Run("WorldLifecycle", WorldLifecycle.Tick);
			Safe.Run("WorldScan", WorldScan.Tick);
			Safe.Run("NetSync", NetSync.Tick);
			_modules?.TickAll(deltaTime);
			Safe.Run("DebugOverlay.Input", DebugOverlay.HandleInput);
			Safe.Run("DevCommandFile", DevCommandFile.Tick);
			Safe.Run("VillageScreen", VillageScreen.Tick);
			Safe.Run("TalkScreen", TalkScreen.Tick);
			Safe.Run("Wanderers", WandererSpawner.Tick);
			Safe.Run("WandererPins", WandererPins.Tick);
			Safe.Run("CampSim", CampSim.Tick);
			Safe.Run("CampMaterializer", CampMaterializer.Tick);
			Safe.Run("QuestSim", QuestSim.Tick);
			Safe.Run("QuestWorld", QuestWorld.Tick);
			Safe.Run("QuestLog", QuestLog.Tick);
			Safe.Run("TownCatchUp", TownCatchUp.Tick);
			Safe.Run("Guide", GuideScreen.Tick);
			Safe.Run("VillageProgress", VillageProgress.Tick);
		}

		private void OnGUI()
		{
			if (!HideOwnUi)
			{
				Safe.Run("DebugOverlay.Draw", delegate
				{
					DebugOverlay.Draw(_modules);
				});
				Safe.Run("NeedsHud.Draw", NeedsHud.Draw);
				Safe.Run("TownPlanView.Draw", TownPlanView.Draw);
				Safe.Run("VillageScreen.Draw", VillageScreen.Draw);
				Safe.Run("TalkScreen.Draw", TalkScreen.Draw);
				Safe.Run("QuestLog.Draw", QuestLog.Draw);
				Safe.Run("Guide.Draw", GuideScreen.Draw);
			}
		}

		private void OnApplicationQuit()
		{
			ModData.SaveIfServer("application quit");
		}

		private void OnDestroy()
		{
			ModData.SaveIfServer("plugin destroyed");
			_modules?.ShutdownAll();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace ValheimDynasty.Villages
{
	internal static class Blueprints
	{
		public enum Use
		{
			Structure,
			Bed,
			Workbench,
			Chest,
			Furniture
		}

		internal sealed class Part
		{
			public string Prefab;

			public string[] Alt;

			public Vector3 Local;

			public float Yaw;

			public Use Use;

			public int MinStage;

			public bool OnGround;

			public Part(string prefab, float x, float y, float z, float yaw, Use use = Use.Structure, params string[] alt)
			{
				//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)
				Prefab = prefab;
				Local = new Vector3(x, y, z);
				Yaw = yaw;
				Use = use;
				Alt = alt;
			}
		}

		internal sealed class Plan
		{
			public string Name;

			public float Raise;

			public Vector2 Half;

			public int Length;

			public List<Part> Parts = new List<Part>();

			public int Stairs;

			public float DoorX;

			public bool HasDoor;
		}

		internal sealed class Site
		{
			public Plan Plan;

			public float Yaw;

			public string Tag;

			public string Key;

			public Func<int, Plan> Make;

			public int MinStairs;

			public Vector3 Pos;

			public Quaternion Rot;

			public float Base;

			public bool Started;

			public bool Walkable;

			public float Floor => Base + Plan.Raise;

			public Vector3 World(Part p)
			{
				//IL_0001: 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_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_0036: 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_0073: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Pos + Rot * new Vector3(p.Local.x, 0f, p.Local.z);
				val.y = ((p.OnGround && (Object)(object)ZoneSystem.instance != (Object)null) ? (ZoneSystem.instance.GetGroundHeight(val) + p.Local.y) : (Base + Plan.Raise + p.Local.y));
				return val;
			}

			public Quaternion WorldRot(Part p)
			{
				//IL_0001: 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_001b: Unknown result type (might be due to invalid IL or missing references)
				return Rot * Quaternion.Euler(0f, p.Yaw, 0f);
			}

			public Vector3 Local(Vector3 w)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: 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)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				return Quaternion.Inverse(Rot) * (w - Pos);
			}

			public bool Contains(Vector3 w, float margin)
			{
				//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_0027: 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)
				Vector3 val = Local(w);
				if (Mathf.Abs(val.x) <= Plan.Half.x + margin && val.z >= 0f - Plan.Half.y - margin)
				{
					return val.z <= Plan.Half.y + 2f * (float)Plan.Stairs + margin;
				}
				return false;
			}

			public bool Inside(Vector3 w, float margin)
			{
				//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_0027: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Local(w);
				if (Mathf.Abs(val.x) <= Plan.Half.x + margin)
				{
					return Mathf.Abs(val.z) <= Plan.Half.y + margin;
				}
				return false;
			}

			public Vector3 Outside(Vector3 w)
			{
				//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_0045: 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_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: 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_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_0157: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0174: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Local(w);
				float num = Plan.Half.x + 0.9f;
				float num2 = Plan.Half.y + 0.9f;
				Vector3[] obj = new Vector3[4]
				{
					new Vector3(0f - num, 0f, Mathf.Clamp(val.z, 0f - Plan.Half.y, Plan.Half.y)),
					new Vector3(num, 0f, Mathf.Clamp(val.z, 0f - Plan.Half.y, Plan.Half.y)),
					new Vector3(Mathf.Clamp(val.x, 0f - Plan.Half.x, Plan.Half.x), 0f, 0f - num2),
					new Vector3(Mathf.Clamp(val.x, 0f - Plan.Half.x, Plan.Half.x), 0f, num2)
				};
				Vector3 val2 = obj[0];
				float num3 = float.MaxValue;
				Vector3[] array = (Vector3[])(object)obj;
				foreach (Vector3 val3 in array)
				{
					Vector3 val4 = val3 - new Vector3(val.x, 0f, val.z);
					float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
					if (sqrMagnitude < num3)
					{
						num3 = sqrMagnitude;
						val2 = val3;
					}
				}
				Vector3 val5 = Pos + Rot * val2;
				val5.y = ZoneSystem.instance.GetGroundHeight(val5);
				return val5;
			}

			public Vector3 Ground(float x, float z)
			{
				//IL_0001: 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_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: 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)
				Vector3 val = Pos + Rot * new Vector3(x, 0f, z);
				val.y = ZoneSystem.instance.GetGroundHeight(val);
				return val;
			}
		}

		private sealed class PlanCache
		{
			public float At;

			public List<Site> Sites;
		}

		internal sealed class PlanEdit
		{
			public bool Cancel;

			public float Dx;

			public float Dz;

			public float Rot;
		}

		private struct Range
		{
			public float Lo;

			public float Hi;

			public float At;
		}

		private sealed class TownCache
		{
			public float At;

			public List<Site> Sites = new List<Site>();
		}

		private static readonly Dictionary<int, Plan> WorkshopCache = new Dictionary<int, Plan>();

		private static readonly Dictionary<int, Plan> StorehouseCache = new Dictionary<int, Plan>();

		public const int HutBeds = 3;

		private static readonly Dictionary<int, Plan> HutCache = new Dictionary<int, Plan>();

		public static readonly int[] HouseLengths = new int[4] { 6, 8, 10, 12 };

		public const int MaxStairs = 6;

		public const float MaxDrop = 4f;

		private static readonly Dictionary<string, Plan> HouseCache = new Dictionary<string, Plan>();

		private static readonly Vector2[] HouseDirs = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(-1f, 0f),
			new Vector2(0f, 1f),
			new Vector2(0f, -1f),
			new Vector2(-1f, -1f)
		};

		private static readonly float[] HouseYaws = new float[4] { 90f, 180f, 0f, 45f };

		private static readonly float[] HouseGap = new float[4] { 6f, 6f, 19f, 14f };

		private static readonly float[] PushBack = new float[3] { 0f, 2f, 4f };

		private static readonly List<Piece> Theirs = new List<Piece>();

		public const string KSite = "vd_site";

		private static readonly List<Piece> Hits = new List<Piece>();

		private static readonly Vector3[] StoreSpots = (Vector3[])(object)new Vector3[4]
		{
			new Vector3(11f, 0f, -8f),
			new Vector3(11f, 0f, 9f),
			new Vector3(-11f, 0f, -9f),
			new Vector3(19f, 0f, 0f)
		};

		private static readonly float[] StoreYaws = new float[4] { -90f, -90f, 90f, -90f };

		private static readonly Vector3[] OldStoreSpots = (Vector3[])(object)new Vector3[1]
		{
			new Vector3(10f, 0f, 10f)
		};

		private static readonly float[] OldStoreYaws = new float[1] { -135f };

		private static readonly Dictionary<string, PlanCache> SiteCache = new Dictionary<string, PlanCache>();

		private static Dictionary<string, PlanEdit> _edits = new Dictionary<string, PlanEdit>();

		private static readonly Dictionary<long, Range> Ranges = new Dictionary<long, Range>();

		private static readonly Dictionary<string, TownCache> Towns = new Dictionary<string, TownCache>();

		public static Plan Workshop => WorkshopWith(1);

		public static Plan Storehouse => StorehouseWith(1);

		private static void Skirt(List<Part> L, float hx, float hz, float doorX, bool frontOpen)
		{
			for (float num = 0f - hz + 1f; num < hz; num += 2f)
			{
				L.Add(new Part("wood_wall_half", 0f - hx, -0.5f, num, 90f, Use.Structure));
				L.Add(new Part("wood_wall_half", hx, -0.5f, num, 90f, Use.Structure));
			}
			for (float num2 = 0f - hx + 1f; num2 < hx; num2 += 2f)
			{
				L.Add(new Part("wood_wall_half", num2, -0.5f, 0f - hz, 0f, Use.Structure));
				if (!frontOpen && Mathf.Abs(num2 - doorX) > 0.5f)
				{
					L.Add(new Part("wood_wall_half", num2, -0.5f, hz, 0f, Use.Structure));
				}
			}
		}

		private static void StairsDown(List<Part> L, float x, float hz, int n)
		{
			for (int i = 0; i < n; i++)
			{
				L.Add(new Part("wood_stair", x, -1f - (float)i, hz + 1f + 2f * (float)i, 0f, Use.Structure));
			}
			float z = hz + 2f * (float)n + 0.7f;
			float[] array = new float[2] { -1.6f, 1.6f };
			foreach (float num in array)
			{
				L.Add(new Part("piece_groundtorch_wood", x + num, 0f, z, 0f, Use.Furniture)
				{
					OnGround = true,
					MinStage = 2
				});
			}
		}

		public static Plan WorkshopWith(int stairs)
		{
			//IL_0037: 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)
			if (WorkshopCache.TryGetValue(stairs, out var value))
			{
				return value;
			}
			Plan plan = new Plan
			{
				Name = "workshop",
				Raise = 0.3f,
				Half = new Vector2(2f, 3f),
				Stairs = stairs,
				DoorX = 0f,
				HasDoor = true
			};
			List<Part> parts = plan.Parts;
			float[] array = new float[2] { -2f, 2f };
			foreach (float x in array)
			{
				float[] array2 = new float[4] { -3f, -1f, 1f, 3f };
				foreach (float z in array2)
				{
					parts.Add(new Part("wood_pole2", x, -1f, z, 0f, Use.Structure));
				}
			}
			array = new float[2] { -1f, 1f };
			foreach (float x2 in array)
			{
				float[] array2 = new float[3] { -2f, 0f, 2f };
				foreach (float z2 in array2)
				{
					parts.Add(new Part("wood_floor", x2, 0f, z2, 0f, Use.Structure));
				}
			}
			parts.Add(new Part("piece_chest_wood", 1.3f, 0f, 0.6f, 90f, Use.Chest));
			parts.Add(new Part("piece_workbench", 0f, 0f, -2.2f, 0f, Use.Workbench));
			parts.Add(new Part("piece_workbench_ext1", -1.3f, 0f, 1f, 0f, Use.Furniture)
			{
				MinStage = 2
			});
			parts.Add(new Part("piece_workbench_ext2", -1.45f, 0f, -0.9f, 90f, Use.Furniture)
			{
				MinStage = 2
			});
			parts.Add(new Part("piece_workbench_ext3", 1.35f, 0f, -1.3f, -90f, Use.Furniture)
			{
				MinStage = 2
			});
			parts.Add(new Part("piece_workbench_ext4", 1.85f, 1.1f, 2f, -90f, Use.Furniture)
			{
				MinStage = 2
			});
			parts.Add(new Part("forge", 3.8f, 0f, -1.2f, 90f, Use.Furniture)
			{
				MinStage = 2,
				OnGround = true
			});
			parts.Add(new Part("smelter", 3.9f, 0f, 1.7f, 90f, Use.Furniture)
			{
				MinStage = 2,
				OnGround = true
			});
			parts.Add(new Part("charcoal_kiln", 3.9f, 0f, 4.6f, 90f, Use.Furniture)
			{
				MinStage = 2,
				OnGround = true
			});
			StairsDown(parts, 0f, 3f, stairs);
			Skirt(parts, 2f, 3f, 0f, frontOpen: true);
			array = new float[2] { 1f, 3f };
			foreach (float y in array)
			{
				float[] array2 = new float[2] { -1f, 1f };
				foreach (float x3 in array2)
				{
					parts.Add(new Part("woodwall", x3, y, -3f, 0f, Use.Structure));
				}
				array2 = new float[3] { -2f, 0f, 2f };
				foreach (float z3 in array2)
				{
					parts.Add(new Part("woodwall", -2f, y, z3, 90f, Use.Structure));
					parts.Add(new Part("woodwall", 2f, y, z3, 90f, Use.Structure));
				}
			}
			array = new float[3] { -2f, 0f, 2f };
			foreach (float z4 in array)
			{
				parts.Add(new Part("wood_roof", 1f, 4f, z4, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -1f, 4f, z4, -90f, Use.Structure));
			}
			parts.Add(new Part("wood_wall_roof", 1f, 4f, -3f, 180f, Use.Structure));
			parts.Add(new Part("wood_wall_roof", -1f, 4f, -3f, 0f, Use.Structure));
			WorkshopCache[stairs] = plan;
			return plan;
		}

		public static Plan StorehouseWith(int stairs)
		{
			//IL_0037: 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)
			if (StorehouseCache.TryGetValue(stairs, out var value))
			{
				return value;
			}
			Plan plan = new Plan
			{
				Name = "storehouse",
				Raise = 0.3f,
				Half = new Vector2(3f, 3f),
				Stairs = stairs,
				DoorX = 0f,
				HasDoor = true
			};
			List<Part> parts = plan.Parts;
			float[] array = new float[4] { -3f, -1f, 1f, 3f };
			foreach (float num in array)
			{
				float[] array2 = new float[4] { -3f, -1f, 1f, 3f };
				foreach (float num2 in array2)
				{
					if (Mathf.Abs(num) == 3f || Mathf.Abs(num2) == 3f)
					{
						parts.Add(new Part("wood_pole2", num, -1f, num2, 0f, Use.Structure));
					}
				}
			}
			array = new float[3] { -2f, 0f, 2f };
			foreach (float x in array)
			{
				float[] array2 = new float[3] { -2f, 0f, 2f };
				foreach (float z in array2)
				{
					parts.Add(new Part("wood_floor", x, 0f, z, 0f, Use.Structure));
				}
			}
			StairsDown(parts, 0f, 3f, stairs);
			Skirt(parts, 3f, 3f, 0f, frontOpen: false);
			array = new float[2] { 1f, 3f };
			foreach (float num3 in array)
			{
				float[] array2 = new float[3] { -2f, 0f, 2f };
				foreach (float z2 in array2)
				{
					parts.Add(new Part("woodwall", -3f, num3, z2, 90f, Use.Structure));
					parts.Add(new Part("woodwall", 3f, num3, z2, 90f, Use.Structure));
				}
				array2 = new float[3] { -2f, 0f, 2f };
				foreach (float num4 in array2)
				{
					parts.Add(new Part("woodwall", num4, num3, -3f, 0f, Use.Structure));
					parts.Add((num3 < 2f && num4 == 0f) ? new Part("wood_door", num4, num3, 3f, 0f, Use.Structure) : new Part("woodwall", num4, num3, 3f, 0f, Use.Structure));
				}
			}
			array = new float[3] { -2f, 0f, 2f };
			foreach (float z3 in array)
			{
				parts.Add(new Part("wood_roof", 2f, 4f, z3, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -2f, 4f, z3, -90f, Use.Structure));
				parts.Add(new Part("wood_roof", 0.5f, 4.75f, z3, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -0.5f, 4.75f, z3, -90f, Use.Structure));
			}
			array = new float[2] { -3f, 3f };
			foreach (float z4 in array)
			{
				parts.Add(new Part("wood_wall_roof", 2f, 4f, z4, 180f, Use.Structure));
				parts.Add(new Part("wood_wall_roof", -2f, 4f, z4, 0f, Use.Structure));
				parts.Add(new Part("wood_wall_half", 0f, 4.5f, z4, 0f, Use.Structure));
			}
			array = new float[3] { -1.9f, 0f, 1.9f };
			foreach (float x2 in array)
			{
				parts.Add(new Part("piece_chest_wood", x2, 0f, -2.45f, 0f, Use.Chest));
			}
			array = new float[2] { -0.9f, 0.9f };
			foreach (float z5 in array)
			{
				parts.Add(new Part("piece_chest_wood", -2.45f, 0f, z5, 90f, Use.Chest));
				parts.Add(new Part("piece_chest_wood", 2.45f, 0f, z5, -90f, Use.Chest));
			}
			StorehouseCache[stairs] = plan;
			return plan;
		}

		public static Plan HutWith(int stairs)
		{
			//IL_0037: 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)
			if (HutCache.TryGetValue(stairs, out var value))
			{
				return value;
			}
			value = new Plan
			{
				Name = "hut",
				Raise = 0.3f,
				Half = new Vector2(2f, 3f),
				Length = 6,
				Stairs = stairs,
				DoorX = 1f,
				HasDoor = true
			};
			List<Part> parts = value.Parts;
			float[] array = new float[2] { -2f, 2f };
			foreach (float x in array)
			{
				float[] array2 = new float[4] { -3f, -1f, 1f, 3f };
				foreach (float z in array2)
				{
					parts.Add(new Part("wood_pole2", x, -1f, z, 0f, Use.Structure));
				}
			}
			array = new float[2] { -1f, 1f };
			foreach (float x2 in array)
			{
				float[] array2 = new float[3] { -2f, 0f, 2f };
				foreach (float z2 in array2)
				{
					parts.Add(new Part("wood_floor", x2, 0f, z2, 0f, Use.Structure));
				}
			}
			array = new float[3] { -2.2f, -0.8f, 0.6f };
			foreach (float z3 in array)
			{
				parts.Add(new Part("bed", -0.55f, 0f, z3, 90f, Use.Bed));
			}
			StairsDown(parts, 1f, 3f, stairs);
			Skirt(parts, 2f, 3f, 1f, frontOpen: false);
			array = new float[3] { -2f, 0f, 2f };
			foreach (float z4 in array)
			{
				parts.Add(new Part("woodwall", -2f, 1f, z4, 90f, Use.Structure));
				parts.Add(new Part("woodwall", 2f, 1f, z4, 90f, Use.Structure));
			}
			array = new float[2] { -1f, 1f };
			foreach (float num in array)
			{
				parts.Add(new Part("woodwall", num, 1f, -3f, 0f, Use.Structure));
				parts.Add((num == 1f) ? new Part("wood_door", num, 1f, 3f, 0f, Use.Structure) : new Part("woodwall", num, 1f, 3f, 0f, Use.Structure));
			}
			array = new float[3] { -2f, 0f, 2f };
			foreach (float z5 in array)
			{
				parts.Add(new Part("wood_roof", 1f, 2f, z5, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -1f, 2f, z5, -90f, Use.Structure));
			}
			array = new float[2] { -3f, 3f };
			foreach (float z6 in array)
			{
				parts.Add(new Part("wood_wall_roof", 1f, 2f, z6, 180f, Use.Structure));
				parts.Add(new Part("wood_wall_roof", -1f, 2f, z6, 0f, Use.Structure));
			}
			HutCache[stairs] = value;
			return value;
		}

		public static int Capacity(int length)
		{
			return 2 * Mathf.FloorToInt(((float)length - 3.4f) / 1.6f);
		}

		public static int LengthFor(int beds)
		{
			int[] houseLengths = HouseLengths;
			foreach (int num in houseLengths)
			{
				if (Capacity(num) >= beds)
				{
					return num;
				}
			}
			return HouseLengths[HouseLengths.Length - 1];
		}

		public static float Drop(Site s)
		{
			GroundRange(s, out var lo, out var hi);
			return hi - lo;
		}

		public static Plan Longhouse(int length, int beds, int stairs)
		{
			//IL_0076: 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)
			string key = length + "|" + beds + "|" + stairs;
			if (HouseCache.TryGetValue(key, out var value))
			{
				return value;
			}
			float num = (float)length / 2f;
			value = new Plan
			{
				Name = "longhouse",
				Raise = 1f,
				Half = new Vector2(4f, num),
				Length = length,
				Stairs = stairs,
				DoorX = 1f,
				HasDoor = true
			};
			List<Part> parts = value.Parts;
			List<float> list = new List<float>();
			for (float num2 = 0f - num; num2 <= num + 0.01f; num2 += 2f)
			{
				list.Add(num2);
			}
			float[] array = new float[3] { -4f, 0f, 4f };
			foreach (float x in array)
			{
				foreach (float item in list)
				{
					parts.Add(new Part("wood_pole2", x, -1f, item, 0f, Use.Structure));
				}
			}
			List<float> list2 = new List<float>();
			for (float num3 = 0f - num + 1f; num3 < num; num3 += 2f)
			{
				list2.Add(num3);
			}
			array = new float[4] { -3f, -1f, 1f, 3f };
			foreach (float x2 in array)
			{
				foreach (float item2 in list2)
				{
					parts.Add(new Part("wood_floor", x2, 0f, item2, 0f, Use.Structure));
				}
			}
			int num4 = Capacity(length) / 2;
			int num5 = 0;
			for (int j = 0; j < num4; j++)
			{
				if (num5 >= beds)
				{
					break;
				}
				float z = 0f - num + 0.95f + 1.6f * (float)j;
				parts.Add(new Part("bed", -2.45f, 0f, z, 90f, Use.Bed));
				num5++;
				if (num5 < beds)
				{
					parts.Add(new Part("bed", 2.45f, 0f, z, -90f, Use.Bed));
					num5++;
				}
			}
			StairsDown(parts, 1f, num, stairs);
			Skirt(parts, 4f, num, 1f, frontOpen: false);
			array = new float[2] { 1f, 3f };
			foreach (float num6 in array)
			{
				foreach (float item3 in list2)
				{
					parts.Add(new Part("woodwall", -4f, num6, item3, 90f, Use.Structure));
					parts.Add(new Part("woodwall", 4f, num6, item3, 90f, Use.Structure));
				}
				float[] array2 = new float[4] { -3f, -1f, 1f, 3f };
				foreach (float num7 in array2)
				{
					parts.Add(new Part("woodwall", num7, num6, 0f - num, 0f, Use.Structure));
					parts.Add((num6 < 2f && num7 == 1f) ? new Part("wood_door", num7, num6, num, 0f, Use.Structure) : new Part("woodwall", num7, num6, num, 0f, Use.Structure));
				}
			}
			foreach (float item4 in list2)
			{
				parts.Add(new Part("wood_roof", 3f, 4f, item4, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -3f, 4f, item4, -90f, Use.Structure));
				parts.Add(new Part("wood_roof", 1f, 5f, item4, 90f, Use.Structure));
				parts.Add(new Part("wood_roof", -1f, 5f, item4, -90f, Use.Structure));
			}
			array = new float[2]
			{
				0f - num,
				num
			};
			foreach (float z2 in array)
			{
				parts.Add(new Part("wood_wall_roof", 3f, 4f, z2, 180f, Use.Structure));
				parts.Add(new Part("wood_wall_roof", -3f, 4f, z2, 0f, Use.Structure));
				parts.Add(new Part("wood_wall_half", 1f, 4.5f, z2, 0f, Use.Structure));
				parts.Add(new Part("wood_wall_half", -1f, 4.5f, z2, 0f, Use.Structure));
				parts.Add(new Part("wood_wall_roof", 1f, 5f, z2, 180f, Use.Structure));
				parts.Add(new Part("wood_wall_roof", -1f, 5f, z2, 0f, Use.Structure));
			}
			parts.Add(new Part("piece_table", -1.6f, 0f, num - 1.5f, 0f, Use.Furniture)
			{
				MinStage = 1
			});
			parts.Add(new Part("piece_bench01", -1.6f, 0f, num - 2.5f, 0f, Use.Furniture, "piece_logbench01")
			{
				MinStage = 1
			});
			parts.Add(new Part("piece_bench01", -1.6f, 0f, num - 0.5f, 180f, Use.Furniture, "piece_logbench01")
			{
				MinStage = 1
			});
			HouseCache[key] = value;
			return value;
		}

		private static void HouseFrame(Vector3 villageCenter, Quaternion face, int slot, int length, out Vector3 pos, out Quaternion rot, float extra = 0f)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0029: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			float num = HouseGap[slot] + extra + (float)length / 2f;
			Vector2 normalized = ((Vector2)(ref HouseDirs[slot])).normalized;
			pos = villageCenter + face * new Vector3(normalized.x * num, 0f, normalized.y * num);
			pos.y = 0f;
			rot = face * Quaternion.Euler(0f, HouseYaws[slot], 0f);
		}

		private static int StairsFor(Site s, float doorX, int min)
		{
			//IL_00a5: 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_002e: 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_004f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			float floor = s.Floor;
			float y = s.Plan.Half.y;
			if (s.Started)
			{
				int num = 0;
				for (int i = 0; i < 6; i++)
				{
					Vector3 at = s.Pos + s.Rot * new Vector3(doorX, 0f, y + 1f + 2f * (float)i);
					at.y = floor - 1f - (float)i;
					if (!VillageLayout.Built("wood_stair", at))
					{
						break;
					}
					num = i + 1;
				}
				if (num > 0)
				{
					return Mathf.Max(num, min);
				}
			}
			if (min <= 0 && s.Ground(doorX, y + 0.8f).y >= floor - 0.2f)
			{
				return 0;
			}
			int j;
			for (j = 1; j < 6 && !(s.Ground(doorX, y + 2f * (float)j).y >= floor - (float)j - 0.1f); j++)
			{
			}
			return j;
		}

		private static Site Place(Vector3 c, Quaternion face, Vector3 local, float yaw, float baseHeight, Func<int, Plan> make, int minStairs, string key = null)
		{
			//IL_003c: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_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_0075: 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)
			Site site = new Site
			{
				Yaw = yaw,
				Base = baseHeight,
				Plan = make(1),
				Key = key,
				Make = make,
				MinStairs = minStairs
			};
			site.Pos = c + face * local;
			site.Pos.y = 0f;
			site.Rot = face * Quaternion.Euler(0f, yaw, 0f);
			Edit(site, face);
			ResolveBase(site);
			site.Plan = make(Mathf.Max(minStairs, StairsFor(site, site.Plan.DoorX, minStairs)));
			Footings(site);
			return site;
		}

		private static void Footings(Site s)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return;
			}
			List<Part> list = null;
			foreach (Part part in s.Plan.Parts)
			{
				float num;
				if (part.Prefab == "wood_pole2" && part.Local.y <= -0.9f)
				{
					num = part.Local.y - 1f;
				}
				else
				{
					if (!(part.Prefab == "wood_stair"))
					{
						continue;
					}
					num = part.Local.y;
				}
				Vector3 val = s.Pos + s.Rot * new Vector3(part.Local.x, 0f, part.Local.z);
				float num2 = s.Floor + num - ZoneSystem.instance.GetGroundHeight(val);
				if (num2 < 0.4f)
				{
					continue;
				}
				int num3 = Mathf.Min(4, Mathf.CeilToInt((num2 - 0.2f) / 2f));
				for (int i = 1; i <= num3; i++)
				{
					if (list == null)
					{
						list = new List<Part>();
					}
					list.Add(new Part("wood_pole2", part.Local.x, num - 1f - 2f * (float)(i - 1), part.Local.z, part.Yaw, Use.Structure));
				}
			}
			if (list != null)
			{
				list.Sort((Part a, Part b) => a.Local.y.CompareTo(b.Local.y));
				Plan plan = new Plan
				{
					Name = s.Plan.Name,
					Raise = s.Plan.Raise,
					Half = s.Plan.Half,
					Length = s.Plan.Length,
					Stairs = s.Plan.Stairs,
					DoorX = s.Plan.DoorX,
					HasDoor = s.Plan.HasDoor
				};
				plan.Parts.AddRange(list);
				plan.Parts.AddRange(s.Plan.Parts);
				s.Plan = plan;
			}
		}

		private static Site HouseSite(Vector3 villageCenter, Quaternion face, int slot, int length, int beds, float baseHeight, float extra = 0f)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			Site site = new Site();
			site.Yaw = HouseYaws[slot];
			site.Base = baseHeight;
			site.Tag = "L|" + slot + "|" + length + "|" + extra.ToString(CultureInfo.InvariantCulture);
			site.Key = "house" + slot;
			site.Make = (int n) => Longhouse(length, beds, n);
			site.MinStairs = 1;
			Site site2 = site;
			HouseFrame(villageCenter, face, slot, length, out site2.Pos, out site2.Rot, extra);
			Edit(site2, face);
			site2.Plan = Longhouse(length, beds, 1);
			ResolveBase(site2);
			site2.Plan = Longhouse(length, beds, StairsFor(site2, 1f, 1));
			Footings(site2);
			return site2;
		}

		public static bool Overlaps(Site a, Site b, float margin)
		{
			//IL_004e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			float num = a.Plan.Half.y + 2f * (float)a.Plan.Stairs;
			for (float num2 = 0f - a.Plan.Half.x; num2 <= a.Plan.Half.x + 0.01f; num2 += 1f)
			{
				for (float num3 = 0f - a.Plan.Half.y; num3 <= num + 0.01f; num3 += 1f)
				{
					if (b.Contains(a.Pos + a.Rot * new Vector3(num2, 0f, num3), margin))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool OnCommons(Site a, Vector3 villageCenter, Quaternion face)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009c: 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)
			//IL_00a5: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.Inverse(face);
			float num = a.Plan.Half.y + 2f * (float)a.Plan.Stairs;
			for (float num2 = 0f - a.Plan.Half.x; num2 <= a.Plan.Half.x + 0.01f; num2 += 1f)
			{
				for (float num3 = 0f - a.Plan.Half.y; num3 <= num + 0.01f; num3 += 1f)
				{
					Vector3 val2 = val * (a.Pos + a.Rot * new Vector3(num2, 0f, num3) - new Vector3(villageCenter.x, 0f, villageCenter.z));
					if (val2.x * val2.x + val2.z * val2.z < 20.25f)
					{
						return true;
					}
					if (val2.x > -5.5f && val2.x < 5.5f && val2.z > -17.5f && val2.z < -6.5f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool Fits(Site s, List<Site> placed, Vector3 c, Quaternion face)
		{
			//IL_000b: 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 (s.Started)
			{
				return true;
			}
			if (OnCommons(s, c, face))
			{
				return false;
			}
			if (PlayerBuiltOn(s))
			{
				return false;
			}
			foreach (Site item in placed)
			{
				if (item.Plan.Parts.Count > 0 && (Overlaps(s, item, 1.5f) || Overlaps(item, s, 1.5f)))
				{
					return false;
				}
			}
			return true;
		}

		private static Site Demolish(string name, Vector3 pos, Quaternion rot, Vector2 half, int stairs)
		{
			//IL_0006: 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_000d: 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_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)
			return new Site
			{
				Pos = pos,
				Rot = rot,
				Plan = new Plan
				{
					Name = name,
					Raise = 0.3f,
					Half = half,
					Stairs = stairs
				}
			};
		}

		private static bool AnythingBuilt(Site s)
		{
			//IL_0001: 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)
			PieceIndex.Near(s.Pos, ((Vector2)(ref s.Plan.Half)).magnitude + 1f, Hits);
			foreach (Piece hit in Hits)
			{
				if (hit.GetCreator() == 0L && s.Inside(((Component)hit).transform.position, 0f))
				{
					switch (PieceIndex.NameOf(hit))
					{
					case "wood_pole2":
					case "wood_floor":
					case "woodwall":
						return true;
					}
				}
			}
			return false;
		}

		public static bool PlayerBuiltOn(Site s, float margin = 2f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			PieceIndex.Near(s.Pos, ((Vector2)(ref s.Plan.Half)).magnitude + 2f * (float)s.Plan.Stairs + margin + 1f, Theirs);
			foreach (Piece their in Theirs)
			{
				if (their.GetCreator() != 0L && !((Object)(object)((Component)their).GetComponent<VillageTotem>() != (Object)null) && s.Contains(((Component)their).transform.position, margin))
				{
					return true;
				}
			}
			return false;
		}

		public static int PlayerBeds(VillageInfo v)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (Bed item in VillagerPlaces.BedsNear(v.Center, v.Radius))
			{
				Piece val = (((Object)(object)item != (Object)null) ? ((Component)item).GetComponent<Piece>() : null);
				if ((Object)(object)val != (Object)null && val.GetCreator() != 0L && !VillagerPlaces.PlayersOwn(item))
				{
					num++;
				}
			}
			return num;
		}

		public static int BedsWanted(VillageInfo v, int people)
		{
			int num = Mathf.Min(Mathf.Max(people, 1), VillageProgress.MaxVillagers());
			return Mathf.Max(0, num - PlayerBeds(v));
		}

		public static bool PlayerWorkbench(Vector3 villageCenter, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			PieceIndex.Near(villageCenter, radius, Theirs);
			foreach (Piece their in Theirs)
			{
				if (their.GetCreator() != 0L && PieceIndex.NameOf(their) == "piece_workbench")
				{
					return true;
				}
			}
			return false;
		}

		private static bool Stamped(Vector3 villageCenter, string prefix, out string tag)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			tag = null;
			PieceIndex.Near(villageCenter, 34f, Hits);
			foreach (Piece hit in Hits)
			{
				if (hit.GetCreator() != 0L)
				{
					continue;
				}
				ZNetView component = ((Component)hit).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid())
				{
					string text = component.GetZDO().GetString("vd_site", "");
					if (text.StartsWith(prefix))
					{
						tag = text;
						return true;
					}
				}
			}
			return false;
		}

		private static int CornersAt(Vector3 villageCenter, Quaternion face, int slot, int length, float extra = 0f)
		{
			//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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0076: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			HouseFrame(villageCenter, face, slot, length, out var pos, out var rot, extra);
			int num = 0;
			float[] array = new float[2] { -4f, 4f };
			foreach (float num2 in array)
			{
				float[] array2 = new float[2]
				{
					(float)(-length) / 2f,
					(float)length / 2f
				};
				foreach (float num3 in array2)
				{
					Vector3 at = pos + rot * new Vector3(num2, 0f, num3);
					if ((Object)(object)PieceIndex.At("wood_pole2", at, 0.3f, 1000f, villagersOnly: true) != (Object)null)
					{
						num++;
					}
				}
			}
			return num;
		}

		private static bool StorehouseFull(Site s)
		{
			//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)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_007b: 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_0084: 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_0093: 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)
			if (!s.Started)
			{
				return false;
			}
			foreach (Part part in s.Plan.Parts)
			{
				if (part.Use != Use.Chest)
				{
					continue;
				}
				Vector3 val = s.World(part);
				Container val2 = null;
				foreach (Component item in WorldScan.All<Container>(3f))
				{
					Container val3 = (Container)(object)((item is Container) ? item : null);
					if (!((Object)(object)val3 == (Object)null))
					{
						Vector3 val4 = ((Component)val3).transform.position - val;
						if (val4.x * val4.x + val4.z * val4.z < 0.20249999f && Mathf.Abs(val4.y) < 0.4f)
						{
							val2 = val3;
							break;
						}
					}
				}
				if ((Object)(object)val2 == (Object)null || val2.GetInventory().HaveEmptySlot())
				{
					return false;
				}
			}
			return true;
		}

		public static List<Site> Sites(Vector3 villageCenter, float baseHeight, int beds, int stage = 3, bool needStorage = false)
		{
			//IL_001d: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			string key = Mathf.RoundToInt(villageCenter.x) + "|" + Mathf.RoundToInt(villageCenter.z) + "|" + baseHeight.ToString("0.0") + "|" + beds;
			if (!SiteCache.TryGetValue(key, out var value) || Time.time - value.At >= 4f)
			{
				if (SiteCache.Count > 64)
				{
					SiteCache.Clear();
				}
				List<Site> list = AllSites(villageCenter, baseHeight, beds);
				List<Site> collection = list.FindAll((Site x) => x.Plan.Name == "hut" || x.Plan.Name == "longhouse");
				list.RemoveAll((Site x) => x.Plan.Name == "hut" || x.Plan.Name == "longhouse");
				list.InsertRange(0, collection);
				value = new PlanCache
				{
					At = Time.time,
					Sites = list
				};
				SiteCache[key] = value;
			}
			if (stage >= 3)
			{
				return value.Sites;
			}
			List<Site> list2 = new List<Site>(value.Sites);
			list2.RemoveAll((Site s) => !s.Started && ((s.Plan.Name == "workshop" && stage < 1) || (s.Plan.Name == "storehouse" && stage < 2 && !needStorage)));
			return list2;
		}

		public static void ForgetPlans()
		{
			SiteCache.Clear();
			Ranges.Clear();
		}

		private static List<Site> AllSites(Vector3 villageCenter, float baseHeight, int beds)
		{
			//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_0006: 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_0012: 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_0023: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0717: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_0720: Unknown result type (might be due to invalid IL or missing references)
			//IL_0725: Unknown result type (might be due to invalid IL or missing references)
			//IL_072a: Unknown result type (might be due to invalid IL or missing references)
			//IL_072f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0742: Unknown result type (might be due to invalid IL or missing references)
			//IL_0747: Unknown result type (might be due to invalid IL or missing references)
			//IL_0756: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = VillageLayout.Facing(villageCenter);
			_edits = EditsFor(villageCenter);
			Site site = Place(villageCenter, val, new Vector3(9f, 0f, 0f), -90f, baseHeight, WorkshopWith, 0, "workshop");
			List<Site> list = new List<Site>();
			if (site.Started || (!Cancelled("workshop") && !PlayerBuiltOn(site) && !PlayerWorkbench(villageCenter, 30f)))
			{
				list.Add(site);
			}
			List<Site> list2 = new List<Site>();
			int num = beds;
			for (int i = 0; i < HouseDirs.Length; i++)
			{
				int num2 = -1;
				int num3 = 2;
				float extra = 0f;
				if (Stamped(villageCenter, "L|" + i + "|", out var tag))
				{
					string[] array = tag.Split(new char[1] { '|' });
					if (array.Length >= 4 && int.TryParse(array[2], out var result) && float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
					{
						num2 = result;
						extra = result2;
					}
				}
				else
				{
					int[] houseLengths = HouseLengths;
					foreach (int num4 in houseLengths)
					{
						int num5 = CornersAt(villageCenter, val, i, num4);
						if (num5 >= num3)
						{
							num3 = num5;
							num2 = num4;
						}
					}
				}
				if (num2 < 0 && Cancelled("house" + i) && (i != 0 || Cancelled("hut") || num <= 0 || num > 3))
				{
					continue;
				}
				if (i == 0 && num2 < 0 && !Cancelled("hut"))
				{
					Site site2 = null;
					Site site3 = null;
					float result3 = -1f;
					if (Stamped(villageCenter, "H|", out tag))
					{
						float.TryParse(tag.Split(new char[1] { '|' })[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result3);
					}
					float[] pushBack = PushBack;
					for (int j = 0; j < pushBack.Length; j++)
					{
						float num6 = pushBack[j];
						if (!(result3 >= 0f) || num6 == result3)
						{
							Site site4 = new Site
							{
								Yaw = HouseYaws[0],
								Base = baseHeight,
								Plan = HutWith(1),
								Tag = "H|" + num6.ToString(CultureInfo.InvariantCulture),
								Key = "hut",
								Make = HutWith,
								MinStairs = 0
							};
							HouseFrame(villageCenter, val, 0, 6, out site4.Pos, out site4.Rot, num6);
							Edit(site4, val);
							ResolveBase(site4);
							site4.Plan = HutWith(StairsFor(site4, 1f, 0));
							Footings(site4);
							if (site4.Started || result3 >= 0f)
							{
								site2 = site4;
								break;
							}
							if (!OnCommons(site4, villageCenter, val) && !PlayerBuiltOn(site4) && (site3 == null || (!SiteReady(site3) && SiteReady(site4)) || (SiteReady(site4) && Drop(site4) + 0.5f < Drop(site3))))
							{
								site3 = site4;
							}
						}
					}
					if (site2 == null && num > 0 && num <= 3)
					{
						site2 = site3;
					}
					if (site2 != null)
					{
						list.Add(site2);
						num -= Mathf.Min(num, 3);
						continue;
					}
				}
				if (num <= 0)
				{
					if (num2 > 0)
					{
						list.Add(HouseSite(villageCenter, val, i, num2, Capacity(num2), baseHeight, extra));
					}
					continue;
				}
				Site site5 = null;
				int num7;
				if (num2 > 0)
				{
					num7 = Mathf.Min(num, Capacity(num2));
					site5 = HouseSite(villageCenter, val, i, num2, num7, baseHeight, extra);
				}
				else
				{
					num2 = LengthFor(Mathf.Min(num, Capacity(12)));
					num7 = Mathf.Min(num, Capacity(num2));
					Site site6 = null;
					float[] pushBack = PushBack;
					foreach (float extra2 in pushBack)
					{
						Site site7 = HouseSite(villageCenter, val, i, num2, num7, baseHeight, extra2);
						if (!Fits(site7, list, villageCenter, val))
						{
							continue;
						}
						if (SiteReady(site7))
						{
							if (site5 == null || Drop(site7) + 0.5f < Drop(site5))
							{
								site5 = site7;
							}
							if (Drop(site7) <= 1.6f)
							{
								break;
							}
						}
						else if (site6 == null)
						{
							site6 = site7;
						}
					}
					if (site5 == null && site6 != null)
					{
						bool flag = false;
						for (int k = i + 1; k < HouseDirs.Length; k++)
						{
							if (flag)
							{
								break;
							}
							pushBack = PushBack;
							foreach (float extra3 in pushBack)
							{
								Site s = HouseSite(villageCenter, val, k, num2, num7, baseHeight, extra3);
								if (Fits(s, list, villageCenter, val) && SiteReady(s))
								{
									flag = true;
									break;
								}
							}
						}
						if (!flag)
						{
							site5 = site6;
						}
					}
				}
				if (site5 != null && Fits(site5, list, villageCenter, val))
				{
					list.Add(site5);
					num -= num7;
				}
			}
			List<Site> list3 = new List<Site>();
			for (int l = 0; l < StoreSpots.Length; l++)
			{
				list3.Add(Place(villageCenter, val, StoreSpots[l], StoreYaws[l], baseHeight, StorehouseWith, 0, "store" + l));
			}
			List<Site> list4 = new List<Site>();
			foreach (Site item in list3)
			{
				if (item.Started)
				{
					list4.Add(item);
				}
			}
			list3.RemoveAll((Site site10) => !site10.Started && Cancelled(site10.Key));
			if (list4.Count == 0 || list4.TrueForAll(StorehouseFull))
			{
				Site site8 = null;
				foreach (Site o in list3)
				{
					if (!o.Started && Fits(o, list, villageCenter, val) && !list4.Exists((Site x) => Overlaps(o, x, 1.5f)))
					{
						if (SiteReady(o))
						{
							site8 = o;
							break;
						}
						if (site8 == null)
						{
							site8 = o;
						}
					}
				}
				if (site8 != null)
				{
					list4.Add(site8);
				}
			}
			list.AddRange(list4);
			if (list4.Count > 0)
			{
				_ = list4[0];
			}
			for (int num8 = 0; num8 < OldStoreSpots.Length; num8++)
			{
				Site site9 = Demolish("old storehouse", villageCenter + val * OldStoreSpots[num8], val * Quaternion.Euler(0f, OldStoreYaws[num8], 0f), new Vector2(3.2f, 3.2f), 1);
				site9.Pos.y = 0f;
				bool flag2 = false;
				foreach (Site item2 in list)
				{
					if (item2.Contains(site9.Pos, 1f))
					{
						flag2 = true;
					}
				}
				if (!flag2 && AnythingBuilt(site9))
				{
					list2.Add(site9);
				}
			}
			list.AddRange(list2);
			return list;
		}

		public static string EditKey(string villageId)
		{
			return "vplan." + villageId;
		}

		public static Dictionary<string, PlanEdit> ParseEdits(string spec)
		{
			Dictionary<string, PlanEdit> dictionary = new Dictionary<string, PlanEdit>();
			if (string.IsNullOrEmpty(spec))
			{
				return dictionary;
			}
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			string[] array = spec.Split(new char[1] { '|' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				if (array2.Length >= 5)
				{
					PlanEdit planEdit = new PlanEdit
					{
						Cancel = (array2[1] == "1")
					};
					float.TryParse(array2[2], NumberStyles.Float, invariantCulture, out planEdit.Dx);
					float.TryParse(array2[3], NumberStyles.Float, invariantCulture, out planEdit.Dz);
					float.TryParse(array2[4], NumberStyles.Float, invariantCulture, out planEdit.Rot);
					dictionary[array2[0]] = planEdit;
				}
			}
			return dictionary;
		}

		public static string EncodeEdits(Dictionary<string, PlanEdit> d)
		{
			CultureInfo invariantCulture = CultureInfo.InvariantCulture;
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, PlanEdit> item in d)
			{
				PlanEdit value = item.Value;
				if (value.Cancel || value.Dx != 0f || value.Dz != 0f || value.Rot != 0f)
				{
					list.Add(item.Key + ":" + (value.Cancel ? "1" : "0") + ":" + value.Dx.ToString("0.#", invariantCulture) + ":" + value.Dz.ToString("0.#", invariantCulture) + ":" + value.Rot.ToString("0", invariantCulture));
				}
			}
			return string.Join("|", list.ToArray());
		}

		private static Dictionary<string, PlanEdit> EditsFor(Vector3 villageCenter)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			VillageInfo villageInfo = VillageInfo.At(villageCenter);
			if (villageInfo == null)
			{
				return new Dictionary<string, PlanEdit>();
			}
			return ParseEdits(ModData.Get(EditKey(villageInfo.Id)));
		}

		private static bool Cancelled(string key)
		{
			if (key != null && _edits.TryGetValue(key, out var value))
			{
				return value.Cancel;
			}
			return false;
		}

		private static void Edit(Site s, Quaternion face)
		{
			//IL_0046: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (s.Key != null && _edits.TryGetValue(s.Key, out var value) && (value.Dx != 0f || value.Dz != 0f || value.Rot != 0f))
			{
				s.Pos += face * new Vector3(value.Dx, 0f, value.Dz);
				s.Rot *= Quaternion.Euler(0f, value.Rot, 0f);
				s.Yaw += value.Rot;
				if (s.Tag != null)
				{
					s.Tag = s.Tag + "|" + value.Dx.ToString("0.#", CultureInfo.InvariantCulture) + "|" + value.Dz.ToString("0.#", CultureInfo.InvariantCulture) + "|" + value.Rot.ToString("0", CultureInfo.InvariantCulture);
				}
			}
		}

		public static List<string> CancelledKeys(VillageInfo v)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, PlanEdit> item in ParseEdits(ModData.Get(EditKey(v.Id))))
			{
				if (item.Value.Cancel)
				{
					list.Add(item.Key);
				}
			}
			return list;
		}

		public static string DebugHouses(Vector3 villageCenter, float baseHeight, int beds)
		{
			//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_0006: 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_0018: 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_0029: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			Quaternion face = VillageLayout.Facing(villageCenter);
			_edits = EditsFor(villageCenter);
			List<Site> list = new List<Site> { Place(villageCenter, face, new Vector3(9f, 0f, 0f), -90f, baseHeight, WorkshopWith, 0, "workshop") };
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < HouseDirs.Length; i++)
			{
				int length = LengthFor(Mathf.Min(beds, Capacity(12)));
				float[] pushBack = PushBack;
				foreach (float num in pushBack)
				{
					Site site = HouseSite(villageCenter, face, i, length, Mathf.Min(beds, Capacity(length)), baseHeight, num);
					bool flag = OnCommons(site, villageCenter, face);
					bool flag2 = false;
					foreach (Site item in list)
					{
						if (Overlaps(site, item, 1.5f) || Overlaps(item, site, 1.5f))
						{
							flag2 = true;
						}
					}
					stringBuilder.Append($" slot{i}+{num}: stairs {site.Plan.Stairs} commons {flag} clash {flag2};");
				}
			}
			return stringBuilder.ToString();
		}

		private static void GroundRange(Site s, out float lo, out float hi)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			long key = ((long)Mathf.RoundToInt(s.Pos.x * 4f) << 40) ^ ((long)Mathf.RoundToInt(s.Pos.z * 4f) << 16) ^ Mathf.RoundToInt(((Quaternion)(ref s.Rot)).eulerAngles.y) ^ ((long)(s.Plan.Half.x * 8f) << 9) ^ ((long)(s.Plan.Half.y * 8f) << 3);
			if (Ranges.TryGetValue(key, out var value) && Time.time - value.At < 8f)
			{
				lo = value.Lo;
				hi = value.Hi;
				return;
			}
			GroundRangeNow(s, out lo, out hi);
			if (Ranges.Count > 512)
			{
				Ranges.Clear();
			}
			Ranges[key] = new Range
			{
				Lo = lo,
				Hi = hi,
				At = Time.time
			};
		}

		private static void GroundRangeNow(Site s, out float lo, out float hi)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			lo = float.MaxValue;
			hi = float.MinValue;
			for (int i = 0; i < 25; i++)
			{
				float num = (float)(i % 5 - 2) / 2f * (s.Plan.Half.x - 0.3f);
				float num2 = (float)(i / 5 - 2) / 2f * (Mathf.Min(s.Plan.Half.y, 4f) - 0.3f);
				float groundHeight = ZoneSystem.instance.GetGroundHeight(s.Pos + s.Rot * new Vector3(num, 0f, num2));
				lo = Mathf.Min(lo, groundHeight);
				hi = Mathf.Max(hi, groundHeight);
			}
		}

		public static void ResolveBase(Site s)
		{
			//IL_0003: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			PieceIndex.Near(s.Pos, ((Vector2)(ref s.Plan.Half)).magnitude + 1f, Hits);
			foreach (Piece hit in Hits)
			{
				if (hit.GetCreator() == 0L && s.Inside(((Component)hit).transform.position, 0.5f))
				{
					num++;
				}
			}
			if (num == 0)
			{
				GroundRange(s, out var _, out var hi);
				s.Base = hi;
				return;
			}
			foreach (Part part in s.Plan.Parts)
			{
				if (part.Use != Use.Structure)
				{
					continue;
				}
				Vector3 val = s.Pos + s.Rot * new Vector3(part.Local.x, 0f, part.Local.z);
				float groundHeight = ZoneSystem.instance.GetGroundHeight(val);
				PieceIndex.Near(val, 0.3f, Hits);
				foreach (Piece hit2 in Hits)
				{
					if (hit2.GetCreator() == 0L && !(PieceIndex.NameOf(hit2) != part.Prefab) && !(Mathf.Abs(((Component)hit2).transform.position.y - (groundHeight + s.Plan.Raise + part.Local.y)) > 3f))
					{
						s.Base = ((Component)hit2).transform.position.y - s.Plan.Raise - part.Local.y;
						s.Started = true;
						GroundRange(s, out var _, out var hi2);
						if (num <= 3 && Mathf.Abs(s.Base - hi2) > 1.5f)
						{
							s.Base = hi2;
							s.Started = false;
						}
						return;
					}
				}
			}
			GroundRange(s, out var _, out var hi3);
			s.Base = hi3;
		}

		public static bool SiteReady(Site s)
		{
			//IL_0052: 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)
			if (s.Started)
			{
				return true;
			}
			GroundRange(s, out var lo, out var hi);
			if (hi - lo > 4f)
			{
				return false;
			}
			float num = hi + s.Plan.Raise;
			float y = s.Plan.Half.y;
			if (s.Ground(s.Plan.DoorX, y + 0.8f).y >= num - 0.2f)
			{
				return true;
			}
			for (int i = 1; i <= 6; i++)
			{
				if (s.Ground(s.Plan.DoorX, y + 2f * (float)i).y >= num - (float)i - 0.1f)
				{
					return true;
				}
			}
			return false;
		}

		public static List<Site> Doors(VillageInfo v)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			if (!Towns.TryGetValue(v.Id, out var value))
			{
				value = new TownCache
				{
					At = -100f
				};
				Towns[v.Id] = value;
			}
			if (Time.time - value.At < 6f)
			{
				return value.Sites;
			}
			value.At = Time.time;
			value.Sites.Clear();
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return value.Sites;
			}
			int stage = 3;
			float h;
			int beds;
			if (CampTown.IsCamp(v))
			{
				h = CampTown.Height(v);
				beds = CampTown.Beds(v);
				CampInfo campInfo = CampTown.Camp(v);
				if (campInfo != null)
				{
					stage = campInfo.Stage;
				}
			}
			else
			{
				if (!VillageGround.Target(v, out h))
				{
					return value.Sites;
				}
				beds = BedsWanted(v, Wanderer.VillagersIn(v));
			}
			foreach (Site item in Sites(v.Center, h, beds, stage))
			{
				if (!item.Plan.HasDoor || !item.Started)
				{
					continue;
				}
				foreach (Part part in item.Plan.Parts)
				{
					if (part.Prefab == "wood_stair")
					{
						item.Walkable = VillageLayout.Built(part.Prefab, item.World(part));
						break;
					}
				}
				if (item.Plan.Stairs == 0)
				{
					item.Walkable = true;
				}
				if (item.Walkable)
				{
					value.Sites.Add(item);
				}
			}
			return value.Sites;
		}

		public static bool Route(Vector3 me, Vector3 goal, out Vector3 via)
		{
			//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_0011: 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)
			//IL_0025: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: 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)
			via = goal;
			VillageInfo villageInfo = VillageInfo.At(goal) ?? VillageInfo.At(me) ?? CampTown.At(goal) ?? CampTown.At(me);
			if (villageInfo == null)
			{
				return false;
			}
			foreach (Site item in Doors(villageInfo))
			{
				float floor = item.Floor;
				bool flag = item.Inside(goal, -0.3f) && goal.y > floor - 0.8f;
				bool flag2 = item.Inside(me, 0.1f) && me.y > floor - 0.6f;
				if (flag != flag2)
				{
					Vector3 val = item.Local(me);
					float doorX = item.Plan.DoorX;
					float y = item.Plan.Half.y;
					float num = 2f * (float)item.Plan.Stairs;
					bool flag3 = Mathf.Abs(val.x - doorX) < 1.6f && val.z > y - 2.3f && val.z < y + num + 2.5f;
					Vector3 val2 = item.Pos + item.Rot * new Vector3(doorX, 0f, y - 1.1f);
					val2.y = floor;
					Vector3 val3 = item.Pos + item.Rot * new Vector3(doorX, 0f, y + num + 1f);
					val3.y = ZoneSystem.instance.GetGroundHeight(val3);
					if (flag)
					{
						via = (flag3 ? val2 : val3);
					}
					else
					{
						via = (flag3 ? val3 : val2);
					}
					return true;
				}
			}
			return false;
		}
	}
	internal static class Landmarks
	{
		private static readonly MethodInfo ListMethod = AccessTools.Method(typeof(ZoneSystem), "GetLocationList", (Type[])null, (Type[])null);

		private static readonly FieldInfo ListField = AccessTools.Field(typeof(ZoneSystem), "m_locationInstances");

		public static bool Near(Vector3 p, float clearance, out string name, float startTempleClearance = 0f)
		{
			//IL_009a: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			name = null;
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			IEnumerable enumerable = null;
			try
			{
				enumerable = ((ListMethod != null) ? (ListMethod.Invoke(instance, null) as IEnumerable) : null);
			}
			catch
			{
			}
			if (enumerable == null && ListField != null && ListField.GetValue(instance) is IDictionary dictionary)
			{
				enumerable = dictionary.Values;
			}
			if (enumerable == null)
			{
				return false;
			}
			foreach (object item in enumerable)
			{
				if (item == null)
				{
					continue;
				}
				Traverse obj2 = Traverse.Create(item);
				Vector3 value = obj2.Field("m_position").GetValue<Vector3>();
				object value2 = obj2.Field("m_location").GetValue();
				if (value2 != null)
				{
					Traverse obj3 = Traverse.Create(value2);
					string text = obj3.Field("m_prefabName").GetValue<string>() ?? "";
					float num = Mathf.Min(obj3.Field("m_exteriorRadius").GetValue<float>(), 32f);
					float num2 = clearance + num;
					if (text == "StartTemple")
					{
						num2 = Mathf.Max(num2, startTempleClearance);
					}
					Vector3 val = value - p;
					val.y = 0f;
					if (((Vector3)(ref val)).sqrMagnitude < num2 * num2)
					{
						name = Pretty(text);
						return true;
					}
				}
			}
			return false;
		}

		public static bool OnTop(Vector3 p, out string name)
		{
			//IL_009a: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			name = null;
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			IEnumerable enumerable = null;
			try
			{
				enumerable = ((ListMethod != null) ? (ListMethod.Invoke(instance, null) as IEnumerable) : null);
			}
			catch
			{
			}
			if (enumerable == null && ListField != null && ListField.GetValue(instance) is IDictionary dictionary)
			{
				enumerable = dictionary.Values;
			}
			if (enumerable == null)
			{
				return false;
			}
			foreach (object item in enumerable)
			{
				if (item == null)
				{
					continue;
				}
				Traverse obj2 = Traverse.Create(item);
				Vector3 value = obj2.Field("m_position").GetValue<Vector3>();
				object value2 = obj2.Field("m_location").GetValue();
				if (value2 != null)
				{
					Traverse val = Traverse.Create(value2);
					string text = val.Field("m_prefabName").GetValue<string>() ?? "";
					float num = ((text == "StartTemple") ? 30f : Mathf.Min(val.Field("m_exteriorRadius").GetValue<float>(), 12f));
					Vector3 val2 = value - p;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < num * num)
					{
						name = Pretty(text) + $" ({((Vector3)(ref val2)).magnitude:0} m away)";
						return true;
					}
				}
			}
			return false;
		}

		public static string Pretty(string prefab)
		{
			if (prefab == "StartTemple")
			{
				return "the sacrificial stones";
			}
			if (prefab.StartsWith("Runestone"))
			{
				return "a runestone";
			}
			if (prefab.StartsWith("Vendor") || prefab.Contains("Haldor"))
			{
				return "the trader";
			}
			if (prefab.Contains("Eikthyrnir") || prefab.Contains("GDKing") || prefab.Contains("Bonemass") || prefab.Contains("Dragonqueen") || prefab.Contains("GoblinKing"))
			{
				return "a boss altar";
			}
			if (prefab.Contains("Crypt") || prefab.Contains("Cave") || prefab.Contains("Burial"))
			{
				return "a dungeon";
			}
			return "a landmark (" + prefab.TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') + ")";
		}
	}
	internal static class TownCatchUp
	{
		private sealed class Town
		{
			public VillageInfo V;

			public int Stage;

			public bool Camp;
		}

		private sealed class Work
		{
			public int Budget;

			public float Hours;

			public int Cleared;

			public int Levelled;

			public int Built;

			public bool Settle;
		}

		private const string KWorked = "vd_worked";

		private const float PiecesPerWorkerHour = 3f;

		private const float MaxHours = 48f;

		private static float _next;

		private static readonly Dictionary<string, Work> Pending = new Dictionary<string, Work>();

		private const int ClearPerStep = 8;

		private const int LevelPerStep = 3;

		private const int BuildPerStep = 12;

		private static readonly Dictionary<string, string> LastNote = new Dictionary<string, string>();

		public static void Tick()
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null || Time.time < _next)
			{
				return;
			}
			_next = Time.time + ((Pending.Count > 0) ? 1.5f : 5f);
			List<Town> list = new List<Town>();
			foreach (VillageInfo item in VillageInfo.All())
			{
				list.Add(new Town
				{
					V = item,
					Stage = 3
				});
			}
			foreach (CampInfo item2 in CampInfo.All())
			{
				if (!item2.Hostile && !CampWar.Ruined(item2))
				{
					list.Add(new Town
					{
						V = CampTown.Of(item2),
						Stage = item2.Stage,
						Camp = true
					});
				}
			}
			foreach (Town t in list)
			{
				if (ZoneSystem.instance.IsZoneLoaded(t.V.Center))
				{
					Safe.Run("TownCatchUp", delegate
					{
						CatchUp(t);
					});
				}
			}
		}

		private static ZNetView Clock(VillageInfo v)
		{
			//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)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			VillageTotem villageTotem = null;
			float num = 100f;
			foreach (Component item in WorldScan.All<VillageTotem>(3f))
			{
				VillageTotem villageTotem2 = item as VillageTotem;
				if (!((Object)(object)villageTotem2 == (Object)null))
				{
					Vector3 val = ((Component)villageTotem2).transform.position - v.Center;
					val.y = 0f;
					if (((Vector3)(ref val)).sqrMagnitude < num)
					{
						num = ((Vector3)(ref val)).sqrMagnitude;
						villageTotem = villageTotem2;
					}
				}
			}
			if ((Object)(object)villageTotem != (Object)null)
			{
				ZNetView component = ((Component)villageTotem).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					return component;
				}
			}
			Fireplace val2 = Anchor(v);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return ((Component)val2).GetComponent<ZNetView>();
		}

		private static Fireplace Anchor(VillageInfo v)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			Fireplace result = null;
			float num = 196f;
			foreach (Component item in WorldScan.All<Fireplace>(3f))
			{
				Fireplace val = (Fireplace)(object)((item is Fireplace) ? item : null);
				if (!((Object)(object)val == (Object)null) && !val.m_infiniteFuel)
				{
					Vector3 val2 = ((Component)val).transform.position - v.Center;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < num)
					{
						num = ((Vector3)(ref val2)).sqrMagnitude;
						result = val;
					}
				}
			}
			return result;
		}

		private static List<VillagerCharacter> People(Town t)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			List<VillagerCharacter> list = new List<VillagerCharacter>();
			string text = (t.Camp ? t.V.Id.Substring("camp:".Length) : null);
			foreach (VillagerCharacter item in VillagerCharacter.All)
			{
				if ((Object)(object)item == (Object)null || ((Character)item).IsDead() || item.IsWanderer)
				{
					continue;
				}
				bool num;
				if (!t.Camp)
				{
					if (!string.IsNullOrEmpty(item.CampId))
					{
						continue;
					}
					num = t.V.Contains(item.Home);
				}
				else
				{
					num = item.CampId == text;
				}
				if (num)
				{
					list.Add(item);
				}
			}
			return list;
		}

		private static void CatchUp(Town t)
		{
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0694: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0754: Unknown result type (might be due to invalid IL or missing references)
			//IL_076e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0786: Unknown result type (might be due to invalid IL or missing references)
			//IL_0794: Unknown result type (might be due to invalid IL or missing references)
			//IL_079a: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = Clock(t.V);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				Note(t, "no totem or fire to keep the clock on yet");
				return;
			}
			if (!val.IsOwner())
			{
				Note(t, "another player is running this town");
				return;
			}
			ZDO zDO = val.GetZDO();
			double netTime = GameApi.NetTime;
			double num = zDO.GetFloat("vd_worked", -1f);
			if (num < 0.0)
			{
				zDO.Set("vd_worked", (float)netTime);
				Note(t, "clock started");
				return;
			}
			List<VillagerCharacter> list = People(t);
			if (list.Count == 0)
			{
				Note(t, "nobody home yet");
				return;
			}
			VillagerCharacter v = list[0];
			float value = VillagersConfig.HomeRadius.Value;
			if (!Pending.TryGetValue(t.V.Id, out var value2))
			{
				double num2 = netTime - num;
				if (num2 >= 150.0)
				{
					Note(t, $"away {num2:0} s with {list.Count} people");
				}
				if (num2 < 150.0)
				{
					if (num2 > 30.0)
					{
						zDO.Set("vd_worked", (float)netTime);
					}
					return;
				}
				zDO.Set("vd_worked", (float)netTime);
				float num3 = Mathf.Min((float)(num2 / (GameApi.DayLengthSeconds / 24.0)), 48f);
				value2 = new Work
				{
					Hours = num3,
					Budget = Mathf.Min(Mathf.RoundToInt((float)list.Count * num3 * 3f), 400)
				};
				if (!t.Camp)
				{
					int num4 = 0;
					int num5 = 0;
					foreach (VillagerCharacter item in list)
					{
						if (item.Job == VillagerJob.Woodcutter)
						{
							num4 += Mathf.RoundToInt(num3 * 4f);
						}
						else if (item.Job == VillagerJob.Miner)
						{
							num5 += Mathf.RoundToInt(num3 * 2f);
						}
						else if (item.Job == VillagerJob.Gatherer)
						{
							num4 += Mathf.RoundToInt(num3 * 2f);
							num5 += Mathf.RoundToInt(num3 * 1f);
						}
					}
					Stock(t.V, "Wood", Mathf.Min(num4, 200));
					Stock(t.V, "Stone", Mathf.Min(num5, 120));
				}
				if (!t.Camp && !VillageInfo.VillagersBuild(t.V))
				{
					return;
				}
				Pending[t.V.Id] = value2;
			}
			else
			{
				zDO.Set("vd_worked", (float)netTime);
			}
			if (!t.Camp && !VillageInfo.VillagersBuild(t.V))
			{
				Finish(t, value2);
				return;
			}
			float h;
			int num6;
			if (t.Camp)
			{
				h = CampTown.Height(t.V);
				num6 = CampTown.Beds(t.V);
			}
			else
			{
				if (!VillageGround.Target(t.V, out h))
				{
					Finish(t, value2);
					return;
				}
				num6 = Blueprints.BedsWanted(t.V, Wanderer.VillagersIn(t.V));
			}
			List<Container> list2 = Village.Chests(t.V.Center, value);
			bool needStorage = list2.Count >= 2 || (list2.Count > 0 && (Object)(object)Village.ChestWithRoom(t.V.Center, value, t.V.Center) == (Object)null);
			List<Blueprints.Site> list3 = Blueprints.Sites(t.V.Center, h, num6, t.Stage, needStorage);
			VillageGround.SetPads(t.V, list3);
			int num7 = 0;
			int num8 = 0;
			int num9 = 0;
			foreach (Blueprints.Site item2 in list3)
			{
				if (item2.Plan.Parts.Count == 0)
				{
					continue;
				}
				foreach (GameObject item3 in new List<GameObject>(TownClearing.OnSite(t.V, item2, 1.5f)))
				{
					if (value2.Budget <= 0 || num7 >= 8)
					{
						break;
					}
					if ((Object)(object)item3 == (Object)null)
					{
						continue;
					}
					if ((Object)(object)item3.GetComponent<TreeBase>() != (Object)null || (Object)(object)item3.GetComponent<TreeLog>() != (Object)null)
					{
						TownClearing.RemoveCleanly(item3);
					}
					else
					{
						ZNetView component = item3.GetComponent<ZNetView>();
						if ((Object)(object)component == (Object)null || !component.IsValid())
						{
							continue;
						}
						if (!component.IsOwner())
						{
							component.ClaimOwnership();
						}
						ZNetScene.instance.Destroy(item3);
					}
					value2.Budget--;
					num7++;
				}
			}
			if (num7 == 0)
			{
				foreach (Vector3 item4 in VillageGround.Cells(t.V))
				{
					if (value2.Budget <= 0 || num8 >= 3)
					{
						break;
					}
					if (VillageGround.IsPad(t.V, item4))
					{
						float h2 = VillageGround.TargetAt(t.V, item4, h);
						if (VillageGround.Check(item4, h2) == VillageGround.CellState.Todo)
						{
							VillageGround.Level(t.V, item4, h2);
							value2.Budget--;
							num8++;
						}
					}
				}
			}
			value2.Cleared += num7;
			value2.Levelled += num8;
			if (num7 > 0 || num8 > 0)
			{
				value2.Settle = true;
				FinishIfSpent(t, value2);
				return;
			}
			if (value2.Settle)
			{
				value2.Settle = false;
				Blueprints.ForgetPlans();
				return;
			}
			int num10 = 0;
			foreach (Blueprints.Site item5 in list3)
			{
				if (value2.Budget <= 0 || num9 >= 12)
				{
					break;
				}
				if (item5.Plan.Parts.Count == 0 || !Blueprints.SiteReady(item5) || !TownClearing.SiteClear(t.V, item5))
				{
					continue;
				}
				foreach (Blueprints.Part part in item5.Plan.Parts)
				{
					if (value2.Budget <= 0 || num9 >= 12)
					{
						break;
					}
					if ((part.Use == Blueprints.Use.Bed && num10++ >= num6) || part.MinStage > t.Stage || part.Use == Blueprints.Use.Chest)
					{
						continue;
					}
					Vector3 val2 = item5.World(part);
					if (VillageLayout.Built(part.Prefab, val2))
					{
						continue;
					}
					bool flag = false;
					string[] alt = part.Alt;
					for (int i = 0; i < alt.Length; i++)
					{
						if (VillageLayout.Built(alt[i], val2))
						{
							flag = true;
						}
					}
					if (flag)
					{
						continue;
					}
					GameObject prefab = ZNetScene.instance.GetPrefab(part.Prefab);
					Piece val3 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null);
					if ((Object)(object)val3 == (Object)null)
					{
						continue;
					}
					if (!t.Camp && !VillageProgress.Knows(t.V, val3.m_name))
					{
						if (part.Use == Blueprints.Use.Structure)
						{
							break;
						}
					}
					else if (!Village.CanAfford(v, val3.m_resources, t.V.Center, value))
					{
						if (part.Use != Blueprints.Use.Furniture)
						{
							break;
						}
					}
					else if (!SomeoneThere(val2))
					{
						Village.Pay(v, val3.m_resources, t.V.Center, value);
						Place(prefab, val2, item5.WorldRot(part), item5.Tag);
						value2.Budget--;
						num9++;
					}
				}
			}
			value2.Built += num9;
			if (num9 < 12 || value2.Budget <= 0)
			{
				Finish(t, value2);
			}
		}

		private static void FinishIfSpent(Town t, Work w)
		{
			if (w.Budget <= 0)
			{
				Finish(t, w);
			}
		}

		private static void Finish(Town t, Work w)
		{
			Pending.Remove(t.V.Id);
			if (w.Cleared + w.Levelled + w.Built > 0)
			{
				DynastyPlugin.Log.LogInfo((object)$"{t.V.Name}: caught up on {w.Hours:0} hours away: cleared {w.Cleared}, levelled {w.Levelled}, built {w.Built} piece(s).");
			}
		}

		private static void Note(Town t, string what)
		{
			if (DynastyPlugin.VerboseOn && (!LastNote.TryGetValue(t.V.Id, out var value) || !(value == what)))
			{
				LastNote[t.V.Id] = what;
				DynastyPlugin.Log.LogInfo((object)(t.V.Name + ": catch-up: " + what + "."));
			}
		}

		private static bool SomeoneThere(Vector3 w)
		{
			//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_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_0038: 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_0045: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsDead())
				{
					Vector3 val = ((Component)allCharacter).transform.position - w;
					if (val.x * val.x + val.z * val.z < 3.61f && Mathf.Abs(val.y) < 3f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void Place(GameObject prefab, Vector3 at, Quaternion rot, string tag)
		{
			//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)
			GameObject obj = Object.Instantiate<GameObject>(prefab, at, rot);
			ZNetView component = obj.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				component.GetZDO().Set("vdyn_built", true);
				if (!string.IsNullOrEmpty(tag))
				{
					component.GetZDO().Set("vd_site", tag);
				}
			}
			WorldScan.Add((Component)(object)obj.GetComponent<Container>());
			WorldScan.Add((Component)(object)obj.GetComponent<Fireplace>());
			WorldScan.Add((Component)(object)obj.GetComponent<Bed>());
			WorldScan.Invalidate<Piece>();
			VillagerPlaces.Invalidate();
		}

		private static void Stock(VillageInfo v, string prefabName, int n)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (n <= 0)
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefabName) : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Container item in Village.Chests(v.Center, VillagersConfig.HomeRadius.Value))
			{
				if (n <= 0)
				{
					break;
				}
				ZNetView component = ((Component)item).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid() || item.IsInUse())
				{
					continue;
				}
				component.ClaimOwnership();
				Inventory inventory = item.GetInventory();
				int num = Mathf.Max(1, val.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize);
				while (n > 0 && inventory.CanAddItem(val, 1))
				{
					int num2 = Mathf.Min(n, num);
					int num3 = inventory.CountItems(val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, -1, true);
					if (!inventory.AddItem(val, num2))
					{
						break;
					}
					int num4 = inventory.CountItems(val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, -1, true) - num3;
					if (num4 <= 0)
					{
						break;
					}
					n -= num4;
				}
			}
		}
	}
	internal static class TownClearing
	{
		private sealed class Cache
		{
			public float At;

			public List<GameObject> Things = new List<GameObject>();
		}

		private static readonly Dictionary<string, Cache> ByVillage = new Dictionary<string, Cache>();

		public static bool IsObstruction(Component c)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			if ((Object)(object)c == (Object)null)
			{
				return false;
			}
			GameObject gameObject = c.gameObject;
			ZNetView component = gameObject.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			if ((Object)(object)gameObject.GetComponentInParent<Piece>() != (Object)null || (Object)(object)gameObject.GetComponent<Plant>() != (Object)null || (Object)(object)gameObject.GetComponentInParent<Character>() != (Object)null || (Object)(object)gameObject.GetComponent<Container>() != (Object)null || (Object)(object)gameObject.GetComponentInParent<Location>() != (Object)null)
			{
				return false;
			}
			Destructible val = (Destructible)(object)((c is Destructible) ? c : null);
			if ((Object)(object)val != (Object)null)
			{
				if ((int)val.m_destructibleType == 4)
				{
					return false;
				}
				if ((Object)(object)gameObject.GetComponent<Pickable>() != (Object)null && Utils.GetPrefabName(gameObject).StartsWith("Pickable_"))
				{
					return false;
				}
			}
			return true;
		}

		public static List<GameObject> In(VillageInfo v)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			if (!ByVillage.TryGetValue(v.Id, out var value))
			{
				value = new Cache
				{
					At = -100f
				};
				ByVillage[v.Id] = value;
			}
			if (Time.time - value.At < 4f)
			{
				value.Things.RemoveAll((GameObject g) => (Object)(object)g == (Object)null);
				return value.Things;
			}
			value.At = Time.time;
			value.Things.Clear();
			float r = v.Radius + 2f;
			Add(value.Things, WorldScan.All<TreeBase>(8f), v.Center, r);
			Add(value.Things, WorldScan.All<TreeLog>(4f), v.Center, r);
			Add(value.Things, WorldScan.All<Destructible>(8f), v.Center, r);
			Add(value.Things, WorldScan.All<MineRock>(10f), v.Center, r);
			Add(value.Things, WorldScan.All<MineRock5>(10f), v.Center, r);
			return value.Things;
		}

		private static void Add(List<GameObject> into, List<Component> from, Vector3 center, float r)
		{
			//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)
			//I