Decompiled source of Imperium v0.2.8

giosuel.Imperium.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using GameNetcodeStuff;
using HarmonyLib;
using Imperium.API.Types;
using Imperium.API.Types.Networking;
using Imperium.Core;
using Imperium.Core.EventLogging;
using Imperium.Core.Input;
using Imperium.Core.LevelEditor;
using Imperium.Core.Lifecycle;
using Imperium.Core.Scripts;
using Imperium.Extensions;
using Imperium.Integration;
using Imperium.Interface;
using Imperium.Interface.Common;
using Imperium.Interface.ComponentManager;
using Imperium.Interface.ComponentManager.Widgets;
using Imperium.Interface.ImperiumUI;
using Imperium.Interface.ImperiumUI.Windows.ControlCenter;
using Imperium.Interface.ImperiumUI.Windows.CruiserControl;
using Imperium.Interface.ImperiumUI.Windows.EventLog;
using Imperium.Interface.ImperiumUI.Windows.Info;
using Imperium.Interface.ImperiumUI.Windows.MoonControl;
using Imperium.Interface.ImperiumUI.Windows.MoonControl.Widgets;
using Imperium.Interface.ImperiumUI.Windows.ObjectExplorer;
using Imperium.Interface.ImperiumUI.Windows.ObjectExplorer.ObjectListEntry;
using Imperium.Interface.ImperiumUI.Windows.ObjectSettings;
using Imperium.Interface.ImperiumUI.Windows.Preferences;
using Imperium.Interface.ImperiumUI.Windows.Rendering;
using Imperium.Interface.ImperiumUI.Windows.SaveEditor;
using Imperium.Interface.ImperiumUI.Windows.ShipControl;
using Imperium.Interface.ImperiumUI.Windows.ShipControl.Widgets;
using Imperium.Interface.ImperiumUI.Windows.Teleportation;
using Imperium.Interface.ImperiumUI.Windows.Teleportation.Widgets;
using Imperium.Interface.ImperiumUI.Windows.Visualization;
using Imperium.Interface.ImperiumUI.Windows.Visualization.ObjectVisualizerEntries;
using Imperium.Interface.ImperiumUI.Windows.Visualization.Widgets;
using Imperium.Interface.LayerSelector;
using Imperium.Interface.MapUI;
using Imperium.Interface.OracleUI;
using Imperium.Interface.SpawningUI;
using Imperium.Netcode;
using Imperium.Patches.Objects;
using Imperium.Patches.Systems;
using Imperium.Types;
using Imperium.Util;
using Imperium.Util.Binding;
using Imperium.Visualizers;
using Imperium.Visualizers.Objects;
using Imperium.Visualizers.Objects.NoiseOverlay;
using JetBrains.Annotations;
using LethalCompanyInputUtils.Api;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UniverseLib.UI;
using WeatherRegistry;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("giosuel.Imperium")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("All-in-one debugging mod for Lethal Company.")]
[assembly: AssemblyFileVersion("0.2.8.0")]
[assembly: AssemblyInformationalVersion("0.2.8-dev.2+2771a9170a8543a3b8bbad5f808ef61d010d1596")]
[assembly: AssemblyProduct("giosuel.Imperium")]
[assembly: AssemblyTitle("giosuel.Imperium")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/giosuel/imperium")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Imperium
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("giosuel.Imperium", "Imperium", "0.2.8")]
	public class Imperium : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "giosuel.Imperium";

		public const string PLUGIN_NAME = "Imperium";

		public const string PLUGIN_VERSION = "0.2.8";

		private static ConfigFile configFile;

		private static Harmony Harmony;

		internal static Terminal Terminal { get; private set; }

		internal static HUDManager HUDManager { get; private set; }

		internal static PlayerControllerB Player { get; set; }

		internal static TimeOfDay TimeOfDay => TimeOfDay.Instance;

		internal static IngamePlayerSettings IngamePlayerSettings => IngamePlayerSettings.Instance;

		internal static StartOfRound StartOfRound => StartOfRound.Instance;

		internal static RoundManager RoundManager => RoundManager.Instance;

		internal static ShipBuildModeManager ShipBuildModeManager => ShipBuildModeManager.Instance;

		internal static ImpSettings Settings { get; private set; }

		internal static ImpOutput IO { get; private set; }

		internal static ImpNetworking Networking { get; set; }

		internal static GameManager GameManager { get; private set; }

		internal static ObjectManager ObjectManager { get; private set; }

		internal static PlayerManager PlayerManager { get; private set; }

		internal static MoonManager MoonManager { get; private set; }

		internal static ShipManager ShipManager { get; private set; }

		internal static CruiserManager CruiserManager { get; private set; }

		internal static Visualization Visualization { get; private set; }

		internal static Oracle Oracle { get; private set; }

		internal static ImpEventLog EventLog { get; private set; }

		internal static ImpMap Map { get; private set; }

		internal static ImpFreecam Freecam { get; private set; }

		internal static ImpNightVision NightVision { get; private set; }

		internal static ImpNoiseListener NoiseListener { get; private set; }

		internal static ImpTapeMeasure ImpTapeMeasure { get; private set; }

		internal static ImpLevelEditor ImpLevelEditor { get; }

		internal static ImpInputBindings InputBindings { get; private set; }

		internal static ImpPositionIndicator ImpPositionIndicator { get; private set; }

		internal static ImpInterfaceManager Interface { get; private set; }

		internal static bool IsImperiumLoaded { get; private set; }

		internal static bool IsImperiumLaunched { get; private set; }

		internal static bool WasImperiumAccessGranted { get; private set; }

		internal static bool IsImperiumEnabled { get; private set; }

		internal static ImpBinaryBinding IsSceneLoaded { get; private set; }

		private void Awake()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			configFile = ((BaseUnityPlugin)this).Config;
			Settings = new ImpSettings(((BaseUnityPlugin)this).Config);
			IO = new ImpOutput(((BaseUnityPlugin)this).Logger);
			InputBindings = new ImpInputBindings();
			((LcInputActions)InputBindings.BaseMap).Disable();
			InputBindings.StaticMap.Disable();
			((LcInputActions)InputBindings.FreecamMap).Disable();
			((LcInputActions)InputBindings.InterfaceMap).Disable();
			if (ImpAssets.Load())
			{
				Harmony = new Harmony("giosuel.Imperium");
				PreLaunchPatch();
				IO.LogInfo("[OK] Imperium is ready!");
				IsImperiumLoaded = true;
			}
		}

		internal static void DisableImperium()
		{
			IsImperiumEnabled = false;
			Interface.Destroy();
			PlayerManager.IsFlying.SetFalse();
			Freecam.IsFreecamEnabled.SetFalse();
			((LcInputActions)InputBindings.BaseMap).Disable();
			InputBindings.StaticMap.Disable();
			((LcInputActions)InputBindings.FreecamMap).Disable();
			((LcInputActions)InputBindings.InterfaceMap).Disable();
		}

		internal static void EnableImperium()
		{
			if (IsImperiumLaunched)
			{
				((LcInputActions)InputBindings.BaseMap).Enable();
				InputBindings.StaticMap.Enable();
				((LcInputActions)InputBindings.FreecamMap).Enable();
				((LcInputActions)InputBindings.InterfaceMap).Enable();
				Interface = ImpInterfaceManager.Create(Settings.Preferences.Theme);
				StartUI();
				Settings.LoadAll();
				IsImperiumEnabled = true;
			}
		}

		internal static void Launch()
		{
			if (!IsImperiumLoaded)
			{
				IO.Send("Imperium failed to launch ⊙︿⊙");
				return;
			}
			Settings = new ImpSettings(configFile);
			Networking.BindAllowClients(Settings.Preferences.AllowClients);
			Terminal = GameObject.Find("TerminalScript").GetComponent<Terminal>();
			HUDManager = Object.FindObjectOfType<HUDManager>();
			IsSceneLoaded = new ImpBinaryBinding(currentValue: false);
			Interface = ImpInterfaceManager.Create(Settings.Preferences.Theme);
			EventLog = new ImpEventLog();
			Oracle = ImpLifecycleObject.Create<Oracle>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			GameManager = ImpLifecycleObject.Create<GameManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			MoonManager = ImpLifecycleObject.Create<MoonManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			ShipManager = ImpLifecycleObject.Create<ShipManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			CruiserManager = ImpLifecycleObject.Create<CruiserManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			ObjectManager = ImpLifecycleObject.Create<ObjectManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			PlayerManager = ImpLifecycleObject.Create<PlayerManager>(IsSceneLoaded, ImpNetworking.ConnectedPlayers);
			Visualization = new Visualization(Oracle.State, ObjectManager, configFile);
			Map = ImpMap.Create();
			Freecam = ImpFreecam.Create();
			NightVision = ImpNightVision.Create();
			ImpTapeMeasure = ImpTapeMeasure.Create();
			NoiseListener = ImpNoiseListener.Create();
			ImpPositionIndicator = ImpPositionIndicator.Create();
			MoonManager.IndoorSpawningPaused.onTrigger += Oracle.Simulate;
			MoonManager.OutdoorSpawningPaused.onTrigger += Oracle.Simulate;
			MoonManager.DaytimeSpawningPaused.onTrigger += Oracle.Simulate;
			MoonManager.IndoorDeviation.onTrigger += Oracle.Simulate;
			MoonManager.DaytimeDeviation.onTrigger += Oracle.Simulate;
			MoonManager.MaxIndoorPower.onTrigger += Oracle.Simulate;
			MoonManager.MaxOutdoorPower.onTrigger += Oracle.Simulate;
			MoonManager.MaxDaytimePower.onTrigger += Oracle.Simulate;
			MoonManager.MinIndoorSpawns.onTrigger += Oracle.Simulate;
			MoonManager.MinOutdoorSpawns.onTrigger += Oracle.Simulate;
			Harmony.PatchAll();
			UnityExplorerIntegration.PatchFunctions(Harmony);
			if (Settings.Preferences.EnableImperium.Value)
			{
				InputBindings.BaseMap.ToggleHUD.performed += ToggleHUD;
				((LcInputActions)InputBindings.BaseMap).Enable();
				InputBindings.StaticMap.Enable();
				((LcInputActions)InputBindings.FreecamMap).Enable();
				((LcInputActions)InputBindings.InterfaceMap).Enable();
				IsImperiumEnabled = true;
				Settings.LoadAll();
				StartUI();
				IsSceneLoaded.SetFalse();
				PlayerManager.UpdateCameras();
			}
			else
			{
				((LcInputActions)InputBindings.BaseMap).Disable();
				InputBindings.StaticMap.Disable();
				((LcInputActions)InputBindings.FreecamMap).Disable();
				((LcInputActions)InputBindings.InterfaceMap).Disable();
			}
			WasImperiumAccessGranted = true;
			IsImperiumLaunched = true;
		}

		private static void ToggleHUD(CallbackContext callbackContext)
		{
			if (!Player.quickMenuManager.isMenuOpen && !Player.inTerminalMenu && !Player.isTypingChat && !ShipBuildModeManager.InBuildMode)
			{
				HUDManager.HideHUD(!Reflection.Get<HUDManager, bool>(HUDManager, "hudHidden"));
			}
		}

		internal static void Unload()
		{
			if (IsImperiumLaunched)
			{
				PreInitPatches.ReturnedFromGame = true;
				Harmony.UnpatchSelf();
				DisableImperium();
				Networking.Unsubscribe();
				WasImperiumAccessGranted = false;
				IsImperiumLaunched = false;
				PreLaunchPatch();
			}
		}

		internal static void Reload()
		{
			Unload();
			Launch();
		}

		private static void StartUI()
		{
			Interface.OpenInterface.onUpdate += delegate(BaseUI openInterface)
			{
				if (Object.op_Implicit((Object)(object)openInterface))
				{
					ImpPositionIndicator.Deactivate();
				}
			};
			Interface.RegisterInterface<ImperiumUI>(ImpAssets.ImperiumUIObject, "ImperiumUI", "Imperium UI", "Imperium's main interface.", InputBindings.InterfaceMap.ImperiumUI, Array.Empty<IBinding<bool>>());
			Interface.RegisterInterface<SpawningUI>(ImpAssets.SpawningUIObject, "SpawningUI", "Spawning", "Allows you to spawn objects\nsuch as Scrap or Entities.", InputBindings.InterfaceMap.SpawningUI, Array.Empty<IBinding<bool>>());
			Interface.RegisterInterface<MapUI>(ImpAssets.MapUIObject, "MapUI", "Map", "Imperium's built-in map.", InputBindings.InterfaceMap.MapUI, Array.Empty<IBinding<bool>>());
			Interface.RegisterInterface<OracleUI>(ImpAssets.OracleUIObject, "OracleUI", "Oracle", "Entity spawning predictions.", InputBindings.InterfaceMap.OracleUI, new IBinding<bool>[1] { IsSceneLoaded });
			Interface.RegisterInterface<MinimapSettings>(ImpAssets.MinimapSettingsObject);
			Interface.RefreshTheme();
			IO.LogInfo("[OK] Imperium UIs have been registered! \\o/");
		}

		private static void PreLaunchPatch()
		{
			Harmony.PatchAll(typeof(PlayerControllerPatch.PreloadPatches));
			Harmony.PatchAll(typeof(TerminalPatch.PreloadPatches));
			Harmony.PatchAll(typeof(PreInitPatches.PreInitSceneScriptPatch));
			Harmony.PatchAll(typeof(PreInitPatches.MenuManagerPatch));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "giosuel.Imperium";

		public const string PLUGIN_NAME = "giosuel.Imperium";

		public const string PLUGIN_VERSION = "0.2.8";
	}
}
namespace Imperium.Visualizers
{
	internal class EntityGizmos : BaseVisualizer<IReadOnlyCollection<EnemyAI>, EntityGizmo>
	{
		internal readonly Dictionary<EnemyType, EntityGizmoConfig> EntityInfoConfigs = new Dictionary<EnemyType, EntityGizmoConfig>();

		private readonly ConfigFile config;

		internal EntityGizmos(IBinding<IReadOnlyCollection<EnemyAI>> objectsBinding, ConfigFile config)
			: base(objectsBinding, (IBinding<bool>)null)
		{
			this.config = config;
			EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>();
			foreach (EnemyType val in array)
			{
				EntityInfoConfigs[val] = new EntityGizmoConfig(val.enemyName, config);
			}
		}

		protected override void OnRefresh(IReadOnlyCollection<EnemyAI> objects)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			foreach (EnemyAI item in objects.Where((EnemyAI entity) => Object.op_Implicit((Object)(object)entity)))
			{
				if (!visualizerObjects.ContainsKey(((Object)item).GetInstanceID()))
				{
					if (!EntityInfoConfigs.TryGetValue(item.enemyType, out var value))
					{
						value = new EntityGizmoConfig(item.enemyType.enemyName, config);
						EntityInfoConfigs[item.enemyType] = value;
					}
					EntityGizmo entityGizmo = new GameObject($"Imp_EntityGizmo_{((Object)item).GetInstanceID()}").AddComponent<EntityGizmo>();
					entityGizmo.Init(value, Imperium.Visualization, item);
					visualizerObjects[((Object)item).GetInstanceID()] = entityGizmo;
				}
			}
		}

		internal void NoiseVisualizerUpdate(EnemyAI instance, Vector3 origin)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (visualizerObjects.TryGetValue(((Object)instance).GetInstanceID(), out var value))
			{
				value.NoiseVisualizerUpdate(origin);
			}
		}

		internal void ConeVisualizerUpdate(EnemyAI instance, Transform eye, float angle, float length, Material material, GizmoType gizmoType = GizmoType.LineOfSight, GizmoDuration gizmoDuration = GizmoDuration.AIInterval, int id = -1, Func<Vector3> relativePositionOverride = null, Func<Transform, Vector3> absolutePositionOverride = null)
		{
			if (visualizerObjects.TryGetValue(((Object)instance).GetInstanceID(), out var value))
			{
				value.ConeVisualizerUpdate(eye ?? ((Component)instance).transform, angle, length, material, (EntityGizmoConfig visConfig) => (gizmoType != 0) ? visConfig.Custom : visConfig.LineOfSight, gizmoDuration, id, relativePositionOverride, absolutePositionOverride);
			}
		}

		internal void SphereVisualizerUpdate(EnemyAI instance, Transform eye, float radius, Material material, GizmoType gizmoType = GizmoType.LineOfSight, GizmoDuration gizmoDuration = GizmoDuration.AIInterval, int id = -1, Func<Vector3> relativePositionOverride = null, Func<Transform, Vector3> absolutePositionOverride = null)
		{
			if (visualizerObjects.TryGetValue(((Object)instance).GetInstanceID(), out var value))
			{
				value.SphereVisualizerUpdate(eye ?? ((Component)instance).transform, radius, material, (EntityGizmoConfig visConfig) => (gizmoType != 0) ? visConfig.Custom : visConfig.LineOfSight, gizmoDuration, id, relativePositionOverride, absolutePositionOverride);
			}
		}

		internal void StaticSphereVisualizerUpdate(EnemyAI instance, Vector3 position, Material material, float radius = 2f, GizmoType gizmoType = GizmoType.LineOfSight, GizmoDuration gizmoDuration = GizmoDuration.Indefinite, int id = -1)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (visualizerObjects.TryGetValue(((Object)instance).GetInstanceID(), out var value))
			{
				value.StaticSphereVisualizerUpdate(((Component)instance).gameObject, position, radius, material, (EntityGizmoConfig visConfig) => (gizmoType != 0) ? visConfig.Custom : visConfig.LineOfSight, gizmoDuration, id);
			}
		}
	}
	internal class KnifeGizmos : BaseVisualizer<Shovel, KnifeGizmo>
	{
		public KnifeGizmos(ImpBinding<bool> visibilityBinding)
			: base((IBinding<Shovel>)null, (IBinding<bool>)visibilityBinding)
		{
		}

		internal void Refresh(KnifeItem knife, bool isActivelyHolding)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!visualizerObjects.TryGetValue(((Object)knife).GetInstanceID(), out var value))
			{
				GameObject val = new GameObject($"Imp_KnifeGizmo_{((Object)knife).GetInstanceID()}");
				val.transform.SetParent(((Component)knife).transform);
				value = val.AddComponent<KnifeGizmo>();
				visualizerObjects[((Object)knife).GetInstanceID()] = value;
			}
			value.Init(knife, isActivelyHolding);
			((Component)value).gameObject.SetActive(Imperium.Settings.Visualization.KnifeIndicators.Value);
		}
	}
	internal class LandmineGizmos : BaseVisualizer<IReadOnlyCollection<Landmine>, LandmineGizmo>
	{
		public LandmineGizmos(IBinding<IReadOnlyCollection<Landmine>> objectsBinding, IBinding<bool> visibilityBinding)
			: base(objectsBinding, visibilityBinding)
		{
		}

		protected override void OnRefresh(IReadOnlyCollection<Landmine> objects)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			foreach (Landmine item in objects.Where((Landmine obj) => Object.op_Implicit((Object)(object)obj)))
			{
				if (!visualizerObjects.ContainsKey(((Object)item).GetInstanceID()))
				{
					GameObject val = new GameObject();
					val.transform.SetParent(((Component)item).transform);
					LandmineGizmo landmineGizmo = val.AddComponent<LandmineGizmo>();
					landmineGizmo.Init(item);
					visualizerObjects[((Object)item).GetInstanceID()] = landmineGizmo;
				}
			}
		}

		internal void SnapshotPlayerHitbox(int landmineId)
		{
			if (visualizerObjects.TryGetValue(landmineId, out var value))
			{
				((Component)value).GetComponent<LandmineGizmo>().SnapshotHitboxes();
			}
		}
	}
	internal class MapHazardIndicators : BaseVisualizer<HashSet<HazardIndicator>, Transform>
	{
		public MapHazardIndicators(ImpBinding<HashSet<HazardIndicator>> objectsBinding, ImpBinding<bool> visibilityBinding)
			: base((IBinding<HashSet<HazardIndicator>>)objectsBinding, (IBinding<bool>)visibilityBinding)
		{
		}

		protected override void OnRefresh(HashSet<HazardIndicator> objects)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			foreach (HazardIndicator @object in objects)
			{
				if (!visualizerObjects.ContainsKey(@object.GetHashCode()))
				{
					visualizerObjects[@object.GetHashCode()] = Visualization.VisualizePoint(null, @object.spawnRange, ImpAssets.WireframeRed, "Imp_HazardSpawnIndicator").transform;
					visualizerObjects[@object.GetHashCode()].position = @object.position;
				}
			}
		}
	}
	internal class HazardIndicator
	{
		internal Vector3 position;

		internal readonly float spawnRange;

		public HazardIndicator(Vector3 position, float spawnRange)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			this.position = position;
			this.spawnRange = spawnRange;
			base..ctor();
		}
	}
	internal class NavMeshVisualizer : BaseVisualizer<bool, Component>
	{
		public NavMeshVisualizer(ImpBinding<bool> isLoadedBinding, ImpBinding<bool> visibilityBinding)
			: base((IBinding<bool>)isLoadedBinding, (IBinding<bool>)visibilityBinding)
		{
		}

		protected override void OnRefresh(bool isSceneLoaded)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			ClearObjects();
			int num = 0;
			foreach (Mesh navmeshSurface in Visualization.GetNavmeshSurfaces())
			{
				GameObject val = new GameObject($"ImpVis_NavMeshSurface_{num}");
				MeshRenderer val2 = val.AddComponent<MeshRenderer>();
				((Renderer)val2).material = ImpAssets.TriggerMaterial;
				val.AddComponent<MeshFilter>().mesh = navmeshSurface;
				visualizerObjects[((Object)val).GetInstanceID()] = (Component)(object)val2;
				num++;
			}
		}
	}
	internal class ObjectInsights : BaseVisualizer<HashSet<Component>, ObjectInsight>
	{
		private readonly ConfigFile config;

		internal readonly ImpBinding<Dictionary<Type, ImpBinding<bool>>> InsightVisibilityBindings = new ImpBinding<Dictionary<Type, ImpBinding<bool>>>(new Dictionary<Type, ImpBinding<bool>>());

		internal readonly ImpConfig<bool> CustomInsights;

		private readonly ImpBinding<Dictionary<Type, InsightDefinition<Component>>> registeredInsights = new ImpBinding<Dictionary<Type, InsightDefinition<Component>>>(new Dictionary<Type, InsightDefinition<Component>>());

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

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

		internal ObjectInsights(ConfigFile config)
			: base((IBinding<HashSet<Component>>)null, (IBinding<bool>)null)
		{
			this.config = config;
			CustomInsights = new ImpConfig<bool>(config, "Visualization.Insights", "Custom", defaultValue: false);
			RegisterDefaultInsights();
			Refresh();
			foreach (KeyValuePair<Type, ImpBinding<bool>> item in InsightVisibilityBindings.Value)
			{
				item.Deconstruct(out var _, out var value);
				value.onTrigger += Refresh;
			}
			registeredInsights.onTrigger += Refresh;
		}

		internal void Refresh()
		{
			((MonoBehaviour)Imperium.ObjectManager).StartCoroutine(refresh());
		}

		private IEnumerator refresh()
		{
			yield return 0;
			Stopwatch stopwatch = Stopwatch.StartNew();
			if (InsightVisibilityBindings.Value.All((KeyValuePair<Type, ImpBinding<bool>> binding) => !binding.Value.Value))
			{
				yield break;
			}
			GameObject[] array = Object.FindObjectsOfType<GameObject>();
			foreach (GameObject val in array)
			{
				if (insightVisualizerObjects.Contains(((Object)val).GetInstanceID()))
				{
					continue;
				}
				foreach (Component item in from component in val.GetComponents<Component>()
					where Object.op_Implicit((Object)(object)component)
					select component)
				{
					InsightDefinition<Component> insightDefinition = FindMostMatchingInsightDefinition(((object)item).GetType());
					if (insightDefinition != null)
					{
						if (!visualizerObjects.TryGetValue(((Object)item).GetInstanceID(), out var value))
						{
							GameObject val2 = new GameObject($"Imp_ObjectInsight_{((Object)val).GetInstanceID()}");
							val2.transform.SetParent(val.transform, true);
							insightVisualizerObjects.Add(((Object)val2).GetInstanceID());
							value = val2.AddComponent<ObjectInsight>();
							value.Init(item, insightDefinition);
							visualizerObjects[((Object)item).GetInstanceID()] = value;
						}
						else if (insightDefinition != value.InsightDefinition)
						{
							value.UpdateInsightDefinition(insightDefinition);
						}
					}
				}
			}
			stopwatch.Stop();
			Imperium.IO.LogInfo($" - SPENT IN INSIGHTS: {stopwatch.ElapsedMilliseconds}");
		}

		private InsightDefinition<Component> FindMostMatchingInsightDefinition(Type inputType)
		{
			foreach (Type parentType in Debugging.GetParentTypes(inputType))
			{
				if (registeredInsights.Value.TryGetValue(parentType, out var value))
				{
					return value;
				}
			}
			return null;
		}

		internal InsightDefinition<T> InsightsFor<T>() where T : Component
		{
			if (registeredInsights.Value.TryGetValue(typeof(T), out var value))
			{
				return value as InsightDefinition<T>;
			}
			InsightDefinitionImpl<T> insightDefinitionImpl = new InsightDefinitionImpl<T>(registeredInsights.Value, InsightVisibilityBindings, config);
			registeredInsights.Value[typeof(T)] = (InsightDefinition<Component>)insightDefinitionImpl;
			registeredInsights.Refresh();
			return insightDefinitionImpl;
		}

		private void RegisterDefaultInsights()
		{
			this.InsightsFor<PlayerControllerB>().SetNameGenerator((PlayerControllerB player) => player.playerUsername ?? ((Object)player).GetInstanceID().ToString()).SetIsDeadGenerator((PlayerControllerB player) => player.isPlayerDead)
				.RegisterInsight("Health", (PlayerControllerB player) => $"{player.health} HP")
				.RegisterInsight("Stamina", (PlayerControllerB player) => $"{player.sprintTime:0.0}s")
				.RegisterInsight("Visibility", (PlayerControllerB player) => $"{((IVisibleThreat)player).GetVisibility():0.0}")
				.RegisterInsight("Interest Level", (PlayerControllerB player) => $"{((IVisibleThreat)player).GetInterestLevel():0.0}")
				.RegisterInsight("Insanity", (PlayerControllerB player) => $"{player.insanityLevel:0.0}")
				.RegisterInsight("Fear Level", (PlayerControllerB player) => $"{Imperium.StartOfRound.fearLevel:0.0}")
				.RegisterInsight("Location", ImpUtils.GetPlayerLocationText)
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Players");
			this.InsightsFor<GrabbableObject>().SetNameGenerator((GrabbableObject item) => item.itemProperties.itemName).RegisterInsight("Value", (GrabbableObject item) => $"{item.scrapValue}$")
				.RegisterInsight("Used Up", (GrabbableObject item) => (!item.itemUsedUp) ? "No" : "Yes")
				.RegisterInsight("Held By", ImpUtils.GetItemHeldByText)
				.RegisterInsight("Cooldown", (GrabbableObject item) => $"{item.currentUseCooldown:0.0}s")
				.RegisterInsight("Location", ImpUtils.GetItemLocationText)
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Items");
			this.InsightsFor<EnemyAI>().SetNameGenerator((EnemyAI entity) => entity.enemyType.enemyName).SetPersonalNameGenerator(Imperium.ObjectManager.GetEntityName)
				.SetIsDeadGenerator((EnemyAI entity) => entity.isEnemyDead)
				.RegisterInsight("Health", (EnemyAI entity) => $"{entity.enemyHP} HP")
				.RegisterInsight("Behaviour State", (EnemyAI entity) => entity.currentBehaviourStateIndex.ToString())
				.RegisterInsight("Movement Speed", (EnemyAI entity) => (!Object.op_Implicit((Object)(object)entity.agent)) ? "0" : $"{entity.agent.speed:0.0}")
				.RegisterInsight("Stun Timer", (EnemyAI entity) => $"{Math.Max(0f, entity.stunNormalizedTimer):0.0}s")
				.RegisterInsight("Target", (EnemyAI entity) => (!Object.op_Implicit((Object)(object)entity.targetPlayer)) ? "-" : entity.targetPlayer.playerUsername)
				.RegisterInsight("Location", ImpUtils.GetEntityLocationText)
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Entities");
			this.InsightsFor<ClaySurgeonAI>().RegisterInsight("Is Master", (ClaySurgeonAI barber) => (!barber.isMaster) ? "No" : "Yes").RegisterInsight("Beat Timer", (ClaySurgeonAI barber) => $"{barber.beatTimer:0.0}s")
				.RegisterInsight("Jump Timer", (ClaySurgeonAI barber) => $"{barber.jumpTimer:0.0}s")
				.RegisterInsight("Current Interval", (ClaySurgeonAI barber) => $"{barber.currentInterval:0.0}s");
			this.InsightsFor<FlowermanAI>().RegisterInsight("Anger Meter", (FlowermanAI flowerman) => $"{flowerman.angerMeter:0.0}").RegisterInsight("Anger Check Timer", (FlowermanAI flowerman) => $"{flowerman.angerCheckInterval:0.0}s")
				.RegisterInsight("Times Threatened", (FlowermanAI flowerman) => $"{flowerman.timesThreatened}x")
				.RegisterInsight("Times Found", (FlowermanAI flowerman) => $"{flowerman.timesFoundSneaking}x");
			this.InsightsFor<SandSpiderAI>().RegisterInsight("On Wall", (SandSpiderAI spider) => (!spider.onWall) ? "No" : "Yes").RegisterInsight("Web Count", (SandSpiderAI spider) => $"({spider.webTraps.Count}/{spider.maxWebTrapsToPlace})")
				.RegisterInsight("Chase Timer", (SandSpiderAI spider) => $"{spider.chaseTimer:0.0}s")
				.RegisterInsight("Wall Timer", (SandSpiderAI spider) => $"{spider.waitOnWallTimer:0.0}s");
			this.InsightsFor<JesterAI>().RegisterInsight("Idle Timer", (JesterAI jester) => $"{jester.beginCrankingTimer:0.0}s").RegisterInsight("Crank Timer", (JesterAI jester) => $"{jester.popUpTimer:0.0}s")
				.RegisterInsight("No Targets Timer", (JesterAI jester) => $"{jester.noPlayersToChaseTimer:0.0}s");
			this.InsightsFor<NutcrackerEnemyAI>().SetPositionOverride((NutcrackerEnemyAI entity) => DefaultPositionOverride((Component)(object)entity) + Vector3.down * 7f);
			this.InsightsFor<CaveDwellerAI>().RegisterInsight("Search Width", (CaveDwellerAI maneater) => $"{maneater.currentSearchWidth:0.#}u");
			this.InsightsFor<MaskedPlayerEnemy>().RegisterInsight("Ship Interest", (MaskedPlayerEnemy masked) => $"{masked.interestInShipCooldown:0.0}").RegisterInsight("Stop and Stare", (MaskedPlayerEnemy masked) => $"{masked.stopAndStareTimer:0.0}s")
				.RegisterInsight("Stamina", (MaskedPlayerEnemy masked) => $"{masked.staminaTimer:0.0}")
				.RegisterInsight("Random Tick Timer", (MaskedPlayerEnemy masked) => $"{masked.randomLookTimer:0.0}");
			this.InsightsFor<Turret>().SetNameGenerator((Turret turret) => $"Turret #{((Object)turret).GetInstanceID()}").SetIsDeadGenerator((Turret turret) => !turret.turretActive)
				.RegisterInsight("Is Active", (Turret turret) => (!turret.turretActive) ? "No" : "Yes")
				.RegisterInsight("Turret Mode", (Turret turret) => ((object)(TurretMode)(ref turret.turretMode)).ToString())
				.RegisterInsight("Rotation Speed", (Turret turret) => turret.rotationSpeed.ToString(CultureInfo.InvariantCulture))
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Turrets");
			this.InsightsFor<Landmine>().SetNameGenerator((Landmine landmine) => $"Landmine #{((Object)landmine).GetInstanceID()}").SetIsDeadGenerator((Landmine landmine) => landmine.hasExploded)
				.RegisterInsight("Has Exploded", (Landmine landmine) => (!landmine.hasExploded) ? "No" : "Yes")
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Landmines");
			this.InsightsFor<SteamValveHazard>().SetNameGenerator((SteamValveHazard steamValve) => $"Steam Valve #{((Object)steamValve).GetInstanceID()}").RegisterInsight("Cracked", (SteamValveHazard steamValve) => (!steamValve.valveHasCracked) ? "No" : "Yes")
				.RegisterInsight("Burst", (SteamValveHazard steamValve) => (!steamValve.valveHasBurst) ? "No" : "Yes")
				.RegisterInsight("Repaired", (SteamValveHazard steamValve) => (!steamValve.valveHasBeenRepaired) ? "No" : "Yes")
				.RegisterInsight("Crack Timer", (SteamValveHazard steamValve) => $"{steamValve.valveCrackTime:0.0}s")
				.RegisterInsight("Burst Timer", (SteamValveHazard steamValve) => $"{steamValve.valveCrackTime:0.0}s")
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("SteamValves");
			this.InsightsFor<VehicleController>().SetNameGenerator((VehicleController _) => "Company Cruiser").SetIsDeadGenerator((VehicleController cruiser) => cruiser.carDestroyed)
				.RegisterInsight("Cruiser HP", (VehicleController cruiser) => $"{cruiser.carHP} HP")
				.RegisterInsight("Ignition Started", (VehicleController cruiser) => (!cruiser.ignitionStarted) ? "No" : "Yes")
				.RegisterInsight("Movement", (VehicleController cruiser) => Formatting.FormatVector(Vector2.op_Implicit(cruiser.moveInputVector), 1))
				.RegisterInsight("Steering", (VehicleController cruiser) => $"{cruiser.steeringInput:0.0}")
				.RegisterInsight("Turbulence", (VehicleController cruiser) => $"{cruiser.turbulenceAmount:0.0}")
				.RegisterInsight("Stress", (VehicleController cruiser) => $"{cruiser.carStress:0.0}")
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("CompanyCruiser");
			this.InsightsFor<BridgeTrigger>().SetNameGenerator((BridgeTrigger bridge) => $"Bridge #{((Object)bridge).GetInstanceID()}").SetIsDeadGenerator((BridgeTrigger bridge) => bridge.hasBridgeFallen)
				.RegisterInsight("Durability", (BridgeTrigger trigger) => $"{trigger.bridgeDurability}")
				.RegisterInsight("Has Fallen", (BridgeTrigger bridge) => (!Reflection.Get<BridgeTrigger, bool>(bridge, "hasBridgeFallen")) ? "No" : "Yes")
				.RegisterInsight("Giant On Bridge", (BridgeTrigger bridge) => (!Reflection.Get<BridgeTrigger, bool>(bridge, "giantOnBridge")) ? "No" : "Yes")
				.SetPositionOverride(DefaultPositionOverride)
				.SetConfigKey("Bridges");
		}

		private Vector3 DefaultPositionOverride(Component obj)
		{
			//IL_0078: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (!entityColliderCache.TryGetValue(((Object)obj).GetInstanceID(), out var value))
			{
				BoxCollider componentInChildren = obj.GetComponentInChildren<BoxCollider>();
				Vector3? obj2;
				if (componentInChildren == null)
				{
					CapsuleCollider componentInChildren2 = obj.GetComponentInChildren<CapsuleCollider>();
					obj2 = ((componentInChildren2 != null) ? new Vector3?(componentInChildren2.center) : null);
				}
				else
				{
					obj2 = componentInChildren.center;
				}
				value = obj2;
				entityColliderCache[((Object)obj).GetInstanceID()] = value;
			}
			if (!value.HasValue)
			{
				return obj.transform.position;
			}
			return obj.transform.position + Vector3.up * value.Value.y * obj.transform.localScale.y * 1.5f;
		}
	}
	internal class PlayerGizmos : BaseVisualizer<IReadOnlyCollection<PlayerControllerB>, PlayerGizmo>
	{
		internal readonly Dictionary<PlayerControllerB, PlayerGizmoConfig> PlayerInfoConfigs = new Dictionary<PlayerControllerB, PlayerGizmoConfig>();

		internal PlayerGizmos(IBinding<IReadOnlyCollection<PlayerControllerB>> objectsBinding, ConfigFile config)
			: base(objectsBinding, (IBinding<bool>)null)
		{
			PlayerControllerB[] allPlayerScripts = Imperium.StartOfRound.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				PlayerInfoConfigs[val] = new PlayerGizmoConfig(val.playerUsername, config);
			}
		}

		protected override void OnRefresh(IReadOnlyCollection<PlayerControllerB> objects)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			foreach (PlayerControllerB @object in objects)
			{
				if (!visualizerObjects.ContainsKey(((Object)@object).GetInstanceID()))
				{
					PlayerGizmo playerGizmo = new GameObject($"Imp_PlayerInfo_{((Object)@object).GetInstanceID()}").AddComponent<PlayerGizmo>();
					if (!PlayerInfoConfigs.TryGetValue(@object, out var value))
					{
						Imperium.IO.LogInfo("[ERR] Player was not found, no config loaded for insight.");
						continue;
					}
					playerGizmo.Init(value, ((Component)@object).GetComponent<PlayerControllerB>());
					visualizerObjects[((Object)@object).GetInstanceID()] = playerGizmo;
				}
			}
		}

		internal void PlayerNoiseUpdate(PlayerControllerB player, float range)
		{
			visualizerObjects[((Object)player).GetInstanceID()].NoiseUpdate(range);
		}
	}
	internal class ScrapSpawnIndicators : BaseVisualizer<IReadOnlyCollection<RandomScrapSpawn>, Transform>
	{
		public ScrapSpawnIndicators(ImpBinding<IReadOnlyCollection<RandomScrapSpawn>> objectsBinding, ImpBinding<bool> visibilityBinding)
			: base((IBinding<IReadOnlyCollection<RandomScrapSpawn>>)objectsBinding, (IBinding<bool>)visibilityBinding)
		{
		}

		protected override void OnRefresh(IReadOnlyCollection<RandomScrapSpawn> objects)
		{
			ClearObjects();
			foreach (RandomScrapSpawn item in objects.Where((RandomScrapSpawn obj) => Object.op_Implicit((Object)(object)obj)))
			{
				if (!visualizerObjects.ContainsKey(((Object)item).GetInstanceID()))
				{
					float size = (item.spawnedItemsCopyPosition ? 1f : item.itemSpawnRange);
					Material material = (item.spawnedItemsCopyPosition ? ImpAssets.WireframeCyan : ImpAssets.WireframeAmaranth);
					visualizerObjects[((Object)item).GetInstanceID()] = Visualization.VisualizePoint(((Component)item).gameObject, size, material, $"Imp_ScrapSpawnIndicator_{((Object)item).GetInstanceID()}").transform;
				}
			}
		}
	}
	internal class ShotgunGizmos : BaseVisualizer<ShotgunItem, ShotgunGizmo>
	{
		public ShotgunGizmos(ImpBinding<bool> visibilityBinding)
			: base((IBinding<ShotgunItem>)null, (IBinding<bool>)visibilityBinding)
		{
		}

		internal void Refresh(ShotgunItem shotgun, bool isActivelyHolding)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!visualizerObjects.TryGetValue(((Object)shotgun).GetInstanceID(), out var value))
			{
				GameObject val = new GameObject($"Imp_ShotgunGizmo_{((Object)shotgun).GetInstanceID()}");
				val.transform.SetParent(((Component)shotgun).transform);
				value = val.AddComponent<ShotgunGizmo>();
				visualizerObjects[((Object)shotgun).GetInstanceID()] = value;
			}
			value.Init(shotgun, isActivelyHolding);
			((Component)value).gameObject.SetActive(Imperium.Settings.Visualization.ShotgunIndicators.Value);
		}
	}
	internal class ShovelGizmos : BaseVisualizer<Shovel, ShovelGizmo>
	{
		public ShovelGizmos(ImpBinding<bool> visibilityBinding)
			: base((IBinding<Shovel>)null, (IBinding<bool>)visibilityBinding)
		{
		}

		internal void Refresh(Shovel shovel, bool isActivelyHolding)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!visualizerObjects.TryGetValue(((Object)shovel).GetInstanceID(), out var value))
			{
				GameObject val = new GameObject($"Imp_ShovelGizmo_{((Object)shovel).GetInstanceID()}");
				val.transform.SetParent(((Component)shovel).transform);
				value = val.AddComponent<ShovelGizmo>();
				visualizerObjects[((Object)shovel).GetInstanceID()] = value;
			}
			value.Init(shovel, isActivelyHolding);
			((Component)value).gameObject.SetActive(Imperium.Settings.Visualization.ShovelIndicators.Value);
		}
	}
	internal class SpawnIndicators : BaseVisualizer<OracleState, SpawnIndicator>
	{
		public SpawnIndicators(ImpBinding<OracleState> oracleStateBinding, ImpBinding<bool> visibilityBinding)
			: base((IBinding<OracleState>)oracleStateBinding, (IBinding<bool>)visibilityBinding)
		{
		}

		protected override void OnRefresh(OracleState state)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			for (int i = state.CurrentCycle; i < state.OutdoorCycles.Length; i++)
			{
				foreach (SpawnReport item in state.OutdoorCycles[i])
				{
					GameObject val = Object.Instantiate<GameObject>(ImpAssets.SpawnIndicator);
					SpawnIndicator spawnIndicator = val.AddComponent<SpawnIndicator>();
					((Component)spawnIndicator).transform.position = item.Position;
					spawnIndicator.Init(Imperium.ObjectManager.GetDisplayName(item.Entity.enemyName), item.SpawnTime);
					visualizerObjects[((Object)val).GetInstanceID()] = spawnIndicator;
				}
			}
		}
	}
	internal class SpikeTrapGizmos : BaseVisualizer<IReadOnlyCollection<SpikeRoofTrap>, SpikeTrapGizmo>
	{
		public SpikeTrapGizmos(IBinding<IReadOnlyCollection<SpikeRoofTrap>> objectsBinding, IBinding<bool> visibilityBinding)
			: base(objectsBinding, visibilityBinding)
		{
		}

		protected override void OnRefresh(IReadOnlyCollection<SpikeRoofTrap> objects)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			ClearObjects();
			foreach (SpikeRoofTrap item in objects.Where((SpikeRoofTrap obj) => Object.op_Implicit((Object)(object)obj)))
			{
				if (!visualizerObjects.ContainsKey(((Object)item).GetInstanceID()))
				{
					GameObject val = new GameObject($"Imp_SpikeTrapGizmo_{((Object)item).GetInstanceID()}");
					val.transform.SetParent(((Component)item).transform.parent);
					SpikeTrapGizmo spikeTrapGizmo = val.AddComponent<SpikeTrapGizmo>();
					spikeTrapGizmo.Init(item);
					visualizerObjects[((Object)item).GetInstanceID()] = spikeTrapGizmo;
				}
			}
		}
	}
	internal class VentTimers : BaseVisualizer<IReadOnlyCollection<EnemyVent>, VentTimer>
	{
		public VentTimers(IBinding<IReadOnlyCollection<EnemyVent>> objectsBinding, IBinding<bool> visibilityBinding)
			: base(objectsBinding, visibilityBinding)
		{
		}

		protected override void OnRefresh(IReadOnlyCollection<EnemyVent> objects)
		{
			//IL_0085: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			foreach (EnemyVent item in objects.Where((EnemyVent obj) => Object.op_Implicit((Object)(object)obj)))
			{
				if (!visualizerObjects.ContainsKey(((Object)item).GetInstanceID()))
				{
					GameObject obj2 = Object.Instantiate<GameObject>(ImpAssets.SpawnTimerObject, ((Component)item).transform, true);
					((Object)obj2).name = $"Imp_VentTimer_{((Object)item).GetInstanceID()}";
					obj2.transform.rotation = ((Component)item).transform.rotation;
					obj2.transform.localRotation = Quaternion.Euler(0f, 180f, -90f);
					obj2.transform.position = ((Component)item).transform.position + Vector3.up * 0.8f;
					VentTimer ventTimer = obj2.AddComponent<VentTimer>();
					ventTimer.vent = item;
					visualizerObjects[((Object)item).GetInstanceID()] = ventTimer;
				}
			}
		}
	}
}
namespace Imperium.Visualizers.Objects
{
	public class EntityGizmo : MonoBehaviour
	{
		private EnemyAI entityController;

		private EntityGizmoConfig entityConfig;

		private Visualization visualization;

		private LineRenderer lastHeardNoise;

		private LineRenderer targetLookLine;

		private LineRenderer targetPlayerLine;

		private readonly LineRenderer[] pathLines = (LineRenderer[])(object)new LineRenderer[20];

		private readonly Dictionary<string, GameObject> VisualizerObjects = new Dictionary<string, GameObject>();

		private readonly Dictionary<string, ulong> VisualizerObjectNetIds = new Dictionary<string, ulong>();

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

		private Vector3 lastHeardNoisePosition;

		private float lastHeardNoiseTimer;

		internal void Init(EntityGizmoConfig config, Visualization visualizer, EnemyAI entity)
		{
			entityConfig = config;
			visualization = visualizer;
			entityController = entity;
			targetLookLine = ImpGeometry.CreateLine(((Component)entity).transform, 0.03f, true, null, null, null);
			targetPlayerLine = ImpGeometry.CreateLine(((Component)entity).transform, 0.03f, true, null, null, null);
			for (int i = 0; i < pathLines.Length; i++)
			{
				pathLines[i] = ImpGeometry.CreateLine(((Component)this).transform, 0.1f, true, null, null, null);
			}
			lastHeardNoise = ImpGeometry.CreateLine(((Component)entity).transform, 0.03f, true, null, null, null);
		}

		internal void NoiseVisualizerUpdate(Vector3 origin)
		{
			//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_0026: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			ImpGeometry.SetLinePositions(lastHeardNoise, ((Component)entityController).transform.position, origin);
			((Component)lastHeardNoise).gameObject.SetActive(entityConfig.Hearing.Value);
			lastHeardNoisePosition = origin;
			lastHeardNoiseTimer = Time.realtimeSinceStartup;
		}

		internal void ConeVisualizerUpdate(Transform eye, float angle, float length, Material material, Func<EntityGizmoConfig, ImpBinding<bool>> configGetter, GizmoDuration gizmoDuration, int id = -1, Func<Vector3> relativePositionOverride = null, Func<Transform, Vector3> absolutePositionOverride = null)
		{
			//IL_00a0: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0117: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (id == -1)
			{
				id = (int)length;
			}
			string text = Visualization.GenerateConeHash((Object)(object)entityController, (Object)(object)eye, angle, id);
			if (!VisualizerObjects.TryGetValue(text, out var value))
			{
				value = new GameObject("ImpVis_LOS_" + text);
				((Renderer)value.AddComponent<MeshRenderer>()).material = material;
				value.AddComponent<MeshFilter>().mesh = visualization.GetOrGenerateCone(angle);
				VisualizerObjects[text] = value;
				Dictionary<string, ulong> visualizerObjectNetIds = VisualizerObjectNetIds;
				NetworkObject component = ((Component)entityController).GetComponent<NetworkObject>();
				visualizerObjectNetIds[text] = ((component != null) ? component.NetworkObjectId : ((ulong)((Object)entityController).GetInstanceID()));
			}
			value.transform.localScale = Vector3.one * length;
			if (Imperium.Settings.Visualization.SmoothAnimations.Value)
			{
				value.transform.localPosition = relativePositionOverride?.Invoke() ?? Vector3.zero;
				value.transform.localRotation = Quaternion.identity;
				value.transform.SetParent(eye, true);
			}
			else
			{
				value.transform.position = absolutePositionOverride?.Invoke(eye) ?? eye.position;
				value.transform.rotation = eye.rotation;
				value.transform.SetParent((Transform)null, true);
			}
			value.gameObject.SetActive(configGetter(entityConfig).Value);
			if (gizmoDuration == GizmoDuration.AIInterval)
			{
				VisualizerTimers[text] = Time.realtimeSinceStartup;
			}
		}

		internal void SphereVisualizerUpdate([CanBeNull] Transform eye, float radius, Material material, Func<EntityGizmoConfig, ImpBinding<bool>> configGetter, GizmoDuration gizmoDuration, int id = -1, Func<Vector3> relativePositionOverride = null, Func<Transform, Vector3> absolutePositionOverride = null)
		{
			//IL_0094: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if (id == -1)
			{
				id = (int)radius;
			}
			string text = Visualization.GenerateSphereHash((Object)(object)entityController, (Object)(object)eye, id);
			GameObject orCreateSphereVisualizerObject = GetOrCreateSphereVisualizerObject(text, radius, material);
			if (Imperium.Settings.Visualization.SmoothAnimations.Value)
			{
				orCreateSphereVisualizerObject.transform.localPosition = relativePositionOverride?.Invoke() ?? Vector3.zero;
				orCreateSphereVisualizerObject.transform.localRotation = Quaternion.identity;
				orCreateSphereVisualizerObject.transform.SetParent(eye, true);
			}
			else
			{
				orCreateSphereVisualizerObject.transform.position = absolutePositionOverride?.Invoke(eye) ?? ((eye != null) ? eye.position : Vector3.zero);
				orCreateSphereVisualizerObject.transform.rotation = (Object.op_Implicit((Object)(object)eye) ? eye.rotation : Quaternion.identity);
				orCreateSphereVisualizerObject.transform.SetParent((Transform)null, true);
			}
			orCreateSphereVisualizerObject.SetActive(configGetter(entityConfig).Value);
			if (gizmoDuration == GizmoDuration.AIInterval)
			{
				VisualizerTimers[text] = Time.realtimeSinceStartup;
			}
		}

		internal void StaticSphereVisualizerUpdate(GameObject ownerObj, Vector3 position, float radius, Material material, Func<EntityGizmoConfig, ImpBinding<bool>> configGetter, GizmoDuration gizmoDuration, int id = -1)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (id == -1)
			{
				id = (int)radius;
			}
			string text = Visualization.GenerateSphereHash((Object)(object)entityController, (Object)(object)ownerObj, id);
			GameObject orCreateSphereVisualizerObject = GetOrCreateSphereVisualizerObject(text, radius, material);
			orCreateSphereVisualizerObject.transform.position = position;
			orCreateSphereVisualizerObject.transform.rotation = Quaternion.identity;
			orCreateSphereVisualizerObject.SetActive(configGetter(entityConfig).Value);
			if (gizmoDuration == GizmoDuration.AIInterval)
			{
				VisualizerTimers[text] = Time.realtimeSinceStartup;
			}
		}

		private GameObject GetOrCreateSphereVisualizerObject(string identifier, float radius, Material material)
		{
			if (!VisualizerObjects.TryGetValue(identifier, out var value))
			{
				value = ImpGeometry.CreatePrimitive((PrimitiveType)0, null, material, radius * 2f, 0, "ImpVis_Custom_" + identifier);
				VisualizerObjects[identifier] = value;
				Dictionary<string, ulong> visualizerObjectNetIds = VisualizerObjectNetIds;
				NetworkObject component = ((Component)entityController).GetComponent<NetworkObject>();
				visualizerObjectNetIds[identifier] = ((component != null) ? component.NetworkObjectId : ((ulong)((Object)entityController).GetInstanceID()));
			}
			return value;
		}

		private void OnDestroy()
		{
			foreach (KeyValuePair<string, GameObject> visualizerObject in VisualizerObjects)
			{
				visualizerObject.Deconstruct(out var _, out var value);
				Object.Destroy((Object)(object)value);
			}
			foreach (LineRenderer item in pathLines.Where((LineRenderer obj) => Object.op_Implicit((Object)(object)obj)))
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			if (Object.op_Implicit((Object)(object)targetLookLine))
			{
				Object.Destroy((Object)(object)((Component)targetLookLine).gameObject);
			}
			if (Object.op_Implicit((Object)(object)targetPlayerLine))
			{
				Object.Destroy((Object)(object)((Component)targetPlayerLine).gameObject);
			}
			if (Object.op_Implicit((Object)(object)lastHeardNoise))
			{
				Object.Destroy((Object)(object)((Component)lastHeardNoise).gameObject);
			}
		}

		private void Update()
		{
			string key;
			if (!Object.op_Implicit((Object)(object)entityController))
			{
				foreach (KeyValuePair<string, GameObject> visualizerObject in VisualizerObjects)
				{
					visualizerObject.Deconstruct(out key, out var value);
					Object.Destroy((Object)(object)value);
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			foreach (KeyValuePair<string, float> visualizerTimer in VisualizerTimers)
			{
				visualizerTimer.Deconstruct(out key, out var value2);
				string key2 = key;
				float num = value2;
				bool flag = Imperium.ObjectManager.DisabledObjects.Value.Contains(VisualizerObjectNetIds[key2]);
				if (Time.realtimeSinceStartup - num > 0.76f && !flag)
				{
					VisualizerObjects[key2].gameObject.SetActive(false);
				}
			}
			DrawPathLines(entityConfig.Pathfinding.Value && ((Behaviour)entityController).enabled);
			DrawNoiseLine(entityConfig.Hearing.Value && ((Behaviour)entityController).enabled);
			DrawTargetPlayerLine(entityConfig.Targeting.Value && ((Behaviour)entityController).enabled);
		}

		private void DrawNoiseLine(bool isShown)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!isShown)
			{
				((Component)lastHeardNoise).gameObject.SetActive(false);
				return;
			}
			if (Time.realtimeSinceStartup - lastHeardNoiseTimer > 5f)
			{
				((Component)lastHeardNoise).gameObject.SetActive(false);
				return;
			}
			ImpGeometry.SetLinePositions(lastHeardNoise, ((Component)entityController).transform.position, lastHeardNoisePosition);
		}

		private void DrawPathLines(bool isShown)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] corners = entityController.agent.path.corners;
			Vector3 val = ((Component)entityController).transform.position;
			for (int i = 0; i < pathLines.Length; i++)
			{
				if (i < corners.Length)
				{
					((Component)pathLines[i]).gameObject.SetActive(isShown);
					if (isShown)
					{
						ImpGeometry.SetLinePositions(pathLines[i], val, corners[i]);
						ImpGeometry.SetLineColor(pathLines[i], Color.white);
						val = corners[i];
					}
				}
				else
				{
					((Component)pathLines[i]).gameObject.SetActive(false);
				}
			}
		}

		private void DrawTargetPlayerLine(bool isShown)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if (!isShown)
			{
				((Component)targetPlayerLine).gameObject.SetActive(false);
			}
			else if (entityController.movingTowardsTargetPlayer && Object.op_Implicit((Object)(object)entityController.targetPlayer))
			{
				((Component)targetPlayerLine).gameObject.SetActive(true);
				ImpGeometry.SetLinePositions(targetPlayerLine, ((Component)entityController).transform.position, ((Component)entityController.targetPlayer).transform.position);
				ImpGeometry.SetLineColor(targetPlayerLine, Color.red, Color.red);
			}
			else
			{
				((Component)targetPlayerLine).gameObject.SetActive(false);
			}
		}
	}
	internal class EntityGizmoConfig
	{
		internal readonly string entityName;

		internal readonly ImpConfig<bool> Info;

		internal readonly ImpConfig<bool> Pathfinding;

		internal readonly ImpConfig<bool> Targeting;

		internal readonly ImpConfig<bool> LineOfSight;

		internal readonly ImpConfig<bool> Hearing;

		internal readonly ImpConfig<bool> Custom;

		internal EntityGizmoConfig(string entityName, ConfigFile config)
		{
			this.entityName = entityName;
			string key = entityName.Replace("\"", "").Replace("'", "").Replace("[", "")
				.Replace("]", "")
				.Replace("\n", "")
				.Replace("\t", "")
				.Replace("\\", "");
			Info = new ImpConfig<bool>(config, "Visualization.EntityGizmos.Info", key, defaultValue: false);
			Pathfinding = new ImpConfig<bool>(config, "Visualization.EntityGizmos.Pathfinding", key, defaultValue: false);
			Targeting = new ImpConfig<bool>(config, "Visualization.EntityGizmos.Targeting", key, defaultValue: false);
			LineOfSight = new ImpConfig<bool>(config, "Visualization.EntityGizmos.LineOfSight", key, defaultValue: false);
			Hearing = new ImpConfig<bool>(config, "Visualization.EntityGizmos.Hearing", key, defaultValue: false);
			Custom = new ImpConfig<bool>(config, "Visualization.EntityGizmos.Custom", key, defaultValue: false);
		}
	}
	public class KnifeGizmo : MonoBehaviour
	{
		private GameObject capsule;

		private Dictionary<int, LineRenderer> targetRays = new Dictionary<int, LineRenderer>();

		private KnifeItem knife;

		private const float CastLength = 0.75f;

		private const float CastRadius = 0.3f;

		private bool isActivelyHolding;

		private void Awake()
		{
			capsule = ImpGeometry.CreatePrimitive((PrimitiveType)1, ((Component)this).transform, ImpAssets.WireframePurple);
		}

		public void Init(KnifeItem item, bool isHolding)
		{
			knife = item;
			isActivelyHolding = isHolding;
			capsule.SetActive(isActivelyHolding);
			if (isActivelyHolding)
			{
				return;
			}
			foreach (KeyValuePair<int, LineRenderer> targetRay in targetRays)
			{
				targetRay.Deconstruct(out var _, out var value);
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
			targetRays.Clear();
		}

		private void Update()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: 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_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			if (!isActivelyHolding || !Object.op_Implicit((Object)(object)((GrabbableObject)knife).playerHeldBy))
			{
				return;
			}
			Transform transform = ((Component)((GrabbableObject)knife).playerHeldBy).transform;
			Transform transform2 = ((Component)((GrabbableObject)knife).playerHeldBy.gameplayCamera).transform;
			Vector3 position = transform2.position;
			Vector3 forward = transform2.forward;
			Vector3 val = position + transform2.right * 0.1f;
			Vector3 val2 = val + forward * 0.75f;
			capsule.transform.position = val + forward * 0.75f / 2f;
			capsule.transform.rotation = Quaternion.LookRotation(transform2.up, forward);
			float num = Vector3.Distance(val, val2) + 0.6f;
			capsule.transform.localScale = new Vector3(0.6f, num / 2f, 0.6f);
			RaycastHit[] array = Physics.SphereCastAll(val, 0.3f, forward, 0.75f, 11012424, (QueryTriggerInteraction)2);
			HashSet<int> hashSet = new HashSet<int>();
			RaycastHit[] array2 = array;
			int i;
			RaycastHit val4 = default(RaycastHit);
			IHittable val5 = default(IHittable);
			for (i = 0; i < array2.Length; i++)
			{
				RaycastHit val3 = array2[i];
				Color value = Color.green;
				int layer = ((Component)((RaycastHit)(ref val3)).collider).gameObject.layer;
				if ((layer == 8 || layer == 11) ? true : false)
				{
					value = Color.white;
				}
				else if ((((RaycastHit)(ref val3)).point != Vector3.zero && Physics.Linecast(position, ((RaycastHit)(ref val3)).point, ref val4, Imperium.StartOfRound.collidersAndRoomMaskAndDefault)) || !((Component)((RaycastHit)(ref val3)).transform).TryGetComponent<IHittable>(ref val5) || (Object)(object)((RaycastHit)(ref val3)).transform == (Object)(object)((Component)transform).transform)
				{
					continue;
				}
				int instanceID = ((Object)((Component)((RaycastHit)(ref val3)).collider).gameObject).GetInstanceID();
				if (!targetRays.TryGetValue(instanceID, out var value2))
				{
					value2 = ImpGeometry.CreateLine(((Component)this).transform, 0.05f, true, null, null, null);
					targetRays[instanceID] = value2;
				}
				hashSet.Add(instanceID);
				ImpGeometry.SetLineColor(value2, value);
				ImpGeometry.SetLinePositions(value2, position + Vector3.up * 0.2f, ((RaycastHit)(ref val3)).point);
			}
			Dictionary<int, LineRenderer> dictionary = new Dictionary<int, LineRenderer>();
			foreach (KeyValuePair<int, LineRenderer> targetRay in targetRays)
			{
				targetRay.Deconstruct(out i, out var value3);
				int num2 = i;
				LineRenderer val6 = value3;
				if (hashSet.Contains(num2))
				{
					dictionary[num2] = val6;
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val6).gameObject);
				}
			}
			targetRays = dictionary;
		}
	}
	public class LandmineGizmo : MonoBehaviour
	{
		private GameObject sphere;

		private Landmine landmine;

		private Dictionary<int, LineRenderer> targetRays = new Dictionary<int, LineRenderer>();

		private void Awake()
		{
			sphere = ImpGeometry.CreatePrimitive((PrimitiveType)0, ((Component)this).transform, ImpAssets.WireframeRed, 12f);
		}

		public void SnapshotHitboxes()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: 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_0203: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)landmine).transform.position + Vector3.up;
			Collider[] array = Physics.OverlapSphere(val, 6f, 2621448, (QueryTriggerInteraction)2);
			BoxCollider val6 = default(BoxCollider);
			CapsuleCollider val7 = default(CapsuleCollider);
			foreach (Collider val2 in array)
			{
				Vector3 position = ((Component)val2).transform.position;
				float num = Vector3.Distance(val, position);
				bool flag = num > 4f && Physics.Linecast(val, position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1);
				Color val3 = (flag ? Color.green : Color.red);
				bool flag2 = false;
				Color val4;
				GameObject val5;
				PlayerControllerB component;
				BoxCollider component2;
				Transform transform;
				switch (((Component)val2).gameObject.layer)
				{
				case 3:
				{
					float num2 = num;
					if (!(num2 >= 6f))
					{
						if (!(num2 >= 5.7f))
						{
							goto IL_00fe;
						}
					}
					else if (!flag)
					{
						val4 = Color.green;
						goto IL_0102;
					}
					if (flag)
					{
						goto IL_00fe;
					}
					val4 = new Color(1f, 0.63f, 0.2f);
					goto IL_0102;
				}
				case 19:
				{
					if (num >= 4.5f)
					{
						val3 = Color.green;
					}
					EnemyAICollisionDetect componentInChildren2 = ((Component)val2).GetComponentInChildren<EnemyAICollisionDetect>();
					if (!((Object)(object)componentInChildren2 == (Object)null))
					{
						Transform transform2 = ((Component)componentInChildren2).transform;
						if (((Component)componentInChildren2).TryGetComponent<BoxCollider>(ref val6))
						{
							GameObject obj = ImpGeometry.CreatePrimitive((PrimitiveType)3, ((Component)componentInChildren2).transform, ImpAssets.WireframeYellow);
							obj.transform.position = transform2.position;
							obj.transform.localPosition = val6.center;
							obj.transform.localScale = val6.size;
							obj.transform.rotation = transform2.rotation;
							obj.transform.SetParent(((Component)this).transform, true);
						}
						if (((Component)componentInChildren2).TryGetComponent<CapsuleCollider>(ref val7))
						{
							GameObject obj2 = ImpGeometry.CreatePrimitive((PrimitiveType)1, ((Component)componentInChildren2).transform, ImpAssets.WireframeYellow);
							obj2.transform.position = transform2.position;
							obj2.transform.localPosition = val7.center;
							obj2.transform.localScale = new Vector3(val7.radius * 2f, val7.height / 2f, val7.radius * 2f);
							obj2.transform.rotation = transform2.rotation;
							obj2.transform.SetParent(((Component)this).transform, true);
						}
						flag2 = true;
					}
					break;
				}
				case 21:
					{
						if (!(num >= 6f))
						{
							Landmine componentInChildren = ((Component)val2).gameObject.GetComponentInChildren<Landmine>();
							if (Object.op_Implicit((Object)(object)componentInChildren) && !componentInChildren.hasExploded)
							{
								((Color)(ref val3))..ctor(0.34f, 0f, 0.56f);
								flag2 = true;
							}
						}
						break;
					}
					IL_00fe:
					val4 = val3;
					goto IL_0102;
					IL_0102:
					val3 = val4;
					val5 = ImpGeometry.CreatePrimitive((PrimitiveType)3, ((Component)this).transform, ImpAssets.WireframeYellow);
					component = ((Component)val2).GetComponent<PlayerControllerB>();
					if (!Object.op_Implicit((Object)(object)component))
					{
						continue;
					}
					component2 = ((Component)component).GetComponent<BoxCollider>();
					transform = ((Component)component2).transform;
					val5.transform.position = transform.position + component2.center;
					val5.transform.localScale = component2.size;
					val5.transform.rotation = transform.rotation;
					flag2 = true;
					break;
				}
				if (flag2)
				{
					LineRenderer lineRenderer = ImpGeometry.CreateLine(((Component)this).transform, 0.05f, true, null, null, null);
					ImpGeometry.SetLineColor(lineRenderer, val3);
					ImpGeometry.SetLinePositions(lineRenderer, val, position + Vector3.up * 0.3f);
				}
			}
		}

		private void Update()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0128: 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_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			if (landmine.hasExploded)
			{
				if (targetRays.Count <= 0)
				{
					return;
				}
				foreach (LineRenderer value4 in targetRays.Values)
				{
					Object.Destroy((Object)(object)((Component)value4).gameObject);
				}
				targetRays.Clear();
				return;
			}
			Collider[] array = Physics.OverlapSphere(((Component)landmine).transform.position, 6f, 2621448, (QueryTriggerInteraction)2);
			HashSet<int> hashSet = new HashSet<int>();
			Collider[] array2 = array;
			int i;
			for (i = 0; i < array2.Length; i++)
			{
				Collider val = array2[i];
				int instanceID = ((Object)((Component)val).gameObject).GetInstanceID();
				if (!targetRays.TryGetValue(instanceID, out var value))
				{
					value = ImpGeometry.CreateLine(((Component)this).transform, 0.05f, true, null, null, null);
					targetRays[instanceID] = value;
				}
				Vector3 position = ((Component)val).transform.position;
				Vector3 position2 = ((Component)landmine).transform.position;
				float num = Vector3.Distance(position2, position);
				bool flag = num > 4f && Physics.Linecast(position2, position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1);
				Color value2 = (flag ? Color.green : Color.red);
				bool flag2 = false;
				switch (((Component)val).gameObject.layer)
				{
				case 3:
					if (!flag && num >= 5.7f)
					{
						((Color)(ref value2))..ctor(1f, 0.63f, 0.2f);
					}
					flag2 = true;
					break;
				case 19:
					if (Object.op_Implicit((Object)(object)((Component)val).GetComponent<EnemyAICollisionDetect>()))
					{
						if (num >= 4.5f)
						{
							value2 = Color.green;
						}
						flag2 = true;
					}
					break;
				case 21:
				{
					Landmine componentInChildren = ((Component)val).gameObject.GetComponentInChildren<Landmine>();
					if (Object.op_Implicit((Object)(object)componentInChildren) && !componentInChildren.hasExploded && !((Object)(object)componentInChildren == (Object)(object)landmine))
					{
						value2 = (Color)((num >= 6f) ? Color.green : new Color(0.79f, 0.09f, 1f));
						flag2 = true;
					}
					break;
				}
				}
				if (flag2)
				{
					hashSet.Add(instanceID);
					ImpGeometry.SetLineColor(value, value2);
					ImpGeometry.SetLinePositions(value, ((Component)landmine).transform.position, position);
				}
			}
			Dictionary<int, LineRenderer> dictionary = new Dictionary<int, LineRenderer>();
			foreach (KeyValuePair<int, LineRenderer> targetRay in targetRays)
			{
				targetRay.Deconstruct(out i, out var value3);
				int num2 = i;
				LineRenderer val2 = value3;
				if (hashSet.Contains(num2))
				{
					dictionary[num2] = val2;
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
			targetRays = dictionary;
		}

		public void Init(Landmine mine)
		{
			//IL_0012: 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_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			landmine = mine;
			Vector3 position = ((Component)landmine).transform.position;
			sphere.transform.position = position + Vector3.up;
		}
	}
	public class ObjectInsight : MonoBehaviour
	{
		private Component targetObject;

		private GameObject insightPanelObject;

		private Transform panelContainer;

		private Transform insightPanel;

		private RectTransform insightPanelRect;

		private RectTransform insightPanelCanvasRect;

		private TMP_Text panelObjectName;

		private TMP_Text panelObjectPersonalName;

		private GameObject panelEntryTemplate;

		private Image deathOverlay;

		private readonly Dictionary<string, ObjectInsightEntry> targetInsightEntries = new Dictionary<string, ObjectInsightEntry>();

		private readonly ImpTimer overlayUpdateTimer = ImpTimer.ForInterval(1f);

		internal InsightDefinition<Component> InsightDefinition { get; private set; }

		internal void Init(Component target, InsightDefinition<Component> definition)
		{
			targetObject = target;
			InsightDefinition = definition;
			insightPanelObject = Object.Instantiate<GameObject>(ImpAssets.ObjectInsightPanel, ((Component)this).transform);
			panelContainer = insightPanelObject.transform.Find("Container");
			insightPanel = panelContainer.Find("Panel");
			insightPanelRect = ((Component)panelContainer).GetComponent<RectTransform>();
			insightPanelCanvasRect = insightPanelObject.GetComponent<RectTransform>();
			panelObjectName = ((Component)insightPanel.Find("Name")).GetComponent<TMP_Text>();
			panelObjectPersonalName = ((Component)insightPanel.Find("PersonalName")).GetComponent<TMP_Text>();
			deathOverlay = ((Component)insightPanel.Find("Death")).GetComponent<Image>();
			panelEntryTemplate = ((Component)insightPanel.Find("Template")).gameObject;
			panelEntryTemplate.SetActive(false);
			InsightDefinition.Insights.onUpdate += OnInsightsUpdate;
			OnInsightsUpdate(InsightDefinition.Insights.Value);
			UpdateInsightOverlay();
		}

		internal void UpdateInsightDefinition(InsightDefinition<Component> definition)
		{
			InsightDefinition.Insights.onUpdate -= OnInsightsUpdate;
			InsightDefinition = definition;
			InsightDefinition.Insights.onUpdate += OnInsightsUpdate;
		}

		private void OnInsightsUpdate(Dictionary<string, Func<Component, string>> insights)
		{
			foreach (var (text2, func2) in insights)
			{
				if (!targetInsightEntries.TryGetValue(text2, out var value))
				{
					targetInsightEntries[text2] = CreateInsightEntry(text2, func2);
				}
				else
				{
					value.Init(text2, func2, targetObject);
				}
			}
			foreach (string item in targetInsightEntries.Keys.ToHashSet().Except(insights.Keys.ToHashSet()))
			{
				Object.Destroy((Object)(object)((Component)targetInsightEntries[item]).gameObject);
				targetInsightEntries.Remove(item);
			}
		}

		private ObjectInsightEntry CreateInsightEntry(string insightName, Func<Component, string> insightGenerator)
		{
			if (targetInsightEntries.TryGetValue(insightName, out var value))
			{
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
			GameObject obj = Object.Instantiate<GameObject>(panelEntryTemplate, insightPanel);
			obj.SetActive(true);
			ObjectInsightEntry objectInsightEntry = obj.gameObject.AddComponent<ObjectInsightEntry>();
			objectInsightEntry.Init(insightName, insightGenerator, targetObject);
			return objectInsightEntry;
		}

		private void UpdateInsightOverlay()
		{
			panelObjectName.text = ((InsightDefinition.NameGenerator != null) ? InsightDefinition.NameGenerator(targetObject) : ((Object)targetObject).GetInstanceID().ToString());
			if (InsightDefinition.PersonalNameGenerator == null)
			{
				((Component)panelObjectPersonalName).gameObject.SetActive(false);
			}
			else
			{
				panelObjectPersonalName.text = InsightDefinition.PersonalNameGenerator(targetObject);
				((Component)panelObjectPersonalName).gameObject.SetActive(true);
			}
			if (InsightDefinition.IsDeadGenerator != null && InsightDefinition.IsDeadGenerator(targetObject))
			{
				if (!Imperium.Settings.Visualization.SSHideInactive.Value)
				{
					((Component)deathOverlay).gameObject.SetActive(true);
				}
			}
			else
			{
				((Component)deathOverlay).gameObject.SetActive(false);
			}
		}

		private void LateUpdate()
		{
			//IL_00c1: 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_00c6: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)targetObject) || !Object.op_Implicit((Object)(object)insightPanelCanvasRect))
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Camera val = (Imperium.Freecam.IsFreecamEnabled.Value ? Imperium.Freecam.FreecamCamera : (Imperium.Player.hasBegunSpectating ? Imperium.StartOfRound.spectateCamera : Imperium.Player.gameplayCamera));
			RenderTexture val2 = ((val != null) ? val.activeTexture : null);
			if (!InsightDefinition.VisibilityBinding.Value || !Object.op_Implicit((Object)(object)val2))
			{
				insightPanelObject.SetActive(false);
				return;
			}
			Vector3 val3 = InsightDefinition.PositionOverride?.Invoke(targetObject) ?? targetObject.transform.position;
			Vector3 val4 = val.WorldToScreenPoint(val3);
			Rect cameraRect = Imperium.Map.Minimap.CameraRect;
			if (((Rect)(ref cameraRect)).Contains(val4))
			{
				insightPanelObject.SetActive(false);
				return;
			}
			if ((Physics.Linecast(((Component)val).transform.position, val3, StartOfRound.Instance.collidersAndRoomMaskAndDefault) && !Imperium.Settings.Visualization.SSAlwaysOnTop.Value) || val4.z < 0f)
			{
				insightPanelObject.SetActive(false);
				return;
			}
			if (overlayUpdateTimer.Tick())
			{
				UpdateInsightOverlay();
			}
			float num = (float)((Texture)val2).width / insightPanelCanvasRect.sizeDelta.x;
			float num2 = (float)((Texture)val2).height / insightPanelCanvasRect.sizeDelta.y;
			float num3 = val4.x / num;
			float num4 = val4.y / num2;
			insightPanelRect.anchoredPosition = new Vector2(num3, num4);
			float num5 = Imperium.Settings.Visualization.SSOverlayScale.Value;
			if (Imperium.Settings.Visualization.SSAutoScale.Value)
			{
				num5 *= Math.Clamp(5f / Vector3.Distance(((Component)val).transform.position, val3), 0.01f, 1f);
			}
			((Component)this).transform.localScale = Vector3.one;
			((Transform)insightPanelRect).localScale = num5 * Vector3.one;
			insightPanelObject.SetActive(true);
		}
	}
	public class ObjectInsightEntry : MonoBehaviour
	{
		private Component targetComponent;

		private Func<Component, string> insightGenerator;

		private TMP_Text insightValueText;

		private readonly ImpTimer entryUpdateTimer = ImpTimer.ForInterval(0.2f);

		public void Init(string insightName, Func<Component, string> generator, Component target)
		{
			insightGenerator = generator;
			targetComponent = target;
			insightValueText = ((Component)((Component)this).transform.Find("Value")).GetComponent<TMP_Text>();
			((Component)((Component)this).transform.Find("Title")).GetComponent<TMP_Text>().text = insightName;
			insightValueText.text = insightGenerator(targetComponent);
		}

		private void Update()
		{
			if (entryUpdateTimer.Tick())
			{
				insightValueText.text = insightGenerator(targetComponent);
			}
		}
	}
	public class PlayerGizmo : MonoBehaviour
	{
		private PlayerControllerB playerController;

		private PlayerGizmoConfig playerGizmoConfig;

		private GameObject noiseRangeSphere;

		internal void Init(PlayerGizmoConfig config, PlayerControllerB player)
		{
			playerGizmoConfig = config;
			playerController = player;
			noiseRangeSphere = ImpGeometry.CreatePrimitive((PrimitiveType)0, ((Component)player).transform, ImpAssets.WireframeRed);
		}

		internal void NoiseUpdate(float range)
		{
		}

		private void Update()
		{
			if (!Object.op_Implicit((Object)(object)playerController))
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				DrawNoiseRange(playerGizmoConfig.NoiseRange.Value);
			}
		}

		private void DrawNoiseRange(bool isShown)
		{
			if (!isShown)
			{
				noiseRangeSphere.SetActive(false);
			}
		}
	}
	internal class PlayerGizmoConfig
	{
		internal readonly string playerName;

		internal readonly ImpBinding<bool> NoiseRange;

		internal PlayerGizmoConfig(string playerName, ConfigFile config)
		{
			this.playerName = playerName;
			NoiseRange = new ImpConfig<bool>(config, "Visualization.PlayerGizmos", "NoiseRange", defaultValue: false);
		}
	}
	public class ShotgunGizmo : MonoBehaviour
	{
		private readonly Dictionary<int, LineRenderer> playerRays = new Dictionary<int, LineRenderer>();

		private readonly LineRenderer[] entityRays = (LineRenderer[])(object)new LineRenderer[10];

		private GameObject rayHolder;

		private LineRenderer spherecastOriginArea;

		private ShotgunItem shotgun;

		private bool isActivelyHolding;

		private const float SpherecastRadius = 5f;

		private const float SpherecastStartOffset = -10f;

		private const float SpherecastRange = 15f;

		private const float EntityMaxDmgRange = 3.7f;

		private const float EntityMidDmgRange = 6f;

		private const float PlayerDmgAngle = 30f;

		private const float PlayerKillRange = 15f;

		private const float PlayerMidDmgRange = 23f;

		private const float PlayerLowDmgRange = 30f;

		private const float CirclePointCount = 64f;

		private static readonly Color MinEntityDamageColor = new Color(0.6f, 1f, 0.6f);

		private static readonly Color MidEntityDamageColor = new Color(0.3f, 1f, 0.3f);

		private static readonly Color MaxEntityDamageColor = new Color(0f, 0.5f, 0f);

		private static readonly Color MinPlayerDamageColor = Color.yellow;

		private static readonly Color MidPlayerDamageColor = new Color(1f, 0.5f, 0f);

		private static readonly Color MaxPlayerDamageColor = Color.red;

		private static readonly Color SpherecastOriginColor = new Color(0.5f, 0f, 0.5f);

		private static readonly Color InvalidTargetColor = new Color(0.3f, 0.3f, 0.3f);

		private static readonly Color TargetObstructedColor = Color.white;

		private static readonly Color HitboxColorMultiplier = new Color(1f, 1f, 1f, 0.35f);

		private void Awake()
		{
			for (int i = 0; i < 10; i++)
			{
				entityRays[i] = ImpGeometry.CreateLine(((Component)this).transform, 0.05f, true, null, null, null);
			}
		}

		private void OnEnable()
		{
			Init(shotgun, isActivelyHolding);
		}

		private void OnDisable()
		{
			if (Object.op_Implicit((Object)(object)rayHolder))
			{
				rayHolder.SetActive(false);
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)rayHolder))
			{
				Object.Destroy((Object)(object)rayHolder);
			}
		}

		private static List<Vector3> GenerateArcPoints(float zOffset, float radius, float degreesArcStart, float degreesArcEnd, float maxWidth = float.PositiveInfinity)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			float num = MathF.PI / 180f * degreesArcStart;
			float num2 = MathF.PI / 180f * degreesArcEnd;
			float num3 = ((num2 - num) % (MathF.PI * 2f) + MathF.PI * 2f) % (MathF.PI * 2f);
			num2 = num + num3;
			List<Vector3> list = new List<Vector3>();
			float num4 = num;
			list.Add(new Vector3(Mathf.Sin(num4) * radius, 0f, Mathf.Cos(num4) * radius + zOffset));
			do
			{
				num4 = Mathf.Min(num4 + MathF.PI / 32f, num2);
				float num5 = Mathf.Max(Mathf.Min(Mathf.Sin(num4) * radius, maxWidth), 0f - maxWidth);
				float num6 = Mathf.Cos(num4) * radius + zOffset;
				list.Add(new Vector3(num5, 0f, num6));
			}
			while (num4 < num2);
			return list;
		}

		private static List<Vector3> Circle(float zOffset, float radius, float maxWidth = float.PositiveInfinity)
		{
			//IL_0024: 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)
			List<Vector3> list = new List<Vector3>();
			float num = 0f;
			list.Add(new Vector3(Mathf.Sin(num) * radius, 0f, Mathf.Cos(num) * radius + zOffset));
			do
			{
				num = Mathf.Min(num + MathF.PI / 32f, MathF.PI * 2f);
				float num2 = Mathf.Max(Mathf.Min(Mathf.Sin(num) * radius, maxWidth), 0f - maxWidth);
				float num3 = Mathf.Cos(num) * radius + zOffset;
				list.Add(new Vector3(num2, 0f, num3));
			}
			while (num < MathF.PI * 2f);
			return list;
		}

		private LineRenderer AddLineToRayHolder(Color lineColor, List<Vector3> points)
		{
			//IL_0012: 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)
			return ImpGeometry.CreateLine(rayHolder.transform, 0.05f, useWorldSpace: false, null, lineColor, lineColor, points.ToArray());
		}

		private void SetupRendererObject()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!((Object)(object)rayHolder != (Object)null))
			{
				GameObject val = new GameObject("ImpShotgunRayHolder");
				val.transform.parent = ((Component)this).transform;
				rayHolder = val;
				spherecastOriginArea = AddLineToRayHolder(SpherecastOriginColor * HitboxColorMultiplier, Circle(-10f, 5f));
				List<Vector3> list = GenerateArcPoints(-10f, 5f, 270f, 90f);
				List<Vector3> list2 = GenerateArcPoints(5f, 5f, 270f, 90f);
				list2.Reverse();
				list2.Add(list[0]);
				List<Vector3> points = list.Concat(list2).ToList();
				AddLineToRayHolder(MinEntityDamageColor * HitboxColorMultiplier, points);
				float num = 6f;
				float num2 = 5f;
				float num3 = Mathf.Abs(-10f);
				float num4 = (Mathf.Pow(num2, 2f) - Mathf.Pow(num, 2f) + Mathf.Pow(num3, 2f)) / (2f * num3);
				float num5 = Mathf.Acos((num3 - num4) / num);
				float num6 = Mathf.Acos(num4 / num2);
				List<Vector3> list3 = GenerateArcPoints(0f, num, -180f + num5 * 57.29578f, 180f - num5 * 57.29578f, 5f);
				List<Vector3> list4 = GenerateArcPoints(-10f, num2, (0f - num6) * 57.29578f, num6 * 57.29578f, 5f);
				list4.Reverse();
				list4.Add(list3[0]);
				List<Vector3> points2 = list3.Concat(list4).ToList();
				AddLineToRayHolder(MidEntityDamageColor * HitboxColorMultiplier, points2);
				AddLineToRayHolder(MaxEntityDamageColor * HitboxColorMultiplier, Circle(0f, 3.7f, 5f));
				List<Vector3> list5 = GenerateArcPoints(0f, 15f, -30f, 30f);
				list5.Insert(0, Vector3.zero);
				list5.Add(Vector3.zero);
				AddLineToRayHolder(MaxPlayerDamageColor * HitboxColorMultiplier, list5);
				List<Vector3> list6 = GenerateArcPoints(0f, 23f, -30f, 30f);
				list6.Insert(0, list5[1]);
				list6.Add(list5[list5.Count - 2]);
				AddLineToRayHolder(MidPlayerDamageColor * HitboxColorMultiplier, list6);
				List<Vector3> list7 = GenerateArcPoints(0f, 30f, -30f, 30f);
				list7.Insert(0, list6[1]);
				list7.Add(list6[list6.Count - 2]);
				AddLineToRayHolder(MinPlayerDamageColor * HitboxColorMultiplier, list7);
			}
		}

		public void Init(ShotgunItem shotgunItem, bool isHolding)
		{
			if (!Object.op_Implicit((Object)(object)shotgunItem))
			{
				return;
			}
			isActivelyHolding = isHolding;
			shotgun = shotgunItem;
			SetupRendererObject();
			bool flag = Object.op_Implicit((Object)(object)((GrabbableObject)shotgunItem).pla