Decompiled source of Platform Zero v0.2.0

BepInEx/plugins/PlatformZero/PlatformZero.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLevelLoader;
using TMPro;
using Unity.AI.Navigation;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyVersion("0.2.0.0")]
namespace PlatformZero;

internal static class InteriorRegistration
{
	internal static ExtendedDungeonFlow Interior;

	internal static void Register()
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Expected O, but got Unknown
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected O, but got Unknown
		if ((Object)(object)Interior != (Object)null)
		{
			return;
		}
		try
		{
			DungeonFlow val = ((IEnumerable<DungeonFlow>)OriginalContent.DungeonFlows).FirstOrDefault((Func<DungeonFlow, bool>)((DungeonFlow f) => ((Object)f).name == "Level1Flow"));
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Factory template not found.");
			}
			DungeonFlow val2 = Object.Instantiate<DungeonFlow>(val);
			((Object)val2).name = "PlatformZeroFlow";
			ExtendedDungeonFlow val3 = ScriptableObject.CreateInstance<ExtendedDungeonFlow>();
			((Object)val3).name = "PlatformZeroExtendedDungeonFlow";
			val3.DungeonFlow = val2;
			val3.DungeonName = "Platform Zero";
			RoundManager val4 = Object.FindObjectOfType<RoundManager>(true);
			val3.FirstTimeDungeonAudio = val4.firstTimeDungeonAudios[0];
			val3.MapTileSize = val4.dungeonFlowTypes[0].MapTileSize;
			val3.IsDynamicOutOfBoundsTriggerEnabled = false;
			val3.IsDynamicDungeonSizeRestrictionEnabled = true;
			val3.DynamicDungeonSizeMinMax = new Vector2(1f, 1f);
			val3.DynamicDungeonSizeLerpRate = 1f;
			val3.LevelMatchingProperties = LevelMatchingProperties.Create((ExtendedContent)(object)val3);
			val3.LevelMatchingProperties.levelTags.Add(new StringWithRarity("Vanilla", 150));
			val3.LevelMatchingProperties.levelTags.Add(new StringWithRarity("Custom", 150));
			val3.LevelMatchingProperties.levelTags.Add(new StringWithRarity("Modded", 150));
			PatchedContent.RegisterExtendedDungeonFlow(val3);
			Interior = val3;
			Plugin.Log.LogInfo((object)"Registered PlatformZeroFlow with LethalLevelLoader; global interior randomizers can discover it.");
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)("Platform Zero registration failed; preserving other interiors. " + ex));
		}
	}

	internal static bool Selected(RoundManager round)
	{
		if ((Object)(object)Interior != (Object)null && (Object)(object)round.currentLevel != (Object)null && round.currentLevel.spawnEnemiesAndScrap && (Object)(object)round.dungeonGenerator != (Object)null)
		{
			return (Object)(object)round.dungeonGenerator.Generator.DungeonFlow == (Object)(object)Interior.DungeonFlow;
		}
		return false;
	}
}
[HarmonyPatch(typeof(AssetBundleLoader), "CreateVanillaExtendedDungeonFlows")]
internal static class RegisterAfterVanillaFlows
{
	private static void Postfix()
	{
		InteriorRegistration.Register();
	}
}
[HarmonyPatch(typeof(DungeonManager), "GetValidExtendedDungeonFlows")]
internal static class FairInteriorWeight
{
	[HarmonyPriority(0)]
	private static void Postfix(ExtendedLevel __0, List<ExtendedDungeonFlowWithRarity> __result)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Expected O, but got Unknown
		ExtendedDungeonFlow entry = InteriorRegistration.Interior;
		if (!((Object)(object)entry == (Object)null) && !((Object)(object)__0 == (Object)null) && !((Object)(object)__0.SelectableLevel == (Object)null) && __0.SelectableLevel.spawnEnemiesAndScrap && !Chainloader.PluginInfos.ContainsKey("Hibyhii.RandomInteriors") && Plugin.Instance.AdaptiveWeight.Value)
		{
			int num = StationPlan.FairWeight(from x in __result
				where (Object)(object)x.extendedDungeonFlow != (Object)(object)entry
				select x.rarity);
			ExtendedDungeonFlowWithRarity val = ((IEnumerable<ExtendedDungeonFlowWithRarity>)__result).FirstOrDefault((Func<ExtendedDungeonFlowWithRarity, bool>)((ExtendedDungeonFlowWithRarity x) => (Object)(object)x.extendedDungeonFlow == (Object)(object)entry));
			if (val == null)
			{
				__result.Add(new ExtendedDungeonFlowWithRarity(entry, num));
			}
			else
			{
				val.rarity = num;
			}
		}
	}
}
[HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")]
internal static class ProgressionLoot
{
	internal sealed class State
	{
		internal float Previous;

		internal bool Changed;
	}

	[HarmonyPriority(0)]
	private static void Prefix(RoundManager __instance, out State __state)
	{
		__state = new State();
		if (((NetworkBehaviour)__instance).IsServer && !((Object)(object)Plugin.Instance.Station == (Object)null) && Plugin.Instance.ProgressionLoot.Value)
		{
			int num = ((!((Object)(object)TimeOfDay.Instance == (Object)null)) ? TimeOfDay.Instance.timesFulfilledQuota : 0);
			float num2 = StationPlan.LootFactor(num);
			__state.Previous = __instance.scrapAmountMultiplier;
			__state.Changed = true;
			__instance.scrapAmountMultiplier *= num2;
			Plugin.Log.LogInfo((object)("Platform Zero scrap count factor " + num2 + "; completed quotas " + num + "."));
		}
	}

	private static Exception Finalizer(RoundManager __instance, State __state, Exception __exception)
	{
		if (__state != null && __state.Changed)
		{
			__instance.scrapAmountMultiplier = __state.Previous;
		}
		return __exception;
	}
}
[BepInPlugin("local.platformzero", "Platform Zero", "0.2.0")]
[BepInDependency("imabatby.lethallevelloader", "1.7.13")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Id = "local.platformzero";

	public const string Version = "0.2.0";

	private const string RequestMessage = "local.platformzero.request.v2";

	private const string EventMessage = "local.platformzero.event.v2";

	internal static Plugin Instance;

	internal static ManualLogSource Log;

	internal Station Station;

	internal ConfigEntry<bool> AdaptiveWeight;

	internal ConfigEntry<bool> ProgressionLoot;

	private NetworkManager network;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		AdaptiveWeight = ((BaseUnityPlugin)this).Config.Bind<bool>("Selection", "Adaptive fair weight", true, "Without Random Interiors, give Platform Zero the average positive weight of the other eligible interiors on each moon. Disable to use LethalLevelLoader manual weights/exclusions. Random Interiors always keeps control when installed.");
		ProgressionLoot = ((BaseUnityPlugin)this).Config.Bind<bool>("Loot", "Progression bonus", true, "Host setting: +5% scrap count per completed quota, capped at +25%, on Platform Zero only. Values are unchanged.");
		harmony = new Harmony("local.platformzero");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Platform Zero 0.2.0: randomized rooms, registered interior selection and quota-based loot. All players need this version.");
	}

	private void Update()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		NetworkManager singleton = NetworkManager.Singleton;
		if ((Object)(object)singleton != (Object)(object)network)
		{
			Unregister();
			network = singleton;
			if ((Object)(object)network != (Object)null && network.CustomMessagingManager != null)
			{
				network.CustomMessagingManager.RegisterNamedMessageHandler("local.platformzero.request.v2", new HandleNamedMessageDelegate(ReceiveRequest));
				network.CustomMessagingManager.RegisterNamedMessageHandler("local.platformzero.event.v2", new HandleNamedMessageDelegate(ReceiveEvent));
			}
			else
			{
				network = null;
			}
		}
	}

	private void Unregister()
	{
		if ((Object)(object)network != (Object)null && network.CustomMessagingManager != null)
		{
			network.CustomMessagingManager.UnregisterNamedMessageHandler("local.platformzero.request.v2");
			network.CustomMessagingManager.UnregisterNamedMessageHandler("local.platformzero.event.v2");
		}
		network = null;
	}

	private void OnDestroy()
	{
		Clear();
		Unregister();
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		Instance = null;
	}

	internal void Clear()
	{
		if ((Object)(object)Station != (Object)null)
		{
			Station.Restore();
			Object.Destroy((Object)(object)((Component)Station).gameObject);
		}
		Station = null;
	}

	internal void Build(RoundManager round)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		if ((Object)(object)Station != (Object)null || !InteriorRegistration.Selected(round))
		{
			return;
		}
		GameObject val = new GameObject("Platform Zero — Last Service");
		Station station = val.AddComponent<Station>();
		try
		{
			station.Build(round);
			Station = station;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Platform Zero generated; seed " + station.Seed + ". Navigation and exit checks passed."));
		}
		catch (Exception ex)
		{
			station.Restore();
			Object.Destroy((Object)(object)val);
			((BaseUnityPlugin)this).Logger.LogError((object)("Platform Zero generation failed; leaving the original interior available. " + ex));
		}
	}

	internal unsafe void Request(int id)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Station == (Object)null || (Object)(object)network == (Object)null || !network.IsListening)
		{
			return;
		}
		if (network.IsServer)
		{
			Station.HandleRequest(network.LocalClientId, id);
			return;
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
		try
		{
			((FastBufferWriter)(ref val)).WriteBytesSafe(Protocol.Request(Station.Seed, id), 8, 0);
			network.CustomMessagingManager.SendNamedMessage("local.platformzero.request.v2", 0uL, val, (NetworkDelivery)3);
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private void ReceiveRequest(ulong sender, FastBufferReader reader)
	{
		if (!((Object)(object)network == (Object)null) && network.IsServer && !((Object)(object)Station == (Object)null) && ((FastBufferReader)(ref reader)).Length - ((FastBufferReader)(ref reader)).Position == 8)
		{
			byte[] data = new byte[8];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, 8, 0);
			if (Protocol.Read(data, out var seed, out var _, out var id, out var _) && seed == Station.Seed)
			{
				Station.HandleRequest(sender, id);
			}
		}
	}

	internal unsafe void Broadcast(int kind, int id, ulong player)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)network == (Object)null || !network.IsServer || (Object)(object)Station == (Object)null)
		{
			return;
		}
		Station.Apply(kind, id, player);
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(20, (Allocator)2, -1);
		try
		{
			((FastBufferWriter)(ref val)).WriteBytesSafe(Protocol.Event(Station.Seed, kind, id, player), 20, 0);
			foreach (ulong connectedClientsId in network.ConnectedClientsIds)
			{
				if (connectedClientsId != network.LocalClientId)
				{
					network.CustomMessagingManager.SendNamedMessage("local.platformzero.event.v2", connectedClientsId, val, (NetworkDelivery)3);
				}
			}
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private void ReceiveEvent(ulong sender, FastBufferReader reader)
	{
		if (sender == 0 && !((Object)(object)Station == (Object)null) && ((FastBufferReader)(ref reader)).Length - ((FastBufferReader)(ref reader)).Position == 20)
		{
			byte[] data = new byte[20];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, 20, 0);
			if (Protocol.Read(data, out var seed, out var kind, out var id, out var player) && seed == Station.Seed)
			{
				Station.Apply(kind, id, player);
			}
		}
	}
}
[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
internal static class BeginFloor
{
	private static void Prefix()
	{
		Plugin.Instance.Clear();
	}
}
[HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")]
internal static class FinishFloor
{
	private static void Prefix(RoundManager __instance)
	{
		Plugin.Instance.Build(__instance);
	}
}
[HarmonyPatch(typeof(RoundManager), "GeneratedFloorPostProcessing")]
internal static class BeforeScrap
{
	private static void Prefix(RoundManager __instance)
	{
		Plugin.Instance.Build(__instance);
	}
}
[HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")]
internal static class MapObjects
{
	private static bool Prefix()
	{
		return (Object)(object)Plugin.Instance.Station == (Object)null;
	}
}
[HarmonyPatch(typeof(RoundManager), "FindMainEntrancePosition")]
internal static class MainEntrancePosition
{
	private static void Postfix(bool getOutsideEntrance, ref Vector3 __result)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if (!getOutsideEntrance && (Object)(object)Plugin.Instance.Station != (Object)null)
		{
			__result = Station.Origin + new Vector3(0f, 0.15f, 3f);
		}
	}
}
internal static class Protocol
{
	public static byte[] Request(int seed, int id)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write(seed);
		binaryWriter.Write(id);
		return memoryStream.ToArray();
	}

	public static byte[] Event(int seed, int kind, int id, ulong player)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write(seed);
		binaryWriter.Write(kind);
		binaryWriter.Write(id);
		binaryWriter.Write(player);
		return memoryStream.ToArray();
	}

	public static bool Read(byte[] data, out int seed, out int kind, out int id, out ulong player)
	{
		seed = (kind = (id = 0));
		player = 0uL;
		if (data == null || (data.Length != 8 && data.Length != 20))
		{
			return false;
		}
		using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(data)))
		{
			seed = binaryReader.ReadInt32();
			if (data.Length == 20)
			{
				kind = binaryReader.ReadInt32();
			}
			id = binaryReader.ReadInt32();
			if (data.Length == 20)
			{
				player = binaryReader.ReadUInt64();
			}
		}
		return true;
	}
}
public sealed class Station : MonoBehaviour
{
	private const int ReturnBell = 200;

	private const int Trap = 1;

	private const int Ticket = 2;

	private const int Blackout = 3;

	private const int Train = 4;

	private const int Return = 5;

	private const int Rattle = 6;

	private const int Watcher = 7;

	private StationPlan plan;

	private Random events;

	internal static readonly Vector3 Origin = new Vector3(0f, -600f, 0f);

	private readonly List<Material> materials = new List<Material>();

	private readonly List<AudioClip> clips = new List<AudioClip>();

	private readonly List<Action> restores = new List<Action>();

	private readonly List<Light> lights = new List<Light>();

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

	private readonly Dictionary<int, Vector3> buttons = new Dictionary<int, Vector3>();

	private readonly Dictionary<int, Transform> doors = new Dictionary<int, Transform>();

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

	private readonly Dictionary<ulong, float> detained = new Dictionary<ulong, float>();

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

	private Material concrete;

	private Material tile;

	private Material rust;

	private Material dark;

	private Material teal;

	private Material amber;

	private Material red;

	private Material white;

	private TMP_FontAsset font;

	private Sprite hand;

	private AudioClip chime;

	private AudioClip rumble;

	private AudioClip breath;

	private TextMeshPro board;

	private GameObject train;

	private float nextEvent;

	private float blackoutUntil;

	private float boardUntil;

	private float trainStarted = -100f;

	private int lastEvent = -1;

	private bool ready;

	private bool restored;

	private bool localDetained;

	private Vector3 localReturn;

	private float localRelease;

	public int Seed { get; private set; }

	private Vector3 W(float x, float y, float z)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		return Origin + new Vector3(x, y, z);
	}

	internal void Build(RoundManager round)
	{
		//IL_0048: 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_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		Seed = StartOfRound.Instance.randomMapSeed;
		plan = new StationPlan(Seed);
		events = StationPlan.CreateRandom(Seed, 324478056u);
		SceneManager.MoveGameObjectToScene(((Component)this).gameObject, ((Component)round.dungeonGenerator).gameObject.scene);
		font = (from t in Object.FindObjectsOfType<TMP_Text>()
			select t.font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null));
		if ((Object)(object)font == (Object)null)
		{
			throw new InvalidOperationException("No game font available.");
		}
		hand = (from t in Object.FindObjectsOfType<InteractTrigger>()
			select t.hoverIcon).FirstOrDefault((Func<Sprite, bool>)((Sprite s) => (Object)(object)s != (Object)null));
		concrete = Mat("Wet concrete", new Color(0.17f, 0.2f, 0.19f), 0f);
		tile = Mat("Ivory ceramic", new Color(0.43f, 0.45f, 0.38f), 0f);
		rust = Mat("Oxidized steel", new Color(0.21f, 0.09f, 0.045f), 0f);
		dark = Mat("Soot", new Color(0.012f, 0.019f, 0.022f), 0f);
		teal = Mat("Exit phosphor", new Color(0.13f, 0.75f, 0.62f), 3f);
		amber = Mat("Sodium", new Color(1f, 0.48f, 0.07f), 4f);
		red = Mat("Alarm", new Color(0.75f, 0.015f, 0.015f), 3f);
		white = Mat("Bone", new Color(0.83f, 0.85f, 0.67f), 1f);
		chime = Tone("Four notes after midnight", 2f, 0);
		rumble = Tone("Empty service", 6f, 1);
		breath = Tone("Ticket inspection", 2.5f, 2);
		BuildConcourse();
		for (int num = 0; num < plan.Rooms.Length; num++)
		{
			BuildRoom(num);
		}
		BuildRedRoom();
		BuildTrain();
		BuildExits();
		BakeNavigation();
		RelocateSpawns();
		Plugin.Log.LogInfo((object)("Station layout: " + plan.Rooms.Length + " rooms, " + plan.Length + "m concourse. " + string.Join(", ", plan.Rooms.Select((StationPlan.Room r) => StationPlan.Names[r.Kind]).ToArray())));
		nextEvent = Time.time + 45f + (float)new Random(Seed ^ 0x7B9).Next(25);
		ready = true;
	}

	private Material Mat(string name, Color color, float glow)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		Shader val = Shader.Find("HDRP/Lit");
		if ((Object)(object)val == (Object)null)
		{
			throw new InvalidOperationException("HDRP/Lit is unavailable.");
		}
		Material val2 = new Material(val);
		((Object)val2).name = "P0 " + name;
		Material val3 = val2;
		val3.SetColor("_BaseColor", color);
		val3.SetFloat("_Smoothness", 0.28f);
		val3.SetFloat("_Metallic", 0f);
		val3.SetColor("_EmissiveColor", color * glow);
		materials.Add(val3);
		return val3;
	}

	private GameObject Box(string name, Vector3 position, Vector3 size, Material material, bool solid = true)
	{
		//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)
		GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
		((Object)val).name = name;
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.position = position;
		val.transform.localScale = size;
		int num = LayerMask.NameToLayer("Room");
		val.layer = ((num >= 0) ? num : 0);
		val.GetComponent<Renderer>().sharedMaterial = material;
		if (!solid)
		{
			val.GetComponent<Collider>().enabled = false;
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
		}
		return val;
	}

	private TextMeshPro Label(string text, Vector3 position, float yaw, float size, Color color)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0029: 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_006d: 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)
		GameObject val = new GameObject("Sign: " + text);
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.position = position;
		val.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
		TextMeshPro val2 = val.AddComponent<TextMeshPro>();
		((TMP_Text)val2).font = font;
		((TMP_Text)val2).text = text;
		((TMP_Text)val2).fontSize = size;
		((Graphic)val2).color = color;
		((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(12f, 4f);
		((TMP_Text)val2).enableWordWrapping = false;
		return val2;
	}

	private void Lamp(Vector3 position, Color color, bool eventLight)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_002a: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Expected O, but got Unknown
		//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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		Box("Fluorescent housing", position + Vector3.up * 0.14f, new Vector3(2f, 0.18f, 0.4f), dark, solid: false);
		Box("Lamp diffuser", position, new Vector3(1.85f, 0.06f, 0.28f), (color.r > 0.7f) ? amber : teal, solid: false);
		GameObject val = new GameObject("Station light");
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.position = position - Vector3.up * 0.2f;
		Light val2 = val.AddComponent<Light>();
		val2.type = (LightType)2;
		val2.color = color;
		val2.range = 14f;
		val2.shadows = (LightShadows)0;
		HDAdditionalLightData val3 = val.AddComponent<HDAdditionalLightData>();
		val3.SetIntensity(1100f, (LightUnit)0);
		if (eventLight)
		{
			lights.Add(val2);
		}
	}

	private void BuildConcourse()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_0097: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0363: Unknown result type (might be due to invalid IL or missing references)
		//IL_0377: Unknown result type (might be due to invalid IL or missing references)
		//IL_0396: Unknown result type (might be due to invalid IL or missing references)
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0426: Unknown result type (might be due to invalid IL or missing references)
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0463: Unknown result type (might be due to invalid IL or missing references)
		//IL_0481: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_050a: Unknown result type (might be due to invalid IL or missing references)
		//IL_051e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0590: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
		float num = plan.Length;
		Box("Concourse foundation", W(0f, -0.3f, num / 2f), new Vector3(18f, 0.6f, num), concrete);
		Box("Vault", W(0f, 6.2f, num / 2f), new Vector3(18f, 0.4f, num), concrete);
		Box("South bulkhead", W(0f, 3f, 0f), new Vector3(18f, 6f, 0.4f), tile);
		Box("North bulkhead", W(0f, 3f, num), new Vector3(18f, 6f, 0.4f), tile);
		for (int i = -1; i <= 1; i += 2)
		{
			float num2 = 0f;
			for (int j = 0; j < plan.Rooms.Length / 2; j++)
			{
				float num3 = plan.Rooms[j * 2].Z;
				Box("Platform wall", W(i * 9, 3f, (num2 + num3 - 2f) / 2f), new Vector3(0.4f, 6f, num3 - 2f - num2), tile);
				Box("Doorway lintel", W(i * 9, 4.7f, num3), new Vector3(0.4f, 2.6f, 4f), concrete);
				num2 = num3 + 2f;
			}
			Box("Platform wall end", W(i * 9, 3f, (num2 + num) / 2f), new Vector3(0.4f, 6f, num - num2), tile);
			int z;
			for (z = 7; (float)z < num - 2f; z += 12)
			{
				Box("Iron column", W(i * 6, 2.8f, z), new Vector3(0.45f, 5.6f, 0.45f), dark);
				Box("Sodium wayfinding stripe", W(i * 6, 0.025f, z + 3), new Vector3(0.14f, 0.025f, 10f), amber, solid: false);
				if (!plan.Rooms.Any((StationPlan.Room r) => Mathf.Abs(r.Z - (z + 3)) < 4))
				{
					Bench((float)i * 7.6f, z + 3, i * 90);
				}
			}
			Box("Overhead pipe", W(i * 7, 5.6f, num / 2f), new Vector3(0.18f, 0.18f, num - 1f), rust, solid: false);
		}
		for (int num4 = 6; (float)num4 < num - 3f; num4 += 12)
		{
			Lamp(W(0f, 5.6f, num4), new Color(1f, 0.65f, 0.3f), eventLight: true);
			Box("Ceramic floor seam", W(0f, 0.015f, num4), new Vector3(18f, 0.015f, 0.06f), dark, solid: false);
			loot.Add(W(3f, 0.25f, num4));
			loot.Add(W(-3f, 0.25f, num4 + 2));
		}
		Box("Departure board", W(0f, 4.2f, 10f), new Vector3(8f, 2f, 0.3f), dark, solid: false);
		board = Label("PLATFORM 0\nLAST SERVICE   00:00\nDESTINATION: HOME", W(0f, 4.2f, 9.81f), 0f, 4.8f, new Color(1f, 0.65f, 0.2f));
		Label("DO NOT BOARD AN EMPTY TRAIN", W(0f, 2.8f, num - 0.3f), 0f, 5f, Color.white);
		Label("P0  /  COMPANY TRANSIT AUTHORITY", W(0f, 4.8f, 0.3f), 180f, 4f, Color.white);
		Box("Train window recess", W(0f, 1.6f, num - 0.35f), new Vector3(12f, 1.7f, 0.1f), dark, solid: false);
		for (int num5 = 2; num5 < plan.Rooms.Length; num5 += 2)
		{
			StationPlan.Room room = plan.Rooms[num5];
			float num6 = (float)(room.Z + plan.Rooms[num5 - 2].Z) / 2f;
			int num7 = ((room.Variant != 0) ? 1 : (-1));
			Box("Abandoned route barrier", W(num7 * 5, 1.4f, num6), new Vector3(7f, 2.8f, 0.35f), dark);
			Label("TRACK " + (room.Kind + 1).ToString("00") + " / CLOSED", W(num7 * 5, 2f, num6 - 0.2f), 0f, 2.5f, Color.white);
		}
	}

	private void Bench(float x, float z, float yaw)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: 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_009f: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Box("Empty bench", W(x, 0.55f, z), new Vector3(2.5f, 0.16f, 0.65f), rust);
		val.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
		Vector3 position = val.transform.position + val.transform.forward * 0.27f + Vector3.up * 0.5f;
		GameObject val2 = Box("Bench back", position, new Vector3(2.5f, 0.85f, 0.12f), dark);
		val2.transform.rotation = val.transform.rotation;
		for (int i = -1; i <= 1; i += 2)
		{
			Box("Bench leg", val.transform.position + val.transform.right * (float)i * 0.9f - Vector3.up * 0.3f, new Vector3(0.1f, 0.6f, 0.4f), dark);
		}
	}

	private void BuildRoom(int i)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0587: Unknown result type (might be due to invalid IL or missing references)
		//IL_058c: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_0476: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_04df: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_054e: Unknown result type (might be due to invalid IL or missing references)
		//IL_055d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0440: Unknown result type (might be due to invalid IL or missing references)
		//IL_044f: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_060a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0625: Unknown result type (might be due to invalid IL or missing references)
		//IL_061e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0655: Unknown result type (might be due to invalid IL or missing references)
		//IL_0664: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0709: Unknown result type (might be due to invalid IL or missing references)
		//IL_0718: Unknown result type (might be due to invalid IL or missing references)
		StationPlan.Room room = plan.Rooms[i];
		int side = room.Side;
		int kind = room.Kind;
		string text = StationPlan.Names[kind];
		float x = room.X;
		float num = room.Z;
		float num2 = side * (9 + room.Width);
		float num3 = (float)room.Depth / 2f;
		Box(text + " floor", W(x, -0.3f, num), new Vector3((float)room.Width, 0.6f, (float)room.Depth), concrete);
		Box(text + " ceiling", W(x, 4.7f, num), new Vector3((float)room.Width, 0.4f, (float)room.Depth), concrete);
		Box("Outer wall", W(num2, 2.3f, num), new Vector3(0.4f, 4.6f, (float)room.Depth), tile);
		Box("Room side", W(x, 2.3f, num - num3), new Vector3((float)room.Width, 4.6f, 0.4f), tile);
		Box("Room side", W(x, 2.3f, num + num3), new Vector3((float)room.Width, 4.6f, 0.4f), tile);
		Box("Room color band", W(num2 - (float)side * 0.25f, 1.2f, num), new Vector3(0.03f, 0.35f, (float)room.Depth - 0.5f), (room.Variant == 0) ? teal : rust, solid: false);
		Label(text, W((float)side * 8.7f, 3.7f, num), (side == -1) ? 90 : (-90), 3.8f, Color.white);
		Lamp(W(x, 4.2f, num), (room.Variant == 2) ? new Color(1f, 0.62f, 0.28f) : new Color(0.3f, 0.85f, 0.7f), eventLight: true);
		for (int j = 0; j < 4; j++)
		{
			float x2 = x + ((j % 2 == 0) ? (-2.6f) : 2.6f);
			float z = num + ((j < 2) ? (-3.8f) : 3.8f);
			loot.Add(W(x2, 0.25f, z));
		}
		switch (kind)
		{
		case 0:
		case 2:
		case 4:
		{
			for (int l = 0; l < 5; l++)
			{
				float z2 = num - 6f + (float)(l * 3);
				Box("Numbered storage locker", W(num2 - (float)(side * 2), 1.25f, z2), new Vector3(1.2f, 2.5f, 1.7f), (l == room.Variant) ? rust : dark);
				Label((kind * 100 + l + 1).ToString("000"), W(num2 - (float)side * 2.65f, 1.8f, z2), (side == -1) ? 90 : (-90), 2.2f, Color.white);
			}
			break;
		}
		case 1:
		{
			Box("Signal desk", W(x, 1f, num + 5f), new Vector3(10f, 2f, 1.5f), dark);
			for (int k = 0; k < 7; k++)
			{
				Box("Signal lamps", W(x - 4f + (float)k * 1.3f, 2.1f, num + 5f), new Vector3(0.35f, 0.12f, 0.35f), (k % 3 == 0) ? red : teal, solid: false);
			}
			Label("NO SIGNAL RECEIVED SINCE 1977", W(x, 3f, num + num3 - 0.3f), 0f, 3.2f, Color.white);
			break;
		}
		case 3:
			Box("Canteen table", W(x, 1f, num), new Vector3(6f, 0.15f, 2f), tile);
			Bench(x, num + 2f, 0f);
			Bench(x, num - 2f, 180f);
			Label("EMPLOYEE OF THE MONTH\nSTILL MISSING", W(x, 3f, num + num3 - 0.3f), 0f, 3.6f, Color.white);
			break;
		case 5:
			Bench(x - 3f, num + 3f, 0f);
			Bench(x + 3f, num + 3f, 0f);
			Label("YOUR NUMBER WILL BE CALLED\nPLEASE KEEP YOUR ORIGINAL FACE", W(x, 3.1f, num + num3 - 0.3f), 0f, 3f, Color.white);
			break;
		default:
			BuildNewTheme(room);
			break;
		}
		Vector3 position = W(x, 1.5f, num - num3 + 0.35f);
		GameObject val = Box("Unscheduled door " + i, position, new Vector3(2.1f, 3f, 0.15f), (i % 2 == 0) ? rust : dark);
		doors.Add(i, val.transform);
		Label((i % 2 == 0) ? "FIRE EXIT" : "AUTHORIZED PERSONNEL", W(x, 3.45f, num - num3 + 0.52f), 180f, 2.8f, (i % 2 == 0) ? Color.green : Color.white);
		Label((i % 2 == 0) ? "INSPECTION OVERDUE / NO SEAL" : "KNOCKING FROM INSIDE", W(x, 0.7f, num - num3 + 0.52f), 180f, 1.4f, Color.white);
		AddButton(val, i, "Open door : [E]");
		if (room.Ticket >= 0)
		{
			int id = 100 + room.Ticket;
			GameObject obj = Box("Old ticket punch", W(x + 4f, 1.25f, num + num3 - 1.3f), new Vector3(0.65f, 1.4f, 0.65f), amber);
			AddButton(obj, id, "Punch abandoned ticket : [E]");
			Label("ONE WAY / NO REFUNDS", W(x + 4f, 2.4f, num + num3 - 1.6f), 0f, 1.8f, Color.white);
		}
	}

	private void BuildNewTheme(StationPlan.Room room)
	{
		//IL_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0350: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_048c: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_051a: Unknown result type (might be due to invalid IL or missing references)
		//IL_052e: 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_007a: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03db: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_041b: Unknown result type (might be due to invalid IL or missing references)
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		float x = room.X;
		float num = room.Z;
		float z = num + (float)room.Depth / 2f - 0.3f;
		switch (room.Kind)
		{
		case 6:
		{
			for (int k = -1; k <= 1; k++)
			{
				Box("Dormant turbine", W(x + (float)(k * 4), 1.2f, num), new Vector3(2.2f, 2.4f, 3f), dark);
				Box("Turbine cooling band", W(x + (float)(k * 4), 1.6f, num - 1.52f), new Vector3(1.8f, 0.15f, 0.03f), amber, solid: false);
			}
			Label("POWER DRAW: 0\nHEARTBEATS: 1", W(x, 3.1f, z), 0f, 3.4f, Color.yellow);
			break;
		}
		case 7:
		{
			for (int j = -1; j <= 1; j += 2)
			{
				Box("Quarantine bed", W(x + (float)(j * 5), 0.7f, num), new Vector3(2f, 0.25f, 4f), tile);
				Box("Privacy partition", W(x + (float)j * 6.3f, 1.7f, num), new Vector3(0.12f, 3f, 5f), teal);
				Box("Unclaimed patient", W(x + (float)(j * 5), 1f, num), new Vector3(0.8f, 0.4f, 2.3f), dark, solid: false);
			}
			Label("DISCHARGE ONLY AFTER\nTHE SECOND PULSE STOPS", W(x, 3f, z), 0f, 3f, Color.white);
			break;
		}
		case 8:
		{
			for (int l = -1; l <= 1; l++)
			{
				Box("Records cabinet", W(x + (float)l * 4.5f, 1.6f, num), new Vector3(1.4f, 3.2f, 4f), rust);
				for (int m = 0; m < 4; m++)
				{
					Box("Index stripe", W(x + (float)l * 4.5f, 0.6f + (float)m * 0.7f, num - 2.02f), new Vector3(1.1f, 0.1f, 0.03f), white, solid: false);
				}
			}
			Label("ARRIVALS / DEPARTURES\nERASE YOUR NAME BEFORE LEAVING", W(x, 3.2f, z), 0f, 3f, Color.white);
			break;
		}
		case 9:
			Bench(x - 4f, num, 0f);
			Bench(x + 4f, num, 0f);
			Box("Offering plinth", W(x, 1f, num + 5f), new Vector3(2f, 2f, 1.4f), dark);
			Box("Broken halo", W(x, 3f, num + 5f), new Vector3(2f, 0.12f, 0.2f), amber, solid: false);
			Label("FOR THOSE WHO MISSED\nTHE LAST CONNECTION", W(x, 3.1f, z), 0f, 3f, Color.white);
			break;
		case 10:
		{
			Box("Black water basin", W(x, 0.025f, num), new Vector3(5f, 0.03f, 5f), dark, solid: false);
			for (int i = -1; i <= 1; i += 2)
			{
				Box("Pressure vessel", W(x + (float)(i * 5), 1.6f, num), new Vector3(2.5f, 3.2f, 4f), rust);
				Box("Pressure gauge", W(x + (float)(i * 5), 2.1f, num - 2.02f), new Vector3(0.6f, 0.6f, 0.04f), teal, solid: false);
			}
			Label("DO NOT DRAIN\nSOMETHING IS HOLDING ITS BREATH", W(x, 3.2f, z), 0f, 3f, Color.white);
			break;
		}
		case 11:
			Box("Screen", W(x, 2.4f, num + 5.4f), new Vector3(7f, 2.8f, 0.15f), white, solid: false);
			Label("NO PASSENGERS DETECTED\nTHEN WHO IS WATCHING?", W(x, 2.4f, num + 5.28f), 0f, 3f, Color.black);
			Bench(x - 3f, num, 0f);
			Bench(x + 3f, num, 0f);
			Box("Projector", W(x, 3.9f, num - 3f), new Vector3(0.6f, 0.5f, 1f), dark, solid: false);
			break;
		}
	}

	private void BuildRedRoom()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_008e: 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_00ca: 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_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		Box("Waiting room foundation", W(80f, -0.3f, 24f), new Vector3(12f, 0.6f, 18f), dark);
		Box("Waiting room ceiling", W(80f, 4.2f, 24f), new Vector3(12f, 0.4f, 18f), dark);
		Box("Waiting room back", W(80f, 2f, 33f), new Vector3(12f, 4f, 0.4f), concrete);
		Box("Waiting room front", W(80f, 2f, 15f), new Vector3(12f, 4f, 0.4f), concrete);
		Box("Waiting room left", W(74f, 2f, 24f), new Vector3(0.4f, 4f, 18f), concrete);
		Box("Waiting room right", W(86f, 2f, 24f), new Vector3(0.4f, 4f, 18f), concrete);
		Lamp(W(80f, 3.6f, 24f), new Color(1f, 0.02f, 0.02f), eventLight: false);
		Label("YOU ARE EARLY.\nWE WERE EXPECTING YOUR REPLACEMENT.", W(80f, 2.7f, 32.7f), 0f, 3.2f, Color.red);
		Label("RING AFTER THE TONE", W(80f, 2.5f, 15.3f), 180f, 2.6f, Color.white);
		GameObject obj = Box("Return bell", W(80f, 1.1f, 16f), new Vector3(0.6f, 0.4f, 0.6f), amber);
		AddButton(obj, 200, "Request return : [E]");
		for (int i = 0; i < 4; i++)
		{
			Bench(76f, 20 + i * 3, 90f);
			Bench(84f, 20 + i * 3, -90f);
		}
		Conductor(W(80f, 0f, 31f), Quaternion.identity);
	}

	private void BuildTrain()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0047: 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_00b1: 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_0113: 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)
		train = new GameObject("The last service");
		train.transform.SetParent(((Component)this).transform, false);
		for (int i = 0; i < 4; i++)
		{
			GameObject val = Box("Ghost carriage", W(0f, 1.6f, 10 + i * 11), new Vector3(3f, 3f, 10f), dark, solid: false);
			val.transform.SetParent(train.transform, true);
			for (int j = -1; j <= 1; j += 2)
			{
				for (int k = 0; k < 4; k++)
				{
					GameObject val2 = Box("Unoccupied window", W((float)j * 1.52f, 2f, 6 + i * 11 + k * 2), new Vector3(0.04f, 1.1f, 1.4f), amber, solid: false);
					val2.transform.SetParent(train.transform, true);
					if (k == 2)
					{
						GameObject val3 = Box("Passenger silhouette", W((float)j * 1.55f, 2.05f, 6 + i * 11 + k * 2), new Vector3(0.05f, 0.8f, 0.35f), dark, solid: false);
						val3.transform.SetParent(train.transform, true);
					}
				}
			}
		}
		train.SetActive(false);
	}

	private void BuildExits()
	{
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		EntranceTeleport[] array = (from e in Object.FindObjectsOfType<EntranceTeleport>()
			where !e.isEntranceToBuilding
			orderby e.entranceId
			select e).ToArray();
		if (!array.Any((EntranceTeleport e) => e.entranceId == 0))
		{
			throw new InvalidOperationException("No original main entrance found.");
		}
		int num = 0;
		EntranceTeleport[] array2 = array;
		foreach (EntranceTeleport val in array2)
		{
			EntranceTeleport captured = val;
			bool flag = val.entranceId == 0;
			int num3 = ((num % 2 != 0) ? 1 : (-1));
			float num4 = (flag ? 0f : ((float)num3 * 8.5f));
			float num5 = (flag ? 0.6f : ((float)(plan.Length - 4 - num / 2 * 4)));
			float num6 = ((!flag) ? (-num3 * 90) : 0);
			if (!flag)
			{
				num++;
			}
			Move(val.entrancePoint, W((!flag) ? (num3 * 6) : 0, 0.15f, flag ? 3f : num5));
			Quaternion old = val.entrancePoint.rotation;
			restores.Add(delegate
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)captured != (Object)null && (Object)(object)captured.entrancePoint != (Object)null)
				{
					captured.entrancePoint.rotation = old;
				}
			});
			val.entrancePoint.rotation = Quaternion.Euler(0f, num6, 0f);
			GameObject obj = Box("Genuine exit " + val.entranceId, W(num4, 1.5f, num5), flag ? new Vector3(2.2f, 3f, 0.3f) : new Vector3(0.3f, 3f, 2.2f), teal);
			AddInteraction(obj, "Leave station : [E]", delegate(PlayerControllerB p)
			{
				if ((Object)(object)p == (Object)(object)Local() && !p.isPlayerDead)
				{
					captured.TeleportPlayer();
				}
			});
			Label(flag ? "SURFACE / MAIN EXIT\nVERIFIED COMPANY SEAL" : "SURFACE / FIRE EXIT\nVERIFIED COMPANY SEAL", flag ? W(num4, 3.8f, num5 + 0.21f) : W(num4 - (float)num3 * 0.21f, 3.8f, num5), flag ? 180 : (-num3 * 90), 2.5f, Color.cyan);
		}
	}

	private void AddButton(GameObject obj, int id, string tip)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		buttons.Add(id, obj.transform.position);
		AddInteraction(obj, tip, delegate(PlayerControllerB p)
		{
			if ((Object)(object)p == (Object)(object)Local())
			{
				Plugin.Instance.Request(id);
			}
		});
	}

	private void AddInteraction(GameObject obj, string tip, UnityAction<PlayerControllerB> action)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		int num = LayerMask.NameToLayer("InteractableObject");
		if (num < 0)
		{
			throw new InvalidOperationException("InteractableObject layer unavailable.");
		}
		obj.layer = num;
		obj.tag = "InteractTrigger";
		InteractTrigger val = obj.AddComponent<InteractTrigger>();
		val.interactable = true;
		val.hoverTip = tip;
		val.hoverIcon = hand;
		val.disableTriggerMesh = false;
		val.oneHandedItemAllowed = true;
		val.twoHandedItemAllowed = true;
		val.holdInteraction = false;
		val.interactCooldown = true;
		val.cooldownTime = 1f;
		val.onInteract = new InteractEvent();
		((UnityEvent<PlayerControllerB>)(object)val.onInteract).AddListener(action);
		val.onInteractEarly = new InteractEvent();
		val.onInteractEarlyOtherClients = new InteractEvent();
		val.onStopInteract = new InteractEvent();
		val.onCancelAnimation = new InteractEvent();
		val.holdingInteractEvent = new InteractEventFloat();
	}

	private void BakeNavigation()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_007f: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00fb: 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_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		Physics.SyncTransforms();
		for (int i = 0; i < NavMesh.GetSettingsCount(); i++)
		{
			NavMeshSurface val = ((Component)this).gameObject.AddComponent<NavMeshSurface>();
			NavMeshBuildSettings settingsByIndex = NavMesh.GetSettingsByIndex(i);
			val.agentTypeID = ((NavMeshBuildSettings)(ref settingsByIndex)).agentTypeID;
			val.collectObjects = (CollectObjects)2;
			val.useGeometry = (NavMeshCollectGeometry)1;
			val.BuildNavMesh();
		}
		NavMeshHit val2 = default(NavMeshHit);
		if (!NavMesh.SamplePosition(W(0f, 0.2f, 4f), ref val2, 2f, -1))
		{
			throw new InvalidOperationException("Station navigation failed to bake.");
		}
		NavMeshPath val3 = new NavMeshPath();
		Vector3 position = ((NavMeshHit)(ref val2)).position;
		if (!NavMesh.CalculatePath(((NavMeshHit)(ref val2)).position, W(0f, 0.1f, plan.Length - 4), -1, val3) || (int)val3.status != 0)
		{
			throw new InvalidOperationException("Station main escape route is disconnected.");
		}
		StationPlan.Room[] rooms = plan.Rooms;
		foreach (StationPlan.Room room in rooms)
		{
			if (!NavMesh.SamplePosition(W(room.Side * 11, 0.2f, room.Z), ref val2, 1f, -1) || !NavMesh.CalculatePath(position, ((NavMeshHit)(ref val2)).position, -1, val3) || (int)val3.status != 0)
			{
				throw new InvalidOperationException("A station room entrance is disconnected.");
			}
		}
		for (int num = loot.Count - 1; num >= 0; num--)
		{
			if (!NavMesh.SamplePosition(loot[num], ref val2, 1.5f, -1) || Mathf.Abs(((NavMeshHit)(ref val2)).position.y - Origin.y) > 0.35f || !NavMesh.CalculatePath(position, ((NavMeshHit)(ref val2)).position, -1, val3) || (int)val3.status != 0)
			{
				loot.RemoveAt(num);
			}
			else
			{
				loot[num] = ((NavMeshHit)(ref val2)).position + Vector3.up * 0.25f;
			}
		}
		if (loot.Count < plan.Rooms.Length * 2)
		{
			throw new InvalidOperationException("Not enough reachable loot locations.");
		}
		StationPlan.Shuffle(loot, StationPlan.CreateRandom(Seed, 1396920897u));
	}

	private void Move(Transform t, Vector3 target)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		Vector3 original = t.position;
		restores.Add(delegate
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t != (Object)null)
			{
				t.position = original;
			}
		});
		t.position = target;
	}

	private static string Hierarchy(Component c)
	{
		string text = "";
		Transform val = c.transform;
		while ((Object)(object)val != (Object)null)
		{
			text = val.GetSiblingIndex().ToString("D5") + "/" + text;
			val = val.parent;
		}
		return text;
	}

	private void RelocateSpawns()
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		foreach (RandomScrapSpawn item in Object.FindObjectsOfType<RandomScrapSpawn>().OrderBy(Hierarchy))
		{
			Move(((Component)item).transform, loot[num++ % loot.Count]);
			bool oldCopy = item.spawnedItemsCopyPosition;
			Transform oldParent = item.spawnWithParent;
			RandomScrapSpawn saved = item;
			restores.Add(delegate
			{
				if ((Object)(object)saved != (Object)null)
				{
					saved.spawnedItemsCopyPosition = oldCopy;
					saved.spawnWithParent = oldParent;
				}
			});
			item.spawnedItemsCopyPosition = true;
			item.spawnWithParent = null;
		}
		num = 0;
		foreach (GameObject item2 in from o in GameObject.FindGameObjectsWithTag("AINode")
			orderby Hierarchy((Component)(object)o.transform)
			select o)
		{
			Move(item2.transform, loot[num++ % loot.Count] - Vector3.up * 0.15f);
		}
		num = 0;
		foreach (EnemyVent item3 in Object.FindObjectsOfType<EnemyVent>().OrderBy(Hierarchy))
		{
			if (!((Object)(object)item3.floorNode == (Object)null))
			{
				Vector3 val = loot[(num++ * 7 + 10) % loot.Count];
				Move(item3.floorNode, val);
				Box("Vent grille", val - Vector3.up * 0.2f, new Vector3(1f, 0.07f, 1f), dark, solid: false);
			}
		}
	}

	private PlayerControllerB Local()
	{
		if (!((Object)(object)GameNetworkManager.Instance == (Object)null))
		{
			return GameNetworkManager.Instance.localPlayerController;
		}
		return null;
	}

	internal void HandleRequest(ulong sender, int id)
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		if (!ready || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase || StartOfRound.Instance.shipIsLeaving)
		{
			return;
		}
		PlayerControllerB val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (Object)(object)x != (Object)null && x.actualClientId == sender && x.isPlayerControlled && !x.isPlayerDead));
		if ((Object)(object)val == (Object)null || !val.isInsideFactory || !buttons.TryGetValue(id, out var value) || Vector3.Distance(((Component)val).transform.position, value) > 4.5f)
		{
			return;
		}
		float value2;
		if (id == 200)
		{
			if (detained.TryGetValue(sender, out value2) && Time.time >= value2 - 7f)
			{
				Plugin.Instance.Broadcast(5, 0, sender);
			}
		}
		else
		{
			if ((detained.TryGetValue(sender, out value2) && Time.time < value2) || (cooldowns.TryGetValue(id, out value2) && Time.time < value2))
			{
				return;
			}
			if (id >= 100 && id <= 102)
			{
				if (!tickets.Contains(id))
				{
					Plugin.Instance.Broadcast(2, id, sender);
				}
			}
			else if (id >= 0 && id < plan.Rooms.Length)
			{
				cooldowns[id] = Time.time + 35f;
				if (plan.Rooms[id].Trap)
				{
					detained[sender] = Time.time + 14f;
					Plugin.Instance.Broadcast(1, id, sender);
				}
				else
				{
					Plugin.Instance.Broadcast(6, id, sender);
				}
			}
		}
	}

	internal void Apply(int kind, int id, ulong player)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: 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_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		if (!ready)
		{
			return;
		}
		if (kind == 1 && doors.ContainsKey(id))
		{
			((MonoBehaviour)this).StartCoroutine(Inspection(id, player));
			return;
		}
		if (kind == 6 && doors.ContainsKey(id))
		{
			Sound(breath, buttons[id], 0.35f);
			if ((Object)(object)Local() != (Object)null && Local().actualClientId == player)
			{
				HUDManager.Instance.DisplayTip("Occupied", "Someone knocks back. The handle will not turn.", false, false, "P0");
			}
			return;
		}
		if (kind == 2 && id >= 100 && id <= 102)
		{
			tickets.Add(id);
			Sound(chime, buttons[id], 0.45f);
			if (tickets.Count == 3)
			{
				((TMP_Text)board).text = "SERVICE RESTORED\nNEXT STOP: 71-GORDION\nTHANK YOU, GREAT ASSET.";
				StationPlan.Room room = plan.Rooms.First((StationPlan.Room r) => r.Ticket == 2);
				Label("THE COMPANY DOES NOT REIMBURSE\nTRAVEL BETWEEN PLANES OF EXISTENCE.", W(room.X, 3f, (float)room.Z + (float)room.Depth / 2f - 0.32f), 0f, 2.8f, Color.cyan);
				if ((Object)(object)Local() != (Object)null && InStation(Local()))
				{
					HUDManager.Instance.DisplayTip("Transit authority", "All three tickets punched. Your commute has been expensed.", false, false, "P0");
				}
			}
			return;
		}
		switch (kind)
		{
		case 3:
			blackoutUntil = Time.time + 9f;
			boardUntil = Time.time + 10f;
			Sound(breath, W(0f, 2f, (float)plan.Length / 2f), 0.5f);
			((TMP_Text)board).text = "SIGNAL LOST\nREMAIN WITH YOUR ORIGINAL CREW";
			return;
		case 4:
			trainStarted = Time.time;
			boardUntil = Time.time + 12f;
			train.SetActive(true);
			Sound(rumble, W(0f, 1f, (float)plan.Length / 2f), 0.6f);
			((TMP_Text)board).text = "00:00  /  SERVICE ARRIVING\nDO NOT MAKE EYE CONTACT";
			return;
		case 7:
			if (id >= 0 && id < plan.Rooms.Length)
			{
				StationPlan.Room room2 = plan.Rooms[id];
				GameObject val = Conductor(W(room2.Side * 7, 0f, room2.Z), Quaternion.Euler(0f, (float)(room2.Side * 90), 0f));
				Sound(chime, val.transform.position, 0.35f);
				Object.Destroy((Object)(object)val, 6f);
				((TMP_Text)board).text = "PASSENGER COUNT DOES NOT MATCH\nDO NOT FOLLOW THE ATTENDANT";
				boardUntil = Time.time + 8f;
				return;
			}
			break;
		}
		if (kind == 5 && (Object)(object)Local() != (Object)null && Local().actualClientId == player)
		{
			Release();
		}
	}

	private IEnumerator Inspection(int id, ulong player)
	{
		Transform door = doors[id];
		Vector3 pos = buttons[id];
		Sound(breath, pos, 0.6f);
		GameObject actor = Conductor(pos + new Vector3(0f, -1.5f, 1.1f), Quaternion.Euler(0f, 180f, 0f));
		float begin = Time.time;
		while (true)
		{
			if (Time.time - begin < 1.4f)
			{
				if (!((Object)(object)door == (Object)null))
				{
					float t = (Time.time - begin) / 1.4f;
					door.localRotation = Quaternion.Euler(0f, Mathf.SmoothStep(0f, 75f, t), 0f);
					actor.transform.position = pos + new Vector3(0f, -1.5f, 1.1f + t * 1.7f);
					yield return null;
					continue;
				}
				break;
			}
			PlayerControllerB p = Local();
			if ((Object)(object)p != (Object)null && p.actualClientId == player && !p.isPlayerDead && InStation(p) && Vector3.Distance(((Component)p).transform.position, pos) < 8f)
			{
				localReturn = pos + new Vector3(0f, -1.35f, 3f);
				localRelease = Time.time + 12f;
				localDetained = true;
				p.TeleportPlayer(W(80f, 0.2f, 19f), false, 0f, false, true);
				p.isInsideFactory = true;
				p.isInElevator = false;
				p.isInHangarShipRoom = false;
				HUDManager.Instance.DisplayTip("Ticket inspection", "Your ticket is not valid for this destination.", true, false, "P0");
			}
			Object.Destroy((Object)(object)actor);
			if ((Object)(object)door != (Object)null)
			{
				door.localRotation = Quaternion.identity;
			}
			break;
		}
	}

	private GameObject Conductor(Vector3 position, Quaternion rotation)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_003f: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: 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_00ea: 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_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		GameObject root = new GameObject("The Conductor");
		root.transform.SetParent(((Component)this).transform, false);
		root.transform.position = position;
		root.transform.rotation = rotation;
		Action<string, Vector3, Vector3, Material> action = delegate(string name, Vector3 p, Vector3 scale, Material mat)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Box(name, Vector3.zero, scale, mat, solid: false);
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = p;
		};
		action("Long coat", new Vector3(0f, 1.4f, 0f), new Vector3(0.7f, 2.2f, 0.35f), dark);
		action("Featureless face", new Vector3(0f, 2.75f, 0f), new Vector3(0.42f, 0.55f, 0.3f), white);
		action("Cap", new Vector3(0f, 3.08f, 0f), new Vector3(0.7f, 0.12f, 0.55f), dark);
		action("Ticket mouth", new Vector3(0f, 2.62f, -0.16f), new Vector3(0.28f, 0.06f, 0.03f), dark);
		for (int num = -1; num <= 1; num += 2)
		{
			action("Gloved arm", new Vector3((float)num * 0.5f, 1.3f, 0f), new Vector3(0.14f, 2.4f, 0.15f), dark);
			action("Eye", new Vector3((float)num * 0.11f, 2.85f, -0.16f), new Vector3(0.045f, 0.04f, 0.02f), amber);
		}
		return root;
	}

	private bool InStation(PlayerControllerB p)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		if (p.isInsideFactory && ((Component)p).transform.position.y < Origin.y + 15f)
		{
			return ((Component)p).transform.position.y > Origin.y - 10f;
		}
		return false;
	}

	private bool InRedRoom(PlayerControllerB p)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (Mathf.Abs(((Component)p).transform.position.x - 80f) < 7f && Mathf.Abs(((Component)p).transform.position.z - 24f) < 10f)
		{
			return InStation(p);
		}
		return false;
	}

	private void Release()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = Local();
		if (localDetained && (Object)(object)val != (Object)null && !val.isPlayerDead && InRedRoom(val))
		{
			val.TeleportPlayer(localReturn, false, 0f, false, true);
		}
		localDetained = false;
	}

	private void Update()
	{
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		if (!ready)
		{
			return;
		}
		PlayerControllerB val = Local();
		if (localDetained && (Object)(object)val != (Object)null)
		{
			if (val.isPlayerDead || !InRedRoom(val))
			{
				localDetained = false;
			}
			else if (Time.time >= localRelease || StartOfRound.Instance.shipIsLeaving)
			{
				Release();
			}
		}
		bool flag = Time.time < blackoutUntil;
		foreach (Light light in lights)
		{
			if ((Object)(object)light != (Object)null)
			{
				((Behaviour)light).enabled = !flag;
			}
		}
		if (boardUntil > 0f && Time.time >= boardUntil)
		{
			boardUntil = 0f;
			((TMP_Text)board).text = ((tickets.Count == 3) ? "SERVICE RESTORED\nNEXT STOP: 71-GORDION\nTHANK YOU, GREAT ASSET." : "PLATFORM 0\nLAST SERVICE   00:00\nDESTINATION: HOME");
		}
		if (train.activeSelf)
		{
			float num = Time.time - trainStarted;
			train.transform.position = new Vector3(0f, 0f, -65f + num * 23f);
			if (num > (float)(plan.Length + 70) / 23f)
			{
				train.SetActive(false);
			}
		}
		if (!((Object)(object)NetworkManager.Singleton != (Object)null) || !NetworkManager.Singleton.IsServer || !(Time.time >= nextEvent) || !((Object)(object)StartOfRound.Instance != (Object)null) || StartOfRound.Instance.inShipPhase || StartOfRound.Instance.shipIsLeaving)
		{
			return;
		}
		if (StartOfRound.Instance.allPlayerScripts.Any((PlayerControllerB x) => (Object)(object)x != (Object)null && x.isPlayerControlled && !x.isPlayerDead && InStation(x)))
		{
			int[] array = new int[3] { 4, 3, 7 }.Where((int e) => e != lastEvent).ToArray();
			lastEvent = array[events.Next(array.Length)];
			Plugin.Instance.Broadcast(lastEvent, events.Next(plan.Rooms.Length), 0uL);
			nextEvent = Time.time + 65f + (float)events.Next(35);
		}
		else
		{
			nextEvent = Time.time + 5f;
		}
	}

	private AudioClip Tone(string name, float length, int mode)
	{
		float[] array = new float[(int)(length * 22050f)];
		Random random = new Random(1977 + mode);
		double[] array2 = new double[4] { 440.0, 349.23, 293.66, 220.0 };
		for (int i = 0; i < array.Length; i++)
		{
			double num = (double)i / 22050.0;
			double num2 = Math.Min(num * 5.0, 1.0) * Math.Min(((double)length - num) * 3.0, 1.0);
			double num3;
			switch (mode)
			{
			case 0:
			{
				int num4 = Math.Min(3, (int)(num / 0.5));
				double num5 = num % 0.5;
				num3 = Math.Sin(num * array2[num4] * Math.PI * 2.0) * Math.Exp((0.0 - num5) * 7.0) * 0.3;
				break;
			}
			case 1:
				num3 = (Math.Sin(num * 48.0 * Math.PI * 2.0) * 0.18 + (random.NextDouble() * 2.0 - 1.0) * 0.08) * (0.7 + 0.3 * Math.Sin(num * 11.0));
				break;
			default:
				num3 = (random.NextDouble() * 2.0 - 1.0) * 0.1 + Math.Sin(num * (90.0 - num * 12.0) * Math.PI * 2.0) * 0.12;
				break;
			}
			array[i] = (float)(num3 * num2);
		}
		AudioClip val = AudioClip.Create(name, array.Length, 1, 22050, false);
		val.SetData(array, 0);
		clips.Add(val);
		return val;
	}

	private void Sound(AudioClip clip, Vector3 position, float volume)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Station sound");
		val.transform.SetParent(((Component)this).transform, false);
		val.transform.position = position;
		AudioSource val2 = val.AddComponent<AudioSource>();
		val2.clip = clip;
		val2.volume = volume;
		val2.spatialBlend = 1f;
		val2.minDistance = 3f;
		val2.maxDistance = 65f;
		val2.rolloffMode = (AudioRolloffMode)1;
		val2.Play();
		Object.Destroy((Object)(object)val, clip.length + 0.2f);
	}

	internal void Restore()
	{
		if (!restored)
		{
			restored = true;
			ready = false;
			((MonoBehaviour)this).StopAllCoroutines();
			Release();
			for (int num = restores.Count - 1; num >= 0; num--)
			{
				restores[num]();
			}
			restores.Clear();
			NavMeshSurface[] components = ((Component)this).GetComponents<NavMeshSurface>();
			foreach (NavMeshSurface val in components)
			{
				val.RemoveData();
			}
		}
	}

	private void OnDestroy()
	{
		Restore();
		foreach (Material material in materials)
		{
			if ((Object)(object)material != (Object)null)
			{
				Object.Destroy((Object)(object)material);
			}
		}
		foreach (AudioClip clip in clips)
		{
			if ((Object)(object)clip != (Object)null)
			{
				Object.Destroy((Object)(object)clip);
			}
		}
	}
}
internal sealed class StationPlan
{
	internal sealed class Room
	{
		internal int Kind;

		internal int Side;

		internal int Width;

		internal int Depth;

		internal int Z;

		internal int Ticket = -1;

		internal int Variant;

		internal bool Trap;

		internal float X => (float)Side * (9f + (float)Width / 2f);
	}

	internal static readonly string[] Names = new string[12]
	{
		"LEFT LUGGAGE", "SIGNAL CONTROL", "LOST PROPERTY", "STAFF CANTEEN", "DEAD LETTER OFFICE", "WAITING ROOM", "GENERATOR HALL", "QUARANTINE WARD", "RECORDS ARCHIVE", "COMMUTER CHAPEL",
		"PUMP STATION", "SCREENING ROOM"
	};

	internal readonly Room[] Rooms;

	internal readonly int Length;

	internal StationPlan(int seed)
	{
		Random random = CreateRandom(seed, 1347174740u);
		int num = 8 + 2 * random.Next(3);
		int[] array = Enumerable.Range(0, Names.Length).ToArray();
		Shuffle(array, random);
		Rooms = new Room[num];
		int num2 = 18;
		for (int i = 0; i < num; i++)
		{
			if (i > 0 && i % 2 == 0)
			{
				num2 += random.Next(24, 31);
			}
			Rooms[i] = new Room
			{
				Kind = array[i],
				Side = ((i % 2 != 0) ? 1 : (-1)),
				Width = 16 + 2 * random.Next(4),
				Depth = 16 + 2 * random.Next(3),
				Z = num2,
				Variant = random.Next(3)
			};
		}
		Length = num2 + 18;
		int[] array2 = Enumerable.Range(0, num).ToArray();
		Shuffle(array2, random);
		for (int j = 0; j < 3; j++)
		{
			Rooms[array2[j]].Ticket = j;
		}
		Shuffle(array2, random);
		for (int k = 0; k < Math.Max(2, num / 3); k++)
		{
			Rooms[array2[k]].Trap = true;
		}
	}

	internal static void Shuffle<T>(IList<T> values, Random random)
	{
		for (int num = values.Count - 1; num > 0; num--)
		{
			int index = random.Next(num + 1);
			T value = values[num];
			values[num] = values[index];
			values[index] = value;
		}
	}

	internal static Random CreateRandom(int seed, uint stream)
	{
		uint num = (uint)seed ^ stream;
		num ^= num >> 16;
		num *= 2146121005;
		num ^= num >> 15;
		num *= 2221713035u;
		num ^= num >> 16;
		return new Random((int)(num & 0x7FFFFFFF));
	}

	internal static float LootFactor(int completedQuotas)
	{
		return 1f + 0.05f * (float)Math.Max(0, Math.Min(5, completedQuotas));
	}

	internal static int FairWeight(IEnumerable<int> weights)
	{
		int[] array = weights.Where((int w) => w > 0).ToArray();
		if (array.Length == 0)
		{
			return 150;
		}
		return Math.Max(1, (int)Math.Round(((IEnumerable<int>)array).Average((Func<int, double>)((int w) => w)), MidpointRounding.AwayFromZero));
	}
}