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 HexSkillBarOverlay v1.0.0
Plugins/HexSkillBarOverlay.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HexSkillBarOverlay.UI; using HexSkillBarOverlay.UI.Models; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("HexSkillVarOverlay")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("HexSkillVarOverlay")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5a4e3281-7d6a-4cf5-8a43-477471bebb33")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace HexSkillBarOverlay { [BepInPlugin("com.hex.skillbaroverlay", "HexSkillBarOverlay", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string PluginGuid = "com.hex.skillbaroverlay"; private const string PluginName = "HexSkillBarOverlay"; private const string PluginVersion = "1.0.0"; private Harmony _harmonyInstance; private GameObject _controllerObject; internal static ManualLogSource Log; internal static Plugin Instance; internal static readonly FieldRef<Skills, Player> SkillsPlayerField = AccessTools.FieldRefAccess<Skills, Player>("m_player"); internal static readonly FieldRef<Skill, SkillDef> SkillInfoField = AccessTools.FieldRefAccess<Skill, SkillDef>("m_info"); internal static readonly FieldRef<Skill, float> SkillLevelField = AccessTools.FieldRefAccess<Skill, float>("m_level"); internal static readonly FieldRef<SkillDef, Sprite> SkillIconField = AccessTools.FieldRefAccess<SkillDef, Sprite>("m_icon"); internal static readonly FieldRef<SkillDef, float> SkillIncreaseStepField = AccessTools.FieldRefAccess<SkillDef, float>("m_increseStep"); internal static readonly FastInvokeHandler SkillsGetSkillMethod = MethodInvoker.GetHandler(AccessTools.Method(typeof(Skills), "GetSkill", (Type[])null, (Type[])null), false); internal static readonly FastInvokeHandler SkillGetLevelPercentageMethod = MethodInvoker.GetHandler(AccessTools.Method(typeof(Skill), "GetLevelPercentage", (Type[])null, (Type[])null), false); internal static AssetBundle Bundle; internal static GameObject SkillBarPrefab; internal static ConfigEntry<bool> EnableDragging { get; private set; } internal static ConfigEntry<float> OverlayPositionX { get; private set; } internal static ConfigEntry<float> OverlayPositionY { get; private set; } private void Awake() { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; EnableDragging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Dragging", false, "Allows the skill bar overlay to be repositioned by dragging it. The game must be paused while moving the overlay."); OverlayPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Overlay Position X", 40f, "Saved horizontal position of the skill bar overlay."); OverlayPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Overlay Position Y", 0f, "Saved vertical position of the skill bar overlay."); Bundle = GetAssetBundleFromResources("skill-bar-overlay"); if ((Object)(object)Bundle == (Object)null) { Log.LogError((object)"Failed to load skill bar AssetBundle."); return; } SkillBarPrefab = Bundle.LoadAsset<GameObject>("SkillBars"); if ((Object)(object)SkillBarPrefab == (Object)null) { Log.LogError((object)"Failed to load SkillBars prefab from AssetBundle."); return; } _controllerObject = new GameObject("HexSkillBarOverlayController"); Object.DontDestroyOnLoad((Object)(object)_controllerObject); _controllerObject.AddComponent<SkillBarPrefabController>(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmonyInstance = new Harmony("com.hex.skillbaroverlay"); _harmonyInstance.PatchAll(executingAssembly); } private void OnDestroy() { Harmony harmonyInstance = _harmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } _harmonyInstance = null; if ((Object)(object)_controllerObject != (Object)null) { Object.Destroy((Object)(object)_controllerObject); _controllerObject = null; } Instance = null; Log = null; } private static AssetBundle GetAssetBundleFromResources(string fileName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetManifestResourceNames().SingleOrDefault((string resourceName) => resourceName.EndsWith(fileName)); if (text == null) { Log.LogError((object)("Could not find embedded resource ending with '" + fileName + "'.")); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { Log.LogError((object)("Failed to open embedded resource stream: " + text)); return null; } return AssetBundle.LoadFromStream(stream); } } } namespace HexSkillBarOverlay.UI { internal sealed class SkillBarDragHandler : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { private RectTransform _rectTransform; private Vector2 _startPosition; private Vector2 _startPointerPosition; internal Action<Vector2> DragEnded { get; set; } private void Awake() { _rectTransform = ((Component)this).GetComponent<RectTransform>(); } public void OnBeginDrag(PointerEventData eventData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rectTransform == (Object)null)) { _startPosition = _rectTransform.anchoredPosition; _startPointerPosition = eventData.position; } } public void OnDrag(PointerEventData eventData) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rectTransform == (Object)null)) { Vector2 val = eventData.position - _startPointerPosition; _rectTransform.anchoredPosition = _startPosition + val; } } public void OnEndDrag(PointerEventData eventData) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rectTransform == (Object)null)) { DragEnded?.Invoke(_rectTransform.anchoredPosition); } } } internal sealed class SkillBarPrefabController : MonoBehaviour { private const float DisplayDuration = 2f; private const float GainPulseScale = 1.5f; private const float GainPulseDuration = 0.25f; private readonly Dictionary<SkillType, SkillBarViewModel> _skillBars = new Dictionary<SkillType, SkillBarViewModel>(); private readonly List<SkillType> _activeSkills = new List<SkillType>(); private readonly Dictionary<SkillType, float> _gainPulseTimes = new Dictionary<SkillType, float>(); private GameObject _canvasObject; private GameObject _skillBarsObject; private RectTransform _container; private GameObject _skillBarTemplate; private SkillBarDragHandler _dragHandler; private GameObject _dragArea; private TextMeshProUGUI _dragText; internal static SkillBarPrefabController Instance { get; private set; } private void Awake() { Instance = this; Plugin.EnableDragging.SettingChanged += OnEnableDraggingChanged; } private void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (_activeSkills.Count == 0) { return; } for (int num = _activeSkills.Count - 1; num >= 0; num--) { SkillType val = _activeSkills[num]; SkillBarViewModel skillBarViewModel = _skillBars[val]; UpdateGainPulse(val, skillBarViewModel); if (!(Time.time < skillBarViewModel.HideTime)) { skillBarViewModel.GameObject.SetActive(false); skillBarViewModel.IsVisible = false; ((Transform)((TMP_Text)skillBarViewModel.GainText).rectTransform).localScale = Vector3.one; ((TMP_Text)skillBarViewModel.GainText).fontStyle = (FontStyles)0; _gainPulseTimes.Remove(val); _activeSkills.RemoveAt(num); } } } internal void CreateUi() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvasObject != (Object)null) && !((Object)(object)Plugin.SkillBarPrefab == (Object)null)) { _canvasObject = new GameObject("HexSkillBarPrefabCanvas"); _canvasObject.transform.SetParent(((Component)this).transform, false); Canvas obj = _canvasObject.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.overrideSorting = true; obj.sortingOrder = 400; CanvasScaler obj2 = _canvasObject.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; _canvasObject.AddComponent<GraphicRaycaster>(); _skillBarsObject = Object.Instantiate<GameObject>(Plugin.SkillBarPrefab, _canvasObject.transform, false); ((Object)_skillBarsObject).name = "HexSkillBarsRuntime"; _container = _skillBarsObject.GetComponent<RectTransform>(); if ((Object)(object)_container != (Object)null) { _container.anchoredPosition = new Vector2(Plugin.OverlayPositionX.Value, Plugin.OverlayPositionY.Value); } Transform obj3 = _skillBarsObject.transform.Find("SkillBar"); _skillBarTemplate = ((obj3 != null) ? ((Component)obj3).gameObject : null); Transform obj4 = _skillBarsObject.transform.Find("DragArea"); _dragArea = ((obj4 != null) ? ((Component)obj4).gameObject : null); GameObject dragArea = _dragArea; object dragText; if (dragArea == null) { dragText = null; } else { Transform obj5 = dragArea.transform.Find("DragText"); dragText = ((obj5 != null) ? ((Component)obj5).GetComponent<TextMeshProUGUI>() : null); } _dragText = (TextMeshProUGUI)dragText; if (!((Object)(object)_container == (Object)null) && !((Object)(object)_skillBarTemplate == (Object)null) && !((Object)(object)_dragArea == (Object)null) && !((Object)(object)_dragText == (Object)null) && ConfigureText(_dragText)) { _dragHandler = _skillBarsObject.AddComponent<SkillBarDragHandler>(); _dragHandler.DragEnded = OnDragEnded; ((Behaviour)_dragHandler).enabled = Plugin.EnableDragging.Value; _dragArea.SetActive(Plugin.EnableDragging.Value); _skillBarTemplate.SetActive(false); } } } private void OnEnableDraggingChanged(object sender, EventArgs eventArgs) { bool value = Plugin.EnableDragging.Value; if ((Object)(object)_dragHandler != (Object)null) { ((Behaviour)_dragHandler).enabled = value; } if ((Object)(object)_dragArea != (Object)null) { _dragArea.SetActive(value); } } private void OnDestroy() { if (Plugin.EnableDragging != null) { Plugin.EnableDragging.SettingChanged -= OnEnableDraggingChanged; } if ((Object)(object)_canvasObject != (Object)null) { Object.Destroy((Object)(object)_canvasObject); _canvasObject = null; } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } internal unsafe void ShowSkill(SkillType skillType, Sprite icon, float level, float progress, float gain) { //IL_0006: 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_00b1: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!_skillBars.TryGetValue(skillType, out var value)) { value = CreateSkillBar(skillType); if (value == null) { return; } _skillBars.Add(skillType, value); } value.SkillIcon.sprite = icon; ((Behaviour)value.SkillIcon).enabled = (Object)(object)icon != (Object)null; ((TMP_Text)value.LevelText).text = ((int)level).ToString(); ((TMP_Text)value.SkillNameText).text = ((object)(*(SkillType*)(&skillType))/*cast due to .constrained prefix*/).ToString(); ((TMP_Text)value.GainText).text = $"+{gain:0.##}"; ((TMP_Text)value.GainText).fontStyle = (FontStyles)1; ((Transform)((TMP_Text)value.GainText).rectTransform).localScale = Vector3.one * 1.5f; float num = Mathf.Clamp01(progress); value.ProgressFillRect.anchorMax = new Vector2(num, 1f); value.HideTime = Time.time + 2f; _gainPulseTimes[skillType] = Time.time; if (!value.IsVisible) { value.GameObject.SetActive(true); value.IsVisible = true; _activeSkills.Add(skillType); } } private SkillBarViewModel CreateSkillBar(SkillType skillType) { //IL_0037: 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) if ((Object)(object)_skillBarTemplate == (Object)null || (Object)(object)_container == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(_skillBarTemplate, (Transform)(object)_container, false); ((Object)val).name = $"SkillBar_{skillType}"; RectTransform component = val.GetComponent<RectTransform>(); Transform obj = val.transform.Find("SkillIcon"); Image val2 = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); Transform obj2 = val.transform.Find("Background/Fill"); Image val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); Transform obj3 = val.transform.Find("Background/Level"); TextMeshProUGUI val4 = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null); Transform obj4 = val.transform.Find("Background/SkillName"); TextMeshProUGUI val5 = ((obj4 != null) ? ((Component)obj4).GetComponent<TextMeshProUGUI>() : null); Transform obj5 = val.transform.Find("Gain"); TextMeshProUGUI val6 = ((obj5 != null) ? ((Component)obj5).GetComponent<TextMeshProUGUI>() : null); if ((Object)(object)component == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { Plugin.Log.LogError((object)$"SkillBar prefab hierarchy is invalid for {skillType}."); Object.Destroy((Object)(object)val); return null; } if (!ConfigureText(val4) || !ConfigureText(val5) || !ConfigureText(val6)) { Object.Destroy((Object)(object)val); return null; } val.SetActive(false); return new SkillBarViewModel(val, component, val2, val3, ((Graphic)val3).rectTransform, val4, val5, val6); } private void UpdateGainPulse(SkillType skillType, SkillBarViewModel skillBar) { //IL_0006: 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_006e: 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_003c: Unknown result type (might be due to invalid IL or missing references) if (_gainPulseTimes.TryGetValue(skillType, out var value)) { float num = Time.time - value; if (num >= 0.25f) { ((Transform)((TMP_Text)skillBar.GainText).rectTransform).localScale = Vector3.one; _gainPulseTimes.Remove(skillType); } else { float num2 = num / 0.25f; float num3 = Mathf.Lerp(1.5f, 1f, num2); ((Transform)((TMP_Text)skillBar.GainText).rectTransform).localScale = Vector3.one * num3; } } } private static bool ConfigureText(TextMeshProUGUI text) { if ((Object)(object)Hud.instance == (Object)null || (Object)(object)Hud.instance.m_healthText == (Object)null) { return false; } ((TMP_Text)text).font = Hud.instance.m_healthText.font; ((TMP_Text)text).fontSharedMaterial = Hud.instance.m_healthText.fontSharedMaterial; ((Graphic)text).raycastTarget = false; return true; } private static void OnDragEnded(Vector2 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Plugin.OverlayPositionX.Value = position.x; Plugin.OverlayPositionY.Value = position.y; } } } namespace HexSkillBarOverlay.UI.Models { internal sealed class SkillBarViewModel { internal GameObject GameObject { get; } internal RectTransform RectTransform { get; } internal Image SkillIcon { get; } internal Image ProgressFill { get; } internal RectTransform ProgressFillRect { get; } internal TextMeshProUGUI LevelText { get; } internal TextMeshProUGUI SkillNameText { get; } internal TextMeshProUGUI GainText { get; } internal float HideTime { get; set; } internal bool IsVisible { get; set; } internal SkillBarViewModel(GameObject gameObject, RectTransform rectTransform, Image skillIcon, Image progressFill, RectTransform progressFillRect, TextMeshProUGUI levelText, TextMeshProUGUI skillNameText, TextMeshProUGUI gainText) { GameObject = gameObject; RectTransform = rectTransform; SkillIcon = skillIcon; ProgressFill = progressFill; ProgressFillRect = progressFillRect; LevelText = levelText; SkillNameText = skillNameText; GainText = gainText; } } } namespace HexSkillBarOverlay.Patches { [HarmonyPatch(typeof(Player), "SetLocalPlayer")] internal static class PlayerSetLocalPlayerPatch { private static void Postfix() { SkillBarPrefabController.Instance?.CreateUi(); } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] internal static class SkillsRaiseSkillPatch { private struct SkillProgressState { internal float Level; internal float Progress; } private static void Prefix(Skills __instance, SkillType skillType, out SkillProgressState __state) { //IL_001f: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown __state = default(SkillProgressState); if (!((Object)(object)Plugin.SkillsPlayerField.Invoke(__instance) != (Object)(object)Player.m_localPlayer) && (int)skillType != 0) { Skill val = (Skill)Plugin.SkillsGetSkillMethod.Invoke((object)__instance, new object[1] { skillType }); if (val != null) { __state.Level = Plugin.SkillLevelField.Invoke(val); __state.Progress = (float)Plugin.SkillGetLevelPercentageMethod.Invoke((object)val, Array.Empty<object>()); } } } private static void Postfix(Skills __instance, SkillType skillType, SkillProgressState __state) { //IL_0018: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Plugin.SkillsPlayerField.Invoke(__instance) != (Object)(object)Player.m_localPlayer || (int)skillType == 0) { return; } Skill val = (Skill)Plugin.SkillsGetSkillMethod.Invoke((object)__instance, new object[1] { skillType }); if (val != null) { SkillDef val2 = Plugin.SkillInfoField.Invoke(val); if (val2 != null) { float num = Plugin.SkillLevelField.Invoke(val); float num2 = (float)Plugin.SkillGetLevelPercentageMethod.Invoke((object)val, Array.Empty<object>()); float gain = (Mathf.Floor(num) - Mathf.Floor(__state.Level)) * 100f + (num2 - __state.Progress) * 100f; Sprite icon = Plugin.SkillIconField.Invoke(val2); SkillBarPrefabController.Instance?.ShowSkill(skillType, icon, num, num2, gain); } } } } }