Decompiled source of ObeliskHub v0.0.2

plugins/ObeliskHub.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using ObeliskHub.Layout;
using Splatform;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ObeliskHub")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ObeliskHub")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.2.0")]
namespace ObeliskHub
{
	internal sealed class ClearCommand : ConsoleCommand
	{
		public const string Seeded = "seeded";

		public const string Placed = "placed";

		public const string All = "all";

		public static readonly string[] Filters = new string[3] { "seeded", "placed", "all" };

		public override string Name => "obeliskhub_clear";

		public override string Help => "[seeded|placed|all] Delete Waypoints (admins). No filter: only report how many there are";

		public override List<string> CommandOptionList()
		{
			return Filters.ToList();
		}

		public override void Run(string[] args)
		{
			if (CommandUtils.RequireWorld())
			{
				WaypointSeeder.RequestClear((args.Length != 0) ? args[0].ToLowerInvariant() : "");
			}
		}
	}
	internal static class CommandUtils
	{
		public static bool IsAdmin(long sender)
		{
			ZNetPeer peer = ZNet.instance.GetPeer(sender);
			if (peer != null)
			{
				return ZNet.instance.IsAdmin(peer.m_rpc.GetSocket().GetHostName());
			}
			return false;
		}

		public static bool RequireWorld()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return true;
			}
			Console.instance.Print("Join a world first");
			return false;
		}

		public static void Report(string message)
		{
			if (Object.op_Implicit((Object)(object)Console.instance))
			{
				Console.instance.Print(message);
			}
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, message, 0, (Sprite)null, false);
			}
		}
	}
	internal sealed class LayoutCommand : ConsoleCommand
	{
		public override string Name => "obeliskhub_layout";

		public override string Help => "Print the Hub's current layout and its validation report";

		public override void Run(string[] args)
		{
			HubLayout currentLayout = HubController.CurrentLayout;
			if (currentLayout == null)
			{
				Console.instance.Print("The Hub has not been built on this client yet");
				return;
			}
			List<WaypointEntry> entries = WaypointRegistry.LayoutWaypoints.Select((WaypointInfo w) => w.ToLayoutEntry()).ToList();
			List<string> list = Validator.Validate(currentLayout, entries);
			string text = ((list.Count == 0) ? "valid" : ($"{list.Count} problems:\n  " + string.Join("\n  ", list.Take(20))));
			string text2 = AsciiRenderer.Render(currentLayout) + text;
			Logger.LogInfo((object)("Hub layout\n" + text2));
			string[] array = text2.Split(new char[1] { '\n' });
			foreach (string text3 in array)
			{
				Console.instance.Print(text3.TrimEnd(Array.Empty<char>()));
			}
		}
	}
	internal sealed class SeedCommand : ConsoleCommand
	{
		public override string Name => "obeliskhub_seed";

		public override string Help => $"[count] Place Waypoints around the world and reveal them on your map (admins; default {20})";

		public override void Run(string[] args)
		{
			if (CommandUtils.RequireWorld())
			{
				int result = 20;
				if (args.Length != 0 && !int.TryParse(args[0], out result))
				{
					Console.instance.Print("Usage: obeliskhub_seed [count]");
				}
				else
				{
					WaypointSeeder.RequestSeed(result);
				}
			}
		}
	}
	internal sealed class StyleCommand : ConsoleCommand
	{
		private static CustomRPC styleRpc;

		public override string Name => "obeliskhub_style";

		public override string Help => "[style] Set the Hub style (admins; saved to the server's config). No style: list them";

		public static void Init()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0027: Expected O, but got Unknown
			styleRpc = NetworkManager.Instance.AddRPC("ObeliskHub_SetStyle", new CoroutineHandler(RPC_ServerSetStyle), new CoroutineHandler(RPC_ClientResult));
		}

		public override List<string> CommandOptionList()
		{
			return HubStyles.All.Select((IHubStyle s) => s.Name).ToList();
		}

		public override void Run(string[] args)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (args.Length == 0)
			{
				Console.instance.Print("Hub style: " + WaypointRegistry.LayoutStyle);
				{
					foreach (IHubStyle item in HubStyles.All)
					{
						Console.instance.Print("  " + item.Name + ": " + item.Description);
					}
					return;
				}
			}
			if (CommandUtils.RequireWorld())
			{
				if (ZNet.instance.IsServer())
				{
					CommandUtils.Report(SetStyle(args[0], isAdmin: true));
					return;
				}
				ZPackage val = new ZPackage();
				val.Write(args[0]);
				styleRpc.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val);
			}
		}

		private static IEnumerator RPC_ServerSetStyle(long sender, ZPackage package)
		{
			string requested = package.ReadString();
			ZPackage val = new ZPackage();
			val.Write(SetStyle(requested, CommandUtils.IsAdmin(sender)));
			styleRpc.SendPackage(sender, val);
			yield break;
		}

		private static IEnumerator RPC_ClientResult(long sender, ZPackage package)
		{
			CommandUtils.Report(package.ReadString());
			yield break;
		}

		private static string SetStyle(string requested, bool isAdmin)
		{
			if (!isAdmin)
			{
				return "Only admins can change the Hub style";
			}
			IHubStyle hubStyle = HubStyles.Find(requested);
			if (hubStyle == null)
			{
				return "Unknown style '" + requested + "'. Styles: " + string.Join(", ", HubStyles.All.Select((IHubStyle s) => s.Name));
			}
			if (hubStyle.Name == ObeliskHubPlugin.HubStyle.Value)
			{
				return "The Hub style is already " + hubStyle.Name;
			}
			ObeliskHubPlugin.HubStyle.Value = hubStyle.Name;
			Logger.LogInfo((object)("Hub style set to " + hubStyle.Name + " from the console"));
			return "Hub style set to " + hubStyle.Name + " and saved to the server's config. " + $"The Hub rebuilds once nobody is inside; anyone inside is returned after {60f} s.";
		}
	}
	internal class HoverRing : MonoBehaviour
	{
		public const float Radius = 1f;

		private const int Segments = 12;

		private const float HideDelay = 0.5f;

		private GameObject ring;

		private float hideTime;

		public void Show()
		{
			if (!Object.op_Implicit((Object)(object)ring))
			{
				ring = CreateRing(((Component)this).transform);
				if (!Object.op_Implicit((Object)(object)ring))
				{
					return;
				}
			}
			ring.SetActive(true);
			hideTime = Time.time + 0.5f;
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)ring) && ring.activeSelf && Time.time > hideTime)
			{
				ring.SetActive(false);
			}
		}

		private static GameObject CreateRing(Transform parent)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = ZNetScene.instance.GetPrefab("piece_workbench");
			CraftingStation val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<CraftingStation>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.m_areaMarker))
			{
				Logger.LogWarning((object)"Workbench area marker not found, no hover ring");
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val.m_areaMarker, parent.position, Quaternion.identity, parent);
			obj.SetActive(false);
			((Object)obj).name = "ObeliskHub_Ring";
			CircleProjector componentInChildren = obj.GetComponentInChildren<CircleProjector>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.m_radius = 1f;
				componentInChildren.m_nrOfSegments = 12;
			}
			return obj;
		}
	}
	internal class Obelisk : MonoBehaviour, Hoverable, Interactable
	{
		public const string PrefabName = "obeliskhub_obelisk";

		private const string BasePrefab = "stone_pillar";

		private static readonly List<Obelisk> Instances = new List<Obelisk>();

		private HoverRing hoverRing;

		private bool IsUpgraded => Object.op_Implicit((Object)(object)ObeliskUpgrade.FindInRange(((Component)this).transform.position));

		public static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_004d: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				Name = "$piece_obeliskhub_obelisk",
				Description = "$piece_obeliskhub_obelisk_desc",
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc,
				CraftingStation = CraftingStations.Stonecutter,
				Icon = ObeliskArt.LoadIcon("obeliskhub_obelisk")
			};
			val.AddRequirement(new RequirementConfig("Obsidian", 20, 0, true));
			val.AddRequirement(new RequirementConfig("Ectoplasm", 10, 0, true));
			val.AddRequirement(new RequirementConfig("SurtlingCore", 4, 0, true));
			CustomPiece val2 = new CustomPiece("obeliskhub_obelisk", "stone_pillar", val);
			val2.PiecePrefab.AddComponent<Obelisk>();
			val2.PiecePrefab.AddComponent<HoverRing>();
			val2.PiecePrefab.AddComponent<SeededPiece>();
			ObeliskArt.Apply(val2.PiecePrefab, "obeliskhub_obelisk");
			PieceManager.Instance.AddPiece(val2);
		}

		public static Obelisk FindInRange(Vector3 position, float range)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Obelisk result = null;
			float num = range * range;
			foreach (Obelisk instance in Instances)
			{
				Vector3 val = ((Component)instance).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude <= num)
				{
					result = instance;
					num = sqrMagnitude;
				}
			}
			return result;
		}

		private void Awake()
		{
			hoverRing = ((Component)this).GetComponent<HoverRing>();
			if (((Component)this).GetComponent<ZNetView>().GetZDO() != null)
			{
				Instances.Add(this);
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$piece_obeliskhub_obelisk");
		}

		public string GetHoverText()
		{
			if (Object.op_Implicit((Object)(object)hoverRing))
			{
				hoverRing.Show();
			}
			string text = (IsUpgraded ? "$piece_obeliskhub_obelisk <color=orange>($obeliskhub_upgraded)</color>" : "$piece_obeliskhub_obelisk");
			return Localization.instance.Localize(text + "\n[<color=yellow><b>$KEY_Use</b></color>] $obeliskhub_enter");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			return Travel.EnterHub((Player)user, IsUpgraded);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal static class ObeliskArt
	{
		private const string BundleName = "obeliskart";

		private const string UnresolvedPrefix = "JVLmock_";

		private static readonly MethodInfo LoadImage = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2]
		{
			typeof(Texture2D),
			typeof(byte[])
		});

		private static readonly int RippleDistance = Shader.PropertyToID("_RippleDistance");

		private static readonly int FlowSpeed = Shader.PropertyToID("_FlowSpeedY");

		private static readonly Dictionary<string, string> MaterialReplacements = new Dictionary<string, string> { ["obsidian"] = "obsidian_nosnow" };

		private static readonly Dictionary<Material, Material> StaticMaterials = new Dictionary<Material, Material>();

		private static GameObject[] visuals;

		public static Sprite LoadIcon(string prefabName)
		{
			//IL_0058: 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_0075: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith(".Icons." + prefabName + ".png"));
			if (text == null)
			{
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = prefabName + "_icon"
			};
			if (LoadImage == null || !(bool)LoadImage.Invoke(null, new object[2] { val, array }))
			{
				Logger.LogWarning((object)(text + " isn't a readable image, " + prefabName + " keeps its placeholder icon"));
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		public static void Apply(GameObject piece, string prefabName)
		{
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = ((IEnumerable<GameObject>)LoadVisuals()).FirstOrDefault((Func<GameObject, bool>)((GameObject v) => ((Object)v).name == prefabName));
			if (!Object.op_Implicit((Object)(object)val))
			{
				Logger.LogInfo((object)("No visual for " + prefabName + " in the obeliskart bundle, it keeps its placeholder look"));
				return;
			}
			GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(((Object)piece).name + "_visual", val);
			PrefabExtension.FixReferences(val2, true);
			List<string> list = (from t in val2.GetComponentsInChildren<Transform>(true)
				where ((Object)t).name.StartsWith("JVLmock_")
				select ((Object)t).name).ToList();
			if (list.Count > 0)
			{
				Logger.LogError((object)(prefabName + ": these models weren't found in the game, it keeps its placeholder look: " + string.Join(", ", list.Distinct())));
				Object.Destroy((Object)(object)val2);
				return;
			}
			MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true);
			for (int num = 0; num < componentsInChildren.Length; num++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[num]);
			}
			HubPieces.RemoveColliders(val2);
			FixMaterials(val2);
			foreach (Renderer item in from r in piece.GetComponentsInChildren<Renderer>(true)
				where !(r is ParticleSystemRenderer)
				select r)
			{
				item.enabled = false;
			}
			val2.transform.SetParent(piece.transform, false);
			val2.transform.localPosition = Vector3.zero;
			Logger.LogInfo((object)$"{prefabName} dressed from the art bundle: {val2.GetComponentsInChildren<Renderer>(true).Length} renderers");
		}

		private static void FixMaterials(GameObject visual)
		{
			Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[j]))
					{
						sharedMaterials[j] = Replacement(sharedMaterials[j]);
						if (sharedMaterials[j].HasProperty(RippleDistance))
						{
							sharedMaterials[j] = StaticCopy(sharedMaterials[j]);
						}
					}
				}
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static Material Replacement(Material material)
		{
			if (!MaterialReplacements.TryGetValue(((Object)material).name, out var value))
			{
				return material;
			}
			Material prefab = Cache.GetPrefab<Material>(value);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				Logger.LogWarning((object)("Material " + value + " not found, keeping " + ((Object)material).name));
				return material;
			}
			return prefab;
		}

		private static Material StaticCopy(Material original)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (!StaticMaterials.TryGetValue(original, out var value) || !Object.op_Implicit((Object)(object)value))
			{
				value = new Material(original)
				{
					name = ((Object)original).name + "_static"
				};
				value.SetFloat(RippleDistance, 0f);
				value.SetFloat(FlowSpeed, 0f);
				StaticMaterials[original] = value;
			}
			return value;
		}

		private static GameObject[] LoadVisuals()
		{
			if (visuals == null)
			{
				AssetBundle val = AssetUtils.LoadAssetBundleFromResources("obeliskart");
				visuals = (GameObject[])(Object.op_Implicit((Object)(object)val) ? ((Array)val.LoadAllAssets<GameObject>()) : ((Array)new GameObject[0]));
			}
			return visuals;
		}
	}
	internal static class ObeliskShard
	{
		private const string PrefabName = "obeliskhub_shard";

		private const string MoltenPrefabName = "obeliskhub_shard_molten";

		private const string ItemName = "$item_obeliskhub_shard";

		private const string MoltenItemName = "$item_obeliskhub_shard_molten";

		private const string BasePrefab = "Thunderstone";

		private const string MoltenBasePrefab = "MoltenCore";

		private const int StackSize = 10;

		private const float Weight = 0.5f;

		private const float UseDuration = 1.5f;

		private const string UseAnimation = "equipping";

		private const ActionType UseAction = (ActionType)100;

		private static MinorActionData currentUse;

		public static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			ItemConfig val = new ItemConfig
			{
				Name = "$item_obeliskhub_shard",
				Description = "$item_obeliskhub_shard_desc",
				CraftingStation = CraftingStations.Cauldron,
				MinStationLevel = 4,
				Icon = ObeliskArt.LoadIcon("obeliskhub_shard"),
				StackSize = 10,
				Weight = 0.5f
			};
			val.AddRequirement(new RequirementConfig("SurtlingCore", 2, 0, true));
			val.AddRequirement(new RequirementConfig("MushroomJotunPuffs", 3, 0, true));
			val.AddRequirement(new RequirementConfig("MushroomMagecap", 3, 0, true));
			AddItem("obeliskhub_shard", "Thunderstone", val);
			ItemConfig val2 = new ItemConfig
			{
				Name = "$item_obeliskhub_shard_molten",
				Description = "$item_obeliskhub_shard_molten_desc",
				CraftingStation = CraftingStations.FoodPreparationTable,
				Icon = ObeliskArt.LoadIcon("obeliskhub_shard_molten"),
				StackSize = 10,
				Weight = 0.5f
			};
			val2.AddRequirement(new RequirementConfig("obeliskhub_shard", 1, 0, true));
			val2.AddRequirement(new RequirementConfig("MoltenCore", 1, 0, true));
			AddItem("obeliskhub_shard_molten", "MoltenCore", val2);
		}

		public static bool IsShard(ItemData item)
		{
			if (!(item.m_shared.m_name == "$item_obeliskhub_shard"))
			{
				return item.m_shared.m_name == "$item_obeliskhub_shard_molten";
			}
			return true;
		}

		public static void BeginUse(Player player, ItemData item)
		{
			//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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (!((Object)(object)player != (Object)(object)Player.m_localPlayer))
			{
				if (currentUse != null && player.m_actionQueue.Remove(currentUse))
				{
					currentUse = null;
				}
				else if (CanEnterHub(player, AllowsAllItems(item)))
				{
					currentUse = new MinorActionData
					{
						m_type = (ActionType)100,
						m_item = item,
						m_duration = 1.5f,
						m_progressText = "$obeliskhub_shard_using " + item.m_shared.m_name,
						m_animation = "equipping",
						m_startEffect = player.m_equipStartEffects
					};
					player.m_actionQueue.Add(currentUse);
				}
			}
		}

		public static void UpdateUse(Player player)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (currentUse == null || (Object)(object)player != (Object)(object)Player.m_localPlayer || player.m_actionQueue.Contains(currentUse))
			{
				return;
			}
			MinorActionData val = currentUse;
			currentUse = null;
			if (!(val.m_time < val.m_duration))
			{
				Inventory inventory = ((Humanoid)player).GetInventory();
				bool allowAllItems = AllowsAllItems(val.m_item);
				if (inventory.ContainsItem(val.m_item) && CanEnterHub(player, allowAllItems) && Travel.EnterHub(player, allowAllItems))
				{
					inventory.RemoveOneItem(val.m_item);
					((Humanoid)player).m_consumeItemEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
		}

		private static bool AllowsAllItems(ItemData item)
		{
			return item.m_shared.m_name == "$item_obeliskhub_shard_molten";
		}

		private static void AddItem(string prefabName, string basePrefabName, ItemConfig config)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			CustomItem val = new CustomItem(prefabName, basePrefabName, config);
			SharedData shared = val.ItemDrop.m_itemData.m_shared;
			shared.m_itemType = (ItemType)2;
			shared.m_teleportable = true;
			shared.m_questItem = false;
			shared.m_value = 0;
			ObeliskArt.Apply(val.ItemPrefab, prefabName);
			ItemManager.Instance.AddItem(val);
		}

		private static bool CanEnterHub(Player player, bool allowAllItems)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (HubSpace.Contains(((Component)player).transform.position))
			{
				((Character)player).Message((MessageType)2, "$obeliskhub_shard_in_hub", 0, (Sprite)null, false);
				return false;
			}
			if (((Character)player).IsAttached() || player.GetDoodadController() != null)
			{
				((Character)player).Message((MessageType)2, "$obeliskhub_shard_attached", 0, (Sprite)null, false);
				return false;
			}
			return Travel.CanEnterHub(player, allowAllItems);
		}
	}
	internal class ObeliskUpgrade : MonoBehaviour, Hoverable
	{
		public const string PrefabName = "obeliskhub_upgrade";

		public const float Range = 2f;

		private const string BasePrefab = "blackmarble_1x1";

		private static readonly List<ObeliskUpgrade> Instances = new List<ObeliskUpgrade>();

		public static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				Name = "$piece_obeliskhub_upgrade",
				Description = "$piece_obeliskhub_upgrade_desc",
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc,
				Icon = ObeliskArt.LoadIcon("obeliskhub_upgrade")
			};
			val.AddRequirement(new RequirementConfig("MoltenCore", 1, 0, true));
			val.AddRequirement(new RequirementConfig("Blackwood", 10, 0, true));
			CustomPiece val2 = new CustomPiece("obeliskhub_upgrade", "blackmarble_1x1", val);
			val2.PiecePrefab.AddComponent<ObeliskUpgrade>();
			AddGlow(val2.PiecePrefab.transform);
			ObeliskArt.Apply(val2.PiecePrefab, "obeliskhub_upgrade");
			PieceManager.Instance.AddPiece(val2);
		}

		private static void AddGlow(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ObeliskHub_Glow");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = Vector3.up * 1.2f;
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(1f, 0.45f, 0.1f);
			obj.range = 4f;
			obj.intensity = 1.5f;
			obj.shadows = (LightShadows)0;
		}

		public static ObeliskUpgrade FindInRange(Vector3 position)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			foreach (ObeliskUpgrade instance in Instances)
			{
				Vector3 val = ((Component)instance).transform.position - position;
				if (((Vector3)(ref val)).sqrMagnitude <= 4f)
				{
					return instance;
				}
			}
			return null;
		}

		private void Awake()
		{
			if (((Component)this).GetComponent<ZNetView>().GetZDO() != null)
			{
				Instances.Add(this);
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$piece_obeliskhub_upgrade");
		}

		public string GetHoverText()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			string text = (Object.op_Implicit((Object)(object)Obelisk.FindInRange(((Component)this).transform.position, 2f)) ? "<color=orange>$obeliskhub_upgrade_connected</color>" : "<color=#888888>$obeliskhub_upgrade_unconnected</color>");
			return Localization.instance.Localize("$piece_obeliskhub_upgrade\n" + text);
		}

		public float GetHoverOffset()
		{
			return 0f;
		}
	}
	internal sealed class SeededPiece : MonoBehaviour
	{
		public static readonly int SeededKey = StringExtensionMethods.GetStableHashCode("obeliskhub_seeded");

		private const float GroundCheckInterval = 1f;

		private static readonly int GroundedKey = StringExtensionMethods.GetStableHashCode("obeliskhub_grounded");

		private ZNetView nview;

		private void Awake()
		{
			nview = ((Component)this).GetComponent<ZNetView>();
			if (nview.GetZDO() != null && nview.GetZDO().GetBool(SeededKey, false))
			{
				WearNTear component = ((Component)this).GetComponent<WearNTear>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.m_noSupportWear = false;
				}
				if (!nview.GetZDO().GetBool(GroundedKey, false))
				{
					((MonoBehaviour)this).StartCoroutine(SettleOnGround());
				}
			}
		}

		private IEnumerator SettleOnGround()
		{
			WaitForSeconds wait = new WaitForSeconds(1f);
			float y = default(float);
			while (nview.IsValid())
			{
				yield return wait;
				Vector3 position = ((Component)this).transform.position;
				if (nview.IsValid() && nview.IsOwner() && ZNetScene.instance.IsAreaReady(position) && ZoneSystem.instance.GetGroundHeight(position, ref y))
				{
					position.y = y;
					((Component)this).transform.position = position;
					nview.GetZDO().SetPosition(position);
					nview.GetZDO().Set(GroundedKey, true);
					break;
				}
			}
		}
	}
	internal class Waypoint : MonoBehaviour, Hoverable, Interactable, TextReceiver
	{
		public const string PrefabName = "obeliskhub_waypoint";

		public const int NameLimit = 20;

		public static readonly int NameKey = StringExtensionMethods.GetStableHashCode("obeliskhub_name");

		private const string BasePrefab = "stone_floor_2x2";

		private const string SetNameRpc = "ObeliskHub_SetName";

		private ZNetView nview;

		public static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_004d: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				Name = "$piece_obeliskhub_waypoint",
				Description = "$piece_obeliskhub_waypoint_desc",
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc,
				CraftingStation = CraftingStations.Workbench,
				Icon = ObeliskArt.LoadIcon("obeliskhub_waypoint")
			};
			val.AddRequirement(new RequirementConfig("Stone", 10, 0, true));
			val.AddRequirement(new RequirementConfig("Obsidian", 2, 0, true));
			val.AddRequirement(new RequirementConfig("SurtlingCore", 1, 0, true));
			CustomPiece val2 = new CustomPiece("obeliskhub_waypoint", "stone_floor_2x2", val);
			val2.PiecePrefab.AddComponent<Waypoint>();
			val2.PiecePrefab.AddComponent<SeededPiece>();
			ObeliskArt.Apply(val2.PiecePrefab, "obeliskhub_waypoint");
			PieceManager.Instance.AddPiece(val2);
		}

		private void Awake()
		{
			nview = ((Component)this).GetComponent<ZNetView>();
			if (nview.GetZDO() != null)
			{
				nview.Register<string>("ObeliskHub_SetName", (Action<long, string>)RPC_SetName);
			}
		}

		public string GetText()
		{
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid())
			{
				return "";
			}
			return nview.GetZDO().GetString(NameKey, "");
		}

		public void SetText(string text)
		{
			if (Object.op_Implicit((Object)(object)nview) && nview.IsValid())
			{
				nview.InvokeRPC("ObeliskHub_SetName", new object[1] { text });
			}
		}

		private void RPC_SetName(long sender, string name)
		{
			if (nview.IsOwner())
			{
				nview.GetZDO().Set(NameKey, name);
			}
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$piece_obeliskhub_waypoint");
		}

		public string GetHoverText()
		{
			string text = GetText();
			string text2 = (string.IsNullOrEmpty(text) ? "$piece_obeliskhub_waypoint <color=#888888>($obeliskhub_waypoint_unnamed)</color>" : ("$piece_obeliskhub_waypoint \"" + text + "\""));
			return Localization.instance.Localize(text2 + "\n[<color=yellow><b>$KEY_Use</b></color>] $obeliskhub_waypoint_setname");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (hold)
			{
				return false;
			}
			if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
			{
				return true;
			}
			TextInput.instance.RequestText((TextReceiver)(object)this, "$obeliskhub_waypoint_name", 20);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal static class CartTransport
	{
		private const string CartPrefab = "Cart";

		private const float ArrivalTimeout = 30f;

		private const float HitchTimeout = 15f;

		private const float BodyBottomMargin = 0.6f;

		private const float BodySideMargin = 0.1f;

		private static readonly int CartHash = StringExtensionMethods.GetStableHashCode("Cart");

		private static readonly float[] HitchAngles = new float[8] { 0f, 45f, -45f, 90f, -90f, 135f, -135f, 180f };

		private static readonly Lazy<int> ObstacleMask = new Lazy<int>(() => LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "vehicle" }));

		private static MonoBehaviour host;

		private static CustomRPC moveCartRpc;

		public static void Init(MonoBehaviour plugin)
		{
			//IL_0017: 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_002d: Expected O, but got Unknown
			//IL_002d: Expected O, but got Unknown
			host = plugin;
			moveCartRpc = NetworkManager.Instance.AddRPC("ObeliskHub_MoveCart", new CoroutineHandler(RPC_ServerMoveCart), new CoroutineHandler(RPC_ClientIgnore));
		}

		public static Vagon GetAttachedCart(Player player)
		{
			return ((IEnumerable<Vagon>)Vagon.m_instances).FirstOrDefault((Func<Vagon, bool>)((Vagon cart) => Object.op_Implicit((Object)(object)cart) && Object.op_Implicit((Object)(object)cart.m_nview) && cart.m_nview.IsValid() && cart.IsAttached((Character)(object)player)));
		}

		public static void BringAlong(Player player, Vagon cart)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			ZDOID uid = cart.m_nview.GetZDO().m_uid;
			cart.Detach();
			host.StartCoroutine(BringCart(player, uid));
		}

		private static IEnumerator BringCart(Player player, ZDOID cartId)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			float deadline = Time.time + 30f;
			while (Object.op_Implicit((Object)(object)player) && ((Character)player).IsTeleporting() && Time.time < deadline)
			{
				yield return null;
			}
			if (!Object.op_Implicit((Object)(object)player) || ((Character)player).IsTeleporting() || ((Character)player).IsDead())
			{
				yield break;
			}
			Vagon component = ZNetScene.instance.GetPrefab("Cart").GetComponent<Vagon>();
			if (!FindClearRotation(player, component, cartId, out var rotation))
			{
				Logger.LogInfo((object)$"No room for the cart at {((Component)player).transform.position}, leaving it behind");
				((Character)player).Message((MessageType)2, "$obeliskhub_cart_left_behind", 0, (Sprite)null, false);
				yield break;
			}
			Vector3 val = HitchPosition(player, component, rotation) + Vector3.up * 0.2f;
			if (ZNet.instance.IsServer())
			{
				MoveCart(ZDOMan.GetSessionID(), cartId, val, rotation);
			}
			else
			{
				ZPackage val2 = new ZPackage();
				val2.Write(cartId);
				val2.Write(val);
				val2.Write(rotation);
				moveCartRpc.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val2);
			}
			deadline = Time.time + 15f;
			while (Object.op_Implicit((Object)(object)player) && !((Character)player).IsTeleporting() && Time.time < deadline)
			{
				GameObject val3 = ZNetScene.instance.FindInstance(cartId);
				Vagon val4 = (Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<Vagon>() : null);
				if (Object.op_Implicit((Object)(object)val4) && val4.m_nview.IsValid() && val4.m_nview.IsOwner())
				{
					Hitch(player, val4, rotation);
					yield break;
				}
				yield return null;
			}
			if (Object.op_Implicit((Object)(object)player))
			{
				((Character)player).Message((MessageType)2, "$obeliskhub_cart_left_behind", 0, (Sprite)null, false);
			}
		}

		private static Quaternion FacingRotation(Player player)
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 forward = ((Component)player).transform.forward;
			forward.y = 0f;
			return Quaternion.LookRotation((((Vector3)(ref forward)).sqrMagnitude > 0.001f) ? forward : Vector3.forward);
		}

		private static bool FindClearRotation(Player player, Vagon cart, ZDOID cartId, out Quaternion rotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0055: 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_0064: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = BodyBounds(cart);
			float[] hitchAngles = HitchAngles;
			foreach (float num in hitchAngles)
			{
				rotation = Quaternion.Euler(0f, num, 0f) * FacingRotation(player);
				if (!Physics.OverlapBox(HitchPosition(player, cart, rotation) + Vector3.up * 0.2f + rotation * ((Bounds)(ref val)).center, ((Bounds)(ref val)).extents, rotation, ObstacleMask.Value, (QueryTriggerInteraction)1).Any((Collider hit) => !IsCart(hit, cartId)))
				{
					return true;
				}
			}
			rotation = Quaternion.identity;
			return false;
		}

		private static bool IsCart(Collider collider, ZDOID cartId)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Vagon componentInParent = ((Component)collider).GetComponentInParent<Vagon>();
			if (Object.op_Implicit((Object)(object)componentInParent) && Object.op_Implicit((Object)(object)componentInParent.m_nview) && componentInParent.m_nview.IsValid())
			{
				return componentInParent.m_nview.GetZDO().m_uid == cartId;
			}
			return false;
		}

		private static Bounds BodyBounds(Vagon cart)
		{
			//IL_0057: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b8: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = (from collider in ((Component)cart).GetComponentsInChildren<Collider>(true)
				where !collider.isTrigger
				select collider).SelectMany((Collider collider) => from corner in Corners(LocalBounds(collider))
				select ((Component)cart).transform.InverseTransformPoint(((Component)collider).transform.TransformPoint(corner))).ToList();
			Vector3 val = ((IEnumerable<Vector3>)list).Aggregate(list[0], (Func<Vector3, Vector3, Vector3>)Vector3.Min);
			Vector3 val2 = ((IEnumerable<Vector3>)list).Aggregate(list[0], (Func<Vector3, Vector3, Vector3>)Vector3.Max);
			val += new Vector3(0.1f, 0.6f, 0.1f);
			val2 -= new Vector3(0.1f, 0f, 0.1f);
			return new Bounds((val + val2) / 2f, val2 - val);
		}

		private static Bounds LocalBounds(Collider collider)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null);
			if (val == null)
			{
				SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null);
				if (val2 == null)
				{
					CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null);
					if (val3 == null)
					{
						MeshCollider val4 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null);
						if (val4 != null && Object.op_Implicit((Object)(object)val4.sharedMesh))
						{
							return val4.sharedMesh.bounds;
						}
						return new Bounds(Vector3.zero, Vector3.zero);
					}
					return new Bounds(val3.center, Vector3.one * Mathf.Max(val3.radius * 2f, val3.height));
				}
				return new Bounds(val2.center, Vector3.one * val2.radius * 2f);
			}
			return new Bounds(val.center, val.size);
		}

		private static IEnumerable<Vector3> Corners(Bounds bounds)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[2]
			{
				((Bounds)(ref bounds)).min.x,
				((Bounds)(ref bounds)).max.x
			};
			foreach (float x in array)
			{
				float[] array2 = new float[2]
				{
					((Bounds)(ref bounds)).min.y,
					((Bounds)(ref bounds)).max.y
				};
				foreach (float y in array2)
				{
					float[] array3 = new float[2]
					{
						((Bounds)(ref bounds)).min.z,
						((Bounds)(ref bounds)).max.z
					};
					foreach (float num in array3)
					{
						yield return new Vector3(x, y, num);
					}
				}
			}
		}

		private static Vector3 HitchPosition(Player player, Vagon cart, Quaternion rotation)
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			Vector3 val = ((Component)cart).transform.InverseTransformPoint(cart.m_attachPoint.position);
			return ((Component)player).transform.position + cart.m_attachOffset - rotation * val;
		}

		private static void Hitch(Player player, Vagon cart, Quaternion rotation)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = HitchPosition(player, cart, rotation);
			((Component)cart).transform.SetPositionAndRotation(val, rotation);
			Rigidbody[] componentsInChildren = ((Component)cart).GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody obj in componentsInChildren)
			{
				obj.linearVelocity = Vector3.zero;
				obj.angularVelocity = Vector3.zero;
			}
			cart.m_body.position = val;
			cart.m_body.rotation = rotation;
			cart.AttachTo(((Component)player).gameObject);
		}

		private static IEnumerator RPC_ServerMoveCart(long sender, ZPackage package)
		{
			MoveCart(sender, package.ReadZDOID(), package.ReadVector3(), package.ReadQuaternion());
			yield break;
		}

		private static IEnumerator RPC_ClientIgnore(long sender, ZPackage package)
		{
			yield break;
		}

		private static void MoveCart(long requester, ZDOID cartId, Vector3 position, Quaternion rotation)
		{
			//IL_0005: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(cartId);
			if (zDO != null && zDO.GetPrefab() == CartHash)
			{
				long owner = zDO.GetOwner();
				if (owner != 0L && owner != requester && ZNet.instance.GetPeer(owner) != null)
				{
					Logger.LogInfo((object)$"Cart {cartId} is in use by {owner}, not moving it for {requester}");
					return;
				}
				zDO.SetOwner(ZDOMan.GetSessionID());
				zDO.SetPosition(position);
				zDO.SetRotation(rotation);
				zDO.SetOwner(requester);
			}
		}
	}
	internal sealed class HubBuilder
	{
		public static readonly string[] DirectionNames = new string[4] { "$obeliskhub_north", "$obeliskhub_east", "$obeliskhub_south", "$obeliskhub_west" };

		private const float FloorThickness = 1f;

		private const string MapTablePrefab = "piece_cartographytable";

		private const string FlatRole = "rug";

		private const int CutCellTiles = 4;

		private const string SignTextFormat = "<voffset=22em><size=2000%>{0}</size>\n<size=700%>{1} $obeliskhub_destinations</size></voffset>";

		private const string ExitNameFormat = "<voffset=26em><size=400%>{0}</size></voffset>";

		private readonly HubLayout layout;

		private readonly HubTheme theme;

		private readonly IReadOnlyDictionary<string, WaypointInfo> waypoints;

		private readonly PiecePlacer placer;

		private readonly RoofBuilder roofBuilder;

		public HubBuilder(Transform root, HubLayout layout, HubTheme theme, IReadOnlyDictionary<string, WaypointInfo> waypoints)
		{
			this.layout = layout;
			this.theme = theme;
			this.waypoints = waypoints;
			placer = new PiecePlacer(root);
			roofBuilder = new RoofBuilder(placer, theme);
		}

		public IEnumerable<object> Build()
		{
			foreach (object item in BuildFloor())
			{
				yield return item;
			}
			foreach (object item2 in BuildWalls())
			{
				yield return item2;
			}
			foreach (object item3 in BuildCeiling())
			{
				yield return item3;
			}
			foreach (object item4 in BuildExits())
			{
				yield return item4;
			}
			foreach (SignSlot sign in layout.Signs)
			{
				string markup = $"<voffset=22em><size=2000%>{DirectionNames[sign.Group]}</size>\n<size=700%>{sign.Count} $obeliskhub_destinations</size></voffset>";
				placer.FloatingText(HubSpace.World(sign.Position), HubSpace.Direction(sign.ReadDirection.Vector()), markup);
				yield return null;
			}
			foreach (object item5 in BuildProps())
			{
				yield return item5;
			}
		}

		private IEnumerable<object> BuildFloor()
		{
			float size = 4f;
			foreach (IGrouping<int, Cell> item in from c in layout.Floor
				group c by c.Z into g
				orderby g.Key
				select g)
			{
				List<int> list = (from c in item
					select c.X into x
					orderby x
					select x).ToList();
				int index = 0;
				for (int num = 1; num <= list.Count; num++)
				{
					if (num >= list.Count || list[num] != list[num - 1] + 1)
					{
						GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
						((Object)obj).name = "FloorCollider";
						obj.transform.SetParent(placer.Root, false);
						obj.transform.position = HubSpace.World(new Vec2((float)(list[index] + list[num - 1]) * size / 2f, (float)item.Key * size), -0.5f);
						obj.transform.localScale = new Vector3((float)(list[num - 1] - list[index] + 1) * size, 1f, size);
						obj.layer = LayerMask.NameToLayer("static_solid");
						((Renderer)obj.GetComponent<MeshRenderer>()).enabled = false;
						index = num;
					}
				}
			}
			PieceTile floorTile = HubPieces.FloorTile(theme.Floor, HubTheme.Stone.Floor);
			PieceTile accentTile = HubPieces.FloorTile(theme.FloorAccent);
			foreach (Cell item2 in layout.Floor)
			{
				PieceTile tile = ((accentTile.IsValid && layout.Accent.Contains(item2)) ? accentTile : floorTile);
				if (!tile.IsValid)
				{
					continue;
				}
				Dir8 value;
				Vector3? cut = (layout.Plan.Cuts.TryGetValue(item2, out value) ? new Vector3?(HubSpace.Direction(value.Vector())) : ((Vector3?)null));
				int across = (cut.HasValue ? 4 : Mathf.Max(1, Mathf.RoundToInt(size / tile.Width)));
				int along = (cut.HasValue ? 4 : Mathf.Max(1, Mathf.RoundToInt(size / tile.Depth)));
				Vector3 scale = new Vector3(size / (float)across / tile.Width, 1f, size / (float)along / tile.Depth);
				Vector3 center = HubSpace.World(item2.Center);
				Vector3 origin = center - new Vector3(size / 2f, 0f, size / 2f);
				for (int i = 0; i < across; i++)
				{
					for (int j = 0; j < along; j++)
					{
						Vector3 val = origin + new Vector3(size / (float)across * ((float)i + 0.5f), 0f, size / (float)along * ((float)j + 0.5f));
						if (!cut.HasValue || !(Vector3.Dot(val - center, cut.Value) > 0.01f))
						{
							placer.Place(tile, val, Quaternion.identity, scale);
							yield return null;
						}
					}
				}
			}
		}

		private List<PieceTile> WallRows(int variant, float height)
		{
			string[][] array = theme.WallStacks ?? HubTheme.Stone.WallStacks;
			string[] array2 = array[Mathf.Clamp(variant, 0, array.Length - 1)];
			List<PieceTile> list = new List<PieceTile>();
			float num = 0f;
			while (list.Count < 16)
			{
				PieceTile item = HubPieces.WallTile(array2[Mathf.Min(list.Count, array2.Length - 1)], HubTheme.Stone.WallStacks[0][0]);
				float num2 = item.Height * theme.WallStretch;
				if (!item.IsValid || (list.Count > 0 && num + num2 / 2f > height))
				{
					break;
				}
				list.Add(item);
				num += num2;
			}
			return list;
		}

		private IEnumerable<object> BuildWalls()
		{
			float height = (float)layout.WallHeight;
			PieceTile cap = HubPieces.WallTile(theme.WallCap);
			float thickness = 0f;
			foreach (WallSegment item in layout.Plan.Walls())
			{
				List<PieceTile> rows = WallRows(item.Variant, height);
				if (rows.Count == 0)
				{
					continue;
				}
				Vector3 a = HubSpace.World(item.A);
				Vector3 b = HubSpace.World(item.B);
				Vector3 outward = HubSpace.Direction(item.Outward);
				float num = Vector3.Distance(a, b);
				if (num < 0.1f)
				{
					continue;
				}
				Vector3 val = (b - a) / num;
				if (Vector3.Dot(Vector3.Cross(val, Vector3.up), outward) < 0f)
				{
					Vector3 val2 = b;
					Vector3 val3 = a;
					_ = -val;
					b = val3;
					a = val2;
				}
				float scaleY = height / rows.Sum((PieceTile r) => r.Height);
				float bottom = 0f;
				foreach (PieceTile item2 in rows)
				{
					float rowHeight = item2.Height * scaleY;
					Vector3 val4 = outward * (item2.Thickness / 2f) + Vector3.up * (bottom + rowHeight / 2f);
					foreach (object item3 in placer.Run(item2, a + val4, b + val4, scaleY, theme.WallStretch))
					{
						yield return item3;
					}
					bottom += rowHeight;
				}
				thickness = Mathf.Max(thickness, rows[0].Thickness);
				Vector3 val5 = outward * (rows[0].Thickness / 2f) + Vector3.up * height;
				if (!cap.IsValid)
				{
					continue;
				}
				foreach (object item4 in placer.Run(cap, a + val5 + Vector3.up * (cap.Height / 2f), b + val5 + Vector3.up * (cap.Height / 2f), 1f))
				{
					yield return item4;
				}
			}
			PieceTile pillar = HubPieces.WallTile(theme.Pillar, HubTheme.Stone.Pillar);
			List<Vec2> columns = (from p in layout.Props
				where p.Kind == PropKind.Column
				select p.Position).ToList();
			Vector3 val6 = default(Vector3);
			foreach (var item5 in layout.Plan.WallCorners())
			{
				var (position, vec) = item5;
				if (columns.Any((Vec2 c) => Vec2.Distance(c, position) < 1.0))
				{
					continue;
				}
				((Vector3)(ref val6))..ctor((float)vec.X, 0f, (float)vec.Z);
				Vector3 val7 = ((((Vector3)(ref val6)).sqrMagnitude > 0.01f) ? (val6 * (thickness / ((Vector3)(ref val6)).sqrMagnitude)) : Vector3.zero);
				foreach (object item6 in placer.Stack(pillar, HubSpace.World(position) + val7, height, Quaternion.LookRotation((((Vector3)(ref val6)).sqrMagnitude > 0.01f) ? val6 : Vector3.forward)))
				{
					yield return item6;
				}
			}
		}

		private IEnumerable<object> BuildCeiling()
		{
			PieceTile tile = HubPieces.FloorTile(theme.Ceiling);
			if (!layout.HasCeiling || !tile.IsValid)
			{
				yield break;
			}
			float num = 4f;
			Vector3 scale = new Vector3(num / tile.Width, 1f, num / tile.Depth);
			float height = (float)layout.WallHeight + tile.Height;
			IEnumerable<Cell> second = from c in layout.Floor.SelectMany((Cell c) => Sides.All.Select((Side s) => c.Step(s)))
				where !layout.Floor.Contains(c) && Sides.All.All((Side s) => layout.Floor.Contains(c.Step(s)))
				select c;
			foreach (Cell item in from c in layout.Floor.Concat(second).Distinct()
				where !layout.CeilingOpen.Contains(c)
				select c)
			{
				placer.Place(tile, HubSpace.World(item.Center, height), Quaternion.identity, scale);
				yield return null;
			}
		}

		private IEnumerable<object> BuildExits()
		{
			GameObject exitPrefab = ZNetScene.instance.GetPrefab("obeliskhub_obelisk");
			if (!Object.op_Implicit((Object)(object)exitPrefab))
			{
				Logger.LogError((object)"obeliskhub_obelisk prefab not found, Hub has no exits");
				yield break;
			}
			PieceTile upgradeTile = HubPieces.FloorTile("obeliskhub_upgrade");
			foreach (ExitSlot exit in layout.Exits)
			{
				if (waypoints.TryGetValue(exit.Key, out var value))
				{
					Vector3 val = HubSpace.Direction(exit.Facing.Vector());
					Quaternion val2 = Quaternion.LookRotation(val);
					Vector3 val3 = HubSpace.World(exit.Position);
					if (upgradeTile.IsValid)
					{
						val3 += Vector3.up * upgradeTile.Height;
						placer.Visual(upgradeTile.Prefab, val3 - val2 * upgradeTile.Anchor, val2);
					}
					GameObject obj = placer.Visual(exitPrefab, val3, val2);
					((Object)obj).name = "ObeliskHub_Exit (" + exit.DisplayName + ")";
					obj.AddComponent<HubExit>().Initialize(value, exit.DisplayName);
					placer.FloatingText(val3, -val, $"<voffset=26em><size=400%>{exit.DisplayName}</size></voffset>");
					yield return null;
				}
			}
		}

		private IEnumerable<object> BuildProps()
		{
			PieceTile column = HubPieces.WallTile(theme.Column, HubTheme.Stone.Column);
			PieceTile beam = HubPieces.WallTile(theme.Beam, HubTheme.Stone.Beam);
			PieceTile arch = HubPieces.WallTile(theme.Arch);
			int roofs = 0;
			foreach (Prop prop in layout.Props)
			{
				Vector3 val = HubSpace.Direction(prop.Facing);
				switch (prop.Kind)
				{
				case PropKind.MapTable:
				{
					GameObject prefab = ZNetScene.instance.GetPrefab("piece_cartographytable");
					if (!Object.op_Implicit((Object)(object)prefab))
					{
						break;
					}
					GameObject obj = placer.Visual(prefab, HubSpace.World(prop.Position), Quaternion.LookRotation(val));
					((Object)obj).name = "ObeliskHub_MapTable";
					obj.AddComponent<HubMapTable>().Initialize((from @group in Enumerable.Range(0, DirectionNames.Length)
						select (from e in layout.Exits
							where e.Group == @group
							orderby e.Number
							select e.DisplayName).ToList()).ToArray());
					break;
				}
				case PropKind.Light:
					placer.Light(HubSpace.World(prop.Position, (float)prop.Height), (float)prop.Range, theme.LightIntensity, theme.LightColor);
					break;
				case PropKind.Column:
					foreach (object item in placer.Stack(column, HubSpace.World(prop.Position), (float)prop.Height, Quaternion.identity))
					{
						yield return item;
					}
					break;
				case PropKind.Beam:
					foreach (object item2 in placer.Bar(beam, HubSpace.World(prop.Position), HubSpace.World(prop.End), (float)prop.Height))
					{
						yield return item2;
					}
					break;
				case PropKind.Arch:
					if (arch.IsValid)
					{
						placer.Arch(arch, HubSpace.World(prop.Position), HubSpace.World(prop.End), (float)prop.Height);
						break;
					}
					foreach (object item3 in placer.Bar(beam, HubSpace.World(prop.Position), HubSpace.World(prop.End), (float)prop.Height))
					{
						yield return item3;
					}
					break;
				case PropKind.GableEnd:
					foreach (object item4 in BuildGableEnd(prop))
					{
						yield return item4;
					}
					break;
				case PropKind.Roof:
					foreach (object item5 in roofBuilder.Build(prop, roofs++))
					{
						yield return item5;
					}
					break;
				case PropKind.Piece:
					BuildPiece(prop);
					break;
				}
				yield return null;
			}
		}

		private IEnumerable<object> BuildGableEnd(Prop prop)
		{
			PieceTile tile = HubPieces.WallTile((theme.WallStacks ?? HubTheme.Stone.WallStacks)[0][0]);
			if (!tile.IsValid)
			{
				yield break;
			}
			Vector3 a = HubSpace.World(prop.Position);
			Vector3 b = HubSpace.World(prop.End);
			Vector3 middle = (a + b) / 2f;
			Vector3 outward = HubSpace.Direction(prop.Facing) * (tile.Thickness / 2f);
			float rowHeight = tile.Height * theme.WallStretch;
			int rows = Mathf.CeilToInt((float)prop.Width / rowHeight);
			for (int row = 0; row < rows; row++)
			{
				float num = 1f - (float)row * rowHeight / (float)prop.Width;
				Vector3 val = outward + Vector3.up * ((float)prop.Height + rowHeight * ((float)row + 0.5f));
				foreach (object item in placer.Run(tile, Vector3.Lerp(middle, a, num) + val, Vector3.Lerp(middle, b, num) + val, theme.WallStretch, theme.WallStretch))
				{
					yield return item;
				}
			}
		}

		private void BuildPiece(Prop prop)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (!theme.Roles.TryGetValue(prop.Role ?? "", out var value) || value.Length == 0)
			{
				return;
			}
			string text = value[Mathf.Abs(prop.Variant) % value.Length];
			Vector3 val = HubSpace.Direction(prop.Facing);
			if (((Vector3)(ref val)).sqrMagnitude < 0.5f)
			{
				val = Vector3.forward;
			}
			switch (prop.Mount)
			{
			case Mount.Plant:
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				if (Object.op_Implicit((Object)(object)prefab))
				{
					placer.Visual(prefab, HubSpace.World(prop.Position, (float)prop.Height), Quaternion.LookRotation(val));
				}
				else
				{
					placer.WarnMissing(text);
				}
				break;
			}
			case Mount.Ceiling:
				placer.HangFrom(text, HubSpace.World(prop.Position, (float)prop.Height), Quaternion.LookRotation(val));
				break;
			case Mount.Floor:
			case Mount.Top:
			{
				GameObject val2 = placer.StandOn(text, HubSpace.World(prop.Position, (float)prop.Height), Quaternion.LookRotation(val));
				if (Object.op_Implicit((Object)(object)val2) && prop.Role == "rug")
				{
					HubPieces.RemoveColliders(val2);
				}
				break;
			}
			case Mount.Wall:
				placer.HangOnWall(text, HubSpace.World(prop.Position, (float)prop.Height), val);
				break;
			}
		}
	}
	internal sealed class HubController : MonoBehaviour
	{
		private const float BuildBudgetMs = 3f;

		private const int RetireBatch = 200;

		private const float FinalWarningSeconds = 10f;

		private static HubController instance;

		private GameObject built;

		private GameObject retiring;

		private Coroutine building;

		private HubLayout currentLayout;

		private bool warned;

		private bool finalWarned;

		public static HubLayout CurrentLayout
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				return instance.currentLayout;
			}
		}

		public static Vector3 ArrivalPoint
		{
			get
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				HubLayout hubLayout = CurrentLayout;
				Vector3 val = (Vector3)((hubLayout == null) ? Vector3.zero : new Vector3((float)hubLayout.Arrival.X, 0f, (float)hubLayout.Arrival.Z));
				return HubSpace.Center + Vector3.up * 0.5f + val;
			}
		}

		public static Quaternion ArrivalRotation
		{
			get
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				Vec2 vec = (CurrentLayout?.ArrivalFacing ?? Side.North).Vector();
				return Quaternion.LookRotation(new Vector3((float)vec.X, 0f, (float)vec.Z));
			}
		}

		private static bool IsHeadless => (int)SystemInfo.graphicsDeviceType == 4;

		public static void EnsureCreated()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)instance) && !IsHeadless)
			{
				instance = new GameObject("ObeliskHub_Hub").AddComponent<HubController>();
				instance.Rebuild(WaypointRegistry.LayoutWaypoints, WaypointRegistry.LayoutStyle);
			}
		}

		public static void RebuildIfCreated(IReadOnlyList<WaypointInfo> waypoints, string style)
		{
			if (Object.op_Implicit((Object)(object)instance))
			{
				instance.Rebuild(waypoints, style);
			}
		}

		private void Rebuild(IReadOnlyList<WaypointInfo> waypoints, string style)
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			Dictionary<string, WaypointInfo> waypoints2 = waypoints.ToDictionary((WaypointInfo w) => w.LayoutKey);
			List<WaypointEntry> entries = waypoints.Select((WaypointInfo w) => w.ToLayoutEntry()).ToList();
			HubLayout hubLayout = HubGenerator.Generate(style, entries);
			foreach (string note in hubLayout.Notes)
			{
				Logger.LogWarning((object)("Hub layout: " + note));
			}
			foreach (string item in Validator.Validate(hubLayout, entries).Take(10))
			{
				Logger.LogError((object)("Hub layout (" + hubLayout.Style + "): " + item));
			}
			if (building != null)
			{
				((MonoBehaviour)this).StopCoroutine(building);
				building = null;
			}
			if (Object.op_Implicit((Object)(object)retiring))
			{
				Object.Destroy((Object)(object)retiring);
			}
			retiring = built;
			if (Object.op_Implicit((Object)(object)retiring))
			{
				retiring.SetActive(false);
			}
			built = new GameObject("ObeliskHub_Layout");
			built.transform.SetParent(((Component)this).transform, false);
			currentLayout = hubLayout;
			HubMapPins.RenameExisting();
			building = ((MonoBehaviour)this).StartCoroutine(BuildOverFrames(built.transform, hubLayout, waypoints2));
		}

		private IEnumerator BuildOverFrames(Transform target, HubLayout layout, IReadOnlyDictionary<string, WaypointInfo> waypoints)
		{
			Stopwatch clock = Stopwatch.StartNew();
			Stopwatch total = Stopwatch.StartNew();
			int frames = 1;
			HubBuilder hubBuilder = new HubBuilder(target, layout, HubTheme.For(layout.Style), waypoints);
			using IEnumerator<object> steps = hubBuilder.Build().GetEnumerator();
			bool more = steps.MoveNext();
			if (Object.op_Implicit((Object)(object)retiring))
			{
				for (int i = retiring.transform.childCount - 1; i >= 0; i--)
				{
					Object.Destroy((Object)(object)((Component)retiring.transform.GetChild(i)).gameObject);
					if (i % 200 == 0)
					{
						yield return null;
						frames++;
					}
				}
				Object.Destroy((Object)(object)retiring);
				retiring = null;
			}
			clock.Restart();
			while (more)
			{
				if (clock.Elapsed.TotalMilliseconds >= 3.0)
				{
					yield return null;
					frames++;
					clock.Restart();
				}
				more = steps.MoveNext();
			}
			building = null;
			Logger.LogInfo((object)($"Hub rebuilt: {layout.Style}, {layout.Exits.Count} exits, {layout.Floor.Count} cells, " + $"{target.childCount} objects over {frames} frames ({total.Elapsed.TotalSeconds:0.0} s)"));
		}

		private void Update()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			HubEnvironment.UpdateLocalPlayer(localPlayer);
			if (Object.op_Implicit((Object)(object)localPlayer) && !((Character)localPlayer).IsTeleporting() && !((Character)localPlayer).IsDead())
			{
				Vector3 position = ((Component)localPlayer).transform.position;
				if (!HubSpace.Contains(position))
				{
					ResetWarnings();
				}
				else if (position.y < HubSpace.Center.y - 30f)
				{
					((Character)localPlayer).TeleportTo(ArrivalPoint, ArrivalRotation, false);
				}
				else if (WaypointRegistry.IsReorganizing)
				{
					UpdateEviction(localPlayer);
				}
				else
				{
					ResetWarnings();
				}
			}
		}

		private void UpdateEviction(Player player)
		{
			float num = WaypointRegistry.EvictTime - Time.time;
			if (num <= 0f)
			{
				if (Travel.ReturnToEntryPoint(player))
				{
					((Character)player).Message((MessageType)2, "$obeliskhub_returned", 0, (Sprite)null, false);
				}
			}
			else if (!warned || (!finalWarned && num <= 10f))
			{
				finalWarned = warned && num <= 10f;
				warned = true;
				((Character)player).Message((MessageType)2, Localization.instance.Localize("$obeliskhub_reorganizing", new string[1] { Mathf.CeilToInt(num).ToString() }), 0, (Sprite)null, false);
			}
		}

		private void ResetWarnings()
		{
			warned = false;
			finalWarned = false;
		}
	}
	internal static class HubDecorations
	{
		private static readonly Type[] FunctionalComponents = new Type[23]
		{
			typeof(Container),
			typeof(Bed),
			typeof(CraftingStation),
			typeof(StationExtension),
			typeof(CookingStation),
			typeof(Smelter),
			typeof(Fermenter),
			typeof(Beehive),
			typeof(SapCollector),
			typeof(Incinerator),
			typeof(Turret),
			typeof(PrivateArea),
			typeof(ShieldGenerator),
			typeof(TeleportWorld),
			typeof(Ship),
			typeof(Vagon),
			typeof(Plant),
			typeof(Pickable),
			typeof(TerrainModifier),
			typeof(TerrainOp),
			typeof(Obelisk),
			typeof(Waypoint),
			typeof(ObeliskUpgrade)
		};

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

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

		public static bool IsRemovingPiece { get; set; }

		public static bool IsBuildZone(Vector3 point)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (IsRemovingPiece)
			{
				return true;
			}
			return HubController.CurrentLayout?.CanDecorate(new Vec2(point.x - HubSpace.Center.x, point.z - HubSpace.Center.z)) ?? false;
		}

		public static bool IsDecoration(Piece piece)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!DecorationsByName.TryGetValue(piece.m_name, out var value))
			{
				value = ((int)piece.m_category == 4 || (int)piece.m_category == 0) && !HasFunctionalComponent(piece);
				DecorationsByName[piece.m_name] = value;
			}
			return value;
		}

		public static CraftingStation FindStation(string name)
		{
			if (StationsByName.TryGetValue(name, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				value = prefab.GetComponent<CraftingStation>();
				if (Object.op_Implicit((Object)(object)value) && value.m_name == name)
				{
					StationsByName[name] = value;
					return value;
				}
			}
			return null;
		}

		private static bool HasFunctionalComponent(Piece piece)
		{
			Type[] functionalComponents = FunctionalComponents;
			foreach (Type type in functionalComponents)
			{
				if (Object.op_Implicit((Object)(object)((Component)piece).GetComponentInChildren(type, true)))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class HubEnvironment
	{
		private const string EnvironmentPrefix = "ObeliskHub_Void_";

		private const string BaseEnvironment = "Clear";

		private static string currentEnvironment;

		private static MapMode modeBeforeEntering = (MapMode)1;

		public static bool IsInside { get; private set; }

		public static void ResetSession()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			IsInside = false;
			currentEnvironment = null;
			modeBeforeEntering = (MapMode)1;
		}

		public static void UpdateLocalPlayer(Player player)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Object.op_Implicit((Object)(object)player) && HubSpace.Contains(((Component)player).transform.position);
			if (flag && !IsInside)
			{
				IsInside = true;
				Enter();
			}
			else if (!flag && IsInside)
			{
				IsInside = false;
				Exit();
			}
			if (IsInside && Object.op_Implicit((Object)(object)EnvMan.instance) && currentEnvironment != null && EnvMan.instance.m_forceEnv != currentEnvironment)
			{
				EnvMan.instance.SetForceEnvironment(currentEnvironment);
			}
		}

		private static void Enter()
		{
			//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)
			if (Object.op_Implicit((Object)(object)EnvMan.instance))
			{
				string layoutStyle = WaypointRegistry.LayoutStyle;
				currentEnvironment = "ObeliskHub_Void_" + layoutStyle;
				RegisterEnvironment(currentEnvironment, HubTheme.For(layoutStyle).Mood);
				EnvMan.instance.SetForceEnvironment(currentEnvironment);
			}
			if (Object.op_Implicit((Object)(object)Minimap.instance))
			{
				modeBeforeEntering = Minimap.instance.m_mode;
				Minimap.instance.SetMapMode((MapMode)0);
			}
		}

		private static void Exit()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)EnvMan.instance) && EnvMan.instance.m_forceEnv == currentEnvironment)
			{
				EnvMan.instance.SetForceEnvironment("");
			}
			if (Object.op_Implicit((Object)(object)Minimap.instance) && !Game.m_noMap && (int)modeBeforeEntering != 0)
			{
				Minimap.instance.SetMapMode((MapMode)1);
			}
		}

		private static void RegisterEnvironment(string name, HubMood mood)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			if (EnvMan.instance.GetEnv(name) == null)
			{
				EnvSetup val = EnvMan.instance.GetEnv("Clear") ?? EnvMan.instance.m_environments[0];
				EnvSetup val2 = val.Clone();
				val2.m_name = name;
				val2.m_default = false;
				val2.m_isWet = (val2.m_isCold = (val2.m_isColdAtNight = (val2.m_isFreezing = (val2.m_isFreezingAtNight = false))));
				val2.m_alwaysDark = false;
				val2.m_snowBuildup = 0f;
				val2.m_fogColorNight = (val2.m_fogColorMorning = (val2.m_fogColorDay = (val2.m_fogColorEvening = mood.Fog)));
				val2.m_fogColorSunNight = (val2.m_fogColorSunMorning = (val2.m_fogColorSunDay = (val2.m_fogColorSunEvening = mood.Fog)));
				val2.m_fogDensityNight = (val2.m_fogDensityMorning = (val2.m_fogDensityDay = (val2.m_fogDensityEvening = mood.FogDensity)));
				val2.m_ambColorDay = (val2.m_ambColorNight = mood.Ambient);
				val2.m_sunColorNight = (val2.m_sunColorMorning = (val2.m_sunColorDay = (val2.m_sunColorEvening = Color.black)));
				val2.m_lightIntensityDay = (val2.m_lightIntensityNight = 1f);
				val2.m_psystems = (GameObject[])(object)new GameObject[0];
				val2.m_envObject = null;
				val2.m_rainCloudAlpha = 0f;
				val2.m_cloudOpacityNight = (val2.m_cloudOpacityMorning = (val2.m_cloudOpacityDay = (val2.m_cloudOpacityEvening = 0f)));
				val2.m_auroraIntensityNight = (val2.m_auroraIntensityMorning = (val2.m_auroraIntensityDay = (val2.m_auroraIntensityEvening = 0f)));
				val2.m_windMin = (val2.m_windMax = 0f);
				val2.m_ambientLoop = null;
				val2.m_ambientVol = 0f;
				val2.m_ambientList = "";
				val2.m_musicMorning = (val2.m_musicDay = (val2.m_musicEvening = (val2.m_musicNight = "")));
				EnvMan.instance.AppendEnvironment(val2);
				Logger.LogInfo((object)("Registered " + name + " environment (based on " + val.m_name + ")"));
			}
		}
	}
	[RequireComponent(typeof(HoverRing))]
	internal sealed class HubExit : MonoBehaviour, Hoverable, Interactable
	{
		private WaypointInfo waypoint;

		private string displayName;

		private HoverRing hoverRing;

		public void Initialize(WaypointInfo target, string name)
		{
			waypoint = target;
			displayName = name;
		}

		private void Awake()
		{
			hoverRing = ((Component)this).GetComponent<HoverRing>();
		}

		public string GetHoverName()
		{
			return displayName;
		}

		public string GetHoverText()
		{
			hoverRing.Show();
			return Localization.instance.Localize("$piece_obeliskhub_obelisk \"" + displayName + "\"\n[<color=yellow><b>$KEY_Use</b></color>] $obeliskhub_travel");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer || ((Character)(Player)user).IsTeleporting())
			{
				return false;
			}
			WaypointInfo waypointInfo = WaypointRegistry.FindLive(waypoint.Id);
			if (waypointInfo == null)
			{
				((Character)user).Message((MessageType)2, "$obeliskhub_waypoint_gone", 0, (Sprite)null, false);
				return false;
			}
			return Travel.Teleport((Player)user, waypointInfo.Position + Vector3.up, waypointInfo.Rotation);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal static class HubMapPins
	{
		private const PinType PinType = (PinType)6;

		private const float SamePlaceDistance = 1f;

		public static void RenameExisting()
		{
			//IL_0056: 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)
			if (!Object.op_Implicit((Object)(object)Minimap.instance))
			{
				return;
			}
			foreach (var item3 in Destinations())
			{
				WaypointInfo item = item3.Waypoint;
				string item2 = item3.Name;
				PinData val = FindPin(item);
				if (val != null && val.m_name != item2)
				{
					Minimap.instance.RemovePin(val);
					Minimap.instance.AddPin(item.Position, (PinType)6, item2, true, val.m_checked, val.m_ownerID, val.m_author);
				}
			}
		}

		public static int AddMissing()
		{
			//IL_0028: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			RenameExisting();
			int num = 0;
			foreach (var (waypointInfo, text) in Destinations())
			{
				if (WaypointRegistry.FindLive(waypointInfo.Id) != null && FindPin(waypointInfo) == null)
				{
					Minimap.instance.AddPin(waypointInfo.Position, (PinType)6, text, true, false, 0L, default(PlatformUserID));
					num++;
				}
			}
			return num;
		}

		private static IEnumerable<(WaypointInfo Waypoint, string Name)> Destinations()
		{
			HubLayout currentLayout = HubController.CurrentLayout;
			if (currentLayout == null)
			{
				yield break;
			}
			Dictionary<string, WaypointInfo> waypoints = WaypointRegistry.LayoutWaypoints.ToDictionary((WaypointInfo w) => w.LayoutKey);
			foreach (ExitSlot exit in currentLayout.Exits)
			{
				if (waypoints.TryGetValue(exit.Key, out var value))
				{
					yield return (Waypoint: value, Name: exit.DisplayName);
				}
			}
		}

		private static PinData FindPin(WaypointInfo waypoint)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_002c: 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)
			foreach (PinData pin in Minimap.instance.m_pins)
			{
				if ((int)pin.m_type == 6 && pin.m_save && Utils.DistanceXZ(pin.m_pos, waypoint.Position) < 1f)
				{
					return pin;
				}
			}
			return null;
		}
	}
	internal sealed class HubMapTable : MonoBehaviour, Hoverable, Interactable
	{
		private List<string>[] halls;

		public void Initialize(List<string>[] destinationsByHall)
		{
			halls = destinationsByHall;
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$obeliskhub_map_title");
		}

		public string GetHoverText()
		{
			return Localization.instance.Localize("$obeliskhub_map_title\n[<color=yellow><b>$KEY_Use</b></color>] $obeliskhub_map_read");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold || (Object)(object)user != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			IEnumerable<string> values = from d in Enumerable.Range(0, halls.Length)
				where halls[d].Count > 0
				select "<b>" + HubBuilder.DirectionNames[d] + "</b>\n" + string.Join("\n", halls[d]);
			TextViewer.instance.ShowText((Style)0, "$obeliskhub_map_title", Localization.instance.Localize(string.Join("\n\n", values)), true);
			int num = HubMapPins.AddMissing();
			((Character)user).Message((MessageType)1, Localization.instance.Localize("$obeliskhub_map_pins_added", new string[1] { num.ToString() }), 0, (Sprite)null, false);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal sealed class HubMood
	{
		public static readonly HubMood Default = new HubMood
		{
			Fog = new Color(0.12f, 0.08f, 0.2f),
			FogDensity = 0.02f,
			Ambient = new Color(0.55f, 0.5f, 0.68f)
		};

		public Color Fog;

		public float FogDensity;

		public Color Ambient;
	}
	internal static class HubPieces
	{
		private const string SignPrefab = "sign";

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

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

		private static readonly Dictionary<string, Bounds?> Meshes = new Dictionary<string, Bounds?>();

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

		private static readonly int AshlandsDamageShaderId = Shader.PropertyToID("_TakingAshlandsDamage");

		public static PieceTile FloorTile(params string[] names)
		{
			return FindTile(floor: true, names);
		}

		public static PieceTile WallTile(params string[] names)
		{
			return FindTile(floor: false, names);
		}

		private static PieceTile FindTile(bool floor, string[] names)
		{
			foreach (string text in names)
			{
				if (!string.IsNullOrEmpty(text))
				{
					string key = (floor ? "floor:" : "wall:") + text;
					if (!Tiles.TryGetValue(key, out var value))
					{
						value = (Tiles[key] = (floor ? PieceTile.MeasureFloor(text) : PieceTile.MeasureWall(text)));
					}
					if (value.IsValid)
					{
						return value;
					}
				}
			}
			return default(PieceTile);
		}

		public static RoofTile Roof(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return default(RoofTile);
			}
			if (!Roofs.TryGetValue(name, out var value))
			{
				value = (Roofs[name] = RoofTile.Measure(name));
			}
			return value;
		}

		public static float ArchSpringSide(PieceTile tile)
		{
			string name = ((Object)tile.Prefab).name;
			if (!ArchSprings.TryGetValue(name, out var value))
			{
				value = (ArchSprings[name] = MeasureArchSpring(tile));
			}
			return value;
		}

		private static float MeasureArchSpring(PieceTile tile)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateVisual(tile.Prefab, Vector3.zero, Quaternion.identity, null);
			List<Vector3> list = new List<Vector3>();
			MeshFilter[] componentsInChildren = val.GetComponentsInChildren<MeshFilter>();
			foreach (MeshFilter val2 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val2.sharedMesh) && val2.sharedMesh.isReadable)
				{
					list.AddRange(((IEnumerable<Vector3>)val2.sharedMesh.vertices).Select((Func<Vector3, Vector3>)((Component)val2).transform.TransformPoint));
				}
			}
			Object.DestroyImmediate((Object)(object)val);
			if (list.Count == 0)
			{
				Logger.LogWarning((object)(((Object)tile.Prefab).name + ": mesh is not readable, assuming which end of the arch springs"));
				return 1f;
			}
			List<float> source = list.Select((Vector3 p) => Vector3.Dot(p, tile.WideAxis)).ToList();
			float bottom = list.Min((Vector3 p) => p.y);
			float num = (((from p in list
				where p.y < bottom + 0.1f
				select Vector3.Dot(p, tile.WideAxis)).Average() > (source.Min() + source.Max()) / 2f) ? 1f : (-1f));
			Logger.LogInfo((object)$"{((Object)tile.Prefab).name}: arch springs from its {num:+0;-0} end");
			return num;
		}

		public static Bounds? MeshBounds(string name, out GameObject prefab)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			prefab = (string.IsNullOrEmpty(name) ? null : ZNetScene.instance.GetPrefab(name));
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return null;
			}
			if (!Meshes.TryGetValue(name, out var value))
			{
				value = (Meshes[name] = (Probe(prefab, out var mesh, out var _) ? new Bounds?(mesh) : ((Bounds?)null)));
			}
			return value;
		}

		public static GameObject CreateVisual(GameObject prefab, Vector3 position, Quaternion rotation, Transform parent)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ZNetView.m_forceDisableInit = true;
			GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation, parent);
			ZNetView.m_forceDisableInit = false;
			WearNTear[] componentsInChildren = val.GetComponentsInChildren<WearNTear>(true);
			foreach (WearNTear val2 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val2.m_new))
				{
					if (Object.op_Implicit((Object)(object)val2.m_worn) && (Object)(object)val2.m_worn != (Object)(object)val2.m_new)
					{
						val2.m_worn.SetActive(false);
					}
					if (Object.op_Implicit((Object)(object)val2.m_broken) && (Object)(object)val2.m_broken != (Object)(object)val2.m_new)
					{
						val2.m_broken.SetActive(false);
					}
					val2.m_new.SetActive(true);
				}
				if (Object.op_Implicit((Object)(object)val2.m_wet))
				{
					val2.m_wet.SetActive(false);
				}
				MeshRenderer[] array = (MeshRenderer[])(object)new MeshRenderer[3] { val2.m_snow, val2.m_snowWorn, val2.m_snowBroken };
				foreach (MeshRenderer val3 in array)
				{
					if (Object.op_Implicit((Object)(object)val3))
					{
						((Renderer)val3).enabled = false;
					}
				}
			}
			Fireplace[] componentsInChildren2 = val.GetComponentsInChildren<Fireplace>(true);
			foreach (Fireplace obj in componentsInChildren2)
			{
				SetActive(obj.m_enabledObject, active: true);
				SetActive(obj.m_enabledObjectHigh, active: true);
				SetActive(obj.m_enabledObjectLow, active: false);
				SetActive(obj.m_fullObject, active: true);
				SetActive(obj.m_halfObject, active: false);
				SetActive(obj.m_emptyObject, active: false);
			}
			MonoBehaviour[] componentsInChildren3 = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val4 in componentsInChildren3)
			{
				string text = ((object)val4).GetType().Namespace;
				if (!(val4 is ZNetView) && !(val4 is Chair) && text != "TMPro" && text != "UnityEngine.UI")
				{
					Object.DestroyImmediate((Object)(object)val4);
				}
			}
			Rigidbody[] componentsInChildren4 = val.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			Object.DestroyImmediate((Object)(object)val.GetComponent<ZNetView>());
			if (Object.op_Implicit((Object)(object)MaterialMan.instance))
			{
				MaterialMan.instance.SetValue<float>(val, AshlandsDamageShaderId, 0f, true);
			}
			return val;
		}

		private static void SetActive(GameObject go, bool active)
		{
			if (Object.op_Implicit((Object)(object)go))
			{
				go.SetActive(active);
			}
		}

		public static void CreateFloatingText(Transform root, Vector3 position, Vector3 awayFromViewer, string markup)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = ZNetScene.instance.GetPrefab("sign");
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return;
			}
			GameObject val = CreateVisual(prefab, position, Quaternion.LookRotation(awayFromViewer), root);
			((Object)val).name = "ObeliskHub_FloatingText";
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			RemoveColliders(val);
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				if (Vector3.Dot(componentInChildren.transform.forward, awayFromViewer) < 0f)
				{
					val.transform.Rotate(Vector3.up, 180f, (Space)0);
				}
				componentInChildren.textWrappingMode = (TextWrappingModes)0;
				componentInChildren.overflowMode = (TextOverflowModes)0;
				componentInChildren.alignment = (TextAlignmentOptions)514;
				componentInChildren.text = Localization.instance.Localize(markup);
			}
		}

		public static void RemoveColliders(GameObject go)
		{
			Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)comp