Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HUDdleUP v1.3.2
plugins/HUDdleUP/HUDdleUP.dll
Decompiled 2 weeks agousing 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.2.0")] [assembly: AssemblyInformationalVersion("1.3.2+97fca4fb3a3d410f043d5bba937d65bb54e6a889")] [assembly: AssemblyProduct("HUDdleUP")] [assembly: AssemblyTitle("HUDdleUP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.2.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; private readonly ConfigEntry<bool> expandDroneTrackingOnTeleporterCharged; 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; } } public bool ExpandDroneTrackingOnTeleporterCharged => expandDroneTrackingOnTeleporterCharged.Value; 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; config.SaveOnConfigSet = false; 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\"."); expandDroneTrackingOnTeleporterCharged = config.Bind<bool>("Advanced", "expandDroneTrackingOnTeleporterCharged", true, "Show broken drones by drone type after the Teleporter is fully charged."); config.SaveOnConfigSet = true; config.Save(); } } 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.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("itsschwer.HUDdleUP", "HUDdleUP", "1.3.2")] 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.2"; 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) { if (interactables.drones > 0) { if (teleporterFullyCharged && Plugin.Config.ExpandDroneTrackingOnTeleporterCharged) { 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) { return AppendDroneTiers(interactables, sb); } } return sb.AppendLine(FormatLine("style", "cIsUtility", "Drones", interactables.drones)); } private static StringBuilder AppendDroneTiers(Interactables interactables, StringBuilder sb) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) 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; } 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"; internal const string PLUGIN_GUID_2 = "com.minimapmod.rebalance"; private const string TARGET_ASSEMBLY = "MiniMapMod"; private const string TARGET_TYPE = "MiniMapMod.MiniMapPlugin"; private const string TARGET_METHOD = "TryCreateMinimap"; internal static void TryPatch() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown if (!Chainloader.PluginInfos.ContainsKey("MiniMap") && !Chainloader.PluginInfos.ContainsKey("com.minimapmod.rebalance")) { return; } try { foreach (Assembly item in from a in AppDomain.CurrentDomain.GetAssemblies() where a.GetName().Name == "MiniMapMod" select a) { string relativePath = Path.GetRelativePath(Paths.PluginPath, item.Location); Plugin.Logger.LogDebug((object)("Compatibility: MiniMapMod> Found assembly at " + relativePath + ".")); MethodInfo? obj = (item?.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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ILCursor val = new ILCursor(il); int loc = -1; Func<Instruction, bool>[] array = new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref loc), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, loc), (Instruction x) => ILPatternMatchingExt.MatchLdnull(x), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(x, "op_Equality") }; if (val.TryGotoNext((MoveType)0, array)) { 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); } } }