Decompiled source of BloodCraftHub v0.14.0
BloodCraftHub.dll
Decompiled a day 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.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Timers; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BloodCraftHub.Behaviors; using BloodCraftHub.Config; using BloodCraftHub.Resources; using BloodCraftHub.Services; using BloodCraftHub.UI; using BloodCraftHub.UI.Forms; using BloodCraftHub.UI.Framework.CustomLib; using BloodCraftHub.UI.Framework.CustomLib.Controls; using BloodCraftHub.UI.Framework.CustomLib.Panel; using BloodCraftHub.UI.Framework.CustomLib.Util; using BloodCraftHub.UI.Framework.ModernLib; using BloodCraftHub.UI.Framework.UniverseLib.UI; using BloodCraftHub.UI.Framework.UniverseLib.UI.Models; using BloodCraftHub.UI.Framework.UniverseLib.UI.ObjectPool; using BloodCraftHub.UI.Framework.UniverseLib.UI.Panels; using BloodCraftHub.UI.Framework.UniverseLib.UI.Widgets; using BloodCraftHub.UI.Framework.UniverseLib.UI.Widgets.ScrollView; using BloodCraftHub.UI.ModContent; using BloodCraftHub.UI.ModContent.Data; using BloodCraftHub.Utils; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Network; using ProjectM.Scripting; using ProjectM.UI; using Stunlock.Core; using TMPro; using Unity.Collections; using Unity.Entities; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("kdpen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Unified client UI for V Rising's Bloodcraft mod. Surfaces every Bloodcraft, KindredCommands, and KindredLogistics chat command as buttons + forms.")] [assembly: AssemblyFileVersion("0.14.0.0")] [assembly: AssemblyInformationalVersion("0.14.0+b0b839b6e4b535a43e18461164d7b185266c4a63")] [assembly: AssemblyProduct("BloodCraftHub")] [assembly: AssemblyTitle("BloodCraftHub")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.14.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BloodCraftHub { internal static class Core { private static World _client; public static World ClientWorld => _client; public static EntityManager EntityManager => _client.EntityManager; public static ManualLogSource Log => Plugin.LogInstance; public static bool HasInitialized { get; private set; } public static Entity LocalCharacter { get; set; } = Entity.Null; public static Entity LocalUser { get; set; } = Entity.Null; public static byte[] SharedKey { get; set; } public static void Initialize(World clientWorld) { if (!HasInitialized) { _client = clientWorld; HasInitialized = true; Log.LogInfo((object)"Core initialized on client world."); } } public static void Reset() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) _client = null; LocalCharacter = Entity.Null; LocalUser = Entity.Null; SharedKey = null; HasInitialized = false; } } [BepInProcess("VRising.exe")] [BepInPlugin("BloodCraftHub", "BloodCraftHub", "0.14.0")] public class Plugin : BasePlugin { public const bool IS_TESTING = false; private static World _client; private Harmony _harmony; public static Plugin Instance { get; private set; } public static ManualLogSource LogInstance => ((BasePlugin)Instance).Log; public static Settings Settings { get; private set; } public static BCHubUIManager UIManager { get; private set; } public static CoreUpdateBehavior CoreUpdateBehavior { get; private set; } public static bool IsClient { get; private set; } public static bool IsInitialized { get; private set; } public static bool IsGameDataInitialized { get; set; } public static EntityManager EntityManager => _client.EntityManager; public static Entity LocalCharacter { get; set; } = Entity.Null; public static bool IsClientNull() { return _client == null; } public override void Load() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown Instance = this; IsClient = Application.productName != "VRisingServer"; LogUtils.Init(((BasePlugin)this).Log); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (!IsClient) { ManualLogSource log = ((BasePlugin)this).Log; val = new BepInExInfoLogInterpolatedStringHandler(45, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BloodCraftHub"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.14.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] is a client mod — not loading on server ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Application.productName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } log.LogInfo(val); return; } Settings = new Settings().InitConfig(); Theme.UIFontMultiplier = Settings.UITextScale; Theme.OverlayFontMultiplier = Settings.OverlayTextScale; EclipseProtocolService.Initialize(); UIManager = new BCHubUIManager(); CoreUpdateBehavior = new CoreUpdateBehavior(); CoreUpdateBehavior.Setup(); CoreUpdateBehavior.Actions.Add(MessageService.ProcessAllMessages); CoreUpdateBehavior.Actions.Add(MessageService.TickInterceptTimeouts); CoreUpdateBehavior.Actions.Add(VBloodScannerService.Tick); CoreUpdateBehavior.Actions.Add(ShiftCooldownService.Tick); CoreUpdateBehavior.Actions.Add(TooltipHover.TickAll); CoreUpdateBehavior.Actions.Add(FormDropdownRegistry.TickCloseOnOutsideClick); CoreUpdateBehavior.Actions.Add(SliderClickRegistry.TickClickOnTrack); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "BloodCraftHub"); IsInitialized = true; ManualLogSource log2 = ((BasePlugin)this).Log; val = new BepInExInfoLogInterpolatedStringHandler(17, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BloodCraftHub"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.14.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded."); } log2.LogInfo(val); } public override bool Unload() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } public static void UIOnInitialize() { if (!UIManager.IsInitialized) { UIManager.SetupAndShowUI(); UIManager.RestoreOverlaysFromSettings(); VBloodScannerService.Initialize(); LogUtils.LogInfo("UI Manager initialized."); } } public static void GameDataOnInitialize(World world) { if (!IsGameDataInitialized && IsClient) { _client = world; IsGameDataInitialized = true; LogUtils.LogInfo("Client world bound; game data initialized."); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BloodCraftHub"; public const string PLUGIN_NAME = "BloodCraftHub"; public const string PLUGIN_VERSION = "0.14.0"; } } namespace BloodCraftHub.Utils { public static class Extensions { private static EntityManager EntityManager => Plugin.EntityManager; public static Color GetTransparent(this Color baseColor, float alpha = 0.7f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) return new Color(baseColor.r, baseColor.g, baseColor.b, alpha); } public static bool Has<T>(this Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = EntityManager; return ((EntityManager)(ref entityManager)).HasComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0)); } public unsafe static T Read<T>(this Entity entity) where T : struct { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) TypeIndex typeIndex = new ComponentType(Il2CppType.Of<T>(), (AccessMode)0).TypeIndex; EntityManager entityManager = EntityManager; return Marshal.PtrToStructure<T>(new IntPtr(((EntityManager)(ref entityManager)).GetComponentDataRawRO(entity, typeIndex))); } public unsafe static void Write<T>(this Entity entity, T componentData) where T : struct { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_003e: Unknown result type (might be due to invalid IL or missing references) TypeIndex typeIndex = new ComponentType(Il2CppType.Of<T>(), (AccessMode)0).TypeIndex; byte[] array = StructureToByteArray(componentData); int num = Marshal.SizeOf<T>(); fixed (byte* ptr = array) { EntityManager entityManager = EntityManager; ((EntityManager)(ref entityManager)).SetComponentDataRaw(entity, typeIndex, (void*)ptr, num); } } public static bool HasValue(this Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return entity != Entity.Null; } private static byte[] StructureToByteArray<T>(T structure) where T : struct { int num = Marshal.SizeOf(structure); byte[] array = new byte[num]; IntPtr intPtr = Marshal.AllocHGlobal(num); try { Marshal.StructureToPtr(structure, intPtr, fDeleteOld: true); Marshal.Copy(intPtr, array, 0, num); return array; } finally { Marshal.FreeHGlobal(intPtr); } } } public static class LogUtils { private static ManualLogSource _log; public static void Init(ManualLogSource log) { _log = log; } public static void LogInfo(object msg) { ManualLogSource log = _log; if (log != null) { log.LogInfo(msg); } } public static void LogWarning(object msg) { ManualLogSource log = _log; if (log != null) { log.LogWarning(msg); } } public static void LogError(object msg) { ManualLogSource log = _log; if (log != null) { log.LogError(msg); } } public static void LogDebug(object msg) { ManualLogSource log = _log; if (log != null) { log.LogDebug(msg); } } } } namespace BloodCraftHub.UI { public class BCHubUIManager : UIManagerBase { private readonly List<IPanelBase> _panels = new List<IPanelBase>(); private FloatingButtonPanel _floatingButton; private MainPanel _mainPanel; private ExperienceOverlayPanel _experienceOverlay; private FamiliarOverlayPanel _familiarOverlay; private FamiliarBrowserOverlayPanel _familiarBrowserOverlay; private DailyQuestOverlayPanel _dailyQuestOverlay; private ProfessionOverlayPanel _professionOverlay; private ShiftSpellOverlayPanel _shiftSpellOverlay; private CombinedOverlayPanel _combinedOverlay; private bool _overlaysSuppressed; private Action _deferredMainPanelRebuild; private Action _deferredOverlayRebuild; public bool IsMainPanelOpen { get { if (_mainPanel != null) { return _mainPanel.Enabled; } return false; } } public MainPanel MainPanel => _mainPanel; public ExperienceOverlayPanel ExperienceOverlay => _experienceOverlay; public FamiliarOverlayPanel FamiliarOverlay => _familiarOverlay; public FamiliarBrowserOverlayPanel FamiliarBrowserOverlay => _familiarBrowserOverlay; public DailyQuestOverlayPanel DailyQuestOverlay => _dailyQuestOverlay; public ProfessionOverlayPanel ProfessionOverlay => _professionOverlay; public ShiftSpellOverlayPanel ShiftSpellOverlay => _shiftSpellOverlay; public CombinedOverlayPanel CombinedOverlay => _combinedOverlay; public bool AreOverlaysSuppressed => _overlaysSuppressed; public void ApplyOverlayLockState() { bool lockOverlays = Settings.LockOverlays; ApplyPinnedTo(_experienceOverlay, lockOverlays); ApplyPinnedTo(_familiarOverlay, lockOverlays); ApplyPinnedTo(_familiarBrowserOverlay, lockOverlays); ApplyPinnedTo(_dailyQuestOverlay, lockOverlays); ApplyPinnedTo(_professionOverlay, lockOverlays); ApplyPinnedTo(_shiftSpellOverlay, lockOverlays); ApplyPinnedTo(_combinedOverlay, lockOverlays); } private static void ApplyPinnedTo(ResizeablePanelBase panel, bool pinned) { if (panel != null) { panel.IsPinned = pinned; } } public override void Reset() { base.Reset(); foreach (IPanelBase panel in _panels) { if (panel is ResizeablePanelBase resizeablePanelBase) { resizeablePanelBase.Reset(); } panel.Destroy(); } _panels.Clear(); _floatingButton = null; _mainPanel = null; _experienceOverlay = null; _familiarOverlay = null; _familiarBrowserOverlay = null; _dailyQuestOverlay = null; _professionOverlay = null; _combinedOverlay = null; _shiftSpellOverlay = null; } protected override void AddMainContentPanel() { _floatingButton = new FloatingButtonPanel(base.UiBase); _panels.Add(_floatingButton); } public override void SetActive(bool active) { _floatingButton?.SetActive(active); _mainPanel?.SetActive(active && IsMainPanelOpen); _experienceOverlay?.SetActive(active && (_experienceOverlay?.Enabled ?? false)); _familiarOverlay?.SetActive(active && (_familiarOverlay?.Enabled ?? false)); _familiarBrowserOverlay?.SetActive(active && (_familiarBrowserOverlay?.Enabled ?? false)); _dailyQuestOverlay?.SetActive(active && (_dailyQuestOverlay?.Enabled ?? false)); _professionOverlay?.SetActive(active && (_professionOverlay?.Enabled ?? false)); _shiftSpellOverlay?.SetActive(active && (_shiftSpellOverlay?.Enabled ?? false)); } public void ToggleMainPanel() { EnsureMainPanel(); _mainPanel.SetActive(!_mainPanel.Enabled); } public void ShowTab(PanelType tab) { EnsureMainPanel(); _mainPanel.SetActive(active: true); _mainPanel.ShowTab(tab); } public void ToggleOverlay(PanelType overlay) { switch (overlay) { case PanelType.ExperienceOverlay: EnsureExperienceOverlay(); _experienceOverlay.SetActive(!_experienceOverlay.Enabled); Settings.SetShowExperienceOverlay(_experienceOverlay.Enabled); break; case PanelType.FamiliarOverlay: EnsureFamiliarOverlay(); _familiarOverlay.SetActive(!_familiarOverlay.Enabled); Settings.SetShowFamiliarOverlay(_familiarOverlay.Enabled); break; case PanelType.FamiliarBrowserOverlay: EnsureFamiliarBrowserOverlay(); _familiarBrowserOverlay.SetActive(!_familiarBrowserOverlay.Enabled); Settings.SetShowFamiliarBrowser(_familiarBrowserOverlay.Enabled); break; case PanelType.DailyQuestOverlay: EnsureDailyQuestOverlay(); _dailyQuestOverlay.SetActive(!_dailyQuestOverlay.Enabled); Settings.SetShowDailyQuestOverlay(_dailyQuestOverlay.Enabled); break; case PanelType.ProfessionOverlay: EnsureProfessionOverlay(); _professionOverlay.SetActive(!_professionOverlay.Enabled); Settings.SetShowProfessionOverlay(_professionOverlay.Enabled); break; case PanelType.ShiftSpellOverlay: EnsureShiftSpellOverlay(); _shiftSpellOverlay.SetActive(!_shiftSpellOverlay.Enabled); Settings.SetShowShiftSpellOverlay(_shiftSpellOverlay.Enabled); break; case PanelType.CombinedOverlay: Settings.SetShowCombinedOverlay(!(_combinedOverlay?.Enabled ?? false)); ApplyCombinedOverlayMutualExclusion(); break; default: throw new ArgumentOutOfRangeException("overlay", overlay, "Not a secondary overlay."); } } public void ApplyCombinedOverlayMutualExclusion() { if (Settings.ShowCombinedOverlay) { EnsureCombinedOverlay(); _combinedOverlay.SetActive(active: true); EnsureExperienceOverlay(); _experienceOverlay.SetActive(active: false); _familiarOverlay?.SetActive(active: false); _dailyQuestOverlay?.SetActive(active: false); _professionOverlay?.SetActive(active: false); return; } _combinedOverlay?.SetActive(active: false); if (Settings.ShowExperienceOverlay) { EnsureExperienceOverlay(); _experienceOverlay.SetActive(active: true); } if (Settings.ShowFamiliarOverlay) { EnsureFamiliarOverlay(); _familiarOverlay.SetActive(active: true); } if (Settings.ShowDailyQuestOverlay) { EnsureDailyQuestOverlay(); _dailyQuestOverlay.SetActive(active: true); } if (Settings.ShowProfessionOverlay) { EnsureProfessionOverlay(); _professionOverlay.SetActive(active: true); } } public void RefreshCombinedOverlaySections() { _combinedOverlay?.RefreshSections(); } public void ToggleAllOverlaysSuppressed() { _overlaysSuppressed = !_overlaysSuppressed; Settings.OverlaysSuppressedByUser = _overlaysSuppressed; ApplyOverlaySuppression(); } private void ApplyOverlaySuppression() { if (_overlaysSuppressed) { _experienceOverlay?.SetActive(active: false); _familiarOverlay?.SetActive(active: false); _familiarBrowserOverlay?.SetActive(active: false); _dailyQuestOverlay?.SetActive(active: false); _professionOverlay?.SetActive(active: false); _shiftSpellOverlay?.SetActive(active: false); _combinedOverlay?.SetActive(active: false); return; } if (Settings.ShowExperienceOverlay) { EnsureExperienceOverlay(); _experienceOverlay.SetActive(active: true); } if (Settings.ShowFamiliarOverlay) { EnsureFamiliarOverlay(); _familiarOverlay.SetActive(active: true); } if (Settings.ShowFamiliarBrowser) { EnsureFamiliarBrowserOverlay(); _familiarBrowserOverlay.SetActive(active: true); } if (Settings.ShowDailyQuestOverlay) { EnsureDailyQuestOverlay(); _dailyQuestOverlay.SetActive(active: true); } if (Settings.ShowProfessionOverlay) { EnsureProfessionOverlay(); _professionOverlay.SetActive(active: true); } if (Settings.ShowShiftSpellOverlay) { EnsureShiftSpellOverlay(); _shiftSpellOverlay.SetActive(active: true); } } public void RestoreOverlaysFromSettings() { if (Settings.ShowCombinedOverlay) { ApplyCombinedOverlayMutualExclusion(); } else { if (Settings.ShowExperienceOverlay) { EnsureExperienceOverlay(); _experienceOverlay.SetActive(active: true); } if (Settings.ShowFamiliarOverlay) { EnsureFamiliarOverlay(); _familiarOverlay.SetActive(active: true); } if (Settings.ShowDailyQuestOverlay) { EnsureDailyQuestOverlay(); _dailyQuestOverlay.SetActive(active: true); } if (Settings.ShowProfessionOverlay) { EnsureProfessionOverlay(); _professionOverlay.SetActive(active: true); } } if (Settings.ShowFamiliarBrowser) { EnsureFamiliarBrowserOverlay(); _familiarBrowserOverlay.SetActive(active: true); } if (Settings.ShowShiftSpellOverlay) { EnsureShiftSpellOverlay(); _shiftSpellOverlay.SetActive(active: true); } if (Settings.ShowCombinedOverlay) { ApplyCombinedOverlayMutualExclusion(); } } public bool IsOverlayOpen(PanelType overlay) { return overlay switch { PanelType.ExperienceOverlay => _experienceOverlay?.Enabled ?? false, PanelType.FamiliarOverlay => _familiarOverlay?.Enabled ?? false, PanelType.FamiliarBrowserOverlay => _familiarBrowserOverlay?.Enabled ?? false, PanelType.DailyQuestOverlay => _dailyQuestOverlay?.Enabled ?? false, PanelType.ProfessionOverlay => _professionOverlay?.Enabled ?? false, PanelType.ShiftSpellOverlay => _shiftSpellOverlay?.Enabled ?? false, PanelType.CombinedOverlay => _combinedOverlay?.Enabled ?? false, _ => false, }; } private void EnsureMainPanel() { if (_mainPanel == null) { _mainPanel = new MainPanel(base.UiBase); _panels.Add(_mainPanel); _mainPanel.SetActive(active: false); } } private void EnsureExperienceOverlay() { if (_experienceOverlay == null) { _experienceOverlay = new ExperienceOverlayPanel(base.UiBase); _panels.Add(_experienceOverlay); _experienceOverlay.SetActive(active: false); } } private void EnsureFamiliarBrowserOverlay() { if (_familiarBrowserOverlay == null) { _familiarBrowserOverlay = new FamiliarBrowserOverlayPanel(base.UiBase); _panels.Add(_familiarBrowserOverlay); _familiarBrowserOverlay.SetActive(active: false); } } private void EnsureDailyQuestOverlay() { if (_dailyQuestOverlay == null) { _dailyQuestOverlay = new DailyQuestOverlayPanel(base.UiBase); _panels.Add(_dailyQuestOverlay); _dailyQuestOverlay.SetActive(active: false); } } private void EnsureFamiliarOverlay() { if (_familiarOverlay == null) { _familiarOverlay = new FamiliarOverlayPanel(base.UiBase); _panels.Add(_familiarOverlay); _familiarOverlay.SetActive(active: false); } } private void EnsureProfessionOverlay() { if (_professionOverlay == null) { _professionOverlay = new ProfessionOverlayPanel(base.UiBase); _panels.Add(_professionOverlay); _professionOverlay.SetActive(active: false); } } private void EnsureShiftSpellOverlay() { if (_shiftSpellOverlay == null) { _shiftSpellOverlay = new ShiftSpellOverlayPanel(base.UiBase); _panels.Add(_shiftSpellOverlay); _shiftSpellOverlay.SetActive(active: false); } } private void EnsureCombinedOverlay() { if (_combinedOverlay == null) { _combinedOverlay = new CombinedOverlayPanel(base.UiBase); _panels.Add(_combinedOverlay); _combinedOverlay.SetActive(active: false); } } public void RefreshAllOpacities() { _experienceOverlay?.RefreshOpacity(); _familiarOverlay?.RefreshOpacity(); _familiarBrowserOverlay?.RefreshOpacity(); _dailyQuestOverlay?.RefreshOpacity(); _professionOverlay?.RefreshOpacity(); _shiftSpellOverlay?.RefreshOpacity(); _combinedOverlay?.RefreshOpacity(); _mainPanel?.RefreshOpacity(); _floatingButton?.RefreshOpacity(); } public void RefreshAllPanelBackgrounds() { _mainPanel?.RefreshBackgroundColor(); _experienceOverlay?.RefreshBackgroundColor(); _familiarOverlay?.RefreshBackgroundColor(); _familiarBrowserOverlay?.RefreshBackgroundColor(); _dailyQuestOverlay?.RefreshBackgroundColor(); _professionOverlay?.RefreshBackgroundColor(); _shiftSpellOverlay?.RefreshBackgroundColor(); _combinedOverlay?.RefreshBackgroundColor(); } public void RefreshScopedInnerBackgrounds() { _mainPanel?.RefreshInnerBackgroundColor(); _familiarBrowserOverlay?.RefreshInnerBackgroundColor(); } public void RefreshProfessionOverlay() { _professionOverlay?.Refresh(); } public void RequestRebuildMainPanel() { if (_mainPanel != null) { CoreUpdateBehavior.Actions.Add(delegate { CoreUpdateBehavior.Actions.Remove(_deferredMainPanelRebuild); _deferredMainPanelRebuild = null; RebuildMainPanelNow(); }); } } private void RebuildMainPanelNow() { if (_mainPanel != null) { bool enabled = _mainPanel.Enabled; PanelType activeTab = _mainPanel.ActiveTab; _mainPanel?.Reset(); _mainPanel.Destroy(); _panels.Remove(_mainPanel); _mainPanel = null; if (enabled) { EnsureMainPanel(); _mainPanel.SetActive(active: true); _mainPanel.ShowTab(activeTab); } } } public void RequestRebuildAllOverlays() { CoreUpdateBehavior.Actions.Add(delegate { CoreUpdateBehavior.Actions.Remove(_deferredOverlayRebuild); _deferredOverlayRebuild = null; RebuildAllOverlaysNow(); }); } private void RebuildAllOverlaysNow() { bool showCombinedOverlay = Settings.ShowCombinedOverlay; RebuildOverlay(ref _experienceOverlay, !showCombinedOverlay && Settings.ShowExperienceOverlay, (UIBase b) => new ExperienceOverlayPanel(b)); RebuildOverlay(ref _familiarOverlay, !showCombinedOverlay && Settings.ShowFamiliarOverlay, (UIBase b) => new FamiliarOverlayPanel(b)); RebuildOverlay(ref _familiarBrowserOverlay, Settings.ShowFamiliarBrowser, (UIBase b) => new FamiliarBrowserOverlayPanel(b)); RebuildOverlay(ref _dailyQuestOverlay, !showCombinedOverlay && Settings.ShowDailyQuestOverlay, (UIBase b) => new DailyQuestOverlayPanel(b)); RebuildOverlay(ref _professionOverlay, !showCombinedOverlay && Settings.ShowProfessionOverlay, (UIBase b) => new ProfessionOverlayPanel(b)); RebuildOverlay(ref _shiftSpellOverlay, Settings.ShowShiftSpellOverlay, (UIBase b) => new ShiftSpellOverlayPanel(b)); RebuildOverlay(ref _combinedOverlay, showCombinedOverlay, (UIBase b) => new CombinedOverlayPanel(b)); _mainPanel?.RefreshAllOverlayToggleStates(); } private void RebuildOverlay<T>(ref T slot, bool wasVisibleByConfig, Func<UIBase, T> factory) where T : ResizeablePanelBase { if (slot != null) { slot.Reset(); slot.Destroy(); _panels.Remove(slot); slot = null; if (wasVisibleByConfig) { T val = factory(base.UiBase); _panels.Add(val); val.SetActive(active: true); slot = val; } } } } public static class TooltipHover { private struct Binding { public RectTransform Rt; public string Text; } private static readonly List<Binding> _bindings = new List<Binding>(); public static TextMeshProUGUI Sink; public static string IdlePlaceholder = "Hint: hover any control for help."; private static bool _firstHitLogged; public static int BindingCount => _bindings.Count; public static void Attach(GameObject target, string text) { if (!((Object)(object)target == (Object)null) && !string.IsNullOrEmpty(text)) { RectTransform component = target.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { _bindings.Add(new Binding { Rt = component, Text = text }); } } } public static void TickAll() { //IL_000e: 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) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Sink == (Object)null) { return; } Vector2 val = Vector2.op_Implicit(Input.mousePosition); string text = null; for (int num = _bindings.Count - 1; num >= 0; num--) { Binding binding = _bindings[num]; if ((Object)(object)binding.Rt == (Object)null) { _bindings.RemoveAt(num); } else if (((Component)binding.Rt).gameObject.activeInHierarchy) { Canvas componentInParent = ((Component)binding.Rt).GetComponentInParent<Canvas>(); Camera val2 = null; if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val2 = componentInParent.worldCamera; } if (RectTransformUtility.RectangleContainsScreenPoint(binding.Rt, val, val2)) { text = binding.Text; } } } ((TMP_Text)Sink).text = text ?? IdlePlaceholder; if (text == null || _firstHitLogged) { return; } _firstHitLogged = true; try { LogUtils.LogInfo($"TooltipHover: first hover registered ({_bindings.Count} bindings tracked)."); } catch { } } } } namespace BloodCraftHub.UI.ModContent { public class CombinedOverlayPanel : ResizeablePanelBase { private static readonly Color COL_XP = new Color(0.55f, 0.95f, 0.55f, 1f); private static readonly Color COL_FAMILIAR = new Color(1f, 0.78f, 0.3f, 1f); private static readonly Color COL_EXPERTISE = new Color(0.85f, 0.85f, 0.85f, 1f); private static readonly Color COL_LEGACY = new Color(1f, 0.45f, 0.45f, 1f); private static readonly Color COL_PROFS = new Color(0.95f, 0.75f, 0.35f, 1f); private static readonly Color COL_QUEST_D = new Color(0f, 1f, 1f, 1f); private static readonly Color COL_QUEST_W = new Color(1f, 0.85f, 0.3f, 1f); private GameObject _xpSection; private GameObject _familiarSection; private GameObject _expertiseSection; private GameObject _legacySection; private GameObject _profSection; private GameObject _questSection; private TextMeshProUGUI _xpLine; private TextMeshProUGUI _famNameLine; private TextMeshProUGUI _famStatsLine; private TextMeshProUGUI _wepLine; private TextMeshProUGUI _wepStatsLine; private TextMeshProUGUI _wepBonusValuesLine; private TextMeshProUGUI _wepCounterLine; private TextMeshProUGUI _blLine; private TextMeshProUGUI _blStatsLine; private TextMeshProUGUI _blBonusValuesLine; private TextMeshProUGUI _blCounterLine; private TextMeshProUGUI _profLine; private GameObject _profWrapMode; private GameObject _profRowMode; private TextMeshProUGUI _profRowEnchanting; private TextMeshProUGUI _profRowAlchemy; private TextMeshProUGUI _profRowHarvesting; private TextMeshProUGUI _profRowBlacksmithing; private TextMeshProUGUI _profRowTailoring; private TextMeshProUGUI _profRowWoodcutting; private TextMeshProUGUI _profRowMining; private TextMeshProUGUI _profRowFishing; private GameObject _profBarEnchanting; private GameObject _profBarAlchemy; private GameObject _profBarHarvesting; private GameObject _profBarBlacksmithing; private GameObject _profBarTailoring; private GameObject _profBarWoodcutting; private GameObject _profBarMining; private GameObject _profBarFishing; private RectTransform _profBarFillEnchanting; private RectTransform _profBarFillAlchemy; private RectTransform _profBarFillHarvesting; private RectTransform _profBarFillBlacksmithing; private RectTransform _profBarFillTailoring; private RectTransform _profBarFillWoodcutting; private RectTransform _profBarFillMining; private RectTransform _profBarFillFishing; private TextMeshProUGUI _dailyLine; private TextMeshProUGUI _weeklyLine; private GameObject _xpBar; private RectTransform _xpBarFill; private GameObject _famBar; private RectTransform _famBarFill; private GameObject _wepBar; private RectTransform _wepBarFill; private GameObject _blBar; private RectTransform _blBarFill; private bool _subscribed; public override string PanelId => "CombinedOverlay"; public override PanelType PanelType => PanelType.CombinedOverlay; public override int MinWidth => 360; public override int MinHeight { get { int num = ResolveRowHeight(Theme.ScaledOverlay(11)); if (Settings.ShowExperienceOverlay) { num += sectionHeight(1, Settings.ShowProgressBarXP); } if (Settings.ShowFamiliarOverlay) { num += sectionHeight(3, Settings.ShowProgressBarFamiliar); } int num2 = 3; if (Settings.ShowOverlayBonusStats) { num2 += 2; } if (Settings.ShowOverlayXpCounter) { num2++; } int num3 = 3; if (Settings.ShowOverlayBonusStats) { num3 += 2; } if (Settings.ShowOverlayXpCounter) { num3++; } if (Settings.CombinedOverlayShowExpertise) { num += sectionHeight(num2, Settings.ShowProgressBarExpertise); } if (Settings.CombinedOverlayShowLegacy) { num += sectionHeight(num3, Settings.ShowProgressBarLegacy); } if (Settings.ShowProfessionOverlay) { if (Settings.ShowProgressBarProfessions) { int num4 = 0; if (Settings.ShowProfessionEnchanting) { num4++; } if (Settings.ShowProfessionAlchemy) { num4++; } if (Settings.ShowProfessionHarvesting) { num4++; } if (Settings.ShowProfessionBlacksmithing) { num4++; } if (Settings.ShowProfessionTailoring) { num4++; } if (Settings.ShowProfessionWoodcutting) { num4++; } if (Settings.ShowProfessionMining) { num4++; } if (Settings.ShowProfessionFishing) { num4++; } num += ResolveRowHeight(Theme.ScaledOverlay(12)) + num4 * (ResolveRowHeight(Theme.ScaledOverlay(12)) + Settings.ProgressBarHeight + 2); } else { num += sectionHeight(3, barVisible: false); } } if (Settings.ShowDailyQuestOverlay) { num += sectionHeight(2, barVisible: false); } return num; static int sectionHeight(int bodyLines, bool barVisible) { return ResolveRowHeight(Theme.ScaledOverlay(12)) + bodyLines * ResolveRowHeight(Theme.ScaledOverlay(13)) + (barVisible ? (Settings.ProgressBarHeight + 2) : 0); } } } public override Vector2 DefaultAnchorMin => new Vector2(0.5f, 0.5f); public override Vector2 DefaultAnchorMax => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPivot => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPosition => new Vector2((0f - base.Owner.Scaler.m_ReferenceResolution.x) * 0.5f, base.Owner.Scaler.m_ReferenceResolution.y * 0.5f - 30f); public override bool CanDrag => true; public override PanelDragger.ResizeTypes CanResize => PanelDragger.ResizeTypes.All; public override float Opacity => Settings.TransparencyToAlpha(Settings.CombinedOverlayTransparency); public override bool UsesCustomBackgroundColor => true; public CombinedOverlayPanel(UIBase owner) : base(owner) { } protected override void LateConstructUI() { base.LateConstructUI(); if ((Object)(object)base.Rect != (Object)null) { base.Rect.SetSizeWithCurrentAnchors((Axis)1, (float)MinHeight); } } protected override void ConstructPanelContent() { base.ConstructPanelContent(); BuildXPSection(); BuildFamiliarSection(); BuildExpertiseSection(); BuildLegacySection(); BuildProfessionSection(); BuildQuestSection(); ApplySectionVisibility(); RenderAll(); if (!_subscribed) { PlayerStateService.ExperienceChanged += OnAnyChanged; PlayerStateService.FamiliarChanged += OnAnyChanged; PlayerStateService.ExpertiseChanged += OnAnyChanged; PlayerStateService.LegacyChanged += OnAnyChanged; PlayerStateService.ProfessionChanged += OnAnyChanged; PlayerStateService.QuestChanged += OnAnyChanged; PlayerStateService.LastResponseChanged += OnAnyChanged; PlayerStateService.BloodInfoChanged += OnAnyChanged; _subscribed = true; } } public void RefreshSections() { ApplySectionVisibility(); RenderAll(); if ((Object)(object)base.Rect != (Object)null) { base.Rect.SetSizeWithCurrentAnchors((Axis)1, (float)MinHeight); EnsureValidSize(); EnsureValidPosition(); if (base.Dragger != null) { base.Dragger.OnEndResize(); } } } private static int ResolveRowHeight(int fontSize) { return Mathf.Max(20, Mathf.RoundToInt((float)fontSize * 1.45f)); } private void ApplySectionVisibility() { if ((Object)(object)_xpSection != (Object)null) { _xpSection.SetActive(Settings.ShowExperienceOverlay); } if ((Object)(object)_familiarSection != (Object)null) { _familiarSection.SetActive(Settings.ShowFamiliarOverlay); } if ((Object)(object)_expertiseSection != (Object)null) { _expertiseSection.SetActive(Settings.CombinedOverlayShowExpertise); } if ((Object)(object)_legacySection != (Object)null) { _legacySection.SetActive(Settings.CombinedOverlayShowLegacy); } if ((Object)(object)_profSection != (Object)null) { _profSection.SetActive(Settings.ShowProfessionOverlay); } if ((Object)(object)_questSection != (Object)null) { _questSection.SetActive(Settings.ShowDailyQuestOverlay); } } private void OnAnyChanged() { RenderAll(); } private void RenderAll() { RenderXP(); RenderFamiliar(); RenderExpertise(); RenderLegacy(); RenderProfessions(); RenderQuests(); } private GameObject BuildSectionRoot(string name) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject obj = UIFactory.CreateVerticalGroup(base.ContentRoot, name, forceWidth: true, forceHeight: false, childControlWidth: true, childControlHeight: true, 1, new Vector4(2f, 2f, 2f, 2f), (Color?)new Color(0f, 0f, 0f, 0f), (TextAnchor?)null, 1f); UIFactory.SetLayoutElement(obj, 260, preferredWidth: 280, flexibleWidth: 1, minHeight: Theme.ScaledOverlayHeight(24), flexibleHeight: 0); return obj; } private TextMeshProUGUI AddSectionHeader(GameObject section, string title, Color color) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) LabelRef labelRef = UIFactory.CreateLabel(section, ((Object)section).name + "_Hdr", title, Theme.OverlayMidlineAlignment(), null, Theme.ScaledOverlay(12)); GameObject gameObject = labelRef.GameObject; int? minWidth = 240; int? preferredWidth = 260; int? num = 1; UIFactory.SetLayoutElement(minHeight: Theme.ScaledOverlayHeight(18), flexibleWidth: num, preferredHeight: Theme.ScaledOverlayHeight(20), gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ((TMP_Text)labelRef.TextMesh).fontStyle = (FontStyles)1; ((Graphic)labelRef.TextMesh).color = color; ((TMP_Text)labelRef.TextMesh).enableWordWrapping = false; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; return labelRef.TextMesh; } private TextMeshProUGUI AddSectionBody(GameObject section, string name, string initialText, int fontSize = 13, bool wrap = false) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) LabelRef labelRef = UIFactory.CreateLabel(section, name, initialText, Theme.OverlayMidlineAlignment(), null, Theme.ScaledOverlay(fontSize)); GameObject gameObject = labelRef.GameObject; int? minWidth = 240; int? preferredWidth = 260; int? num = 1; UIFactory.SetLayoutElement(minHeight: Theme.ScaledOverlayHeight(18), flexibleWidth: num, preferredHeight: Theme.ScaledOverlayHeight(20), gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ((TMP_Text)labelRef.TextMesh).enableWordWrapping = wrap; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; if (wrap) { ContentSizeFitter obj = labelRef.GameObject.AddComponent<ContentSizeFitter>(); obj.horizontalFit = (FitMode)0; obj.verticalFit = (FitMode)2; } return labelRef.TextMesh; } private GameObject AddMiniBar(GameObject section, string name, Color fillColor, out RectTransform fill) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) GameObject obj = MiniBar.Create(section, name, out fill, fillColor, Settings.ProgressBarHeight); obj.SetActive(false); return obj; } private void BuildXPSection() { //IL_001d: 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) _xpSection = BuildSectionRoot("XPSection"); AddSectionHeader(_xpSection, "EXPERIENCE", COL_XP); _xpLine = AddSectionBody(_xpSection, "XPLine", "Lv —"); _xpBar = AddMiniBar(_xpSection, "XPBar", new Color(0.55f, 0.95f, 0.55f, 0.95f), out _xpBarFill); } private void BuildFamiliarSection() { //IL_001d: 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) _familiarSection = BuildSectionRoot("FamiliarSection"); AddSectionHeader(_familiarSection, "FAMILIAR", COL_FAMILIAR); _famNameLine = AddSectionBody(_familiarSection, "FamName", "(no familiar bound)"); _famBar = AddMiniBar(_familiarSection, "FamBar", new Color(1f, 0.6f, 0.2f, 0.95f), out _famBarFill); _famStatsLine = AddSectionBody(_familiarSection, "FamStats", "—", 12, wrap: true); } private void BuildExpertiseSection() { //IL_001d: 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) _expertiseSection = BuildSectionRoot("ExpertiseSection"); AddSectionHeader(_expertiseSection, "WEAPON EXPERTISE", COL_EXPERTISE); _wepLine = AddSectionBody(_expertiseSection, "WepLine", "—"); _wepBar = AddMiniBar(_expertiseSection, "WepBar", new Color(0.75f, 0.75f, 0.85f, 0.95f), out _wepBarFill); _wepStatsLine = AddSectionBody(_expertiseSection, "WepStats", "—", 12, wrap: true); _wepBonusValuesLine = AddSectionBody(_expertiseSection, "WepBonusValues", "", 11, wrap: true); ((TMP_Text)_wepBonusValuesLine).fontStyle = (FontStyles)2; ((Component)_wepBonusValuesLine).gameObject.SetActive(false); _wepCounterLine = AddSectionBody(_expertiseSection, "WepCounter", "", 11); ((TMP_Text)_wepCounterLine).fontStyle = (FontStyles)2; ((Component)_wepCounterLine).gameObject.SetActive(false); } private void BuildLegacySection() { //IL_001d: 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) _legacySection = BuildSectionRoot("LegacySection"); AddSectionHeader(_legacySection, "BLOOD LEGACY", COL_LEGACY); _blLine = AddSectionBody(_legacySection, "BlLine", "—"); _blBar = AddMiniBar(_legacySection, "BlBar", new Color(0.85f, 0.3f, 0.3f, 0.95f), out _blBarFill); _blStatsLine = AddSectionBody(_legacySection, "BlStats", "—", 12, wrap: true); _blBonusValuesLine = AddSectionBody(_legacySection, "BlBonusValues", "", 11, wrap: true); ((TMP_Text)_blBonusValuesLine).fontStyle = (FontStyles)2; ((Component)_blBonusValuesLine).gameObject.SetActive(false); _blCounterLine = AddSectionBody(_legacySection, "BlCounter", "", 11); ((TMP_Text)_blCounterLine).fontStyle = (FontStyles)2; ((Component)_blCounterLine).gameObject.SetActive(false); } private void BuildProfessionSection() { //IL_001d: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: 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_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) _profSection = BuildSectionRoot("ProfSection"); AddSectionHeader(_profSection, "PROFESSIONS", COL_PROFS); _profWrapMode = UIFactory.CreateVerticalGroup(_profSection, "ProfWrapMode", forceWidth: true, forceHeight: false, childControlWidth: true, childControlHeight: true, 0, new Vector4(0f, 0f, 0f, 0f), (Color?)new Color(0f, 0f, 0f, 0f), (TextAnchor?)null, 1f); UIFactory.SetLayoutElement(_profWrapMode, 240, preferredWidth: 320, flexibleWidth: 1, minHeight: Theme.ScaledOverlayHeight(18), flexibleHeight: 0); LabelRef labelRef = UIFactory.CreateLabel(_profWrapMode, "ProfLine", "—", Theme.OverlayMidlineAlignment(), null, Theme.ScaledOverlay(12)); UIFactory.SetLayoutElement(labelRef.GameObject, 240, preferredWidth: 320, flexibleWidth: 1, minHeight: Theme.ScaledOverlayHeight(18), flexibleHeight: 0); ((TMP_Text)labelRef.TextMesh).enableWordWrapping = true; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; ContentSizeFitter obj = labelRef.GameObject.AddComponent<ContentSizeFitter>(); obj.horizontalFit = (FitMode)0; obj.verticalFit = (FitMode)2; _profLine = labelRef.TextMesh; _profRowMode = UIFactory.CreateVerticalGroup(_profSection, "ProfRowMode", forceWidth: true, forceHeight: false, childControlWidth: true, childControlHeight: true, 1, new Vector4(0f, 0f, 0f, 0f), (Color?)new Color(0f, 0f, 0f, 0f), (TextAnchor?)null, 1f); UIFactory.SetLayoutElement(_profRowMode, 240, preferredWidth: 320, flexibleWidth: 1, minHeight: Theme.ScaledOverlayHeight(18), flexibleHeight: 0); Color fillColor = default(Color); ((Color)(ref fillColor))..ctor(0.95f, 0.75f, 0.35f, 0.95f); _profRowEnchanting = AddProfRow(_profRowMode, "ProfRow_Enchanting", "Enchanting —"); _profBarEnchanting = AddMiniBar(_profRowMode, "ProfBar_Enchanting", fillColor, out _profBarFillEnchanting); _profRowAlchemy = AddProfRow(_profRowMode, "ProfRow_Alchemy", "Alchemy —"); _profBarAlchemy = AddMiniBar(_profRowMode, "ProfBar_Alchemy", fillColor, out _profBarFillAlchemy); _profRowHarvesting = AddProfRow(_profRowMode, "ProfRow_Harvesting", "Harvesting —"); _profBarHarvesting = AddMiniBar(_profRowMode, "ProfBar_Harvesting", fillColor, out _profBarFillHarvesting); _profRowBlacksmithing = AddProfRow(_profRowMode, "ProfRow_Blacksmithing", "Blacksmithing —"); _profBarBlacksmithing = AddMiniBar(_profRowMode, "ProfBar_Blacksmithing", fillColor, out _profBarFillBlacksmithing); _profRowTailoring = AddProfRow(_profRowMode, "ProfRow_Tailoring", "Tailoring —"); _profBarTailoring = AddMiniBar(_profRowMode, "ProfBar_Tailoring", fillColor, out _profBarFillTailoring); _profRowWoodcutting = AddProfRow(_profRowMode, "ProfRow_Woodcutting", "Woodcutting —"); _profBarWoodcutting = AddMiniBar(_profRowMode, "ProfBar_Woodcutting", fillColor, out _profBarFillWoodcutting); _profRowMining = AddProfRow(_profRowMode, "ProfRow_Mining", "Mining —"); _profBarMining = AddMiniBar(_profRowMode, "ProfBar_Mining", fillColor, out _profBarFillMining); _profRowFishing = AddProfRow(_profRowMode, "ProfRow_Fishing", "Fishing —"); _profBarFishing = AddMiniBar(_profRowMode, "ProfBar_Fishing", fillColor, out _profBarFillFishing); } private TextMeshProUGUI AddProfRow(GameObject parent, string name, string initial) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) LabelRef labelRef = UIFactory.CreateLabel(parent, name, initial, Theme.OverlayMidlineAlignment(), null, Theme.ScaledOverlay(12)); GameObject gameObject = labelRef.GameObject; int? minWidth = 240; int? preferredWidth = 260; int? num = 1; UIFactory.SetLayoutElement(minHeight: Theme.ScaledOverlayHeight(18), flexibleWidth: num, preferredHeight: Theme.ScaledOverlayHeight(20), gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ((TMP_Text)labelRef.TextMesh).enableWordWrapping = false; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; return labelRef.TextMesh; } private void BuildQuestSection() { //IL_001d: 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) _questSection = BuildSectionRoot("QuestSection"); AddSectionHeader(_questSection, "DAILY / WEEKLY QUEST", COL_QUEST_D); _dailyLine = AddSectionBody(_questSection, "DailyLine", "Daily: —"); _weeklyLine = AddSectionBody(_questSection, "WeeklyLine", "Weekly: —"); ((Graphic)_weeklyLine).color = COL_QUEST_W; } private static void SyncBar(GameObject bar, RectTransform fill, float progress, bool show) { if (!((Object)(object)bar == (Object)null)) { if (bar.activeSelf != show) { bar.SetActive(show); } if (show && (Object)(object)fill != (Object)null) { MiniBar.SetProgress(fill, progress); } } } private void RenderXP() { if (!((Object)(object)_xpLine == (Object)null)) { PlayerStateService.ExperienceState experience = PlayerStateService.Experience; string value = ((experience.Class == PlayerStateService.PlayerClass.None) ? "(no class)" : experience.Class.ToString()); string value2 = ((experience.Prestige > 0) ? $" P{experience.Prestige}" : ""); ((TMP_Text)_xpLine).text = $"Lv {experience.Level} ({experience.Progress * 100f:0.#}%){value2} {value}"; SyncBar(_xpBar, _xpBarFill, experience.Progress, Settings.ShowProgressBarXP); } } private void RenderFamiliar() { if (!((Object)(object)_famNameLine == (Object)null)) { PlayerStateService.FamiliarState familiar = PlayerStateService.Familiar; if (!familiar.HasActive) { ((TMP_Text)_famNameLine).text = "(no familiar bound)"; ((TMP_Text)_famStatsLine).text = "—"; SyncBar(_famBar, _famBarFill, 0f, show: false); return; } string value = ((familiar.Prestige > 0) ? $" P{familiar.Prestige}" : ""); ((TMP_Text)_famNameLine).text = $"{familiar.Name} Lv {familiar.Level} ({familiar.Progress * 100f:0.#}%){value}"; ((TMP_Text)_famStatsLine).text = $"HP {familiar.MaxHealth} PP {familiar.PhysicalPower} SP {familiar.SpellPower}"; SyncBar(_famBar, _famBarFill, familiar.Progress, Settings.ShowProgressBarFamiliar); } } private void RenderExpertise() { if (!((Object)(object)_wepLine == (Object)null)) { PlayerStateService.ExpertiseState expertise = PlayerStateService.Expertise; string value = ((expertise.Prestige > 0) ? $" P{expertise.Prestige}" : ""); ((TMP_Text)_wepLine).text = $"{expertise.Type} Lv {expertise.Level} ({expertise.Progress * 100f:0.#}%){value}"; List<PlayerStateService.WeaponStatType> list = PlayerStateService.DecodeWeaponBonusStats(expertise.BonusStatsRaw); ((TMP_Text)_wepStatsLine).text = ((list == null || list.Count == 0) ? "Stats: (none chosen)" : ("Stats: " + string.Join(", ", list))); SyncBar(_wepBar, _wepBarFill, expertise.Progress, Settings.ShowProgressBarExpertise); RenderWepBonusValuesSubRow(); RenderWepCounterSubRow(); } } private void RenderLegacy() { if (!((Object)(object)_blLine == (Object)null)) { PlayerStateService.LegacyState legacy = PlayerStateService.Legacy; string value = ((legacy.Prestige > 0) ? $" P{legacy.Prestige}" : ""); ((TMP_Text)_blLine).text = $"{legacy.Type} Lv {legacy.Level} ({legacy.Progress * 100f:0.#}%){value}"; List<PlayerStateService.BloodStatType> list = PlayerStateService.DecodeBloodBonusStats(legacy.BonusStatsRaw); ((TMP_Text)_blStatsLine).text = ((list == null || list.Count == 0) ? "Stats: (none chosen)" : ("Stats: " + string.Join(", ", list))); SyncBar(_blBar, _blBarFill, legacy.Progress, Settings.ShowProgressBarLegacy); RenderBlBonusValuesSubRow(); RenderBlCounterSubRow(); } } private void RenderWepBonusValuesSubRow() { if (!((Object)(object)_wepBonusValuesLine == (Object)null)) { bool showOverlayBonusStats = Settings.ShowOverlayBonusStats; ExperienceOverlayPanel experienceOverlayPanel = Plugin.UIManager?.ExperienceOverlay; List<string> list = ((!showOverlayBonusStats) ? null : experienceOverlayPanel?.BuildCleanedWepGetStatsLines()); bool flag = list != null && list.Count > 0; if (((Component)_wepBonusValuesLine).gameObject.activeSelf != (showOverlayBonusStats && flag)) { ((Component)_wepBonusValuesLine).gameObject.SetActive(showOverlayBonusStats && flag); } if (showOverlayBonusStats && flag) { ((TMP_Text)_wepBonusValuesLine).text = string.Join("\n", list); } } } private void RenderWepCounterSubRow() { if (!((Object)(object)_wepCounterLine == (Object)null)) { bool showOverlayXpCounter = Settings.ShowOverlayXpCounter; ExperienceOverlayPanel experienceOverlayPanel = Plugin.UIManager?.ExperienceOverlay; bool flag = showOverlayXpCounter && (experienceOverlayPanel?.WepGetHasData ?? false); if (((Component)_wepCounterLine).gameObject.activeSelf != flag) { ((Component)_wepCounterLine).gameObject.SetActive(flag); } if (flag) { int wepGetRawExpertise = experienceOverlayPanel.WepGetRawExpertise; float wepGetProgressPct = experienceOverlayPanel.WepGetProgressPct; int num = ((wepGetProgressPct > 0.01f) ? Mathf.RoundToInt((float)wepGetRawExpertise * 100f / wepGetProgressPct) : 0); ((TMP_Text)_wepCounterLine).text = ((num > 0) ? $"Exp: {wepGetRawExpertise} / {num} ({wepGetProgressPct:0.0}%)" : $"Exp: {wepGetRawExpertise} ({wepGetProgressPct:0.0}%)"); } } } private void RenderBlBonusValuesSubRow() { if (!((Object)(object)_blBonusValuesLine == (Object)null)) { bool showOverlayBonusStats = Settings.ShowOverlayBonusStats; PlayerStateService.BloodInfo bloodInfoLatest = PlayerStateService.BloodInfoLatest; bool flag = bloodInfoLatest.StatLines != null && bloodInfoLatest.StatLines.Count > 0; if (((Component)_blBonusValuesLine).gameObject.activeSelf != (showOverlayBonusStats && flag)) { ((Component)_blBonusValuesLine).gameObject.SetActive(showOverlayBonusStats && flag); } if (showOverlayBonusStats && flag) { ((TMP_Text)_blBonusValuesLine).text = string.Join("\n", bloodInfoLatest.StatLines); } } } private void RenderBlCounterSubRow() { if ((Object)(object)_blCounterLine == (Object)null) { return; } bool showOverlayXpCounter = Settings.ShowOverlayXpCounter; PlayerStateService.BloodInfo bloodInfoLatest = PlayerStateService.BloodInfoLatest; bool flag = showOverlayXpCounter && !string.IsNullOrEmpty(bloodInfoLatest.Essence) && !string.IsNullOrEmpty(bloodInfoLatest.ProgressPct); if (((Component)_blCounterLine).gameObject.activeSelf != flag) { ((Component)_blCounterLine).gameObject.SetActive(flag); } if (flag) { if (float.TryParse(bloodInfoLatest.ProgressPct, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && int.TryParse(bloodInfoLatest.Essence, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2)) { int num = ((result > 0.01f) ? Mathf.RoundToInt((float)result2 * 100f / result) : 0); ((TMP_Text)_blCounterLine).text = ((num > 0) ? $"Ess: {result2} / {num} ({result:0.0}%)" : $"Ess: {result2} ({result:0.0}%)"); } else { ((TMP_Text)_blCounterLine).text = $"Ess: {bloodInfoLatest.Essence} ({bloodInfoLatest.ProgressPct}%)"; } } } private void RenderProfessions() { if ((Object)(object)_profLine == (Object)null) { return; } PlayerStateService.ProfessionState profession = PlayerStateService.Profession; bool showProgressBarProfessions = Settings.ShowProgressBarProfessions; if ((Object)(object)_profWrapMode != (Object)null && _profWrapMode.activeSelf != !showProgressBarProfessions) { _profWrapMode.SetActive(!showProgressBarProfessions); } if ((Object)(object)_profRowMode != (Object)null && _profRowMode.activeSelf != showProgressBarProfessions) { _profRowMode.SetActive(showProgressBarProfessions); } if (!showProgressBarProfessions) { List<string> list = new List<string>(8); if (Settings.ShowProfessionEnchanting) { list.Add($"Enchanting {profession.EnchantingLevel}"); } if (Settings.ShowProfessionAlchemy) { list.Add($"Alchemy {profession.AlchemyLevel}"); } if (Settings.ShowProfessionHarvesting) { list.Add($"Harvesting {profession.HarvestingLevel}"); } if (Settings.ShowProfessionBlacksmithing) { list.Add($"Blacksmithing {profession.BlacksmithingLevel}"); } if (Settings.ShowProfessionTailoring) { list.Add($"Tailoring {profession.TailoringLevel}"); } if (Settings.ShowProfessionWoodcutting) { list.Add($"Woodcutting {profession.WoodcuttingLevel}"); } if (Settings.ShowProfessionMining) { list.Add($"Mining {profession.MiningLevel}"); } if (Settings.ShowProfessionFishing) { list.Add($"Fishing {profession.FishingLevel}"); } ((TMP_Text)_profLine).text = ((list.Count == 0) ? "(all professions hidden in Settings)" : string.Join(" ", list)); } else { RenderProfRow(_profRowEnchanting, _profBarEnchanting, _profBarFillEnchanting, Settings.ShowProfessionEnchanting, "Enchanting", profession.EnchantingLevel, profession.EnchantingProgress); RenderProfRow(_profRowAlchemy, _profBarAlchemy, _profBarFillAlchemy, Settings.ShowProfessionAlchemy, "Alchemy", profession.AlchemyLevel, profession.AlchemyProgress); RenderProfRow(_profRowHarvesting, _profBarHarvesting, _profBarFillHarvesting, Settings.ShowProfessionHarvesting, "Harvesting", profession.HarvestingLevel, profession.HarvestingProgress); RenderProfRow(_profRowBlacksmithing, _profBarBlacksmithing, _profBarFillBlacksmithing, Settings.ShowProfessionBlacksmithing, "Blacksmithing", profession.BlacksmithingLevel, profession.BlacksmithingProgress); RenderProfRow(_profRowTailoring, _profBarTailoring, _profBarFillTailoring, Settings.ShowProfessionTailoring, "Tailoring", profession.TailoringLevel, profession.TailoringProgress); RenderProfRow(_profRowWoodcutting, _profBarWoodcutting, _profBarFillWoodcutting, Settings.ShowProfessionWoodcutting, "Woodcutting", profession.WoodcuttingLevel, profession.WoodcuttingProgress); RenderProfRow(_profRowMining, _profBarMining, _profBarFillMining, Settings.ShowProfessionMining, "Mining", profession.MiningLevel, profession.MiningProgress); RenderProfRow(_profRowFishing, _profBarFishing, _profBarFillFishing, Settings.ShowProfessionFishing, "Fishing", profession.FishingLevel, profession.FishingProgress); } } private static void RenderProfRow(TextMeshProUGUI label, GameObject bar, RectTransform fill, bool show, string name, int level, float progress) { if ((Object)(object)label != (Object)null) { if (((Component)label).gameObject.activeSelf != show) { ((Component)label).gameObject.SetActive(show); } if (show) { ((TMP_Text)label).text = $"{name}: Lv {level} ({progress * 100f:0.#}%)"; } } SyncBar(bar, fill, progress, show); } private void RenderQuests() { if (!((Object)(object)_dailyLine == (Object)null)) { PlayerStateService.QuestState dailyQuest = PlayerStateService.DailyQuest; PlayerStateService.QuestState weeklyQuest = PlayerStateService.WeeklyQuest; ((TMP_Text)_dailyLine).text = FormatQuest("Daily", dailyQuest); ((TMP_Text)_weeklyLine).text = FormatQuest("Weekly", weeklyQuest); } } private static string FormatQuest(string label, PlayerStateService.QuestState q) { if (string.IsNullOrEmpty(q.TargetName)) { return label + ": —"; } if (q.Goal <= 0 || q.Progress < q.Goal) { return $"{label}: {q.TargetName} ({q.Progress}/{q.Goal})"; } return label + ": " + q.TargetName + " — Complete!"; } internal override void Reset() { if (_subscribed) { PlayerStateService.ExperienceChanged -= OnAnyChanged; PlayerStateService.FamiliarChanged -= OnAnyChanged; PlayerStateService.ExpertiseChanged -= OnAnyChanged; PlayerStateService.LegacyChanged -= OnAnyChanged; PlayerStateService.ProfessionChanged -= OnAnyChanged; PlayerStateService.QuestChanged -= OnAnyChanged; PlayerStateService.LastResponseChanged -= OnAnyChanged; PlayerStateService.BloodInfoChanged -= OnAnyChanged; _subscribed = false; } } } public class DailyQuestOverlayPanel : ResizeablePanelBase { private LabelRef _dailyTitleLabel; private LabelRef _dailyTargetLabel; private LabelRef _dailyProgressLabel; private LabelRef _weeklyTitleLabel; private LabelRef _weeklyTargetLabel; private LabelRef _weeklyProgressLabel; private bool _subscribed; public override string PanelId => "DailyQuestOverlay"; public override PanelType PanelType => PanelType.DailyQuestOverlay; public override int MinWidth => 260; public override int MinHeight => 130; public override Vector2 DefaultAnchorMin => new Vector2(0.5f, 0.5f); public override Vector2 DefaultAnchorMax => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPivot => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPosition => new Vector2((0f - base.Owner.Scaler.m_ReferenceResolution.x) * 0.5f + 280f, base.Owner.Scaler.m_ReferenceResolution.y * 0.5f - 40f); public override bool CanDrag => true; public override PanelDragger.ResizeTypes CanResize => PanelDragger.ResizeTypes.All; public override float Opacity => Settings.TransparencyToAlpha(Settings.DailyQuestTransparency); public override bool UsesCustomBackgroundColor => true; public DailyQuestOverlayPanel(UIBase owner) : base(owner) { } protected override void ConstructPanelContent() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) base.ConstructPanelContent(); _dailyTitleLabel = AddRow("DailyTitle", "Daily Quest", (FontStyles)1, Theme.ScaledOverlay(14)); ((Graphic)_dailyTitleLabel.TextMesh).color = new Color(0f, 1f, 1f); ApplyStrongOutline(_dailyTitleLabel.TextMesh); _dailyTargetLabel = AddRow("DailyTarget", "—", (FontStyles)0, Theme.ScaledOverlay(13)); _dailyProgressLabel = AddRow("DailyProgress", "—", (FontStyles)2, Theme.ScaledOverlay(13)); AddSpacer(6); _weeklyTitleLabel = AddRow("WeeklyTitle", "Weekly Quest", (FontStyles)1, Theme.ScaledOverlay(14)); ((Graphic)_weeklyTitleLabel.TextMesh).color = new Color(1f, 0.85f, 0.3f); ApplyStrongOutline(_weeklyTitleLabel.TextMesh); _weeklyTargetLabel = AddRow("WeeklyTarget", "—", (FontStyles)0, Theme.ScaledOverlay(13)); _weeklyProgressLabel = AddRow("WeeklyProgress", "—", (FontStyles)2, Theme.ScaledOverlay(13)); Render(); if (!_subscribed) { PlayerStateService.QuestChanged += OnQuestChanged; _subscribed = true; } } private LabelRef AddRow(string name, string text, FontStyles style, int fontSize) { //IL_0008: 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) LabelRef labelRef = UIFactory.CreateLabel(base.ContentRoot, name, text, Theme.OverlayMidlineAlignment(), null, fontSize); GameObject gameObject = labelRef.GameObject; int? minWidth = 240; int? preferredWidth = 260; int? num = 1; UIFactory.SetLayoutElement(minHeight: 20, flexibleWidth: num, preferredHeight: 22, gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ((TMP_Text)labelRef.TextMesh).enableWordWrapping = false; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; ((TMP_Text)labelRef.TextMesh).fontStyle = style; return labelRef; } private void AddSpacer(int height) { //IL_000d: 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) GameObject gameObject = UIFactory.CreateUIObject("Spacer", base.ContentRoot); int? minHeight = height; int? preferredHeight = height; int? flexibleHeight = 0; int? flexibleWidth = 1; UIFactory.SetLayoutElement(gameObject, null, minHeight, flexibleWidth, flexibleHeight, null, preferredHeight); } private void OnQuestChanged() { Render(); } private void Render() { if (_dailyTitleLabel != null) { FillRow(_dailyTargetLabel, _dailyProgressLabel, PlayerStateService.DailyQuest, ".quest r d"); FillRow(_weeklyTargetLabel, _weeklyProgressLabel, PlayerStateService.WeeklyQuest, ".quest r w"); } } private static void FillRow(LabelRef target, LabelRef progress, PlayerStateService.QuestState s, string rerollHint) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s.TargetName) && s.Goal <= 0) { ((TMP_Text)target.TextMesh).text = "(none yet)"; ((TMP_Text)progress.TextMesh).text = "Check back after refresh."; ((Graphic)progress.TextMesh).color = Color.white; return; } ((TMP_Text)target.TextMesh).text = (s.IsVBlood ? ("⚔ " + s.TargetName + " (V Blood)") : ("⚔ " + s.TargetName)); if (s.Goal > 0 && s.Progress >= s.Goal) { ((TMP_Text)progress.TextMesh).text = "Complete! (" + rerollHint + " to reroll)"; ((Graphic)progress.TextMesh).color = new Color(0.6f, 1f, 0.6f); return; } ((TMP_Text)progress.TextMesh).text = $"Progress: {s.Progress} / {s.Goal}"; ((Graphic)progress.TextMesh).color = Color.white; } private static void ApplyStrongOutline(TextMeshProUGUI t) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)t == (Object)null) { return; } try { ((TMP_Text)t).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)t).outlineWidth = 0.25f; } catch { } } internal override void Reset() { if (_subscribed) { PlayerStateService.QuestChanged -= OnQuestChanged; _subscribed = false; } } } public class ExperienceOverlayPanel : ResizeablePanelBase { private LabelRef _levelLabel; private LabelRef _progressLabel; private GameObject _xpBar; private RectTransform _xpBarFill; private RectTransform _xpBarSubFill; private LabelRef _classLabel; private LabelRef _weaponLabel; private LabelRef _weaponCounterLabel; private GameObject _weaponBar; private RectTransform _weaponBarFill; private RectTransform _weaponBarSubFill; private LabelRef _weaponStatsLabel; private LabelRef _legacyLabel; private LabelRef _legacyCounterLabel; private GameObject _legacyBar; private RectTransform _legacyBarFill; private RectTransform _legacyBarSubFill; private LabelRef _legacyStatsLabel; private LabelRef _exoLabel; private int _wepGetRawExpertise; private float _wepGetProgressPct; private bool _wepGetHasData; private bool _subscribed; private bool _expertiseSubscribed; private bool _legacySubscribed; private bool _prestigeSubscribed; private bool _lastResponseSubscribed; private bool _bloodInfoSubscribed; private bool _exoFetchScheduled; private int _exoLevel; private int _exoMaxLevel; private List<string> _cachedWepGetLines; private Action _bonusStatsTicker; private double _lastBonusStatsFetchAt; private const double OVERLAY_BONUS_REFRESH_SECONDS = 10.0; private bool _bonusStatsFetchToggle; private PlayerStateService.WeaponType _lastSeenWeaponType; private PlayerStateService.BloodType _lastSeenBloodType; private bool _seenWeaponTypeBaseline; private bool _seenBloodTypeBaseline; private static readonly Regex _wepGetPreambleRegex = new Regex("Your weapon expertise is \\[<color=white>\\d+</color>\\]\\[<color=#90EE90>\\d+</color>\\] and you have <color=yellow>(?<xp>[^<]+)</color> <color=#FFC0CB>expertise</color> \\(<color=white>(?<pct>[^<%]+)%?</color>\\) with", RegexOptions.Compiled); private static readonly Regex _tmpTagStripRegex = new Regex("</?color(=[^>]*)?>", RegexOptions.Compiled); public override string PanelId => "ExperienceOverlay"; public override PanelType PanelType => PanelType.ExperienceOverlay; public override int MinWidth => 240; public override int MinHeight { get { int num = ResolveRowHeight(Theme.ScaledOverlay(16)); int num2 = ResolveRowHeight(Theme.ScaledOverlay(13)); int num3 = ResolveRowHeight(Theme.ScaledOverlay(11)); int num4 = ResolveRowHeight(Theme.ScaledOverlay(11)) * 2; int num5 = num + 5 * num2 + 12; int num6 = 0; if (Settings.ShowProgressBarXP) { num6++; } if (Settings.ShowProgressBarExpertise) { num6++; } if (Settings.ShowProgressBarLegacy) { num6++; } if (num6 > 0) { num5 += num6 * (Settings.ProgressBarHeight + 2); } if (Settings.ShowOverlayBonusStats) { num5 += 2 * num4; } if (Settings.ShowOverlayXpCounter) { num5 += 2 * num3; } return num5; } } public override Vector2 DefaultAnchorMin => new Vector2(0.5f, 0.5f); public override Vector2 DefaultAnchorMax => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPivot => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPosition => new Vector2((0f - base.Owner.Scaler.m_ReferenceResolution.x) * 0.5f, base.Owner.Scaler.m_ReferenceResolution.y * 0.5f); public override bool CanDrag => true; public override PanelDragger.ResizeTypes CanResize => PanelDragger.ResizeTypes.All; public override float Opacity => Settings.TransparencyToAlpha(Settings.XPOverlayTransparency); public override bool UsesCustomBackgroundColor => true; public bool WepGetHasData => _wepGetHasData; public int WepGetRawExpertise => _wepGetRawExpertise; public float WepGetProgressPct => _wepGetProgressPct; public IReadOnlyList<string> CachedWepGetLines => _cachedWepGetLines; public List<string> BuildCleanedWepGetStatsLines() { if (_cachedWepGetLines == null || _cachedWepGetLines.Count == 0) { return null; } List<string> list = new List<string>(_cachedWepGetLines.Count); foreach (string cachedWepGetLine in _cachedWepGetLines) { string text = _tmpTagStripRegex.Replace(cachedWepGetLine, string.Empty).Trim(); if (!string.IsNullOrEmpty(text) && !IsWepGetPreambleOrPlaceholder(text)) { list.Add(text); } } if (list.Count <= 0) { return null; } return list; } public ExperienceOverlayPanel(UIBase owner) : base(owner) { } protected override void ConstructPanelContent() { //IL_006e: 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_01f9: Unknown result type (might be due to invalid IL or missing references) base.ConstructPanelContent(); _levelLabel = AddRow("LevelLabel", "Level —", (FontStyles)1, Theme.ScaledOverlay(16)); _progressLabel = AddRow("ProgressLabel", "XP — %", (FontStyles)0, Theme.ScaledOverlay(14)); _xpBar = MiniBar.CreateWithSubLine(base.ContentRoot, "XpBar", out _xpBarFill, out _xpBarSubFill, new Color(0.4f, 0.85f, 1f, 0.95f), ResolveBarHeight()); _xpBar.SetActive(false); _classLabel = AddRow("ClassLabel", "Class —", (FontStyles)2, Theme.ScaledOverlay(13)); _weaponLabel = AddRow("WeaponLabel", "Weapon —", (FontStyles)0, Theme.ScaledOverlay(13)); _weaponCounterLabel = AddRow("WeaponCounterLabel", "", (FontStyles)2, Theme.ScaledOverlay(11)); _weaponCounterLabel.GameObject.SetActive(false); _weaponBar = MiniBar.CreateWithSubLine(base.ContentRoot, "WeaponXpBar", out _weaponBarFill, out _weaponBarSubFill, new Color(1f, 0.45f, 0.3f, 0.95f), ResolveBarHeight()); _weaponBar.SetActive(false); _weaponStatsLabel = AddRow("WeaponStatsLabel", "", (FontStyles)2, Theme.ScaledOverlay(11)); ConfigureBonusStatsLabel(_weaponStatsLabel); _weaponStatsLabel.GameObject.SetActive(false); _legacyLabel = AddRow("LegacyLabel", "Legacy —", (FontStyles)0, Theme.ScaledOverlay(13)); _legacyCounterLabel = AddRow("LegacyCounterLabel", "", (FontStyles)2, Theme.ScaledOverlay(11)); _legacyCounterLabel.GameObject.SetActive(false); _legacyBar = MiniBar.CreateWithSubLine(base.ContentRoot, "LegacyXpBar", out _legacyBarFill, out _legacyBarSubFill, new Color(0.75f, 0.25f, 0.45f, 0.95f), ResolveBarHeight()); _legacyBar.SetActive(false); _legacyStatsLabel = AddRow("LegacyStatsLabel", "", (FontStyles)2, Theme.ScaledOverlay(11)); ConfigureBonusStatsLabel(_legacyStatsLabel); _legacyStatsLabel.GameObject.SetActive(false); _exoLabel = AddRow("ExoLabel", "EXO Prestige —", (FontStyles)2, Theme.ScaledOverlay(13)); Render(PlayerStateService.Experience); TryRenderExoFromState(); if (!_subscribed) { PlayerStateService.ExperienceChanged += OnExperienceChanged; _subscribed = true; } if (!_expertiseSubscribed) { PlayerStateService.ExpertiseChanged += OnExpertiseChanged; _expertiseSubscribed = true; } if (!_legacySubscribed) { PlayerStateService.LegacyChanged += OnLegacyChanged; _legacySubscribed = true; } if (!_prestigeSubscribed) { PlayerStateService.PrestigeInfoChanged += OnPrestigeInfoChanged; _prestigeSubscribed = true; } if (!_lastResponseSubscribed) { PlayerStateService.LastResponseChanged += OnLastResponseChanged; _lastResponseSubscribed = true; } if (!_bloodInfoSubscribed) { PlayerStateService.BloodInfoChanged += OnBloodInfoChanged; _bloodInfoSubscribed = true; } RenderWeapon(PlayerStateService.Expertise); RenderLegacy(PlayerStateService.Legacy); PlayerStateService.LastServerResponse lastResponse = PlayerStateService.LastResponse; if (lastResponse.Command == ".wep get" && lastResponse.Lines != null && lastResponse.Lines.Count > 0) { _cachedWepGetLines = new List<string>(lastResponse.Lines); } ScheduleExoFetch(); if (_bonusStatsTicker == null) { _bonusStatsTicker = BonusStatsTick; CoreUpdateBehavior.Actions.Add(_bonusStatsTicker); } } private void ScheduleExoFetch() { if (_exoFetchScheduled) { return; } _exoFetchScheduled = true; Action ticker = null; ticker = delegate { if (!MessageService.IsInitialized) { return; } CoreUpdateBehavior.Actions.Remove(ticker); try { MessageService.EnqueueMessage(".prestige get Exo"); } catch (Exception ex) { LogUtils.LogWarning("ExperienceOverlay: auto .prestige get Exo failed — " + ex.Message); } }; CoreUpdateBehavior.Actions.Add(ticker); } private void ConfigureBonusStatsLabel(LabelRef lbl) { if (lbl != null) { ((TMP_Text)lbl.TextMesh).enableWordWrapping = true; ((TMP_Text)lbl.TextMesh).overflowMode = (TextOverflowModes)0; GameObject gameObject = lbl.GameObject; int? minWidth = 220; int? preferredWidth = 240; int? num = 1; UIFactory.SetLayoutElement(minHeight: 16, flexibleWidth: num, preferredHeight: -1, gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ContentSizeFitter obj = lbl.GameObject.AddComponent<ContentSizeFitter>(); obj.horizontalFit = (FitMode)0; obj.verticalFit = (FitMode)2; } } private LabelRef AddRow(string name, string text, FontStyles style, int fontSize) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) int value = ResolveRowHeight(fontSize); LabelRef labelRef = UIFactory.CreateLabel(base.ContentRoot, name, text, Theme.OverlayMidlineAlignment(), null, fontSize); GameObject gameObject = labelRef.GameObject; int? minWidth = 220; int? preferredWidth = 240; int? num = 1; UIFactory.SetLayoutElement(minHeight: value, flexibleWidth: num, preferredHeight: value, gameObject: gameObject, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ((TMP_Text)labelRef.TextMesh).enableWordWrapping = false; ((TMP_Text)labelRef.TextMesh).overflowMode = (TextOverflowModes)0; ((TMP_Text)labelRef.TextMesh).fontStyle = style; return labelRef; } private static int ResolveRowHeight(int fontSize) { return Mathf.Max(20, Mathf.RoundToInt((float)fontSize * 1.45f)); } private void OnExperienceChanged() { Render(PlayerStateService.Experience); } private void OnExpertiseChanged() { PlayerStateService.ExpertiseState expertise = PlayerStateService.Expertise; if (_seenWeaponTypeBaseline && expertise.Type != _lastSeenWeaponType) { _lastBonusStatsFetchAt = 0.0; _bonusStatsFetchToggle = true; _cachedWepGetLines = null; } _lastSeenWeaponType = expertise.Type; _seenWeaponTypeBaseline = true; RenderWeapon(expertise); RenderWeaponStats(); } private void OnLegacyChanged() { PlayerStateService.LegacyState legacy = PlayerStateService.Legacy; if (_seenBloodTypeBaseline && legacy.Type != _lastSeenBloodType) { _lastBonusStatsFetchAt = 0.0; _bonusStatsFetchToggle = false; } _lastSeenBloodType = legacy.Type; _seenBloodTypeBaseline = true; RenderLegacy(legacy); RenderLegacyStats(); } private void OnLastResponseChanged() { PlayerStateService.LastServerResponse lastResponse = PlayerStateService.LastResponse; if (!(lastResponse.Command != ".wep get") && lastResponse.Lines != null) { _cachedWepGetLines = new List<string>(lastResponse.Lines); ParseWepGetPreamble(_cachedWepGetLines); RenderWeaponStats(); RenderWeaponCounter(); } } private void ParseWepGetPreamble(List<string> lines) { if (lines == null || lines.Count == 0) { _wepGetHasData = false; return; } foreach (string line in lines) { Match match = _wepGetPreambleRegex.Match(line); if (match.Success && int.TryParse(match.Groups["xp"].Value.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && float.TryParse(match.Groups["pct"].Value.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { _wepGetRawExpertise = result; _wepGetProgressPct = result2; _wepGetHasData = true; break; } } } private void OnBloodInfoChanged() { RenderLegacyStats(); RenderLegacyCounter(); } private void RenderWeapon(PlayerStateService.ExpertiseState e) { if (_weaponLabel == null) { return; } ApplyBarChrome(); if (e.Level <= 0 && e.Type == PlayerStateService.WeaponType.Sword) { ((TMP_Text)_weaponLabel.TextMesh).text = "Weapon —"; if ((Object)(object)_weaponBar != (Object)null && _weaponBar.activeSelf) { _weaponBar.SetActive(false); } RenderWeaponCounter(); return; } string text = ((e.Prestige > 0) ? $"Weapon: {e.Type} Lv {e.Level} ({e.Progress * 100f:0.#}%) Pr {e.Prestige}" : $"Weapon: {e.Type} Lv {e.Level} ({e.Progress * 100f:0.#}%)"); ((TMP_Text)_weaponLabel.TextMesh).text = text; bool showProgressBarExpertise = Settings.ShowProgressBarExpertise; if ((Object)(object)_weaponBar != (Object)null && _weaponBar.activeSelf != showProgressBarExpertise) { _weaponBar.SetActive(showProgressBarExpertise); } if (showProgressBarExpertise) { MiniBar.SetProgress(_weaponBarFill, e.Progress); int maxExpertiseLevel = PlayerStateService.Config.MaxExpertiseLevel; float progress = ((maxExpertiseLevel > 0) ? Mathf.Clamp01((float)e.Level / (float)maxExpertiseLevel) : 0f); ApplySubLine(_weaponBar, _weaponBarSubFill, Settings.ShowPrestigeSubLine && maxExpertiseLevel > 0, progress); } RenderWeaponCounter(); } private void RenderLegacy(PlayerStateService.LegacyState l) { if (_legacyLabel == null) { return; } ApplyBarChrome(); if (l.Level <= 0 && l.Type == PlayerStateService.BloodType.Worker) { ((TMP_Text)_legacyLabel.TextMesh).text = "Legacy —"; if ((Object)(object)_legacyBar != (Object)null && _legacyBar.activeSelf) { _legacyBar.SetActive(false); } RenderLegacyCounter(); return; } string text = ((l.Prestige > 0) ? $"Legacy: {l.Type} Lv {l.Level} ({l.Progress * 100f:0.#}%) Pr {l.Prestige}" : $"Legacy: {l.Type} Lv {l.Level} ({l.Progress * 100f:0.#}%)"); ((TMP_Text)_legacyLabel.TextMesh).text = text; bool showProgressBarLegacy = Settings.ShowProgressBarLegacy; if ((Object)(object)_legacyBar != (Object)null && _legacyBar.activeSelf != showProgressBarLegacy) { _legacyBar.SetActive(showProgressBarLegacy); } if (showProgressBarLegacy) { MiniBar.SetProgress(_legacyBarFill, l.Progress); int maxLegacyLevel = PlayerStateService.Config.MaxLegacyLevel; float progress = ((maxLegacyLevel > 0) ? Mathf.Clamp01((float)l.Level / (float)maxLegacyLevel) : 0f); ApplySubLine(_legacyBar, _legacyBarSubFill, Settings.ShowPrestigeSubLine && maxLegacyLevel > 0, progress); } RenderLegacyCounter(); } private void RenderWeaponStats() { if (_weaponStatsLabel == null) { return; } if (!Settings.ShowOverlayBonusStats || _cachedWepGetLines == null || _cachedWepGetLines.Count == 0) { if (_weaponStatsLabel.GameObject.activeSelf) { _weaponStatsLabel.GameObject.SetActive(false); } return; } List<string> list = new List<string>(_cachedWepGetLines.Count); foreach (string cachedWepGetLine in _cachedWepGetLines) { string text = _tmpTagStripRegex.Replace(cachedWepGetLine, string.Empty).Trim(); if (!string.IsNullOrEmpty(text) && !IsWepGetPreambleOrPlaceholder(text)) { list.Add(text); } } if (list.Count == 0) { if (_weaponStatsLabel.GameObject.activeSelf) { _weaponStatsLabel.GameObject.SetActive(false); } return; } ((TMP_Text)_weaponStatsLabel.TextMesh).text = string.Join("\n", list); if (!_weaponStatsLabel.GameObject.activeSelf) { _weaponStatsLabel.GameObject.SetActive(true); } } private static bool IsWepGetPreambleOrPlaceholder(string strippedLine) { if (!strippedLine.StartsWith("Your weapon expertise is", StringComparison.Ordinal) && !strippedLine.StartsWith("No bonuses from currently equipped", StringComparison.Ordinal)) { return strippedLine.StartsWith("You haven't gained any expertise for", StringComparison.Ordinal); } return true; } private void RenderWeaponCounter() { if (_weaponCounterLabel == null) { return; } if (!Settings.ShowOverlayXpCounter || !_wepGetHasData) { if (_weaponCounterLabel.GameObject.activeSelf) { _weaponCounterLabel.GameObject.SetActive(false); } return; } int num = ((_wepGetProgressPct > 0.01f) ? Mathf.RoundToInt((float)_wepGetRawExpertise * 100f / _wepGetProgressPct) : 0); string text = ((num > 0) ? $"Exp: {_wepGetRawExpertise} / {num} ({_wepGetProgressPct:0.0}%)" : $"Exp: {_wepGetRawExpertise} ({_wepGetProgressPct:0.0}%)"); ((TMP_Text)_weaponCounterLabel.TextMesh).text = text; if (!_weaponCounterLabel.GameObject.activeSelf) { _weaponCounterLabel.GameObject.SetActive(true); } } private void RenderLegacyCounter() { if (_legacyCounterLabel == null) { return; } bool showOverlayXpCounter = Settings.ShowOverlayXpCounter; PlayerStateService.BloodInfo bloodInfoLatest = PlayerStateService.BloodInfoLatest; if (!showOverlayXpCounter || string.IsNullOrEmpty(bloodInfoLatest.BloodType)) { if (_legacyCounterLabel.GameObject.activeSelf) { _legacyCounterLabel.GameObject.SetActive(false); } return; } if (!int.TryParse(bloodInfoLatest.Essence ?? "", NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { if (!float.TryParse(bloodInfoLatest.Essence ?? "", NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { if (_legacyCounterLabel.GameObject.activeSelf) { _legacyCounterLabel.GameObject.SetActive(false); } return; } result = Mathf.RoundToInt(result2); } if (!float.TryParse(bloodInfoLatest.ProgressPct ?? "", NumberStyles.Float, CultureInfo.InvariantCulture, out var result3)) { result3 = 0f; } int num = ((result3 > 0.01f) ? Mathf.RoundToInt((float)result * 100f / result3) : 0); string text = ((num > 0) ? $"Ess: {result} / {num} ({result3:0.0}%)" : $"Ess: {result} ({result3:0.0}%)"); ((TMP_Text)_legacyCounterLabel.TextMesh).text = text; if (!_legacyCounterLabel.GameObject.activeSelf) { _legacyCounterLabel.GameObject.SetActive(true); } } private static int ResolveBarHeight() { return Settings.ProgressBarHeight; } private void ApplyBarChrome() { int height = ResolveBarHeight(); MiniBar.SetHeight(_xpBar, height); MiniBar.SetHeight(_weaponBar, height); MiniBar.SetHeight(_legacyBar, height); } private static void ApplySubLine(GameObject bar, RectTransform subFill, bool wantVisible, float progress01) { if ((Object)(object)bar == (Object)null || (Object)(object)subFill == (Object)null) { return; } GameObject gameObject = ((Component)subFill).gameObject; if (!wantVisible) { if (gameObject.activeSelf) { gameObject.SetActive(false); } return; } if (!gameObject.activeSelf) { gameObject.SetActive(true); } MiniBar.SetProgress(subFill, progress01); } private void RenderLegacyStats() { if (_legacyStatsLabel == null) { return; } bool showOverlayBonusStats = Settings.ShowOverlayBonusStats; PlayerStateService.BloodInfo bloodInfoLatest = PlayerStateService.BloodInfoLatest; bool flag = !string.IsNullOrEmpty(bloodInfoLatest.BloodType) && bloodInfoLatest.StatLines != null && bloodInfoLatest.StatLines.Count > 0; if (!showOverlayBonusStats || !flag) { if (_legacyStatsLabel.GameObject.activeSelf) { _legacyStatsLabel.GameObject.SetActive(false); } return; } ((TMP_Text)_legacyStatsLabel.TextMesh).text = string.Join("\n", bloodInfoLatest.StatLines); if (!_legacyStatsLabel.GameObject.activeSelf) { _legacyStatsLabel.GameObject.SetActive(true); } } private void BonusStatsTick() { RenderWeaponStats(); RenderLegacyStats(); if (!Settings.ShowOverlayBonusStats || !MessageService.IsInitialized) { return; } bool valueOrDefault = (Plugin.UIManager?.CombinedOverlay?.Enabled).GetValueOrDefault(); if (!base.Enabled && !valueOrDefault) { return; } double realtimeSinceStartupAsDouble = Time.realtimeSinceStartupAsDouble; if (_lastBonusStatsFetchAt > 0.0 && realtimeSinceStartupAsDouble - _lastBonusStatsFetchAt < 10.0) { return; } _lastBonusStatsFetchAt = realtimeSinceStartupAsDouble; try { if (_bonusStatsFetchToggle) { MessageService.EnqueueMessageSilent(".wep get"); } else { PlayerStateService.LegacyState legacy = PlayerStateService.Legacy; if (PlayerStateService.IsBondableBloodType(legacy.Type)) { MessageService.EnqueueMessageSilent($".bl get {legacy.Type}"); } } _bonusStatsFetchToggle = !_bonusStatsFetchToggle; } catch (Exception ex) { LogUtils.LogWarning("ExperienceOverlay: bonus-stats refresh failed — " + ex.Message); } } private void OnPrestigeInfoChanged() { TryRenderExoFromState(); } private void TryRenderExoFromState() { PlayerStateService.PrestigeInfo prestigeInfoLatest = PlayerStateService.PrestigeInfoLatest; if (prestigeInfoLatest.TypeName != null && string.Equals(prestigeInfoLatest.TypeName, "Exo", StringComparison.OrdinalIgnoreCase)) { _exoLevel = prestigeInfoLatest.Level; _exoMaxLevel = prestigeInfoLatest.MaxLevel; if (_exoLabel != null) { ((TMP_Text)_exoLabel.TextMesh).text = $"EXO Prestige: {_exoLevel}" + ((_exoMaxLevel > 0) ? $" / {_exoMaxLevel}" : ""); } } } private void Render(PlayerStateService.ExperienceState s) { if (_levelLabel != null) { ApplyBarChrome(); string text = ((s.Prestige > 0) ? $"Level {s.Level} Prestige {s.Prestige}" : $"Level {s.Level}"); ((TMP_Text)_levelLabel.TextMesh).text = text; ((TMP_Text)_progressLabel.TextMesh).text = $"XP {s.Progress * 100f:0.#}%"; ((TMP_Text)_classLabel.TextMesh).text = $"Class: {s.Class}"; bool showProgressBarXP = Settings.ShowProgressBarXP; if ((Object)(object)_xpBar != (Object)null && _xpBar.activeSelf != showProgressBarXP) { _xpBar.SetActive(showProgressBarXP); } if (showProgressBarXP) { MiniBar.SetProgress(_xpBarFill, s.Progress); int maxPlayerLevel = PlayerStateService.Config.MaxPlayerLevel; float progress = ((maxPlayerLevel > 0) ? Mathf.Clamp01((float)s.Level / (float)maxPlayerLevel) : 0f); ApplySubLine(_xpBar, _xpBarSubFill, Settings.ShowPrestigeSubLine && maxPlayerLevel > 0, progress); } } } internal override void Reset() { if (_subscribed) { PlayerStateService.ExperienceChanged -= OnExperienceChanged; _subscribed = false; } if (_expertiseSubscribed) { PlayerStateService.ExpertiseChanged -= OnExpertiseChanged; _expertiseSubscribed = false; } if (_legacySubscribed) { PlayerStateService.LegacyChanged -= OnLegacyChanged; _legacySubscribed = false; } if (_prestigeSubscribed) { PlayerStateService.PrestigeInfoChanged -= OnPrestigeInfoChanged; _prestigeSubscribed = false; } if (_lastResponseSubscribed) { PlayerStateService.LastResponseChanged -= OnLastResponseChanged; _lastResponseSubscribed = false; } if (_bloodInfoSubscribed) { PlayerStateService.BloodInfoChanged -= OnBloodInfoChanged; _bloodInfoSubscribed = false; } if (_bonusStatsTicker != null) { CoreUpdateBehavior.Actions.Remove(_bonusStatsTicker); _bonusStatsTicker = null; } } } public class FamiliarBrowserOverlayPanel : ResizeablePanelBase { private enum ViewMode { BoxView, VBloodView } private struct VBloodOverlayRow { public string BaseName; public string DisplayName; public string Box; public int Index; public int Level; public int Prestige; public bool IsShiny; public bool IsPrimal; public string ShinySchool; } private TextMeshProUGUI _boxNameLabel; private TextMeshProUGUI _activeFamLabel; private TextMeshProUGUI _swapWarningLabel; private GameObject _famListContainer; private ButtonRef _toggleBtn; private ButtonRef _unbindBtn; private ButtonRef _sortBtn; private ButtonRef _scanBtn; private ViewMode _viewMode; private ButtonRef _viewBtn; private GameObject _boxNavRow; private TextMeshProUGUI _vbStatusLabel; private bool _vbSummonStatusSubscribed; private bool _vbCollectionSubscribed; private int _pendingSwapIndex = -1; private float _pendingSwapDeadline = -1f; private const float SWAP_CONFIRM_WINDOW_SECONDS = 5f; private bool _subscribed; private bool _autoPullDone; public override string PanelId => "FamiliarBrowserOverlay"; public override PanelType PanelType => PanelType.FamiliarBrowserOverlay; public override int MinWidth => 280; public override int MinHeight => 440; public override Vector2 DefaultAnchorMin => new Vector2(0.5f, 0.5f); public override Vector2 DefaultAnchorMax => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPivot => new Vector2(0.5f, 0.5f); public override Vector2 DefaultPosition => new Vector2(base.Owner.Scaler.m_ReferenceResolution.x * 0.5f - 320f, -40f); public override bool CanDrag => true; public override PanelDragger.ResizeTypes CanResize => PanelDragger.ResizeTypes.All; public override float Opacity => Settings.TransparencyToAlpha(Settings.FamiliarBrowserTransparency); public override bool UsesCustomBackgroundColor => true; public override bool UsesCustomInnerBackgroundColor => true; public FamiliarBrowserOverlayPanel(UIBase owner) : base(owner) { } protected override void ConstructPanelContent() { base.ConstructPanelContent(); VerticalLayoutGroup component = base.ContentRoot.GetComponent<VerticalLayoutGroup>(); if ((Object)(object)component != (Object)null) { ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; } BuildHeader(); BuildFamiliarList(); BuildFooter(); if (!_subscribed) { PlayerStateService.BoxListChanged += OnAnyBoxStateChanged; PlayerStateService.BoxContentsChanged += OnAnyBoxStateChanged; PlayerStateService.ActiveBoxChanged += OnAnyBoxStateChanged; PlayerStateService.FamiliarChanged += OnAnyBoxStateChanged; _subscribed = true; } if (!_vbCollectionSubscribed) { PlayerStateService.VBloodCollectionChanged += OnAnyBoxStateChanged; VBloodScannerService.ScanStateChanged += OnScanStateChanged; _vbCollectionSubscribed = true; } ApplyViewModeVisibility(); CoreUpdateBehavior.Actions.Add(TickDeferredAutoPull); Render(); } private void TickDeferredAutoPull() { if (!_autoPullDone && MessageService.IsInitialized) { _autoPullDone = true; if (PlayerStateService.BoxList == null || PlayerStateService.BoxList.Count <= 0) { EnqueueOrWarn(".fam boxes"); } } } private void BuildHeader() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) GameObject val = UIFactory.CreateHorizontalGroup(base.ContentRoot, "OverlayToolbar", forceExpandWidth: true, forceExpandHeight: false, childControlWidth: true, childControlHeight: true, 4, new Vector4(0f, 0f, 0f, 0f)); int? minWidth = 260; int? preferredWidth = 280; int? num = 1; UIFactory.SetLayoutElement(minHeight: 28, flexibleWidth: num, preferredHeight: 30, gameObject: val, minWidth: minWidth, flexibleHeight: 0, preferredWidth: preferredWidth); ButtonRef buttonRef = UIFactory.CreateButton(val, "BoxPrev", "←"); GameObject gameObject = buttonRef.GameObject; int? minWidth2 = 28; int? preferredWidth2 = 30; num = 0; UIFactory.SetLayoutElement(minHeight: 26, flexibleWidth: num, preferredHeight: 28, gameObject: gameObject, minWidth: minWidth2, flexibleHeight: 0, preferredWidth: preferredWidth2); TextMeshProUGUI componentInChildren = ((Component)buttonRef.Component).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).fontSize = Theme.ScaledOverlay(16); ((TMP_Text)componentInChildren).fontStyle = (FontStyles)1; } buttonRef.OnClick = delegate { CycleBox(-1); }; TooltipHover.Attach(buttonRef.GameObject, "Previous box (cycles left through your familiar boxes)."); ButtonRef buttonRef2 = UIFactory.CreateButton(val, "BoxNext", "→"); GameObject gameObject2 = buttonRef2.GameObject; int? minWidth3 = 28; preferredWidth = 30; num = 0; UIFactory.SetLayoutElement(minHeight: 26, flexibleWidth: num, preferredHeight: 28, gameObject: gameObject2, minWidth: minWidth3, flexibleHeight: 0, preferredWidth: preferredWidth); TextMeshProUGUI componentInChildren2 = ((Component)buttonRef2.Component).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren2 != (Object)null) { ((TMP_Text)componentInChildren2).fontSize = Theme.ScaledOverlay(16); ((TMP_Text)componentInChildren2).fontStyle = (FontStyles)1; } buttonRef2.OnClick = delegate { CycleBox(1); }; TooltipHover.Attach(buttonRef2.GameObject, "Next box (cycles right through your familiar boxes)."); ButtonRef buttonRef3 = UIFactory.CreateButton(val, "BoxRefresh", "Reload"); GameObject gameObject3 = buttonRef3.GameObject; int? minWidth4 = 54; preferredWidth2 = 60; num = 0; UIFactory.SetLayoutElement(minHeight: 26, flexibleWidth: num, preferredHeight: 28, gameObject: gameObject3, minWidth: minWidth4, flexibleHeight: 0, preferredWidth: preferredWidth2); TextMeshProUGUI componentInChildren3 = ((Component)buttonRef3.Component).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren3 != (Object)null) { ((TMP_Text)componentInChildren3).fontSize = Theme.ScaledOverlay(11); } buttonRef3.OnClick = delegate { EnqueueOrWarn(".fam boxes"); EnqueueOrWarn(".fam l"); }; TooltipHover.Attach(buttonRef3.GameObject, "Re-pull the box list AND the current box's familiar list from the server."); _scanBtn = UIFactory.CreateButton(val, "OverlayScanBtn", FormatScanBtnText()); GameObject gameObject4 = _scanBtn.GameObject; int? minWidth5 = 54; preferredWidth = 60; num = 0; UIFactory.SetLayoutElement(minHeight: 26, flexibleWidth: num, preferredHeight: 28, gameObject: gameObject4, minWidth: minWidth5, flexibleHeight: 0, preferredWidth: preferredWidth); TextMeshProUGUI componentInChildren4 = ((Component)_scanBtn.Component).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren4 != (Object)null) { ((TMP_Text)componentInChildren4).fontSize = Theme.ScaledOverlay(11); } _scanBtn.OnClick = delegate { if (VBloodScannerService.Scanning) { VBloodScannerService.CancelScan(); } else { VBloodScannerService.StartScan(); } RefreshScanBtnText(); }; TooltipHover.Attach(_scanBtn.GameObject, "Run the V-Blood box-sweep scan from the overlay — same as the V-Bloods tab's Scan all button. Walks every box; ~30-60s; restores your active box at the end. Click again while running to cancel."); _viewBtn = UIFactory.CreateButton(val, "ViewModeBtn", FormatViewBtnText()); GameObject gameObject5 = _viewBtn.GameObject; int? minWidth6 = 60; preferredWidth2 = 70; num = 0; UIFactory.SetLayoutElement(minHeight: 26, flexibleWidth: num, preferredHeight: 28, gameObject: gameObject5, minWidth: minWidth6, flexibleHeight: 0, preferredWidth: preferredWidth2); TextMeshProUGUI componentInChildren5 = ((Component)_viewBtn.Component).