Decompiled source of NightVisionGoggles v1.0.0

NightVisionGoggles.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NightVisionGoggles")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NightVisionGoggles")]
[assembly: AssemblyTitle("NightVisionGoggles")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NightVisionMod
{
	internal static class GogglesFactory
	{
		private static readonly List<(Renderer renderer, Color color)> Parts = new List<(Renderer, Color)>();

		private static bool _assetsApplied;

		internal static AudioClip ToggleOnClip;

		internal static AudioClip ToggleOffClip;

		internal static AudioClip BatteryDeadClip;

		private static readonly Color Body = new Color(0.16f, 0.17f, 0.15f);

		private static readonly Color Black = new Color(0.05f, 0.05f, 0.05f);

		private static readonly Color Lens = new Color(0.1f, 0.35f, 0.12f);

		private static readonly Color Olive = new Color(0.26f, 0.3f, 0.16f);

		public static Item Create()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: 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_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NetworkPrefabs.CreateNetworkPrefab("NightVisionGogglesItem");
			val.layer = 6;
			val.tag = "PhysicsProp";
			MeshRenderer mainObjectRenderer = Part(val, "Bridge", new Vector3(0f, 0f, 0f), new Vector3(0.2f, 0.065f, 0.07f), Body);
			Part(val, "TubeL", new Vector3(-0.055f, 0f, 0.065f), new Vector3(0.075f, 0.075f, 0.09f), Black);
			Part(val, "TubeR", new Vector3(0.055f, 0f, 0.065f), new Vector3(0.075f, 0.075f, 0.09f), Black);
			MeshRenderer val2 = Part(val, "LensL", new Vector3(-0.055f, 0f, 0.111f), new Vector3(0.058f, 0.058f, 0.004f), Lens);
			MeshRenderer val3 = Part(val, "LensR", new Vector3(0.055f, 0f, 0.111f), new Vector3(0.058f, 0.058f, 0.004f), Lens);
			Part(val, "Battery", new Vector3(0f, 0.048f, 0f), new Vector3(0.06f, 0.03f, 0.05f), Olive);
			Part(val, "StrapL", new Vector3(-0.112f, 0f, -0.03f), new Vector3(0.012f, 0.03f, 0.09f), Olive);
			Part(val, "StrapR", new Vector3(0.112f, 0f, -0.03f), new Vector3(0.012f, 0.03f, 0.09f), Olive);
			Part(val, "StrapBack", new Vector3(0f, 0f, -0.075f), new Vector3(0.236f, 0.03f, 0.012f), Olive);
			BoxCollider obj = val.AddComponent<BoxCollider>();
			((Collider)obj).isTrigger = true;
			obj.center = new Vector3(0f, 0.01f, 0.02f);
			obj.size = new Vector3(0.26f, 0.13f, 0.22f);
			GameObject val4 = new GameObject("ScanNode")
			{
				layer = 22
			};
			val4.transform.SetParent(val.transform, false);
			BoxCollider obj2 = val4.AddComponent<BoxCollider>();
			((Collider)obj2).isTrigger = true;
			obj2.size = Vector3.one * 0.4f;
			ScanNodeProperties obj3 = val4.AddComponent<ScanNodeProperties>();
			obj3.headerText = "Night Vision Goggles";
			obj3.subText = "See in the dark. Monsters light up.";
			obj3.nodeType = 0;
			obj3.minRange = 1;
			obj3.maxRange = 13;
			obj3.requiresLineOfSight = true;
			obj3.creatureScanID = -1;
			AudioSource val5 = val.AddComponent<AudioSource>();
			val5.playOnAwake = false;
			val5.spatialBlend = 1f;
			val5.rolloffMode = (AudioRolloffMode)1;
			val5.maxDistance = 15f;
			Item val6 = ScriptableObject.CreateInstance<Item>();
			((Object)val6).name = "NightVisionGogglesItem";
			val6.itemName = "Night Vision Goggles";
			val6.creditsWorth = Plugin.Price.Value;
			val6.weight = 1f + Mathf.Max(0f, Plugin.WeightLbs.Value) / 105f;
			val6.isScrap = false;
			val6.twoHanded = false;
			val6.twoHandedAnimation = false;
			val6.holdButtonUse = false;
			val6.requiresBattery = true;
			val6.batteryUsage = Mathf.Max(10f, Plugin.BatteryLifeSeconds.Value);
			val6.itemIsTrigger = false;
			val6.canBeGrabbedBeforeGameStart = true;
			val6.isConductiveMetal = true;
			val6.itemSpawnsOnGround = true;
			val6.allowDroppingAheadOfPlayer = true;
			val6.grabAnim = "";
			val6.verticalOffset = 0.08f;
			val6.restingRotation = Vector3.zero;
			val6.positionOffset = new Vector3(0f, 0.04f, 0.02f);
			val6.rotationOffset = new Vector3(0f, 90f, 0f);
			val6.toolTips = new string[2]
			{
				"Night vision on/off : [LMB]",
				"Wear & toggle from inventory : [" + Plugin.ToggleKey.Value.ToUpperInvariant() + "]"
			};
			val6.spawnPositionTypes = new List<ItemGroup>();
			val6.meshVariants = (Mesh[])(object)new Mesh[0];
			val6.materialVariants = (Material[])(object)new Material[0];
			val6.highestSalePercentage = 80;
			val6.itemIcon = MakeIcon();
			val6.spawnPrefab = val;
			R.Set(val6, "syncUseFunction", true);
			GogglesItem gogglesItem = val.AddComponent<GogglesItem>();
			((GrabbableObject)gogglesItem).itemProperties = val6;
			((GrabbableObject)gogglesItem).grabbable = true;
			((GrabbableObject)gogglesItem).grabbableToEnemies = true;
			((GrabbableObject)gogglesItem).mainObjectRenderer = mainObjectRenderer;
			gogglesItem.audioSource = val5;
			gogglesItem.lenses = (Renderer[])(object)new Renderer[2]
			{
				(Renderer)val2,
				(Renderer)val3
			};
			return val6;
		}

		private static MeshRenderer Part(GameObject parent, string name, Vector3 pos, Vector3 size, Color color)
		{
			//IL_0037: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>());
			((Object)obj).name = name;
			obj.layer = 6;
			obj.transform.SetParent(parent.transform, false);
			obj.transform.localPosition = pos;
			obj.transform.localScale = size;
			MeshRenderer component = obj.GetComponent<MeshRenderer>();
			Parts.Add(((Renderer)(object)component, color));
			return component;
		}

		public static GameObject BuildCosmetic()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("NVG_WornGoggles");
			MaterialPropertyBlock val2 = new MaterialPropertyBlock();
			MeshRenderer[] componentsInChildren = Plugin.GogglesItemDef.spawnPrefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val3 in componentsInChildren)
			{
				MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)((Component)val3).transform == (Object)(object)Plugin.GogglesItemDef.spawnPrefab.transform))
				{
					GameObject val4 = new GameObject(((Object)val3).name);
					val4.transform.SetParent(val.transform, false);
					val4.transform.localPosition = ((Component)val3).transform.localPosition;
					val4.transform.localRotation = ((Component)val3).transform.localRotation;
					val4.transform.localScale = ((Component)val3).transform.localScale;
					val4.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
					MeshRenderer val5 = val4.AddComponent<MeshRenderer>();
					((Renderer)val5).sharedMaterial = ((Renderer)val3).sharedMaterial;
					if (((Object)val3).name.StartsWith("Lens"))
					{
						val2.Clear();
						val2.SetColor("_EmissiveColor", new Color(0.2f, 1f, 0.3f) * 6f);
						((Renderer)val5).SetPropertyBlock(val2);
					}
				}
			}
			return val;
		}

		private static Sprite MakeIcon()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0170: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[16384];
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(40f, 64f);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(88f, 64f);
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					Vector2 val4 = new Vector2((float)j + 0.5f, (float)i + 0.5f);
					float num = Vector2.Distance(val4, val2);
					float num2 = Vector2.Distance(val4, val3);
					bool flag = (num <= 27f && num >= 15f) || (num2 <= 27f && num2 >= 15f);
					bool flag2 = j >= 52 && j <= 76 && i >= 56 && i <= 72;
					bool flag3 = (j <= 16 || j >= 112) && i >= 59 && i <= 69 && j >= 4 && j <= 124;
					bool flag4 = ((j > 12 && j < 16) || (j > 112 && j < 116)) && i >= 56 && i <= 72;
					bool flag5 = num < 15f || num2 < 15f;
					array[i * 128 + j] = ((flag || ((flag2 || flag3 || flag4) && !flag5)) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
		}

		public static void ApplyVanillaAssets(StartOfRound sor)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0117: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			if (_assetsApplied || (Object)(object)sor == (Object)null || (Object)(object)sor.allItemsList == (Object)null)
			{
				return;
			}
			try
			{
				List<Item> itemsList = sor.allItemsList.itemsList;
				Material val = null;
				foreach (Item item3 in itemsList)
				{
					if (!((Object)(object)item3 == (Object)null) && !((Object)(object)item3.spawnPrefab == (Object)null) && !((Object)(object)item3 == (Object)(object)Plugin.GogglesItemDef))
					{
						MeshRenderer componentInChildren = item3.spawnPrefab.GetComponentInChildren<MeshRenderer>(true);
						if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null && ((Renderer)componentInChildren).sharedMaterial.HasProperty("_BaseColor"))
						{
							val = ((Renderer)componentInChildren).sharedMaterial;
							break;
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					foreach (var part in Parts)
					{
						Renderer item = part.renderer;
						Color item2 = part.color;
						Material val2 = new Material(val)
						{
							name = "NVG_" + ((Object)item).name
						};
						string[] array = new string[4] { "_BaseColorMap", "_NormalMap", "_MaskMap", "_EmissiveColorMap" };
						foreach (string text in array)
						{
							if (val2.HasProperty(text))
							{
								val2.SetTexture(text, (Texture)null);
							}
						}
						val2.DisableKeyword("_NORMALMAP");
						val2.DisableKeyword("_MASKMAP");
						val2.SetColor("_BaseColor", item2);
						if (val2.HasProperty("_Metallic"))
						{
							val2.SetFloat("_Metallic", 0.2f);
						}
						if (val2.HasProperty("_Smoothness"))
						{
							val2.SetFloat("_Smoothness", 0.5f);
						}
						item.sharedMaterial = val2;
					}
				}
				else
				{
					Plugin.Log.LogWarning((object)"Couldn't find a vanilla material to copy; the goggles may look pink.");
				}
				Item val3 = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item val5) => (Object)(object)val5 != (Object)null && val5.itemName == "Flashlight")) ?? ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item val5) => (Object)(object)val5 != (Object)null && val5.itemName == "Pro-flashlight"));
				if ((Object)(object)val3 != (Object)null)
				{
					Plugin.GogglesItemDef.grabSFX = val3.grabSFX;
					Plugin.GogglesItemDef.dropSFX = val3.dropSFX;
					Plugin.GogglesItemDef.pocketSFX = val3.pocketSFX;
					FlashlightItem val4 = (((Object)(object)val3.spawnPrefab != (Object)null) ? val3.spawnPrefab.GetComponent<FlashlightItem>() : null);
					if ((Object)(object)val4 != (Object)null)
					{
						if (R.Get(val4, "flashlightClips") is AudioClip[] array2 && array2.Length != 0)
						{
							ToggleOnClip = array2[0];
							ToggleOffClip = ((array2.Length > 1) ? array2[1] : array2[0]);
						}
						object obj = R.Get(val4, "outOfBatteriesClip");
						BatteryDeadClip = (AudioClip)((obj is AudioClip) ? obj : null);
					}
				}
				_assetsApplied = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to apply vanilla assets: " + ex));
			}
		}
	}
	internal static class R
	{
		private static readonly HashSet<string> Warned = new HashSet<string>();

		private static void Warn(string what)
		{
			if (Warned.Add(what))
			{
				Plugin.Log.LogWarning((object)("Game member not found (game version difference?): " + what));
			}
		}

		public static object Get(object obj, string name)
		{
			if (obj == null)
			{
				return null;
			}
			FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), name);
			if (fieldInfo != null)
			{
				return fieldInfo.GetValue(obj);
			}
			PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), name);
			if (propertyInfo != null && propertyInfo.CanRead)
			{
				return propertyInfo.GetValue(obj);
			}
			Warn(obj.GetType().Name + "." + name);
			return null;
		}

		public static void Set(object obj, string name, object value)
		{
			if (obj == null)
			{
				return;
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), name);
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(obj, value);
					return;
				}
				PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), name);
				if (propertyInfo != null && propertyInfo.CanWrite)
				{
					propertyInfo.SetValue(obj, value);
				}
				else
				{
					Warn(obj.GetType().Name + "." + name);
				}
			}
			catch (Exception ex)
			{
				Warn(obj.GetType().Name + "." + name + " (" + ex.Message + ")");
			}
		}
	}
	public class GogglesItem : GrabbableObject
	{
		public AudioSource audioSource;

		public Renderer[] lenses;

		private static readonly int EmissiveId = Shader.PropertyToID("_EmissiveColor");

		private static MaterialPropertyBlock _block;

		private bool _lensLit;

		public static readonly HashSet<GogglesItem> All = new HashSet<GogglesItem>();

		public bool IsWorking
		{
			get
			{
				if (base.isBeingUsed && base.insertedBattery != null && !base.insertedBattery.empty)
				{
					return base.insertedBattery.charge > 0f;
				}
				return false;
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			bool flag = base.insertedBattery != null && !base.insertedBattery.empty && base.insertedBattery.charge > 0f;
			base.isBeingUsed = used && flag;
			Plugin.Log.LogInfo((object)("Goggles switched " + (base.isBeingUsed ? "ON" : "OFF") + " (requested " + (used ? "on" : "off") + ", battery " + ((base.insertedBattery != null) ? base.insertedBattery.charge.ToString("0.00") : "none") + ", held by " + (((Object)(object)base.playerHeldBy != (Object)null) ? base.playerHeldBy.playerUsername : "nobody") + ")"));
			PlayClip(base.isBeingUsed ? GogglesFactory.ToggleOnClip : GogglesFactory.ToggleOffClip);
			UpdateLens();
		}

		public void TogglePowerFromInventory()
		{
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			bool flag = !base.isBeingUsed;
			if (flag && (base.insertedBattery == null || base.insertedBattery.empty || base.insertedBattery.charge <= 0f))
			{
				HUDManager.Instance.DisplayTip("Night Vision Goggles", "Battery dead. Charge them at the ship.", true, false, "LC_Tip1");
				return;
			}
			((GrabbableObject)this).ItemActivate(flag, true);
			try
			{
				if (R.Get(this, "isSendingItemRPC") is int num)
				{
					R.Set(this, "isSendingItemRPC", num + 1);
				}
				AccessTools.Method(typeof(GrabbableObject), "ActivateItemServerRpc", (Type[])null, (Type[])null)?.Invoke(this, new object[2] { flag, true });
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Couldn't sync goggles on/off to other players: " + (ex.InnerException?.Message ?? ex.Message)));
			}
		}

		public override void UseUpBatteries()
		{
			((GrabbableObject)this).UseUpBatteries();
			base.isBeingUsed = false;
			PlayClip(GogglesFactory.BatteryDeadClip);
			UpdateLens();
			if ((Object)(object)base.playerHeldBy != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				HUDManager.Instance.DisplayTip("Night Vision Goggles", "Battery dead. Charge them at the ship.", true, false, "LC_Tip1");
			}
		}

		public override void DiscardItem()
		{
			if (base.isBeingUsed)
			{
				base.isBeingUsed = false;
				PlayClip(GogglesFactory.ToggleOffClip);
			}
			((GrabbableObject)this).DiscardItem();
			UpdateLens();
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
			All.Add(this);
			if (_lensLit != IsWorking)
			{
				UpdateLens();
			}
			if ((Object)(object)base.playerHeldBy != (Object)null && ((NetworkBehaviour)base.playerHeldBy).IsOwner)
			{
				try
				{
					NightVisionController.GetOrCreate().Tick("goggles");
				}
				catch (Exception e)
				{
					NightVisionController.ReportError("goggles update", e);
				}
			}
		}

		private void PlayClip(AudioClip clip)
		{
			if ((Object)(object)clip != (Object)null && (Object)(object)audioSource != (Object)null)
			{
				audioSource.PlayOneShot(clip, 0.8f);
			}
		}

		private void UpdateLens()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			_lensLit = IsWorking;
			if (lenses == null)
			{
				return;
			}
			if (_block == null)
			{
				_block = new MaterialPropertyBlock();
			}
			Renderer[] array = lenses;
			foreach (Renderer val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.GetPropertyBlock(_block);
					_block.SetColor(EmissiveId, _lensLit ? (new Color(0.2f, 1f, 0.3f) * 6f) : Color.black);
					val.SetPropertyBlock(_block);
				}
			}
		}
	}
	public class NightVisionController : MonoBehaviour
	{
		private class Highlight
		{
			public Component Target;

			public bool IsMonster;

			public string Label;

			public Color Color;

			public Renderer[] Renderers;

			public MaterialPropertyBlock[] Saved;

			public bool[] HadBlock;

			public bool Visible;

			public bool LineOfSight;

			public Vector3 CenterOffset;

			public float Height = 1.5f;

			public float Distance;

			public GameObject Light;

			public RectTransform Marker;

			public Image Box;

			public TextMeshProUGUI Text;
		}

		private const float RefreshInterval = 0.25f;

		private const float TrapScanInterval = 2f;

		private static readonly int EmissiveId = Shader.PropertyToID("_EmissiveColor");

		private static readonly int EmissionId = Shader.PropertyToID("_EmissionColor");

		private bool _active;

		private Light _nv;

		private bool _captured;

		private float _origIntensity;

		private float _origRange;

		private Color _origColor;

		private bool _origEnabled;

		private LightShadows _origShadows;

		private float _origShadowStrength;

		private const float VanillaNightVision = 366.9317f;

		private const FrameSettingsField FogField = (FrameSettingsField)28;

		private HDAdditionalCameraData _fogCam;

		private bool _origCustomSettings;

		private bool _origFogMask;

		private bool _origFogEnabled;

		private readonly Dictionary<PlayerControllerB, GameObject> _worn = new Dictionary<PlayerControllerB, GameObject>();

		private Key _toggleKey;

		private bool _keyParsed;

		private RawImage _screen;

		private Color _origScreenColor;

		private GameObject _overlayRoot;

		private RectTransform _container;

		private Image _fallbackTint;

		private TMP_FontAsset _font;

		private static Sprite _bracketSprite;

		private static Sprite _vignetteSprite;

		private readonly Dictionary<Component, Highlight> _highlights = new Dictionary<Component, Highlight>();

		private readonly List<Component> _trapCache = new List<Component>();

		private float _nextRefresh;

		private float _nextTrapScan;

		private static Type[] _trapTypes;

		public static NightVisionController Instance;

		private bool _loggedRunning;

		private string _lastReason;

		private static int _creations;

		private int _lastTickFrame = -1;

		private static float _nextErrorLog;

		private float _nextAlive;

		private readonly Dictionary<string, int> _driverCalls = new Dictionary<string, int>();

		private readonly List<GogglesItem> _allGoggles = new List<GogglesItem>();

		private float _nextGogglesScan;

		private string _localSource = "?";

		private int _ticks;

		private float _nextHeartbeat;

		private static MaterialPropertyBlock _tmp;

		private void Awake()
		{
			Instance = this;
		}

		public static NightVisionController GetOrCreate()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			_creations++;
			if (_creations > 1)
			{
				Plugin.Log.LogWarning((object)$"Night vision controller was removed by the game; recreating it (#{_creations}).");
			}
			GameObject val = new GameObject("NightVisionGogglesController");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			Instance = val.AddComponent<NightVisionController>();
			return Instance;
		}

		public static void ReportError(string where, Exception e)
		{
			if (!(Time.realtimeSinceStartup < _nextErrorLog))
			{
				_nextErrorLog = Time.realtimeSinceStartup + 5f;
				Plugin.Log.LogError((object)$"Night vision {where} failed: {e}");
			}
		}

		public void Tick(string driver = "?")
		{
			_driverCalls.TryGetValue(driver, out var value);
			_driverCalls[driver] = value + 1;
			if (Time.realtimeSinceStartup >= _nextAlive)
			{
				_nextAlive = Time.realtimeSinceStartup + 10f;
				Plugin.Log.LogInfo((object)("[alive] calls: " + string.Join(", ", _driverCalls.Select((KeyValuePair<string, int> kv) => kv.Key + "=" + kv.Value)) + $", goggles in world={_allGoggles.Count}, active={_active}"));
			}
			if (Time.frameCount == _lastTickFrame)
			{
				return;
			}
			_lastTickFrame = Time.frameCount;
			try
			{
				TickInner();
			}
			catch (Exception e)
			{
				ReportError("tick", e);
			}
		}

		private void TickInner()
		{
			if (!_loggedRunning)
			{
				_loggedRunning = true;
				Plugin.Log.LogInfo((object)"Night vision controller is running.");
			}
			PlayerControllerB val = ResolveLocal();
			if ((Object)(object)val != (Object)null && (Object)(object)_nv != (Object)null && (Object)/*isinst with value type is only supported in some contexts*/ != (Object)(object)_nv)
			{
				if (_active)
				{
					Deactivate();
				}
				_nv = null;
				_captured = false;
			}
			_ticks++;
			LogWhyNotActive(val);
			try
			{
				HandleToggleKey(val);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Toggle key error: " + ex.Message));
			}
			try
			{
				UpdateWornGoggles(val);
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogWarning((object)("Worn goggles error: " + ex2.Message));
			}
			bool flag = (Object)(object)val != (Object)null && val.isPlayerControlled && !val.isPlayerDead && HasWorkingGoggles(val);
			Heartbeat(val, flag);
			try
			{
				if (flag && !_active)
				{
					Activate(val);
				}
				else if (!flag && _active)
				{
					Deactivate();
				}
				if (_active)
				{
					ApplyNightVision();
					if (Time.time >= _nextRefresh)
					{
						_nextRefresh = Time.time + 0.25f;
						Refresh(val);
					}
					UpdatePerFrame(val);
				}
			}
			catch (Exception ex3)
			{
				Plugin.Log.LogError((object)("Night vision error, switching effect off: " + ex3));
				Deactivate();
			}
		}

		private PlayerControllerB ResolveLocal()
		{
			GogglesItem.All.RemoveWhere((GogglesItem x) => (Object)(object)x == (Object)null);
			_allGoggles.Clear();
			_allGoggles.AddRange(GogglesItem.All);
			foreach (GogglesItem allGoggle in _allGoggles)
			{
				if (!((Object)(object)allGoggle == (Object)null) && !((Object)(object)((GrabbableObject)allGoggle).playerHeldBy == (Object)null))
				{
					PlayerControllerB playerHeldBy = ((GrabbableObject)allGoggle).playerHeldBy;
					if (((NetworkBehaviour)playerHeldBy).IsOwner && playerHeldBy.isPlayerControlled)
					{
						_localSource = "goggles holder";
						return playerHeldBy;
					}
				}
			}
			PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null);
			if ((Object)(object)val != (Object)null)
			{
				_localSource = "StartOfRound";
				return val;
			}
			_localSource = "GameNetworkManager";
			if (!((Object)(object)GameNetworkManager.Instance != (Object)null))
			{
				return null;
			}
			return GameNetworkManager.Instance.localPlayerController;
		}

		private void LateUpdate()
		{
			Tick("lateupdate");
		}

		private void Heartbeat(PlayerControllerB local, bool want)
		{
			if (Time.realtimeSinceStartup < _nextHeartbeat)
			{
				return;
			}
			_nextHeartbeat = Time.realtimeSinceStartup + 10f;
			if (_allGoggles.Count == 0)
			{
				return;
			}
			PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
			PlayerControllerB val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null);
			Plugin.Log.LogInfo((object)("[status] local=" + (((Object)(object)local != (Object)null) ? local.playerUsername : "none") + " via " + _localSource + "; GNM local=" + (((Object)(object)val != (Object)null) ? (val.playerUsername + "#" + ((Object)val).GetInstanceID()) : "none") + ", SOR local=" + (((Object)(object)val2 != (Object)null) ? (val2.playerUsername + "#" + ((Object)val2).GetInstanceID()) : "none") + ", " + $"you#{(((Object)(object)local != (Object)null) ? ((Object)local).GetInstanceID() : 0)} slots={(((Object)(object)local != (Object)null && local.ItemSlots != null) ? local.ItemSlots.Length : (-1))}"));
			if (!((Object)(object)local == (Object)null) && local.ItemSlots != null)
			{
				List<GogglesItem> source = _allGoggles.Where((GogglesItem i) => (Object)(object)i != (Object)null).ToList();
				string arg = string.Join("; ", source.Select((GogglesItem i) => string.Format("on={0} working={1} pocketed={2} heldBy={3} ", ((GrabbableObject)i).isBeingUsed, i.IsWorking, ((GrabbableObject)i).isPocketed, ((Object)(object)((GrabbableObject)i).playerHeldBy != (Object)null) ? ((GrabbableObject)i).playerHeldBy.playerUsername : "none") + "battery=" + ((((GrabbableObject)i).insertedBattery != null) ? (((GrabbableObject)i).insertedBattery.charge.ToString("0.00") + (((GrabbableObject)i).insertedBattery.empty ? " (empty)" : "")) : "none")));
				Plugin.Log.LogInfo((object)($"[status] ticks={_ticks} player={local.playerUsername} controlled={local.isPlayerControlled} dead={local.isPlayerDead} " + $"want={want} active={_active} goggles: {arg}"));
			}
		}

		private void LogWhyNotActive(PlayerControllerB local)
		{
			if (_active || (Object)(object)local == (Object)null)
			{
				return;
			}
			GogglesItem gogglesItem = GogglesItem.All.FirstOrDefault((GogglesItem i) => (Object)(object)i != (Object)null && ((GrabbableObject)i).isBeingUsed && (Object)(object)((GrabbableObject)i).playerHeldBy != (Object)null && ((NetworkBehaviour)((GrabbableObject)i).playerHeldBy).IsOwner);
			if ((Object)(object)gogglesItem == (Object)null)
			{
				_lastReason = null;
				return;
			}
			string text = ((!local.isPlayerControlled) ? "player not controlled" : (local.isPlayerDead ? "player dead" : (((Object)(object)((GrabbableObject)gogglesItem).playerHeldBy != (Object)(object)local) ? "goggles not held by you" : ((((GrabbableObject)gogglesItem).insertedBattery == null) ? "no battery" : (((GrabbableObject)gogglesItem).insertedBattery.empty ? "battery marked empty" : ((((GrabbableObject)gogglesItem).insertedBattery.charge <= 0f) ? "battery charge 0" : null))))));
			if (text != null && text != _lastReason)
			{
				_lastReason = text;
				Plugin.Log.LogInfo((object)("Goggles are on but night vision is not active: " + text));
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			Deactivate();
			foreach (GameObject value in _worn.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			_worn.Clear();
		}

		private void HandleToggleKey(PlayerControllerB local)
		{
			//IL_00a2: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)local == (Object)null || !local.isPlayerControlled || local.isPlayerDead || Keyboard.current == null)
			{
				return;
			}
			if (!_keyParsed)
			{
				_keyParsed = true;
				if (!Enum.TryParse<Key>(Plugin.ToggleKey.Value.Trim(), ignoreCase: true, out _toggleKey) || (int)_toggleKey == 0)
				{
					Plugin.Log.LogWarning((object)("ToggleKey '" + Plugin.ToggleKey.Value + "' isn't a valid key name; using N."));
					_toggleKey = (Key)28;
				}
			}
			if (!((ButtonControl)Keyboard.current[_toggleKey]).wasPressedThisFrame)
			{
				return;
			}
			object obj = R.Get(local, "isTypingChat");
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			if (((uint)num & (flag ? 1u : 0u)) != 0)
			{
				return;
			}
			obj = R.Get(local, "inTerminalMenu");
			bool flag2 = default(bool);
			int num2;
			if (obj is bool)
			{
				flag2 = (bool)obj;
				num2 = 1;
			}
			else
			{
				num2 = 0;
			}
			if (((uint)num2 & (flag2 ? 1u : 0u)) != 0)
			{
				return;
			}
			obj = R.Get(R.Get(local, "quickMenuManager"), "isMenuOpen");
			bool flag3 = default(bool);
			int num3;
			if (obj is bool)
			{
				flag3 = (bool)obj;
				num3 = 1;
			}
			else
			{
				num3 = 0;
			}
			if (((uint)num3 & (flag3 ? 1u : 0u)) == 0)
			{
				GogglesItem gogglesItem = GogglesItem.All.FirstOrDefault((GogglesItem i) => (Object)(object)i != (Object)null && (Object)(object)((GrabbableObject)i).playerHeldBy == (Object)(object)local);
				if (!((Object)(object)gogglesItem == (Object)null))
				{
					gogglesItem.TogglePowerFromInventory();
				}
			}
		}

		private void UpdateWornGoggles(PlayerControllerB local)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: 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)
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null)
			{
				return;
			}
			Vector3 val = Plugin.ParseVec(Plugin.HeadOffset.Value, new Vector3(0f, 0.02f, 0.06f));
			PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
			foreach (PlayerControllerB p in allPlayerScripts)
			{
				if ((Object)(object)p == (Object)null)
				{
					continue;
				}
				bool num = (Object)(object)p != (Object)(object)local && p.isPlayerControlled && !p.isPlayerDead && (Object)(object)p.gameplayCamera != (Object)null && GogglesItem.All.Any((GogglesItem g) => (Object)(object)g != (Object)null && g.IsWorking && ((GrabbableObject)g).isPocketed && (Object)(object)((GrabbableObject)g).playerHeldBy == (Object)(object)p);
				_worn.TryGetValue(p, out var value);
				if (!num)
				{
					if ((Object)(object)value != (Object)null && value.activeSelf)
					{
						value.SetActive(false);
					}
					continue;
				}
				if ((Object)(object)value == (Object)null)
				{
					value = GogglesFactory.BuildCosmetic();
					_worn[p] = value;
				}
				if (!value.activeSelf)
				{
					value.SetActive(true);
				}
				Transform transform = ((Component)p.gameplayCamera).transform;
				Quaternion val2 = Quaternion.LookRotation(transform.forward, ((Component)p).transform.up);
				value.transform.SetPositionAndRotation(transform.position + val2 * val, val2);
			}
		}

		private static bool HasWorkingGoggles(PlayerControllerB p)
		{
			foreach (GogglesItem item in GogglesItem.All)
			{
				if ((Object)(object)item != (Object)null && item.IsWorking && (Object)(object)((GrabbableObject)item).playerHeldBy == (Object)(object)p)
				{
					return true;
				}
			}
			return false;
		}

		private void Activate(PlayerControllerB local)
		{
			//IL_00a2: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			_active = true;
			ref Light nv = ref _nv;
			object obj = R.Get(local, "nightVision");
			nv = (Light)((obj is Light) ? obj : null);
			if ((Object)(object)_nv == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Player night-vision light not found; only monster highlighting will work.");
			}
			if ((Object)(object)_nv != (Object)null)
			{
				if (!_captured)
				{
					_origIntensity = _nv.intensity;
					_origRange = _nv.range;
					_origColor = _nv.color;
					_captured = true;
				}
				_origEnabled = ((Behaviour)_nv).enabled;
				_origShadows = _nv.shadows;
				_origShadowStrength = _nv.shadowStrength;
			}
			_fogCam = (((Object)(object)local.gameplayCamera != (Object)null) ? ((Component)local.gameplayCamera).GetComponent<HDAdditionalCameraData>() : null);
			if ((Object)(object)_fogCam != (Object)null)
			{
				_origCustomSettings = _fogCam.customRenderingSettings;
				_origFogMask = ((BitArray128)(ref _fogCam.renderingPathCustomFrameSettingsOverrideMask.mask))[28u];
				_origFogEnabled = ((FrameSettings)(ref _fogCam.renderingPathCustomFrameSettings)).IsEnabled((FrameSettingsField)28);
			}
			BuildOverlay();
			Plugin.Log.LogInfo((object)("Night vision ON. Light: " + (((Object)(object)_nv != (Object)null) ? $"found (normal intensity {_origIntensity:0.#}, range {_origRange:0.#})" : "MISSING") + ", screen: " + (((Object)(object)_screen != (Object)null) ? ((Object)_screen).name : "fallback overlay") + ", fog control: " + (((Object)(object)_fogCam != (Object)null) ? "yes" : "no") + ", label font: " + (((Object)(object)_font != (Object)null) ? "yes" : "no")));
			_nextRefresh = 0f;
			_nextTrapScan = 0f;
		}

		private void Deactivate()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if (!_active)
			{
				return;
			}
			_active = false;
			if ((Object)(object)_nv != (Object)null && _captured)
			{
				_nv.intensity = _origIntensity;
				_nv.range = _origRange;
				_nv.color = _origColor;
				_nv.shadows = _origShadows;
				_nv.shadowStrength = _origShadowStrength;
				((Behaviour)_nv).enabled = _origEnabled;
			}
			if ((Object)(object)_fogCam != (Object)null)
			{
				((FrameSettings)(ref _fogCam.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, _origFogEnabled);
				((BitArray128)(ref _fogCam.renderingPathCustomFrameSettingsOverrideMask.mask))[28u] = _origFogMask;
				_fogCam.customRenderingSettings = _origCustomSettings;
			}
			_fogCam = null;
			Plugin.Log.LogInfo((object)"Night vision OFF.");
			if ((Object)(object)_screen != (Object)null)
			{
				((Graphic)_screen).color = _origScreenColor;
			}
			_screen = null;
			foreach (Highlight value in _highlights.Values)
			{
				Untrack(value);
			}
			_highlights.Clear();
			_trapCache.Clear();
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayRoot);
			}
			_overlayRoot = null;
			_container = null;
			_fallbackTint = null;
		}

		private void ApplyNightVision()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nv != (Object)null)
			{
				((Behaviour)_nv).enabled = true;
				_nv.intensity = Mathf.Max(0f, Plugin.Brightness.Value);
				_nv.range = Mathf.Max(_origRange, Plugin.LightRange.Value);
				_nv.shadows = (LightShadows)0;
				_nv.shadowStrength = 0f;
				_nv.color = new Color(0.75f, 1f, 0.75f);
			}
			if ((Object)(object)_fogCam != (Object)null && Plugin.RemoveFog.Value)
			{
				_fogCam.customRenderingSettings = true;
				((BitArray128)(ref _fogCam.renderingPathCustomFrameSettingsOverrideMask.mask))[28u] = true;
				((FrameSettings)(ref _fogCam.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, false);
			}
			float num = Mathf.Clamp01(Plugin.TintStrength.Value);
			if ((Object)(object)_screen != (Object)null)
			{
				((Graphic)_screen).color = Color.Lerp(_origScreenColor, new Color(0.35f, 1f, 0.4f, _origScreenColor.a), num);
			}
			else if ((Object)(object)_fallbackTint != (Object)null)
			{
				((Graphic)_fallbackTint).color = new Color(0.1f, 1f, 0.2f, num * 0.25f);
			}
		}

		private void BuildOverlay()
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			ref RawImage screen = ref _screen;
			object obj = R.Get(HUDManager.Instance, "playerScreenTexture");
			screen = (RawImage)((obj is RawImage) ? obj : null);
			if ((Object)(object)_screen == (Object)null)
			{
				GameObject val = GameObject.Find("Systems/UI/Canvas/Panel/GameObject/PlayerScreen");
				if ((Object)(object)val != (Object)null)
				{
					_screen = val.GetComponent<RawImage>();
				}
			}
			if ((Object)(object)_screen != (Object)null)
			{
				_origScreenColor = ((Graphic)_screen).color;
				_overlayRoot = new GameObject("NVG_Overlay", new Type[1] { typeof(RectTransform) });
				_overlayRoot.transform.SetParent(((Component)_screen).transform, false);
			}
			else
			{
				Plugin.Log.LogWarning((object)"Couldn't find the game's screen image; using a plain overlay instead.");
				_overlayRoot = new GameObject("NVG_OverlayCanvas", new Type[1] { typeof(RectTransform) });
				Canvas obj2 = _overlayRoot.AddComponent<Canvas>();
				obj2.renderMode = (RenderMode)0;
				obj2.sortingOrder = -50;
				RectTransform val2 = NewUI("Tint", _overlayRoot.transform);
				Stretch(val2);
				_fallbackTint = ((Component)val2).gameObject.AddComponent<Image>();
				((Graphic)_fallbackTint).raycastTarget = false;
			}
			_container = (RectTransform)_overlayRoot.transform;
			Stretch(_container);
			if (Plugin.Vignette.Value)
			{
				RectTransform obj3 = NewUI("Vignette", (Transform)(object)_container);
				Stretch(obj3);
				Image obj4 = ((Component)obj3).gameObject.AddComponent<Image>();
				obj4.sprite = VignetteSprite();
				((Graphic)obj4).color = Color.white;
				((Graphic)obj4).raycastTarget = false;
			}
			_font = (((Object)(object)HUDManager.Instance != (Object)null) ? (from t in ((Component)HUDManager.Instance).GetComponentsInChildren<TextMeshProUGUI>(true)
				select ((TMP_Text)t).font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null)) : null);
			if ((Object)(object)_font == (Object)null)
			{
				_font = (from t in Object.FindObjectsOfType<TextMeshProUGUI>()
					select ((TMP_Text)t).font).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null));
			}
		}

		private void Refresh(PlayerControllerB local)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			Camera gameplayCamera = local.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)gameplayCamera).transform.position;
			float value = Plugin.MaxDistance.Value;
			Color color = Plugin.ParseColor(Plugin.MonsterColor.Value, new Color(1f, 0.15f, 0.1f));
			Color color2 = Plugin.ParseColor(Plugin.TrapColor.Value, new Color(1f, 0.8f, 0.1f));
			HashSet<Component> seen = new HashSet<Component>();
			if ((Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.SpawnedEnemies != null)
			{
				foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
				{
					if (!((Object)(object)spawnedEnemy == (Object)null) && !spawnedEnemy.isEnemyDead)
					{
						float num = Vector3.Distance(position, ((Component)spawnedEnemy).transform.position);
						if (!(num > value))
						{
							string label = (((Object)(object)spawnedEnemy.enemyType != (Object)null && !string.IsNullOrEmpty(spawnedEnemy.enemyType.enemyName)) ? spawnedEnemy.enemyType.enemyName : "Monster");
							Track((Component)(object)spawnedEnemy, isMonster: true, label, color, num, seen);
						}
					}
				}
			}
			if (Plugin.HighlightTraps.Value)
			{
				if (Time.time >= _nextTrapScan)
				{
					_nextTrapScan = Time.time + 2f;
					ScanTraps();
				}
				bool flag = default(bool);
				foreach (Component item in _trapCache)
				{
					if ((Object)(object)item == (Object)null)
					{
						continue;
					}
					int num2;
					if (((object)item).GetType().Name == "Landmine")
					{
						object obj = R.Get(item, "hasExploded");
						if (obj is bool)
						{
							flag = (bool)obj;
							num2 = 1;
						}
						else
						{
							num2 = 0;
						}
					}
					else
					{
						num2 = 0;
					}
					if (((uint)num2 & (flag ? 1u : 0u)) == 0)
					{
						float num3 = Vector3.Distance(position, item.transform.position);
						if (!(num3 > value))
						{
							Track(item, isMonster: false, TrapName(item), color2, num3, seen);
						}
					}
				}
			}
			foreach (Component item2 in _highlights.Keys.Where((Component k) => (Object)(object)k == (Object)null || !seen.Contains(k)).ToList())
			{
				Untrack(_highlights[item2]);
				_highlights.Remove(item2);
			}
			int num4 = ((R.Get(StartOfRound.Instance, "collidersAndRoomMaskAndDefault") is int num5) ? num5 : 2305);
			foreach (Highlight value2 in _highlights.Values)
			{
				Vector3 val = value2.Target.transform.position + value2.CenterOffset;
				value2.LineOfSight = !Physics.Linecast(position, val, num4, (QueryTriggerInteraction)1);
			}
			HashSet<Highlight> hashSet = new HashSet<Highlight>(Plugin.MonsterLights.Value ? (from h in _highlights.Values
				where h.IsMonster && h.Visible
				orderby h.Distance
				select h).Take(Mathf.Max(0, Plugin.MaxMonsterLights.Value)) : Enumerable.Empty<Highlight>());
			foreach (Highlight value3 in _highlights.Values)
			{
				if (hashSet.Contains(value3))
				{
					if ((Object)(object)value3.Light == (Object)null)
					{
						value3.Light = MakeLight(value3.Color);
					}
					if ((Object)(object)value3.Light != (Object)null && !value3.Light.activeSelf)
					{
						value3.Light.SetActive(true);
					}
				}
				else if ((Object)(object)value3.Light != (Object)null && value3.Light.activeSelf)
				{
					value3.Light.SetActive(false);
				}
			}
		}

		private void Track(Component target, bool isMonster, string label, Color color, float distance, HashSet<Component> seen)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			seen.Add(target);
			if (!_highlights.TryGetValue(target, out var value))
			{
				value = new Highlight
				{
					Target = target,
					IsMonster = isMonster,
					Label = label.ToUpperInvariant(),
					Color = color
				};
				int radarLayer = LayerMask.NameToLayer("MapRadar");
				value.Renderers = (from r in target.GetComponentsInChildren<Renderer>(true)
					where (r is MeshRenderer || r is SkinnedMeshRenderer) && ((Component)r).gameObject.layer != radarLayer && ((Component)r).gameObject.layer != 22 && ((Object)((Component)r).gameObject).name.IndexOf("MapDot", StringComparison.OrdinalIgnoreCase) < 0
					select r).ToArray();
				value.Saved = (MaterialPropertyBlock[])(object)new MaterialPropertyBlock[value.Renderers.Length];
				value.HadBlock = new bool[value.Renderers.Length];
				for (int num = 0; num < value.Renderers.Length; num++)
				{
					value.HadBlock[num] = value.Renderers[num].HasPropertyBlock();
					if (value.HadBlock[num])
					{
						value.Saved[num] = new MaterialPropertyBlock();
						value.Renderers[num].GetPropertyBlock(value.Saved[num]);
					}
				}
				_highlights[target] = value;
			}
			value.Distance = distance;
			Bounds val = default(Bounds);
			bool flag = false;
			Renderer[] renderers = value.Renderers;
			foreach (Renderer val2 in renderers)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && ((Component)val2).gameObject.activeInHierarchy)
				{
					if (!flag)
					{
						val = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
				}
			}
			value.Visible = flag;
			if (flag)
			{
				value.CenterOffset = ((Bounds)(ref val)).center - target.transform.position;
				value.Height = Mathf.Max(0.3f, ((Bounds)(ref val)).size.y);
			}
			ApplyGlow(value);
		}

		private void ScanTraps()
		{
			_trapCache.Clear();
			if (_trapTypes == null)
			{
				_trapTypes = (from t in ((IEnumerable<string>)new string[3] { "Turret", "Landmine", "SpikeRoofTrap" }).Select((Func<string, Type>)AccessTools.TypeByName)
					where t != null && typeof(Component).IsAssignableFrom(t)
					select t).ToArray();
			}
			Type[] trapTypes = _trapTypes;
			for (int num = 0; num < trapTypes.Length; num++)
			{
				Object[] array = Object.FindObjectsOfType(trapTypes[num]);
				foreach (Object obj in array)
				{
					Component val = (Component)(object)((obj is Component) ? obj : null);
					if (val != null)
					{
						_trapCache.Add(val);
					}
				}
			}
		}

		private static string TrapName(Component t)
		{
			return ((object)t).GetType().Name switch
			{
				"Turret" => "Turret", 
				"Landmine" => "Landmine", 
				"SpikeRoofTrap" => "Spike trap", 
				_ => "Trap", 
			};
		}

		private static void ApplyGlow(Highlight h)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_005e: 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)
			if (_tmp == null)
			{
				_tmp = new MaterialPropertyBlock();
			}
			Color val = h.Color * Mathf.Max(0f, Plugin.GlowIntensity.Value);
			Renderer[] renderers = h.Renderers;
			foreach (Renderer val2 in renderers)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.GetPropertyBlock(_tmp);
					_tmp.SetColor(EmissiveId, val);
					_tmp.SetColor(EmissionId, val);
					val2.SetPropertyBlock(_tmp);
				}
			}
		}

		private static void Untrack(Highlight h)
		{
			if (h.Renderers != null)
			{
				for (int i = 0; i < h.Renderers.Length; i++)
				{
					Renderer val = h.Renderers[i];
					if (!((Object)(object)val == (Object)null))
					{
						val.SetPropertyBlock(h.HadBlock[i] ? h.Saved[i] : null);
					}
				}
			}
			if ((Object)(object)h.Light != (Object)null)
			{
				Object.Destroy((Object)(object)h.Light);
			}
			if ((Object)(object)h.Marker != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)h.Marker).gameObject);
			}
			h.Light = null;
			h.Marker = null;
		}

		private GameObject MakeLight(Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = new GameObject("NVG_MonsterLight");
				val.SetActive(false);
				Light val2 = val.AddComponent<Light>();
				val2.type = (LightType)2;
				if ((Object)(object)_nv != (Object)null)
				{
					Component component = ((Component)_nv).GetComponent("HDAdditionalLightData");
					if ((Object)(object)component != (Object)null)
					{
						Component val3 = val.AddComponent(((object)component).GetType());
						AccessTools.Method(((object)component).GetType(), "CopyTo", (Type[])null, (Type[])null)?.Invoke(component, new object[1] { val3 });
					}
				}
				val2.type = (LightType)2;
				val2.shadows = (LightShadows)0;
				val2.color = color;
				float num = Mathf.Max(_origIntensity, 366.9317f);
				val2.intensity = num * Mathf.Max(0f, Plugin.MonsterLightBoost.Value);
				val2.range = 6f;
				val.SetActive(true);
				return val;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Couldn't create a monster spotlight: " + ex.Message));
				return null;
			}
		}

		private void UpdatePerFrame(PlayerControllerB local)
		{
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: 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_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			Camera gameplayCamera = local.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null || (Object)(object)_container == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)gameplayCamera).transform.position;
			Rect rect = _container.rect;
			float num = Mathf.Tan(gameplayCamera.fieldOfView * 0.5f * (MathF.PI / 180f));
			foreach (Highlight value in _highlights.Values)
			{
				if ((Object)(object)value.Target == (Object)null)
				{
					continue;
				}
				Vector3 val = value.Target.transform.position + value.CenterOffset;
				if ((Object)(object)value.Light != (Object)null && value.Light.activeSelf)
				{
					Vector3 val2 = position - val;
					float num2 = Mathf.Min(1.5f, ((Vector3)(ref val2)).magnitude * 0.5f);
					value.Light.transform.position = val + ((Vector3)(ref val2)).normalized * num2;
					Light component = value.Light.GetComponent<Light>();
					if ((Object)(object)component != (Object)null)
					{
						component.range = 3f + value.Height + num2;
					}
				}
				bool num3 = Plugin.Markers.Value && value.Visible && (value.LineOfSight || Plugin.MarkersThroughWalls.Value);
				Vector3 val3 = gameplayCamera.WorldToViewportPoint(val);
				if (!num3 || val3.z <= 0.1f || val3.x < -0.1f || val3.x > 1.1f || val3.y < -0.1f || val3.y > 1.1f)
				{
					if ((Object)(object)value.Marker != (Object)null && ((Component)value.Marker).gameObject.activeSelf)
					{
						((Component)value.Marker).gameObject.SetActive(false);
					}
					continue;
				}
				if ((Object)(object)value.Marker == (Object)null)
				{
					CreateMarker(value);
				}
				if (!((Component)value.Marker).gameObject.activeSelf)
				{
					((Component)value.Marker).gameObject.SetActive(true);
				}
				RectTransform marker = value.Marker;
				Vector2 anchorMin = (value.Marker.anchorMax = new Vector2(val3.x, val3.y));
				marker.anchorMin = anchorMin;
				value.Marker.anchoredPosition = Vector2.zero;
				float num4 = 2f * val3.z * num;
				float num5 = Mathf.Clamp(value.Height / num4 * ((Rect)(ref rect)).height * 1.1f, 18f, ((Rect)(ref rect)).height * 0.9f);
				float num6 = Mathf.Clamp(num5 * 0.75f, 18f, ((Rect)(ref rect)).width * 0.9f);
				value.Marker.sizeDelta = new Vector2(num6, num5);
				Color color = value.Color;
				color.a = (value.LineOfSight ? 0.95f : 0.45f);
				((Graphic)value.Box).color = color;
				if ((Object)(object)value.Text != (Object)null)
				{
					((Component)value.Text).gameObject.SetActive(Plugin.ShowNames.Value);
					((TMP_Text)value.Text).text = $"{value.Label}  {Mathf.RoundToInt(value.Distance)}m";
					((Graphic)value.Text).color = color;
					((TMP_Text)value.Text).fontSize = Mathf.Clamp(((Rect)(ref rect)).height * 0.03f, 9f, 18f);
				}
			}
		}

		private void CreateMarker(Highlight h)
		{
			//IL_001c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			RectTransform val = NewUI("NVG_Marker", (Transform)(object)_container);
			val.pivot = new Vector2(0.5f, 0.5f);
			RectTransform obj = NewUI("Box", (Transform)(object)val);
			Stretch(obj);
			Image val2 = ((Component)obj).gameObject.AddComponent<Image>();
			val2.sprite = BracketSprite();
			val2.type = (Type)1;
			((Graphic)val2).raycastTarget = false;
			TextMeshProUGUI val3 = null;
			if ((Object)(object)_font != (Object)null)
			{
				RectTransform obj2 = NewUI("Label", (Transform)(object)val);
				obj2.anchorMin = new Vector2(0.5f, 0f);
				obj2.anchorMax = new Vector2(0.5f, 0f);
				obj2.pivot = new Vector2(0.5f, 1f);
				obj2.anchoredPosition = new Vector2(0f, -2f);
				obj2.sizeDelta = new Vector2(220f, 24f);
				val3 = ((Component)obj2).gameObject.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val3).font = _font;
				((TMP_Text)val3).alignment = (TextAlignmentOptions)258;
				((Graphic)val3).raycastTarget = false;
			}
			h.Marker = val;
			h.Box = val2;
			h.Text = val3;
		}

		private static RectTransform NewUI(string name, Transform parent)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			return (RectTransform)val.transform;
		}

		private static void Stretch(RectTransform rt)
		{
			//IL_0001: 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_0017: 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)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		private static Sprite BracketSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_bracketSprite != (Object)null)
			{
				return _bracketSprite;
			}
			Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[2304];
			for (int i = 0; i < 48; i++)
			{
				for (int j = 0; j < 48; j++)
				{
					bool num = j < 3 || j >= 45;
					bool flag = i < 3 || i >= 45;
					bool flag2 = j < 14 || j >= 34;
					bool flag3 = i < 14 || i >= 34;
					bool flag4 = (num && flag3) || (flag && flag2);
					array[i * 48 + j] = (flag4 ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)0));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			_bracketSprite = Sprite.Create(val, new Rect(0f, 0f, 48f, 48f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(15f, 15f, 15f, 15f));
			return _bracketSprite;
		}

		private static Sprite VignetteSprite()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_vignetteSprite != (Object)null)
			{
				return _vignetteSprite;
			}
			Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[65536];
			for (int i = 0; i < 256; i++)
			{
				for (int j = 0; j < 256; j++)
				{
					float num = ((float)j + 0.5f) / 256f * 2f - 1f;
					float num2 = ((float)i + 0.5f) / 256f * 2f - 1f;
					float num3 = Mathf.Sqrt(num * num * 0.9f + num2 * num2);
					float num4 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.75f, 1.35f, num3)) * 0.92f;
					if (i % 4 == 0)
					{
						num4 = Mathf.Max(num4, 0.07f);
					}
					array[i * 256 + j] = new Color32((byte)0, (byte)12, (byte)2, (byte)(Mathf.Clamp01(num4) * 255f));
				}
			}
			val.SetPixels32(array);
			val.Apply();
			_vignetteSprite = Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f);
			return _vignetteSprite;
		}
	}
	[BepInPlugin("markj.nightvisiongoggles", "NightVisionGoggles", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "markj.nightvisiongoggles";

		public const string Name = "NightVisionGoggles";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static Item GogglesItemDef;

		internal static ConfigEntry<int> Price;

		internal static ConfigEntry<float> BatteryLifeSeconds;

		internal static ConfigEntry<float> WeightLbs;

		internal static ConfigEntry<float> Brightness;

		internal static ConfigEntry<float> LightRange;

		internal static ConfigEntry<float> TintStrength;

		internal static ConfigEntry<bool> Vignette;

		internal static ConfigEntry<bool> RemoveFog;

		internal static ConfigEntry<string> ToggleKey;

		internal static ConfigEntry<string> HeadOffset;

		internal static ConfigEntry<float> MaxDistance;

		internal static ConfigEntry<string> MonsterColor;

		internal static ConfigEntry<float> GlowIntensity;

		internal static ConfigEntry<bool> MonsterLights;

		internal static ConfigEntry<int> MaxMonsterLights;

		internal static ConfigEntry<float> MonsterLightBoost;

		internal static ConfigEntry<bool> Markers;

		internal static ConfigEntry<bool> MarkersThroughWalls;

		internal static ConfigEntry<bool> ShowNames;

		internal static ConfigEntry<bool> HighlightTraps;

		internal static ConfigEntry<string> TrapColor;

		private void Awake()
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Price = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Price", 180, "Store price in credits. Everyone in the lobby should use the same value.");
			BatteryLifeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BatteryLifeSeconds", 300f, "How many seconds a full battery lasts while the goggles are on.");
			WeightLbs = ((BaseUnityPlugin)this).Config.Bind<float>("General", "WeightLbs", 4f, "Item weight in pounds.");
			Brightness = ((BaseUnityPlugin)this).Config.Bind<float>("NightVision", "Intensity", 7500f, "Night vision light strength. The game's normal value is about 367. Try 3000-20000.");
			LightRange = ((BaseUnityPlugin)this).Config.Bind<float>("NightVision", "LightRange", 1000f, "How far (metres) the night vision lights things up.");
			RemoveFog = ((BaseUnityPlugin)this).Config.Bind<bool>("NightVision", "RemoveFog", true, "Clear the fog while the goggles are on, so you can see much further.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("Controls", "ToggleKey", "N", "Key that switches the goggles on/off while they're anywhere in your inventory (Unity key name, e.g. N, V, F, B).");
			HeadOffset = ((BaseUnityPlugin)this).Config.Bind<string>("Visuals", "HeadOffset", "0,0.02,0.06", "x,y,z offset of the goggles on other players' heads (from their eyes). Tweak if they float or sink in.");
			TintStrength = ((BaseUnityPlugin)this).Config.Bind<float>("NightVision", "GreenTint", 0.6f, new ConfigDescription("How green the screen goes. 0 = no tint, 1 = full green.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			Vignette = ((BaseUnityPlugin)this).Config.Bind<bool>("NightVision", "Vignette", true, "Dark goggle-style edges around the screen.");
			MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Monsters", "MaxDistance", 60f, "Monsters further than this (metres) aren't highlighted.");
			MonsterColor = ((BaseUnityPlugin)this).Config.Bind<string>("Monsters", "Color", "1,0.15,0.1", "r,g,b colour monsters glow and are boxed in (0-1 each).");
			GlowIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Monsters", "GlowIntensity", 8f, "How strongly monsters glow. Raise it if they look dim, lower it if they're blinding.");
			MonsterLights = ((BaseUnityPlugin)this).Config.Bind<bool>("Monsters", "SpotlightMonsters", true, "Shine a coloured light on nearby monsters so they stand out from the dark.");
			MaxMonsterLights = ((BaseUnityPlugin)this).Config.Bind<int>("Monsters", "MaxSpotlights", 6, "Only the closest this-many monsters get a spotlight (keeps FPS up).");
			MonsterLightBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Monsters", "SpotlightStrength", 4f, "How bright each monster spotlight is.");
			Markers = ((BaseUnityPlugin)this).Config.Bind<bool>("Monsters", "TargetBoxes", true, "Draw a box around monsters on screen.");
			MarkersThroughWalls = ((BaseUnityPlugin)this).Config.Bind<bool>("Monsters", "BoxesThroughWalls", false, "Show boxes for monsters behind walls too (much easier, kind of cheaty).");
			ShowNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Monsters", "ShowNames", true, "Show the monster's name and distance under its box.");
			HighlightTraps = ((BaseUnityPlugin)this).Config.Bind<bool>("Monsters", "HighlightTraps", true, "Also highlight turrets, landmines and spike traps.");
			TrapColor = ((BaseUnityPlugin)this).Config.Bind<string>("Monsters", "TrapColor", "1,0.8,0.1", "r,g,b colour for traps.");
			GogglesItemDef = GogglesFactory.Create();
			Items.RegisterShopItem(GogglesItemDef, Price.Value);
			new Harmony("markj.nightvisiongoggles").PatchAll(typeof(Patches));
			Log.LogInfo((object)"NightVisionGoggles 1.0.0 loaded.");
		}

		internal static Color ParseColor(string s, Color fallback)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			string[] array = s.Split(',');
			if (array.Length >= 3 && float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return new Color(result, result2, result3, 1f);
			}
			return fallback;
		}

		internal static Vector3 ParseVec(string s, Vector3 fallback)
		{
			//IL_006a: 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)
			string[] array = s.Split(',');
			if (array.Length == 3 && float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return new Vector3(result, result2, result3);
			}
			return fallback;
		}
	}
	[HarmonyPatch]
	internal static class Patches
	{
		private static bool _loggedTickError;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void StartOfRoundAwake(StartOfRound __instance)
		{
			GogglesFactory.ApplyVanillaAssets(__instance);
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PlayerUpdate(PlayerControllerB __instance)
		{
			try
			{
				if (((NetworkBehaviour)__instance).IsOwner)
				{
					NightVisionController.GetOrCreate().Tick("player");
				}
			}
			catch (Exception e)
			{
				NightVisionController.ReportError("player update", e);
			}
		}
	}
}