Decompiled source of Radius Glasses v1.0.0

plugins/SeerSpectacles.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SeerSpectacles.Core;
using SeerSpectacles.Dev;
using SeerSpectacles.Gameplay;
using SeerSpectacles.UI;
using SeerSpectacles.Visual;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SeerSpectacles
{
	public static class Cfg
	{
		public static readonly ConfigEntry<string>[] Levels = new ConfigEntry<string>[8];

		public static ConfigEntry<string> Sight;

		public static readonly Dictionary<Category, ConfigEntry<bool>> Show = new Dictionary<Category, ConfigEntry<bool>>();

		public static readonly Dictionary<Category, ConfigEntry<string>> Colour = new Dictionary<Category, ConfigEntry<string>>();

		public static ConfigEntry<KeyCode> CycleKey;

		public static ConfigEntry<bool> ShowHud;

		public static ConfigEntry<float> LineWidth;

		public static ConfigEntry<float> CurtainHeight;

		public static ConfigEntry<float> InnerGlow;

		public static ConfigEntry<float> Brightness;

		public static ConfigEntry<float> CropRange;

		public static ConfigEntry<bool> Extensions;

		public static ConfigEntry<bool> Convention;

		public const int RuleSlots = 10;

		public static readonly List<ConfigEntry<string>> ExtraRules = new List<ConfigEntry<string>>();

		private static ConfigFile _file;

		public static void Bind(ConfigFile c)
		{
			//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_000d: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Expected O, but got Unknown
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			string[] array = new string[8] { "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Mistlands", "Ashlands", "Deep North" };
			for (int i = 0; i < 8; i++)
			{
				Levels[i] = c.Bind<string>("1 - Glasses", "Level" + (i + 1), LevelTable.Defaults[i], new ConfigDescription(string.Format("Level {0} ({1}): where it is {2} and from what, as 'Station level | Item:amount, Item:amount'. ", i + 1, array[i], (i == 0) ? "made" : "upgraded") + "Stations: Workbench, Forge, Stonecutter, Artisan, Cauldron, Galdr, Blackforge or a prefab name. Up to four materials fit the crafting panel at once.", (AcceptableValueBase)null, new object[1] { val }));
			}
			Sight = c.Bind<string>("1 - Glasses", "SightPerLevel", "50, 60, 75, 90, 105, 120, 140, 160", new ConfigDescription("How far the glasses show radii at each level, in metres, comma separated from level 1. A level never sees less than the one before.", (AcceptableValueBase)null, new object[1] { val }));
			_file = c;
			foreach (Category item in Categories.All)
			{
				BindCategory(item);
			}
			Categories.Added += BindCategory;
			CycleKey = c.Bind<KeyCode>("3 - Client", "CycleKey", (KeyCode)104, "While you wear the glasses: this key shows one category after the other, then all again. With Shift it puts the lines away and back.");
			ShowHud = c.Bind<bool>("3 - Client", "ShowStandingLine", true, "Show at the top of the screen which radii cover the spot you stand on.");
			LineWidth = c.Bind<float>("3 - Client", "LineWidth", 0.2f, new ConfigDescription("Width of the line on the ground, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.04f, 0.6f), Array.Empty<object>()));
			CurtainHeight = c.Bind<float>("3 - Client", "CurtainHeight", 0.8f, new ConfigDescription("Height of the fading light wall above the line, in metres; 0 draws only the line.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>()));
			InnerGlow = c.Bind<float>("3 - Client", "InnerGlow", 1.4f, new ConfigDescription("Width of the soft glow on the ground inside the line (it shows which side is covered), in metres; 0 turns it off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 4f), Array.Empty<object>()));
			Brightness = c.Bind<float>("3 - Client", "Brightness", 1f, new ConfigDescription("How strong the lines are drawn: 0.5 is half as bright.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1.5f), Array.Empty<object>()));
			CropRange = c.Bind<float>("3 - Client", "CropRange", 20f, new ConfigDescription("Growing plants are drawn only this close to you (a field has hundreds), in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
			Extensions = c.Bind<bool>("4 - Other mods", "ReadOtherMods", true, "Show the radii of other mods: Feeding Troughs, Thrallhold, Holmgang (Battle Arena), Animal Leash, Monster Leash, Hourglass, any mod following the SeerRadius convention, and the rules below. None of them is needed; each counts only when it is installed.");
			Convention = c.Bind<bool>("4 - Other mods", "SeerRadiusConvention", true, "Look for components on pieces and creatures that have a member named SeerRadius (any mod can add one without depending on this mod; see README).");
			for (int j = 1; j <= 10; j++)
			{
				ExtraRules.Add(c.Bind<string>("4 - Other mods", "Rule" + j, "", (j == 1) ? "A radius of another mod, read by reflection, as 'Key=Value; Key=Value'. Example: 'Assembly=MyMod; Type=MyMod.Kennel; List=All; Radius=Range; Category=Kennel; Colour=FF8800'. Keys: Type, Assembly, List (static member, or 'pieces'/'characters'), Radius, Center, Active, Group, Label, Shape (Column/Ball), Category, Title, Colour, Tint, Arc, Faint. Read when the game starts." : "Another rule like Rule1."));
			}
		}

		private static void BindCategory(Category cat)
		{
			if (_file != null && !Show.ContainsKey(cat))
			{
				string text = Categories.Key(cat);
				string text2 = (Categories.IsCustom(cat) ? "4 - Other mods" : "2 - Categories");
				Show[cat] = _file.Bind<bool>(text2, "Show" + text, true, "Draw the " + Describe(cat) + ".");
				Colour[cat] = _file.Bind<string>(text2, "Colour" + text, Categories.DefaultHex(cat), "Colour of the " + Describe(cat) + ", as hex RRGGBB.");
			}
		}

		private static string Describe(Category cat)
		{
			switch (cat)
			{
			case Category.Workshop:
				return "build range of crafting stations (grows with their extensions)";
			case Category.Ward:
				return "area of wards";
			case Category.Base:
				return "player base, where no monsters spawn";
			case Category.Warmth:
				return "warmth of fires (no freezing, beds can be used)";
			case Category.Comfort:
				return "10 m around comfort pieces, where they count for resting";
			case Category.Turret:
				return "range of ballistas";
			case Category.Shield:
				return "dome of shield generators";
			case Category.Mistfree:
				return "mist-free circle of wisp torches";
			case Category.Breeding:
				return "range in which tamed animals count their own kind before they stop breeding";
			case Category.Crops:
				return "room growing plants need";
			case Category.Feeding:
				return "reach of feeding stations (Feeding Troughs mod)";
			case Category.Settlement:
				return "settlement round each banner (Thrallhold mod)";
			case Category.WorkArea:
				return "working radius of work posts (Thrallhold mod)";
			case Category.Guard:
				return "circle guarded by guard posts (Thrallhold mod)";
			case Category.TownPlace:
				return "places of a thrall town (Thrallhold mod)";
			case Category.ArenaRoom:
				return "calm rooms of camp banners and chambers, in the team's colour (Holmgang mod)";
			case Category.ArenaField:
				return "fighting field of Holmgang desks (Holmgang mod)";
			case Category.Tether:
				return "reach of animals tied fast (Animal Leash / Monster Leash mods)";
			case Category.Hourglass:
				return "reach in which an hourglass reads a station (Hourglass mod)";
			default:
			{
				CustomCategory customCategory = Categories.CustomOf(cat);
				if (customCategory == null)
				{
					return cat.ToString();
				}
				return "radius '" + customCategory.Title + "' of another mod";
			}
			}
		}

		public static Color ColourOf(Category cat)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!Categories.TryParseHex(Colour.TryGetValue(cat, out var value) ? value.Value : Categories.DefaultHex(cat), out var r, out var g, out var b))
			{
				Categories.TryParseHex(Categories.DefaultHex(cat), out r, out g, out b);
			}
			return new Color(r, g, b, 1f);
		}

		public static bool Shows(Category cat)
		{
			if (Show.TryGetValue(cat, out var value))
			{
				return value.Value;
			}
			return true;
		}
	}
	public static class Lang
	{
		private static readonly (string key, string en, string de)[] Texts = new(string, string, string)[36]
		{
			("seer_item_spectacles", "Radius glasses", "Radiusbrille"),
			("seer_item_spectacles_desc", "Two polished lenses in a frame tied with leather. Through them you see how far things reach: the build range of a workbench, the circle of a ward, the warmth of a fire, the ground where no monster spawns. Worn as a trinket.", "Zwei geschliffene Linsen in einem mit Leder gebundenen Gestell. Durch sie siehst du, wie weit die Dinge reichen: den Bauradius der Werkbank, den Kreis der Schutzrune, die Wärme des Feuers, den Boden, auf dem kein Monster erscheint. Wird als Schmuckstück getragen."),
			("seer_tt_sight", "Sight", "Sichtweite"),
			("seer_tt_levels", "Levels", "Stufen"),
			("seer_tt_made", "Level {0} at {1}, level {2}", "Stufe {0} an: {1}, Stufe {2}"),
			("seer_tt_next", "Next: {0} m at {1}, level {2}", "Nächste: {0} m an: {1}, Stufe {2}"),
			("seer_tt_elsewhere", "This level is made at {0} (level {1}), not here.", "Diese Stufe entsteht an: {0} (Stufe {1}), nicht hier."),
			("seer_tt_key", "[{0}] one category after the other · Shift+[{0}] lines away", "[{0}] eine Art nach der anderen · Umschalt+[{0}] Linien weg"),
			("seer_hud_here", "Here", "Hier"),
			("seer_hud_nothing", "outside every radius", "außerhalb aller Radien"),
			("seer_hud_off", "off", "aus"),
			("seer_hud_noaccess", "no access", "kein Zugang"),
			("seer_hud_comfort", "Comfort {0}", "Komfort {0}"),
			("seer_mode_all", "Radius glasses: all radii", "Radiusbrille: alle Radien"),
			("seer_mode_one", "Radius glasses: {0}", "Radiusbrille: {0}"),
			("seer_mode_off", "Radius glasses: lines put away", "Radiusbrille: Linien weggelegt"),
			("seer_mode_on", "Radius glasses: lines back", "Radiusbrille: Linien wieder da"),
			("seer_cat_workshop", "Workshop", "Werkstatt"),
			("seer_cat_ward", "Ward", "Schutzrune"),
			("seer_cat_base", "Base, no spawns", "Basis, kein Spawn"),
			("seer_cat_warmth", "Warmth", "Wärme"),
			("seer_cat_comfort", "Comfort", "Komfort"),
			("seer_cat_turret", "Ballista", "Balliste"),
			("seer_cat_shield", "Shield", "Schild"),
			("seer_cat_mistfree", "No mist", "Nebelfrei"),
			("seer_cat_breeding", "Breeding", "Zucht"),
			("seer_cat_crops", "Plants", "Pflanzen"),
			("seer_cat_feeding", "Feeding station", "Futterstelle"),
			("seer_cat_settlement", "Settlement", "Siedlung"),
			("seer_cat_workarea", "Work area", "Arbeitsbereich"),
			("seer_cat_guard", "Guarded", "Bewacht"),
			("seer_cat_townplace", "Town place", "Stadtort"),
			("seer_cat_arenaroom", "Camp room", "Lagerraum"),
			("seer_cat_arenafield", "Holmgang field", "Holmgang-Feld"),
			("seer_cat_tether", "Tether reach", "Leinenreichweite"),
			("seer_cat_hourglass", "Hourglass reach", "Sanduhr-Reichweite")
		};

		public static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			(string, string, string)[] texts = Texts;
			for (int i = 0; i < texts.Length; i++)
			{
				(string, string, string) tuple = texts[i];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				string item3 = tuple.Item3;
				dictionary[item] = item2;
				dictionary2[item] = item3;
			}
			string text = "English";
			localization.AddTranslation(ref text, dictionary);
			text = "German";
			localization.AddTranslation(ref text, dictionary2);
		}

		public static string T(string token, params object[] args)
		{
			string text = ((Localization.instance != null) ? Localization.instance.Localize("$" + token) : token);
			if (args == null || args.Length == 0)
			{
				return text;
			}
			try
			{
				return string.Format(text, args);
			}
			catch (FormatException)
			{
				return text;
			}
		}

		public static string CategoryName(Category c)
		{
			string text = Categories.Token(c);
			if (text != null)
			{
				return T(text);
			}
			CustomCategory customCategory = Categories.CustomOf(c);
			if (customCategory == null)
			{
				return c.ToString();
			}
			return L(customCategory.Title);
		}

		public static string L(string token)
		{
			string text;
			if (Localization.instance == null || string.IsNullOrEmpty(token))
			{
				text = token;
				if (text == null)
				{
					return "";
				}
			}
			else
			{
				text = Localization.instance.Localize(token);
			}
			return text;
		}
	}
	[BepInPlugin("zap.radiusglasses", "Radius Glasses", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class SeerSpectaclesPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "zap.radiusglasses";

		public const string PluginName = "Radius Glasses";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		public static SeerSpectaclesPlugin Instance { get; private set; }

		public static string PluginDir { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static string AssetPath(string fileName)
		{
			return Path.Combine(PluginDir ?? "", "Assets", fileName);
		}

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Cfg.Bind(((BaseUnityPlugin)this).Config);
			Lang.Register();
			SpectacleItem.Init();
			Recipes.HookConfig();
			RadiusView.Ensure(((Component)this).gameObject);
			_harmony = new Harmony("zap.radiusglasses");
			_harmony.PatchAll(typeof(SeerSpectaclesPlugin).Assembly);
			SelfTest.TryStart(((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace SeerSpectacles.Visual
{
	internal sealed class GroundProbe : IGround
	{
		public const float Headroom = 2.2f;

		private const float Grid = 4f;

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

		private readonly int _terrainMask;

		private readonly int _solidMask;

		public int Probes { get; private set; }

		public int Cached => _cache.Count;

		public GroundProbe()
		{
			_terrainMask = LayerMask.GetMask(new string[1] { "terrain" });
			_solidMask = LayerMask.GetMask(new string[3] { "piece", "static_solid", "terrain" });
		}

		public void Clear()
		{
			_cache.Clear();
		}

		public float HeightAt(float x, float z, float refY)
		{
			int num = Mathf.RoundToInt(x * 4f);
			int num2 = Mathf.RoundToInt(z * 4f);
			int num3 = Mathf.FloorToInt(refY);
			long key = ((long)(num & 0xFFFFFF) << 40) | ((long)(num2 & 0xFFFFFF) << 16) | (num3 & 0xFFFF);
			if (_cache.TryGetValue(key, out var value))
			{
				return value;
			}
			value = Probe((float)num / 4f, (float)num2 / 4f, refY);
			if (_cache.Count > 400000)
			{
				_cache.Clear();
			}
			_cache[key] = value;
			return value;
		}

		private float Probe(float x, float z, float refY)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			Probes++;
			float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f);
			RaycastHit val = default(RaycastHit);
			float num2 = ((!Physics.Raycast(new Vector3(x, refY + 400f, z), Vector3.down, ref val, 1200f, _terrainMask)) ? (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(new Vector3(x, refY, z)) : refY) : ((RaycastHit)(ref val)).point.y);
			float num3 = refY + 2.2f;
			float num4 = num2;
			if (num2 < num3)
			{
				float num5 = num3 - num2 + 0.3f;
				RaycastHit val2 = default(RaycastHit);
				if (Physics.Raycast(new Vector3(x, num3, z), Vector3.down, ref val2, num5, _solidMask) && (Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody == (Object)null)
				{
					num4 = ((RaycastHit)(ref val2)).point.y;
				}
			}
			return Mathf.Max(num4, num);
		}
	}
	internal static class MeshKit
	{
		public static Mesh Torus(string name, float r, float t, int seg = 28, int side = 8, float from = 0f, float to = 360f, float yScale = 1f)
		{
			//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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00bb: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<int> list3 = new List<int>();
			bool flag = Mathf.Approximately(to - from, 360f);
			int num = (flag ? seg : (seg + 1));
			Vector3 val = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)Math.PI / 180f * Mathf.Lerp(from, to, (float)i / (float)seg);
				((Vector3)(ref val))..ctor(Mathf.Cos(num2) * r, Mathf.Sin(num2) * r * yScale, 0f);
				Vector3 val2 = new Vector3(Mathf.Cos(num2), Mathf.Sin(num2) * yScale, 0f);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				for (int j = 0; j < side; j++)
				{
					float num3 = (float)j * (float)Math.PI * 2f / (float)side;
					Vector3 val3 = normalized * Mathf.Cos(num3) + Vector3.forward * Mathf.Sin(num3);
					list.Add(val + val3 * t);
					list2.Add(val3);
				}
			}
			int num4 = (flag ? seg : seg);
			for (int k = 0; k < num4; k++)
			{
				int num5 = (flag ? ((k + 1) % seg) : (k + 1));
				for (int l = 0; l < side; l++)
				{
					int num6 = (l + 1) % side;
					int item = k * side + l;
					int item2 = k * side + num6;
					int item3 = num5 * side + l;
					int item4 = num5 * side + num6;
					list3.Add(item);
					list3.Add(item3);
					list3.Add(item2);
					list3.Add(item2);
					list3.Add(item3);
					list3.Add(item4);
				}
			}
			return Make(name, list, list2, list3);
		}

		public static Mesh Disc(string name, float r, int seg = 28, float yScale = 1f)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			for (int i = 0; i < 2; i++)
			{
				int count = list.Count;
				Vector3 item = ((i == 0) ? Vector3.forward : Vector3.back);
				list.Add(Vector3.zero);
				list2.Add(item);
				list3.Add(new Vector2(0.5f, 0.5f));
				for (int j = 0; j < seg; j++)
				{
					float num = (float)j * (float)Math.PI * 2f / (float)seg;
					list.Add(new Vector3(Mathf.Cos(num) * r, Mathf.Sin(num) * r * yScale, 0f));
					list2.Add(item);
					list3.Add(new Vector2(0.5f + Mathf.Cos(num) * 0.5f, 0.5f + Mathf.Sin(num) * 0.5f));
				}
				for (int k = 0; k < seg; k++)
				{
					int item2 = count + 1 + k;
					int item3 = count + 1 + (k + 1) % seg;
					if (i == 0)
					{
						list4.Add(count);
						list4.Add(item2);
						list4.Add(item3);
					}
					else
					{
						list4.Add(count);
						list4.Add(item3);
						list4.Add(item2);
					}
				}
			}
			Mesh obj = Make(name, list, list2, list4);
			obj.SetUVs(0, list3);
			return obj;
		}

		public static Mesh Rod(string name, IList<Vector3> path, float t, int side = 6)
		{
			//IL_002a: 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_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_004e: 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_005a: 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_0081: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: 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)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<int> list3 = new List<int>();
			Vector3 val;
			for (int i = 0; i < path.Count; i++)
			{
				val = path[Mathf.Min(path.Count - 1, i + 1)] - path[Mathf.Max(0, i - 1)];
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				Vector3 val2 = Vector3.Cross(normalized, Vector3.up);
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val2 = Vector3.Cross(normalized, Vector3.right);
				}
				((Vector3)(ref val2)).Normalize();
				Vector3 val3 = Vector3.Cross(val2, normalized);
				for (int j = 0; j < side; j++)
				{
					float num = (float)j * (float)Math.PI * 2f / (float)side;
					Vector3 val4 = val2 * Mathf.Cos(num) + val3 * Mathf.Sin(num);
					list.Add(path[i] + val4 * t);
					list2.Add(val4);
				}
			}
			for (int k = 0; k < path.Count - 1; k++)
			{
				for (int l = 0; l < side; l++)
				{
					int num2 = (l + 1) % side;
					int item = k * side + l;
					int item2 = k * side + num2;
					int item3 = (k + 1) * side + l;
					int item4 = (k + 1) * side + num2;
					list3.Add(item);
					list3.Add(item3);
					list3.Add(item2);
					list3.Add(item2);
					list3.Add(item3);
					list3.Add(item4);
				}
			}
			int[] array = new int[2]
			{
				0,
				path.Count - 1
			};
			foreach (int num3 in array)
			{
				int count = list.Count;
				Vector3 normalized2;
				if (num3 != 0)
				{
					val = path[num3] - path[num3 - 1];
					normalized2 = ((Vector3)(ref val)).normalized;
				}
				else
				{
					val = path[0] - path[1];
					normalized2 = ((Vector3)(ref val)).normalized;
				}
				Vector3 val5 = normalized2;
				list.Add(path[num3] + val5 * t * 0.6f);
				list2.Add(val5);
				for (int n = 0; n < side; n++)
				{
					int num4 = (n + 1) % side;
					int item5 = num3 * side + n;
					int item6 = num3 * side + num4;
					if (num3 == 0)
					{
						list3.Add(count);
						list3.Add(item5);
						list3.Add(item6);
					}
					else
					{
						list3.Add(count);
						list3.Add(item6);
						list3.Add(item5);
					}
				}
			}
			return Make(name, list, list2, list3);
		}

		private static Mesh Make(string name, List<Vector3> v, List<Vector3> n, List<int> tri)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name
			};
			val.SetVertices(v);
			val.SetNormals(n);
			val.SetTriangles(tri, 0);
			val.RecalculateBounds();
			return val;
		}

		public static GameObject Part(string name, Transform parent, Mesh mesh, Material mat)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = mat;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			return val;
		}

		public static void SetLayer(GameObject go, int layer)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			go.layer = layer;
			foreach (Transform item in go.transform)
			{
				SetLayer(((Component)item).gameObject, layer);
			}
		}
	}
	public class RadiusView : MonoBehaviour
	{
		private sealed class Group
		{
			public Category Cat;

			public int Id;

			public bool Faint;

			public Color? Tint;

			public readonly List<Zone> Zones = new List<Zone>();

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

			public int Sig;

			public bool Dirty;

			public bool Seen;

			public Vector3 BuiltAt;

			public float BuiltTime = -999f;

			public GameObject Go;

			public Mesh Mesh;

			public int Vertices;

			public int Stretches;
		}

		private sealed class Job
		{
			public Group Group;

			public List<Zone> Zones;

			public List<Polyline> Lines;

			public IEnumerator<int> Steps;

			public Vector3 Viewer;

			public float Range;
		}

		public const float ScanSeconds = 0.5f;

		public const float RebuildMovedShare = 0.15f;

		public const float RebuildMovedMin = 6f;

		public const float StaticRefresh = 30f;

		public const float MovingRefresh = 1f;

		public const float ProbeLifetime = 120f;

		public const float BudgetMs = 2.5f;

		private Job _job;

		private GameObject _root;

		private readonly Dictionary<long, Group> _groups = new Dictionary<long, Group>();

		private readonly List<Found> _found = new List<Found>();

		private readonly GroundProbe _probe = new GroundProbe();

		private readonly Stopwatch _watch = new Stopwatch();

		private Material _mat;

		private float _nextScan;

		private float _clearProbeAt;

		private bool _shown;

		public static RadiusView Instance { get; private set; }

		public int Mode { get; private set; } = -1;

		public bool Off { get; private set; }

		public float Sight { get; private set; }

		public int GroupCount => _groups.Count;

		public int ProbeCount => _probe.Probes;

		public bool Settled
		{
			get
			{
				if (_job != null)
				{
					return false;
				}
				foreach (Group value in _groups.Values)
				{
					if (value.Dirty)
					{
						return false;
					}
				}
				return _groups.Count > 0;
			}
		}

		public static void Ensure(GameObject host)
		{
			if (!((Object)(object)Instance != (Object)null) && !GUIManager.IsHeadless())
			{
				Instance = host.AddComponent<RadiusView>();
			}
		}

		private void Update()
		{
			//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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			ItemData val = SpectacleItem.Worn(localPlayer);
			if (val != null)
			{
				Keys(localPlayer);
			}
			if (val == null || ((Character)localPlayer).IsDead())
			{
				if (_shown)
				{
					HideAll();
				}
				StandingLine.Hide();
				return;
			}
			bool flag = Off || Game.IsPaused();
			if (Root().activeSelf == flag)
			{
				Root().SetActive(!flag);
			}
			if (flag)
			{
				StandingLine.Hide();
				return;
			}
			_shown = true;
			Sight = Recipes.SightFor(val.m_quality);
			Vector3 position = ((Component)localPlayer).transform.position;
			if (Time.time >= _nextScan)
			{
				_nextScan = Time.time + 0.5f;
				Scan(position);
				StandingLine.Show(Standing(localPlayer));
			}
			if (Time.time >= _clearProbeAt)
			{
				_clearProbeAt = Time.time + 120f;
				_probe.Clear();
				Sources.ClearFloors();
			}
			Rebuild(position);
			Visibility();
			if ((Object)(object)_mat != (Object)null)
			{
				float num = 0.88f + 0.12f * Mathf.Sin(Time.time * 1.6f);
				_mat.color = new Color(1f, 1f, 1f, num);
			}
		}

		private void Keys(Player p)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (ZInput.GetKeyDown(Cfg.CycleKey.Value, true) && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen())
			{
				if (ZInput.GetKey((KeyCode)304, true) || ZInput.GetKey((KeyCode)303, true))
				{
					Off = !Off;
					Message(Lang.T(Off ? "seer_mode_off" : "seer_mode_on"));
				}
				else if (Off)
				{
					Off = false;
					Message(Lang.T("seer_mode_on"));
				}
				else
				{
					Mode = NextMode(Mode);
					Message((Mode < 0) ? Lang.T("seer_mode_all") : Lang.T("seer_mode_one", Lang.CategoryName((Category)Mode)));
				}
			}
		}

		public int NextMode(int mode)
		{
			HashSet<Category> hashSet = new HashSet<Category>();
			foreach (Group value in _groups.Values)
			{
				if (value.Stretches > 0 || value.Zones.Count > 0)
				{
					hashSet.Add(value.Cat);
				}
			}
			int num = ((mode < 0) ? (-1) : Categories.Index((Category)mode));
			IReadOnlyList<Category> all = Categories.All;
			for (int i = num + 1; i < all.Count; i++)
			{
				if (hashSet.Contains(all[i]))
				{
					return (int)all[i];
				}
			}
			return -1;
		}

		public void SetMode(int mode)
		{
			Mode = mode;
			Visibility();
		}

		public void SetOff(bool off)
		{
			Off = off;
		}

		private static void Message(string s)
		{
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				MessageHud.instance.ShowMessage((MessageType)1, s, 0, (Sprite)null, false, true);
			}
		}

		private void Scan(Vector3 viewer)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			Sources.Collect(viewer, Sight, Cfg.CropRange.Value, _found);
			foreach (Group value3 in _groups.Values)
			{
				value3.Seen = false;
				value3.Zones.Clear();
				value3.Labels.Clear();
			}
			foreach (Found item in _found)
			{
				long key = (long)(((ulong)item.Cat << 32) | (uint)item.Group);
				if (!_groups.TryGetValue(key, out var value))
				{
					value = new Group
					{
						Cat = item.Cat,
						Id = item.Group,
						Dirty = true
					};
					_groups[key] = value;
				}
				value.Seen = true;
				value.Faint = item.Faint;
				if (!Same(value.Tint, item.Tint))
				{
					value.Tint = item.Tint;
					value.Dirty = true;
				}
				value.Zones.Add(item.Zone);
				value.Labels.Add(item.Label);
			}
			List<long> list = new List<long>();
			foreach (KeyValuePair<long, Group> group in _groups)
			{
				Group value2 = group.Value;
				if (!value2.Seen)
				{
					list.Add(group.Key);
					continue;
				}
				bool flag = Categories.Moving(value2.Cat);
				int num = Signature(value2.Zones, flag ? 1f : 5f);
				float num2 = (flag ? 1f : 30f);
				float num3 = Mathf.Max(6f, Sight * 0.15f);
				if (num != value2.Sig || Utils.DistanceXZ(viewer, value2.BuiltAt) > num3 || Time.time - value2.BuiltTime > num2)
				{
					value2.Sig = num;
					value2.Dirty = true;
				}
			}
			foreach (long item2 in list)
			{
				Group obj = _groups[item2];
				if (_job != null && _job.Group == obj)
				{
					_job = null;
				}
				if ((Object)(object)obj.Go != (Object)null)
				{
					Object.Destroy((Object)(object)obj.Go);
				}
				if ((Object)(object)obj.Mesh != (Object)null)
				{
					Object.Destroy((Object)(object)obj.Mesh);
				}
				_groups.Remove(item2);
			}
		}

		private static bool Same(Color? a, Color? b)
		{
			//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_0025: 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)
			if (a.HasValue == b.HasValue)
			{
				if (a.HasValue)
				{
					Color32 val = Color32.op_Implicit(a.Value);
					return ((Color32)(ref val)).Equals(Color32.op_Implicit(b.Value));
				}
				return true;
			}
			return false;
		}

		private static int Signature(List<Zone> zones, float perMetre)
		{
			int num = zones.Count * 7919;
			foreach (Zone zone in zones)
			{
				int num2 = Mathf.RoundToInt(zone.Center.X * perMetre);
				num2 = num2 * 31 + Mathf.RoundToInt(zone.Center.Y * perMetre);
				num2 = num2 * 31 + Mathf.RoundToInt(zone.Center.Z * perMetre);
				num2 = num2 * 31 + Mathf.RoundToInt(zone.Radius * 10f);
				num2 = num2 * 31 + (int)zone.Shape;
				num2 = num2 * 31 + Mathf.RoundToInt(zone.Arc) + Mathf.RoundToInt(zone.Facing * 20f) * 1009;
				num2 ^= num2 >> 15;
				num2 *= 739982445;
				num2 ^= num2 >> 12;
				num += num2;
			}
			return num;
		}

		private void Rebuild(Vector3 viewer)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			_watch.Reset();
			_watch.Start();
			while (_watch.Elapsed.TotalMilliseconds < 2.5)
			{
				if (_job == null)
				{
					Group obj = null;
					foreach (Group value in _groups.Values)
					{
						if (value.Dirty)
						{
							obj = value;
							break;
						}
					}
					if (obj == null)
					{
						break;
					}
					Begin(obj, viewer);
				}
				if (!_job.Steps.MoveNext())
				{
					Finish(_job);
					_job = null;
				}
			}
			_watch.Stop();
		}

		private void Begin(Group g, Vector3 viewer)
		{
			//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_0051: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			g.Dirty = false;
			bool flag = Categories.Small(g.Cat);
			float num = ViewRangeOf(g);
			OutlineSettings s = new OutlineSettings
			{
				Step = (flag ? 0.12f : 0.5f),
				MinSegments = (flag ? 12 : 16),
				Viewer = new V3(viewer.x, viewer.y, viewer.z),
				ViewRange = num
			};
			List<Zone> zones = new List<Zone>(g.Zones);
			List<Polyline> list = new List<Polyline>();
			_job = new Job
			{
				Group = g,
				Zones = zones,
				Lines = list,
				Steps = Outline.Steps(zones, _probe, s, list).GetEnumerator(),
				Viewer = viewer,
				Range = num
			};
		}

		private void Finish(Job job)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//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_00a9: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			Group obj = job.Group;
			obj.BuiltAt = job.Viewer;
			obj.BuiltTime = Time.time;
			bool flag = Categories.Small(obj.Cat);
			if ((Object)(object)obj.Go == (Object)null)
			{
				obj.Go = new GameObject("seer_" + obj.Cat.ToString() + "_" + obj.Id);
				obj.Go.transform.SetParent(Root().transform, false);
				obj.Mesh = new Mesh
				{
					name = ((Object)obj.Go).name
				};
				obj.Mesh.MarkDynamic();
				obj.Go.AddComponent<MeshFilter>().sharedMesh = obj.Mesh;
				MeshRenderer obj2 = obj.Go.AddComponent<MeshRenderer>();
				((Renderer)obj2).sharedMaterial = Material();
				((Renderer)obj2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)obj2).receiveShadows = false;
			}
			RibbonStyle st = new RibbonStyle
			{
				Colour = Shade(obj),
				Width = (flag ? (Cfg.LineWidth.Value * 0.45f) : Cfg.LineWidth.Value),
				Curtain = (flag ? 0f : Cfg.CurtainHeight.Value),
				Glow = (flag ? Mathf.Min(0.2f, Cfg.InnerGlow.Value) : Cfg.InnerGlow.Value),
				Lift = 0.04f + 0.008f * (float)Mathf.Min(Categories.Index(obj.Cat), 20),
				Alpha = (obj.Faint ? 0.45f : 1f) * Cfg.Brightness.Value
			};
			obj.Vertices = RibbonMesh.Fill(obj.Mesh, job.Lines, job.Zones, st, _probe, job.Viewer, job.Range);
			obj.Stretches = job.Lines.Count;
		}

		private GameObject Root()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if ((Object)(object)_root != (Object)null)
			{
				return _root;
			}
			_root = new GameObject("seer_lines");
			_root.transform.SetParent(((Component)this).transform, false);
			return _root;
		}

		private float ViewRangeOf(Group g)
		{
			if (!Categories.Small(g.Cat))
			{
				return Sight;
			}
			return Mathf.Min(Sight, Cfg.CropRange.Value);
		}

		private static Color Shade(Group g)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_00c2: 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_00b4: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_0110: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_017d: 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_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_01e7: 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_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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)
			if (g.Tint.HasValue)
			{
				Color value = g.Tint.Value;
				float num = Mathf.Max(value.r, Mathf.Max(value.g, value.b));
				if (!(num < 0.4f))
				{
					return value;
				}
				return Color.Lerp(value, Color.white, 0.4f - num + 0.15f);
			}
			Color val = Cfg.ColourOf(g.Cat);
			if (Categories.ShadedGroups(g.Cat) && g.Id != 0)
			{
				float num2 = default(float);
				float num3 = default(float);
				float num4 = default(float);
				Color.RGBToHSV(val, ref num2, ref num3, ref num4);
				float num5 = (float)((g.Id & 0x7FFFFFFF) % 7 - 3) * 0.035f;
				return Color.HSVToRGB((num2 + num5 + 1f) % 1f, num3, num4);
			}
			if (g.Cat != Category.Workshop)
			{
				return val;
			}
			int id = g.Id;
			if (id == StringExtensionMethods.GetStableHashCode("$piece_forge"))
			{
				return Color.Lerp(val, new Color(1f, 0.45f, 0.12f), 0.5f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_stonecutter"))
			{
				return Color.Lerp(val, Color.white, 0.5f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_artisanstation"))
			{
				return Color.Lerp(val, new Color(0.75f, 0.55f, 0.3f), 0.55f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_blackforge"))
			{
				return Color.Lerp(val, new Color(0.62f, 0.3f, 0.08f), 0.5f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_magetable"))
			{
				return Color.Lerp(val, new Color(1f, 0.96f, 0.55f), 0.55f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_cauldron"))
			{
				return Color.Lerp(val, new Color(1f, 0.72f, 0.62f), 0.55f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_preptable"))
			{
				return Color.Lerp(val, new Color(0.8f, 0.86f, 0.5f), 0.55f);
			}
			if (id == StringExtensionMethods.GetStableHashCode("$piece_meadcauldron"))
			{
				return Color.Lerp(val, new Color(0.9f, 0.55f, 0.3f), 0.55f);
			}
			return val;
		}

		private Material Material()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			if ((Object)(object)_mat != (Object)null)
			{
				return _mat;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended");
			_mat = new Material(val)
			{
				name = "seer_radius"
			};
			_mat.renderQueue = 3100;
			return _mat;
		}

		private void Visibility()
		{
			foreach (Group value in _groups.Values)
			{
				if (!((Object)(object)value.Go == (Object)null))
				{
					bool flag = Mode < 0 || (int)value.Cat == Mode;
					if (value.Go.activeSelf != flag)
					{
						value.Go.SetActive(flag);
					}
				}
			}
		}

		private void HideAll()
		{
			_shown = false;
			_job = null;
			_probe.Clear();
			Sources.ClearFloors();
			foreach (Group value in _groups.Values)
			{
				if ((Object)(object)value.Go != (Object)null)
				{
					Object.Destroy((Object)(object)value.Go);
				}
				if ((Object)(object)value.Mesh != (Object)null)
				{
					Object.Destroy((Object)(object)value.Mesh);
				}
			}
			_groups.Clear();
		}

		private List<(Category cat, Color colour, string text)> Standing(Player p)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			List<(Category, Color, string)> list = new List<(Category, Color, string)>();
			Vector3 position = ((Component)p).transform.position;
			V3 p2 = new V3(position.x, position.y, position.z);
			foreach (Category item3 in Categories.All)
			{
				if (Mode >= 0 && (int)item3 != Mode)
				{
					continue;
				}
				List<string> list2 = new List<string>();
				bool flag = true;
				Color item = Cfg.ColourOf(item3);
				foreach (Group value in _groups.Values)
				{
					if (value.Cat != item3)
					{
						continue;
					}
					for (int i = 0; i < value.Zones.Count; i++)
					{
						if (value.Zones[i].Contains(p2))
						{
							if (!value.Faint)
							{
								flag = false;
							}
							string item2 = Lang.L(value.Labels[i]);
							if (!list2.Contains(item2))
							{
								list2.Add(item2);
							}
							item = Shade(value);
						}
					}
				}
				if (list2.Count == 0)
				{
					continue;
				}
				string text = Lang.CategoryName(item3);
				if (Categories.NamesInHud(item3))
				{
					text = text + " (" + string.Join(", ", list2) + ")";
				}
				if (item3 == Category.Ward)
				{
					if (flag)
					{
						text = text + " (" + Lang.T("seer_hud_off") + ")";
					}
					else if (!PrivateArea.CheckAccess(position, 0f, false, false))
					{
						text = text + " (" + Lang.T("seer_hud_noaccess") + ")";
					}
				}
				if (item3 == Category.Comfort)
				{
					text = Lang.T("seer_hud_comfort", SE_Rested.CalculateComfortLevel(p));
				}
				list.Add((item3, item, text));
			}
			return list;
		}

		public Dictionary<Category, (int groups, int zones, int stretches, int vertices)> Stats()
		{
			Dictionary<Category, (int, int, int, int)> dictionary = new Dictionary<Category, (int, int, int, int)>();
			foreach (Group value2 in _groups.Values)
			{
				dictionary.TryGetValue(value2.Cat, out var value);
				dictionary[value2.Cat] = (value.Item1 + 1, value.Item2 + value2.Zones.Count, value.Item3 + value2.Stretches, value.Item4 + value2.Vertices);
			}
			return dictionary;
		}

		public List<Zone> ZonesOf(Category cat)
		{
			List<Zone> list = new List<Zone>();
			foreach (Group value in _groups.Values)
			{
				if (value.Cat == cat)
				{
					list.AddRange(value.Zones);
				}
			}
			return list;
		}

		public string StandingText(Player p)
		{
			List<string> list = new List<string>();
			foreach (var item in Standing(p))
			{
				list.Add(item.text);
			}
			return string.Join(" · ", list);
		}
	}
	internal struct RibbonStyle
	{
		public Color Colour;

		public float Width;

		public float Curtain;

		public float Glow;

		public float Lift;

		public float Alpha;
	}
	internal static class RibbonMesh
	{
		public const float LineAlpha = 0.9f;

		public const float GlowAlpha = 0.26f;

		public const float CurtainAlpha = 0.3f;

		public const float ColourScale = 0.72f;

		public const float CurtainNear = 2f;

		public const float CurtainFar = 8f;

		public const float FadeShare = 0.18f;

		private static readonly List<Vector3> V = new List<Vector3>();

		private static readonly List<Color> C = new List<Color>();

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

		public static int Fill(Mesh mesh, List<Polyline> lines, IList<Zone> zones, RibbonStyle st, IGround ground, Vector3 viewer, float sight)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			V.Clear();
			C.Clear();
			T.Clear();
			foreach (Polyline line in lines)
			{
				if (line.Points.Count >= 2)
				{
					Strip(line, zones[line.Zone], st, ground, viewer, sight);
				}
			}
			mesh.Clear();
			mesh.indexFormat = (IndexFormat)(V.Count > 65000);
			mesh.SetVertices(V);
			mesh.SetColors(C);
			mesh.SetTriangles(T, 0);
			mesh.RecalculateBounds();
			return V.Count;
		}

		private static void Strip(Polyline pl, Zone z, RibbonStyle st, IGround ground, Vector3 viewer, float sight)
		{
			//IL_0069: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0122: 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_0129: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: 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_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: 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)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: 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_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: 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_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			int count = pl.Points.Count;
			int num = (pl.Closed ? (count + 1) : count);
			int count2 = V.Count;
			float num2 = Mathf.Min(st.Glow, z.Radius * 0.5f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(z.Center.X, 0f, z.Center.Z);
			if (z.IsSector)
			{
				val += new Vector3(Mathf.Sin(z.Facing), 0f, Mathf.Cos(z.Facing)) * (z.Radius * 0.5f);
			}
			Vector3 val2 = default(Vector3);
			Vector3 right = default(Vector3);
			Vector3 val5 = default(Vector3);
			Color c = default(Color);
			for (int i = 0; i < num; i++)
			{
				int num3 = i % count;
				V3 v = pl.Points[num3];
				((Vector3)(ref val2))..ctor(v.X, v.Y, v.Z);
				Vector3 val3 = P(pl, pl.Closed ? ((num3 - 1 + count) % count) : Mathf.Max(0, num3 - 1));
				Vector3 val4 = P(pl, pl.Closed ? ((num3 + 1) % count) : Mathf.Min(count - 1, num3 + 1)) - val3;
				val4.y = 0f;
				if (((Vector3)(ref val4)).sqrMagnitude < 1E-08f)
				{
					val4 = Vector3.forward;
				}
				((Vector3)(ref val4)).Normalize();
				((Vector3)(ref right))..ctor(val.x - val2.x, 0f, val.z - val2.z);
				if (((Vector3)(ref right)).sqrMagnitude < 1E-08f)
				{
					right = Vector3.right;
				}
				((Vector3)(ref right)).Normalize();
				((Vector3)(ref val5))..ctor(0f - val4.z, 0f, val4.x);
				if (Vector3.Dot(val5, right) < 0f)
				{
					val5 = -val5;
				}
				float num4 = Utils.DistanceXZ(val2, viewer);
				float num5 = Mathf.Clamp01((sight - num4) / Mathf.Max(1f, sight * 0.18f)) * st.Alpha;
				((Color)(ref c))..ctor(st.Colour.r * 0.72f, st.Colour.g * 0.72f, st.Colour.b * 0.72f);
				float num6 = Mathf.Clamp01((num4 - 2f) / 6f);
				Vector3 val6 = Vector3.up * st.Lift;
				V.Add(val2 - val5 * (st.Width * 0.5f) + val6);
				C.Add(A(c, 0.9f * num5));
				V.Add(val2 + val5 * (st.Width * 0.5f) + val6);
				C.Add(A(c, 0.9f * num5));
				Vector3 val7 = val2 + val5 * (st.Width * 0.5f + num2);
				val7.y = ((num2 > 0f) ? ground.HeightAt(val7.x, val7.z, z.Center.Y) : val2.y);
				V.Add(val7 + val6);
				C.Add(A(c, 0f));
				V.Add(val2 + val6);
				C.Add(A(c, 0.3f * num5 * num6));
				V.Add(val2 + val6 + Vector3.up * st.Curtain);
				C.Add(A(c, 0f));
			}
			for (int j = 0; j < num - 1; j++)
			{
				int num7 = count2 + j * 5;
				int num8 = num7 + 5;
				Quad(num7, num7 + 1, num8, num8 + 1);
				if (num2 > 0f)
				{
					Quad(num7 + 1, num7 + 2, num8 + 1, num8 + 2);
				}
				if (st.Curtain > 0f)
				{
					Quad(num7 + 3, num7 + 4, num8 + 3, num8 + 4);
				}
			}
		}

		private static Vector3 P(Polyline pl, int i)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(pl.Points[i].X, pl.Points[i].Y, pl.Points[i].Z);
		}

		private static Color A(Color c, float a)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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)
			return new Color(c.r, c.g, c.b, a);
		}

		private static void Quad(int a0, int a1, int b0, int b1)
		{
			T.Add(a0);
			T.Add(b0);
			T.Add(a1);
			T.Add(a1);
			T.Add(b0);
			T.Add(b1);
		}
	}
	internal static class SpectacleModel
	{
		public static Vector3 FaceOffset = new Vector3(0f, 0.019f, 0.123f);

		public const float LensSpread = 0.039f;

		public const float LensRadius = 0.0265f;

		public const float LensOval = 0.88f;

		public const float RimTube = 0.0042f;

		public const float TempleSpread = 0.084f;

		private static Material _frame;

		private static Material _lens;

		public static Material FrameMat
		{
			get
			{
				//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_0049: 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_0068: Expected O, but got Unknown
				if ((Object)(object)_frame != (Object)null)
				{
					return _frame;
				}
				_frame = new Material(Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse") ?? Shader.Find("Sprites/Default"))
				{
					name = "seer_frame",
					color = new Color(0.33f, 0.22f, 0.11f)
				};
				if (_frame.HasProperty("_Metallic"))
				{
					_frame.SetFloat("_Metallic", 0.65f);
				}
				if (_frame.HasProperty("_Glossiness"))
				{
					_frame.SetFloat("_Glossiness", 0.55f);
				}
				return _frame;
			}
		}

		public static Material LensMat
		{
			get
			{
				//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_003d: Expected O, but got Unknown
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Expected O, but got Unknown
				if ((Object)(object)_lens != (Object)null)
				{
					return _lens;
				}
				Shader val = Shader.Find("Legacy Shaders/Particles/Alpha Blended");
				if ((Object)(object)val != (Object)null)
				{
					_lens = new Material(val)
					{
						name = "seer_lens"
					};
					_lens.SetColor("_TintColor", new Color(0.3f, 0.36f, 0.4f, 0.05f));
				}
				else
				{
					_lens = new Material(Shader.Find("Sprites/Default") ?? FrameMat.shader)
					{
						name = "seer_lens",
						color = new Color(0.6f, 0.7f, 0.75f, 0.15f)
					};
				}
				return _lens;
			}
		}

		public static GameObject Build(Transform parent, bool worn, float scale = 1f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0028: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0146: 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_0180: 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_01ba: 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)
			GameObject val = new GameObject("seer_spectacles");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = (worn ? FaceOffset : Vector3.zero);
			val.transform.localScale = Vector3.one * scale;
			Mesh mesh = MeshKit.Torus("seer_rim", 0.0265f, 0.0042f, 32, 8, 0f, 360f, 0.88f);
			Mesh mesh2 = MeshKit.Disc("seer_lens", 0.0244f, 32, 0.88f);
			float[] array = new float[2] { -1f, 1f };
			Vector3 localPosition = default(Vector3);
			foreach (float num in array)
			{
				((Vector3)(ref localPosition))..ctor(num * 0.039f, 0f, 0f);
				MeshKit.Part((num < 0f) ? "rim_l" : "rim_r", val.transform, mesh, FrameMat).transform.localPosition = localPosition;
				MeshKit.Part((num < 0f) ? "lens_l" : "lens_r", val.transform, mesh2, LensMat).transform.localPosition = localPosition;
				float num2 = num * 0.0655f;
				List<Vector3> path = new List<Vector3>
				{
					new Vector3(num2, 0.004f, -0.002f),
					new Vector3(num * 0.078f, 0.007f, -0.025f),
					new Vector3(num * 0.084f, 0.008f, -0.07f),
					new Vector3(num * 0.084f, 0.005f, -0.11f),
					new Vector3(num * 0.081f, -0.012f, -0.132f),
					new Vector3(num * 0.076f, -0.03f, -0.14f)
				};
				MeshKit.Part((num < 0f) ? "temple_l" : "temple_r", val.transform, MeshKit.Rod("seer_temple", path, 0.00336f), FrameMat);
			}
			float num3 = 0.012500001f;
			Mesh mesh3 = MeshKit.Torus("seer_bridge", num3 + 0.0042f, 0.00357f, 12, 6, 20f, 160f);
			MeshKit.Part("bridge", val.transform, mesh3, FrameMat).transform.localPosition = new Vector3(0f, 0.004f, 0f);
			return val;
		}
	}
}
namespace SeerSpectacles.UI
{
	internal static class StandingLine
	{
		public const float Top = 54f;

		private static GameObject _go;

		private static Text _text;

		public static string Last { get; private set; } = "";

		public static void Show(List<(Category cat, Color colour, string text)> parts)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!Cfg.ShowHud.Value)
			{
				Hide();
			}
			else
			{
				if ((Object)(object)_go == (Object)null && !Build())
				{
					return;
				}
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("<color=#D8D0B8>").Append(Lang.T("seer_hud_here")).Append(":</color> ");
				if (parts.Count == 0)
				{
					stringBuilder.Append("<color=#A8A090>").Append(Lang.T("seer_hud_nothing")).Append("</color>");
				}
				for (int i = 0; i < parts.Count; i++)
				{
					if (i > 0)
					{
						stringBuilder.Append("<color=#A8A090>  ·  </color>");
					}
					stringBuilder.Append("<color=#").Append(ColorUtility.ToHtmlStringRGB(parts[i].colour)).Append(">●</color> ")
						.Append(parts[i].text);
				}
				Last = stringBuilder.ToString();
				_text.text = Last;
				if (!_go.activeSelf)
				{
					_go.SetActive(true);
				}
			}
		}

		public static void Hide()
		{
			if ((Object)(object)_go != (Object)null && _go.activeSelf)
			{
				_go.SetActive(false);
			}
		}

		private static bool Build()
		{
			//IL_004d: 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_006b: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Hud.instance == (Object)null || (Object)(object)Hud.instance.m_rootObject == (Object)null || GUIManager.Instance == null)
			{
				return false;
			}
			GUIManager instance = GUIManager.Instance;
			_go = instance.CreateText("", Hud.instance.m_rootObject.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -54f), instance.AveriaSerifBold, 18, Color.white, true, new Color(0f, 0f, 0f, 0.9f), 1400f, 30f, false);
			((Object)_go).name = "seer_standing_line";
			_text = _go.GetComponent<Text>();
			_text.alignment = (TextAnchor)4;
			_text.supportRichText = true;
			((Graphic)_text).raycastTarget = false;
			_text.horizontalOverflow = (HorizontalWrapMode)1;
			return true;
		}
	}
}
namespace SeerSpectacles.Gameplay
{
	internal static class Extensions
	{
		private sealed class Rule
		{
			public string Mod;

			public RuleSpec Spec;

			public Type Type;

			public Expr List;

			public Expr Radius;

			public Expr Center;

			public Expr Active;

			public Expr Group;

			public Expr Faint;

			public Expr Tint;

			public Expr Arc;

			public Expr CategoryExpr;

			public Expr ShapeExpr;

			public Expr TitleExpr;

			public Expr ColourExpr;

			public Template Label;

			public Category Cat;

			public bool Dead;

			public int Errors;

			public int Drawn;
		}

		private sealed class Host : IExprHost
		{
			private readonly Dictionary<string, Type> _types = new Dictionary<string, Type>();

			public Type FindType(string fullName)
			{
				if (_types.TryGetValue(fullName, out var value))
				{
					return value;
				}
				value = null;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					value = SafeType(assemblies[i], fullName);
					if (value != null)
					{
						break;
					}
				}
				_types[fullName] = value;
				return value;
			}

			public bool Call(string name, object self, object[] args, out object result)
			{
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01af: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
				result = null;
				if (!name.StartsWith("zdo", StringComparison.Ordinal))
				{
					return false;
				}
				if (args.Length < 1 || !(args[0] is string text))
				{
					return false;
				}
				object obj = ((self is Component) ? self : null);
				ZNetView val = ((obj != null) ? ((Component)obj).GetComponentInParent<ZNetView>() : null);
				ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null);
				object obj2 = ((args.Length > 1) ? args[1] : null);
				double d;
				double num = (Expr.TryNumber(obj2, out d) ? d : 0.0);
				switch (name)
				{
				case "zdoString":
					result = ((val2 != null) ? val2.GetString(text, (obj2 as string) ?? "") : ((obj2 as string) ?? ""));
					return true;
				case "zdoFloat":
					result = ((val2 != null) ? val2.GetFloat(text, (float)num) : ((float)num));
					return true;
				case "zdoInt":
					result = ((val2 != null) ? val2.GetInt(text, (int)num) : ((int)num));
					return true;
				case "zdoLong":
					result = ((val2 != null) ? val2.GetLong(text, (long)num) : ((long)num));
					return true;
				case "zdoBool":
					result = ((val2 != null) ? val2.GetBool(text, num != 0.0) : (num != 0.0));
					return true;
				case "zdoVec3":
				{
					object obj3 = ((self is Component) ? self : null);
					Vector3 val3 = ((obj3 != null) ? ((Component)obj3).transform.position : Vector3.zero);
					result = ((val2 != null) ? val2.GetVec3(text, val3) : val3);
					return true;
				}
				default:
					return false;
				}
			}
		}

		public const string Convention = "SeerRadius";

		private const int MaxErrors = 8;

		private static readonly List<Rule> Rules = new List<Rule>();

		private static readonly List<Rule> PieceRules = new List<Rule>();

		private static readonly List<Rule> CharacterRules = new List<Rule>();

		private static readonly Dictionary<Type, Rule> ConventionRules = new Dictionary<Type, Rule>();

		private static readonly HashSet<string> FoundMods = new HashSet<string>();

		private static readonly Host TheHost = new Host();

		private static bool _ready;

		private static readonly Dictionary<Component, List<(Component c, Rule r)>> Attached = new Dictionary<Component, List<(Component, Rule)>>();

		private static readonly List<Found> PieceFinds = new List<Found>();

		private static float _pieceScanAt = -999f;

		private static float _pruneAt;

		private static Vector3 _pieceScanFrom;

		private static readonly List<(Component, Rule)> None = new List<(Component, Rule)>();

		public static bool Present(string assembly)
		{
			Prepare();
			return FoundMods.Contains(assembly);
		}

		public static IEnumerable<string> Describe()
		{
			Prepare();
			foreach (Rule rule in Rules)
			{
				yield return string.Format("{0}: {1} → {2}{3}, drawn {4}", rule.Mod, rule.Type?.Name, Categories.Key(rule.Cat), rule.Dead ? " (off)" : "", rule.Drawn);
			}
			foreach (Rule value in ConventionRules.Values)
			{
				if (value != null)
				{
					yield return string.Format("{0}: {1} → (convention){2}, drawn {3}", value.Mod, value.Type?.Name, value.Dead ? " (off)" : "", value.Drawn);
				}
			}
		}

		private static void Prepare()
		{
			if (_ready)
			{
				return;
			}
			_ready = true;
			if (!Cfg.Extensions.Value)
			{
				return;
			}
			Dictionary<string, Assembly> dictionary = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					dictionary[assembly.GetName().Name] = assembly;
				}
				catch (Exception)
				{
				}
			}
			KnownMods.Mod[] all = KnownMods.All;
			foreach (KnownMods.Mod mod in all)
			{
				if (!dictionary.TryGetValue(mod.Assembly, out var value))
				{
					continue;
				}
				int num = 0;
				string[] rules = mod.Rules;
				foreach (string text in rules)
				{
					if (!RuleSpec.TryParse(text, out var spec, out var error))
					{
						SeerSpectaclesPlugin.Log.LogWarning((object)(mod.Name + ": rule not read (" + error + "): " + text));
					}
					else
					{
						if (string.IsNullOrEmpty(spec.Assembly))
						{
							spec.Assembly = mod.Assembly;
						}
						if (Add(mod.Name, spec, value))
						{
							num++;
						}
					}
				}
				if (num > 0)
				{
					FoundMods.Add(mod.Assembly);
				}
				SeerSpectaclesPlugin.Log.LogInfo((object)$"{mod.Name} found: {num} of {mod.Rules.Length} kinds of radius are read.");
			}
			foreach (ConfigEntry<string> extraRule in Cfg.ExtraRules)
			{
				string value2 = extraRule.Value;
				if (string.IsNullOrWhiteSpace(value2))
				{
					continue;
				}
				if (!RuleSpec.TryParse(value2, out var spec2, out var error2))
				{
					SeerSpectaclesPlugin.Log.LogWarning((object)("Config " + ((ConfigEntryBase)extraRule).Definition.Key + ": not read (" + error2 + ")."));
					continue;
				}
				Assembly value3 = null;
				if (!string.IsNullOrEmpty(spec2.Assembly) && !dictionary.TryGetValue(spec2.Assembly, out value3))
				{
					SeerSpectaclesPlugin.Log.LogInfo((object)("Config " + ((ConfigEntryBase)extraRule).Definition.Key + ": assembly " + spec2.Assembly + " is not loaded; rule waits."));
				}
				else
				{
					Add("Config " + ((ConfigEntryBase)extraRule).Definition.Key, spec2, value3);
				}
			}
		}

		private static bool Add(string mod, RuleSpec spec, Assembly asm)
		{
			Type type = ((asm != null) ? SafeType(asm, spec.Type) : TheHost.FindType(spec.Type));
			if (type == null)
			{
				SeerSpectaclesPlugin.Log.LogWarning((object)(mod + ": type " + spec.Type + " not found; that radius is not shown."));
				return false;
			}
			Rule rule = new Rule
			{
				Mod = mod,
				Spec = spec,
				Type = type
			};
			try
			{
				if (spec.Source == RuleSource.List)
				{
					rule.List = Expr.Parse(spec.ListText.Contains("::") ? spec.ListText : (type.FullName + "::" + spec.ListText));
				}
				rule.Radius = Expr.Parse(spec.Radius);
				rule.Center = Opt(spec.Center);
				rule.Active = Opt(spec.Active);
				rule.Group = Opt(spec.Group);
				rule.Faint = Opt(spec.Faint);
				rule.Tint = Opt(spec.Tint);
				rule.Arc = Opt(spec.Arc);
				rule.Label = (string.IsNullOrEmpty(spec.Label) ? null : Template.Parse(spec.Label));
			}
			catch (FormatException ex)
			{
				SeerSpectaclesPlugin.Log.LogWarning((object)(mod + ": rule for " + type.Name + " not read: " + ex.Message));
				return false;
			}
			rule.Cat = Categories.Named(spec.Category, spec.Title, spec.Colour);
			Rules.Add(rule);
			if (spec.Source == RuleSource.Pieces)
			{
				PieceRules.Add(rule);
			}
			if (spec.Source == RuleSource.Characters)
			{
				CharacterRules.Add(rule);
			}
			return true;
		}

		private static Expr Opt(string s)
		{
			if (!string.IsNullOrWhiteSpace(s))
			{
				return Expr.Parse(s);
			}
			return null;
		}

		private static Type SafeType(Assembly a, string name)
		{
			try
			{
				return a.GetType(name, throwOnError: false);
			}
			catch (Exception)
			{
				return null;
			}
		}

		private static Rule ConventionOf(Type t)
		{
			if (ConventionRules.TryGetValue(t, out var value))
			{
				return value;
			}
			value = null;
			string name = t.Assembly.GetName().Name;
			if (!name.StartsWith("assembly_", StringComparison.Ordinal) && !name.StartsWith("Unity", StringComparison.Ordinal) && Has(t, "SeerRadius"))
			{
				value = new Rule
				{
					Mod = name,
					Type = t,
					Spec = new RuleSpec
					{
						Type = t.FullName,
						Radius = "SeerRadius",
						Text = "(convention)"
					},
					Radius = Expr.Parse("SeerRadius"),
					Center = (Has(t, "SeerCenter") ? Expr.Parse("SeerCenter") : null),
					Active = (Has(t, "SeerActive") ? Expr.Parse("SeerActive") : null),
					Group = (Has(t, "SeerGroup") ? Expr.Parse("SeerGroup") : null),
					Faint = (Has(t, "SeerFaint") ? Expr.Parse("SeerFaint") : null),
					Tint = (Has(t, "SeerTint") ? Expr.Parse("SeerTint") : null),
					Arc = (Has(t, "SeerArc") ? Expr.Parse("SeerArc") : null),
					Label = (Has(t, "SeerLabel") ? Template.Parse("{SeerLabel}") : null),
					CategoryExpr = (Has(t, "SeerCategory") ? Expr.Parse("SeerCategory") : null),
					TitleExpr = (Has(t, "SeerTitle") ? Expr.Parse("SeerTitle") : null),
					ColourExpr = (Has(t, "SeerColour") ? Expr.Parse("SeerColour") : (Has(t, "SeerColor") ? Expr.Parse("SeerColor") : null)),
					ShapeExpr = (Has(t, "SeerShape") ? Expr.Parse("SeerShape") : null)
				};
				if (value.CategoryExpr == null && value.TitleExpr == null && value.ColourExpr == null && value.ShapeExpr == null)
				{
					value.Cat = Categories.Named(t.Name, null, null);
				}
				SeerSpectaclesPlugin.Log.LogInfo((object)(name + ": " + t.Name + " shows its radius to the spectacles (SeerRadius)."));
			}
			ConventionRules[t] = value;
			return value;
		}

		private static bool Has(Type t, string name)
		{
			Type type = t;
			while (type != null && type != typeof(MonoBehaviour))
			{
				if (type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) != null)
				{
					return true;
				}
				if (type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) != null)
				{
					return true;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.Name == name && methodInfo.GetParameters().Length == 0)
					{
						return true;
					}
				}
				type = type.BaseType;
			}
			return false;
		}

		public static void Collect(Vector3 viewer, float sight, List<Found> into)
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			Prepare();
			if (!Cfg.Extensions.Value)
			{
				return;
			}
			foreach (Rule rule in Rules)
			{
				if (rule.Dead || rule.Spec.Source != RuleSource.List || !Cfg.Shows(rule.Cat))
				{
					continue;
				}
				object obj;
				try
				{
					obj = rule.List.Eval(null, TheHost);
				}
				catch (Exception e)
				{
					Fail(rule, e, fatal: true);
					continue;
				}
				if (!(obj is IEnumerable enumerable))
				{
					continue;
				}
				try
				{
					foreach (object item in enumerable)
					{
						Read(rule, (Component)((item is Component) ? item : null), viewer, sight, into);
					}
				}
				catch (InvalidOperationException)
				{
				}
			}
			Attachments(viewer, sight, into);
			if (!(Time.time > _pruneAt))
			{
				return;
			}
			_pruneAt = Time.time + 30f;
			List<Component> list = new List<Component>();
			foreach (Component key in Attached.Keys)
			{
				if ((Object)(object)key == (Object)null)
				{
					list.Add(key);
				}
			}
			foreach (Component item2 in list)
			{
				Attached.Remove(item2);
			}
		}

		private static void Attachments(Vector3 viewer, float sight, List<Found> into)
		{
			//IL_004f: 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_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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			bool value = Cfg.Convention.Value;
			if (value || PieceRules.Count > 0)
			{
				if (Time.time - _pieceScanAt >= 2f || Utils.DistanceXZ(viewer, _pieceScanFrom) >= 4f)
				{
					_pieceScanAt = Time.time;
					_pieceScanFrom = viewer;
					PieceFinds.Clear();
					float num = sight + 60f;
					foreach (Piece s_allPiece in Piece.s_allPieces)
					{
						if ((Object)(object)s_allPiece == (Object)null)
						{
							continue;
						}
						Vector3 position = ((Component)s_allPiece).transform.position;
						float num2 = position.x - viewer.x;
						float num3 = position.z - viewer.z;
						if (num2 * num2 + num3 * num3 > num * num)
						{
							continue;
						}
						foreach (var item in On((Component)(object)s_allPiece, PieceRules, value))
						{
							var (c, _) = item;
							Read(item.r, c, viewer, sight, PieceFinds);
						}
					}
				}
				into.AddRange(PieceFinds);
			}
			if (!value && CharacterRules.Count <= 0)
			{
				return;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter == (Object)null || allCharacter.IsDead() || Utils.DistanceXZ(((Component)allCharacter).transform.position, viewer) > sight + 60f)
				{
					continue;
				}
				foreach (var item2 in On((Component)(object)allCharacter, CharacterRules, value))
				{
					var (c2, _) = item2;
					Read(item2.r, c2, viewer, sight, into);
				}
			}
		}

		private static List<(Component c, Rule r)> On(Component host, List<Rule> rules, bool convention)
		{
			if (Attached.TryGetValue(host, out List<(Component, Rule)> value))
			{
				return value;
			}
			value = null;
			MonoBehaviour[] components = host.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				foreach (Rule rule2 in rules)
				{
					if (rule2.Type.IsAssignableFrom(type))
					{
						(value ?? (value = new List<(Component, Rule)>())).Add(((Component)(object)val, rule2));
					}
				}
				if (convention)
				{
					Rule rule = ConventionOf(type);
					if (rule != null)
					{
						(value ?? (value = new List<(Component, Rule)>())).Add(((Component)(object)val, rule));
					}
				}
			}
			value = value ?? None;
			Attached[host] = value;
			return value;
		}

		private static void Read(Rule r, Component c, Vector3 viewer, float sight, List<Found> into)
		{
			//IL_00b1: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			if (r.Dead || (Object)(object)c == (Object)null)
			{
				return;
			}
			try
			{
				Behaviour val = (Behaviour)(object)((c is Behaviour) ? c : null);
				if (val != null && !val.isActiveAndEnabled)
				{
					return;
				}
				ZNetView componentInParent = c.GetComponentInParent<ZNetView>();
				if (((Object)(object)componentInParent != (Object)null && !componentInParent.IsValid()) || (r.Active != null && !Expr.ToBool(r.Active.Eval(c, TheHost))) || !Expr.TryNumber(r.Radius.Eval(c, TheHost), out var d))
				{
					return;
				}
				float num = (float)d;
				if (num < 0.1f || float.IsNaN(num) || num > 2000f)
				{
					return;
				}
				Vector3 val2 = c.transform.position;
				if (r.Center != null && r.Center.Eval(c, TheHost) is Vector3 val3)
				{
					val2 = val3;
				}
				if (!(Utils.DistanceXZ(val2, viewer) - num < sight))
				{
					return;
				}
				Category cat = r.Cat;
				ZoneShape shape = r.Spec.Shape;
				int num3;
				if (r.CategoryExpr != null || r.ShapeExpr != null || r.TitleExpr != null || r.ColourExpr != null)
				{
					string text = r.CategoryExpr?.Eval(c, TheHost) as string;
					if (string.IsNullOrWhiteSpace(text))
					{
						text = r.Type.Name;
					}
					string title = r.TitleExpr?.Eval(c, TheHost) as string;
					string hex = ColourText(r.ColourExpr?.Eval(c, TheHost));
					cat = Categories.Named(text, title, hex);
					if (r.ShapeExpr != null)
					{
						object obj = r.ShapeExpr.Eval(c, TheHost);
						if (!(obj is string text2) || (!text2.Equals("Ball", StringComparison.OrdinalIgnoreCase) && !text2.Equals("Sphere", StringComparison.OrdinalIgnoreCase)))
						{
							bool flag = default(bool);
							int num2;
							if (obj is bool)
							{
								flag = (bool)obj;
								num2 = 1;
							}
							else
							{
								num2 = 0;
							}
							if (((uint)num2 & (flag ? 1u : 0u)) == 0)
							{
								num3 = 0;
								goto IL_0218;
							}
						}
						num3 = 1;
						goto IL_0218;
					}
				}
				goto IL_021a;
				IL_021a:
				if (Cfg.Shows(cat))
				{
					int num4 = 0;
					if (r.Group != null)
					{
						object obj2 = r.Group.Eval(c, TheHost);
						num4 = ((obj2 != null) ? StringExtensionMethods.GetStableHashCode(Expr.Format(obj2, null)) : 0);
					}
					string text3 = r.Label?.Eval(c, TheHost);
					if (string.IsNullOrWhiteSpace(text3))
					{
						text3 = NameOf(c);
					}
					bool faint = r.Faint != null && Expr.ToBool(r.Faint.Eval(c, TheHost));
					Color? tint = null;
					if (r.Tint != null && TryColour(r.Tint.Eval(c, TheHost), out var c2))
					{
						tint = c2;
					}
					float arc = 0f;
					float facing = 0f;
					if (r.Arc != null && Expr.TryNumber(r.Arc.Eval(c, TheHost), out var d2) && d2 > 0.0 && d2 < 180.0)
					{
						arc = (float)d2;
						Vector3 forward = c.transform.forward;
						facing = Mathf.Atan2(forward.x, forward.z);
					}
					Sources.Add(into, cat, num4, val2, num, shape, text3, faint, arc, facing, tint);
					r.Drawn++;
				}
				return;
				IL_0218:
				shape = (ZoneShape)num3;
				goto IL_021a;
			}
			catch (Exception ex)
			{
				Fail(r, (ex is TargetInvocationException { InnerException: not null } ex2) ? ex2.InnerException : ex, ex is MissingMemberException);
			}
		}

		private static void Fail(Rule r, Exception e, bool fatal)
		{
			r.Errors++;
			if (fatal || r.Errors >= 8)
			{
				r.Dead = true;
				SeerSpectaclesPlugin.Log.LogWarning((object)(r.Mod + ": radius of " + r.Type?.Name + " cannot be read (" + e.GetType().Name + ": " + e.Message + "); it is not shown any more."));
			}
		}

		private static string NameOf(Component c)
		{
			Piece componentInParent = c.GetComponentInParent<Piece>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent.m_name;
			}
			Character componentInParent2 = c.GetComponentInParent<Character>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				return componentInParent2.m_name;
			}
			return Utils.GetPrefabName(c.gameObject);
		}

		private static string ColourText(object o)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (o == null)
			{
				return null;
			}
			if (o is string result)
			{
				return result;
			}
			if (!TryColour(o, out var c))
			{
				return null;
			}
			return ColorUtility.ToHtmlStringRGB(c);
		}

		private static bool TryColour(object o, out Color c)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0025: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			c = Color.white;
			if (!(o is Color val))
			{
				if (!(o is Color32 val2))
				{
					if (o is string s)
					{
						if (!Categories.TryParseHex(s, out var r, out var g, out var b))
						{
							return false;
						}
						c = new Color(r, g, b, 1f);
						return true;
					}
					return false;
				}
				c = Color32.op_Implicit(val2);
				return true;
			}
			c = val;
			return true;
		}
	}
	public static class Recipes
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class AddToObjectDB
		{
			[HarmonyPriority(0)]
			private static void Postfix()
			{
				Apply();
			}
		}

		[HarmonyPatch(typeof(Requirement), "GetAmount")]
		private static class AmountPerLevel
		{
			private static bool Prefix(Requirement __instance, int qualityLevel, ref int __result)
			{
				if (!LevelOf.TryGetValue(__instance, out var value))
				{
					return true;
				}
				__result = ((qualityLevel == value && Amounts.TryGetValue(__instance, out var value2)) ? value2 : 0);
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "RequiredCraftingStation")]
		private static class StationPerLevel
		{
			private static bool Prefix(Player __instance, Recipe recipe, int qualityLevel, bool checkLevel, ref bool __result)
			{
				if ((Object)(object)recipe == (Object)null || (Object)(object)recipe != (Object)(object)Ours)
				{
					return true;
				}
				CraftingStation cur = __instance.m_currentStation;
				if ((Object)(object)cur != (Object)null && cur.m_upgrader)
				{
					__result = true;
					return false;
				}
				if ((Object)(object)cur == (Object)null)
				{
					__result = false;
					return false;
				}
				if (!checkLevel && qualityLevel <= 1)
				{
					__result = Specs.Any((LevelSpec s) => s != null && (Object)(object)StationOf(s) != (Object)null && StationOf(s).m_name == cur.m_name);
					return false;
				}
				LevelSpec levelSpec = SpecFor(qualityLevel);
				CraftingStation val = StationOf(levelSpec);
				__result = (Object)(object)val != (Object)null && val.m_name == cur.m_name && (!checkLevel || cur.GetLevel(true) >= levelSpec.StationLevel);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class NeverAtTheWrongStation
		{
			private static bool Prefix(InventoryGui __instance, Player player)
			{
				if ((Object)(object)Ours == (Object)null || (Object)(object)__instance.m_craftRecipe != (Object)(object)Ours)
				{
					return true;
				}
				if (StationAllows(player, QualityOf(__instance.m_craftUpgradeItem)))
				{
					return true;
				}
				__instance.m_craftTimer = -1f;
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")]
		private static class CraftOnlyAtFirstStation
		{
			private static void Prefix()
			{
				if (!((Object)(object)Ours == (Object)null))
				{
					CraftingStation val = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetCurrentCraftingStation() : null);
					CraftingStation val2 = StationOf(SpecFor(1));
					Ours.m_noCraftOnlyUpgrade = (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || val.m_name != val2.m_name;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")]
		private static class ShownStationLevel
		{
			private static void Postfix(InventoryGui __instance, Player player)
			{
				//IL_0129: 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)
				try
				{
					if (!((Object)(object)Ours == (Object)null) && !((Object)(object)((RecipeDataPair)(ref __instance.m_selectedRecipe)).Recipe != (Object)(object)Ours) && !((Object)(object)__instance.m_minStationLevelIcon == (Object)null) && ((Component)__instance.m_minStationLevelIcon).gameObject.activeSelf)
					{
						ItemData itemData = ((RecipeDataPair)(ref __instance.m_selectedRecipe)).ItemData;
						int quality = ((itemData == null) ? 1 : (itemData.m_quality + 1));
						LevelSpec levelSpec = SpecFor(quality);
						CraftingStation val = StationOf(levelSpec);
						CraftingStation val2 = (((Object)(object)player != (Object)null) ? player.GetCurrentCraftingStation() : null);
						__instance.m_minStationLevelText.text = levelSpec.StationLevel.ToString();
						bool num = StationAllows(player, quality);
						bool flag = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)25);
						bool flag2 = (Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null || val2.m_name != val.m_name;
						bool flag3 = !num && (flag2 || !flag) && Mathf.Sin(Time.time * 10f) > 0f;
						((Graphic)__instance.m_minStationLevelText).color = (flag3 ? Color.red : __instance.m_minStationLevelBasecolor);
						if (!num && (Object)(object)__instance.m_craftButton != (Object)null)
						{
							((Selectable)__instance.m_craftButton).interactable = false;
						}
					}
				}
				catch (Exception ex)
				{
					SeerSpectaclesPlug