Decompiled source of HUDdleUP v1.3.1

plugins/HUDdleUP/HUDdleUP.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Railgunner.Reload;
using EntityStates.Railgunner.Weapon;
using HUDdleUP.Bandit;
using HUDdleUP.Behaviours;
using HUDdleUP.Compatibility;
using HUDdleUP.Loot;
using HUDdleUP.Multiplayer;
using HUDdleUP.Railgunner;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using Rewired;
using RoR2;
using RoR2.Networking;
using RoR2.Skills;
using RoR2.UI;
using RoR2.UI.SkinControllers;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HUDdleUP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1+820816e2ad0526655a6b3b0bad441a360bebab80")]
[assembly: AssemblyProduct("HUDdleUP")]
[assembly: AssemblyTitle("HUDdleUP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.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 HUDdleUP
{
	public sealed class Config
	{
		private readonly ConfigFile file;

		private readonly ConfigEntry<bool> fullerItemDescriptions;

		private readonly ConfigEntry<bool> fullerEquipmentDescriptions;

		private readonly ConfigEntry<bool> fullerDescriptionsOnPickUp;

		private readonly ConfigEntry<bool> equipmentIconCooldownVisual;

		private readonly ConfigEntry<bool> commandMenuItemTooltips;

		private readonly ConfigEntry<bool> renameEquipmentDrones;

		private readonly ConfigEntry<bool> runDifficultyTooltip;

		private readonly ConfigEntry<bool> scoreboardShowChat;

		private readonly ConfigEntry<bool> lootPanel;

		private readonly ConfigEntry<bool> dronePanel;

		private readonly ConfigEntry<bool> multiplayerConnectionPanel;

		private readonly ConfigEntry<bool> railgunnerAccuracyPanel;

		private readonly ConfigEntry<bool> banditComboPanel;

		public bool FullerItemDescriptions => fullerItemDescriptions.Value;

		public bool FullerEquipmentDescriptions => fullerEquipmentDescriptions.Value;

		public bool FullerDescriptionsOnPickUp => fullerDescriptionsOnPickUp.Value;

		public bool EquipmentIconCooldownVisual => equipmentIconCooldownVisual.Value;

		public bool CommandMenuItemTooltips => commandMenuItemTooltips.Value;

		public bool RenameEquipmentDrones => renameEquipmentDrones.Value;

		public bool RunDifficultyTooltip => runDifficultyTooltip.Value;

		public bool ScoreboardShowChat => scoreboardShowChat.Value;

		public bool LootPanel => lootPanel.Value;

		public bool DronePanel => dronePanel.Value;

		public bool MultiplayerConnectionPanel => multiplayerConnectionPanel.Value;

		public bool RailgunnerAccuracyPanel => railgunnerAccuracyPanel.Value;

		public bool BanditComboPanel => banditComboPanel.Value;

		public bool TrackInteractables
		{
			get
			{
				if (!lootPanel.Value)
				{
					return dronePanel.Value;
				}
				return true;
			}
		}

		internal void Reload()
		{
			Plugin.Logger.LogDebug((object)("Reloading " + file.ConfigFilePath.Substring(file.ConfigFilePath.LastIndexOf(Path.DirectorySeparatorChar) + 1)));
			file.Reload();
		}

		internal Config(ConfigFile config)
		{
			file = config;
			fullerItemDescriptions = config.Bind<bool>("_", "fullerItemDescriptions", true, "Replace the default short (pickup) descriptions in item tooltips with a combination of the short and detailed descriptions.\n\nNote that this mod currently does not provide calculated item stack stats.");
			fullerEquipmentDescriptions = config.Bind<bool>("_", "fullerEquipmentDescriptions", true, "Replace the default short (pickup) descriptions in equipment tooltips with a combination of the short and detailed descriptions, as well as the equipment cooldown.");
			fullerDescriptionsOnPickUp = config.Bind<bool>("_", "fullerDescriptionsOnPickUp", false, "Also use the fuller item/equipment descriptions in pick up notifications.");
			equipmentIconCooldownVisual = config.Bind<bool>("_", "equipmentIconCooldownVisual", true, "Add the cooldown progress visual from skill icons to the equipment icon.");
			commandMenuItemTooltips = config.Bind<bool>("_", "commandMenuItemTooltips", true, "Add tooltips to items and equipment in pickup picker menus (e.g. command cubes, void potentials, scrappers) that show the (fuller) description of the item.");
			renameEquipmentDrones = config.Bind<bool>("_", "renameEquipmentDrones", true, "Replace the names of equipment drones in ally cards with the name of its held equipment.");
			runDifficultyTooltip = config.Bind<bool>("_", "runDifficultyTooltip", true, "Add a tooltip to the difficulty icon in the HUD that shows the description of the run's difficulty.");
			scoreboardShowChat = config.Bind<bool>("_", "scoreboardShowChat", true, "Show the chat history when the scoreboard is open.");
			lootPanel = config.Bind<bool>("HUD Panels", "lootPanel", true, "Add a Loot panel to the HUD to track how much loot is left on a stage.\n\nOnly visible when the scoreboard is open.");
			dronePanel = config.Bind<bool>("HUD Panels", "dronePanel", true, "Add a Drone panel to the HUD to track how many interactable drones are left on a stage.\n\nOnly visible when the scoreboard is open.");
			multiplayerConnectionPanel = config.Bind<bool>("HUD Panels", "multiplayerConnectionPanel", true, "Add a Connection panel to the HUD to check multiplayer latency (ping).\n\nOnly visible when the scoreboard is open.");
			railgunnerAccuracyPanel = config.Bind<bool>("HUD Panels", "railgunnerAccuracyPanel", true, "Add an Accuracy panel to the HUD to track your accuracy with landing perfect reloads and hitting weak points.");
			banditComboPanel = config.Bind<bool>("HUD Panels", "banditComboPanel", true, "Add a Combo panel to the HUD to track your consecutive cooldown resets when using the special skill \"Lights Out\".");
		}
	}
	internal static class HarmonyHelper
	{
		internal static void TryPatchAll(this Harmony harmony)
		{
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly());
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception arg)
				{
					Plugin.Logger.LogError((object)$"Failed to apply patch in {type.FullName}\n{arg}");
				}
			}
		}
	}
	public sealed class HUDPanel
	{
		public readonly GameObject gameObject;

		public readonly TextMeshProUGUI label;

		public readonly Transform stripContainer;

		private HUDPanel(GameObject panel, TextMeshProUGUI label, Transform stripContainer)
		{
			gameObject = panel;
			this.label = label;
			this.stripContainer = stripContainer;
		}

		public TextMeshProUGUI AddTextComponent(string name)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI obj = Object.Instantiate<TextMeshProUGUI>(label, ((Component)stripContainer).transform);
			((Object)obj).name = name;
			LayoutElement val = default(LayoutElement);
			if (((Component)obj).TryGetComponent<LayoutElement>(ref val))
			{
				Object.Destroy((Object)(object)val);
			}
			LabelSkinController val2 = default(LabelSkinController);
			if (((Component)obj).TryGetComponent<LabelSkinController>(ref val2))
			{
				val2.labelType = (LabelType)0;
			}
			((TMP_Text)obj).fontSize = 12f;
			((TMP_Text)obj).fontSizeMax = 12f;
			((TMP_Text)obj).fontSizeMin = 6f;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)257;
			((TMP_Text)obj).text = "hello world.";
			return obj;
		}

		public static HUDPanel ClonePanel(ObjectivePanelController objectivePanel, string name)
		{
			ObjectivePanelController obj = Object.Instantiate<ObjectivePanelController>(objectivePanel, ((Component)objectivePanel).transform.parent);
			GameObject val = ((Component)obj).gameObject;
			((Object)val).name = name;
			Object.DestroyImmediate((Object)(object)obj);
			Transform child = val.transform.GetChild(val.transform.childCount - 1);
			for (int num = ((Component)child).transform.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)child.GetChild(num)).gameObject);
			}
			HudObjectiveTargetSetter val2 = default(HudObjectiveTargetSetter);
			if (val.TryGetComponent<HudObjectiveTargetSetter>(ref val2))
			{
				Object.Destroy((Object)(object)val2);
			}
			TextMeshProUGUI val3 = (TextMeshProUGUI)(((object)val.GetComponentInChildren<HGTextMeshProUGUI>()) ?? ((object)val.GetComponentInChildren<TextMeshProUGUI>()));
			LanguageTextMeshController val4 = default(LanguageTextMeshController);
			if ((Object)(object)val3 == (Object)null)
			{
				Plugin.Logger.LogWarning((object)("New HUD panel \"" + ((Object)val).name + "\" is missing a label!"));
			}
			else if (((Component)val3).TryGetComponent<LanguageTextMeshController>(ref val4))
			{
				Object.DestroyImmediate((Object)(object)val4);
			}
			return new HUDPanel(val, val3, child);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("itsschwer.HUDdleUP", "HUDdleUP", "1.3.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string GUID = "itsschwer.HUDdleUP";

		public const string Author = "itsschwer";

		public const string Name = "HUDdleUP";

		public const string Version = "1.3.1";

		internal static ManualLogSource Logger { get; private set; }

		public static Config Config { get; private set; }

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			Logger.Sources.Remove((ILogSource)(object)((BaseUnityPlugin)this).Logger);
			Logger = Logger.CreateLogSource("itsschwer.HUDdleUP");
			Config = new Config(((BaseUnityPlugin)this).Config);
			HarmonyHelper.TryPatchAll(new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID));
			MiniMapMod.TryPatch();
			Logger.LogMessage((object)"~awake.");
		}

		private void OnEnable()
		{
			Run.onRunStartGlobal += OnRunStart;
			Run.onRunDestroyGlobal += OnRunDestroy;
			Logger.LogMessage((object)"~enabled.");
		}

		private void OnDisable()
		{
			Run.onRunStartGlobal -= OnRunStart;
			Run.onRunDestroyGlobal -= OnRunDestroy;
			Logger.LogMessage((object)"~disabled.");
		}

		private void OnRunStart(Run _)
		{
			InteractablesTracker.Hook();
			LootPanel.Hook();
			DronePanel.Hook();
			ConnectionPanel.Hook();
			RailgunnerAccuracyPanel.Hook();
			BanditComboPanel.Hook();
		}

		private void OnRunDestroy(Run _)
		{
			InteractablesTracker.Unhook();
			LootPanel.Unhook();
			DronePanel.Unhook();
			ConnectionPanel.Unhook();
			RailgunnerAccuracyPanel.Unhook();
			BanditComboPanel.Unhook();
		}
	}
	public static class TooltipHelper
	{
		public static TooltipProvider AddTooltipProvider(Graphic target, bool suppressLogs = false)
		{
			if ((Object)(object)target == (Object)null)
			{
				return null;
			}
			((Component)(object)target).AddGraphicRaycasterToParentCanvas(!suppressLogs);
			target.raycastTarget = true;
			return ((Component)target).gameObject.AddComponentIfMissing<TooltipProvider>(!suppressLogs);
		}

		private static bool AddGraphicRaycasterToParentCanvas(this Component child, bool emitLog)
		{
			GameObject gameObject = ((Component)child.GetComponentInParent<Canvas>()).gameObject;
			if (emitLog)
			{
				Plugin.Logger.LogDebug((object)("Found parent canvas " + ((Object)gameObject).name + " for " + ((Object)child).name));
			}
			return Object.op_Implicit((Object)(object)gameObject.AddComponentIfMissing<GraphicRaycaster>(emitLog));
		}

		private static T AddComponentIfMissing<T>(this GameObject target, bool emitLog) where T : Component
		{
			T val = target.GetComponent<T>();
			if ((Object)(object)val == (Object)null)
			{
				val = target.AddComponent<T>();
				if (emitLog)
				{
					Plugin.Logger.LogDebug((object)("Added " + typeof(T).FullName + " to " + ((Object)target).name));
				}
			}
			return val;
		}
	}
}
namespace HUDdleUP.Patches
{
	[HarmonyPatch]
	internal static class EquipmentCooldownProgressVisual
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(HUD), "Awake")]
		private static void HUD_Awake(HUD __instance)
		{
			if (!Plugin.Config.EquipmentIconCooldownVisual || __instance.skillIcons.Length == 0 || !Object.op_Implicit((Object)(object)__instance.skillIcons[0]))
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)__instance.skillIcons[0].cooldownRemapPanel) || !Object.op_Implicit((Object)(object)((Component)__instance.skillIcons[0].cooldownRemapPanel).gameObject))
			{
				Plugin.Logger.LogWarning((object)"EquipmentCooldownProgressVisual> Could not initialize — missing cooldownRemapPanel. This warning can safely be ignored if RiskUI is installed.");
				return;
			}
			GameObject gameObject = ((Component)__instance.skillIcons[0].cooldownRemapPanel).gameObject;
			EquipmentIcon[] equipmentIcons = __instance.equipmentIcons;
			for (int i = 0; i < equipmentIcons.Length; i++)
			{
				EquipmentCooldownPanel.Init(equipmentIcons[i], gameObject);
			}
		}
	}
	[HarmonyPatch]
	internal static class EquipmentDroneUseHeldEquipmentNameInAllyCard
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(AllyCardController), "LateUpdate")]
		private static void AllyCardController_LateUpdate(AllyCardController __instance)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Config.RenameEquipmentDrones || !Object.op_Implicit((Object)(object)__instance.sourceMaster) || !Object.op_Implicit((Object)(object)__instance.sourceMaster.inventory))
			{
				return;
			}
			EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(__instance.sourceMaster.inventory.currentEquipmentIndex);
			if ((Object)(object)equipmentDef == (Object)null)
			{
				return;
			}
			string @string = Language.GetString(equipmentDef.nameToken);
			if (!(((TMP_Text)__instance.nameLabel).text == @string))
			{
				CharacterBody body = __instance.sourceMaster.GetBody();
				if (!((Object)(object)body == (Object)null) && !(body.baseNameToken != "EQUIPMENTDRONE_BODY_NAME"))
				{
					((TMP_Text)__instance.nameLabel).text = Language.GetString(equipmentDef.nameToken);
				}
			}
		}
	}
	[HarmonyPatch]
	public static class FullerDescriptions
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemIcon), "SetItemIndex")]
		[HarmonyPatch(new Type[]
		{
			typeof(ItemIndex),
			typeof(int),
			typeof(float)
		})]
		private static void ItemIcon_SetItemIndex(ItemIcon __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Config.FullerItemDescriptions)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef(__instance.itemIndex);
				if (!((Object)(object)itemDef == (Object)null) && !((Object)(object)__instance.tooltipProvider == (Object)null))
				{
					__instance.tooltipProvider.overrideBodyText = GetCombinedDescription(itemDef.descriptionToken, itemDef.pickupToken);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EquipmentIcon), "SetDisplayData")]
		private static void EquipmentIcon_SetDisplayData(EquipmentIcon __instance)
		{
			if (Plugin.Config.FullerEquipmentDescriptions)
			{
				EquipmentDef equipmentDef = __instance.currentDisplayData.equipmentDef;
				if (!((Object)(object)equipmentDef == (Object)null) && !((Object)(object)__instance.tooltipProvider == (Object)null))
				{
					StringBuilder stringBuilder = new StringBuilder(GetCombinedDescription(equipmentDef.descriptionToken, equipmentDef.pickupToken));
					stringBuilder.AppendLine().AppendLine().Append(GetEquipmentCooldown(equipmentDef, __instance.targetInventory));
					__instance.tooltipProvider.overrideBodyText = stringBuilder.ToString();
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GenericNotification), "SetItem")]
		private static void GenericNotification_SetItem(GenericNotification __instance, ItemDef itemDef)
		{
			if (Plugin.Config.FullerItemDescriptions && Plugin.Config.FullerDescriptionsOnPickUp)
			{
				__instance.descriptionText.token = GetCombinedDescription(itemDef.descriptionToken, itemDef.pickupToken);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GenericNotification), "SetEquipment")]
		private static void GenericNotification_SetEquipment(GenericNotification __instance, EquipmentDef equipmentDef)
		{
			if (Plugin.Config.FullerEquipmentDescriptions && Plugin.Config.FullerDescriptionsOnPickUp)
			{
				__instance.descriptionText.token = GetCombinedDescription(equipmentDef.descriptionToken, equipmentDef.pickupToken);
			}
		}

		public static string GetCombinedDescription(string descriptionToken, string pickupToken)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string @string = Language.GetString(descriptionToken);
			string string2 = Language.GetString(pickupToken);
			if (@string != descriptionToken && @string != string2)
			{
				stringBuilder.AppendLine("<style=cStack>" + string2 + "</style>");
				stringBuilder.AppendLine();
				stringBuilder.Append(@string);
			}
			else
			{
				stringBuilder.Append(string2);
			}
			return stringBuilder.ToString();
		}

		public static string GetEquipmentCooldown(EquipmentDef equipment, Inventory inventory)
		{
			if ((Object)(object)inventory == (Object)null)
			{
				return $"Cooldown: <style=cIsDamage>{equipment.cooldown:0.###}s</style>";
			}
			StringBuilder stringBuilder = new StringBuilder();
			float num = inventory.CalculateEquipmentCooldownScale();
			stringBuilder.Append($"Cooldown: <style=cIsDamage>{equipment.cooldown * num:0.###}s</style>");
			if (num < 1f)
			{
				stringBuilder.Append($" <style=cStack>({equipment.cooldown}×<style=cIsUtility>{num:0.###%}</style>)</style>");
			}
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch]
	internal static class PickupPickerTooltips
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(PickupPickerPanel), "SetPickupOptions")]
		private static void PickupPickerPanel_SetPickupOptions(PickupPickerPanel __instance, Option[] options)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Config.CommandMenuItemTooltips)
			{
				return;
			}
			for (int i = 0; i < options.Length; i++)
			{
				TooltipProvider val = TooltipHelper.AddTooltipProvider(((Component)__instance.buttonAllocator.elements[i]).GetComponent<Graphic>(), suppressLogs: true);
				PickupDef pickupDef = PickupCatalog.GetPickupDef(((Option)(ref options[i])).pickupIndex);
				ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex);
				bool flag = (Object)(object)itemDef != (Object)null;
				val.titleColor = pickupDef.darkColor;
				val.titleToken = (flag ? itemDef.nameToken : equipmentDef.nameToken);
				val.bodyToken = (flag ? itemDef.descriptionToken : equipmentDef.descriptionToken);
				if (flag)
				{
					val.overrideBodyText = FullerDescriptions.GetCombinedDescription(val.bodyToken, itemDef.pickupToken);
				}
				else
				{
					val.overrideBodyText = FullerDescriptions.GetCombinedDescription(val.bodyToken, equipmentDef.pickupToken) + "\n\n" + FullerDescriptions.GetEquipmentCooldown(equipmentDef, null);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class RunDifficultyTooltip
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CurrentDifficultyIconController), "Start")]
		private static void CurrentDifficultyIconController_Start(CurrentDifficultyIconController __instance)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Config.RunDifficultyTooltip && (Object)(object)Run.instance != (Object)null)
			{
				TooltipProvider obj = TooltipHelper.AddTooltipProvider(((Component)__instance).GetComponent<Graphic>());
				DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(Run.instance.selectedDifficulty);
				obj.titleColor = difficultyDef.color;
				obj.titleToken = difficultyDef.nameToken;
				obj.bodyToken = difficultyDef.descriptionToken;
			}
		}
	}
	[HarmonyPatch]
	internal static class ScoreboardShowChat
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ChatBox), "UpdateFade")]
		private static void ChatBox_UpdateFade(ChatBox __instance)
		{
			if (Plugin.Config.ScoreboardShowChat && (Object)(object)__instance.fadeGroup != (Object)null)
			{
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				Player val = ((firstLocalUser != null) ? firstLocalUser.inputPlayer : null);
				if (val != null && val.GetButton("info"))
				{
					__instance.fadeGroup.alpha = 1f;
				}
			}
		}
	}
}
namespace HUDdleUP.Railgunner
{
	internal sealed class RailgunnerAccuracyPanel : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private static HUD hud;

		private static ReloadAccuracy reloadAccuracy;

		private static WeakPointAccuracy weakPointAccuracy;

		private HUDPanel panel;

		private TextMeshProUGUI display;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
			if (reloadAccuracy != null)
			{
				reloadAccuracy.Unhook();
				reloadAccuracy = null;
			}
			if (weakPointAccuracy != null)
			{
				weakPointAccuracy.Unhook();
				weakPointAccuracy = null;
			}
		}

		private static void Init(HUD hud, ref bool _)
		{
			//IL_004f: 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)
			if (!Plugin.Config.RailgunnerAccuracyPanel || (Object)(object)RailgunnerAccuracyPanel.hud != (Object)null)
			{
				return;
			}
			ObjectivePanelController componentInChildren = ((Component)hud).GetComponentInChildren<ObjectivePanelController>();
			if (!Object.op_Implicit((Object)(object)componentInChildren) || (Object)(object)hud.localUserViewer.cachedBody == (Object)null)
			{
				return;
			}
			RailgunnerAccuracyPanel.hud = hud;
			if (hud.localUserViewer.cachedBody.bodyIndex != BodyCatalog.FindBodyIndex("RailgunnerBody"))
			{
				Plugin.Logger.LogDebug((object)"Local user is not Railgunner, skipping RailgunnerAccuracyPanel initialization.");
				return;
			}
			if (reloadAccuracy == null)
			{
				reloadAccuracy = new ReloadAccuracy();
				reloadAccuracy.Hook();
			}
			if (weakPointAccuracy == null)
			{
				weakPointAccuracy = new WeakPointAccuracy();
				weakPointAccuracy.Hook();
			}
			HUDPanel hUDPanel = HUDPanel.ClonePanel(componentInChildren, "RailgunnerAccuracyPanel");
			((Component)hud).gameObject.AddComponent<RailgunnerAccuracyPanel>().panel = hUDPanel;
			Plugin.Logger.LogDebug((object)"Initialized RailgunnerAccuracyPanel.");
		}

		private void Start()
		{
			((TMP_Text)panel.label).text = "Accuracy:";
			display = panel.AddTextComponent("Accuracy Tracker");
		}

		private void Update()
		{
			if (reloadAccuracy != null)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine(reloadAccuracy.ToString());
				stringBuilder.AppendLine();
				stringBuilder.AppendLine(weakPointAccuracy.ToString());
				((TMP_Text)display).text = stringBuilder.ToString();
			}
		}
	}
	internal sealed class ReloadAccuracy
	{
		private static readonly MethodInfo AttemptBoost = typeof(Reloading).GetMethod("AttemptBoost", BindingFlags.Instance | BindingFlags.Public);

		private readonly string labelColor = "#" + ColorUtility.ToHtmlStringRGB(DamageColor.FindColor((DamageColorIndex)12));

		private int totalReloads;

		private int perfectReloads;

		private int totalReloadsStage;

		private int perfectReloadsStage;

		private int consecutive;

		private int consecutiveBest;

		private Hook OnReloadAttemptBoost;

		public void Hook()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			MethodInfo method = typeof(ReloadAccuracy).GetMethod("RecordReload", BindingFlags.Instance | BindingFlags.NonPublic);
			OnReloadAttemptBoost = new Hook((MethodBase)AttemptBoost, method, (object)this);
			Stage.onStageStartGlobal += OnStageStart;
		}

		public void Unhook()
		{
			OnReloadAttemptBoost.Dispose();
			Stage.onStageStartGlobal -= OnStageStart;
		}

		private bool RecordReload(Func<Reloading, bool> orig, Reloading self)
		{
			bool num = orig(self);
			if (num)
			{
				perfectReloads++;
				perfectReloadsStage++;
				consecutive++;
			}
			else
			{
				if (consecutive > consecutiveBest)
				{
					consecutiveBest = consecutive;
				}
				consecutive = 0;
			}
			totalReloads++;
			totalReloadsStage++;
			return num;
		}

		private void OnStageStart(Stage _)
		{
			totalReloadsStage = 0;
			perfectReloadsStage = 0;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<style=cStack>> </style><color=" + labelColor + ">Perfect Reloads</color><style=cStack>: </style>");
			if (totalReloads == 0)
			{
				stringBuilder.Append("<style=cStack>-.--%</style>");
			}
			else
			{
				stringBuilder.Append($"{(float)perfectReloads / (float)totalReloads:0.00%}");
			}
			stringBuilder.AppendLine();
			stringBuilder.Append("<style=cStack>   > this stage: </style>");
			if (totalReloadsStage == 0)
			{
				stringBuilder.Append("<style=cStack>-.--%</style>");
			}
			else
			{
				stringBuilder.Append($"{(float)perfectReloadsStage / (float)totalReloadsStage:0.00%}");
			}
			stringBuilder.AppendLine($"<style=cStack> ({perfectReloadsStage}/{totalReloadsStage})</style>");
			stringBuilder.Append($"<style=cStack>   > consecutive: </style>{consecutive}<style=cStack> ({consecutiveBest})</style>");
			return stringBuilder.ToString();
		}
	}
	internal sealed class WeakPointAccuracy
	{
		private readonly string labelColor = "#" + ColorUtility.ToHtmlStringRGB(DamageColor.FindColor((DamageColorIndex)5));

		private int shots;

		private int weakPointHits;

		private int consecutive;

		private int consecutiveBest;

		public void Hook()
		{
			BaseFireSnipe.onFireSnipe += Snipe_onFireSnipe;
			BaseFireSnipe.onWeakPointHit += Snipe_onWeakPointHit;
			BaseFireSnipe.onWeakPointMissed += Snipe_onWeakPointMissed;
			Stage.onStageStartGlobal += OnStageStart;
		}

		public void Unhook()
		{
			BaseFireSnipe.onFireSnipe -= Snipe_onFireSnipe;
			BaseFireSnipe.onWeakPointHit -= Snipe_onWeakPointHit;
			BaseFireSnipe.onWeakPointMissed -= Snipe_onWeakPointMissed;
			Stage.onStageStartGlobal -= OnStageStart;
		}

		private void Snipe_onFireSnipe(BaseFireSnipe snipe)
		{
			if (((EntityState)snipe).isAuthority)
			{
				shots++;
			}
		}

		private void Snipe_onWeakPointHit(DamageInfo _)
		{
			weakPointHits++;
			consecutive++;
		}

		private void Snipe_onWeakPointMissed()
		{
			if (consecutive > consecutiveBest)
			{
				consecutiveBest = consecutive;
			}
			consecutive = 0;
		}

		private void OnStageStart(Stage _)
		{
			shots = 0;
			weakPointHits = 0;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<style=cStack>> </style><color=" + labelColor + ">Weak Points Hit</color><style=cStack>: </style>");
			stringBuilder.AppendLine($"{weakPointHits}<style=cStack> : {shots}</style>");
			stringBuilder.Append($"<style=cStack>   > consecutive: </style>{consecutive}<style=cStack> ({consecutiveBest})</style>");
			return stringBuilder.ToString();
		}
	}
}
namespace HUDdleUP.Multiplayer
{
	internal sealed class ConnectionPanel : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private const float updateFrequency = 0.2f;

		private float lastUpdateTimestamp;

		private static HUD hud;

		private HUDPanel panel;

		private TextMeshProUGUI display;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
		}

		public static void Init(HUD hud, ref bool _)
		{
			if (Plugin.Config.MultiplayerConnectionPanel && NetworkUser.readOnlyInstancesList.Count > 1 && !((Object)(object)ConnectionPanel.hud != (Object)null))
			{
				ObjectivePanelController componentInChildren = ((Component)hud).GetComponentInChildren<ObjectivePanelController>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					ConnectionPanel.hud = hud;
					HUDPanel hUDPanel = HUDPanel.ClonePanel(componentInChildren, "ConnectionPanel");
					((Component)hud).gameObject.AddComponent<ConnectionPanel>().panel = hUDPanel;
					Plugin.Logger.LogDebug((object)"Initialized ConnectionPanel");
				}
			}
		}

		private void Start()
		{
			((TMP_Text)panel.label).text = "Connection:";
			display = panel.AddTextComponent("Multiplayer Connection");
		}

		private void Update()
		{
			bool activeSelf = hud.scoreboardPanel.activeSelf;
			panel.gameObject.SetActive(activeSelf);
			if (activeSelf && !(Time.unscaledTime - lastUpdateTimestamp < 0.2f))
			{
				lastUpdateTimestamp = Time.unscaledTime;
				((TMP_Text)display).text = "<style=cStack>> <style=cIsUtility>Ping (round-trip time)</style>:</style>\n" + (NetworkServer.active ? GetPingHost() : GetPingClient());
			}
		}

		private string GetPingClient()
		{
			int num = -1;
			if (NetworkClient.active && Object.op_Implicit((Object)(object)NetworkManagerSystem.singleton))
			{
				NetworkConnection connection = ((NetworkManager)NetworkManagerSystem.singleton).client.connection;
				if (connection != null)
				{
					num = (int)RttManager.GetConnectionRTTInMilliseconds(connection);
				}
			}
			return $"<style=cStack>   > You are client</style>\n<style=cStack>      > <style=cSub>{num}</style> ms</style>";
		}

		private string GetPingHost()
		{
			StringBuilder stringBuilder = new StringBuilder("<style=cStack>   > You are host</style>");
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((NetworkBehaviour)readOnlyInstances).hasAuthority)
				{
					int num = ((((NetworkBehaviour)readOnlyInstances).connectionToClient != null) ? ((int)RttManager.GetConnectionRTTInMilliseconds(((NetworkBehaviour)readOnlyInstances).connectionToClient)) : (-1));
					stringBuilder.AppendLine().Append($"<style=cStack>   > <style=cUserSetting>{readOnlyInstances.userName}</style>: <style=cSub>{num}</style> ms</style>");
				}
			}
			return stringBuilder.ToString();
		}
	}
}
namespace HUDdleUP.Loot
{
	internal sealed class DronePanel : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private static HUD hud;

		private HUDPanel panel;

		private TextMeshProUGUI display;

		private InteractablesTracker tracker;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
		}

		private static void Init(HUD hud, ref bool _)
		{
			if (Plugin.Config.DronePanel && !((Object)(object)DronePanel.hud != (Object)null))
			{
				ObjectivePanelController componentInChildren = ((Component)hud).GetComponentInChildren<ObjectivePanelController>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					DronePanel.hud = hud;
					HUDPanel hUDPanel = HUDPanel.ClonePanel(componentInChildren, "DronePanel");
					((Component)hud).gameObject.AddComponent<DronePanel>().panel = hUDPanel;
					Plugin.Logger.LogDebug((object)"Initialized DronePanel.");
				}
			}
		}

		private void Start()
		{
			((TMP_Text)panel.label).text = "Drones:";
			display = panel.AddTextComponent("Drone Tracker");
			tracker = ((Component)hud).GetComponent<InteractablesTracker>();
		}

		private void Update()
		{
			bool activeSelf = hud.scoreboardPanel.activeSelf;
			panel.gameObject.SetActive(activeSelf);
			if (activeSelf)
			{
				((TMP_Text)display).text = GenerateText();
			}
		}

		public string GenerateText()
		{
			if ((Object)(object)tracker == (Object)null)
			{
				return "<style=cDeath>error: missing interactables tracker</style>";
			}
			if (tracker.interactables == null)
			{
				return "<style=cDeath>error: missing interactables</style>";
			}
			Interactables interactables = tracker.interactables;
			bool flag = false;
			bool teleporterFullyCharged = false;
			if ((Object)(object)TeleporterInteraction.instance != (Object)null)
			{
				flag = TeleporterInteraction.instance.monstersCleared;
				teleporterFullyCharged = TeleporterInteraction.instance.isCharged;
			}
			StringBuilder stringBuilder = new StringBuilder();
			if (interactables.gunnerTurrets > 0)
			{
				stringBuilder.AppendLine(FormatLine("style", "cIsUtility", Language.GetString("TURRET1_BODY_NAME"), interactables.gunnerTurrets));
			}
			GenerateDronesText(interactables, flag, teleporterFullyCharged, stringBuilder);
			if (interactables.droneTerminals > 0)
			{
				stringBuilder.AppendLine(LootPanel.FormatLine("style", "cIsUtility", "DRONE_VENDOR_TERMINAL_NAME", interactables.droneTerminalsAvailable, interactables.droneTerminals));
			}
			if (flag)
			{
				bool flag2 = InstanceTracker.GetInstancesList<DroneCombinerController>().Count > 0;
				stringBuilder.AppendLine();
				stringBuilder.AppendLine(LootPanel.FormatLabel("<style=cSub>" + Language.GetString("DRONE_SCRAPPER_NAME") + "</style>") + (interactables.droneScrapperPresent ? "@" : "×"));
				stringBuilder.AppendLine(LootPanel.FormatLabel("<style=cSub>" + Language.GetString("DRONE_COMBINER_NAME") + "</style>") + (flag2 ? "@" : "×"));
			}
			return stringBuilder.ToString();
		}

		private static StringBuilder GenerateDronesText(Interactables interactables, bool teleporterBossDefeated, bool teleporterFullyCharged, StringBuilder sb)
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			if (interactables.drones > 0)
			{
				if (teleporterFullyCharged)
				{
					AppendDrone("DRONE_GUNNER_BODY_NAME", (ColorIndex)1, interactables.gunnerDrones, sb);
					AppendDrone("DRONE_HEALING_BODY_NAME", (ColorIndex)1, interactables.healingDrones, sb);
					AppendDrone("DRONE_HAULER_BODY_NAME", (ColorIndex)1, interactables.transportDrones, sb);
					AppendDrone("DRONE_JUNK_BODY_NAME", (ColorIndex)1, interactables.junkDrones, sb);
					AppendDrone("DRONE_MISSILE_BODY_NAME", (ColorIndex)2, interactables.missileDrones, sb);
					AppendDrone("FLAMEDRONE_BODY_NAME", (ColorIndex)2, interactables.incineratorDrones, sb);
					AppendDrone("EMERGENCYDRONE_BODY_NAME", (ColorIndex)2, interactables.emergencyDrones, sb);
					AppendDrone("DRONE_RECHARGE_BODY_NAME", (ColorIndex)2, interactables.barrierDrones, sb);
					AppendDrone("DRONE_CLEANUP_BODY_NAME", (ColorIndex)2, interactables.cleanupDrones, sb);
					AppendDrone("DRONE_JAILER_BODY_NAME", (ColorIndex)2, interactables.jailerDrones, sb);
					AppendDrone("DRONE_BOMBARDMENT_BODY_NAME", (ColorIndex)3, interactables.bombardmentDrones, sb);
					AppendDrone("DRONE_COPYCAT_BODY_NAME", (ColorIndex)3, interactables.freezeDrones, sb);
					AppendDrone("DRONE_MEGA_BODY_NAME", (ColorIndex)3, interactables.tc280Drones, sb);
					AppendDrone("EQUIPMENTDRONE_BODY_NAME", (ColorIndex)5, interactables.equipmentDrones, sb);
					return sb;
				}
				if (teleporterBossDefeated)
				{
					List<string> list = new List<string>();
					if (interactables.t1Drones > 0)
					{
						list.Add(Util.GenerateColoredString(interactables.t1Drones.ToString(), ColorCatalog.GetColor((ColorIndex)1)));
					}
					if (interactables.t2Drones > 0)
					{
						list.Add(Util.GenerateColoredString(interactables.t2Drones.ToString(), ColorCatalog.GetColor((ColorIndex)2)));
					}
					if (interactables.t3Drones > 0)
					{
						list.Add(Util.GenerateColoredString(interactables.t3Drones.ToString(), ColorCatalog.GetColor((ColorIndex)3)));
					}
					if (interactables.equipmentDrones > 0)
					{
						list.Add(Util.GenerateColoredString(interactables.equipmentDrones.ToString(), ColorCatalog.GetColor((ColorIndex)5)));
					}
					string text = string.Join(" · ", list);
					if (!string.IsNullOrEmpty(text))
					{
						sb.AppendLine(LootPanel.FormatLabel("<style=cIsUtility>Drones</style>") + "<style=cStack>" + text + "</style>");
					}
					return sb;
				}
			}
			return sb.AppendLine(FormatLine("style", "cIsUtility", "Drones", interactables.drones));
		}

		private static StringBuilder AppendDrone(string nameToken, ColorIndex color, int count, StringBuilder sb)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (count > 0)
			{
				sb.AppendLine($"{LootPanel.FormatLabel(Util.GenerateColoredString(Language.GetString(nameToken), ColorCatalog.GetColor(color)))}{count}");
			}
			return sb;
		}

		private static string FormatLine(string tagKey, string tagValue, string label, int count)
		{
			return string.Format("{0}{1}", LootPanel.FormatLabel("<" + tagKey + "=" + tagValue + ">" + label + "</" + tagKey + ">"), count);
		}
	}
	public sealed record Interactables
	{
		public int drones => gunnerDrones + healingDrones + missileDrones + incineratorDrones + emergencyDrones + tc280Drones + equipmentDrones + transportDrones + junkDrones + barrierDrones + cleanupDrones + jailerDrones + bombardmentDrones + freezeDrones;

		public int t1Drones => gunnerDrones + healingDrones + transportDrones + junkDrones;

		public int t2Drones => missileDrones + incineratorDrones + emergencyDrones + barrierDrones + cleanupDrones + jailerDrones;

		public int t3Drones => tc280Drones + bombardmentDrones + freezeDrones;

		public readonly int chests;

		public readonly int chestsAvailable;

		public readonly int terminals;

		public readonly int terminalsAvailable;

		public readonly int chanceShrines;

		public readonly int chanceShrinesAvailable;

		public readonly int shrineChances;

		public readonly int shrineChancesAvailable;

		public readonly int lockboxes;

		public readonly int lockboxesAvailable;

		public readonly int adaptiveChests;

		public readonly int adaptiveChestsAvailable;

		public readonly int voids;

		public readonly int voidsAvailable;

		public readonly int cloakedChests;

		public readonly int cloakedChestsAvailable;

		public readonly int equipment;

		public readonly int equipmentAvailable;

		public readonly int lunarPods;

		public readonly int lunarPodsAvailable;

		public readonly bool cleansingPoolPresent;

		public readonly int whiteTakers;

		public readonly int greenTakers;

		public readonly int redTakers;

		public readonly int yellowTakers;

		public readonly int gunnerTurrets;

		public readonly int gunnerDrones;

		public readonly int healingDrones;

		public readonly int missileDrones;

		public readonly int incineratorDrones;

		public readonly int emergencyDrones;

		public readonly int tc280Drones;

		public readonly int equipmentDrones;

		public readonly int transportDrones;

		public readonly int junkDrones;

		public readonly int barrierDrones;

		public readonly int cleanupDrones;

		public readonly int jailerDrones;

		public readonly int bombardmentDrones;

		public readonly int freezeDrones;

		public readonly int droneTerminals;

		public readonly int droneTerminalsAvailable;

		public readonly bool droneScrapperPresent;

		public Interactables()
			: this(InstanceTracker.GetInstancesList<PurchaseInteraction>())
		{
		}

		public Interactables(List<PurchaseInteraction> interactions)
		{
			//IL_07ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0816: Expected I4, but got Unknown
			for (int i = 0; i < interactions.Count; i++)
			{
				switch (interactions[i].displayNameToken)
				{
				case "CHEST1_NAME":
				case "CHEST2_NAME":
				case "CATEGORYCHEST_UTILITY_NAME":
				case "CATEGORYCHEST2_DAMAGE_NAME":
				case "CATEGORYCHEST_HEALING_NAME":
				case "CATEGORYCHEST_DAMAGE_NAME":
				case "CATEGORYCHEST2_HEALING_NAME":
				case "CATEGORYCHEST2_UTILITY_NAME":
				case "GOLDCHEST_NAME":
					chests++;
					if (interactions[i].available)
					{
						chestsAvailable++;
					}
					break;
				case "EQUIPMENTBARREL_NAME":
					equipment++;
					if (interactions[i].available)
					{
						equipmentAvailable++;
					}
					break;
				case "MULTISHOP_TERMINAL_NAME":
					if (((Object)interactions[i]).name.Contains("Equipment"))
					{
						equipment++;
						if (interactions[i].available)
						{
							equipmentAvailable++;
						}
					}
					else
					{
						terminals++;
						if (interactions[i].available)
						{
							terminalsAvailable++;
						}
					}
					break;
				case "SHRINE_CHANCE_NAME":
					chanceShrines++;
					if (interactions[i].available)
					{
						chanceShrinesAvailable++;
					}
					if (NetworkServer.active)
					{
						ShrineChanceBehavior component = ((Component)interactions[i]).GetComponent<ShrineChanceBehavior>();
						shrineChances += component.maxPurchaseCount;
						shrineChancesAvailable += component.maxPurchaseCount - component.successfulPurchaseCount;
					}
					break;
				case "VOIDLOCKBOX_NAME":
				case "LOCKBOX_NAME":
					lockboxes++;
					if (interactions[i].available)
					{
						lockboxesAvailable++;
					}
					break;
				case "CASINOCHEST_NAME":
					adaptiveChests++;
					if (interactions[i].available)
					{
						adaptiveChestsAvailable++;
					}
					break;
				case "VOID_TRIPLE_NAME":
				case "VOID_CHEST_NAME":
					voids++;
					if (interactions[i].available)
					{
						voidsAvailable++;
					}
					break;
				case "CHEST1_STEALTHED_NAME":
					cloakedChests++;
					if (interactions[i].available)
					{
						cloakedChestsAvailable++;
					}
					break;
				case "DUPLICATOR_WILD_NAME":
				case "BAZAAR_CAULDRON_NAME":
				case "DUPLICATOR_NAME":
				case "DUPLICATOR_MILITARY_NAME":
				{
					CostTypeIndex costType = interactions[i].costType;
					switch (costType - 4)
					{
					case 0:
						whiteTakers++;
						break;
					case 1:
						greenTakers++;
						break;
					case 2:
						redTakers++;
						break;
					case 6:
						yellowTakers++;
						break;
					}
					break;
				}
				case "SHRINE_CLEANSE_NAME":
					cleansingPoolPresent = true;
					break;
				case "LUNAR_CHEST_NAME":
					lunarPods++;
					if (interactions[i].available)
					{
						lunarPodsAvailable++;
					}
					break;
				case "TURRET1_INTERACTABLE_NAME":
					gunnerTurrets++;
					break;
				case "DRONE_GUNNER_INTERACTABLE_NAME":
					gunnerDrones++;
					break;
				case "DRONE_HEALING_INTERACTABLE_NAME":
					healingDrones++;
					break;
				case "DRONE_MISSILE_INTERACTABLE_NAME":
					missileDrones++;
					break;
				case "FLAMEDRONE_INTERACTABLE_NAME":
					incineratorDrones++;
					break;
				case "EMERGENCYDRONE_INTERACTABLE_NAME":
					emergencyDrones++;
					break;
				case "DRONE_MEGA_INTERACTABLE_NAME":
					tc280Drones++;
					break;
				case "EQUIPMENTDRONE_INTERACTABLE_NAME":
					equipmentDrones++;
					break;
				case "DRONE_HAULER_INTERACTABLE_NAME":
					transportDrones++;
					break;
				case "DRONE_JUNK_INTERACTABLE_NAME":
					junkDrones++;
					break;
				case "DRONE_RECHARGE_INTERACTABLE_NAME":
					barrierDrones++;
					break;
				case "DRONE_CLEANUP_INTERACTABLE_NAME":
					cleanupDrones++;
					break;
				case "DRONE_JAILER_INTERACTABLE_NAME":
					jailerDrones++;
					break;
				case "DRONE_BOMBARDMENT_INTERACTABLE_NAME":
					bombardmentDrones++;
					break;
				case "DRONE_COPYCAT_INTERACTABLE_NAME":
					freezeDrones++;
					break;
				case "DRONE_VENDOR_TERMINAL_NAME":
					droneTerminals++;
					if (interactions[i].available)
					{
						droneTerminalsAvailable++;
					}
					break;
				case "DRONE_SCRAPPER_NAME":
					droneScrapperPresent = true;
					break;
				}
			}
		}

		[CompilerGenerated]
		private bool PrintMembers(StringBuilder builder)
		{
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("chests = ");
			builder.Append(chests.ToString());
			builder.Append(", chestsAvailable = ");
			builder.Append(chestsAvailable.ToString());
			builder.Append(", terminals = ");
			builder.Append(terminals.ToString());
			builder.Append(", terminalsAvailable = ");
			builder.Append(terminalsAvailable.ToString());
			builder.Append(", chanceShrines = ");
			builder.Append(chanceShrines.ToString());
			builder.Append(", chanceShrinesAvailable = ");
			builder.Append(chanceShrinesAvailable.ToString());
			builder.Append(", shrineChances = ");
			builder.Append(shrineChances.ToString());
			builder.Append(", shrineChancesAvailable = ");
			builder.Append(shrineChancesAvailable.ToString());
			builder.Append(", lockboxes = ");
			builder.Append(lockboxes.ToString());
			builder.Append(", lockboxesAvailable = ");
			builder.Append(lockboxesAvailable.ToString());
			builder.Append(", adaptiveChests = ");
			builder.Append(adaptiveChests.ToString());
			builder.Append(", adaptiveChestsAvailable = ");
			builder.Append(adaptiveChestsAvailable.ToString());
			builder.Append(", voids = ");
			builder.Append(voids.ToString());
			builder.Append(", voidsAvailable = ");
			builder.Append(voidsAvailable.ToString());
			builder.Append(", cloakedChests = ");
			builder.Append(cloakedChests.ToString());
			builder.Append(", cloakedChestsAvailable = ");
			builder.Append(cloakedChestsAvailable.ToString());
			builder.Append(", equipment = ");
			builder.Append(equipment.ToString());
			builder.Append(", equipmentAvailable = ");
			builder.Append(equipmentAvailable.ToString());
			builder.Append(", lunarPods = ");
			builder.Append(lunarPods.ToString());
			builder.Append(", lunarPodsAvailable = ");
			builder.Append(lunarPodsAvailable.ToString());
			builder.Append(", cleansingPoolPresent = ");
			builder.Append(cleansingPoolPresent.ToString());
			builder.Append(", whiteTakers = ");
			builder.Append(whiteTakers.ToString());
			builder.Append(", greenTakers = ");
			builder.Append(greenTakers.ToString());
			builder.Append(", redTakers = ");
			builder.Append(redTakers.ToString());
			builder.Append(", yellowTakers = ");
			builder.Append(yellowTakers.ToString());
			builder.Append(", gunnerTurrets = ");
			builder.Append(gunnerTurrets.ToString());
			builder.Append(", gunnerDrones = ");
			builder.Append(gunnerDrones.ToString());
			builder.Append(", healingDrones = ");
			builder.Append(healingDrones.ToString());
			builder.Append(", missileDrones = ");
			builder.Append(missileDrones.ToString());
			builder.Append(", incineratorDrones = ");
			builder.Append(incineratorDrones.ToString());
			builder.Append(", emergencyDrones = ");
			builder.Append(emergencyDrones.ToString());
			builder.Append(", tc280Drones = ");
			builder.Append(tc280Drones.ToString());
			builder.Append(", equipmentDrones = ");
			builder.Append(equipmentDrones.ToString());
			builder.Append(", transportDrones = ");
			builder.Append(transportDrones.ToString());
			builder.Append(", junkDrones = ");
			builder.Append(junkDrones.ToString());
			builder.Append(", barrierDrones = ");
			builder.Append(barrierDrones.ToString());
			builder.Append(", cleanupDrones = ");
			builder.Append(cleanupDrones.ToString());
			builder.Append(", jailerDrones = ");
			builder.Append(jailerDrones.ToString());
			builder.Append(", bombardmentDrones = ");
			builder.Append(bombardmentDrones.ToString());
			builder.Append(", freezeDrones = ");
			builder.Append(freezeDrones.ToString());
			builder.Append(", drones = ");
			builder.Append(drones.ToString());
			builder.Append(", t1Drones = ");
			builder.Append(t1Drones.ToString());
			builder.Append(", t2Drones = ");
			builder.Append(t2Drones.ToString());
			builder.Append(", t3Drones = ");
			builder.Append(t3Drones.ToString());
			builder.Append(", droneTerminals = ");
			builder.Append(droneTerminals.ToString());
			builder.Append(", droneTerminalsAvailable = ");
			builder.Append(droneTerminalsAvailable.ToString());
			builder.Append(", droneScrapperPresent = ");
			builder.Append(droneScrapperPresent.ToString());
			return true;
		}
	}
	internal sealed class InteractablesTracker : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private const float updateFrequency = 1f / 30f;

		private float lastUpdateTimestamp;

		private static HUD hud;

		internal Interactables interactables;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
		}

		private static void Init(HUD hud, ref bool _)
		{
			if (Plugin.Config.TrackInteractables && !((Object)(object)InteractablesTracker.hud != (Object)null))
			{
				InteractablesTracker.hud = hud;
				((Component)hud).gameObject.AddComponent<InteractablesTracker>();
				Plugin.Logger.LogDebug((object)"Initialized InteractablesTracker.");
			}
		}

		private void Update()
		{
			if (hud.scoreboardPanel.activeSelf && !(Time.unscaledTime - lastUpdateTimestamp < 1f / 30f))
			{
				lastUpdateTimestamp = Time.unscaledTime;
				interactables = new Interactables();
			}
		}
	}
	internal sealed class LootPanel : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private static HUD hud;

		private HUDPanel panel;

		private TextMeshProUGUI display;

		private InteractablesTracker tracker;

		private const float scrapperSearchFrequency = 0.25f;

		private float lastScrapperSearchTimestamp;

		private bool scrapperPresent;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
		}

		private static void Init(HUD hud, ref bool _)
		{
			if (Plugin.Config.LootPanel && !((Object)(object)LootPanel.hud != (Object)null))
			{
				ObjectivePanelController componentInChildren = ((Component)hud).GetComponentInChildren<ObjectivePanelController>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					LootPanel.hud = hud;
					HUDPanel hUDPanel = HUDPanel.ClonePanel(componentInChildren, "LootPanel");
					((Component)hud).gameObject.AddComponent<LootPanel>().panel = hUDPanel;
					Plugin.Logger.LogDebug((object)"Initialized LootPanel.");
				}
			}
		}

		private void Start()
		{
			((TMP_Text)panel.label).text = "Loot:";
			display = panel.AddTextComponent("Loot Tracker");
			tracker = ((Component)hud).GetComponent<InteractablesTracker>();
		}

		private void Update()
		{
			bool activeSelf = hud.scoreboardPanel.activeSelf;
			panel.gameObject.SetActive(activeSelf);
			if (activeSelf)
			{
				if (Time.unscaledTime - lastScrapperSearchTimestamp >= 0.25f)
				{
					lastScrapperSearchTimestamp = Time.unscaledTime;
					scrapperPresent = (Object)(object)Object.FindObjectOfType<ScrapperController>() != (Object)null;
				}
				((TMP_Text)display).text = GenerateText();
			}
		}

		public string GenerateText()
		{
			if ((Object)(object)tracker == (Object)null)
			{
				return "<style=cDeath>error: missing interactables tracker</style>";
			}
			if (tracker.interactables == null)
			{
				return "<style=cDeath>error: missing interactables</style>";
			}
			Interactables interactables = tracker.interactables;
			string tagValue = "#" + ColorCatalog.GetColorHexString((ColorIndex)5);
			StringBuilder stringBuilder = new StringBuilder();
			if (interactables.terminals > 0)
			{
				stringBuilder.AppendLine(FormatLine("style", "cIsUtility", "MULTISHOP_TERMINAL_NAME", interactables.terminalsAvailable, interactables.terminals));
			}
			if (interactables.chests > 0)
			{
				stringBuilder.AppendLine(FormatLine("style", "cIsDamage", "CHEST1_NAME", interactables.chestsAvailable, interactables.chests));
			}
			if (interactables.adaptiveChests > 0)
			{
				stringBuilder.AppendLine(FormatLine("style", "cArtifact", "CASINOCHEST_NAME", interactables.adaptiveChestsAvailable, interactables.adaptiveChests));
			}
			if (interactables.chanceShrines > 0)
			{
				stringBuilder.AppendLine(NetworkServer.active ? FormatLine("style", "cShrine", "SHRINE_CHANCE_NAME", interactables.shrineChancesAvailable, interactables.shrineChances, interactables.chanceShrinesAvailable) : FormatLine("style", "cShrine", "SHRINE_CHANCE_NAME", interactables.chanceShrinesAvailable, interactables.chanceShrines));
			}
			if (interactables.equipment > 0)
			{
				stringBuilder.AppendLine(FormatLine("color", tagValue, "EQUIPMENTBARREL_NAME", interactables.equipmentAvailable, interactables.equipment));
			}
			if (interactables.lockboxes > 0)
			{
				stringBuilder.AppendLine(FormatLine("style", "cHumanObjective", "LOCKBOX_NAME", interactables.lockboxesAvailable, interactables.lockboxes));
			}
			if ((Object)(object)TeleporterInteraction.instance != (Object)null)
			{
				if (TeleporterInteraction.instance.monstersCleared)
				{
					string text = (interactables.cleansingPoolPresent ? " · <style=cLunarObjective>@</style>" : "");
					stringBuilder.AppendLine().AppendLine(FormatLabel("<style=cSub>" + Language.GetString("SCRAPPER_NAME") + "</style>") + (scrapperPresent ? "@" : "×") + text);
					AppendFabricators(interactables, stringBuilder);
					if (interactables.voids > 0)
					{
						stringBuilder.AppendLine(FormatLine("style", "cIsVoid", "VOID_CHEST_NAME", interactables.voidsAvailable, interactables.voids));
					}
					if (interactables.lunarPods > 0)
					{
						stringBuilder.AppendLine(FormatLine("style", "cLunarObjective", "LUNAR_CHEST_NAME", interactables.lunarPodsAvailable, interactables.lunarPods));
					}
				}
				if (TeleporterInteraction.instance.isCharged && interactables.cloakedChests > 0)
				{
					stringBuilder.AppendLine().AppendLine(FormatLine("style", "cLunarObjective", "CHEST1_STEALTHED_NAME", interactables.cloakedChestsAvailable, interactables.cloakedChests));
				}
			}
			stringBuilder.AppendLine().AppendLine(FormatEnemies());
			if ((Object)(object)TeleporterInteraction.instance != (Object)null && TeleporterInteraction.instance.shrineBonusStacks > 0)
			{
				stringBuilder.AppendLine($"<style=cStack>Invitations: <style=cIsUtility>{TeleporterInteraction.instance.shrineBonusStacks}</style></style>");
			}
			if (Object.op_Implicit((Object)(object)Stage.instance) && Object.op_Implicit((Object)(object)Stage.instance.sceneDef))
			{
				stringBuilder.AppendLine().AppendLine("<style=cStack>-- " + Language.GetString(Stage.instance.sceneDef.nameToken) + " --</style>");
			}
			return stringBuilder.ToString();
		}

		private static StringBuilder AppendFabricators(Interactables interactables, StringBuilder sb)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			if (interactables.whiteTakers > 0)
			{
				list.Add(Util.GenerateColoredString(interactables.whiteTakers.ToString(), ColorCatalog.GetColor((ColorIndex)1)));
			}
			if (interactables.greenTakers > 0)
			{
				list.Add(Util.GenerateColoredString(interactables.greenTakers.ToString(), ColorCatalog.GetColor((ColorIndex)2)));
			}
			if (interactables.redTakers > 0)
			{
				list.Add(Util.GenerateColoredString(interactables.redTakers.ToString(), ColorCatalog.GetColor((ColorIndex)3)));
			}
			if (interactables.yellowTakers > 0)
			{
				list.Add(Util.GenerateColoredString(interactables.yellowTakers.ToString(), ColorCatalog.GetColor((ColorIndex)13)));
			}
			string text = string.Join(" · ", list);
			if (!string.IsNullOrEmpty(text))
			{
				sb.AppendLine(FormatToken("DUPLICATOR_NAME", "style", "cStack") + "<style=cStack>" + text + "</style>");
			}
			return sb;
		}

		private static string FormatEnemies()
		{
			int count = TeamComponent.GetTeamMembers((TeamIndex)2).Count;
			int count2 = TeamComponent.GetTeamMembers((TeamIndex)3).Count;
			int count3 = TeamComponent.GetTeamMembers((TeamIndex)4).Count;
			List<string> list = new List<string>();
			if (count > 0)
			{
				list.Add($"<style=cSub>{count}</style>");
			}
			if (count2 > 0)
			{
				list.Add($"<style=cLunarObjective>{count2}</style>");
			}
			if (count3 > 0)
			{
				list.Add($"<style=cIsVoid>{count3}</style>");
			}
			string text = string.Join(" · ", list);
			return "<style=cStack>Enemies: " + (string.IsNullOrEmpty(text) ? "0" : text) + "</style>";
		}

		private static string FormatLine(string tagKey, string tagValue, string token, int available, int total, int meta)
		{
			return FormatToken(token, tagKey, tagValue) + FormatCounter(available, total, meta);
		}

		internal static string FormatLine(string tagKey, string tagValue, string token, int available, int total)
		{
			return FormatToken(token, tagKey, tagValue) + FormatCounter(available, total);
		}

		private static string FormatToken(string token, string tagKey, string tagValue)
		{
			return FormatLabel("<" + tagKey + "=" + tagValue + ">" + Language.GetString(token) + "</" + tagKey + ">");
		}

		internal static string FormatLabel(string label)
		{
			return "<style=cStack>> </style>" + label + "<style=cStack>:</style> ";
		}

		private static string FormatCounter(int available, int total, int meta)
		{
			return $"{FormatCounter(available, total)}<style=cStack><size=90%> ({meta})</size></style>";
		}

		private static string FormatCounter(int available, int total)
		{
			if (available != 0)
			{
				return $"{available}<style=cStack>/{total}</style>";
			}
			return $"<style=cSub>{available}</style><style=cStack>/{total}</style>";
		}
	}
}
namespace HUDdleUP.Bandit
{
	internal sealed class BanditComboPanel : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static ShouldHudDisplayDelegate <0>__Init;
		}

		private static HUD hud;

		private static ConsecutiveReset tracker;

		private HUDPanel panel;

		private TextMeshProUGUI display;

		public static void Hook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay += (ShouldHudDisplayDelegate)obj;
		}

		public static void Unhook()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Init;
			if (obj == null)
			{
				ShouldHudDisplayDelegate val = Init;
				<>O.<0>__Init = val;
				obj = (object)val;
			}
			HUD.shouldHudDisplay -= (ShouldHudDisplayDelegate)obj;
			if (tracker != null)
			{
				tracker.Unhook();
				tracker = null;
			}
		}

		private static void Init(HUD hud, ref bool _)
		{
			//IL_004f: 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)
			if (!Plugin.Config.BanditComboPanel || (Object)(object)BanditComboPanel.hud != (Object)null)
			{
				return;
			}
			ObjectivePanelController componentInChildren = ((Component)hud).GetComponentInChildren<ObjectivePanelController>();
			if (!Object.op_Implicit((Object)(object)componentInChildren) || (Object)(object)hud.localUserViewer.cachedBody == (Object)null)
			{
				return;
			}
			BanditComboPanel.hud = hud;
			if (hud.localUserViewer.cachedBody.bodyIndex != BodyCatalog.FindBodyIndex("Bandit2Body"))
			{
				Plugin.Logger.LogDebug((object)"Local user is not Bandit, skipping BanditComboPanel initialization.");
				return;
			}
			if (!ConsecutiveReset.HasRequiredSkill(hud.localUserViewer.cachedBody))
			{
				Plugin.Logger.LogDebug((object)"Local user is Bandit but does not have \"Lights Out\" selected, skipping BanditComboPanel initialization.");
				return;
			}
			if (tracker == null)
			{
				tracker = new ConsecutiveReset(hud.localUserViewer);
				tracker.Hook();
			}
			HUDPanel hUDPanel = HUDPanel.ClonePanel(componentInChildren, "BanditComboPanel");
			((Component)hud).gameObject.AddComponent<BanditComboPanel>().panel = hUDPanel;
			Plugin.Logger.LogDebug((object)"Initialized BanditComboPanel.");
		}

		private void Start()
		{
			((TMP_Text)panel.label).text = "Combo:";
			display = panel.AddTextComponent("Combo Tracker");
		}

		private void Update()
		{
			if (tracker != null)
			{
				((TMP_Text)display).text = tracker.ToString();
			}
		}

		private void FixedUpdate()
		{
			if (tracker != null)
			{
				tracker.FixedUpdate();
			}
		}
	}
	internal sealed class ConsecutiveReset
	{
		private const string banditSkullColour = "#40C5E4";

		private static readonly SkillDef requiredSkillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName("Bandit2.ResetRevolver"));

		private readonly LocalUser user;

		private CharacterBody _trackedBody;

		private bool waitingForKill;

		private int _resets;

		private int consecutive;

		private int consecutiveBest;

		private int totalShots;

		private int resetShots;

		private int totalShotsStage;

		private int resetShotsStage;

		private CharacterBody trackedBody
		{
			get
			{
				return _trackedBody;
			}
			set
			{
				if ((Object)(object)value != (Object)(object)_trackedBody)
				{
					if ((Object)(object)_trackedBody != (Object)null)
					{
						_trackedBody.onSkillActivatedAuthority -= Tracker_Start;
					}
					_trackedBody = value;
					if ((Object)(object)_trackedBody != (Object)null)
					{
						_trackedBody.onSkillActivatedAuthority += Tracker_Start;
						resets = 0;
						waitingForKill = false;
					}
				}
			}
		}

		private int resets
		{
			get
			{
				return _resets;
			}
			set
			{
				_resets = value;
				if (resets < consecutive && consecutive > consecutiveBest)
				{
					consecutiveBest = consecutive;
				}
				consecutive = resets;
			}
		}

		public ConsecutiveReset(LocalUser user)
		{
			this.user = user;
		}

		public void Hook()
		{
			GlobalEventManager.onCharacterDeathGlobal += Tracker_End;
			Stage.onStageStartGlobal += OnStageStart;
		}

		public void Unhook()
		{
			GlobalEventManager.onCharacterDeathGlobal -= Tracker_End;
			trackedBody = null;
			Stage.onStageStartGlobal -= OnStageStart;
		}

		private void OnStageStart(Stage _)
		{
			totalShotsStage = 0;
			resetShotsStage = 0;
		}

		private void Tracker_Start(GenericSkill skillSlot)
		{
			if ((Object)(object)skillSlot.skillDef == (Object)(object)requiredSkillDef && (Object)(object)requiredSkillDef != (Object)null)
			{
				if (waitingForKill)
				{
					resets = 0;
				}
				waitingForKill = true;
				totalShots++;
				totalShotsStage++;
			}
		}

		private void Tracker_End(DamageReport damageReport)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			if (!((Object)(object)damageReport.attackerBody == (Object)null) && !((Object)(object)damageReport.attackerBody != (Object)(object)trackedBody) && (HUDdleUP.Compatibility.Compatibility.ExtractDamageType(damageReport.damageInfo) & 4) == 4)
			{
				waitingForKill = false;
				resets++;
				resetShots++;
				resetShotsStage++;
			}
		}

		internal static bool HasRequiredSkill(CharacterBody body)
		{
			return Object.op_Implicit((Object)(object)body.skillLocator.FindSkillByDef(requiredSkillDef));
		}

		private bool HasRequiredSkill()
		{
			return HasRequiredSkill(trackedBody);
		}

		internal void FixedUpdate()
		{
			trackedBody = user.currentNetworkUser.GetCurrentBody();
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("<style=cStack>> </style><color=#40C5E4>Consecutive Resets</color><style=cStack>: </style>");
			if (totalShots == 0)
			{
				stringBuilder.Append("<style=cStack>-.--%</style>");
			}
			else
			{
				stringBuilder.Append($"{(float)resetShots / (float)totalShots:0.00%}");
			}
			stringBuilder.AppendLine();
			stringBuilder.Append("<style=cStack>   > this stage: </style>");
			if (totalShotsStage == 0)
			{
				stringBuilder.Append("<style=cStack>-.--%</style>");
			}
			else
			{
				stringBuilder.Append($"{(float)resetShotsStage / (float)totalShotsStage:0.00%}");
			}
			stringBuilder.AppendLine($"<style=cStack> ({resetShotsStage}/{totalShotsStage})</style>");
			stringBuilder.Append($"<style=cStack>   > consecutive: </style>{consecutive}<style=cStack> ({consecutiveBest})</style>");
			bool flag = !HasRequiredSkill();
			bool flag2 = !NetworkServer.active;
			if (flag || flag2)
			{
				stringBuilder.AppendLine().AppendLine();
				if (flag)
				{
					stringBuilder.AppendLine("<size=80%><style=cDeath>WARN: nothing to track</style></size>");
					stringBuilder.Append("<size=80%><style=cStack>    × <style=cDeath><color=#40C5E4>" + Language.GetString(requiredSkillDef.skillNameToken) + "</color> not selected.</style></style></size>");
				}
				if (flag && flag2)
				{
					stringBuilder.AppendLine();
				}
				if (flag2)
				{
					stringBuilder.AppendLine("<size=80%><style=cDeath>WARN: sorry, this feature only works").Append("  on host.</style></size>");
					stringBuilder.AppendLine().Append("<size=80%><style=cStack>    × <style=cDeath>report on <style=cStack>GitHub</style> if you know a fix!</style></style></size>");
				}
			}
			return stringBuilder.ToString();
		}
	}
}
namespace HUDdleUP.Compatibility
{
	internal static class Compatibility
	{
		private static FieldInfo _DamageType_Field;

		private static FieldInfo _DamageTypeCombo_Field;

		internal static FieldInfo DamageType_Field
		{
			get
			{
				if (_DamageType_Field == null)
				{
					Plugin.Logger.LogWarning((object)"MissingFieldException: Using Seekers of the Storm version of DamageInfo.damageType");
					_DamageType_Field = DamageTypeCombo_Field.FieldType.GetField("damageType");
				}
				return _DamageType_Field;
			}
		}

		internal static FieldInfo DamageTypeCombo_Field
		{
			get
			{
				if (_DamageTypeCombo_Field == null)
				{
					_DamageTypeCombo_Field = typeof(DamageInfo).GetField("damageType");
				}
				return _DamageTypeCombo_Field;
			}
		}

		internal static DamageType ExtractDamageType(DamageInfo damageInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return ExtractDamageType_Old(damageInfo);
			}
			catch (MissingFieldException)
			{
				object value = DamageTypeCombo_Field.GetValue(damageInfo);
				return (DamageType)DamageType_Field.GetValue(value);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static DamageType ExtractDamageType_Old(DamageInfo damageInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return DamageTypeCombo.op_Implicit(damageInfo.damageType);
		}
	}
	internal static class MiniMapMod
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__TryCreateMinimap_InSeparatePanel;
		}

		internal const string PLUGIN_GUID = "MiniMap";

		private const string TARGET_ASSEMBLY = "MiniMapMod";

		private const string TARGET_TYPE = "MiniMapMod.MiniMapPlugin";

		private const string TARGET_METHOD = "TryCreateMinimap";

		internal static void TryPatch()
		{
			//IL_0080: 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_0080: Expected O, but got Unknown
			if (!Chainloader.PluginInfos.ContainsKey("MiniMap"))
			{
				return;
			}
			try
			{
				MethodInfo? obj = (AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "MiniMapMod")?.GetType("MiniMapMod.MiniMapPlugin"))?.GetMethod("TryCreateMinimap", BindingFlags.Instance | BindingFlags.NonPublic);
				object obj2 = <>O.<0>__TryCreateMinimap_InSeparatePanel;
				if (obj2 == null)
				{
					Manipulator val = TryCreateMinimap_InSeparatePanel;
					<>O.<0>__TryCreateMinimap_InSeparatePanel = val;
					obj2 = (object)val;
				}
				new ILHook((MethodBase)obj, (Manipulator)obj2);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)ex);
			}
		}

		private static void TryCreateMinimap_InSeparatePanel(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			Func<Instruction, bool>[] array = new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "ObjectivePanel"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<GameObject>(x, "Find"),
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, 0)
			};
			if (val.TryGotoNext((MoveType)2, array))
			{
				int index = val.Index;
				val.Index = index - 1;
				val.EmitDelegate<Func<GameObject, GameObject>>((Func<GameObject, GameObject>)delegate(GameObject objectivePanelGameObject)
				{
					if ((Object)(object)objectivePanelGameObject == (Object)null)
					{
						return null;
					}
					Plugin.Logger.LogDebug((object)("Compatibility: MiniMapMod> Attempting to redirect minimap creation from " + ((Object)objectivePanelGameObject).name + " to separate panel."));
					try
					{
						HUDPanel hUDPanel = HUDPanel.ClonePanel(objectivePanelGameObject.GetComponent<ObjectivePanelController>(), "MinimapPanel");
						if (Object.op_Implicit((Object)(object)hUDPanel.label))
						{
							Object.Destroy((Object)(object)((Component)hUDPanel.label).gameObject);
						}
						hUDPanel.gameObject.transform.SetAsFirstSibling();
						return hUDPanel.gameObject;
					}
					catch (Exception ex)
					{
						Plugin.Logger.LogError((object)ex);
						Plugin.Logger.LogWarning((object)"Compatibility: MiniMapMod> Attempt to redirect minimap creation failed! Using original target instead. Other HUD panels may have non-functional copies of the minimap.");
						return objectivePanelGameObject;
					}
				});
			}
			else
			{
				Plugin.Logger.LogError((object)"Compatibility: MiniMapMod> Cannot hook TryCreateMinimap: failed to match IL instructions.");
			}
		}
	}
}
namespace HUDdleUP.Behaviours
{
	internal class EquipmentCooldownPanel : MonoBehaviour
	{
		private static float LastLogTime;

		private EquipmentIcon parent;

		private RawImage cooldownRemapPanel;

		private float cooldownEndTime;

		private float cooldownTimerMax;

		internal static void Init(EquipmentIcon parent, GameObject target)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(target, ((Component)parent).transform);
			EquipmentCooldownPanel equipmentCooldownPanel = val.AddComponent<EquipmentCooldownPanel>();
			equipmentCooldownPanel.parent = parent;
			equipmentCooldownPanel.cooldownRemapPanel = val.GetComponent<RawImage>();
			((RectTransform)((Component)equipmentCooldownPanel.cooldownRemapPanel).transform).sizeDelta = ((RectTransform)((Component)parent).transform).sizeDelta;
		}

		private void Update()
		{
			//IL_010a: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parent == (Object)null)
			{
				float time = Time.time;
				if (!Mathf.Approximately(LastLogTime, time))
				{
					Plugin.Logger.LogWarning((object)"EquipmentCooldownPanel> Component instantiated but parent became null, removing self. This warning can safely be ignored if Starstorm 2 is installed.");
					LastLogTime = time;
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			float num = 1f;
			if (Object.op_Implicit((Object)(object)parent.targetInventory))
			{
				EquipmentState val = (parent.displayAlternateEquipment ? parent.targetInventory.alternateEquipmentState : parent.targetInventory.currentEquipmentState);
				float timeUntilClamped = ((FixedTimeStamp)(ref val.chargeFinishTime)).timeUntilClamped;
				if (cooldownEndTime != val.chargeFinishTime.t)
				{
					cooldownTimerMax = timeUntilClamped;
					cooldownEndTime = val.chargeFinishTime.t;
				}
				if (cooldownTimerMax > 0f)
				{
					num = 1f - timeUntilClamped / cooldownTimerMax;
				}
			}
			((Behaviour)cooldownRemapPanel).enabled = num < 1f;
			((Graphic)cooldownRemapPanel).color = new Color(1f, 1f, 1f, num);
		}
	}
}