Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NightVisionGoggles v1.0.0
NightVisionGoggles.dll
Decompiled 5 hours agousing 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); } } } }