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 EladsHUDPlus v1.0.0
EladsHUDPlus.dll
Decompiled 18 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using CustomHUD; using Dissonance; using GameNetcodeStuff; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; 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("EladsHUD")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EladsHUD")] [assembly: AssemblyTitle("EladsHUD")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public enum PocketFlashlightOptions { Disabled, Vanilla, Separate } public enum StaminaTextOptions { Disabled, PercentageOnly, Full } internal class CustomHUD_Mono : MonoBehaviour { public static CustomHUD_Mono instance; [Header("Health")] public CanvasGroup healthGroup; public Image healthBar; public TextMeshProUGUI healthText; public TextMeshProUGUI healthText2; [Header("Stamina")] public CanvasGroup staminaGroup; public Image staminaBar; public Image staminaBarChangeFG; public TextMeshProUGUI staminaText; public TextMeshProUGUI carryText; [Header("Battery")] public CanvasGroup batteryGroup; public Image batteryBar; public TextMeshProUGUI batteryText; [Header("Flashlight")] public CanvasGroup flashlightGroup; public Image flashlightBar; public TextMeshProUGUI flashlightText; private Color staminaColor; internal Color staminaWarnColor = new Color(255f, 0f, 0f); internal float colorLerp; private int lastHealth = 100; private float lastHealthChange; private float shownStaminaRate; private void Awake() { if ((Object)(object)instance != (Object)null) { throw new Exception("2 instances of CustomHUD_Mono!"); } instance = this; } private void Start() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) staminaColor = ((Graphic)staminaBar).color; } public void UpdateFromPlayer(PlayerControllerB player) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) lastHealthChange += Time.deltaTime; if (player.health < lastHealth) { Debug.Log((object)"o shit"); Debug.Log((object)player.health); Debug.Log((object)lastHealth); lastHealthChange = 0f; } lastHealth = player.health; int health = player.health; float sprintMeter = player.sprintMeter; _ = player.sprintTime; if ((double)sprintMeter < 0.3) { colorLerp = Mathf.Clamp01(colorLerp + Time.deltaTime * 8f); } else { colorLerp = Mathf.Clamp01(colorLerp - Time.deltaTime * 8f); } ((Graphic)staminaBar).color = Color.Lerp(staminaColor, staminaWarnColor, colorLerp); int num = Mathf.FloorToInt(sprintMeter * 100f); float num2 = CalculateStaminaOverTime(player); float num3 = num2 * 100f; if (Mathf.Sign(num3) != Mathf.Sign(shownStaminaRate) || Mathf.Abs(num3 - shownStaminaRate) >= 0.05f) { shownStaminaRate = num3; } float num4 = shownStaminaRate; if (Plugin.detailedStamina.Value != StaminaTextOptions.Disabled) { ((TMP_Text)staminaText).text = $"{num}<size=75%><voffset=1>%</voffset></size>"; } else { ((TMP_Text)staminaText).text = ""; } float num5 = Mathf.Sign(num2); if (num5 != -1f) { if (num5 != 0f) { if (num5 != 1f) { } staminaBar.fillAmount = sprintMeter; staminaBarChangeFG.fillAmount = 0f; if (Plugin.detailedStamina.Value == StaminaTextOptions.Full) { TextMeshProUGUI obj = staminaText; ((TMP_Text)obj).text = ((TMP_Text)obj).text + " | +" + num4.ToString("0.0") + "<size=75%>/sec</size>"; } } else { staminaBar.fillAmount = sprintMeter; staminaBarChangeFG.fillAmount = 0f; if (Plugin.detailedStamina.Value == StaminaTextOptions.Full) { TextMeshProUGUI obj2 = staminaText; ((TMP_Text)obj2).text = ((TMP_Text)obj2).text + " | +0.0<size=75%>/sec</size>"; } } } else { staminaBar.fillAmount = sprintMeter - Mathf.Abs(num2); ((Graphic)staminaBarChangeFG).color = Color.Lerp(Color.white, staminaWarnColor, colorLerp); staminaBarChangeFG.fillAmount = Mathf.Min(sprintMeter, Mathf.Abs(num2)); ((Transform)((Graphic)staminaBarChangeFG).rectTransform).localPosition = new Vector3(1f + 276f * Mathf.Max(0f, sprintMeter - Mathf.Abs(num2)) + 0.05f, 0f); if (Plugin.detailedStamina.Value == StaminaTextOptions.Full) { TextMeshProUGUI obj3 = staminaText; ((TMP_Text)obj3).text = ((TMP_Text)obj3).text + " | " + num4.ToString("0.0") + "<size=75%>/sec</size>"; } } float num6 = Mathf.RoundToInt(Mathf.Clamp(player.carryWeight - 1f, 0f, 100f) * 105f); if (Plugin.shouldDoKGConversion) { num6 *= 0.453592f; ((TMP_Text)carryText).text = $"{num6}<size=60%>kg</size>"; } else { ((TMP_Text)carryText).text = $"{num6}<size=60%>lb</size>"; } healthBar.fillAmount = (float)health / 100f; ((TMP_Text)healthText).text = health.ToString(); if ((Object)(object)healthText2 != (Object)null) { ((TMP_Text)healthText2).text = health.ToString(); } float value = Plugin.healthbarHideDelay.Value; healthGroup.alpha = (Plugin.autoHideHealthbar.Value ? Mathf.InverseLerp(value + 1f, value, lastHealthChange) : 1f); ((Component)flashlightGroup).gameObject.SetActive(UpdateFlashlight(player)); ((Component)batteryGroup).gameObject.SetActive(UpdateBattery(player)); try { HeadwearHud.instance?.Apply(player); } catch (Exception ex) { Plugin.Log("Head item battery: " + ex); Plugin.showHeadwear.Value = false; } } private bool UpdateFlashlight(PlayerControllerB player) { if (Plugin.pocketedFlashlightDisplayMode.Value != PocketFlashlightOptions.Separate) { return false; } if (!((Behaviour)player.helmetLight).enabled) { return false; } GrabbableObject pocketedFlashlight = player.pocketedFlashlight; if ((Object)(object)pocketedFlashlight == (Object)null) { return false; } if (!pocketedFlashlight.itemProperties.requiresBattery) { return false; } if (pocketedFlashlight.insertedBattery == null) { return false; } flashlightBar.fillAmount = pocketedFlashlight.insertedBattery.charge; int num = Mathf.CeilToInt(pocketedFlashlight.insertedBattery.charge * pocketedFlashlight.itemProperties.batteryUsage); ((TMP_Text)flashlightText).text = $"{Mathf.CeilToInt(pocketedFlashlight.insertedBattery.charge * 100f)}%"; if (!Plugin.displayTimeLeft.Value) { return true; } TextMeshProUGUI obj = flashlightText; ((TMP_Text)obj).text = ((TMP_Text)obj).text + string.Format(" <size=60%>{0}:{1}", num / 60, (num % 60).ToString("D2")); return true; } private bool UpdateBattery(PlayerControllerB player) { GrabbableObject val = player.currentlyHeldObjectServer; if ((Object)(object)val == (Object)null && Plugin.pocketedFlashlightDisplayMode.Value == PocketFlashlightOptions.Vanilla) { val = player.pocketedFlashlight; } if ((Object)(object)val == (Object)null) { return false; } if (!val.itemProperties.requiresBattery) { return false; } if (val.insertedBattery == null) { return false; } batteryBar.fillAmount = val.insertedBattery.charge; int num = (int)(val.insertedBattery.charge / val.itemProperties.batteryUsage); int num2 = Mathf.CeilToInt(val.insertedBattery.charge * val.itemProperties.batteryUsage); ((TMP_Text)batteryText).text = $"{Mathf.CeilToInt(val.insertedBattery.charge * 100f)}%"; if (!Plugin.displayTimeLeft.Value) { return true; } if (val.itemProperties.itemIsTrigger) { TextMeshProUGUI obj = batteryText; ((TMP_Text)obj).text = ((TMP_Text)obj).text + $" ({num} uses remaining)"; } else { TextMeshProUGUI obj2 = batteryText; ((TMP_Text)obj2).text = ((TMP_Text)obj2).text + string.Format(" ({0}:{1} remaining)", num2 / 60, (num2 % 60).ToString("D2")); } return true; } private float CalculateStaminaOverTime(PlayerControllerB player) { if (player.sprintMeter == 1f) { return 0f; } bool privateField = player.GetPrivateField<bool>("isWalking"); float sprintTime = player.sprintTime; float num = 1f; if ((double)player.drunkness > 0.019999999552965164) { num *= Mathf.Abs(StartOfRound.Instance.drunknessSpeedEffect.Evaluate(player.drunkness) - 1.25f); } if (player.isSprinting) { return -1f / sprintTime * player.carryWeight * num; } if (player.isMovementHindered > 0 && privateField) { return -1f / sprintTime * num * 0.5f; } if (privateField) { return 1f / (sprintTime + 9f) * num; } return 1f / (sprintTime + 4f) * num; } } namespace CustomHUD { internal class CursorMode : MonoBehaviour { [HarmonyPatch(typeof(PlayerControllerB), "PlayerLookInput")] internal static class LookPatch { [HarmonyPrefix] private static bool Prefix() { return !Active; } } internal static ConfigEntry<bool> enabledCfg; internal static ConfigEntry<string> keyCfg; internal static ConfigEntry<bool> holdCfg; private InputAction action; internal static bool Active { get; private set; } public static void Bind(ConfigFile cfg) { enabledCfg = cfg.Bind<bool>("Cursor", "EnableCursorKey", true, "Press a key to show the mouse cursor so you can point at the HUD (hover a buff / injury icon to see what it does). The camera stops turning while the cursor is shown."); keyCfg = cfg.Bind<string>("Cursor", "CursorKey", "<Mouse>/middleButton", "Input System path of the key. Examples: <Mouse>/middleButton, <Mouse>/forwardButton, <Keyboard>/leftAlt, <Keyboard>/f2"); holdCfg = cfg.Bind<bool>("Cursor", "HoldToShow", false, "Off: press once to show the cursor, again to hide it. On: the cursor shows only while you hold the key."); } public static void Create(GameObject hud) { hud.AddComponent<CursorMode>(); } private void OnEnable() { MakeAction(); keyCfg.SettingChanged += OnKeyChanged; } private void OnDisable() { keyCfg.SettingChanged -= OnKeyChanged; InputAction obj = action; if (obj != null) { obj.Disable(); } InputAction obj2 = action; if (obj2 != null) { obj2.Dispose(); } action = null; SetActive(on: false, touchCursor: true); } private void OnKeyChanged(object sender, EventArgs e) { InputAction obj = action; if (obj != null) { obj.Disable(); } InputAction obj2 = action; if (obj2 != null) { obj2.Dispose(); } MakeAction(); } private void MakeAction() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { action = new InputAction("EladsHUD Cursor", (InputActionType)1, keyCfg.Value, (string)null, (string)null, (string)null); action.Enable(); } catch (Exception ex) { Plugin.Log("Cursor key '" + keyCfg.Value + "' is not valid: " + ex.Message); action = null; } } private void Update() { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) try { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); bool flag = (Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled || ((Object)(object)val.quickMenuManager != (Object)null && val.quickMenuManager.isMenuOpen) || val.inTerminalMenu || val.isTypingChat || val.inSpecialMenu; if (!enabledCfg.Value || action == null || flag) { SetActive(on: false, !flag); return; } if (holdCfg.Value) { SetActive(action.IsPressed(), touchCursor: true); } else if (action.WasPressedThisFrame()) { SetActive(!Active, touchCursor: true); } if (Active && (int)Cursor.lockState != 0) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } catch (Exception ex) { Plugin.Log("Cursor: " + ex.Message); SetActive(on: false, touchCursor: true); ((Behaviour)this).enabled = false; } } private static void SetActive(bool on, bool touchCursor) { if (on != Active) { Active = on; if (touchCursor) { Cursor.lockState = (CursorLockMode)(!on); Cursor.visible = on; } } } internal static Vector2 MousePosition() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Mouse current = Mouse.current; if (current == null) { return new Vector2(-9999f, -9999f); } return ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(); } } internal class HeadwearHud { private class LampIcon { public RectTransform root; public Image fill; public Image outline; public Image rays; } private class Segment { public RectTransform root; public RectTransform batteryIcon; public Image batteryFillImage; public LampIcon lamp; public RectTransform flashIcon; public Image flashFillImage; public TextMeshProUGUI text; } public static HeadwearHud instance; private const float LampAngle = -47f; private const float SpriteAspect = 0.79591835f; private static Sprite fillSprite; private static Sprite outlineSprite; private static Sprite raysSprite; private readonly CustomHUD_Mono hud; private readonly RectTransform batteryLayout; private readonly RectTransform flashlightRow; private readonly RectTransform smallRow; private readonly LampIcon smallIcon; private readonly TextMeshProUGUI smallText; private readonly LayoutElement smallLayout; private readonly Vector2 rowAnchorMin; private readonly Vector2 rowAnchorMax; private readonly Vector2 rowPivot; private readonly LayoutElement flashlightLayout; private readonly Vector2 flashAnchorMin; private readonly Vector2 flashAnchorMax; private readonly Vector2 flashPivot; private readonly Vector2 flashSize; private readonly LampIcon bigIcon; private readonly Graphic batteryBG; private readonly Graphic batteryFill; private bool batteryIconsHidden; private static bool acChecked; private static MethodInfo getPlayer; private static FieldInfo helmetField; private static MethodInfo perkMultiplier; private static FieldInfo serverConfigInstance; private static FieldInfo itemsField; private static FieldInfo tacticalField; private static FieldInfo tacticalTime; private static FieldInfo tacticalTimeLight; private static bool acConfigChecked; private static readonly Dictionary<Type, FieldInfo> lightFieldByType = new Dictionary<Type, FieldInfo>(); private static readonly Color DrainRed = new Color(1f, 0.22f, 0.12f); private readonly Dictionary<TextMeshProUGUI, float> redAmount = new Dictionary<TextMeshProUGUI, float>(); private readonly Dictionary<TextMeshProUGUI, Color> baseColor = new Dictionary<TextMeshProUGUI, Color>(); private readonly HashSet<TextMeshProUGUI> redThisFrame = new HashSet<TextMeshProUGUI>(); private RectTransform compactRoot; private Segment[] segments; private bool compactActive; private Graphic eladBatteryText; private const string CompactTimeSize = "<size=70%>"; private const float FlashIconScale = 1.3f; private const float SegmentGap = 10f; private const float BatteryIconWidth = 30f; private const float LampIconWidth = 42f; private const float FlashIconWidth = 46f; private const float RowStartX = -4f; private static Type helmetInterface; private static bool helmetInterfaceChecked; private static void CheckAC() { if (acChecked) { return; } acChecked = true; Type type = Plugin.FindType("AdvancedCompany", "AdvancedCompany.Game.Player"); if (!(type == null)) { getPlayer = AccessTools.Method(type, "GetPlayer", new Type[1] { typeof(PlayerControllerB) }, (Type[])null); helmetField = AccessTools.Field(type, "Helmet"); if (getPlayer == null || helmetField == null) { Plugin.Log("AdvancedCompany found, but its head slot changed - head item battery not shown."); } else { Plugin.Log("AdvancedCompany found: head-slot item battery is shown."); } } } private static void CheckACConfig() { if (!acConfigChecked) { acConfigChecked = true; Type type = Plugin.FindType("AdvancedCompany", "AdvancedCompany.Perks"); perkMultiplier = ((type != null) ? AccessTools.Method(type, "GetMultiplier", new Type[1] { typeof(string) }, (Type[])null) : null); Type type2 = Plugin.FindType("AdvancedCompany", "AdvancedCompany.Config.ServerConfiguration"); serverConfigInstance = ((type2 != null) ? AccessTools.Field(type2, "Instance") : null); itemsField = ((type2 != null) ? AccessTools.Field(type2, "Items") : null); tacticalField = ((itemsField != null) ? AccessTools.Field(itemsField.FieldType, "TacticalHelmet") : null); tacticalTime = ((tacticalField != null) ? AccessTools.Field(tacticalField.FieldType, "BatteryTime") : null); tacticalTimeLight = ((tacticalField != null) ? AccessTools.Field(tacticalField.FieldType, "BatteryTimeWithLight") : null); } } private static float SecondsPerFullCharge(GrabbableObject item) { CheckACConfig(); float num = 1f; try { if (perkMultiplier != null) { num = Convert.ToSingle(perkMultiplier.Invoke(null, new object[1] { "ExtraBattery" })); } } catch { } float num2 = Mathf.Max(0.01f, item.itemProperties.batteryUsage * Mathf.Max(0.01f, num)); float num3 = (item.isBeingUsed ? (1f / num2) : 0f); if (!(num3 > 0f)) { return num2; } return 1f / num3; } private static bool TacticalLightOn(GrabbableObject item) { Type type = ((object)item).GetType(); if (!lightFieldByType.TryGetValue(type, out var value)) { value = type.GetField("isFlashlightBeingUsed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (value != null && value.FieldType != typeof(bool)) { value = null; } lightFieldByType[type] = value; } if (value != null) { return (bool)value.GetValue(item); } return false; } private static GrabbableObject GetHeadItem(PlayerControllerB player) { CheckAC(); if (getPlayer == null || helmetField == null || (Object)(object)player == (Object)null) { return null; } object obj = getPlayer.Invoke(null, new object[1] { player }); if (obj == null) { return null; } object? value = helmetField.GetValue(obj); GrabbableObject val = (GrabbableObject)((value is GrabbableObject) ? value : null); if ((Object)(object)val == (Object)null || (Object)(object)val.itemProperties == (Object)null || !val.itemProperties.requiresBattery || val.insertedBattery == null) { return null; } return val; } private static bool IsOn(GrabbableObject item) { if (!item.isBeingUsed) { return TacticalLightOn(item); } return true; } public static void Create(CustomHUD_Mono hud) { try { LoadSprites(); instance = new HeadwearHud(hud); } catch (Exception ex) { Plugin.Log("Head item battery HUD could not be created: " + ex); instance = null; } } private static void LoadSprites() { if (!((Object)(object)fillSprite != (Object)null)) { fillSprite = StatusPanel.LoadSprite("LampFill.png", mipmaps: false); outlineSprite = StatusPanel.LoadSprite("LampOutline.png", mipmaps: false); raysSprite = StatusPanel.LoadSprite("LampRays.png", mipmaps: false); } } private HeadwearHud(CustomHUD_Mono hud) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) this.hud = hud; flashlightRow = (RectTransform)((Component)hud.flashlightGroup).transform; batteryLayout = (RectTransform)((Transform)flashlightRow).parent; GameObject val = Object.Instantiate<GameObject>(((Component)flashlightRow).gameObject, (Transform)(object)batteryLayout); ((Object)val).name = "HeadwearRow"; smallRow = (RectTransform)val.transform; ((Transform)smallRow).SetSiblingIndex(((Transform)flashlightRow).GetSiblingIndex()); Transform obj = ((Transform)smallRow).Find("Battery"); smallText = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null); string[] array = new string[3] { "Icon", "Outline", "Flash" }; foreach (string text in array) { Transform val2 = ((Transform)smallRow).Find(text); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } smallIcon = MakeIcon(smallRow, new Vector2(0f, 0.5f), new Vector2(60f, 1f), 30f); smallLayout = val.GetComponent<LayoutElement>() ?? val.AddComponent<LayoutElement>(); rowAnchorMin = smallRow.anchorMin; rowAnchorMax = smallRow.anchorMax; rowPivot = smallRow.pivot; val.SetActive(false); flashlightLayout = ((Component)flashlightRow).GetComponent<LayoutElement>() ?? ((Component)flashlightRow).gameObject.AddComponent<LayoutElement>(); flashAnchorMin = flashlightRow.anchorMin; flashAnchorMax = flashlightRow.anchorMax; flashPivot = flashlightRow.pivot; flashSize = flashlightRow.sizeDelta; ((Transform)flashlightRow).SetAsLastSibling(); if (Plugin.flashlightGap.Value) { Transform obj2 = ((Transform)flashlightRow).Find("Icon"); Image val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); Sprite val4 = StatusPanel.LoadSprite("FlashlightGap.png", mipmaps: false); if ((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null) { val3.sprite = val4; } } RectTransform val5 = (RectTransform)((Component)hud.batteryGroup).transform; Transform obj3 = ((Transform)val5).Find("BG"); batteryBG = ((obj3 != null) ? ((Component)obj3).GetComponent<Graphic>() : null); batteryFill = (Graphic)(object)hud.batteryBar; bigIcon = MakeIcon(val5, new Vector2(0f, 0f), new Vector2(17f, 20f), 34f); ((Component)bigIcon.root).gameObject.SetActive(false); } private static LampIcon MakeIcon(RectTransform parent, Vector2 anchor, Vector2 center, float width) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) LampIcon lampIcon = new LampIcon(); GameObject val = new GameObject("HeadLamp", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); lampIcon.root = (RectTransform)val.transform; RectTransform root = lampIcon.root; Vector2 anchorMin = (lampIcon.root.anchorMax = anchor); root.anchorMin = anchorMin; lampIcon.root.pivot = new Vector2(0.5f, 0.5f); lampIcon.root.anchoredPosition = center; lampIcon.root.sizeDelta = new Vector2(width, width * 0.79591835f); ((Transform)lampIcon.root).localRotation = Quaternion.Euler(0f, 0f, -47f); lampIcon.fill = MakeImage(lampIcon.root, "Fill", fillSprite); lampIcon.fill.type = (Type)3; lampIcon.fill.fillMethod = (FillMethod)0; lampIcon.fill.fillOrigin = 0; lampIcon.outline = MakeImage(lampIcon.root, "Outline", outlineSprite); lampIcon.rays = MakeImage(lampIcon.root, "Rays", raysSprite); return lampIcon; } private static Image MakeImage(RectTransform parent, string name, Sprite sprite) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; Vector2 offsetMin = (val2.offsetMax = Vector2.zero); val2.offsetMin = offsetMin; Image obj = val.AddComponent<Image>(); obj.sprite = sprite; ((Graphic)obj).raycastTarget = false; ((Graphic)obj).color = new Color(1f, 0.996f, 0f); return obj; } public void Apply(PlayerControllerB player) { redThisFrame.Clear(); ApplyLayout(player); ApplyTints(); } private void MarkRedIfFastDrain(TextMeshProUGUI text, GrabbableObject item) { if ((Object)(object)text != (Object)null && (Object)(object)item != (Object)null && TacticalLightOn(item) && item.insertedBattery != null && item.insertedBattery.charge > 0f) { redThisFrame.Add(text); } } private void ApplyTints() { Tint(hud.batteryText); Tint(smallText); if (segments != null) { Segment[] array = segments; foreach (Segment segment in array) { Tint(segment.text); } } } private void Tint(TextMeshProUGUI text) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null) { return; } redAmount.TryGetValue(text, out var value); if (value <= 0f) { baseColor[text] = ((Graphic)text).color; } float num = (redThisFrame.Contains(text) ? 1f : 0f); if (value != 0f || num != 0f) { value = Mathf.MoveTowards(value, num, Time.deltaTime * 3f); redAmount[text] = value; if (baseColor.TryGetValue(text, out var value2)) { ((Graphic)text).color = Color.Lerp(value2, DrainRed, value); } } } private void ApplyLayout(PlayerControllerB player) { //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) GrabbableObject val = (((Object)(object)player != (Object)null) ? player.currentlyHeldObjectServer : null); GrabbableObject val2 = null; if (Plugin.showHeadwear.Value) { val2 = GetHeadItem(player); if ((Object)(object)val2 != (Object)null && (Object)(object)val2 == (Object)(object)val) { val2 = null; } if ((Object)(object)val2 != (Object)null && !IsOn(val2) && !Plugin.showHeadwearWhenOff.Value) { val2 = null; } } bool activeSelf = ((Component)hud.batteryGroup).gameObject.activeSelf; bool activeSelf2 = ((Component)hud.flashlightGroup).gameObject.activeSelf; bool flag = activeSelf && Plugin.showHeadwear.Value && IsHeadwear(val); if (Plugin.compactBattery.Value) { ApplyCompact(val, activeSelf, flag, val2, activeSelf2); return; } LeaveCompact(); if (flag) { SetBigMode(big: true); ShowBig(val); } else { if (!activeSelf && (Object)(object)val2 != (Object)null) { RestoreFlashlightRow(); ((Component)smallRow).gameObject.SetActive(false); SetBigMode(big: true); ((Component)hud.batteryGroup).gameObject.SetActive(true); ShowBig(val2); return; } SetBigMode(big: false); } if ((Object)(object)val2 == (Object)null) { RestoreFlashlightRow(); ((Component)smallRow).gameObject.SetActive(false); return; } ((Component)smallRow).gameObject.SetActive(true); Describe(val2, out var charge, out var on, out var percent, out var secondsLeft); SetIcon(smallIcon, charge, on); MarkRedIfFastDrain(smallText, val2); if ((Object)(object)smallText != (Object)null) { ((TMP_Text)smallText).text = $"{percent}%"; if (Plugin.displayTimeLeft.Value) { TextMeshProUGUI obj = smallText; ((TMP_Text)obj).text = ((TMP_Text)obj).text + string.Format(" <size=60%>{0}:{1}", secondsLeft / 60, (secondsLeft % 60).ToString("D2")); } } if (activeSelf2) { flashlightLayout.ignoreLayout = true; if ((Object)(object)((Transform)flashlightRow).parent != (Object)(object)smallRow) { ((Transform)flashlightRow).SetParent((Transform)(object)smallRow, false); } RectTransform obj2 = flashlightRow; RectTransform obj3 = flashlightRow; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 0.5f); obj3.anchorMax = val3; obj2.anchorMin = val3; flashlightRow.pivot = new Vector2(0f, 0.5f); flashlightRow.anchoredPosition = new Vector2(TextEnd(smallText) - 36f, 0f); } else { RestoreFlashlightRow(); } } private void RestoreFlashlightRow() { //IL_003f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)((Transform)flashlightRow).parent == (Object)(object)batteryLayout) || flashlightLayout.ignoreLayout) { ((Transform)flashlightRow).SetParent((Transform)(object)batteryLayout, false); flashlightRow.anchorMin = flashAnchorMin; flashlightRow.anchorMax = flashAnchorMax; flashlightRow.pivot = flashPivot; flashlightRow.sizeDelta = flashSize; flashlightLayout.ignoreLayout = false; ((Transform)flashlightRow).SetAsLastSibling(); } } private static float TextEnd(TextMeshProUGUI text) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null) { return 180f; } return ((TMP_Text)text).rectTransform.anchoredPosition.x + ((TMP_Text)text).preferredWidth; } private void BuildCompact() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Expected O, but got Unknown //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)hud.batteryGroup).transform; GameObject val2 = new GameObject("CompactBatteryRow", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent((Transform)(object)val, false); compactRoot = (RectTransform)val2.transform; compactRoot.anchorMin = Vector2.zero; compactRoot.anchorMax = Vector2.one; RectTransform obj = compactRoot; Vector2 offsetMin = (compactRoot.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; eladBatteryText = (Graphic)(object)hud.batteryText; segments = new Segment[3]; for (int i = 0; i < 3; i++) { Segment segment = new Segment(); GameObject val3 = new GameObject("Segment" + i, new Type[1] { typeof(RectTransform) }); val3.transform.SetParent((Transform)(object)compactRoot, false); segment.root = (RectTransform)val3.transform; RectTransform root = segment.root; offsetMin = (segment.root.anchorMax = Vector2.zero); root.anchorMin = offsetMin; segment.root.pivot = Vector2.zero; segment.root.sizeDelta = new Vector2(10f, 36f); GameObject val4 = new GameObject("BatteryIcon", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent((Transform)(object)segment.root, false); segment.batteryIcon = (RectTransform)val4.transform; RectTransform batteryIcon = segment.batteryIcon; offsetMin = (segment.batteryIcon.anchorMax = Vector2.zero); batteryIcon.anchorMin = offsetMin; segment.batteryIcon.pivot = Vector2.zero; segment.batteryIcon.anchoredPosition = Vector2.zero; segment.batteryIcon.sizeDelta = new Vector2(30f, 36f); if ((Object)(object)batteryBG != (Object)null) { Object.Instantiate<GameObject>(((Component)batteryBG).gameObject, (Transform)(object)segment.batteryIcon, false); } if ((Object)(object)hud.batteryBar != (Object)null) { segment.batteryFillImage = Object.Instantiate<GameObject>(((Component)hud.batteryBar).gameObject, (Transform)(object)segment.batteryIcon, false).GetComponent<Image>(); } Graphic[] componentsInChildren = ((Component)segment.batteryIcon).GetComponentsInChildren<Graphic>(true); for (int j = 0; j < componentsInChildren.Length; j++) { ((Behaviour)componentsInChildren[j]).enabled = true; } segment.lamp = MakeIcon(segment.root, Vector2.zero, new Vector2(21f, 19f), 34f); GameObject val5 = new GameObject("FlashIcon", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent((Transform)(object)segment.root, false); segment.flashIcon = (RectTransform)val5.transform; RectTransform flashIcon = segment.flashIcon; offsetMin = (segment.flashIcon.anchorMax = Vector2.zero); flashIcon.anchorMin = offsetMin; segment.flashIcon.pivot = Vector2.zero; segment.flashIcon.sizeDelta = new Vector2(30f, 24f); ((Transform)segment.flashIcon).localScale = Vector3.one * 1.3f; segment.flashIcon.anchoredPosition = new Vector2(-55f, 0.84000015f); string[] array = new string[3] { "Icon", "Outline", "Flash" }; foreach (string text in array) { Transform val6 = ((Transform)flashlightRow).Find(text); if (!((Object)(object)val6 == (Object)null)) { GameObject val7 = Object.Instantiate<GameObject>(((Component)val6).gameObject, (Transform)(object)segment.flashIcon, false); if (text == "Icon") { segment.flashFillImage = val7.GetComponent<Image>(); } } } if ((Object)(object)eladBatteryText != (Object)null) { GameObject val8 = Object.Instantiate<GameObject>(((Component)eladBatteryText).gameObject, (Transform)(object)segment.root, false); segment.text = val8.GetComponent<TextMeshProUGUI>(); ((Behaviour)segment.text).enabled = true; ((TMP_Text)segment.text).fontSize = ((TMP_Text)hud.batteryText).fontSize; ((TMP_Text)segment.text).enableWordWrapping = false; ((TMP_Text)segment.text).overflowMode = (TextOverflowModes)0; RectTransform rectTransform = ((TMP_Text)segment.text).rectTransform; offsetMin = (rectTransform.anchorMax = Vector2.zero); rectTransform.anchorMin = offsetMin; rectTransform.pivot = Vector2.zero; rectTransform.sizeDelta = new Vector2(200f, 22.5f); } segments[i] = segment; } ((Component)compactRoot).gameObject.SetActive(false); } private void ApplyCompact(GrabbableObject held, bool heldShown, bool heldIsHeadwear, GrabbableObject item, bool flashlightShown) { //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)compactRoot == (Object)null) { BuildCompact(); } int num = 0; if (heldShown) { Segment segment = segments[num++]; if (heldIsHeadwear) { ShowLampSegment(segment, held); } else { ShowKind(segment, battery: true); if ((Object)(object)segment.batteryFillImage != (Object)null && (Object)(object)hud.batteryBar != (Object)null) { segment.batteryFillImage.fillAmount = hud.batteryBar.fillAmount; } SetSegText(segment, CompactBatteryText(((Object)(object)hud.batteryText != (Object)null) ? ((TMP_Text)hud.batteryText).text : ""), 30f); } } if ((Object)(object)item != (Object)null) { ShowLampSegment(segments[num++], item); } if (flashlightShown) { Segment segment2 = segments[num++]; ShowKind(segment2, battery: false, lamp: false, flash: true); if ((Object)(object)segment2.flashFillImage != (Object)null && (Object)(object)hud.flashlightBar != (Object)null) { segment2.flashFillImage.fillAmount = hud.flashlightBar.fillAmount; } SetSegText(segment2, CompactFlashlightText(((Object)(object)hud.flashlightText != (Object)null) ? ((TMP_Text)hud.flashlightText).text : ""), 46f); } float num2 = -4f; for (int i = 0; i < segments.Length; i++) { Segment segment3 = segments[i]; ((Component)segment3.root).gameObject.SetActive(i < num); if (i < num) { segment3.root.anchoredPosition = new Vector2(num2, 0f); num2 += ((TMP_Text)segment3.text).rectTransform.anchoredPosition.x + ((TMP_Text)segment3.text).preferredWidth + 10f; } } ((Component)smallRow).gameObject.SetActive(false); RestoreFlashlightRow(); ((Component)hud.flashlightGroup).gameObject.SetActive(false); SetBigMode(big: false); SetEladBatteryVisible(num == 0); ((Component)compactRoot).gameObject.SetActive(num > 0); ((Component)hud.batteryGroup).gameObject.SetActive(num > 0); compactActive = true; } private void LeaveCompact() { if (compactActive) { compactActive = false; if ((Object)(object)compactRoot != (Object)null) { ((Component)compactRoot).gameObject.SetActive(false); } SetEladBatteryVisible(visible: true); } } private void SetEladBatteryVisible(bool visible) { if ((Object)(object)batteryBG != (Object)null) { ((Behaviour)batteryBG).enabled = visible && !batteryIconsHidden; } if ((Object)(object)batteryFill != (Object)null) { ((Behaviour)batteryFill).enabled = visible && !batteryIconsHidden; } if ((Object)(object)eladBatteryText != (Object)null) { ((Behaviour)eladBatteryText).enabled = visible; } } private void ShowLampSegment(Segment seg, GrabbableObject item) { ShowKind(seg, battery: false, lamp: true); Describe(item, out var charge, out var on, out var percent, out var secondsLeft); SetIcon(seg.lamp, charge, on); MarkRedIfFastDrain(seg.text, item); string text = $"{percent}%"; if (Plugin.displayTimeLeft.Value) { text += string.Format(" {0}({1}:{2})</size>", "<size=70%>", secondsLeft / 60, (secondsLeft % 60).ToString("D2")); } SetSegText(seg, text, 42f); } private static void ShowKind(Segment seg, bool battery = false, bool lamp = false, bool flash = false) { ((Component)seg.batteryIcon).gameObject.SetActive(battery); ((Component)seg.lamp.root).gameObject.SetActive(lamp); ((Component)seg.flashIcon).gameObject.SetActive(flash); } private static void SetSegText(Segment seg, string text, float iconWidth) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)seg.text == (Object)null)) { ((TMP_Text)seg.text).text = text; ((TMP_Text)seg.text).rectTransform.anchoredPosition = new Vector2(iconWidth + 2f, 5f); } } private static string CompactBatteryText(string text) { text = text.Replace(" remaining)", ")"); int num = text.IndexOf(" (", StringComparison.Ordinal); if (num >= 0) { return text.Substring(0, num) + " <size=70%>" + text.Substring(num + 1) + "</size>"; } return text; } private static string CompactFlashlightText(string text) { int num = text.IndexOf("<size=60%>", StringComparison.Ordinal); if (num < 0) { return text.Trim(); } string text2 = text.Substring(0, num).Trim(); string text3 = text.Substring(num + "<size=60%>".Length).Replace("</size>", "").Trim(); if (text3.Length <= 0) { return text2; } return text2 + " <size=70%>(" + text3 + ")</size>"; } private void ShowBig(GrabbableObject item) { Describe(item, out var charge, out var on, out var percent, out var secondsLeft); SetIcon(bigIcon, charge, on); MarkRedIfFastDrain(hud.batteryText, item); if ((Object)(object)hud.batteryText != (Object)null) { ((TMP_Text)hud.batteryText).text = $"{percent}%"; if (Plugin.displayTimeLeft.Value) { TextMeshProUGUI batteryText = hud.batteryText; ((TMP_Text)batteryText).text = ((TMP_Text)batteryText).text + string.Format(" ({0}:{1} remaining)", secondsLeft / 60, (secondsLeft % 60).ToString("D2")); } } } private static void Describe(GrabbableObject item, out float charge, out bool on, out int percent, out int secondsLeft) { charge = Mathf.Clamp01(item.insertedBattery.charge); on = IsOn(item) && charge > 0f; percent = Mathf.CeilToInt(charge * 100f); secondsLeft = Mathf.CeilToInt(charge * SecondsPerFullCharge(item)); } private static bool IsHeadwear(GrabbableObject item) { if ((Object)(object)item == (Object)null || (Object)(object)item.itemProperties == (Object)null || !item.itemProperties.requiresBattery || item.insertedBattery == null) { return false; } if (!helmetInterfaceChecked) { helmetInterfaceChecked = true; helmetInterface = Plugin.FindType("AdvancedCompany", "AdvancedCompany.Objects.IHelmet"); } if (helmetInterface != null) { return helmetInterface.IsInstanceOfType(item); } return false; } private void SetIcon(LampIcon icon, float charge, bool on) { icon.fill.fillAmount = charge; ((Behaviour)icon.fill).enabled = charge > 0f; ((Behaviour)icon.rays).enabled = on; } private void SetBigMode(bool big) { ((Component)bigIcon.root).gameObject.SetActive(big); if (big != batteryIconsHidden) { batteryIconsHidden = big; if ((Object)(object)batteryBG != (Object)null) { ((Behaviour)batteryBG).enabled = !big; } if ((Object)(object)batteryFill != (Object)null) { ((Behaviour)batteryFill).enabled = !big; } } } } internal class HudExtras : MonoBehaviour { internal enum MicIconStyle { Solid, TopGap, FullGap } private enum MicState { Hidden, Talking, Muted } internal static ConfigEntry<bool> moveUtilitySlot; internal static ConfigEntry<bool> hideUtilityKey; internal static ConfigEntry<float> utilityOffsetX; internal static ConfigEntry<float> utilityOffsetY; internal static ConfigEntry<bool> showMic; internal static ConfigEntry<bool> showMuted; internal static ConfigEntry<float> micOffsetX; internal static ConfigEntry<float> micOffsetY; internal static ConfigEntry<float> micSize; internal static ConfigEntry<MicIconStyle> micStyle; public static HudExtras instance; private const float SlotLeft = 291f; private const float SlotCenterY = -138f; private const float MicLeft = 277f; private const float MicCenterY = -84f; private const float MicBaseSize = 36f; private static readonly Color MutedColor = new Color(1f, 0.22f, 0.2f, 0.9f); private RectTransform hudRect; private RectTransform slot; private RectTransform slotFrame; private Behaviour slotKeyText; private Vector3 slotHomePos; private bool slotPlaced; private RectTransform micRect; private Image micImage; private Sprite micSprite; private Sprite mutedSprite; private Color talkingColor; private float talkHold; private readonly Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>(); private Image vanillaPTT; private float vanillaPTTAlpha = -1f; internal static void Bind(ConfigFile config) { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown moveUtilitySlot = config.Bind<bool>("UtilitySlot", "NextToHealthBar", true, "Put the utility slot at the right end of the health bar. Off = where it was before (above the HUD)."); hideUtilityKey = config.Bind<bool>("UtilitySlot", "HideKeyText", true, "Hide the [TAB] key text next to the utility slot."); utilityOffsetX = config.Bind<float>("UtilitySlot", "OffsetX", 0f, "Move the utility slot left/right (negative = left)."); utilityOffsetY = config.Bind<float>("UtilitySlot", "OffsetY", 0f, "Move the utility slot up/down (negative = down)."); showMic = config.Bind<bool>("Mic", "ShowMicIcon", true, "Show a mic icon at the right end of the stamina bar while you talk (push to talk: while the talk key is held; voice activation: while the game hears you). Off = no mic icon (the muted icon has its own setting)."); showMuted = config.Bind<bool>("Mic", "ShowMutedIcon", true, "Show a red crossed-out mic while your mic is turned off in the game settings."); micStyle = config.Bind<MicIconStyle>("Mic", "IconStyle", MicIconStyle.Solid, "How the mic icon is drawn.\nSolid - one solid shape.\nTopGap - the top part has an outline with a gap inside, like the battery icon; thin stand.\nFullGap - the top part and the stand both have an outline with a gap inside."); micOffsetX = config.Bind<float>("Mic", "OffsetX", 0f, "Move the mic icon left/right (negative = left)."); micOffsetY = config.Bind<float>("Mic", "OffsetY", 0f, "Move the mic icon up/down (negative = down)."); micSize = config.Bind<float>("Mic", "Size", 1f, new ConfigDescription("Size of the mic icon.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); utilityOffsetX.SettingChanged += delegate { instance?.Dirty(); }; utilityOffsetY.SettingChanged += delegate { instance?.Dirty(); }; moveUtilitySlot.SettingChanged += delegate { instance?.Dirty(); }; micOffsetX.SettingChanged += delegate { instance?.PlaceMic(); }; micOffsetY.SettingChanged += delegate { instance?.PlaceMic(); }; micSize.SettingChanged += delegate { instance?.PlaceMic(); }; micStyle.SettingChanged += delegate { instance?.LoadMicSprites(); }; } internal static void Create(GameObject hud, HUDManager hudManager, CustomHUD_Mono mono) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) HudExtras hudExtras = (instance = hud.AddComponent<HudExtras>()); hudExtras.hudRect = (RectTransform)hud.transform; try { ref RectTransform reference = ref hudExtras.slot; Transform parent = ((Component)hudManager.itemOnlySlotIcon).transform.parent; reference = (RectTransform)(object)((parent is RectTransform) ? parent : null); hudExtras.slotFrame = (((Object)(object)hudManager.itemOnlySlotIconFrame != (Object)null) ? ((Graphic)hudManager.itemOnlySlotIconFrame).rectTransform : null); hudExtras.slotKeyText = (Behaviour)(object)hudManager.utilitySlotKeyText; if ((Object)(object)hudExtras.slot != (Object)null) { hudExtras.slotHomePos = ((Transform)hudExtras.slot).localPosition; } } catch (Exception ex) { Plugin.Log("Utility slot: " + ex.Message); } hudExtras.talkingColor = (Color)(((Object)(object)mono.carryText != (Object)null) ? ((Graphic)mono.carryText).color : new Color(1f, 0.43f, 0f)); hudExtras.talkingColor.a = 1f; hudExtras.BuildMic(); } private void Dirty() { slotPlaced = false; } private void PlaceSlot() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)slot == (Object)null) { return; } ((Transform)slot).localPosition = slotHomePos; if (!moveUtilitySlot.Value) { slotPlaced = true; return; } RectTransform obj = (((Object)(object)slotFrame != (Object)null) ? slotFrame : slot); Vector3[] array = (Vector3[])(object)new Vector3[4]; obj.GetWorldCorners(array); float num = float.MaxValue; float num2 = float.MinValue; float num3 = float.MaxValue; float num4 = float.MinValue; Vector3[] array2 = array; foreach (Vector3 val in array2) { Vector3 val2 = ((Transform)hudRect).InverseTransformPoint(val); num = Mathf.Min(num, val2.x); num2 = Mathf.Max(num2, val2.x); num3 = Mathf.Min(num3, val2.y); num4 = Mathf.Max(num4, val2.y); } if (!(num4 - num3 < 1f)) { float num5 = 291f + utilityOffsetX.Value - num; float num6 = -138f + utilityOffsetY.Value - (num3 + num4) / 2f; RectTransform obj2 = slot; ((Transform)obj2).localPosition = ((Transform)obj2).localPosition + new Vector3(num5, num6, 0f); slotPlaced = true; } } private void BuildMic() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) LoadMicSprites(); GameObject val = new GameObject("SleepyMiles Mic", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)hudRect, false); micRect = (RectTransform)val.transform; RectTransform obj = micRect; RectTransform obj2 = micRect; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); obj2.anchorMax = val2; obj.anchorMin = val2; micRect.pivot = new Vector2(0f, 0.5f); micImage = val.AddComponent<Image>(); ((Graphic)micImage).raycastTarget = false; micImage.preserveAspect = true; ((Behaviour)micImage).enabled = false; PlaceMic(); } private Sprite GetSprite(string file) { if (!spriteCache.TryGetValue(file, out var value)) { value = StatusPanel.LoadSprite(file, mipmaps: false); spriteCache[file] = value; } return value; } private void LoadMicSprites() { string text = micStyle.Value.ToString(); micSprite = GetSprite("Mic_" + text + ".png"); mutedSprite = GetSprite("Mic_" + text + "_Muted.png"); } private void PlaceMic() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)micRect == (Object)null)) { float num = 36f * micSize.Value; micRect.sizeDelta = new Vector2(num, num); micRect.anchoredPosition = new Vector2(277f + micOffsetX.Value, -84f + micOffsetY.Value); } } private void HideVanillaPTT() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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) if ((Object)(object)vanillaPTT == (Object)null) { vanillaPTT = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.PTTIcon : null); if ((Object)(object)vanillaPTT == (Object)null) { return; } vanillaPTTAlpha = ((Graphic)vanillaPTT).color.a; } Color color = ((Graphic)vanillaPTT).color; float num = (showMic.Value ? 0f : vanillaPTTAlpha); if (color.a != num) { color.a = num; ((Graphic)vanillaPTT).color = color; } } private MicState GetMicState() { Settings val = IngamePlayerSettings.Instance?.settings; if (val == null) { return MicState.Hidden; } if (!val.micEnabled) { if (!showMuted.Value) { return MicState.Hidden; } return MicState.Muted; } if (!showMic.Value) { return MicState.Hidden; } DissonanceComms val2 = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.voiceChatModule : null); if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).enabled) { return MicState.Hidden; } if (val2.IsMuted) { talkHold = 0f; return MicState.Hidden; } if (val.pushToTalk) { return MicState.Talking; } bool flag = false; try { VoicePlayerState val3 = val2.FindPlayer(val2.LocalPlayerName); flag = val3 != null && val3.IsSpeaking; } catch { } if (flag) { talkHold = 0.3f; } else { talkHold -= Time.deltaTime; } if (!(talkHold > 0f)) { return MicState.Hidden; } return MicState.Talking; } private void LateUpdate() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!slotPlaced) { try { PlaceSlot(); } catch (Exception ex) { Plugin.Log("Utility slot: " + ex.Message); slotPlaced = true; } } if ((Object)(object)slotKeyText != (Object)null) { bool flag = !hideUtilityKey.Value; if (slotKeyText.enabled != flag) { slotKeyText.enabled = flag; } } if (!((Object)(object)micImage == (Object)null)) { HideVanillaPTT(); MicState micState = MicState.Hidden; try { micState = GetMicState(); } catch { } Sprite val = null; Color mutedColor = talkingColor; switch (micState) { case MicState.Talking: val = micSprite; break; case MicState.Muted: val = mutedSprite; mutedColor = MutedColor; break; } if ((Object)(object)val == (Object)null) { ((Behaviour)micImage).enabled = false; return; } micImage.sprite = val; ((Graphic)micImage).color = mutedColor; ((Behaviour)micImage).enabled = true; } } } internal class HudOutline : MonoBehaviour { private bool applied; private bool dirty = true; private float nextScan; private TMP_FontAsset vanillaFont; private Material vanillaMaterial; private static HudOutline instance; public static void Create(GameObject hud) { instance = hud.AddComponent<HudOutline>(); } public static void Bind(ConfigFile cfg) { Plugin.textOutline = cfg.Bind<bool>("Outline", "OutlineNumbers", false, "Outline the stamina / weight numbers and the battery, flashlight and head item % rows like the vanilla control tips on the right of the screen (same game font and outline)."); Plugin.textOutline.SettingChanged += delegate { if ((Object)(object)instance != (Object)null) { instance.dirty = true; } }; } private void LateUpdate() { if (!dirty && Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 0.5f; bool value = Plugin.textOutline.Value; if (!value && !applied) { dirty = false; return; } try { if (!value || !((Object)(object)vanillaFont == (Object)null) || FindVanilla()) { Apply(value, dirty); applied = value; dirty = false; } } catch (Exception ex) { Plugin.Log("Outline: " + ex.Message); } } private void Apply(bool on, bool force) { TextMeshProUGUI[] componentsInChildren = ((Component)this).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val in componentsInChildren) { if (!IsNumberText(val)) { continue; } OutlineMarker outlineMarker = ((Component)val).GetComponent<OutlineMarker>(); if (!force && (Object)(object)outlineMarker != (Object)null) { continue; } if ((Object)(object)outlineMarker == (Object)null) { outlineMarker = ((Component)val).gameObject.AddComponent<OutlineMarker>(); outlineMarker.originalFont = ((TMP_Text)val).font; outlineMarker.original = ((TMP_Text)val).fontSharedMaterial; } if (on) { if ((Object)(object)((TMP_Text)val).font != (Object)(object)vanillaFont) { ((TMP_Text)val).font = vanillaFont; } ((TMP_Text)val).fontSharedMaterial = vanillaMaterial; } else { if ((Object)(object)outlineMarker.originalFont != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)(object)outlineMarker.originalFont) { ((TMP_Text)val).font = outlineMarker.originalFont; } ((TMP_Text)val).fontSharedMaterial = outlineMarker.original; } ((TMP_Text)val).UpdateMeshPadding(); ((Graphic)val).SetVerticesDirty(); } } private bool FindVanilla() { HUDManager val = HUDManager.Instance; if ((Object)(object)val == (Object)null || val.controlTipLines == null) { return false; } TextMeshProUGUI[] controlTipLines = val.controlTipLines; foreach (TextMeshProUGUI val2 in controlTipLines) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((TMP_Text)val2).font == (Object)null) && !((Object)(object)((TMP_Text)val2).fontSharedMaterial == (Object)null)) { vanillaFont = ((TMP_Text)val2).font; vanillaMaterial = ((TMP_Text)val2).fontSharedMaterial; return true; } } return false; } private static bool IsNumberText(TextMeshProUGUI text) { string name = ((Object)text).name; switch (name) { default: return name.StartsWith("BatteryStuf"); case "StaminaInfo": case "CarryInfo": case "Battery": return true; } } } internal class OutlineMarker : MonoBehaviour { public TMP_FontAsset originalFont; public Material original; } [HarmonyPatch(typeof(CustomHUD_Mono), "UpdateFromPlayer")] internal static class InjectorTint { private static readonly Color InjectorColor = new Color(0f, 0.9f, 1f); private const float FadeInSpeed = 2f; private const float FadeOutSpeed = 1f; private static bool checkedType; private static Type effectType; private static float intensity; [HarmonyPostfix] [HarmonyPriority(200)] [HarmonyAfter(new string[] { "Miles.TZPPlus" })] private static void Postfix(CustomHUD_Mono __instance, PlayerControllerB player) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) try { if (!checkedType) { checkedType = true; effectType = Plugin.FindType("UsualScrap", "UsualScrap.Behaviors.Effects.ProductivityAutoinjectorEffect"); } if (!(effectType == null) && !((Object)(object)__instance.staminaBar == (Object)null)) { bool flag = Plugin.injectorStaminaColor.Value && (Object)(object)player != (Object)null && (Object)(object)((Component)player).GetComponent(effectType) != (Object)null; intensity = Mathf.MoveTowards(intensity, flag ? 1f : 0f, (flag ? 2f : 1f) * Time.deltaTime); if (!(intensity <= 0f)) { Color val = Color.Lerp(InjectorColor, __instance.staminaWarnColor, __instance.colorLerp); ((Graphic)__instance.staminaBar).color = Color.Lerp(((Graphic)__instance.staminaBar).color, val, intensity); } } } catch { } } } [BepInPlugin("me.eladnlg.customhud", "EladsHUD+", "1.0.0")] public class Plugin : BaseUnityPlugin { public static Plugin instance; public AssetBundle assets; public GameObject HUD; public static bool shouldDoKGConversion; internal static ConfigEntry<PocketFlashlightOptions> pocketedFlashlightDisplayMode; internal static ConfigEntry<StaminaTextOptions> detailedStamina; internal static ConfigEntry<bool> displayTimeLeft; internal static ConfigEntry<float> hudScale; internal static ConfigEntry<bool> autoHideHealthbar; internal static ConfigEntry<float> healthbarHideDelay; internal static ConfigEntry<bool> hidePlanetInfo; internal static ConfigEntry<bool> showStatusWarnings; internal static ConfigEntry<float> statusWarningTime; internal static ConfigEntry<bool> showFrailtyConditions; internal static ConfigEntry<bool> showBuffs; internal static ConfigEntry<bool> coloredBuffNumbers; internal static ConfigEntry<bool> injectorStaminaColor; internal static ConfigEntry<bool> showHeadwear; internal static ConfigEntry<bool> showHeadwearWhenOff; internal static ConfigEntry<bool> flashlightGap; internal static ConfigEntry<bool> compactBattery; internal static ConfigEntry<bool> textOutline; internal static ConfigEntry<float> statusOffsetX; internal static ConfigEntry<int> statusIconsPerRow; internal static ConfigEntry<bool> statusShrinkRows; internal static ConfigEntry<float> statusOffsetY; internal static void Log(string message) { Plugin plugin = instance; if (plugin != null) { ((BaseUnityPlugin)plugin).Logger.LogInfo((object)message); } } internal static void LogError(string message) { Plugin plugin = instance; if (plugin != null) { ((BaseUnityPlugin)plugin).Logger.LogError((object)message); } } internal static Type FindType(string assemblyName, string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetName().Name == assemblyName) { return assembly.GetType(fullName, throwOnError: false); } } catch { } } return null; } private void Awake() { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Expected O, but got Unknown //IL_03ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance != (Object)null) { throw new Exception("what the cuck??? more than 1 plugin instance."); } instance = this; hudScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HUDScale", 1f, "The size of the HUD."); autoHideHealthbar = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideHealthbarAutomatically", true, "Should the healthbar be hidden after not taking damage for a while."); healthbarHideDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HealthbarHideDelay", 4f, "The amount of time before the healthbar starts fading away."); pocketedFlashlightDisplayMode = ((BaseUnityPlugin)this).Config.Bind<PocketFlashlightOptions>("General", "FlashlightBattery", PocketFlashlightOptions.Separate, "How the flashlight battery is displayed whilst unequipped.\nDisabled - Flashlight battery will not be displayed.\nVanilla - Flashlight battery will be displayed when you don't have a battery-using item equipped.\nSeparate - Flashlight battery will be displayed using a dedicated panel. (recommended)"); detailedStamina = ((BaseUnityPlugin)this).Config.Bind<StaminaTextOptions>("General", "DetailedStamina", StaminaTextOptions.PercentageOnly, "What the stamina text should display.\nDisabled - The stamina text will be hidden.\nPercentageOnly - Only the percentage will be displayed. (recommended)\nFull - Both percentage and rate of gain/loss will be displayed."); displayTimeLeft = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisplayTimeLeft", true, "Should the uses/time left for a battery-using item be displayed."); hidePlanetInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HidePlanetInfo", false, "Should planet info be hidden. If modifying from an in-game menu, this requires you to rejoin the game."); showStatusWarnings = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "ShowWarnings", true, "Show the vanilla warning text (steam leak, Cadaver spores / fever, low oxygen) under the health bar. Vanilla shows it in the HUD that Elad's HUD hides."); statusWarningTime = ((BaseUnityPlugin)this).Config.Bind<float>("Status", "WarningTime", 4f, new ConfigDescription("How many seconds a warning stays after its cause stops (steam leak warnings stay while you are in the steam).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>())); showFrailtyConditions = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "ShowFrailtyConditions", true, "If the Frailty mod is installed, show its status effects (broken leg, bleeding, ...) with the time left under the health bar, instead of Frailty's own icons."); showBuffs = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "ShowBuffs", true, "Show UsualScrap's Productivity Auto-Injector (time left) under the health bar. Other mods (e.g. TZPPlus) add their own icons here through StatusApi and have their own settings."); coloredBuffNumbers = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "ColoredBuffNumbers", false, "Buff numbers (TZP %, TZP Rush and injector time) in the buff's own colour instead of white."); injectorStaminaColor = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "InjectorStaminaColor", true, "The stamina bar fades to cyan while UsualScrap's Productivity Auto-Injector is active (still turns red when stamina is low)."); showHeadwear = ((BaseUnityPlugin)this).Config.Bind<bool>("Headwear", "ShowHeadwearBattery", true, "Show the battery of the AdvancedCompany head-slot item (Helmet Lamp, Tactical Helmet, Headset, Vision Enhancer). Alone it uses the normal battery row; with a battery item or TZP in your hand it moves to a small row above (next to the flashlight if that is shown too)."); showHeadwearWhenOff = ((BaseUnityPlugin)this).Config.Bind<bool>("Headwear", "ShowWhenSwitchedOff", true, "Keep showing the head item while it is switched off (light rays only show while it is on). Off = only show it while it is on, like the pocketed flashlight."); flashlightGap = ((BaseUnityPlugin)this).Config.Bind<bool>("Headwear", "FlashlightIconGap", true, "Give the pocketed-flashlight icon a small gap inside its outline, like the battery and head lamp icons. Needs a rejoin to change."); compactBattery = ((BaseUnityPlugin)this).Config.Bind<bool>("Headwear", "CompactBatteryUI", false, "Compact battery UI: held item, head item and flashlight all in the main battery row (left to right, in that order), with slightly smaller numbers and (4:30) instead of (4:30 remaining)."); HudOutline.Bind(((BaseUnityPlugin)this).Config); CursorMode.Bind(((BaseUnityPlugin)this).Config); HudExtras.Bind(((BaseUnityPlugin)this).Config); statusIconsPerRow = ((BaseUnityPlugin)this).Config.Bind<int>("Status", "IconsPerRow", 7, new ConfigDescription("Status icons per row. While everything fits, it stays one row (buffs first, then injuries / debuffs). With more, buffs get their own row(s) and injuries / debuffs start a new row below.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); statusShrinkRows = ((BaseUnityPlugin)this).Config.Bind<bool>("Status", "ShrinkWithMoreRows", false, "Make the status icons a bit smaller once there are 2 or more rows."); statusOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Status", "OffsetX", 0f, "Move the status area left/right (negative = left)."); statusOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Status", "OffsetY", 0f, "Move the status area up/down (negative = down)."); statusOffsetX.SettingChanged += delegate { StatusPanel.instance?.ApplyOffset(); }; statusOffsetY.SettingChanged += delegate { StatusPanel.instance?.ApplyOffset(); }; ((BaseUnityPlugin)this).Logger.LogInfo((object)"EladsHUD+ 1.0.0 is loaded!"); assets = AssetUtils.LoadAssetBundleFromResources("customhud", typeof(PlayerPatches).Assembly); HUD = assets.LoadAsset<GameObject>("PlayerInfo"); new Harmony("me.eladnlg.customhud").PatchAll(Assembly.GetExecutingAssembly()); } private void Start() { ((BaseUnityPlugin)this).Logger.LogInfo((object)(Chainloader.PluginInfos.Count + " plugins loaded")); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin GUID: " + pluginInfo.Value.Metadata.GUID)); } shouldDoKGConversion = Chainloader.PluginInfos.Any((KeyValuePair<string, PluginInfo> pair) => pair.Value.Metadata.GUID == "com.zduniusz.lethalcompany.lbtokg"); } } [HarmonyPatch(typeof(HUDManager))] public class HUDPatches { private static void Safe(string what, Action action) { try { action(); } catch (Exception ex) { Plugin.LogError(what + " could not be created: " + ex); } } [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Awake_Postfix(HUDManager __instance) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) HUDElement[] privateField = __instance.GetPrivateField<HUDElement[]>("HUDElements"); HUDElement val = privateField[2]; GameObject HUD = Object.Instantiate<GameObject>(Plugin.instance.HUD, ((Component)val.canvasGroup).transform.parent); HUD.transform.localScale = Vector3.one * 0.75f * Plugin.hudScale.Value; Transform parent = ((Component)__instance.itemOnlySlotIcon).transform.parent; parent.SetParent(HUD.transform, true); parent.SetAsLastSibling(); val.canvasGroup.alpha = 0f; Transform val2 = ((Component)val.canvasGroup).transform.Find("CinematicGraphics"); if ((Object)(object)val2 != (Object)null && !Plugin.hidePlanetInfo.Value) { val2.SetParent(HUD.transform.parent); } privateField[2].canvasGroup = HUD.GetComponent<CanvasGroup>(); CustomHUD_Mono mono = HUD.GetComponent<CustomHUD_Mono>(); if ((Object)(object)mono == (Object)null) { Plugin.LogError("The HUD prefab lost its CustomHUD_Mono script (assembly must be named EladsHUD). EladsHUD+ extras disabled."); return; } Safe("Status row", delegate { StatusPanel.Create(HUD, mono); }); Safe("Head item battery", delegate { HeadwearHud.Create(mono); }); Safe("Outline", delegate { HudOutline.Create(HUD); }); Safe("Cursor mode", delegate { CursorMode.Create(HUD); }); Safe("Utility slot / mic", delegate { HudExtras.Create(HUD, __instance, mono); }); } } [HarmonyPatch(typeof(PlayerControllerB))] public static class PlayerPatches { private static readonly HashSet<string> loggedErrors = new HashSet<string>(); [HarmonyPrefix] [HarmonyPatch("LateUpdate")] private static void LateUpdate_Prefix(PlayerControllerB __instance) { if (!((NetworkBehaviour)__instance).IsOwner || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject) || (Object)(object)CustomHUD_Mono.instance == (Object)null) { return; } try { CustomHUD_Mono.instance.UpdateFromPlayer(__instance); } catch (Exception ex) { string item = ex.GetType().Name + ex.StackTrace; if (loggedErrors.Add(item)) { Plugin.LogError("Elad's HUD update failed (shown once, further ones hidden): " + ex); } } } } internal static class ReflectionUtils { public static T GetPrivateField<T>(this object obj, string field) { return (T)obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); } } public static class StatusApi { public const int Version = 1; public static bool Available => (Object)(object)StatusPanel.instance != (Object)null; public static void Show(string key, Sprite icon, bool isBuff, Color frameColor, string timer, Color timerColor, string title, string description) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(key)) { StatusPanel.pendingExternal[key] = new StatusPanel.External { icon = icon, isBuff = isBuff, frameColor = frameColor, timer = timer, timerColor = timerColor, title = title, description = description }; } } } internal static class StatusInfo { private static readonly Color Injury = new Color(1f, 0.35f, 0.35f); private static readonly Color TZP = new Color(1f, 0.72f, 0.11f); private static readonly Color Injector = new Color(0f, 0.86f, 1f); private static readonly Dictionary<string, (string title, string body, Color color)> entries = new Dictionary<string, (string, string, Color)> { { "BrokenLeg", ("Broken Leg", "Sprinting drains your stamina much faster.", Injury) }, { "FracturedLeg", ("Fractured Leg", "Sprinting drains your stamina faster.", Injury) }, { "BrokenArm", ("Broken Arm", "You can only hold light items. Anything heavier slips out of your hands.", Injury) }, { "FracturedArm", ("Fractured Arm", "Heavy items slip out of your hands.", Injury) }, { "Bleeding", ("Bleeding", "Your health doesn't regenerate and you leave a blood trail. UsualScrap's Bandages and Medical Kit make it end sooner.", Injury) }, { "Blindness", ("Blinded", "A bright glare washes out your vision.", Injury) }, { "Concussed", ("Concussed", "Your vision blurs when you move, with a red tint and dark edges.", Injury) }, { "Laceration", ("Laceration", "A deep wound. Treat it with a UsualScrap Bandage or Medical Kit before the time runs out, or it turns into Fatal Bleeding.", Injury) }, { "FatalBleeding", ("Fatal Bleeding", "You keep losing health until it stops, and it can kill you. UsualScrap's Bandages and Medical Kit make it end sooner. Healing helps you survive it.", Injury) }, { "Paralyze", ("Paralyze", "Electricity in your body. Every now and then it locks you up for a moment. Higher levels lock you up more often.", Injury) }, { "Paralyze2", ("Paralyze II", "Electricity in your body. Every now and then it locks you up for a moment. Level II: it locks you up more often.", Injury) }, { "Paralyze3", ("Paralyze III", "Electricity in your body. Every now and then it locks you up for a moment. Level III: it locks you up the most often.", Injury) }, { "Paralysis", ("Paralysis", "You can't move or jump, and your camera turns slowly.", Injury) }, { "buff:Injector", ("Productivity Auto-Injector", "You move faster, jump higher and don't feel the weight you carry.", Injector) } }; public static bool TryGet(string key, out string title, out string body, out Color color) { //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) //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) if (entries.TryGetValue(key, out (string, string, Color) value)) { (title, body, color) = value; return true; } title = key; body = ""; color = Color.white; return false; } } internal class StatusPanel : MonoBehaviour { private class Slot { public RectTransform rect; public CanvasGroup group; public Image frame; public Image icon; public TextMeshProUGUI timer; public bool active; } internal struct External { public Sprite icon; public bool isBuff; public Color frameColor; public Color timerColor; public string timer; public string title; public string description; } public static StatusPanel instance; private const float SlotSize = 30f; private const float SlotSpacing = 6f; private const float TimerHeight = 16f; private const float RowGap = 4f; private const float PanelWidth = 270f; private RectTransform root; private RectTransform conditionRow; private RectTransform warningRect; private CanvasGroup warningGroup; private TextMeshProUGUI warningText; private TMP_FontAsset font; private float warningHideTime = -1f; private readonly Dictionary<string, Slot> slots = new Dictionary<string, Slot>(); private readonly List<string> order = new List<string>(); private static bool frailtyChecked; private static Type frailtyManagerType; private static FieldInfo conditionsField; private static FieldInfo startField; private static FieldInfo durationField; private static FieldInfo typeField; private static Type frailtyHudType; private static readonly Dictionary<string, string> hudFieldByType = new Dictionary<string, string> { { "BrokenLeg", "brokenLegHud" }, { "BrokenArm", "brokenArmHud" }, { "FracturedLeg", "fracturedLegHud" }, { "FracturedArm", "fracturedArmHud" }, { "Bleeding", "bleedingHud" }, { "Blindness", "blindnessHud" }, { "Concussed", "concussedHud" }, { "Laceration", "lacerationHud" }, { "FatalBleeding", "fatalBleedingHud" }, { "Paralyze", "paralyzeHud" }, { "Paralyze2", "paralyze2Hud" }, { "Paralyze3", "paralyze3Hud" }, { "Paralysis", "paralysisHud" } }; private static FieldInfo tierField; private static readonly Color InjectorColor = new Color(0f, 0.86f, 1f); private static Sprite buffFrame; private static Sprite injectorIcon; private static bool buffsChecked; private static Type injectorType; private static FieldInfo injectorTicks; private static FieldInfo frailtyConditionHudField; private static bool tzpPlusInstalled; internal static readonly Dictionary<string, External> pendingExternal = new Dictionary<string, External>(); private static readonly Dictionary<string, External> externalInfo = new Dictionary<string, External>(); private const float TooltipWidth = 240f; private const float TooltipPad = 7f; private RectTransform tooltipRect; private CanvasGroup tooltipGroup; private TextMeshProUGUI tooltipText; private Image tooltipAccent; private string tooltipKey; public static void Create(GameObject hud, CustomHUD_Mono mono) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("StatusPanel (SleepyMiles)", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(hud.transform, false); instance = val.AddComponent<StatusPanel>(); instance.font = (((Object)(object)mono != (Object)null && (Object)(object)mono.healthText != (Object)null) ? ((TMP_Text)mono.healthText).font : null); instance.Build(); } private void Build() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0021: 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_0055: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) root = (RectTransform)((Component)this).transform; root.anchorMin = new Vector2(0f, 0f); root.anchorMax = new Vector2(0f, 0f); root.pivot = new Vector2(0f, 1f); root.sizeDelta = new Vector2(270f, 0f); ApplyOffset(); conditionRow = NewRect("Conditions", (Transform)(object)root); RectTransform obj = conditionRow; RectTransform obj2 = conditionRow; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); obj2.anchorMax = val; obj.anchorMin = val; conditionRow.pivot = new Vector2(0f, 1f); conditionRow.sizeDelta = new Vector2(270f, 46f); warningRect = NewRect("Warning", (Transform)(object)root); RectTransform obj3 = warningRect; RectTransform obj4 = warningRect; ((Vector2)(ref val))..ctor(0f, 1f); obj4.anchorMax = val; obj3.anchorMin = val; warningRect.pivot = new Vector2(0f, 1f); warningRect.sizeDelta = new Vector2(270f, 80f); warningGroup = ((Component)warningRect).gameObject.AddComponent<CanvasGroup>(); warningGroup.alpha = 0f; warningGroup.blocksRaycasts = false; warningGroup.interactable = false; warningText = NewText(warningRect, 17f, (TextAlignmentOptions)257); ((TMP_Text)warningText).enableWordWrapping = true; RectTransform rectTransform = ((TMP_Text)warningText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; val = (rectTransform.offsetMin = (rectTransform.offsetMax = Vector2.zero)); BuildTooltip(); } internal void ApplyOffset() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root != (Object)null) { root.anchoredPosition = new Vector2(Plugin.statusOffsetX.Value, 5f + Plugin.statusOffsetY.Value); } } private static RectTransform NewRect(string name, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); return (RectTransform)val.transform; } private TextMeshProUGUI NewText(RectTransform parent, float size, TextAlignmentOptions align) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((Component)NewRect("Text", (Transform)(object)parent)).gameObject.AddComponent<TextMeshProUGUI>(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val).font = font; } ((TMP_Text)val).fontSize = size; ((TMP_Text)val).alignment = align; ((Graphic)val).raycastTarget = false; ((TMP_Text)val).enableWordWrapping = false; ((TMP_Text)val).overflowMode = (TextOverflowModes)0; ((Graphic)val).color = Color.white; return val; } public void ShowWarning(string message) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (Plugin.showStatusWarnings.Value && !string.IsNullOrEmpty(message)) { ((TMP_Text)warningText).text = FormatWarning(message); TextMeshProUGUI val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.statusEffectText : null); ((Graphic)warningText).color = (((Object)(object)val != (Object)null) ? new Color(((Graphic)val).color.r, ((Graphic)val).color.g, ((Graphic)val).color.b, 1f) : new Color(1f, 0.35f, 0.25f)); warningHideTime = Time.time + Mathf.Max(0.5f, Plugin.statusWarningTime.Value); } } private static string FormatWarning(string message) { string text = message.Replace("\r", "").Replace("\n\n", "\n").Trim(); int num = text.IndexOf('\n'); if (num < 0) { return text; } return text.Substring(0, num) + "\n<size=80%>" + text.Substring(num + 1) + "</size>"; } private static bool FrailtyAvailable() { if (!frailtyChecked) { frailtyChecked = true; frailtyManagerType = Plugin.FindType("Frailty", "Frailty.Manager.ConditionManager"); Type type = Plugin.FindType("Frailty", "Frailty.Manager.Condition"); frailtyHudType = Plugin.FindType("Frailty", "Frailty.Patches.HUDPatch"); if (frailtyManagerType != null && type != null) { conditionsField = AccessTools.Field(frailtyManagerType, "conditions"); startField = AccessTools.Field(type, "startTime"); durationField = AccessTools.Field(type, "duration"); typeField = AccessTools.Field(type, "type"); tierField = AccessTools.Field(type, "tier"); } if (frailtyManagerType != null) { if (conditionsField == null || startField == null || durationField == null || typeField == null) { Plugin.Log("Frailty found, but its conditions changed - status effects not shown in Elad's HUD."); frailtyManagerType = null; } else { Plugin.Log("Frailty found: status effects with time left are shown under the health bar."); } } } return frailtyManagerType != null; } private Slot GetSlot(string typeName, Action<Slot> setup = null) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) if (slots.TryGetValue(typeName, out var value)) { return value; } value = new Slot(); value.rect = NewRect(typeName, (Transform)(object)conditionRow); RectTransform rect = value.rect; RectTransform rect2 = value.rect; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rect2.anchorMax = val; rect.anchorMin = val; value.rect.pivot = new Vector2(0f, 1f); value.rect.sizeDelta = new Vector2(30f, 46f); value.group = ((Component)value.rect).gameObject.AddComponent<CanvasGroup>(); value.group.alpha = 0f; value.group.blocksRaycasts = false; RectTransform val2 = NewRect("Frame", (Transform)(object)value.rect); ((Vector2)(ref val))..ctor(0.5f, 1f); val2.anchorMax = val; val2.anchorMin = val; val2.pivot = new Vector2(0.5f, 1f); val2.sizeDelta = new Vector2(30f, 30f); value.frame = ((Component)val2).gameObject.AddComponent<Image>(); ((Graphic)value.frame).raycastTarget = false; RectTransform val3 = NewRect("Icon", (Transform)(object)val2); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val = (val3.offsetMin = (val3.offsetMax = Vector2.zero)); value.icon = ((Component)val3).gameObject.AddComponent<Image>(); ((Graphic)value.icon).raycastTarget = false; value.icon.preserveAspect = true; if (setup != null) { setup(value); } else { CopyFrailtySprites(typeName, value); } RectTransform val5 = NewRect("Time", (Transform)(object)value.rect); ((Vector2)(ref val))..ctor(0.5f, 0f); val5.anchorMax = val; val5.anchorMin = val; val5.pivot = new Vector2(0.5f, 0f); val5.sizeDelta = new Vector2(36f, 16f); value.timer = NewText(val5, 14f, (TextAlignmentOptions)514); RectTransform rectTransform = ((TMP_Text)value.timer).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; val = (rectTransform.offsetMin = (rectTransform.offsetMax = Vector2.zero)); slots[typeName] = value; return value; } private static void CopyFrailtySprites(string typeName, Slot slot) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) ((Graphic)slot.frame).color = new Color(1f, 0f, 0.216f, 0.22f); ((Behaviour)slot.icon).enabled = false; try { if (frailtyHudType == null || !hudFieldByType.TryGetValue(typeName, out var value)) { return; } object? obj = AccessTools.Field(frailtyHudType, value)?.GetValue(null); Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return; } Image component = val.GetComponent<Image>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null) { slot.frame.sprite = component.sprite; ((Graphic)slot.frame).color = ((Graphic)component).color; } Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true); foreach (Image val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)(object)component) && !((Object)(ob