Decompiled source of ValheimCityBuilder v1.0.4

plugins/ValheimCityBuilder.dll

Decompiled 21 hours 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.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.PostProcessing;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 ValheimAnno
{
	public static class Ages
	{
		public class Result
		{
			public Blueprint Plan;

			public int Native;

			public int Swapped;

			public int Dropped;
		}

		public static readonly string[] Keys;

		public static readonly string[] Roman;

		public static readonly string[] Lands;

		public const int Max = 6;

		private static int cur;

		private static float curT;

		public static int Override;

		private static readonly Dictionary<string, int> ItemAge;

		private static readonly Dictionary<string, int> StationAge;

		private static readonly Dictionary<string, int> pieceAge;

		public static readonly HashSet<string> UnknownItems;

		private static List<string> buildable;

		private static readonly Dictionary<long, string> subs;

		private static readonly Dictionary<Blueprint, Dictionary<int, Result>> cache;

		public static int Current
		{
			get
			{
				if (Override >= 0)
				{
					return Mathf.Min(Override, 6);
				}
				if (cur >= 0 && Time.time < curT)
				{
					return cur;
				}
				int result = 0;
				for (int i = 1; i < Keys.Length; i++)
				{
					if (Defs.GlobalKey(Keys[i]))
					{
						result = i;
					}
				}
				cur = result;
				curT = Time.time + 2f;
				return result;
			}
		}

		public static int ForBuilding(BDef d)
		{
			if (d == null)
			{
				return Current;
			}
			return Mathf.Clamp(Mathf.Max(Current, d.Tier), 0, 6);
		}

		public static string Name(int a)
		{
			a = Mathf.Clamp(a, 0, 6);
			return "Age " + Roman[a] + " – " + Lands[a];
		}

		private static void Items(int age, params string[] items)
		{
			foreach (string key in items)
			{
				ItemAge[key] = age;
			}
		}

		static Ages()
		{
			Keys = new string[7] { null, "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen" };
			Roman = new string[7] { "I", "II", "III", "IV", "V", "VI", "VII" };
			Lands = new string[7] { "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Mistlands", "Ashlands" };
			cur = -1;
			Override = -1;
			ItemAge = new Dictionary<string, int>();
			StationAge = new Dictionary<string, int>
			{
				{ "piece_workbench", 0 },
				{ "forge", 1 },
				{ "piece_stonecutter", 2 },
				{ "piece_cauldron", 1 },
				{ "piece_artisanstation", 4 },
				{ "blackforge", 5 },
				{ "piece_magetable", 5 },
				{ "piece_preptable", 4 }
			};
			pieceAge = new Dictionary<string, int>();
			UnknownItems = new HashSet<string>();
			subs = new Dictionary<long, string>();
			cache = new Dictionary<Blueprint, Dictionary<int, Result>>();
			Items(0, "Wood", "Stone", "Flint", "Resin", "LeatherScraps", "DeerHide", "Feathers", "Raspberry", "Mushroom", "Dandelion", "Honey", "Coins", "QueenBee", "HardAntler", "TrophyDeer", "TrophyBoar", "TrophyNeck", "NeckTail", "RawMeat", "DeerMeat");
			Items(1, "FineWood", "RoundLog", "Copper", "CopperOre", "Tin", "TinOre", "Bronze", "BronzeNails", "TrollHide", "GreydwarfEye", "SurtlingCore", "Coal", "Thistle", "Blueberries", "BoneFragments", "Carrot", "AncientSeed", "Amber", "AmberPearl", "Ruby", "TrophyEikthyr", "TrophyGreydwarf", "TrophyFrostTroll", "TrophySkeleton", "Bronze", "BeltStrength");
			Items(2, "Iron", "IronNails", "IronScrap", "ElderBark", "Chain", "Guck", "Bloodbag", "Entrails", "Ooze", "Turnip", "WitheredBone", "TrophyTheElder", "TrophyDraugr", "CryptKey", "Thunderstone");
			Items(3, "Silver", "SilverOre", "Obsidian", "WolfPelt", "WolfFang", "WolfClaw", "Crystal", "FreezeGland", "DragonEgg", "Onion", "JuteRed", "TrophyBonemass", "TrophyWolf", "TrophyHatchling");
			Items(4, "BlackMetal", "BlackMetalScrap", "LinenThread", "Flax", "Barley", "Needle", "LoxPelt", "Tar", "GoblinTotem", "DragonTear", "TrophyDragonQueen", "TrophyGoblin", "TrophyLox");
			Items(5, "BlackMarble", "YggdrasilWood", "Eitr", "Sap", "Carapace", "Mandible", "JuteBlue", "Wisp", "BlackCore", "DvergrNeedle", "Softtissue", "ScaleHide", "Bilebag", "RoyalJelly", "MechanicalSpring", "CopperScrap", "TrophyGoblinKing", "DvergrKeyFragment", "BlackMarbleWall");
			Items(1, "PineCone", "FirCone", "BeechSeeds", "BirchSeeds", "Acorn", "CarrotSeeds", "MushroomYellow", "FeastBlackforest_Material");
			Items(2, "Ectoplasm", "TurnipSeeds", "FeastSwamps_Material", "FeastOceans_Material");
			Items(3, "FeastMountains_Material", "SilverNecklace");
			Items(4, "Cloudberry", "CandleWick", "BarleyWine", "YagluthDrop", "FeastPlains_Material", "OnionSeeds");
			Items(5, "Lantern", "BarrelRings", "SharpeningStone", "ShieldCore", "QueenDrop", "MushroomJotunPuffs", "MushroomMagecap", "FeastMistlands_Material");
			Items(6, "Frostwood", "MooseHide", "NornThread", "Ice", "BjornHide", "SealHide", "Gold", "SulfurStone", "CeramicPlate", "Charredskull", "Pot_Shard_Green", "Pot_Shard_Red", "FaderDrop", "FrostCore", "FeastAshlands_Material", "FeastDeepNorth_Material", "TrophyMoose", "TrophyBjorn", "BjornPaw", "MooseSinew");
			Items(6, "Grausten", "Blackwood", "FlametalNew", "Flametal", "FlametalOre", "CharredBone", "CelestialFeather", "AskHide", "AskBladder", "MoltenCore", "ProustitePowder", "CharcoalResin", "BellFragment", "CharredCogwheel", "MorgenSinew", "MorgenHeart", "TrophySeekerQueen", "GemstoneRed", "GemstoneBlue", "GemstoneGreen", "Vineberry", "Fiddleheadfern");
		}

		public static int PieceAge(string prefab)
		{
			if (pieceAge.TryGetValue(prefab, out var value))
			{
				return value;
			}
			value = 0;
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null);
			Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null);
			bool flag = false;
			if ((Object)(object)val2 != (Object)null)
			{
				if ((Object)(object)val2.m_craftingStation != (Object)null && StationAge.TryGetValue(Util.PrefabName(((Component)val2.m_craftingStation).gameObject), out var value2))
				{
					value = Mathf.Max(value, value2);
				}
				if (val2.m_resources != null)
				{
					Requirement[] resources = val2.m_resources;
					foreach (Requirement val3 in resources)
					{
						if (val3 != null && !((Object)(object)val3.m_resItem == (Object)null))
						{
							flag = true;
							string text = Util.PrefabName(((Component)val3.m_resItem).gameObject);
							if (ItemAge.TryGetValue(text, out var value3))
							{
								value = Mathf.Max(value, value3);
							}
							else
							{
								UnknownItems.Add(text);
							}
						}
					}
				}
			}
			if (!flag)
			{
				value = Mathf.Max(value, AgeByName(prefab));
			}
			pieceAge[prefab] = value;
			return value;
		}

		private static int AgeByName(string n)
		{
			n = n.ToLowerInvariant();
			if (n.Contains("ashland") || n.Contains("charred") || n.Contains("grausten") || n.Contains("ashwood") || n.Contains("flametal") || n.Contains("blackwood"))
			{
				return 6;
			}
			if (n.Contains("dvergr") || n.Contains("blackmarble") || n.Contains("yggdrasil") || n.Contains("mistlands"))
			{
				return 5;
			}
			if (n.Contains("goblin") || n.Contains("darkwood") || n.Contains("blackmetal"))
			{
				return 4;
			}
			if (n.Contains("crystal") || n.Contains("mountain"))
			{
				return 3;
			}
			if (n.Contains("sunken") || n.Contains("swamp") || n.Contains("iron"))
			{
				return 2;
			}
			return 0;
		}

		public static string Kind(string prefab)
		{
			string text = prefab.ToLowerInvariant();
			if (text.Contains("stair") || text.Contains("ladder") || text.Contains("ramp"))
			{
				return "stair";
			}
			if (text.Contains("door") || text.Contains("gate"))
			{
				return "door";
			}
			if (text.Contains("window"))
			{
				return "window";
			}
			if (text.Contains("roof"))
			{
				if (!text.Contains("top"))
				{
					if (!text.Contains("corner"))
					{
						if (!text.Contains("wall"))
						{
							return "roof";
						}
						return "roofwall";
					}
					if (!text.Contains("icorner"))
					{
						return "roof_oc";
					}
					return "roof_ic";
				}
				return "rooftop";
			}
			if (text.Contains("floor"))
			{
				return "floor";
			}
			if (text.Contains("wall"))
			{
				return "wall";
			}
			if (text.Contains("beam") || text.Contains("pole") || text.Contains("log") || text.Contains("pillar") || text.Contains("column") || text.Contains("arch"))
			{
				return "beam";
			}
			if (text.Contains("fence") || text.Contains("stake"))
			{
				return "fence";
			}
			return "decor";
		}

		public static bool Structural(string kind)
		{
			if (kind != "decor" && kind != "door" && kind != "window")
			{
				return kind != "fence";
			}
			return false;
		}

		private static List<string> Buildable()
		{
			if (buildable != null)
			{
				return buildable;
			}
			buildable = new List<string>();
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return buildable;
			}
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					Piece component = prefab.GetComponent<Piece>();
					if (!((Object)(object)component == (Object)null) && component.m_resources != null && component.m_resources.Length != 0)
					{
						buildable.Add(((Object)prefab).name);
					}
				}
			}
			return buildable;
		}

		public static string Substitute(string prefab, int maxAge)
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			long key = ((long)StringExtensionMethods.GetStableHashCode(prefab) << 8) | (uint)maxAge;
			if (subs.TryGetValue(key, out var value))
			{
				return value;
			}
			value = null;
			string text = Kind(prefab);
			PM pM = PieceInfo.Get(prefab);
			float num = 0.3f;
			foreach (string item in Buildable())
			{
				if (item == prefab || PieceAge(item) > maxAge || Kind(item) != text)
				{
					continue;
				}
				PM pM2 = PieceInfo.Get(item);
				Vector3 val;
				float num2;
				if (pM.Snaps.Count >= 2 && pM2.Snaps.Count >= 2)
				{
					val = pM.SMin - pM2.SMin;
					float magnitude = ((Vector3)(ref val)).magnitude;
					val = pM.SMax - pM2.SMax;
					num2 = magnitude + ((Vector3)(ref val)).magnitude;
					if (pM.Snaps.Count != pM2.Snaps.Count)
					{
						num2 += 0.08f;
					}
				}
				else
				{
					if (!pM.HasMesh || !pM2.HasMesh)
					{
						continue;
					}
					val = ((Bounds)(ref pM.Mesh)).size - ((Bounds)(ref pM2.Mesh)).size;
					float num3 = ((Vector3)(ref val)).magnitude * 0.5f;
					val = ((Bounds)(ref pM.Mesh)).center - ((Bounds)(ref pM2.Mesh)).center;
					num2 = num3 + ((Vector3)(ref val)).magnitude * 0.5f;
				}
				if (item.StartsWith("wood_") || item.StartsWith("stone_"))
				{
					num2 -= 0.02f;
				}
				if (num2 < num)
				{
					num = num2;
					value = item;
				}
			}
			subs[key] = value;
			return value;
		}

		public static int NativeAge(Blueprint bp)
		{
			int num = 0;
			foreach (BPPart part in bp.Parts)
			{
				if (part.Tag == BType.None)
				{
					num = Mathf.Max(num, PieceAge(part.Prefab));
				}
			}
			return num;
		}

		public static Result Adapt(Blueprint bp, int age)
		{
			if (!cache.TryGetValue(bp, out var value))
			{
				value = (cache[bp] = new Dictionary<int, Result>());
			}
			if (value.TryGetValue(age, out var value2))
			{
				return value2;
			}
			value2 = new Result
			{
				Native = NativeAge(bp)
			};
			if (value2.Native <= age)
			{
				value2.Plan = bp;
				value[age] = value2;
				return value2;
			}
			Blueprint blueprint = new Blueprint
			{
				Type = bp.Type,
				HalfW = bp.HalfW,
				HalfD = bp.HalfD
			};
			int num = 0;
			int num2 = 0;
			foreach (BPPart part in bp.Parts)
			{
				string text = Kind(part.Prefab);
				bool flag = Structural(text);
				if (flag)
				{
					num++;
				}
				if (part.Tag != BType.None || PieceAge(part.Prefab) <= age)
				{
					blueprint.Parts.Add(Copy(part, part.Prefab));
					continue;
				}
				string text2 = ((text == "decor") ? null : Substitute(part.Prefab, age));
				if (text2 != null)
				{
					blueprint.Parts.Add(Copy(part, text2));
					value2.Swapped++;
					continue;
				}
				value2.Dropped++;
				if (flag)
				{
					num2++;
				}
			}
			value2.Plan = ((num > 0 && (float)num2 > Mathf.Max(2f, (float)num * 0.08f)) ? null : blueprint);
			value[age] = value2;
			return value2;
		}

		private static BPPart Copy(BPPart p, string prefab)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return new BPPart
			{
				Prefab = prefab,
				Pos = p.Pos,
				Rot = p.Rot,
				Yaw = p.Yaw,
				Tag = p.Tag,
				Bid = p.Bid,
				Residents = p.Residents
			};
		}

		public static int MinAge(Blueprint bp)
		{
			for (int i = 0; i <= 6; i++)
			{
				if (Adapt(bp, i).Plan != null)
				{
					return i;
				}
			}
			return 6;
		}

		public static int BuildingAge(AnnoBuilding b)
		{
			int num = 0;
			foreach (ZNetView item in HouseGen.GroupViews(((Component)b).gameObject, b.Group))
			{
				if (item.GetZDO().GetInt("anno_bld", 0) == 0)
				{
					num = Mathf.Max(num, PieceAge(Util.PrefabName(((Component)item).gameObject)));
				}
			}
			return num;
		}
	}
	public class AnnoScaler : MonoBehaviour
	{
		public const int Tree = 0;

		public const int Rock = 1;

		public const int Bush = 2;

		public int Kind;

		public static bool On
		{
			get
			{
				if (Flat.Active)
				{
					return Plugin.SmallNature.Value;
				}
				return false;
			}
		}

		public static void Attach(Component c, int kind)
		{
			if (!On || (Object)(object)c == (Object)null)
			{
				return;
			}
			GameObject gameObject = c.gameObject;
			if ((Object)(object)gameObject.GetComponent<Piece>() != (Object)null || (Object)(object)gameObject.GetComponent<ZNetView>() == (Object)null || (Object)(object)gameObject.GetComponent<AnnoScaler>() != (Object)null)
			{
				return;
			}
			if (kind == 2)
			{
				string text = Util.PrefabName(gameObject).ToLowerInvariant();
				if (text.Contains("rock"))
				{
					kind = 1;
				}
				else if (!text.Contains("bush") && !text.Contains("shrub") && !text.Contains("stub"))
				{
					return;
				}
			}
			gameObject.AddComponent<AnnoScaler>().Kind = kind;
		}

		private void Start()
		{
			//IL_000d: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float num = Height();
				float num2 = Hash01(((Component)this).transform.position);
				float num3 = 1f;
				if (Kind == 0 && num > 0.5f)
				{
					num3 = Mathf.Lerp(Plugin.TreeHeightMin.Value, Plugin.TreeHeightMax.Value, num2) / num;
				}
				else if (Kind == 1 && num > 0.5f)
				{
					float num4 = Mathf.Lerp(1.4f, 2.6f, num2);
					num3 = ((num > num4) ? (num4 / num) : 1f);
				}
				else if (Kind == 2)
				{
					num3 = 0.6f;
				}
				num3 = Mathf.Clamp(num3, 0.12f, 1f);
				if (num3 < 0.98f)
				{
					Transform transform = ((Component)this).transform;
					transform.localScale *= num3;
				}
			}
			catch
			{
			}
			Object.Destroy((Object)(object)this);
		}

		private float Height()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			float num = float.MinValue;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer))
				{
					float num2 = num;
					Bounds bounds = val.bounds;
					num = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y);
				}
			}
			if (num != float.MinValue)
			{
				return num - ((Component)this).transform.position.y;
			}
			return 0f;
		}

		private static float Hash01(Vector3 p)
		{
			//IL_0000: 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 (float)(((Mathf.RoundToInt(p.x * 7.13f) * 73856093) ^ (Mathf.RoundToInt(p.z * 5.71f) * 19349663)) & 0xFFFF) / 65535f;
		}
	}
	public static class AnnoLook
	{
		private static int clutterDone;

		private static int vegDone;

		public const string EnvName = "AnnoSunny";

		private static float lastFog = -1f;

		private static float baseFog;

		public static void Tick()
		{
			if (AnnoScaler.On)
			{
				ShortGrass();
				TidyVegetation();
			}
		}

		private static void ShortGrass()
		{
			ClutterSystem instance = ClutterSystem.instance;
			if ((Object)(object)instance == (Object)null || ((Object)instance).GetInstanceID() == clutterDone)
			{
				return;
			}
			clutterDone = ((Object)instance).GetInstanceID();
			float num = Mathf.Clamp(Plugin.GrassScale.Value, 0.1f, 1f);
			foreach (Clutter item in instance.m_clutter)
			{
				if (item != null)
				{
					item.m_scaleMin *= num;
					item.m_scaleMax *= num;
				}
			}
			try
			{
				instance.ClearAll();
			}
			catch
			{
			}
			Plugin.Log("[Look] Grass scaled to " + num);
		}

		private static void TidyVegetation()
		{
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance == (Object)null || ((Object)instance).GetInstanceID() == vegDone || instance.m_vegetation == null)
			{
				return;
			}
			vegDone = ((Object)instance).GetInstanceID();
			int num = 0;
			foreach (ZoneVegetation item in instance.m_vegetation)
			{
				if (item != null && !((Object)(object)item.m_prefab == (Object)null))
				{
					string text = ((Object)item.m_prefab).name.ToLowerInvariant();
					if (!text.Contains("pickable") && !text.Contains("mine") && !text.Contains("berry") && (text.Contains("rock") || text.Contains("stub") || text.Contains("log") || text.Contains("bush") || text.Contains("shrub")))
					{
						item.m_min *= 0.3f;
						item.m_max *= 0.3f;
						num++;
					}
				}
			}
			Plugin.Log("[Look] Thinned out " + num + " kinds of loose vegetation for new areas");
		}

		public static void Fog(bool anno, float dist, float blend = 1f)
		{
			if (RenderSettings.fog)
			{
				float fogDensity = RenderSettings.fogDensity;
				if (!Mathf.Approximately(fogDensity, lastFog))
				{
					baseFog = fogDensity;
				}
				float num = ((anno && Plugin.AnnoLight.Value) ? Mathf.Lerp(1f, Mathf.Lerp(0.6f, 0.12f, Mathf.InverseLerp(30f, 300f, dist)), Mathf.Clamp01(blend)) : 1f);
				lastFog = baseFog * num;
				RenderSettings.fogDensity = lastFog;
			}
		}

		public static void EnemyHud(bool anno)
		{
			try
			{
				EnemyHud instance = EnemyHud.instance;
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_hudRoot != (Object)null && instance.m_hudRoot.activeSelf == anno)
				{
					instance.m_hudRoot.SetActive(!anno);
				}
			}
			catch
			{
			}
		}

		public unsafe static string EnsureEnv()
		{
			//IL_00c5: 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)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			EnvMan instance = EnvMan.instance;
			if ((Object)(object)instance == (Object)null || !Plugin.AnnoLight.Value)
			{
				return "Clear";
			}
			if (instance.m_environments.Any((EnvSetup e) => e != null && e.m_name == "AnnoSunny"))
			{
				return "AnnoSunny";
			}
			EnvSetup val = ((IEnumerable<EnvSetup>)instance.m_environments).FirstOrDefault((Func<EnvSetup, bool>)((EnvSetup e) => e != null && e.m_name == "Clear"));
			if (val == null)
			{
				return "Clear";
			}
			string[] obj = new string[12]
			{
				"[Look] Clear: fogDay=",
				val.m_fogDensityDay.ToString(),
				" light=",
				val.m_lightIntensityDay.ToString(),
				" sun=",
				null,
				null,
				null,
				null,
				null,
				null,
				null
			};
			Color sunColorDay = val.m_sunColorDay;
			obj[5] = ((object)(*(Color*)(&sunColorDay))/*cast due to .constrained prefix*/).ToString();
			obj[6] = " amb=";
			sunColorDay = val.m_ambColorDay;
			obj[7] = ((object)(*(Color*)(&sunColorDay))/*cast due to .constrained prefix*/).ToString();
			obj[8] = " fogCol=";
			sunColorDay = val.m_fogColorDay;
			obj[9] = ((object)(*(Color*)(&sunColorDay))/*cast due to .constrained prefix*/).ToString();
			obj[10] = " clouds=";
			obj[11] = val.m_cloudOpacityDay.ToString();
			Plugin.Log(string.Concat(obj));
			EnvSetup val2 = val.Clone();
			val2.m_name = "AnnoSunny";
			val2.m_fogDensityDay = val.m_fogDensityDay * 0.3f;
			val2.m_fogDensityMorning = val.m_fogDensityMorning * 0.35f;
			val2.m_fogDensityEvening = val.m_fogDensityEvening * 0.35f;
			val2.m_fogColorDay = new Color(0.68f, 0.81f, 0.94f);
			val2.m_fogColorSunDay = new Color(0.96f, 0.9f, 0.76f);
			val2.m_sunColorDay = new Color(1f, 0.95f, 0.84f);
			val2.m_lightIntensityDay = val.m_lightIntensityDay * 1.15f;
			val2.m_ambColorDay = Color.Lerp(val.m_ambColorDay, new Color(0.6f, 0.68f, 0.78f), 0.45f);
			val2.m_cloudOpacityDay = val.m_cloudOpacityDay * 0.5f;
			instance.AppendEnvironment(val2);
			return "AnnoSunny";
		}
	}
	public class AnnoMode : MonoBehaviour
	{
		private enum Tool
		{
			None,
			Place,
			Road,
			Demolish,
			Paste,
			CopyArea
		}

		private class Note
		{
			public string Text;

			public float Until;

			public string Label;

			public Action Act;
		}

		public class ClipItem
		{
			public BDef Def;

			public Blueprint Plan;

			public Vector3 Off;

			public float Yaw;

			public bool Free;

			public Dictionary<string, int> Cost;

			public AnnoBuilding Source;

			public int Group;

			public Vector3 SrcCenter;

			public float SrcYaw;
		}

		public class Clip
		{
			public string Name;

			public bool Move;

			public bool OnRoadGrid;

			public readonly List<ClipItem> Items = new List<ClipItem>();

			public List<KeyValuePair<Vector2Int, int>> Roads = new List<KeyValuePair<Vector2Int, int>>();

			public int Parts => Items.Sum((ClipItem i) => i.Plan.Parts.Count);
		}

		public static bool Active;

		public static Vector3 Focus;

		private static Vector3 focusTarget;

		private static float yaw;

		private static float dist = 90f;

		private static float distTarget = 90f;

		private static float baseFov = -1f;

		private const float MinDist = 15f;

		private const float MaxDist = 380f;

		private AnnoBuilding hoverBuilding;

		private Tool tool;

		private BDef selected;

		private float placeYaw;

		private GameObject ghost;

		private Blueprint plan;

		private string planName;

		private int variant;

		private bool blocked;

		private bool fogBlocked;

		private Vector3 placePoint;

		private Roads.RDef road;

		private bool roadStarted;

		private Vector3 roadStart;

		private readonly List<GameObject> selTrees = new List<GameObject>();

		private readonly List<AnnoBuilding> selBuildings = new List<AnnoBuilding>();

		private readonly List<Soldier> selSoldiers = new List<Soldier>();

		private bool dragging;

		private Vector2 dragStart;

		private string hoverText;

		private bool initDone;

		private Rect panelRect;

		public static AnnoMode Instance;

		public static float PitchOverride = float.NaN;

		private static float dayTimer;

		private static float anchorT;

		private static bool anchorOk;

		private static Vector3 anchorPos = Vector3.positiveInfinity;

		private static bool flatTipShown;

		private static LineRenderer orderRing;

		private static float orderUntil;

		private static readonly List<Rect> uiRects = new List<Rect>();

		private static readonly List<Rect> uiNext = new List<Rect>();

		private string tab;

		private bool storageOpen;

		private string bpSearch = "";

		private Vector2 bpScroll;

		private string tip;

		private BDef tipDef;

		private Rect tipAnchor;

		private float trayTop;

		private static bool uiTyping;

		private static readonly string[] Cats = new string[7] { "Residences", "Raw Materials", "Production", "Public", "Military", "Roads", "Blueprints" };

		private static readonly string[] StorageGoods = new string[22]
		{
			"Wood", "Stone", "Flint", "Coins", "Raspberry", "Blueberries", "Mushroom", "Carrot", "Honey", "RawMeat",
			"DeerMeat", "CookedMeat", "CookedDeerMeat", "MeadHealthMinor", "Coal", "Barley", "BarleyFlour", "Bread", "LeatherScraps", "DeerHide",
			"SpearFlint", "ShieldWood"
		};

		private static readonly List<Note> notes = new List<Note>();

		public static bool Hints = true;

		public static readonly Dictionary<string, Rect> Named = new Dictionary<string, Rect>();

		public static float PortraitBarY = 0.8f;

		public static float PortraitTopY = 96f;

		private static GUIStyle wrapC;

		private static GUIStyle wrapL;

		private readonly Dictionary<int, KeyValuePair<float, int>> ageCache = new Dictionary<int, KeyValuePair<float, int>>();

		private readonly Dictionary<int, KeyValuePair<float, int>> nearCache = new Dictionary<int, KeyValuePair<float, int>>();

		private Rect mapRect;

		private Clip clip;

		private Clip lastClip;

		private float pasteYaw;

		private GameObject pasteGhost;

		private readonly List<GameObject> pasteItemGhosts = new List<GameObject>();

		private readonly List<bool> pasteItemBlocked = new List<bool>();

		private readonly List<GameObject> pasteRoadGhosts = new List<GameObject>();

		private Vector3 pastePivot = Vector3.positiveInfinity;

		private float pasteLastYaw = float.NaN;

		private float pasteRecheck;

		private int pasteBlocked;

		private HashSet<int> moveGroups;

		private Vector3? remotePivot;

		private bool areaStarted;

		private Vector3 areaStart;

		private readonly List<KeyValuePair<AnnoBuilding, Vector3>> areaCenters = new List<KeyValuePair<AnnoBuilding, Vector3>>();

		private readonly HashSet<AnnoBuilding> areaHits = new HashSet<AnnoBuilding>();

		private static Material ghostMat;

		private static LineRenderer ring;

		private bool ringWanted;

		private float rangeT;

		private int rangeCount;

		private Vector3 rangeAt = Vector3.positiveInfinity;

		private bool mapOpen;

		private bool researchOpen;

		private int siteOpen;

		private int siteTab;

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

		private ZDO scoutTargeting;

		private float mapZoom = 1f;

		private Vector2 mapCenter = new Vector2(float.NaN, 0f);

		private bool mapDrag;

		private Vector2 mapDragFrom;

		private Vector2 mapDragCenter;

		private float zoomFrom = 1f;

		private float zoomTo = 1f;

		private float zoomT0;

		private float zoomDur = -1f;

		private Vector2 centerFrom;

		private Vector2 centerTo;

		private bool centerMove;

		private static readonly string[] SiteTabs = new string[4] { "Overview", "Trade", "Diplomacy", "Attack" };

		private int researchRow;

		public static float CamDist => dist;

		public static float CamYaw => yaw;

		private bool InGame
		{
			get
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
				{
					return (Object)(object)GameCamera.instance != (Object)null;
				}
				return false;
			}
		}

		private static GUIStyle WrapC
		{
			get
			{
				//IL_000c: 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_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				if (wrapC == null)
				{
					wrapC = new GUIStyle(UI.SmallC)
					{
						wordWrap = true,
						alignment = (TextAnchor)1
					};
				}
				return wrapC;
			}
		}

		private static GUIStyle WrapL
		{
			get
			{
				//IL_000c: 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_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				if (wrapL == null)
				{
					wrapL = new GUIStyle(UI.Small)
					{
						wordWrap = true,
						alignment = (TextAnchor)0
					};
				}
				return wrapL;
			}
		}

		private static bool Ctrl
		{
			get
			{
				if (!In.Held((Key)55))
				{
					return In.Held((Key)56);
				}
				return true;
			}
		}

		public static string LayoutDir => Path.Combine(Imports.Dir, "layouts");

		private bool WorldWindowOpen
		{
			get
			{
				if (!mapOpen && !researchOpen)
				{
					return siteOpen != 0;
				}
				return true;
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		public void RemoteSetActive(bool on)
		{
			if (InGame && on != Active)
			{
				SetActive(on);
			}
		}

		public static void RemoteCamera(Vector3 p, float d, float y)
		{
			//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)
			focusTarget = p;
			Focus = p;
			if (d > 0f)
			{
				distTarget = (dist = Mathf.Clamp(d, 4f, 380f));
			}
			if (!float.IsNaN(y))
			{
				yaw = y;
			}
		}

		public static void RemoteTeleport(Vector3 p)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_004f: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				float num = ((WorldGenerator.instance != null) ? WorldGenerator.instance.GetHeight(p.x, p.z) : p.y);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(p.x, Mathf.Max(num, 30f) + 1.5f, p.z);
				try
				{
					((Character)localPlayer).TeleportTo(val, ((Component)localPlayer).transform.rotation, true);
				}
				catch
				{
					MovePlayer(localPlayer, val);
				}
				focusTarget = (Focus = val);
			}
		}

		public void RemotePlaceYaw(float y)
		{
			placeYaw = y;
		}

		public void RemoteTab(string t)
		{
			tab = ((string.IsNullOrEmpty(t) || t == "none") ? null : t);
		}

		public void RemoteSelect(AnnoBuilding b)
		{
			ClearSelection();
			if ((Object)(object)b != (Object)null)
			{
				selBuildings.Add(Primary(b));
			}
		}

		private void Update()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			if (!InGame)
			{
				if (Active)
				{
					SetActive(on: false);
				}
				return;
			}
			if (!initDone)
			{
				initDone = true;
				PieceInfo.Dump();
				Imports.Reload();
				StarterKit();
			}
			AnnoLook.Tick();
			Colony.Update(Time.deltaTime);
			WorldTick(Time.deltaTime);
			PlayerWorker.Tick(Time.deltaTime);
			KeepDay();
			if (TypingSomewhere() || uiTyping)
			{
				return;
			}
			if (In.Pressed(Plugin.ToggleKey.Value))
			{
				SetActive(!Active);
			}
			if (!Active)
			{
				return;
			}
			if (In.Pressed((Key)102))
			{
				Miniature.Enabled = !Miniature.Enabled;
				Plugin.MiniOn.Value = Miniature.Enabled;
				Toast(Miniature.Enabled ? "Miniature look on" : "Miniature look off");
			}
			if (In.Pressed((Key)21))
			{
				Plugin.GridOn.Value = !Plugin.GridOn.Value;
				if (Plugin.GridOn.Value)
				{
					placeYaw = Mathf.Round(placeYaw / 90f) * 90f;
				}
				Toast(Plugin.GridOn.Value ? "Grid on" : "Grid off");
			}
			if (In.Pressed((Key)71))
			{
				if (selBuildings.Count > 0)
				{
					DemolishSelected();
				}
				else
				{
					SetTool((tool != Tool.Demolish) ? Tool.Demolish : Tool.None);
				}
			}
			if (Plugin.HideHud.Value)
			{
				SetHud(visible: false);
			}
			WorldHotkeys();
			UpdateCameraControls();
			AnnoMap.Tick(Focus, yaw);
			hoverText = null;
			hoverBuilding = ((tool == Tool.None && !MouseOverUI()) ? BuildingUnderMouse() : null);
			BuildHotkeys();
			switch (tool)
			{
			case Tool.Place:
				UpdatePlacement();
				break;
			case Tool.Road:
				UpdateRoad();
				break;
			case Tool.Demolish:
				UpdateDemolish();
				break;
			case Tool.Paste:
				UpdatePaste();
				break;
			case Tool.CopyArea:
				UpdateCopyArea();
				break;
			default:
				UpdateSelection();
				break;
			}
			if (tool == Tool.None && selBuildings.Count == 1 && IsGatherer(selBuildings[0].Def))
			{
				ShowRange(((Component)selBuildings[0]).transform.position, selBuildings[0].Def.Job);
			}
			EndFrameRange();
			if ((Object)(object)orderRing != (Object)null && ((Component)orderRing).gameObject.activeSelf && Time.time > orderUntil)
			{
				((Component)orderRing).gameObject.SetActive(false);
			}
		}

		private static void WorldTick(float dt)
		{
			try
			{
				FogLayer.Ensure();
				AnnoWorld.Tick(dt);
				Fog.Tick(dt);
				Sites.Tick(dt);
				Sites.Deliveries(dt);
				Expeditions.Tick(dt);
				Scouts.Tick(dt);
				Tech.Tick(dt);
			}
			catch (Exception ex)
			{
				Plugin.Warn("Welt-Takt: " + ex);
			}
		}

		private static bool IsGatherer(BDef d)
		{
			if (d != null)
			{
				if (d.Job != Job.Holz && d.Job != Job.Stein && d.Job != Job.Sammeln)
				{
					return d.Job == Job.Jagd;
				}
				return true;
			}
			return false;
		}

		private static void KeepDay()
		{
			dayTimer -= Time.unscaledDeltaTime;
			if (dayTimer > 0f || (Object)(object)EnvMan.instance == (Object)null)
			{
				return;
			}
			dayTimer = 1f;
			if (!Plugin.AlwaysDay.Value)
			{
				return;
			}
			try
			{
				Traverse obj = Traverse.Create((object)EnvMan.instance);
				obj.Field("m_debugTimeOfDay").SetValue((object)true);
				obj.Field("m_debugTime").SetValue((object)Plugin.DayTime.Value);
			}
			catch
			{
			}
		}

		private static bool TypingSomewhere()
		{
			try
			{
				if (Console.IsVisible())
				{
					return true;
				}
				if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
				{
					return true;
				}
				if (TextInput.IsVisible())
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void StarterKit()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			string[] array = new string[4] { "AxeStone", "Hammer", "Hoe", "Torch" };
			foreach (string text in array)
			{
				string text2 = Economy.SharedName(text);
				if (text2 != null && inventory.CountItems(text2, -1, true) <= 0)
				{
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
					ItemData val = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone();
					val.m_dropPrefab = itemPrefab;
					val.m_stack = 1;
					val.m_durability = val.GetMaxDurability();
					inventory.AddItem(val);
				}
			}
			try
			{
				ItemData val2 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData val3) => (int)val3.m_shared.m_skillType == 7));
				if (val2 != null && ((Humanoid)localPlayer).GetCurrentWeapon() != val2)
				{
					((Humanoid)localPlayer).EquipItem(val2, true);
				}
			}
			catch
			{
			}
		}

		private void SetActive(bool on)
		{
			//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_0085: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			Active = on;
			try
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					Player.m_localPlayer.SetGhostMode(on);
				}
			}
			catch
			{
			}
			SetHud(!on || !Plugin.HideHud.Value);
			try
			{
				if ((Object)(object)EnvMan.instance != (Object)null && Plugin.ClearWeather.Value)
				{
					EnvMan.instance.SetForceEnvironment(on ? AnnoLook.EnsureEnv() : "");
				}
			}
			catch
			{
			}
			if (on)
			{
				Focus = (focusTarget = ((Component)Player.m_localPlayer).transform.position);
				yaw = ((Component)GameCamera.instance).transform.eulerAngles.y;
				dist = (distTarget = 90f);
				Toast("City view  ·  WASD move, Q/E rotate, wheel zoom");
				if (!Flat.Active && !flatTipShown)
				{
					flatTipShown = true;
					Toast("Tip: this world has normal Valheim terrain. New worlds you create with the mod installed are flat, which makes building much easier.");
				}
			}
			else
			{
				SetTool(Tool.None);
				ClearSelection();
				Camera val = Cam();
				if ((Object)(object)val != (Object)null && baseFov > 0f)
				{
					val.fieldOfView = baseFov;
				}
			}
		}

		private static void SetHud(bool visible)
		{
			try
			{
				if (!((Object)(object)Hud.instance == (Object)null))
				{
					GameObject value = Traverse.Create((object)Hud.instance).Field("m_rootObject").GetValue<GameObject>();
					if ((Object)(object)value != (Object)null)
					{
						value.SetActive(visible);
					}
				}
			}
			catch
			{
			}
		}

		private void SetTool(Tool t)
		{
			if (tool == Tool.Place && t != Tool.Place)
			{
				CancelPlacement();
			}
			if (tool == Tool.Road)
			{
				Roads.HidePreview();
				roadStarted = false;
			}
			if (tool == Tool.Paste && t != Tool.Paste)
			{
				EndPaste();
			}
			if (tool == Tool.CopyArea)
			{
				Roads.HidePreview();
				areaStarted = false;
				areaHits.Clear();
			}
			GridOverlay.Hide();
			tool = t;
			if (t == Tool.Demolish)
			{
				Toast("Demolish: click a building (right click to stop)");
			}
			if (t == Tool.CopyArea)
			{
				EnterCopyArea();
			}
		}

		private void UpdateCameraControls()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_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_0071: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			Quaternion val = Quaternion.Euler(0f, yaw, 0f);
			Vector3 val2 = Vector3.zero;
			if (In.Held((Key)37))
			{
				val2 += val * Vector3.forward;
			}
			if (In.Held((Key)33))
			{
				val2 += val * Vector3.back;
			}
			if (In.Held((Key)15))
			{
				val2 += val * Vector3.left;
			}
			if (In.Held((Key)18))
			{
				val2 += val * Vector3.right;
			}
			float num = Mathf.Lerp(16f, 160f, Mathf.InverseLerp(15f, 380f, dist));
			if (In.Held((Key)51))
			{
				num *= 2.5f;
			}
			focusTarget += ((Vector3)(ref val2)).normalized * num * unscaledDeltaTime;
			if (In.Held((Key)31))
			{
				yaw -= 100f * unscaledDeltaTime;
			}
			if (In.Held((Key)19))
			{
				yaw += 100f * unscaledDeltaTime;
			}
			if (In.MiddleHeld)
			{
				yaw += In.MouseDelta.x * 0.25f;
			}
			float scroll = In.Scroll;
			if (Mathf.Abs(scroll) > 0.01f && !MouseOverUI())
			{
				distTarget = Mathf.Clamp(distTarget * Mathf.Pow(0.72f, scroll), 15f, 380f);
			}
			if (In.Held((Key)67) || In.Held((Key)80))
			{
				distTarget = Mathf.Max(15f, distTarget * (1f - 2.5f * unscaledDeltaTime));
			}
			if (In.Held((Key)66) || In.Held((Key)81))
			{
				distTarget = Mathf.Min(380f, distTarget * (1f + 2.5f * unscaledDeltaTime));
			}
			Player localPlayer = Player.m_localPlayer;
			Vector3 val3 = focusTarget - ((Component)localPlayer).transform.position;
			val3.y = 0f;
			if (PlayerWorker.Busy)
			{
				if (((Vector3)(ref val3)).magnitude > 90f)
				{
					focusTarget = ((Component)localPlayer).transform.position + ((Vector3)(ref val3)).normalized * 90f;
				}
			}
			else
			{
				Vector3 val4;
				float num2;
				if (!SettlementAnchor(out var p) || !(FlatDist(focusTarget - p) < 130f))
				{
					val4 = focusTarget;
					num2 = 60f;
				}
				else if (FlatDist(focusTarget - p) < 50f)
				{
					val4 = p;
					num2 = 6f;
				}
				else
				{
					val4 = Vector3.Lerp(p, focusTarget, 0.5f);
					num2 = 20f;
				}
				if (FlatDist(((Component)localPlayer).transform.position - val4) > num2)
				{
					MovePlayer(localPlayer, val4);
				}
			}
			focusTarget.y = Util.Ground(focusTarget);
			Focus = Vector3.Lerp(Focus, focusTarget, 1f - Mathf.Exp(-12f * unscaledDeltaTime));
			dist = Mathf.Lerp(dist, distTarget, 1f - Mathf.Exp(-18f * unscaledDeltaTime));
		}

		private static float FlatDist(Vector3 v)
		{
			v.y = 0f;
			return ((Vector3)(ref v)).magnitude;
		}

		private static bool SettlementAnchor(out Vector3 p)
		{
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			anchorT -= Time.unscaledDeltaTime;
			if (anchorT <= 0f)
			{
				anchorT = 5f;
				List<AnnoBuilding> list = AnnoBuilding.All.Where((AnnoBuilding b) => (Object)(object)b != (Object)null && b.Valid).ToList();
				anchorOk = list.Count > 0;
				if (anchorOk)
				{
					Vector3 val = Vector3.zero;
					foreach (AnnoBuilding item in list)
					{
						val += ((Component)item).transform.position;
					}
					val /= (float)list.Count;
					Vector3 val2 = val;
					float num = float.MaxValue;
					foreach (Vector2 item2 in Roads.AllCells())
					{
						float num2 = (item2.x - val.x) * (item2.x - val.x) + (item2.y - val.z) * (item2.y - val.z);
						if (num2 < num)
						{
							num = num2;
							val2 = new Vector3(item2.x, 0f, item2.y);
						}
					}
					if (num > 900f)
					{
						val2 = val;
					}
					if (!float.IsInfinity(anchorPos.x) && FlatDist(val2 - anchorPos) < 12f)
					{
						val2 = anchorPos;
					}
					anchorPos = val2;
				}
			}
			p = anchorPos;
			return anchorOk;
		}

		private static void MovePlayer(Player pl, Vector3 p)
		{
			//IL_0021: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f);
			p.y = Mathf.Max(Util.Ground(p), num) + 0.4f;
			((Component)pl).transform.position = p;
			Rigidbody component = ((Component)pl).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				component.position = p;
				component.velocity = Vector3.zero;
			}
		}

		public static void ApplyCamera(Transform cam)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005c: 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_0066: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Lerp(34f, 62f, Mathf.InverseLerp(15f, 266f, dist));
			if (!float.IsNaN(PitchOverride))
			{
				num = PitchOverride;
			}
			Quaternion val = Quaternion.Euler(num, yaw, 0f);
			Vector3 val2 = Focus - val * Vector3.forward * dist;
			float num2 = Util.Ground(val2) + 2f;
			if (val2.y < num2)
			{
				val2.y = num2;
			}
			cam.SetPositionAndRotation(val2, val);
			Camera component = ((Component)cam).GetComponent<Camera>();
			if ((Object)(object)component != (Object)null)
			{
				if (baseFov < 0f)
				{
					baseFov = component.fieldOfView;
				}
				component.fieldOfView = Plugin.AnnoFov.Value;
				if (component.farClipPlane < dist + 600f)
				{
					component.farClipPlane = dist + 600f;
				}
			}
		}

		private void Select(BDef def)
		{
			SetTool(Tool.None);
			ClearSelection();
			if (!Defs.Unlocked(def))
			{
				Toast(def.Name + " unlocks " + Defs.UnlockNames[def.Tier]);
				return;
			}
			selected = def;
			variant = -1;
			tool = Tool.Place;
			NewPlan(next: false);
		}

		private List<ImportedBP> Variants(BDef def)
		{
			return (from v in def.Variants.Select(Imports.ByStem)
				where v != null
				select v).ToList();
		}

		private void NewPlan(bool next)
		{
			if (selected == null)
			{
				return;
			}
			if ((Object)(object)ghost != (Object)null)
			{
				Object.Destroy((Object)(object)ghost);
			}
			int num = ((selected.Import != null) ? Ages.Current : Ages.ForBuilding(selected));
			if (selected.Import != null)
			{
				Ages.Result result = Ages.Adapt(Imports.FreePlan(selected.Import), num);
				if (result.Plan == null)
				{
					Toast(selected.Import.Name + " needs " + Ages.Name(Ages.MinAge(Imports.FreePlan(selected.Import))) + " materials");
					selected = null;
					tool = Tool.None;
					return;
				}
				plan = result.Plan;
				planName = selected.Import.Name + ((result.Swapped + result.Dropped > 0) ? ("  ·  simplified to Age " + Ages.Roman[num] + " materials") : "");
			}
			else
			{
				List<Imports.Choice> list = Imports.Choices(selected, num);
				if (list.Count > 0)
				{
					int num2 = Mathf.Max(1, list.Count((Imports.Choice c) => !c.Simplified));
					variant = (next ? ((variant + 1) % list.Count) : Random.Range(0, num2));
					plan = list[variant].Plan;
					planName = list[variant].Label + "  (" + (variant + 1) + "/" + list.Count + ")";
				}
				else
				{
					plan = HouseGen.Make(selected, Random.Range(1, int.MaxValue));
					planName = "simple " + Ages.Roman[num] + " style";
				}
			}
			ghost = HouseGen.MakeGhost(plan);
			if (selected.Crop != null)
			{
				AddFieldGhost(ghost, plan, selected.FieldSize);
			}
		}

		private static void AddFieldGhost(GameObject root, Blueprint bp, float size)
		{
			//IL_0030: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			Object.Destroy((Object)(object)obj.GetComponent<Collider>());
			obj.transform.SetParent(root.transform, false);
			obj.transform.localScale = new Vector3(size, 0.08f, size);
			obj.transform.localPosition = new Vector3(0f, 0.1f, 0f - (bp.HalfD + size / 2f + 0.5f));
			Shader val = Shader.Find("Sprites/Default");
			Renderer component = obj.GetComponent<Renderer>();
			if ((Object)(object)val != (Object)null && (Object)(object)component != (Object)null)
			{
				component.material = new Material(val);
				component.material.color = new Color(0.95f, 0.78f, 0.3f, 0.35f);
			}
		}

		private void CancelPlacement()
		{
			GridOverlay.Hide();
			selected = null;
			plan = null;
			if ((Object)(object)ghost != (Object)null)
			{
				Object.Destroy((Object)(object)ghost);
			}
			ghost = null;
			if (tool == Tool.Place)
			{
				tool = Tool.None;
			}
		}

		public static GameObject MakeGhost(GameObject prefab)
		{
			//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_0102: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetView), "m_forceDisableInit");
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(null, true);
			}
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(prefab);
			}
			finally
			{
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(null, false);
				}
			}
			((Object)val).name = "AnnoGhost";
			Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Rigidbody[] componentsInChildren2 = val.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren2[i]);
			}
			MonoBehaviour[] componentsInChildren3 = val.GetComponentsInChildren<MonoBehaviour>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Behaviour)componentsInChildren3[i]).enabled = false;
			}
			Renderer[] componentsInChildren4 = val.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Material[] materials = componentsInChildren4[i].materials;
				foreach (Material val2 in materials)
				{
					if (val2.HasProperty("_Color"))
					{
						Color color = val2.color;
						color.a = 0.55f;
						val2.color = color;
					}
				}
			}
			return val;
		}

		private Vector3 Snap(Vector3 p)
		{
			//IL_0025: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.GridOn.Value)
			{
				return p;
			}
			float num = Mathf.Max(0.5f, Plugin.GridSize.Value);
			p.x = Mathf.Round(p.x / num) * num;
			p.z = Mathf.Round(p.z / num) * num;
			p.y = Util.Ground(p);
			return p;
		}

		private void UpdatePlacement()
		{
			//IL_008f: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			if (selected == null)
			{
				tool = Tool.None;
				return;
			}
			if (In.RightDown || In.Pressed((Key)60))
			{
				CancelPlacement();
				return;
			}
			if (In.Pressed((Key)32))
			{
				placeYaw += (Plugin.GridOn.Value ? 90f : 45f);
			}
			if (In.Pressed((Key)34))
			{
				NewPlan(next: true);
			}
			if (!MouseGround(out var p))
			{
				if ((Object)(object)ghost != (Object)null)
				{
					ghost.SetActive(false);
				}
				GridOverlay.Hide();
				return;
			}
			p = Snap(p);
			if (Plugin.GridOn.Value)
			{
				GridOverlay.Show(p, Mathf.Max(0.5f, Plugin.GridSize.Value));
			}
			else
			{
				GridOverlay.Hide();
			}
			Quaternion val = Quaternion.Euler(0f, placeYaw, 0f);
			placePoint = p;
			fogBlocked = !Fog.AreaExplored(p, Mathf.Max(plan.HalfW, plan.HalfD));
			blocked = fogBlocked || Blocked(plan, new Vector3(p.x, HouseGen.TargetHeight(p, val, plan), p.z), val);
			if ((Object)(object)ghost != (Object)null)
			{
				ghost.SetActive(true);
				ghost.transform.SetPositionAndRotation(p, val);
			}
			if (IsGatherer(selected))
			{
				ShowRange(p, selected.Job);
			}
			if (In.LeftDown && !MouseOverUI())
			{
				Place(selected, p, val);
			}
		}

		private static bool Blocked(Blueprint bp, Vector3 c, Quaternion rot)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Mathf.Max(0.5f, bp.HalfW - 1.3f), 1.4f, Mathf.Max(0.5f, bp.HalfD - 1.3f));
			Collider[] array = Physics.OverlapBox(c + Vector3.up * 1.7f, val, rot, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				Piece componentInParent = ((Component)array[i]).GetComponentInParent<Piece>();
				if ((Object)(object)componentInParent != (Object)null && (Object)(object)((Component)componentInParent).GetComponent<ZNetView>() != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private void Place(BDef def, Vector3 pos, Quaternion rot)
		{
			//IL_00ae: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (plan == null)
			{
				return;
			}
			if (fogBlocked)
			{
				Toast("Unexplored land – you can't build in the fog. Send scouts first.");
				return;
			}
			if (blocked)
			{
				Toast("Space occupied – something is already here");
				return;
			}
			Dictionary<string, int> dictionary = Economy.CostOf(def);
			if (!Economy.Has(dictionary))
			{
				Toast("Missing: " + string.Join(", ", (from kv in dictionary
					where Economy.Count(kv.Key) < kv.Value
					select kv.Value - Economy.Count(kv.Key) + " " + Defs.Nice(kv.Key)).ToArray()));
			}
			else
			{
				Economy.Spend(dictionary);
				Vector3 center = default(Vector3);
				((Vector3)(ref center))..ctor(pos.x, HouseGen.TargetHeight(pos, rot, plan), pos.z);
				((MonoBehaviour)this).StartCoroutine(HouseGen.Build(plan, center, rot, def.Name, def, 0, null, def.Import != null));
				Toast(def.Name + ": construction site set up");
				NewPlan(next: false);
			}
		}

		private void SelectRoad(Roads.RDef d)
		{
			SetTool(Tool.None);
			CancelPlacement();
			ClearSelection();
			road = d;
			roadStarted = false;
			tool = Tool.Road;
			Toast(d.Area ? (d.Name + ": click two corners") : (d.Name + ": click start, then end (right click to stop)"));
		}

		private void UpdateRoad()
		{
			//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_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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			if (In.RightDown || In.Pressed((Key)60))
			{
				if (roadStarted)
				{
					roadStarted = false;
					Roads.HidePreview();
				}
				else
				{
					SetTool(Tool.None);
				}
			}
			else
			{
				if (!MouseGround(out var p))
				{
					return;
				}
				p = Roads.Snap(p);
				GridOverlay.Show(p, 2f);
				if (!roadStarted)
				{
					Roads.Preview(new List<Vector3> { p }, road.Area, ok: true);
					hoverText = road.Name + ": " + (road.Area ? "click the first corner" : "click the start point");
					if (In.LeftDown && !MouseOverUI())
					{
						roadStart = p;
						roadStarted = true;
					}
					return;
				}
				List<Vector3> list = (road.Area ? Roads.AreaCells(roadStart, p) : Roads.Route(roadStart, p));
				int num = Roads.Cost(road, list);
				bool flag = road.CostItem == null || Economy.Count(road.CostItem) >= num;
				Roads.Preview(list, road.Area, flag);
				hoverText = road.Name + " – " + (road.Area ? (list.Count + " tiles") : (list.Count * 2 + " m")) + ((num > 0) ? (", " + num + " " + Defs.Nice(road.CostItem)) : "");
				if (!In.LeftDown || MouseOverUI())
				{
					return;
				}
				if (!flag)
				{
					Toast("Missing: " + (num - Economy.Count(road.CostItem)) + " " + Defs.Nice(road.CostItem));
					return;
				}
				Roads.Build(road, list);
				if (num > 0)
				{
					Economy.Spend(road.CostItem, num);
				}
				if (road.Area)
				{
					roadStarted = false;
				}
				else
				{
					roadStart = p;
				}
			}
		}

		private void UpdateDemolish()
		{
			//IL_003a: 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)
			if (In.RightDown || In.Pressed((Key)60))
			{
				SetTool(Tool.None);
				return;
			}
			AnnoBuilding annoBuilding = BuildingUnderMouse();
			GameObject val = null;
			if ((Object)(object)annoBuilding == (Object)null)
			{
				Camera val2 = Cam();
				RaycastHit val3 = default(RaycastHit);
				if ((Object)(object)val2 != (Object)null && Physics.Raycast(val2.ScreenPointToRay(Vector2.op_Implicit(In.MousePos)), ref val3, 800f, -1, (QueryTriggerInteraction)1))
				{
					RoadTile componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<RoadTile>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						val = ((Component)componentInParent).gameObject;
					}
				}
			}
			hoverText = (((Object)(object)annoBuilding != (Object)null) ? ("Demolish: " + annoBuilding.Def.Name) : (((Object)(object)val != (Object)null) ? "Remove road tile" : "Demolish: click a building or road"));
			if (!In.LeftDown || MouseOverUI())
			{
				return;
			}
			if ((Object)(object)annoBuilding != (Object)null)
			{
				Toast(annoBuilding.Def.Name + " demolished (" + HouseGen.Demolish(((Component)annoBuilding).gameObject) + " pieces, half the cost refunded)");
			}
			else if ((Object)(object)val != (Object)null)
			{
				ZNetView component = val.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.ClaimOwnership();
					ZNetScene.instance.Destroy(val);
				}
			}
		}

		private void DemolishSelected()
		{
			int num = 0;
			AnnoBuilding[] array = selBuildings.ToArray();
			foreach (AnnoBuilding annoBuilding in array)
			{
				if ((Object)(object)annoBuilding != (Object)null && annoBuilding.Valid)
				{
					HouseGen.Demolish(((Component)annoBuilding).gameObject);
					num++;
				}
			}
			ClearSelection();
			Toast(num + " buildings demolished");
		}

		private void ClearSelection()
		{
			selTrees.Clear();
			selBuildings.Clear();
			selSoldiers.Clear();
		}

		private AnnoBuilding BuildingUnderMouse()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Camera val = Cam();
			RaycastHit val2 = default(RaycastHit);
			if ((Object)(object)val == (Object)null || !Physics.Raycast(val.ScreenPointToRay(Vector2.op_Implicit(In.MousePos)), ref val2, 800f, -1, (QueryTriggerInteraction)1))
			{
				return null;
			}
			return BuildingOf(((Component)((RaycastHit)(ref val2)).collider).gameObject);
		}

		private static AnnoBuilding BuildingOf(GameObject go)
		{
			AnnoBuilding componentInParent = go.GetComponentInParent<AnnoBuilding>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return Primary(componentInParent);
			}
			ZNetView componentInParent2 = go.GetComponentInParent<ZNetView>();
			if ((Object)(object)componentInParent2 == (Object)null || !componentInParent2.IsValid() || (Object)(object)go.GetComponentInParent<Piece>() == (Object)null)
			{
				return null;
			}
			int g = componentInParent2.GetZDO().GetInt("anno_grp", 0);
			if (g == 0)
			{
				return null;
			}
			return AnnoBuilding.All.FirstOrDefault((AnnoBuilding b) => (Object)(object)b != (Object)null && b.Valid && b.Group == g);
		}

		private static AnnoBuilding Primary(AnnoBuilding b)
		{
			int g = b.Group;
			if (g == 0)
			{
				return b;
			}
			return AnnoBuilding.All.FirstOrDefault((AnnoBuilding x) => (Object)(object)x != (Object)null && x.Valid && x.Group == g) ?? b;
		}

		private static Camera Cam()
		{
			if (!((Object)(object)GameCamera.instance != (Object)null))
			{
				return Camera.main;
			}
			return ((Component)GameCamera.instance).GetComponent<Camera>() ?? Camera.main;
		}

		private void UpdateSelection()
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			selSoldiers.RemoveAll((Soldier s) => (Object)(object)s == (Object)null || !s.Valid);
			if (selSoldiers.Count > 0 && !MouseOverUI())
			{
				Character val = EnemyUnderMouse();
				hoverText = (((Object)(object)val != (Object)null) ? ("Attack: " + Military.NameOf(val)) : "Right click: march here");
				if (In.RightDown)
				{
					Vector3 p;
					if ((Object)(object)val != (Object)null)
					{
						Military.Order(selSoldiers, ((Component)val).transform.position, val);
						OrderMarker(((Component)val).transform.position, attack: true);
					}
					else if (MouseGround(out p))
					{
						Military.Order(selSoldiers, p, null);
						OrderMarker(p, attack: false);
					}
					return;
				}
			}
			if (In.RightDown || In.Pressed((Key)60))
			{
				if (selBuildings.Count == 0 && selTrees.Count == 0)
				{
					tab = null;
					storageOpen = false;
				}
				ClearSelection();
				return;
			}
			if (In.LeftDown && !MouseOverUI())
			{
				dragging = true;
				dragStart = In.MousePos;
			}
			if (dragging && In.LeftUp)
			{
				dragging = false;
				Vector2 mousePos = In.MousePos;
				if (!In.Shift)
				{
					ClearSelection();
				}
				Vector2 val2 = mousePos - dragStart;
				if (((Vector2)(ref val2)).magnitude < 8f)
				{
					ClickSelect();
				}
				else
				{
					BoxSelect(dragStart, mousePos);
				}
			}
		}

		private void ClickSelect()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			Camera val = Cam();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			RaycastHit[] array = Physics.RaycastAll(val.ScreenPointToRay(Vector2.op_Implicit(In.MousePos)), 800f, -1, (QueryTriggerInteraction)2);
			Array.Sort(array, (RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance));
			RaycastHit[] array2 = array;
			for (int num = 0; num < array2.Length; num++)
			{
				RaycastHit val2 = array2[num];
				Soldier componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Soldier>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.Valid)
				{
					SelectSquadOf(componentInParent);
					break;
				}
				GameObject val3 = PlayerWorker.Clearable((Component)(object)((RaycastHit)(ref val2)).collider);
				if (((RaycastHit)(ref val2)).collider.isTrigger && (Object)(object)val3 == (Object)null)
				{
					continue;
				}
				AnnoBuilding annoBuilding = BuildingOf(((Component)((RaycastHit)(ref val2)).collider).gameObject);
				if ((Object)(object)annoBuilding != (Object)null)
				{
					if (selBuildings.Contains(annoBuilding))
					{
						selBuildings.Remove(annoBuilding);
					}
					else
					{
						selBuildings.Add(annoBuilding);
					}
				}
				else if ((Object)(object)val3 != (Object)null)
				{
					Toggle(selTrees, val3);
				}
				break;
			}
		}

		private void SelectSquadOf(Soldier s)
		{
			selBuildings.Clear();
			selTrees.Clear();
			if (!In.Shift)
			{
				selSoldiers.Clear();
			}
			foreach (Soldier item in Military.Squad(s.HutBid))
			{
				if (!selSoldiers.Contains(item))
				{
					selSoldiers.Add(item);
				}
			}
		}

		public void SelectSquad(int bid)
		{
			ClearSelection();
			selSoldiers.AddRange(Military.Squad(bid));
		}

		private Character EnemyUnderMouse()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Camera val = Cam();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			RaycastHit[] array = Physics.RaycastAll(val.ScreenPointToRay(Vector2.op_Implicit(In.MousePos)), 800f, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				Character componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Character>();
				if (Military.Hostile(componentInParent))
				{
					return componentInParent;
				}
			}
			if (!MouseGround(out var p))
			{
				return null;
			}
			Character result = null;
			float num = 3f;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (Military.Hostile(allCharacter))
				{
					Vector3 val3 = ((Component)allCharacter).transform.position - p;
					val3.y = 0f;
					if (((Vector3)(ref val3)).magnitude < num)
					{
						num = ((Vector3)(ref val3)).magnitude;
						result = allCharacter;
					}
				}
			}
			return result;
		}

		private static void OrderMarker(Vector3 c, bool attack)
		{
			//IL_00c8: 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_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_0032: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)orderRing == (Object)null)
			{
				Shader val = Shader.Find("Sprites/Default");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				GameObject val2 = new GameObject("AnnoOrder");
				Object.DontDestroyOnLoad((Object)val2);
				orderRing = val2.AddComponent<LineRenderer>();
				((Renderer)orderRing).sharedMaterial = new Material(val);
				orderRing.useWorldSpace = true;
				orderRing.loop = true;
				orderRing.widthMultiplier = 0.25f;
				((Renderer)orderRing).shadowCastingMode = (ShadowCastingMode)0;
			}
			((Component)orderRing).gameObject.SetActive(true);
			LineRenderer obj = orderRing;
			Color startColor = (orderRing.endColor = (attack ? new Color(1f, 0.4f, 0.3f, 0.9f) : new Color(0.98f, 0.84f, 0.5f, 0.9f)));
			obj.startColor = startColor;
			orderRing.positionCount = 32;
			for (int i = 0; i < 32; i++)
			{
				float num = (float)i * (float)Math.PI * 2f / 32f;
				Vector3 val4 = c + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 1.6f;
				val4.y = Util.Ground(val4) + 0.2f;
				orderRing.SetPosition(i, val4);
			}
			orderUntil = Time.time + 1.2f;
		}

		private static void Toggle(List<GameObject> list, GameObject go)
		{
			if (list.Contains(go))
			{
				list.Remove(go);
			}
			else
			{
				list.Add(go);
			}
		}

		private void BoxSelect(Vector2 a, Vector2 b)
		{
			//IL_0021: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0130: 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_021d: Unknown result type (might be due to invalid IL or missing references)
			Camera cam = Cam();
			if ((Object)(object)cam == (Object)null)
			{
				return;
			}
			Rect r = Rect.MinMaxRect(Mathf.Min(a.x, b.x), Mathf.Min(a.y, b.y), Mathf.Max(a.x, b.x), Mathf.Max(a.y, b.y));
			Func<Vector3, bool> inside = delegate(Vector3 w)
			{
				//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_000c: 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_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val2 = cam.WorldToScreenPoint(w);
				return val2.z > 0f && ((Rect)(ref r)).Contains(new Vector2(val2.x, val2.y));
			};
			List<Soldier> list = Soldier.All.Where((Soldier s) => (Object)(object)s != (Object)null && s.Valid && inside(((Component)s).transform.position + Vector3.up)).ToList();
			if (list.Count > 0)
			{
				selBuildings.Clear();
				selTrees.Clear();
				foreach (Soldier item2 in list)
				{
					if (!selSoldiers.Contains(item2))
					{
						selSoldiers.Add(item2);
					}
				}
				Toast(selSoldiers.Count + " soldiers selected  ·  right click to give orders");
				return;
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			Collider[] array = Physics.OverlapSphere(Focus, Mathf.Max(60f, dist * 1.6f), -1, (QueryTriggerInteraction)2);
			for (int num = 0; num < array.Length; num++)
			{
				GameObject val = PlayerWorker.Clearable((Component)(object)array[num]);
				if ((Object)(object)val != (Object)null && inside(val.transform.position))
				{
					hashSet.Add(val);
				}
			}
			foreach (GameObject item3 in hashSet)
			{
				if (!selTrees.Contains(item3))
				{
					selTrees.Add(item3);
				}
			}
			foreach (AnnoBuilding item4 in AnnoBuilding.All)
			{
				if (!((Object)(object)item4 == (Object)null) && item4.Valid && inside(((Component)item4).transform.position))
				{
					AnnoBuilding item = Primary(item4);
					if (!selBuildings.Contains(item))
					{
						selBuildings.Add(item);
					}
				}
			}
			if (hashSet.Count + selBuildings.Count > 0)
			{
				Toast(hashSet.Count + " objects, " + selBuildings.Count + " buildings selected");
			}
		}

		public static void ClearNotes()
		{
			notes.Clear();
		}

		public static void Toast(string s)
		{
			if (string.IsNullOrEmpty(s) || (!Hints && (s.Contains("WASD") || s.Contains("right click") || s.Contains("click a building"))))
			{
				return;
			}
			Note note = notes.FirstOrDefault((Note n) => n.Text == s);
			if (note != null)
			{
				note.Until = Time.time + 5f;
				return;
			}
			notes.Add(new Note
			{
				Text = s,
				Until = Time.time + 5f
			});
			while (notes.Count > 5)
			{
				notes.RemoveAt(0);
			}
		}

		private Rect Reg(Rect r)
		{
			//IL_0019: 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)
			if (UI.Repaint && UI.Pass == null)
			{
				uiNext.Add(r);
			}
			return r;
		}

		private bool MouseOverUI()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0050: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!Active)
			{
				return false;
			}
			Vector2 val = UI.MouseFromInput();
			foreach (Rect uiRect in uiRects)
			{
				Rect current = uiRect;
				if (((Rect)(ref current)).Contains(val))
				{
					return true;
				}
			}
			Rect windowRect = DevTools.WindowRect;
			return ((Rect)(ref windowRect)).Contains(new Vector2(In.MousePos.x, (float)Screen.height - In.MousePos.y));
		}

		public static bool MouseGround(out Vector3 p)
		{
			//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_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			p = Vector3.zero;
			Camera val = Cam();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			RaycastHit val2 = default(RaycastHit);
			if (!Physics.Raycast(val.ScreenPointToRay(Vector2.op_Implicit(In.MousePos)), ref val2, 800f, Util.GroundMask, (QueryTriggerInteraction)1))
			{
				return false;
			}
			p = ((RaycastHit)(ref val2)).point;
			return true;
		}

		private static string TierItem(int t)
		{
			if (t > 1)
			{
				if (t != 2)
				{
					return "HelmetIron";
				}
				return "HelmetBronze";
			}
			return "HelmetLeather";
		}

		private static string Single(int t)
		{
			return Defs.TierNames[t].TrimEnd('s');
		}

		private static string Ok(bool ok)
		{
			if (!ok)
			{
				return "<color=#ff7a62>!</color>";
			}
			return "<color=#9ee377>OK</color>";
		}

		private static Sprite CatIcon(string c)
		{
			return (Sprite)(c switch
			{
				"Residences" => Icons.Piece("bed"), 
				"Raw Materials" => Icons.Item("AxeStone"), 
				"Production" => Icons.Piece("fermenter") ?? Icons.Item("MeadHealthMinor"), 
				"Roads" => Icons.Piece("paved_road") ?? Icons.Item("Stone"), 
				"Military" => Icons.Item("SpearFlint"), 
				"Public" => Icons.Piece("fire_pit") ?? Icons.Item("Thunderstone"), 
				_ => Icons.Item("Hammer"), 
			});
		}

		private static string BestItem(string[] items)
		{
			string result = items[0];
			int num = 0;
			foreach (string text in items)
			{
				int num2 = Economy.Count(text);
				if (num2 > num)
				{
					num = num2;
					result = text;
				}
			}
			return result;
		}

		private static string Breakdown(string[] items)
		{
			return string.Join("\n", (from i in items
				select new KeyValuePair<string, int>(i, Economy.Count(i)) into kv
				orderby kv.Value descending
				select "<color=" + ((kv.Value > 0) ? "#9ee377" : "#b3b0a3") + ">•  " + Defs.Nice(kv.Key) + "  " + kv.Value + "</color>").ToArray());
		}

		private static string MadeBy(string[] items)
		{
			string[] array = (from d in Defs.All
				where d.Out.Keys.Any(((IEnumerable<string>)items).Contains<string>) || Gathers(d).Any(((IEnumerable<string>)items).Contains<string>)
				select d.Name).Distinct().ToArray();
			if (array.Length != 0)
			{
				return string.Join(", ", array);
			}
			return null;
		}

		private static string[] Gathers(BDef d)
		{
			switch (d.Job)
			{
			case Job.Holz:
				return new string[1] { "Wood" };
			case Job.Stein:
				return new string[1] { "Stone" };
			case Job.Sammeln:
				return new string[3] { "Raspberry", "Mushroom", "Flint" };
			case Job.Jagd:
				return new string[2] { "RawMeat", "DeerHide" };
			case Job.Farm:
				if (d.CropItem == null)
				{
					return new string[0];
				}
				return new string[1] { d.CropItem };
			default:
				return new string[0];
			}
		}

		private static string RichWord(float r)
		{
			if (!(r >= 30f))
			{
				if (!(r >= 18f))
				{
					if (!(r >= 8f))
					{
						return "Poor";
					}
					return "Decent";
				}
				return "Rich";
			}
			return "Very rich";
		}

		private static string NearbyWord(Job j)
		{
			return j switch
			{
				Job.Holz => "trees", 
				Job.Stein => "rocks", 
				Job.Sammeln => "bushes & pickables", 
				Job.Jagd => "animals", 
				_ => "resources", 
			};
		}

		private static void Name(string n, Rect r)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (UI.Repaint)
			{
				if (UI.Pass != null)
				{
					UI.Pass.Named[n] = r;
				}
				else
				{
					Named[n] = r;
				}
			}
		}

		private void OnGUI()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!InGame || Plugin.UiHidden)
			{
				return;
			}
			DrawUi(null);
			if ((int)Event.current.type != 7 || Rigs.All.Count <= 0)
			{
				return;
			}
			foreach (Rig item in Rigs.All)
			{
				if ((Object)(object)item.RT == (Object)null)
				{
					continue;
				}
				try
				{
					if (item.Ui)
					{
						DrawUi(item);
					}
					if (item.Cursor)
					{
						UI.Begin(item);
						GUI.matrix *= Matrix4x4.Scale(new Vector3(1f / UI.S, 1f / UI.S, 1f));
						VCursor.DrawFor(item);
						UI.End(item);
					}
				}
				catch (Exception ex)
				{
					UI.End(item);
					Plugin.Warn("Rig-Oberflaeche: " + ex.Message);
				}
			}
		}

		private void DrawUi(Rig rig)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			UI.Begin(rig);
			bool flag = rig == null;
			if (flag && UI.Repaint)
			{
				uiNext.Clear();
			}
			tip = null;
			tipDef = null;
			if (!Active)
			{
				Rect r = default(Rect);
				((Rect)(ref r))..ctor(14f, UI.Portrait ? 58f : 10f, 330f, 30f);
				UI.PlateBox(r);
				UI.Text(new Rect(((Rect)(ref r)).x + 12f, ((Rect)(ref r)).y, ((Rect)(ref r)).width - 20f, ((Rect)(ref r)).height), "<color=#f5d07a>" + ((object)Plugin.ToggleKey.Value/*cast due to .constrained prefix*/).ToString() + "</color>  City view       <color=#f5d07a>F8</color>  Dev tools", UI.Small);
				DrawNotes(active: false);
				if (flag && UI.Repaint)
				{
					uiRects.Clear();
				}
				UI.End(rig);
				return;
			}
			DrawWorldLabels();
			if (flag)
			{
				DrawSelectionBox();
			}
			DrawTopBar();
			if (!UI.Portrait)
			{
				DrawMinimap();
			}
			DrawBuildBar();
			DrawPanel();
			DrawPastePanel();
			DrawWorldWindows();
			DrawNotes(active: true);
			if (!UI.Portrait)
			{
				DrawHints();
			}
			DrawCursorTip();
			DrawTooltip();
			if (flag)
			{
				uiTyping = GUIUtility.keyboardControl != 0 && tab == "Blueprints";
				if (UI.Repaint)
				{
					uiRects.Clear();
					uiRects.AddRange(uiNext);
				}
			}
			UI.End(rig);
		}

		private void DrawTopBar()
		{
			//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_0029: 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_0050: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_071f: 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_0771: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_0661: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			if (!UI.Portrait)
			{
				Rect r = Reg(new Rect(18f, 12f, 280f, 84f));
				UI.Frame(r);
				UI.TextShadow(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 5f, ((Rect)(ref r)).width, 26f), Flat.WorldName ?? "Settlement", UI.HeadC);
				UI.Text(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 29f, ((Rect)(ref r)).width, 16f), "<color=#f5d07a>" + Ages.Name(Ages.Current) + "</color>", UI.TinyC);
				if (UI.Hover(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, 46f)))
				{
					tip = "<b>" + Ages.Name(Ages.Current) + "</b>\nNew buildings use the materials of this age. Each defeated boss opens the next age.\n" + BossAltar.Hint();
				}
				float x = ((Rect)(ref r)).x + 18f;
				x = QuickGood(x, ((Rect)(ref r)).y + 53f, "Wood");
				x = QuickGood(x, ((Rect)(ref r)).y + 53f, "Stone");
				if (UI.Button(new Rect(((Rect)(ref r)).xMax - 92f, ((Rect)(ref r)).y + 52f, 78f, 22f), storageOpen ? "Close" : "Storage"))
				{
					storageOpen = !storageOpen;
				}
				if (storageOpen)
				{
					DrawStorage(((Rect)(ref r)).x, ((Rect)(ref r)).yMax + 14f);
				}
			}
			List<int> list = (from t in Enumerable.Range(1, 3)
				where t == 1 || Economy.Capacity(t) > 0
				select t).ToList();
			bool flag = HouseGen.Sites.Count > 0;
			float num = 379f + (float)list.Count * 150f + (flag ? 90f : 0f) + 120f;
			Rect val = Reg(new Rect((UI.W - num) / 2f, UI.Portrait ? PortraitTopY : 10f, num, 54f));
			Name("topbar", val);
			UI.Frame(val);
			float num2 = ((Rect)(ref val)).x + 24f;
			float num3 = ((Rect)(ref val)).y + 10f;
			Rect r2 = default(Rect);
			((Rect)(ref r2))..ctor(num2, num3, 165f, 34f);
			UI.Icon(new Rect(num2, num3, 34f, 34f), Icons.Item("Coins"));
			UI.Text(new Rect