Decompiled source of World Edit v1.9.2

plugins/WorldEdit.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
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 Splatform;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.PostProcessing;
using UnityEngine.Rendering;
using UnityEngine.UI;

[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;
			}
			if (d.OwnLook)
			{
				return 6;
			}
			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 static class Alliance
	{
		public const string Rpc = "AnnoAlly";

		public const float HelpEvery = 120f;

		public const float HelpRange = 2600f;

		public const int HelpFrom = 2;

		private static readonly List<long> members = new List<long>();

		private static float membersT;

		private static readonly HashSet<int> clans = new HashSet<int>();

		private static float clansT;

		public static readonly Color OwnBorder = new Color(1f, 0.82f, 0.35f, 0.85f);

		public static readonly Color AllyBorder = new Color(0.45f, 0.95f, 0.5f, 0.85f);

		public static readonly Color WarBorder = new Color(1f, 0.35f, 0.3f, 0.85f);

		public static readonly Color OtherBorder = new Color(0.8f, 0.8f, 0.78f, 0.6f);

		private static float watchT;

		private static float sentT;

		private static float askedT;

		public static string LastCall = "";

		public static string Name
		{
			get
			{
				string text = ((AnnoWorld.Data != null) ? AnnoWorld.Data.AllianceName : null);
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
				return "Your alliance";
			}
		}

		public static bool HasName
		{
			get
			{
				if (AnnoWorld.Data != null)
				{
					return !string.IsNullOrEmpty(AnnoWorld.Data.AllianceName);
				}
				return false;
			}
		}

		public static bool Any => Members().Count > 1;

		public static void Rename(string name)
		{
			if (AnnoWorld.Data != null)
			{
				AnnoWorld.Data.AllianceName = (name ?? "").Trim();
				AnnoWorld.Data.AllianceNameAt = Diplo.Now;
				AnnoWorld.Save();
			}
		}

		public static void Adopt(Peers.Info i)
		{
			if (i != null && AnnoWorld.Data != null && !string.IsNullOrEmpty(i.Alliance) && In(i.Colony) && !(i.AllianceAt <= AnnoWorld.Data.AllianceNameAt))
			{
				AnnoWorld.Data.AllianceName = i.Alliance;
				AnnoWorld.Data.AllianceNameAt = i.AllianceAt;
				AnnoMode.Toast("Your alliance is now called " + i.Alliance);
				AnnoWorld.Save();
			}
		}

		private static bool Linked(long a, long b)
		{
			if (a == b)
			{
				return false;
			}
			if (Diplo.StanceOf(a, b) == Diplo.Stance.Ally)
			{
				return Diplo.StanceOf(b, a) == Diplo.Stance.Ally;
			}
			return false;
		}

		public static List<long> Members()
		{
			if (Time.time < membersT)
			{
				return members;
			}
			membersT = Time.time + 1f;
			members.Clear();
			members.Add(Col.Me);
			for (int i = 0; i < members.Count; i++)
			{
				long num = members[i];
				foreach (Peers.Info value in Peers.All.Values)
				{
					if (value != null && value.Colony != num && !members.Contains(value.Colony) && Linked(num, value.Colony))
					{
						members.Add(value.Colony);
					}
				}
			}
			return members;
		}

		public static bool In(long c)
		{
			return Members().Contains(c);
		}

		public static List<Peers.Info> Others()
		{
			return (from i in (from c in Members()
					where c != Col.Me
					select c).Select(Peers.Of)
				where i != null
				select i).ToList();
		}

		public static List<int> MyClans()
		{
			if (AnnoWorld.Data == null)
			{
				return new List<int>();
			}
			return (from s in AnnoWorld.Data.Sites
				where s != null && s.Status == 2
				select s.Id).ToList();
		}

		public static HashSet<int> Clans()
		{
			if (Time.time < clansT)
			{
				return clans;
			}
			clansT = Time.time + 1f;
			clans.Clear();
			foreach (int item in MyClans())
			{
				clans.Add(item);
			}
			foreach (Peers.Info item2 in Others())
			{
				if (item2.Clans == null)
				{
					continue;
				}
				foreach (int clan in item2.Clans)
				{
					clans.Add(clan);
				}
			}
			return clans;
		}

		public static bool ClanAllied(int siteId)
		{
			if (siteId == 0)
			{
				return false;
			}
			return Clans().Contains(siteId);
		}

		public static string ClanBy(int siteId)
		{
			if (MyClans().Contains(siteId))
			{
				return "you";
			}
			foreach (Peers.Info item in Others())
			{
				if (item.Clans != null && item.Clans.Contains(siteId))
				{
					return item.Owner;
				}
			}
			return "an ally";
		}

		public static void WriteHello(ZPackage p)
		{
			p.Write((AnnoWorld.Data != null) ? (AnnoWorld.Data.AllianceName ?? "") : "");
			p.Write((AnnoWorld.Data != null) ? ((long)(AnnoWorld.Data.AllianceNameAt * 1000.0)) : 0);
			List<int> list = MyClans();
			p.Write(list.Count);
			foreach (int item in list)
			{
				p.Write(item);
			}
		}

		public static void ReadHello(Peers.Info i, ZPackage p)
		{
			i.Alliance = p.ReadString();
			i.AllianceAt = (double)p.ReadLong() / 1000.0;
			int num = p.ReadInt();
			i.Clans = new List<int>();
			for (int j = 0; j < num; j++)
			{
				i.Clans.Add(p.ReadInt());
			}
		}

		public static Color BorderColor(long c)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (c == Col.Me)
			{
				return OwnBorder;
			}
			if (Diplo.AtWar(Col.Me, c) || Diplo.WarComing(Col.Me, c))
			{
				return WarBorder;
			}
			if (In(c) || Town.Friendly(c))
			{
				return AllyBorder;
			}
			return OtherBorder;
		}

		public static float RadiusOf(float r)
		{
			return Mathf.Clamp(r + 60f, 50f, 400f);
		}

		public static void ShowBorders()
		{
			//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_004a: 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_005c: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if (!Col.Multi || Peers.All.Count == 0 || Plugin.Borders == null || !Plugin.Borders.Value)
			{
				return;
			}
			Vector3 home = AnnoWorld.Home;
			float num = 0f;
			foreach (Ledger.Entry building in Ledger.Buildings)
			{
				float num2 = num;
				Vector2 val = new Vector2(building.Pos.x - home.x, building.Pos.z - home.z);
				num = Mathf.Max(num2, ((Vector2)(ref val)).magnitude);
			}
			if (num > 0f)
			{
				RangeRings.Show(new Vector3(home.x, 0f, home.z), RadiusOf(num), OwnBorder);
			}
			foreach (Peers.Info value in Peers.All.Values)
			{
				if (value != null && value.Colony != Col.Me && value.Buildings != 0)
				{
					Vector3 val2 = value.Home - home;
					if (!(((Vector3)(ref val2)).magnitude > 1200f))
					{
						RangeRings.Show(value.Home, RadiusOf(value.Radius), BorderColor(value.Colony));
					}
				}
			}
			Features.Use("mp.borders");
		}

		public static void Watch()
		{
			if (!Any || ZRoutedRpc.instance == null || Time.time < watchT)
			{
				return;
			}
			watchT = Time.time + 10f;
			if (!(Time.time < sentT))
			{
				int count = Defense.RaidersInTown().Count;
				if (count >= 2)
				{
					sentT = Time.time + 120f;
					Call(count);
				}
			}
		}

		public static void Call(int enemies)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (ZRoutedRpc.instance == null)
			{
				return;
			}
			Vector3 home = AnnoWorld.Home;
			int num = 0;
			foreach (Peers.Info item in Others())
			{
				if (item.Online)
				{
					try
					{
						ZPackage val = new ZPackage();
						val.Write(1);
						val.Write(Col.Me);
						val.Write(Peers.ColonyName());
						val.Write(enemies);
						val.Write(home.x);
						val.Write(home.z);
						ZRoutedRpc.instance.InvokeRoutedRPC(item.Peer, "AnnoAlly", new object[1] { val });
						num++;
					}
					catch (Exception ex)
					{
						Plugin.Warn("[MP] Hilferuf senden: " + ex.Message);
					}
				}
			}
			AnnoMode.Toast((num > 0) ? ("Your alliance has been called for help (" + num + ")") : "Nobody in your alliance is online");
			if (num > 0)
			{
				Features.Use("mp.ally_help");
			}
		}

		public static void OnRpc(long sender, ZPackage p)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				p.ReadInt();
				long c = p.ReadLong();
				string name = p.ReadString();
				int num = p.ReadInt();
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(p.ReadSingle(), 0f, p.ReadSingle());
				if (c == Col.Me || !In(c))
				{
					return;
				}
				Vector3 val2 = val - AnnoWorld.Home;
				if (!(((Vector3)(ref val2)).magnitude > 2600f) && !(Time.time < askedT))
				{
					askedT = Time.time + 30f;
					LastCall = name + " (" + num + ")";
					AnnoMode.Notify(name + " is under attack by " + num + " enemies and calls " + Name + " for help!", "Send squads", delegate
					{
						AnnoMode.Toast(Diplo.MarchToTown(c) ?? ("Your squads march to help " + name));
					});
					Features.Use("mp.ally_help");
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("[MP] Hilferuf: " + ex.Message);
			}
		}
	}
	public class AnnoMode : MonoBehaviour
	{
		private enum Tool
		{
			None,
			Place,
			Road,
			Demolish,
			Paste,
			CopyArea,
			Wall,
			Zone,
			Brush,
			Editor
		}

		private class PendingBuild
		{
			public BDef Def;

			public Blueprint Plan;

			public Vector3 Pos;

			public Quaternion Rot;

			public float Coast;

			public List<ZDOID> Ids;

			public WorldSave World;

			public GameObject Ghost;

			public float ClearAt;
		}

		private class Note
		{
			public string Text;

			public float Until;

			public string Label;

			public Action Act;
		}

		private class LabelInfo
		{
			public float Until;

			public int Group;

			public string Problem;
		}

		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 class CoPeer
		{
			public long Id;

			public string Name = "";

			public string Tool = "";

			public string Act = "";

			public int ActN = -1;

			public float ActT = -99f;

			public float Seen;

			public bool On;

			public bool HasCur;

			public bool Square;

			public bool Busy;

			public bool HasGhost;

			public Vector3 Cur;

			public Vector3 Focus;

			public Vector3 Show;

			public float R;

			public float Ang;

			public Bounds Ghost;

			public readonly List<Bounds> Boxes = new List<Bounds>();

			public Color Col;

			public LineRenderer Ring;

			public LineRenderer GhostLR;

			public readonly List<LineRenderer> BoxLR = new List<LineRenderer>();
		}

		public class CrForm
		{
			public string Id = "";

			public string Kind = "Hill";

			public string Shape = "Circle";

			public List<Vector3> Pts = new List<Vector3>();

			public float H = 20f;

			public float W = 8f;

			public float A;

			private List<Vector3> path;

			private static readonly CultureInfo CI = CultureInfo.InvariantCulture;

			public List<Vector3> Path
			{
				get
				{
					if (path == null)
					{
						path = ((Shape == "Line" && Pts.Count >= 3) ? CrCurve(Pts) : new List<Vector3>(Pts));
					}
					return path;
				}
			}

			public Vector3 Center
			{
				get
				{
					//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_0019: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Unknown result type (might be due to invalid IL or missing references)
					//IL_003c: Unknown result type (might be due to invalid IL or missing references)
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					//IL_005c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0069: Unknown result type (might be due to invalid IL or missing references)
					if (Shape == "Circle")
					{
						return Pts[0];
					}
					Vector3 val = Vector3.zero;
					foreach (Vector3 pt in Pts)
					{
						val += pt;
					}
					return val / (float)Pts.Count;
				}
			}

			public float Radius
			{
				get
				{
					//IL_0024: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					if (!(Shape == "Circle"))
					{
						return 0f;
					}
					return Mathf.Max(2f, FlatDist(Pts[1] - Pts[0]));
				}
			}

			public Rect Bounds
			{
				get
				{
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_0049: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Unknown result type (might be due to invalid IL or missing references)
					//IL_006a: Unknown result type (might be due to invalid IL or missing references)
					//IL_013d: Unknown result type (might be due to invalid IL or missing references)
					//IL_021f: Unknown result type (might be due to invalid IL or missing references)
					if (Shape == "Circle")
					{
						float radius = Radius;
						return Rect.MinMaxRect(Pts[0].x - radius, Pts[0].z - radius, Pts[0].x + radius, Pts[0].z + radius);
					}
					if (Shape == "Rect")
					{
						List<Vector3> source = RectCorners();
						return Rect.MinMaxRect(source.Min((Vector3 p) => p.x) - 1f, source.Min((Vector3 p) => p.z) - 1f, source.Max((Vector3 p) => p.x) + 1f, source.Max((Vector3 p) => p.z) + 1f);
					}
					float num = Pts.Min((Vector3 p) => p.x);
					float num2 = Pts.Min((Vector3 p) => p.z);
					float num3 = Pts.Max((Vector3 p) => p.x);
					float num4 = Pts.Max((Vector3 p) => p.z);
					float num5 = ((Shape == "Line") ? (W + 2f) : 1f);
					return Rect.MinMaxRect(num - num5, num2 - num5, num3 + num5, num4 + num5);
				}
			}

			public string Ser()
			{
				return "F|" + Kind + "|" + Shape + "|" + H.ToString("0.##", CI) + "|" + W.ToString("0.##", CI) + "|" + string.Join(";", Pts.Select((Vector3 p) => p.x.ToString("0.#", CI) + "," + p.z.ToString("0.#", CI)).ToArray()) + ((Shape == "Rect" && Mathf.Abs(A) > 0.01f) ? ("|" + A.ToString("0.#", CI)) : "");
			}

			public void RectFrame(out Vector3 c, out float hx, out float hz)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: 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)
				c = (Pts[0] + Pts[1]) * 0.5f;
				Vector3 val = Quaternion.Euler(0f, 0f - A, 0f) * (Pts[1] - Pts[0]);
				hx = Mathf.Max(1f, Mathf.Abs(val.x) * 0.5f);
				hz = Mathf.Max(1f, Mathf.Abs(val.z) * 0.5f);
			}

			public List<Vector3> RectCorners()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: 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_0052: 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_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_007a: 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_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: 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)
				RectFrame(out var c, out var hx, out var hz);
				Quaternion val = Quaternion.Euler(0f, A, 0f);
				return new List<Vector3>
				{
					c + val * new Vector3(0f - hx, 0f, 0f - hz),
					c + val * new Vector3(hx, 0f, 0f - hz),
					c + val * new Vector3(hx, 0f, hz),
					c + val * new Vector3(0f - hx, 0f, hz)
				};
			}

			public static CrForm Parse(string id, string s)
			{
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				if (string.IsNullOrEmpty(s))
				{
					return null;
				}
				string[] array = s.Split('|');
				if (array.Length < 6 || array[0] != "F")
				{
					return null;
				}
				CrForm crForm = new CrForm
				{
					Id = id,
					Kind = array[1],
					Shape = array[2]
				};
				float.TryParse(array[3], NumberStyles.Float, CI, out crForm.H);
				float.TryParse(array[4], NumberStyles.Float, CI, out crForm.W);
				string[] array2 = array[5].Split(';');
				for (int i = 0; i < array2.Length; i++)
				{
					string[] array3 = array2[i].Split(',');
					if (array3.Length == 2 && float.TryParse(array3[0], NumberStyles.Float, CI, out var result) && float.TryParse(array3[1], NumberStyles.Float, CI, out var result2))
					{
						crForm.Pts.Add(new Vector3(result, 0f, result2));
					}
				}
				if (array.Length > 6)
				{
					float.TryParse(array[6], NumberStyles.Float, CI, out crForm.A);
				}
				if (crForm.Pts.Count < 2)
				{
					return null;
				}
				return crForm;
			}

			public CrForm Clone()
			{
				return new CrForm
				{
					Id = Id,
					Kind = Kind,
					Shape = Shape,
					H = H,
					W = W,
					A = A,
					Pts = new List<Vector3>(Pts)
				};
			}

			public void Dirty()
			{
				path = null;
			}
		}

		private class CrUnit
		{
			public string Group;

			public string Name;

			public readonly List<GameObject> Objs = new List<GameObject>();

			public readonly List<ZDOID> Ids = new List<ZDOID>();

			public Bounds B;

			public LineRenderer LR;
		}

		private class CrTool
		{
			public string Cat;

			public string Name;

			public string Group;

			public string Tip;

			public string Bundle;

			public Ed E;

			public Ed[] Eds;

			public Ed? Ic;
		}

		private class CrLineType
		{
			public string Name;

			public string Prefab;

			public string Gate;

			public string Tip;

			public string Paint;

			public string Rail;

			public string Pillar;

			public float DeckTop;

			public float DeckSize = 2f;

			public float PillarLen = 4f;

			public float SagDefault;

			public string Group = "Fences";

			public string Kind = "seg";

			public float Len = 2f;

			public float Off;

			public float Base;

			public float RowH;

			public float GateOff;

			public float GateBase;

			public bool Fixed;

			public string[] Veg;

			public bool Available
			{
				get
				{
					if (Kind == "path")
					{
						if (Prefab == null)
						{
							return true;
						}
						ZNetScene instance = ZNetScene.instance;
						if ((Object)(object)instance != (Object)null)
						{
							return (Object)(object)instance.GetPrefab(Prefab) != (Object)null;
						}
						return false;
					}
					if (Kind == "bridge")
					{
						ZNetScene instance2 = ZNetScene.instance;
						if ((Object)(object)instance2 != (Object)null)
						{
							return (Object)(object)instance2.GetPrefab(Prefab) != (Object)null;
						}
						return false;
					}
					ZNetScene zs = ZNetScene.instance;
					if ((Object)(object)zs == (Object)null)
					{
						return false;
					}
					if (Kind == "veg")
					{
						if (Veg != null)
						{
							return Veg.Any((string v) => (Object)(object)zs.GetPrefab(v) != (Object)null);
						}
						return false;
					}
					return (Object)(object)zs.GetPrefab(Prefab) != (Object)null;
				}
			}
		}

		public class CrLineDef
		{
			public string Id = "";

			public string Type = "Wood fence";

			public string Sides = "Line";

			public bool Curve = true;

			public float Width = 3f;

			public float Spacing = 6f;

			public int Rows = 1;

			public int Gap;

			public float Sag = float.NaN;

			public int Hill;

			public List<Vector3> Pts = new List<Vector3>();

			private static readonly CultureInfo CI = CultureInfo.InvariantCulture;

			public string Ser()
			{
				//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_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				StringBuilder stringBuilder = new StringBuilder("1|");
				stringBuilder.Append(Type).Append('|').Append(Sides)
					.Append('|')
					.Append(Curve ? 1 : 0)
					.Append('|')
					.Append(Width.ToString("0.##", CI))
					.Append('|')
					.Append(Spacing.ToString("0.##", CI))
					.Append('|')
					.Append(Rows)
					.Append('|')
					.Append(Gap)
					.Append('|');
				for (int i = 0; i < Pts.Count; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append(';');
					}
					stringBuilder.Append(Pts[i].x.ToString("0.##", CI)).Append(',').Append(Pts[i].z.ToString("0.##", CI));
				}
				if (!float.IsNaN(Sag) || Hill != 0)
				{
					stringBuilder.Append('|').Append(float.IsNaN(Sag) ? "" : Sag.ToString("0.##", CI));
				}
				if (Hill != 0)
				{
					stringBuilder.Append('|').Append(Hill);
				}
				return stringBuilder.ToString();
			}

			public static CrLineDef Parse(string id, string s)
			{
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				if (string.IsNullOrEmpty(s))
				{
					return null;
				}
				string[] array = s.Split('|');
				if (array.Length < 9 || array[0] != "1")
				{
					return null;
				}
				CrLineDef crLineDef = new CrLineDef
				{
					Id = id,
					Type = array[1],
					Sides = array[2],
					Curve = (array[3] == "1")
				};
				NumberStyles style = NumberStyles.Float;
				float.TryParse(array[4], style, CI, out crLineDef.Width);
				float.TryParse(array[5], style, CI, out crLineDef.Spacing);
				int.TryParse(array[6], out crLineDef.Rows);
				int.TryParse(array[7], out crLineDef.Gap);
				if (array.Length > 9 && array[9].Length > 0 && float.TryParse(array[9], style, CI, out var result))
				{
					crLineDef.Sag = result;
				}
				if (array.Length > 10)
				{
					int.TryParse(array[10], out crLineDef.Hill);
				}
				string[] array2 = array[8].Split(';');
				for (int i = 0; i < array2.Length; i++)
				{
					string[] array3 = array2[i].Split(',');
					if (array3.Length == 2 && float.TryParse(array3[0], style, CI, out var result2) && float.TryParse(array3[1], style, CI, out var result3))
					{
						crLineDef.Pts.Add(new Vector3(result2, 0f, result3));
					}
				}
				if (crLineDef.Pts.Count < 2)
				{
					return null;
				}
				return crLineDef;
			}
		}

		public class CrVegItem
		{
			public string Prefab = "";

			public float W = 1f;
		}

		public class CrVegPreset
		{
			public string Name = "";

			public List<CrVegItem> Items = new List<CrVegItem>();

			public float Density = 1f;

			public float Spacing = 3.5f;

			public float ScaleMin = 0.85f;

			public float ScaleMax = 1.2f;

			public float MaxSlope = 40f;

			public bool Builtin;

			public bool Modified;
		}

		public class CrPresetFile
		{
			public List<CrVegPreset> Presets = new List<CrVegPreset>();
		}

		public enum BrushMode
		{
			Raise,
			Lower,
			Smooth,
			Flatten
		}

		public enum Ed
		{
			Raise,
			Lower,
			Smooth,
			Flatten,
			Roughen,
			Terrace,
			Peak,
			Clear,
			Forest,
			Rocks,
			Paint,
			Select,
			Line,
			Fence,
			Veg,
			River,
			House,
			Road,
			Lake,
			Piece,
			Pick,
			Eyedrop,
			Biome,
			Form,
			Sea
		}

		private struct Removed
		{
			public string Prefab;

			public Vector3 Pos;

			public Quaternion Rot;

			public Vector3 Scale;

			public long Creator;

			public string Line;

			public string Def;

			public string Auto;

			public string Deco;

			public string Bp;

			public string Link;

			public float BpYaw;

			public bool Tun;

			public bool Hold;

			public ZDOID Was;
		}

		private struct KeyVal
		{
			public ZDOID Id;

			public string Key;

			public string Old;

			public int OldI;

			public bool IsInt;
		}

		private class PieceSnap
		{
			public ZDOID Id;

			public Removed R;
		}

		private class PaintSnap
		{
			public TerrainComp TC;

			public Heightmap HM;

			public Color[] Mask;

			public bool[] Mod;
		}

		private class EdStep
		{
			public string What;

			public readonly Dictionary<long, float> H = new Dictionary<long, float>();

			public readonly List<Removed> Gone = new List<Removed>();

			public readonly List<ZDOID> Made = new List<ZDOID>();

			public readonly List<PaintSnap> Paint = new List<PaintSnap>();

			public readonly List<PieceSnap> Pieces = new List<PieceSnap>();

			public readonly HashSet<ZDOID> PieceIds = new HashSet<ZDOID>();

			public readonly Dictionary<Vector2s, string> Water = new Dictionary<Vector2s, string>();

			public readonly Dictionary<Vector2s, string> Lines = new Dictionary<Vector2s, string>();

			public readonly HashSet<string> Adapted = new HashSet<string>();

			public readonly Dictionary<Vector2s, string> Holes = new Dictionary<Vector2s, string>();

			public readonly Dictionary<Vector2s, string> Dry = new Dictionary<Vector2s, string>();

			public readonly List<KeyVal> KV = new List<KeyVal>();

			public readonly List<string> GKAdd = new List<string>();

			public readonly List<string> GKDel = new List<string>();

			public bool Empty
			{
				get
				{
					if (H.Count == 0 && Gone.Count == 0 && Made.Count == 0 && Paint.Count == 0 && Water.Count == 0 && Lines.Count == 0 && Holes.Count == 0 && Dry.Count == 0 && KV.Count == 0 && GKAdd.Count == 0)
					{
						return GKDel.Count == 0;
					}
					return false;
				}
			}
		}

		private class TerrainClip
		{
			public int W;

			public int D;

			public float[] H;

			public readonly List<Removed> Veg = new List<Removed>();
		}

		private bool allianceOn;

		private string allyEdit;

		private string townEdit;

		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 AnnoBuilding hoverBuilding;

		private Tool tool;

		private BDef selected;

		private float placeYaw;

		private float rotHeld;

		private GameObject ghost;

		private Blueprint plan;

		private string planName;

		private int variant;

		private bool blocked;

		private bool fogBlocked;

		private Vector3 placePoint;

		private List<Blockers.Hit> blockHits;

		private readonly List<PendingBuild> pendingBuilds = new List<PendingBuild>();

		private Roads.RDef road;

		private bool roadStarted;

		private List<Vector3> levelCells;

		private float levelY;

		private float levelMid;

		private float levelLo;

		private float levelHi;

		private int levelSkipped;

		private Vector3 roadStart;

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

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

		private readonly HashSet<string> skipKinds = new HashSet<string>();

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

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

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

		private bool patrolPick;

		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 worldKeyT = 2f;

		private static float dayTimer;

		private static Vector3 vikingHome;

		private static Quaternion vikingRot;

		private static bool haveVikingHome;

		private static float savedFixed = -1f;

		private static float ourFixed = -1f;

		private static readonly FieldInfo fiMaxAir = AccessTools.Field(typeof(Character), "m_maxAirAltitude");

		public static float NoFallUntil;

		private const float HeldRange = 150f;

		private static float camLift;

		private static float anchorT;

		private static bool anchorOk;

		private static Vector3 anchorPos = Vector3.positiveInfinity;

		private static bool flatTipShown;

		private Vector3 loadWaitAt = Vector3.positiveInfinity;

		private float loadWaitT;

		private float freeMissingT;

		private bool selViking;

		private static string foreignHover;

		private ZDO scoutClickZ;

		private float scoutClickT;

		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[8] { "Residences", "Raw Materials", "Production", "Public", "Military", "Harbor", "Roads", "Blueprints" };

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

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

		public static bool Hints = true;

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

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

		private static int terrainMask;

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

		public static float PortraitBarY = 0.8f;

		public static float PortraitTopY = 96f;

		private int storageTab;

		private int storagePage;

		private const int OtherPage = 25;

		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 int dismissArm;

		private float dismissT;

		private ZDO soldierDismiss;

		private float soldierDismissT;

		private const float SelRowH = 30f;

		private const int SelMaxRows = 8;

		private Vector2 selScroll;

		private Rect mapRect;

		private static Texture2D heartTex;

		private static Texture2D bubbleTex;

		private static readonly Dictionary<AnnoBuilding, LabelInfo> labelInfo = new Dictionary<AnnoBuilding, LabelInfo>();

		private static float labelPrune;

		private const float SquadBannerRange = 300f;

		private const float SquadBannerHeight = 3.4f;

		private static readonly Color SquadColor = new Color(0.78f, 0.25f, 0.2f);

		private static readonly Color HeroColor = new Color(0.62f, 0.42f, 0.86f);

		public static readonly Biome[] CrBiomes;

		private static readonly string[] CrBiomeNames;

		private Biome crBiome = (Biome)16;

		private bool crBiomeVeg = true;

		private bool crBiomeDrag;

		private Vector3 crBiomeA;

		public static bool BpbOpen;

		public static string BpbTab;

		private string bpbSearch = "";

		private string bpbSource;

		private string vhSearchField = "";

		private Vector2 bpbScroll;

		private bool bpbTyping;

		private int bpbSize;

		private int bpbSort;

		private const int SmallPieces = 40;

		private static Color DarkFill;

		private static readonly string[][] VhOrders;

		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 bool zoneStarted;

		private Vector3 zoneStart;

		private Rect zoneRect;

		private bool zoneOk;

		private float zoneH;

		private string zoneWhy;

		private static Material ghostMat;

		private static LineRenderer ring;

		private bool ringWanted;

		private float rangeT;

		private int rangeCount;

		private int rangeFine;

		private int rangeCore;

		private Vector3 rangeAt = Vector3.positiveInfinity;

		private string rangeNote;

		private HuntGrounds.Info huntInfo;

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

		private List<Levels.Spot> upgradeSpots = new List<Levels.Spot>();

		private AnnoBuilding upgradeGhostFor;

		private float upgradeGhostSeen;

		private float upgradeGhostT;

		public const string CoRpc = "WorldEditPresence";

		private const int CoVer = 1;

		public static readonly Dictionary<long, CoPeer> CoPeers;

		private static ZRoutedRpc coRegOn;

		private static float coSendT;

		private static float coBeatT;

		private static bool coSentOn;

		private static string coLastSig;

		private static string coAct;

		private static int coActN;

		private static readonly Color[] CoPal;

		private static readonly string[] FormShapes;

		private string crFormShape = "Circle";

		private string crFormKind = "Mountain";

		private float crFormH = 25f;

		private float crFormW = 8f;

		private CrForm crFormSel;

		private CrForm crFormEdit;

		private int crFormHandle = -2;

		private Vector3 crFormGrab;

		private Vector3 crFormA;

		private bool crFormMaking;

		private readonly List<Vector3> crFormPts = new List<Vector3>();

		private float crFormPendH;

		private float crFormPendS = 1f;

		private float crFormPendT;

		private float crFormLastClick;

		private float crFormRectA;

		private float crFormPendA;

		private bool crFormLasso;

		private Vector2 crFormDownM;

		private readonly List<LineRenderer> crFormLR = new List<LineRenderer>();

		private int crFormLRUsed;

		private static readonly Color CrFormCol;

		private static readonly Color CrFormNewCol;

		public const int LayHouse = 0;

		public const int LayPiece = 1;

		public const int LayLine = 2;

		public const int LayTree = 3;

		public const int LayRock = 4;

		public const int LayPlant = 5;

		public const int LayWater = 6;

		public const int LayCount = 7;

		private static readonly string[] LayNames;

		private static readonly string[] LayTips;

		public static int crLayHide;

		public static int crLayLock;

		private bool crLayersOpen;

		private float crLayersX;

		private static readonly Dictionary<int, int> layCat;

		private static readonly Dictionary<GameObject, Renderer[]> layHidden;

		private static readonly List<Renderer> layWaterHidden;

		private static float layTickT;

		private static int layApplied;

		private const float AdGrade = 0.33f;

		private const float AdTunnel = 5.6f;

		private const float AdBridge = 2.2f;

		private const float AdTunH = 4f;

		public const string AutoKey = "cb_auto";

		public const string TunKey = "cb_tun";

		private bool crAdapting;

		private static string crAutoSig;

		private static bool crTunFlag;

		private readonly Dictionary<long, float> weights = new Dictionary<long, float>();

		private readonly HashSet<string> crTilesPending = new HashSet<string>();

		private static readonly Collider[] tunHits;

		public const string BpKey = "cb_bp";

		public const string BpYawKey = "cb_bpyaw";

		private readonly List<CrUnit> crSelU = new List<CrUnit>();

		private CrUnit crHov;

		private LineRenderer crHovLR;

		private bool crMoving;

		private bool crBoxing;

		private bool crPressed;

		private bool crDragCand;

		private bool crDragging;

		private bool crLiftOnly;

		private float crLiftT;

		private Vector2 crDragA;

		private float crRefreshT;

		private Vector2 crBoxA;

		private Vector2 crBoxAUi;

		private Vector3 crMoveFrom;

		private Vector3 crMovePivot;

		private float crMoveYaw;

		private float crMoveLift;

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

		private readonly List<Vector3> crMovePos = new List<Vector3>();

		private readonly List<Quaternion> crMoveRot = new List<Quaternion>();

		private List<float> crFloors;

		private int crFloor = -1;

		private readonly List<Renderer> crHidR = new List<Renderer>();

		private readonly List<Collider> crHidC = new List<Collider>();

		private string crStamp;

		private GameObject crStampGhost;

		private Vector3 crStampScale = Vector3.one;

		private float crStampYaw;

		private float crStampLift;

		private bool crStampNature;

		private static FieldInfo fCrInstances;

		private static int crSelMask;

		private static readonly Color CrSelColor;

		private static readonly Color CrHovColor;

		private static readonly Color CrPipColor;

		private LineRenderer crAllLR;

		private GameObject crLastClick;

		private float crLastClickT;

		private static readonly Ed[] SculptEds;

		private static readonly string[] SculptNames;

		private static readonly string[] FormNames;

		private static readonly string[] FormTips;

		private Ed crLastSculpt;

		private Ed crLastPlant = Ed.Veg;

		private string crForm = "Hill";

		private string crSelFor;

		private readonly HashSet<Ed> crAreaEds = new HashSet<Ed>();

		public static bool Creator;

		private bool crHist;

		private bool crTyping;

		private Ed crLastEd;

		private string crPrevTab;

		private Vector2 crInspScroll;

		private Vector2 crCatScroll;

		private float crInspH = 400f;

		private const float CrTopH = 56f;

		private const float CrBottomH = 132f;

		private const float CrTopX = 254f;

		private const float CrLeftMin = 64f;

		private const float CrLeftMax = 380f;

		private const float CrRightMin = 300f;

		private const float CrRightMax = 640f;

		private const float CrCompactW = 150f;

		private static bool crHideAll;

		private static float crLW;

		private static float crRW;

		private static string crResize;

		private static readonly Dictionary<string, string> CrBundleTips;

		private readonly Dictionary<string, CrTool> crBundleLast = new Dictionary<string, CrTool>();

		private string crLineGroup = "Fences";

		private static readonly CrTool[] CrPalette;

		public const string CrBlockKey = "cb_nocreator";

		private const string CrAdaptTip = "<b>Paths adapt to the terrain</b>\nUp a hill as far as it is walkable – the ramp is cut into the ground. Where it gets too steep: a stone tunnel through the hill. Over gaps, ravines and water: a bridge (wood, or stone for paved roads). Fences and torches along the path follow.\n\nAlso when you change the terrain on a path later (raise a hill on it, dig a river through it). Ctrl+Z undoes it together with your change.";

		private const string CrViewTip = "<b>View distance</b>  (click to switch)\nNormal: like the game.\nFar: much more land loaded, trees and rocks stay detailed far away, less haze.\nExtreme: even further – needs a strong PC.\n\n<color=#9a9a9a>Only while the Creator is open. Your Viking plays with the normal view distance.</color>";

		private static readonly CrLineType[] CrLineTypes;

		private readonly List<Vector3> crPts = new List<Vector3>();

		private static readonly LineRenderer[] crLR;

		private static readonly List<LineRenderer> crHandleLR;

		public const string LineDefKey = "cb_linedef";

		private CrLineDef crSel;

		private int crDragPt = -1;

		private bool crSelDirty;

		private int crNewHill;

		private static FieldInfo fInstances;

		private static int crAlongSide;

		public const string LinesKey = "cb_lines";

		private static string crBuildTag;

		private static string crBuildDef;

		private const int KVeg = 0;

		private const int KRock = 1;

		private static readonly List<CrVegPreset>[] crPresetLists;

		private bool crAddOpen;

		private string crAddBiome = "Meadows";

		private static readonly Dictionary<string, string> CrNames;

		private static Dictionary<string, List<string>> crCatalog;

		private static readonly string[] RockWords;

		private int crPresetSave;

		private static readonly int[] crRej;

		private float crRiverW = 6f;

		private float crRiverD = 1.8f;

		private float crRiverBank = 6f;

		private float crRiverLevel = 40f;

		private float crRiverStep = 0.6f;

		private bool crRiverFixed;

		private float crLakeD = 3f;

		private float crLakeBank = 8f;

		private float crLakeLevel = 40f;

		private bool crLakeFixed;

		private string crLakeLvlId;

		private string crLakeLvlOld;

		private Vector2s crLakeLvlZone;

		private float crLakeLvlT;

		private readonly Dictionary<Vector2s, string> crLakeLvlDry = new Dictionary<Vector2s, string>();

		private bool crSeaBack;

		private bool crSeaStroke;

		private float crSeaT;

		private static List<Piece> crPieceList;

		private string crPieceCat;

		private string crPieceSearch = "";

		private Vector2 crPieceScroll;

		private Piece crPiece;

		private GameObject crPieceGhost;

		private float crPieceLift;

		private readonly List<Vector3> crPieceSnaps = new List<Vector3>();

		private float crPieceYaw;

		private float crPieceGrid;

		private bool crPieceSnap = true;

		private static int crPieceMask;

		public const string DecoKey = "cb_deco";

		public const string LinkKey = "cb_link";

		public const string HoldKey = "cb_hold";

		private ImportedBP crBp;

		private GameObject crBpGhost;

		private float crBpYaw;

		private float crBpLift;

		private string crBpSearch = "";

		private Vector2 crBpScroll;

		private bool crBpLevel = true;

		private bool crBpClear = true;

		private const int CrSpawnPerFrame = 250;

		public bool crSpawning;

		private bool merchantOpen;

		private long playerOpen;

		private bool playerOn;

		private int giveIdx;

		private int wantIdx = 1;

		private int giveN = 10;

		private int wantN = 10;

		private static readonly string[] TradeExtras;

		private bool settingsOpen;

		private string sliderDrag;

		private bool pendingNature;

		private string migratePick;

		private string migrateDone;

		private static Texture2D gearTex;

		private const float RowH = 34f;

		private const float LabelW = 250f;

		private float settingsH;

		private int selShip;

		private float coastLen;

		private string coastWhy;

		private Vector3 coastAt = new Vector3(float.NaN, 0f, 0f);

		private float coastYaw;

		private GameObject dockGhost;

		private int scrapAsk;

		private BrushMode brushMode;

		private bool stroking;

		private float strokeT;

		private float flatH;

		private Dictionary<long, float> strokeOrig;

		private readonly List<Dictionary<long, float>> brushUndo = new List<Dictionary<long, float>>();

		private static LineRenderer brushRing;

		public const float BrushMax = 60f;

		private long townOpen;

		private bool townOn;

		private bool binfoOn;

		private int townTab;

		private string townItem;

		private int townN = 10;

		private float townReqT;

		private Vector2 townScroll;

		private long binfoColony;

		private ZDOID binfoId;

		private float binfoReqT;

		private Rank inviteRank = Rank.Citizen;

		private long fSquadColony;

		private int fSquadBid;

		private static readonly string[] TownTabs;

		private const float MembershipH = 96f;

		private static readonly Color MemberSquadColor;

		private const float MemberClearReach = 150f;

		private Walls.WDef wallDef;

		private bool wallStarted;

		private Vector3 wallStart;

		private LineRenderer wallLine;

		private Ed ed;

		private bool edStroking;

		private bool edSelHas;

		private bool edSelDrag;

		private bool edLineStarted;

		private bool edPasting;

		private float edStrokeT;

		private float edFlatH;

		private Vector3 edSelA;

		private Vector3 edLineA;

		private Rect edSel;

		private int edPasteRot;

		private EdStep edCur;

		private TerrainClip edClip;

		private readonly List<EdStep> edUndo = new List<EdStep>();

		private readonly List<EdStep> edRedo = new List<EdStep>();

		private static readonly Dictionary<ZDOID, ZDOID> edRemap;

		private const int EdUndoMax = 40;

		private static LineRenderer edLR;

		public const float EdMaxSel = 200f;

		public const string LineKey = "cb_line";

		private static readonly string[] EdNames;

		public static readonly string[] TreeTypes;

		public static readonly string[] PaintTypes;

		public static readonly string[] LineModes;

		private bool edRealLast;

		private static readonly string[] RockPrefabs;

		private static readonly Dictionary<string, string[]> biomeVeg;

		private static FieldInfo fPMask;

		private static FieldInfo fPMod;

		private static FieldInfo fPOps;

		private static FieldInfo fPNview;

		private static MethodInfo mPSave;

		private static bool pInit;

		public static bool edDigDry;

		private static readonly List<Vector2Int> edDryQ;

		private static LineRenderer seaRing;

		private string edSeaNote;

		private float? edFlatPick;

		private readonly List<LineRenderer> edClrLR = new List<LineRenderer>();

		private float edClrT;

		private static float rRepeatT;

		private static int rFrame;

		private static int rSteps;

		private static float liftRepeatT;

		private static int liftFrame;

		private static float liftVal;

		private bool mapOpen;

		private bool researchOpen;

		private int siteOpen;

		private int siteTab;

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

		private readonly HashSet<int> heroPick = 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;

		private int researchRow;

		private ZDO scoutDismiss;

		private float scoutDismissT;

		private static float MaxDist
		{
			get
			{
				if (!Creator)
				{
					return 380f;
				}
				return CrView.MaxZoom;
			}
		}

		public static float CamDist => dist;

		public static float CamYaw => yaw;

		public float PlaceYawNow => placeYaw;

		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 CrAreaOn
		{
			get
			{
				if (Creator && AreaCapable(ed))
				{
					return crAreaEds.Contains(AreaKey(ed));
				}
				return false;
			}
		}

		private static float CrLW
		{
			get
			{
				if (crLW < 0f)
				{
					crLW = Plugin.CrLeftWidth.Value;
				}
				if (!crHideAll && !Plugin.CrLeftHidden.Value)
				{
					return Mathf.Clamp(crLW, 64f, 380f);
				}
				return 0f;
			}
		}

		private static float CrRW
		{
			get
			{
				if (crRW < 0f)
				{
					crRW = Plugin.CrRightWidth.Value;
				}
				if (!crHideAll && !Plugin.CrRightHidden.Value)
				{
					return Mathf.Clamp(crRW, 300f, 640f);
				}
				return 0f;
			}
		}

		public static bool CrBlocked
		{
			get
			{
				ZoneSystem instance = ZoneSystem.instance;
				try
				{
					return (Object)(object)instance != (Object)null && instance.GetGlobalKey("cb_nocreator");
				}
				catch
				{
					return false;
				}
			}
		}

		public static bool CrMultiplayer
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					return !ZNet.IsSinglePlayer;
				}
				return false;
			}
		}

		public static bool CrIsAdmin
		{
			get
			{
				ZNet instance = ZNet.instance;
				if ((Object)(object)instance == (Object)null || ZNet.IsSinglePlayer || instance.IsServer())
				{
					return true;
				}
				try
				{
					return instance.LocalPlayerIsAdminOrHost();
				}
				catch
				{
					return false;
				}
			}
		}

		private static bool CrAllowed
		{
			get
			{
				if (CrBlocked)
				{
					return CrIsAdmin;
				}
				return true;
			}
		}

		private int CrKind => (ed == Ed.Rocks) ? 1 : 0;

		private float ModesHeight => 22f + (Plugin.CityMod ? 4f : 2f) * 34f + 8f + ((CrMultiplayer && CrIsAdmin) ? 34f : 0f);

		public static bool TerrainOpen
		{
			get
			{
				if ((Object)(object)Instance != (Object)null)
				{
					if (!(Instance.tab == "Terrain") && !(Instance.tab == "World Editor") && Instance.tool != Tool.Brush && Instance.tool != Tool.Zone)
					{
						return Instance.tool == Tool.Editor;
					}
					return true;
				}
				return false;
			}
		}

		private bool ForeignSquadSelected => fSquadBid != 0;

		public static bool EditorRealSize
		{
			get
			{
				if ((Object)(object)Instance != (Object)null && Plugin.EdRealSize != null && Plugin.EdRealSize.Value)
				{
					if (Instance.tool != Tool.Editor)
					{
						return Instance.tab == "World Editor";
					}
					return true;
				}
				return false;
			}
		}

		private bool EdSquare
		{
			get
			{
				if (Plugin.BrushSquare.Value)
				{
					return ed != Ed.Paint;
				}
				return false;
			}
		}

		private static float EdAmt => Mathf.Clamp(Plugin.EdAmount.Value, 1f, 100f);

		private bool EdWheelBrush
		{
			get
			{
				if (tool == Tool.Editor)
				{
					if (!EdTerrainBrush(ed) && ed != Ed.Paint && ed != Ed.Veg && ed != Ed.Forest && ed != Ed.Rocks && ed != Ed.Clear && ed != Ed.Sea)
					{
						if (ed == Ed.Form)
						{
							return crFormSel != null;
						}
						return false;
					}
					return true;
				}
				return false;
			}
		}

		private static float EdWater
		{
			get
			{
				if (!((Object)(object)ZoneSystem.instance != (Object)null))
				{
					return 30f;
				}
				return ZoneSystem.instance.m_waterLevel;
			}
		}

		private static float EdAngle
		{
			get
			{
				if (Plugin.BrushAngle == null)
				{
					return 0f;
				}
				return Mathf.Repeat(Plugin.BrushAngle.Value, 90f);
			}
		}

		private static bool EdAligned
		{
			get
			{
				float edAngle = EdAngle;
				if (!(edAngle < 0.01f) && !(Mathf.Abs(edAngle - 45f) < 0.01f))
				{
					return edAngle > 89.99f;
				}
				return true;
			}
		}

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

		private int NameEdit(Rect r, string ctl, ref string buf)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			GUI.SetNextControlName(ctl);
			buf = GUI.TextField(r, buf ?? "", 28, UI.Field);
			if (GUI.GetNameOfFocusedControl() != ctl)
			{
				GUI.FocusControl(ctl);
			}
			if (In.Pressed((Key)60))
			{
				return 2;
			}
			if (In.Pressed((Key)2) || In.Pressed((Key)77))
			{
				return 1;
			}
			if (Event.current != null && (int)Event.current.type == 0 && !((Rect)(ref r)).Contains(Event.current.mousePosition))
			{
				return 1;
			}
			return 0;
		}

		private void PlateName(Rect pl)
		{
			//IL_00d1: 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_00e3: 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_005f: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(((Rect)(ref pl)).x + 70f, ((Rect)(ref pl)).y + 3f, ((Rect)(ref pl)).width - 140f, 26f);
			if (townEdit != null)
			{
				int num = NameEdit(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + 1f, ((Rect)(ref r)).width, 24f), "townname", ref townEdit);
				if (num == 1)
				{
					string text = (townEdit ?? "").Trim();
					if (text.Length > 0 && AnnoWorld.Data != null)
					{
						AnnoWorld.Data.ColonyName = text;
						AnnoWorld.Save();
						Toast("Your town is now called " + text);
						Features.Use("mp.town_name");
					}
				}
				if (num != 0)
				{
					townEdit = null;
				}
				return;
			}
			UI.TextShadow(r, Peers.ColonyName(), UI.HeadC);
			Reg(r);
			if (UI.Hover(r))
			{
				tip = "<b>" + Peers.ColonyName() + "</b>\nWorld: " + (Flat.WorldName ?? "–") + "\n<color=#b3b0a3>Click to rename your town</color>";
			}
			if (UI.Click(r))
			{
				townEdit = Peers.ColonyName();
				Name("townname", r);
			}
		}

		private void AllianceButton(Rect plate)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (!Col.Multi)
			{
				return;
			}
			Rect r = Reg(new Rect(((Rect)(ref plate)).x + 40f, ((Rect)(ref plate)).y + 8f, 26f, 26f));
			bool flag = UI.Hover(r);
			UI.Nine(r, flag ? UI.SlotHi : UI.Slot, 6);
			UI.Tex(new Rect(((Rect)(ref r)).x + 6f, ((Rect)(ref r)).y + 6f, 14f, 14f), (Texture)(object)UI.Dot, (flag || allianceOn) ? Color.white : (Alliance.Any ? UI.Green : UI.Gold));
			if (flag)
			{
				tip = "<b>" + (Alliance.HasName ? Alliance.Name : "Alliance") + "</b>  <color=#b3b0a3>(" + Alliance.Members().Count + ")</color>\nName your alliance, see every member – also the ones an ally brought in – and call for help.";
			}
			if (UI.Click(r))
			{
				allianceOn = !allianceOn;
				if (allianceOn)
				{
					mapOpen = (researchOpen = (playerOn = false));
					siteOpen = 0;
					CloseTownWindows();
				}
			}
		}

		private void AllianceKeys()
		{
			if (allianceOn && In.Pressed((Key)60))
			{
				allianceOn = false;
			}
		}

		private void DrawAlliance()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: 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_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0741: Unknown result type (might be due to invalid IL or missing references)
			//IL_0746: Unknown result type (might be due to invalid IL or missing references)
			//IL_0683: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_06df: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ab: Unknown result type (might be due to invalid IL or missing references)
			Features.Use("mp.alliance_group");
			List<Peers.Info> list = Alliance.Others();
			List<int> list2 = Alliance.Clans().ToList();
			float num = 720f;
			float num2 = 300f + (float)Mathf.Min(6, list.Count) * 34f + (float)Mathf.Min(5, list2.Count) * 30f;
			Rect r = Reg(new Rect((UI.W - num) / 2f, (UI.H - num2) / 2f - 20f, num, num2));
			UI.Frame(r);
			if (UI.CloseButton(new Rect(((Rect)(ref r)).xMax - 46f, ((Rect)(ref r)).y + 14f, 30f, 30f)))
			{
				allianceOn = false;
				return;
			}
			float num3 = ((Rect)(ref r)).x + 30f;
			float num4 = ((Rect)(ref r)).y + 12f;
			float num5 = num - 60f;
			if (allyEdit != null)
			{
				int num6 = NameEdit(new Rect(((Rect)(ref r)).x + num / 2f - 160f, num4 + 2f, 320f, 28f), "allyname", ref allyEdit);
				if (num6 == 1)
				{
					string text = (allyEdit ?? "").Trim();
					if (text.Length > 0)
					{
						Alliance.Rename(text);
						Toast("Your alliance is now called " + text);
						Features.Use("mp.alliance_name");
					}
				}
				if (num6 != 0)
				{
					allyEdit = null;
				}
			}
			else
			{
				Rect r2 = default(Rect);
				((Rect)(ref r2))..ctor(((Rect)(ref r)).x, num4, num, 32f);
				UI.TextShadow(r2, "<color=#bfffd0>" + (Alliance.HasName ? Alliance.Name : "Name your alliance…") + "</color>", UI.Title);
				Reg(r2);
				if (UI.Hover(r2))
				{
					tip = "<b>Alliance name</b>\nClick to rename. Every member takes the new name over – the latest rename wins.";
				}
				if (UI.Click(r2))
				{
					allyEdit = (Alliance.HasName ? Alliance.Name : "");
				}
			}
			num4 += 36f;
			UI.Text(new Rect(((Rect)(ref r)).x, num4, num, 18f), Alliance.Members().Count + ((Alliance.Members().Count == 1) ? " town" : " towns") + "  ·  " + list2.Count + " allied clans", UI.TinyC);
			num4 += 22f;
			UI.Divider(((Rect)(ref r)).x + 40f, num4, num - 80f);
			num4 += 16f;
			Section(num3, ref num4, num5, "Members");
			UI.Icon(new Rect(num3, num4 + 2f, 26f, 26f), Icons.Item("Coins"), 0.9f);
			UI.Text(new Rect(num3 + 32f, num4 + 1f, num5 - 40f, 20f), "<color=#f5d07a>" + Peers.ColonyName() + "</color>  <color=#b3b0a3>you</color>", UI.Small);
			num4 += 30f;
			if (list.Count == 0)
			{
				UI.Text(new Rect(num3, num4, num5, 36f), "<color=#b3b0a3>Nobody else yet. Click another player's town, then \"Offer alliance\". Everyone an ally brings in shows up here for all of you.</color>", UI.TinyWrap);
				num4 += 40f;
			}
			foreach (Peers.Info item in list.Take(6))
			{
				bool flag = Diplo.Allied(Col.Me, item.Colony);
				UI.Text(new Rect(num3 + 32f, num4 + 1f, num5 - 210f, 20f), "<color=#f2bfff>" + item.Name + "</color>  <color=#b3b0a3>" + item.Owner + (flag ? "" : " · through an ally") + "</color>", UI.Small);
				Rect r3 = new Rect(num3 + 32f, num4 + 17f, num5 - 210f, 16f);
				string[] obj = new string[7]
				{
					"<color=#b3b0a3>",
					item.Online ? "online" : "offline, resting",
					"  ·  ",
					item.Pop.ToString(),
					" residents  ·  ",
					null,
					null
				};
				Vector3 val = item.Home - AnnoWorld.Home;
				obj[5] = Mathf.RoundToInt(((Vector3)(ref val)).magnitude).ToString();
				obj[6] = " m away</color>";
				UI.Text(r3, string.Concat(obj), UI.Tiny);
				UI.Tex(new Rect(num3 + 6f, num4 + 10f, 9f, 9f), (Texture)(object)UI.Dot, item.Online ? UI.Green : UI.Dim);
				Rect r4 = new Rect(num3 + num5 - 170f, num4, 110f, 26f);
				if (UI.Button(r4, "Send squads", danger: false, item.Online))
				{
					Toast(Diplo.MarchToTown(item.Colony) ?? ("Your squads march to " + item.Name));
				}
				if (UI.Hover(r4))
				{
					tip = "<b>Help " + item.Name + "</b>\nAll your soldiers (not the tower archers) march to their town and fight what they meet there.";
				}
				if (UI.Button(new Rect(num3 + num5 - 54f, num4, 54f, 26f), "Open"))
				{
					OpenPlayer(item.Colony);
					allianceOn = false;
					return;
				}
				num4 += 34f;
			}
			num4 += 6f;
			Section(num3, ref num4, num5, "Allied clans");
			if (list2.Count == 0)
			{
				UI.Text(new Rect(num3, num4, num5, 36f), "<color=#b3b0a3>An alliance with a Viking clan on the world map counts for the whole alliance: nobody in it is attacked by them any more.</color>", UI.TinyWrap);
				num4 += 40f;
			}
			foreach (int item2 in list2.Take(5))
			{
				SiteData siteData = Sites.Get(item2);
				string text2 = ((siteData != null) ? siteData.Name : "a clan far away");
				UI.Text(new Rect(num3 + 6f, num4 + 1f, num5 - 120f, 20f), "<color=#bfffd0>" + text2 + "</color>  <color=#b3b0a3>brought in by " + Alliance.ClanBy(item2) + "</color>", UI.Small);
				if (siteData != null && UI.Button(new Rect(num3 + num5 - 100f, num4, 100f, 26f), "Open"))
				{
					OpenSite(item2);
					allianceOn = false;
					return;
				}
				num4 += 30f;
			}
			num4 += 6f;
			Rect r5 = new Rect(num3, num4, 220f, 32f);
			if (UI.Button(r5, "Call for help", danger: false, Alliance.Any))
			{
				Alliance.Call(Defense.RaidersInTown().Count);
			}
			if (UI.Hover(r5))
			{
				tip = "<b>Call for help</b>\nEvery member online gets a message with a button that marches their squads to your town. It goes out by itself when at least " + 2 + " enemies are in your town.";
			}
			UI.Text(new Rect(num3 + 232f, num4 + 6f, num5 - 232f, 20f), "<color=#b3b0a3>Borders of the towns you know are rings on the ground – gold yours, green your alliance, red at war (Settings).</color>", UI.Tiny);
		}

		private void Awake()
		{
			Instance = this;
			((MonoBehaviour)this).useGUILayout = false;
		}

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

		public static void RemoteCamera(Vector3 p, float d, float y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			p.y = Util.Ground(p);
			focusTarget = p;
			Focus = p;
			if (d > 0f)
			{
				distTarget = (dist = Mathf.Clamp(d, 4f, MaxDist));
			}
			if (!float.IsNaN(y))
			{
				yaw = y;
			}
		}

		public static void RemoteTeleport(Vector3 p)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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 (Exception e)
				{
					Plugin.Quiet(e, "AnnoMode.cs:69");
					MovePlayer(localPlayer, val);
				}
				focusTarget = (Focus = val);
			}
		}

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

		public void RemoteStartPlace(BType t)
		{
			BDef bDef = Defs.Get(t);
			if (bDef != null)
			{
				Select(bDef);
			}
		}

		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 LateUpdate()
		{
			try
			{
				CrView.Tick(Creator && Active && InGame);
			}
			catch (Exception e)
			{
				Plugin.Quiet(e, "CrView");
			}
		}

		private void Update()
		{
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			if (!InGame)
			{
				if (Active)
				{
					SetActive(on: false);
				}
				return;
			}
			if (!initDone)
			{
				initDone = true;
				PieceInfo.Dump();
				Imports.Reload();
				if (Plugin.CityMod)
				{
					StarterKit();
				}
			}
			Prof.Frame(Time.unscaledDeltaTime);
			long t = Prof.T();
			AnnoLook.Tick();
			Prof.Add("m:AnnoLook", t);
			bool cityMod = Plugin.CityMod;
			if (cityMod)
			{
				t = Prof.T();
				Colony.Update(Time.deltaTime);
				Prof.Add("m:Colony", t);
			}
			if (cityMod)
			{
				WorldTick(Time.deltaTime);
			}
			try
			{
				Rivers.Tick();
			}
			catch (Exception e)
			{
				Plugin.Quiet(e, "Rivers.Tick");
			}
			try
			{
				TerrainHoles.Tick();
			}
			catch (Exception e2)
			{
				Plugin.Quiet(e2, "TerrainHoles.Tick");
			}
			try
			{
				SeaDry.Tick();
			}
			catch (Exception e3)
			{
				Plugin.Quiet(e3, "SeaDry.Tick");
			}
			try
			{
				BpOnline.Tick();
				if (Active)
				{
					BpThumbs.Tick();
				}
			}
			catch (Exception e4)
			{
				Plugin.Quiet(e4, "Blueprint.Tick");
			}
			try
			{
				BiomePaint.Tick();
			}
			catch (Exception e5)
			{
				Plugin.Quiet(e5, "Biome.Tick");
			}
			try
			{
				CoTick();
			}
			catch (Exception e6)
			{
				Plugin.Quiet(e6, "CoEdit.Tick");
			}
			try
			{
				CrLayerTick();
			}
			catch (Exception e7)
			{
				Plugin.Quiet(e7, "Layers.Tick");
			}
			try
			{
				if (EdLog.On || EdLog.FilePath != null)
				{
					CrTool crTool = (Creator ? CrActive() : null);
					EdLog.Tick(Creator && Active, Active && !Creator, ((crTool != null) ? crTool.Name : "-") + " / " + ((tool == Tool.Editor) ? ed.ToString() : tool.ToString()), Focus, dist, yaw);
				}
			}
			catch (Exception e8)
			{
				Plugin.Quiet(e8, "EdLog.Tick");
			}
			if (cityMod)
			{
				t = Prof.T();
				PlayerWorker.Tick(Time.deltaTime);
				Prof.Add("m:PlayerWorker", t);
			}
			if ((Object)(object)upgradeGhostFor != (Object)null && (!Active || Time.unscaledTime - upgradeGhostSeen > 0.2f))
			{
				ClearUpgradeGhost();
			}
			if (cityMod)
			{
				try
				{
					WalkerTrim.Tick(Time.deltaTime);
				}
				catch (Exception e9)
				{
					Plugin.Quiet(e9, "AnnoMode.cs:87");
				}
			}
			KeepDay();
			if (TypingSomewhere() || uiTyping)
			{
				return;
			}
			if (cityMod)
			{
				try
				{
					ItemRules.InventoryKeys();
				}
				catch (Exception ex)
				{
					Plugin.Warn("Item-Regel: " + ex.Message);
				}
			}
			if (Plugin.CreatorOn.Value && In.Pressed(Plugin.CreatorKey.Value))
			{
				CrToggle();
			}
			else if (cityMod && In.Pressed(Plugin.ToggleKey.Value))
			{
				string why;
				if (!Plugin.CityOn.Value)
				{
					if (!Creator)
					{
						Player localPlayer = Player.m_localPlayer;
						if ((Object)(object)localPlayer != (Object)null)
						{
							((Character)localPlayer).Message((MessageType)2, "The city builder is turned off in the settings" + (Plugin.CreatorOn.Value ? ("  ·  " + ((object)Plugin.CreatorKey.Value/*cast due to .constrained prefix*/).ToString() + " opens the Creator") : ""), 0, (Sprite)null, false);
						}
					}
				}
				else if (Creator)
				{
					CrToCity();
				}
				else if (!Active && !CanEnter(out why))
				{
					Player localPlayer2 = Player.m_localPlayer;
					if ((Object)(object)localPlayer2 != (Object)null)
					{
						((Character)localPlayer2).Message((MessageType)2, why, 0, (Sprite)null, false);
					}
				}
				else
				{
					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) && !In.Ctrl)
			{
				Plugin.GridOn.Value = !Plugin.GridOn.Value;
				if (Plugin.GridOn.Value)
				{
					placeYaw = Mathf.Round(placeYaw / 90f) * 90f;
				}
				if (tool == Tool.Road)
				{
					if (roadStarted)
					{
						Roads.FreeEnd();
					}
					roadStarted = false;
					Roads.HidePreview();
					HideRing();
					bool flag = road != null && road.Ops != null;
					Toast(Plugin.GridOn.Value ? "Grid on – click start and end" : (flag ? ("Grid off – paint freely, " + In.SizeKeys + " width") : "Grid off – stone and plank paths always use the grid"));
				}
				else
				{
					Toast(Plugin.GridOn.Value ? "Grid on" : "Grid off");
				}
			}
			if (In.Pressed((Key)71) && tool != Tool.Editor && !Creator)
			{
				if (selBuildings.Count > 0)
				{
					DemolishSelected();
				}
				else
				{
					SetTool((tool != Tool.Demolish) ? Tool.Demolish : Tool.None);
				}
			}
			if (Plugin.HideHud.Value)
			{
				SetHud(visible: false);
			}
			if (!Creator)
			{
				WorldHotkeys();
			}
			SettingsKeys();
			UpdateCameraControls();
			AnnoMap.Tick(Focus, yaw);
			hoverText = null;
			hoverBuilding = ((tool == Tool.None && !MouseOverUI()) ? BuildingUnderMouse() : null);
			if ((Object)(object)hoverBuilding == (Object)null && foreignHover != null && tool == Tool.None)
			{
				hoverText = foreignHover;
			}
			if (tool == Tool.None && !MouseOverUI())
			{
				ShipHover();
			}
			EdTick();
			if (!Creator)
			{
				BuildHotkeys();
			}
			if (Creator && tool != Tool.Editor && tool != Tool.Road)
			{
				SelectEd(ed);
			}
			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;
			case Tool.Wall:
				UpdateWall();
				break;
			case Tool.Zone:
				UpdateZone();
				break;
			case Tool.Brush:
				UpdateBrush();
				break;
			case Tool.Editor:
				UpdateEditor();
				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, label: false, selBuildings[0].Def);
			}
			EndFrameRange();
			ShowInfluence();
			try
			{
				Alliance.ShowBorders();
			}
			catch (Exception e10)
			{
				Plugin.Quiet(e10, "Alliance.ShowBorders");
			}
			RangeRings.EndFrame();
			Leveling.Marks(show: true);
			try
			{
				TickPendingBuilds();
			}
			catch (Exception e11)
			{
				Plugin.Quiet(e11, "AnnoMode.TickPendingBuilds");
			}
			Blockers.EndFrame();
			Leveling.PlanEndFrame();
			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
			{
				long t = Prof.T();
				FogLayer.Ensure();
				Prof.Add("m:FogLayer", t);
				t = Prof.T();
				Peers.Tick(dt);
				Prof.Add("m:Peers", t);
				worldKeyT -= dt;
				if (worldKeyT <= 0f)
				{
					worldKeyT = 5f;
					try
					{
						Flat.CheckKey();
					}
					catch (Exception e)
					{
						Plugin.Quiet(e, "Flat.CheckKey");
					}
				}
				t = Prof.T();
				AnnoWorld.Tick(dt);
				Prof.Add("m:AnnoWorld", t);
				t = Prof.T();
				Fog.Tick(dt);
				Prof.Add("m:Fog", t);
				t = Prof.T();
				Sites.Tick(dt);
				Sites.Deliveries(dt);
				Prof.Add("m:Sites", t);
				t = Prof.T();
				Expeditions.Tick(dt);
				Heroes.Tick(dt);
				Prof.Add("m:Expeditions", t);
				t = Prof.T();
				Ships.Tick(dt);
				ShipViews.Update();
				Prof.Add("m:Ships", t);
				t = Prof.T();
				Events.Tick(dt);
				Prof.Add("m:Events", t);
				t = Prof.T();
				Scouts.Tick(dt);
				Prof.Add("m:Scouts", t);
				t = Prof.T();
				try
				{
					Diplo.TickMarch();
				}
				catch (Exception e2)
				{
					Plugin.Quiet(e2, "Diplo.March");
				}
				Prof.Add("m:March", t);
				t = Prof.T();
				Perf.Tick(dt);
				Prof.Add("m:Perf", t);
				t = Prof.T();
				Conquest.Tick(dt);
				Prof.Add("m:Conquest", t);
				t = Prof.T();
				Tech.Tick(dt);
				Prof.Add("m:Tech", t);
				t = Prof.T();
				Plans.Tick(dt);
				Prof.Add("m:Plans", t);
			}
			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 (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.cs:181");
			}
		}

		internal 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 (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.cs:192");
			}
			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 (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.cs:218");
			}
		}

		public static bool VikingHome(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)
			p = vikingHome;
			if (Active)
			{
				return haveVikingHome;
			}
			return false;
		}

		private static bool CanEnter(out string why)
		{
			why = null;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || DevTools.FreeBuild)
			{
				return true;
			}
			bool flag = false;
			try
			{
				flag = localPlayer.IsSensed() || EnemyNear(localPlayer, 18f);
			}
			catch (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.cs:235");
			}
			if (flag)
			{
				why = "Enemies are nearby – you can't switch to the city view right now";
				return false;
			}
			return true;
		}

		private static bool EnemyNear(Player pl, float r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_005a: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)pl).transform.position;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)pl) && !allCharacter.IsPlayer() && !allCharacter.IsDead() && !allCharacter.IsTamed() && (int)allCharacter.GetFaction() != 1)
				{
					Vector3 val = ((Component)allCharacter).transform.position - position;
					if (!(((Vector3)(ref val)).sqrMagnitude > r * r) && BaseAI.IsEnemy(allCharacter, (Character)(object)pl))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void CityPhysics(bool on)
		{
			try
			{
				if (on)
				{
					if (Plugin.CityPhysicsRate != null && Plugin.CityPhysicsRate.Value > 0)
					{
						float num = 1f / (float)Mathf.Clamp(Plugin.CityPhysicsRate.Value, 20, 50);
						if (!(Time.fixedDeltaTime >= num - 0.0001f))
						{
							savedFixed = Time.fixedDeltaTime;
							Time.fixedDeltaTime = (ourFixed = num);
						}
					}
				}
				else if (savedFixed > 0f)
				{
					if (Mathf.Abs(Time.fixedDeltaTime - ourFixed) < 0.0001f)
					{
						Time.fixedDeltaTime = savedFixed;
					}
					savedFixed = (ourFixed = -1f);
				}
			}
			catch (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.cs:274");
			}
		}

		private static void ResetFall(Player pl)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pl == (Object)null || fiMaxAir == null)
			{
				return;
			}
			try
			{
				fiMaxAir.SetValue(pl, ((Component)pl).transform.position.y);
			}
			catch (Exception e)
			{
				Plugin.Quiet(e, "AnnoMode.ResetFall");
			}
		}

		private static void ReturnViking()
		{
			//IL_00ce: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (