using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DemigodPanel.Diagnostics; using DemigodPanel.Logic; using DemigodPanel.Nd; using DemigodPanel.Runestone; using DemigodPanel.Ui; using HarmonyLib; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using NorseDemigods; using NorseDemigods.Abilities; using NorseDemigods.Attributes; using NorseDemigods.Demigods; using NorseDemigods.StatusEffects; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Profiling; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NorseDemigodsUI")] [assembly: AssemblyDescription("Ability bar and Demigod panel for Norse Demigods.")] [assembly: AssemblyCompany("RDMods")] [assembly: AssemblyProduct("DemigodPanel")] [assembly: AssemblyCopyright("Copyright © RDMods 2026")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("0.8.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.8.2.0")] namespace DemigodPanel { internal sealed class ConfigMigration { private readonly Dictionary _orphans; private readonly HashSet _inFileAtStart = new HashSet(); public bool CanRead => _orphans != null; public ConfigMigration(ConfigFile config) { _orphans = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries")?.GetValue(config) as Dictionary; if (_orphans == null) { Plugin.Log.LogWarning((object)"Could not read old config lines; moved settings start at their defaults."); } else { _inFileAtStart.UnionWith(_orphans.Keys); } } public bool InFile(string section, string key) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (_orphans != null) { return _orphans.ContainsKey(new ConfigDefinition(section, key)); } return false; } public void Move(string oldSection, string oldKey, ConfigEntryBase entry) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ConfigDefinition key = new ConfigDefinition(oldSection, oldKey); if (_orphans != null && entry != null && _orphans.TryGetValue(key, out var value)) { _orphans.Remove(key); if (!_inFileAtStart.Contains(entry.Definition)) { entry.SetSerializedValue(value); Plugin.Log.LogInfo((object)("Config: moved [" + oldSection + "] " + oldKey + " to [" + entry.Definition.Section + "] " + entry.Definition.Key + ".")); } } } public void DropSections(params string[] sections) { if (_orphans == null) { return; } List list = new List(); foreach (ConfigDefinition key in _orphans.Keys) { if (Array.IndexOf(sections, key.Section) >= 0) { list.Add(key); } } foreach (ConfigDefinition item in list) { _orphans.Remove(item); } } } [HarmonyPatch] internal static class ConfigSaveFence { private static IEnumerable TargetMethods() { yield return AccessTools.Method(typeof(ZNet), "Start", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZNet), "OnDestroy", (Type[])null, (Type[])null); } [HarmonyPriority(800)] private static void Prefix() { ConfigSaver.WaitForWrite(); } } internal static class ConfigSaver { private sealed class Pending { public ConfigFile File; public float Due; public Action Written; } private const float Delay = 1f; private static readonly List Queue = new List(); private static int _writing; private static volatile bool _mainThread; private static int _busyInARow; private const int BusyWarnAfter = 10; public static bool Writing => Volatile.Read(in _writing) > 0; public static void Request(ConfigFile file, Action written = null) { float due = Time.realtimeSinceStartup + 1f; foreach (Pending item in Queue) { if (item.File == file) { item.Due = due; return; } } Queue.Add(new Pending { File = file, Due = due, Written = written }); } public static void Tick() { if (Queue.Count == 0) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; for (int num = Queue.Count - 1; num >= 0; num--) { Pending pending = Queue[num]; if (realtimeSinceStartup >= pending.Due) { Queue.RemoveAt(num); Write(pending); } } } public static void FlushNow() { WaitForWrite(); foreach (Pending item in Queue) { Save(item); } Queue.Clear(); } public static void WaitForWrite() { if (Writing) { Stopwatch stopwatch = Stopwatch.StartNew(); while (Writing && stopwatch.ElapsedMilliseconds < 3000) { Thread.Sleep(1); } } } private static void Write(Pending p) { if (_mainThread) { Save(p); return; } Interlocked.Increment(ref _writing); if (!ThreadPool.QueueUserWorkItem(delegate { Background(p); })) { Interlocked.Decrement(ref _writing); Save(p); } } private static void Background(Pending p) { try { Stopwatch stopwatch = Stopwatch.StartNew(); int num = GC.CollectionCount(0); p.File.Save(); p.Written?.Invoke(); Interlocked.Exchange(ref _busyInARow, 0); double totalMilliseconds = stopwatch.Elapsed.TotalMilliseconds; if (totalMilliseconds > 100.0 || Perf.On) { Plugin.Log.LogInfo((object)($"[DGP-SAVE] {Path.GetFileName(p.File.ConfigFilePath)} written in {totalMilliseconds:0.0} ms " + $"on a worker thread (garbage collections meanwhile: {GC.CollectionCount(0) - num}).")); } } catch (IOException ex) { Plugin.Log.LogDebug((object)("Config save postponed: " + ex.Message)); if (Interlocked.Increment(ref _busyInARow) == 10) { Plugin.Log.LogWarning((object)(Path.GetFileName(p.File.ConfigFilePath) + " could not be saved for about " + $"{10} s ({ex.Message}); still retrying. Settings apply but may not be kept.")); } RetryOnMainThread(p); } catch (Exception ex2) { _mainThread = true; Plugin.Log.LogWarning((object)("Saving the config on a worker thread failed (" + ex2.GetType().Name + ": " + ex2.Message + "); it is saved on the game thread from now on.")); RetryOnMainThread(p); } finally { Interlocked.Decrement(ref _writing); } } private static void RetryOnMainThread(Pending p) { ThreadingHelper.Instance.StartSyncInvoke((Action)delegate { Request(p.File, p.Written); }); } private static void Save(Pending p) { try { p.File.Save(); p.Written?.Invoke(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not save " + Path.GetFileName(p.File.ConfigFilePath) + ": " + ex.Message)); } } } internal sealed class ConfigWatcher : IDisposable { private readonly ConfigFile _config; private readonly FileSystemWatcher _watcher; private readonly object _known = new object(); private DateTime _knownWrite; private long _knownLength = -1L; private bool _reloading; public int Reloads { get; private set; } public ConfigWatcher(ConfigFile config) { _config = config; Remember(); _config.SettingChanged += OnSettingChanged; _watcher = new FileSystemWatcher(Path.GetDirectoryName(config.ConfigFilePath), Path.GetFileName(config.ConfigFilePath)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), SynchronizingObject = ThreadingHelper.SynchronizingObject }; _watcher.Changed += OnFileEvent; _watcher.Created += OnFileEvent; _watcher.Renamed += OnFileEvent; _watcher.EnableRaisingEvents = true; } public void Dispose() { _config.SettingChanged -= OnSettingChanged; _watcher.EnableRaisingEvents = false; _watcher.Dispose(); } private void OnSettingChanged(object sender, SettingChangedEventArgs e) { if (!_reloading) { ConfigSaver.Request(_config, Remember); } } private void OnFileEvent(object sender, FileSystemEventArgs e) { try { if (ConfigSaver.Writing) { return; } FileInfo fileInfo = new FileInfo(_config.ConfigFilePath); bool flag; lock (_known) { flag = fileInfo.Exists && fileInfo.LastWriteTimeUtc == _knownWrite && fileInfo.Length == _knownLength; } if (!fileInfo.Exists || flag) { return; } Reloads++; Plugin.Log.LogInfo((object)("Reloading " + Path.GetFileName(_config.ConfigFilePath))); Remember(); _reloading = true; try { _config.Reload(); } finally { _reloading = false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read " + Path.GetFileName(_config.ConfigFilePath) + "; check its entries. (" + ex.Message + ")")); } } private void Remember() { try { FileInfo fileInfo = new FileInfo(_config.ConfigFilePath); lock (_known) { _knownWrite = (fileInfo.Exists ? fileInfo.LastWriteTimeUtc : DateTime.MinValue); _knownLength = (fileInfo.Exists ? fileInfo.Length : (-1)); } } catch (IOException) { lock (_known) { _knownLength = -1L; } } } } internal sealed class Guard { private const int MaxFailures = 5; private const float Window = 120f; private static readonly float[] RetryDelays = new float[4] { 1f, 4f, 15f, 60f }; private static readonly List Shared = new List(); private readonly string _name; private readonly bool _keepTrying; private int _failures; private float _windowStart = float.NegativeInfinity; private float _retryAt; public bool Off { get; private set; } public bool Ready { get { if (!Off) { return Time.realtimeSinceStartup >= _retryAt; } return false; } } public Guard(string name, bool shared = false, bool keepTrying = false) { _name = name; _keepTrying = keepTrying; if (shared) { Shared.Add(this); } } public static void ResetShared() { foreach (Guard item in Shared) { item.Off = false; item._failures = 0; item._windowStart = float.NegativeInfinity; item._retryAt = 0f; } } public bool Fail(Exception ex) { float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _windowStart > 120f) { _failures = 0; _windowStart = realtimeSinceStartup; } _failures++; if (_failures >= 5) { if (_keepTrying) { _retryAt = realtimeSinceStartup + RetryDelays[RetryDelays.Length - 1]; if (_failures == 5) { Plugin.Log.LogError((object)(_name + ": keeps failing, retrying every minute. Last error in " + Where(ex) + ": " + ex?.Message)); } return false; } Off = true; Plugin.Log.LogError((object)(_name + ": switched off after repeated errors. Last error in " + Where(ex) + ": " + ex?.Message)); return true; } float num = RetryDelays[Math.Min(_failures - 1, RetryDelays.Length - 1)]; _retryAt = realtimeSinceStartup + num; if (_failures == 1) { Plugin.Log.LogError((object)$"{_name}: error, paused for {num:0} s and then retried: {ex}"); } else { Plugin.Log.LogWarning((object)$"{_name}: error again ({_failures}), retrying in {num:0} s: {ex?.Message}"); } return false; } private static string Where(Exception ex) { MethodBase methodBase = ex?.TargetSite; if (!(methodBase != null)) { return "?"; } return ((methodBase.DeclaringType != null) ? (methodBase.DeclaringType.Name + ".") : string.Empty) + methodBase.Name; } } internal enum MeterStyle { DemigodPanel, NorseDemigods } [BepInPlugin("com.rdmods.norsedemigodsui", "NorseDemigodsUI", "0.8.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "com.rdmods.norsedemigodsui"; public const string Name = "NorseDemigodsUI"; public const string Version = "0.8.2"; internal static ConfigEntry Enabled; internal static ConfigEntry RunestoneRequired; internal static ConfigEntry InfusionSpoilers; internal static ConfigEntry PanelKey; internal static ConfigEntry ShowAbilityBar; internal static ConfigEntry ShowSpecialAttacks; internal static ConfigEntry BarOffset; internal static ConfigEntry BarScale; internal static ConfigEntry Meters; internal static ConfigEntry ShowEnergyBar; internal static ConfigEntry ShowXpBar; internal static ConfigEntry ShowCompanionBars; internal static ConfigEntry CompanionsOffset; internal static ConfigEntry CompanionsScale; internal static ConfigEntry MetersOffset; internal static ConfigEntry MetersScale; internal static ConfigEntry EnergyBarWidth; internal static ConfigEntry XpBarWidth; internal static ConfigEntry CompanionBarWidth; private Harmony _harmony; private GameObject _uiRoot; private ConfigWatcher _watcher; private const string General = "01 - General"; private const string Runestone = "02 - Runestone"; private const string Bar = "03 - Ability Bar"; private const string MetersSection = "04 - Meters"; private const string Companions = "05 - Companions"; internal const string DiagnosticsSection = "06 - Diagnostics"; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; if (GUIManager.IsHeadless()) { ((Behaviour)this).enabled = false; Log.LogInfo((object)"NorseDemigodsUI 0.8.2 is client-only; it does nothing on a dedicated server."); return; } BindConfig(); Loc.Register(); _harmony = new Harmony("com.rdmods.norsedemigodsui"); Hook(typeof(NdEvents), "god change events (a 10/s check takes over)"); Hook(typeof(GodChosenMessage), "the god chosen message"); Hook(typeof(NdMeterVisibility), "hiding its meters at god setup"); Hook(typeof(StatusIcons.CooldownHook), "cooldown icons"); Hook(typeof(StatusIcons.WolfHook), "the wolf's status icon"); Hook(typeof(StatusIcons.ShieldHook), "the elemental shield's status icon"); Hook(typeof(RunestoneRules.SpawnGiftHook), "the runestone spawn gift"); Hook(typeof(RunestoneRules.OldRunestoneHook), "opening the panel from an old runestone"); Hook(typeof(HuginTip), "the Hugin tip"); Hook(typeof(ConfigSaveFence), "waiting for a config save when joining or leaving a world"); GUIManager.OnCustomGUIAvailable += BuildUi; Step(RunestoneRules.Init, "the runestone rules"); Step(CheckNdVersion, "the version check"); Step(NdBridge.Init, "god switching from the panel"); Log.LogInfo((object)"NorseDemigodsUI 0.8.2 loaded."); } private void BindConfig() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; ConfigMigration configMigration = new ConfigMigration(((BaseUnityPlugin)this).Config); bool num = !configMigration.CanRead || configMigration.InFile("04 - Meters", "Position") || configMigration.InFile("5 - Meters", "Offset"); Enabled = Bind("01 - General", "Enabled", value: true, "Shows the ability bar, the Energy, XP and companion bars and the Demigod panel. Only affects you."); PanelKey = Bind("01 - General", "Panel Key", new KeyboardShortcut((KeyCode)107, Array.Empty()), "Opens and closes the Demigod panel. Norse Demigods uses P for its Teleport ability by default."); InfusionSpoilers = Bind("01 - General", "Infusion Spoilers", value: false, "Off: how to infuse each god's abilities is a riddle. On: the panel names the exact item, its recipe and the workstation. Only affects you."); RunestoneRequired = Bind("02 - Runestone", "Runestone Required", value: false, "Off: you get no runestone and can't craft one; you choose and change gods in the Demigod panel. On: Norse Demigods gives the runestone at first spawn and it can be crafted, and using it opens the panel. Only affects you."); ShowAbilityBar = Bind("03 - Ability Bar", "Show Ability Bar", value: true, "Shows your god's abilities, keys, costs and cooldowns above the bottom of the screen."); ShowSpecialAttacks = Bind("03 - Ability Bar", "Show Special Attacks", value: true, "Adds small slots for weapon special attacks and Teleport after the four ability slots."); BarScale = Bind("03 - Ability Bar", "Scale", 1f, "Size of the ability bar (1 = normal).", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f)); BarOffset = Bind("03 - Ability Bar", "Position", new Vector2(0f, 150f), "The bar's centre, in UI units from the bottom centre of the screen. Set it by dragging the bar while the inventory or the menu is open.", null, advanced: true); Meters = Bind("04 - Meters", "Meter Style", MeterStyle.DemigodPanel, "DemigodPanel: our Energy, XP and companion bars replace Norse Demigods' meters. NorseDemigods: Norse Demigods' own meters, and ours are off."); ShowEnergyBar = Bind("04 - Meters", "Show Energy Bar", value: true, "Shows the Energy bar (Meter Style DemigodPanel)."); ShowXpBar = Bind("04 - Meters", "Show XP Bar", value: true, "Shows the XP bar (Meter Style DemigodPanel)."); MetersScale = Bind("04 - Meters", "Scale", 1f, "Size of the Energy and XP bars (1 = normal).", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f)); MetersOffset = Bind("04 - Meters", "Position", new Vector2(0f, 94f), "The Energy and XP bars' centre, in UI units from the bottom centre of the screen. Set it by dragging the bars while the inventory or the menu is open.", null, advanced: true); EnergyBarWidth = Bind("04 - Meters", "Energy Bar Width", 216, "Width of the Energy bar, in UI units (before Scale).", (AcceptableValueBase)(object)new AcceptableValueRange(80, 600), advanced: true); XpBarWidth = Bind("04 - Meters", "XP Bar Width", 216, "Width of the XP bar, in UI units (before Scale).", (AcceptableValueBase)(object)new AcceptableValueRange(80, 600), advanced: true); ShowCompanionBars = Bind("05 - Companions", "Show Companion Bars", value: true, "Shows bars for your wolf, minions, necks, Stone Golem and surtlings (Meter Style DemigodPanel)."); CompanionsScale = Bind("05 - Companions", "Scale", 1f, "Size of the companion bars (1 = normal).", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f)); CompanionsOffset = Bind("05 - Companions", "Position", new Vector2(-150f, 215f), "The companion bars' lower-left corner, in UI units from the bottom centre of the screen. Set it by dragging the bars while a companion is out and the inventory or the menu is open.", null, advanced: true); CompanionBarWidth = Bind("05 - Companions", "Bar Width", 156, "Width of each companion bar, in UI units (before Scale; the icon is extra).", (AcceptableValueBase)(object)new AcceptableValueRange(80, 400), advanced: true); Perf.Bind(((BaseUnityPlugin)this).Config, "06 - Diagnostics"); Migrate(configMigration); if (!num) { MetersScale.Value = BarScale.Value; MetersOffset.Value = BarOffset.Value + new Vector2(0f, -56f * BarScale.Value); } ((BaseUnityPlugin)this).Config.Save(); _watcher = new ConfigWatcher(((BaseUnityPlugin)this).Config); RunestoneRequired.SettingChanged += OnRunestoneSetting; InfusionSpoilers.SettingChanged += OnTextSetting; } private static void OnTextSetting(object sender, EventArgs e) { NdEvents.MarkConfigChanged(); } private ConfigEntry Bind(string section, string key, T value, string description, AcceptableValueBase range = null, bool advanced = false) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) return ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, section, key, value, description, false, false, true, range, (Action)null, (!advanced) ? ((ConfigurationManagerAttributes)null) : new ConfigurationManagerAttributes { IsAdvanced = true }); } private void Migrate(ConfigMigration m) { m.Move("4 - Ability Bar", "Meter Style", (ConfigEntryBase)(object)Meters); m.Move("4 - Ability Bar", "Show Energy Bar", (ConfigEntryBase)(object)ShowEnergyBar); m.Move("4 - Ability Bar", "Show XP Bar", (ConfigEntryBase)(object)ShowXpBar); m.Move("4 - Ability Bar", "Show Companion Bars", (ConfigEntryBase)(object)ShowCompanionBars); m.Move("4 - Ability Bar", "Companions Offset", (ConfigEntryBase)(object)CompanionsOffset); m.Move("5 - Diagnostics", "Enabled", (ConfigEntryBase)(object)Perf.EnabledEntry); m.Move("1 - General", "Enabled", (ConfigEntryBase)(object)Enabled); m.Move("3 - Panel", "Panel Key", (ConfigEntryBase)(object)PanelKey); m.Move("2 - Runestone", "Runestone Required", (ConfigEntryBase)(object)RunestoneRequired); m.Move("4 - Ability Bar", "Show Ability Bar", (ConfigEntryBase)(object)ShowAbilityBar); m.Move("4 - Ability Bar", "Show Special Attacks", (ConfigEntryBase)(object)ShowSpecialAttacks); m.Move("4 - Ability Bar", "Scale", (ConfigEntryBase)(object)BarScale); m.Move("4 - Ability Bar", "Offset", (ConfigEntryBase)(object)BarOffset); m.Move("5 - Meters", "Meter Style", (ConfigEntryBase)(object)Meters); m.Move("5 - Meters", "Show Energy Bar", (ConfigEntryBase)(object)ShowEnergyBar); m.Move("5 - Meters", "Show XP Bar", (ConfigEntryBase)(object)ShowXpBar); m.Move("5 - Meters", "Scale", (ConfigEntryBase)(object)MetersScale); m.Move("5 - Meters", "Offset", (ConfigEntryBase)(object)MetersOffset); m.Move("5 - Meters", "Energy Bar Width", (ConfigEntryBase)(object)EnergyBarWidth); m.Move("5 - Meters", "XP Bar Width", (ConfigEntryBase)(object)XpBarWidth); m.Move("6 - Companions", "Show Companion Bars", (ConfigEntryBase)(object)ShowCompanionBars); m.Move("6 - Companions", "Scale", (ConfigEntryBase)(object)CompanionsScale); m.Move("6 - Companions", "Offset", (ConfigEntryBase)(object)CompanionsOffset); m.Move("6 - Companions", "Bar Width", (ConfigEntryBase)(object)CompanionBarWidth); m.Move("7 - Diagnostics", "Enabled", (ConfigEntryBase)(object)Perf.EnabledEntry); m.DropSections("1 - General", "2 - Runestone", "3 - Panel", "4 - Ability Bar", "5 - Meters", "6 - Companions", "7 - Diagnostics", "5 - Diagnostics"); } private void Hook(Type group, string feature) { try { _harmony.PatchAll(group); } catch (Exception ex) { Log.LogWarning((object)("Could not hook Norse Demigods for " + feature + "; that part is off, everything else works. (" + ex.GetType().Name + ": " + ex.Message + ")")); } } private static void Step(Action step, string feature) { try { step(); } catch (Exception ex) { Log.LogWarning((object)("Norse Demigods setup for " + feature + " failed; that part is off. (" + ex.GetType().Name + ": " + ex.Message + ")")); } } private static void OnRunestoneSetting(object sender, EventArgs e) { RunestoneRules.Apply(); } private static void CheckNdVersion() { if (Chainloader.PluginInfos.TryGetValue("NorseDemigods", out var value)) { Version version = value.Metadata.Version; if (version.Major != 1 || version.Minor != 7) { Log.LogWarning((object)$"Built for Norse Demigods 1.7.x, found {version}. If something breaks, the panel switches itself off."); } } } private void BuildUi() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (!((Object)(object)_uiRoot != (Object)null) && !((Object)(object)GUIManager.CustomGUIFront == (Object)null) && Utils.InMainScene()) { _uiRoot = new GameObject("DemigodPanel"); _uiRoot.AddComponent(); } } private void Update() { ConfigSaver.Tick(); } private void OnApplicationQuit() { ConfigSaver.FlushNow(); } private void OnDestroy() { if (RunestoneRequired == null) { return; } ConfigSaver.FlushNow(); GUIManager.OnCustomGUIAvailable -= BuildUi; RunestoneRequired.SettingChanged -= OnRunestoneSetting; if (InfusionSpoilers != null) { InfusionSpoilers.SettingChanged -= OnTextSetting; } RunestoneRules.Shutdown(); _watcher?.Dispose(); if ((Object)(object)_uiRoot != (Object)null) { Object.Destroy((Object)(object)_uiRoot); } try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception arg) { Log.LogError((object)$"Unpatch failed: {arg}"); } } } internal static class Loc { private const string Resource = "DemigodPanel.Assets.Translations.English.json"; public static void Register() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DemigodPanel.Assets.Translations.English.json"); if (stream == null) { Plugin.Log.LogWarning((object)"English translation resource missing."); return; } using StreamReader streamReader = new StreamReader(stream); LocalizationManager.Instance.GetLocalization().AddJsonFile("English", streamReader.ReadToEnd()); KeyLabel.Translate = KeyName; } private static string KeyName(string keyCode) { string text = "$dgp_keyname_" + keyCode; string text2 = T(text); if (!Missing(text2) && !(text2 == text)) { return text2; } return null; } public static string T(string token) { if (Localization.instance == null) { return token; } return Localization.instance.Localize(token); } public static string F(string token, params object[] args) { string text = T(token); try { return string.Format(text, args); } catch (FormatException) { return text; } } public static string KeyHint(string label) { return "[" + label + "]"; } public static bool Missing(string text) { if (text != null) { if (text.StartsWith("[")) { return text.EndsWith("]"); } return false; } return true; } } internal static class Utils { private static GameObject _selected; private static InputField _field; private static TMP_InputField _tmpField; public static bool InMainScene() { //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) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == "main"; } public static bool HotkeysAllowed() { if ((Object)(object)Player.m_localPlayer == (Object)null || Menu.IsVisible() || InventoryGui.IsVisible() || StoreGui.IsVisible() || Minimap.IsOpen() || TextInput.IsVisible() || Console.IsVisible() || Minimap.InTextInput()) { return false; } Chat instance = Chat.instance; if ((Object)(object)instance != (Object)null && instance.HasFocus()) { return false; } EventSystem current = EventSystem.current; GameObject val = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null); if ((Object)(object)val == (Object)null) { _selected = null; return true; } if ((Object)(object)val != (Object)(object)_selected) { _selected = val; _field = val.GetComponent(); _tmpField = val.GetComponent(); } if (!((Object)(object)_field != (Object)null) || !_field.isFocused) { if ((Object)(object)_tmpField != (Object)null) { return !_tmpField.isFocused; } return true; } return false; } public static bool Pressed(KeyboardShortcut shortcut) { //IL_0002: 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_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, false)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!ZInput.GetKey(modifier, false)) { return false; } } return true; } public static Sprite ToSprite(Texture2D texture) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)texture == (Object)null)) { return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); } return null; } public static byte[] ReadResource(string name) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int i; int num; for (i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } return (i == array.Length) ? array : null; } } } namespace DemigodPanel.Ui { internal sealed class AbilitiesTab : PanelTab { private readonly NumberSheet _sheet = new NumberSheet(); private const int PerRow = 5; private const float CellW = 84f; private const float CellH = 104f; private const float Tile = 56f; private RectTransform _list; private DetailsCard _details; private FigureView _figure; private Demigod _god; private readonly List _items = new List(); private readonly List _marks = new List(); private readonly List _keyLabels = new List(); private readonly List _layout = new List(); private readonly List _now = new List(); private int _abilityCount; private int _pinned = -1; private int _hovered = -1; private readonly HoverHold _hold = new HoverHold(); private object _shownSubject; private int _shownLevel = -1; private int _shownCooldown = -1; private int _shownEnergy = -1; private int _shownGear; private int _shownActiveMask = -1; private int _shownConfig = -1; private int _shownUnarmed = -1; private int _shownTrophies = -1; private bool _shownActive; private bool _shownInfused; public override void Build(DemigodPanelView view, RectTransform root) { UiKit.Inset((Transform)(object)root, "LeftBg", 30f, 190f, 430f, 520f); _list = UiKit.Box((Transform)(object)root, "List", 30f, 190f, 430f, 520f); _details = new DetailsCard((Transform)(object)root, 475f, 190f, 520f, 520f); _figure = new FigureView((Transform)(object)root, 1010f, 190f, 360f, 520f); } public override void Rebuild(Demigod god) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) _god = god; _shownSubject = null; _shownLevel = -1; if ((Object)(object)god == (Object)null) { Clear(); _figure.Show(null, string.Empty); return; } _figure.Show(god.DemigodName, NdBridge.GodDisplayName(god.DemigodName)); List list = AbilityView.Sorted(god.Abilities?.Values); if (SameLayout(list, god.DefaultAttributes)) { Rebind(list, god.DefaultAttributes); return; } Clear(); float num = 10f; UiKit.Text((Transform)(object)_list, Loc.T("$dgp_active"), 18, UiKit.Orange, (TextAnchor)0, 14f, num, 402f, 24f, bold: true); num += 32f; for (int i = 0; i < list.Count; i++) { AddTile(list[i], 8f + (float)(i % 5) * 84f, num + (float)(i / 5) * 104f); } _abilityCount = list.Count; num += (float)((list.Count + 5 - 1) / 5) * 104f + 4f; UiKit.Text((Transform)(object)_list, Loc.T("$dgp_passive"), 18, UiKit.Orange, (TextAnchor)0, 14f, num, 402f, 24f, bold: true); num += 30f; if (god.DefaultAttributes != null) { foreach (DemigodAttribute value in god.DefaultAttributes.Values) { if (value != null) { AddTraitRow(value, num); num += 27f; } } } _pinned = ((list.Count <= 0) ? (-1) : 0); UpdateHighlights(); } private void Clear() { _items.Clear(); _marks.Clear(); _keyLabels.Clear(); _layout.Clear(); _abilityCount = 0; _pinned = -1; _hovered = -1; for (int num = ((Transform)_list).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_list).GetChild(num)).gameObject); } } private bool SameLayout(List abilities, Dictionary traits) { _now.Clear(); foreach (DemigodAbility ability in abilities) { _now.Add(((object)ability).GetType()); } if (traits != null) { foreach (DemigodAttribute value in traits.Values) { if (value != null) { _now.Add(((object)value).GetType()); } } } return RowLayout.Same(_layout, _now); } private void Rebind(List abilities, Dictionary traits) { for (int i = 0; i < abilities.Count; i++) { _items[i] = abilities[i]; } if (traits != null) { int count = abilities.Count; foreach (DemigodAttribute value in traits.Values) { if (value != null) { _items[count++] = value; } } } RefreshKeyLabels(); UpdateHighlights(); } private void AddTile(DemigodAbility ability, float x, float y) { //IL_0058: 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) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) int index = _items.Count; RectTransform obj = UiKit.Box((Transform)(object)_list, ((object)ability).GetType().Name, x, y, 84f, 100f); Image val = ((Component)obj).gameObject.AddComponent(); val.sprite = UiKit.White; ((Graphic)val).color = Color.clear; DemigodPanelView.Place(SlotArt.Socket((Transform)(object)obj, "Socket", AbilityView.Icon(ability), 56f, out var _), 14f, 4f, 56f, 56f); Text item = UiKit.Text((Transform)(object)obj, AbilityView.KeyLabelOf(ability), 11, UiKit.Gold, (TextAnchor)1, 0f, 62f, 84f, 14f, bold: true); UiKit.Text((Transform)(object)obj, ability.DisplayName, 12, Color.white, (TextAnchor)1, 0f, 76f, 84f, 30f).lineSpacing = 0.85f; _items.Add(ability); _marks.Add(val); _keyLabels.Add(item); _layout.Add(((object)ability).GetType()); UiKit.Hover(((Component)obj).gameObject, delegate { Hover(index); }, delegate { Unhover(index); }, delegate { Pin(index); }); } private void AddTraitRow(DemigodAttribute trait, float y) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) int index = _items.Count; RectTransform obj = UiKit.Box((Transform)(object)_list, ((object)trait).GetType().Name, 8f, y, 414f, 25f); Image val = ((Component)obj).gameObject.AddComponent(); val.sprite = UiKit.White; ((Graphic)val).color = UiKit.Row; UiKit.Text((Transform)(object)obj, "◆ " + trait.DisplayName, 15, UiKit.Ice, (TextAnchor)3, 10f, 0f, 394f, 25f); _items.Add(trait); _marks.Add(val); _layout.Add(((object)trait).GetType()); UiKit.Hover(((Component)obj).gameObject, delegate { Hover(index); }, delegate { Unhover(index); }, delegate { Pin(index); }); } private void Hover(int index) { _hold.Enter(); _hovered = index; UpdateHighlights(); Refresh(); } private void Unhover(int index) { if (_hovered == index) { _hold.Exit(); } } public override void Tick() { if (_hold.Expired() && _hovered >= 0) { _hovered = -1; UpdateHighlights(); Refresh(); } } public override void Hidden() { _hold.Enter(); _hovered = -1; UpdateHighlights(); } private void Pin(int index) { _pinned = index; UpdateHighlights(); Refresh(); } private void UpdateHighlights() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _marks.Count; i++) { Image val = _marks[i]; if (!((Object)(object)val == (Object)null)) { Color val2 = ((i >= _abilityCount) ? UiKit.Row : Color.clear); ((Graphic)val).color = ((i == _pinned) ? UiKit.RowSelected : ((i == _hovered) ? UiKit.RowHover : val2)); } } } private void RefreshKeyLabels() { for (int i = 0; i < _keyLabels.Count && i < _items.Count; i++) { object obj = _items[i]; DemigodAbility val = (DemigodAbility)((obj is DemigodAbility) ? obj : null); if (val != null) { string text = AbilityView.KeyLabelOf(val); if (_keyLabels[i].text != text) { _keyLabels[i].text = text; } } } } private object Item(int index) { if (index < 0 || index >= _items.Count) { return null; } return _items[index]; } public override void Refresh() { if ((Object)(object)Root == (Object)null || !Root.activeInHierarchy) { return; } Player player = Player.m_localPlayer; if ((Object)(object)_god == (Object)null || (Object)(object)player == (Object)null) { _details.Show(null, null, string.Empty, string.Empty, string.Empty); return; } if (_shownConfig != NdEvents.ConfigVersion) { RefreshKeyLabels(); } object obj = Item(_hovered) ?? Item(_pinned); int level = Mathf.FloorToInt(NdBridge.Level(player)); bool infused = NdBridge.AbilitiesInfused(player); int num = -1; bool flag = false; DemigodAbility val = (DemigodAbility)((obj is DemigodAbility) ? obj : null); if (val != null) { StatusEffect statusEffect = ((Character)player).GetSEMan().GetStatusEffect(AbilityView.CooldownHash(val)); num = (((Object)(object)statusEffect != (Object)null) ? Mathf.CeilToInt(statusEffect.GetRemaningTime()) : (-1)); flag = val.IsActive; } SE_Demigod val2 = NdBridge.StatusOf(player); int num2 = (((Object)(object)val2 != (Object)null) ? val2.Energy : (-1)); int num3 = GearStamp(player); int num4 = ActiveMask(_god); int num5 = Mathf.FloorToInt(NdBridge.SkillLevel(player, (SkillType)11)); int count = player.m_trophies.Count; if (obj == _shownSubject && level == _shownLevel && num == _shownCooldown && flag == _shownActive && infused == _shownInfused && num2 == _shownEnergy && num3 == _shownGear && num4 == _shownActiveMask && _shownConfig == NdEvents.ConfigVersion && num5 == _shownUnarmed && count == _shownTrophies) { return; } bool flag2 = obj == _shownSubject && _shownLevel >= 0 && level > _shownLevel; _shownEnergy = num2; _shownGear = num3; _shownUnarmed = num5; _shownTrophies = count; _shownActiveMask = num4; _shownConfig = NdEvents.ConfigVersion; _shownSubject = obj; _shownLevel = level; _shownCooldown = num; _shownActive = flag; _shownInfused = infused; _sheet.SetPlayer(player, asOtherGod: false); if (!flag2) { _sheet.ForgetValues(); } string pulsed = null; DemigodAbility val3 = (DemigodAbility)((obj is DemigodAbility) ? obj : null); if (val3 == null) { DemigodAttribute val4 = (DemigodAttribute)((obj is DemigodAttribute) ? obj : null); if (val4 != null) { string god = (((Object)(object)_god != (Object)null) ? _god.DemigodName : null); string body = _sheet.BuildWithPulse(delegate { _sheet.Begin(); return Texts.TraitBody(val4, level, live: true, god, _sheet); }, out pulsed); _details.Show(val4, null, val4.DisplayName, Loc.T("$dgp_kind_trait"), body, _sheet, flag2 ? pulsed : null); } else { _details.Show(null, null, string.Empty, string.Empty, Loc.T("$dgp_hover_hint")); } } else { string body2 = _sheet.BuildWithPulse(delegate { _sheet.Begin(); return Texts.AbilityBody(val3, player, level, infused, _sheet); }, out pulsed); _details.Show(val3, AbilityView.Icon(val3), val3.DisplayName, Texts.KindLabel(val3) + " · " + AbilityView.KeyLabelOf(val3), body2, _sheet, flag2 ? pulsed : null, round: true); } } internal static int ActiveMask(Demigod god) { int num = 0; int num2 = 1; if (god?.Abilities != null) { foreach (DemigodAbility value in god.Abilities.Values) { if (value.IsActive) { num |= num2; } num2 <<= 1; } } return num; } internal static int GearStamp(Player p) { int num = ((17 * 31 + ((((Humanoid)p).m_helmetItem != null) ? RuntimeHelpers.GetHashCode(((Humanoid)p).m_helmetItem) : 0)) * 31 + ((((Humanoid)p).m_chestItem != null) ? RuntimeHelpers.GetHashCode(((Humanoid)p).m_chestItem) : 0)) * 31 + ((((Humanoid)p).m_legItem != null) ? RuntimeHelpers.GetHashCode(((Humanoid)p).m_legItem) : 0); ItemData currentWeapon = ((Humanoid)p).GetCurrentWeapon(); return num * 31 + ((currentWeapon != null) ? RuntimeHelpers.GetHashCode(currentWeapon) : 0); } } internal sealed class AbilityBar { private sealed class Slot { public DemigodAbility Ability; public int CooldownHash; public bool Small; public Image Icon; public Image Tint; public Image Sweep; public Image ActiveFrame; public TMP_Text CooldownText; public TMP_Text CostText; public Image CostBadge; public float CooldownEnd; public float CooldownTotal; public int SweepSteps; public int ShownStep; public int ShownSeconds = -1; public bool Dim; public bool Short; public EitrUse Eitr; public int EnergyNeeded; } private const float BigSize = 64f; private const float SmallSize = 42f; private const float Gap = 8f; private const float TickSeconds = 0.1f; private static readonly string[] Seconds = BuildSeconds(); private static readonly Color ShortTint = new Color(0.08f, 0.16f, 0.42f, 0.7f); private static readonly Color DimIcon = new Color(0.45f, 0.45f, 0.45f, 0.9f); private bool _costsInfused; private float _costsUnarmed = -1f; private readonly List _slots = new List(); private RectTransform _root; private float _tick; private Demigod _builtFor; private bool _anyCooldown; public bool HasGod => (Object)(object)_builtFor != (Object)null; public int Version { get; private set; } public RectTransform Root { get { if (!((Object)(object)_root != (Object)null) || !((Component)_root).gameObject.activeInHierarchy) { return null; } return _root; } } public int SlotCount => _slots.Count; public RectTransform Bounds => Root; public RectTransform SlotRect(int i) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown return (RectTransform)((Component)_slots[i].Icon).transform.parent; } public DemigodAbility SlotAbility(int i) { if (i < 0 || i >= _slots.Count) { return null; } return _slots[i].Ability; } public bool Shows(DemigodAbility ability) { if (ability == null || (Object)(object)Root == (Object)null) { return false; } Type type = ((object)ability).GetType(); foreach (Slot slot in _slots) { if (slot.Ability != null && ((object)slot.Ability).GetType() == type) { return true; } } return false; } public void Place(Vector2 offset) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null && _root.anchoredPosition != offset) { _root.anchoredPosition = offset; } } public void Rebuild(Demigod god) { long start = Perf.Begin(); long mem = Perf.BeginMem(); RebuildInner(god); Perf.End(Perf.Scope.BarRebuild, start, mem); } private void RebuildInner(Demigod god) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) Destroy(); _builtFor = god; Hud instance = Hud.instance; if ((Object)(object)god == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)instance.m_rootObject == (Object)null) { return; } GameObject val = new GameObject("DemigodAbilityBar", new Type[2] { typeof(RectTransform), typeof(Canvas) }); _root = (RectTransform)val.transform; ((Transform)_root).SetParent(instance.m_rootObject.transform, false); RectTransform root = _root; RectTransform root2 = _root; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0f); root2.anchorMax = val2; root.anchorMin = val2; _root.pivot = new Vector2(0.5f, 0.5f); List list = AbilityView.Sorted(god.Abilities?.Values); float num = 0f; bool flag = false; foreach (DemigodAbility item in list) { bool flag2 = AbilityView.Kind(item) != AbilityKind.Slot; if (!flag2 || Plugin.ShowSpecialAttacks.Value) { if (flag2 && !flag) { num += 16f; flag = true; } float num2 = (flag2 ? 42f : 64f); _slots.Add(BuildSlot(item, num, num2, flag2)); num += num2 + 8f; } } float num3 = Mathf.Max(0f, num - 8f); _root.sizeDelta = new Vector2(num3, 86f); foreach (Slot slot in _slots) { RectTransform val3 = (RectTransform)((Component)slot.Icon).transform.parent; val3.anchoredPosition += new Vector2((0f - num3) * 0.5f, 0f); } _costsInfused = NdBridge.AbilitiesInfused(Player.m_localPlayer); RefreshCosts(Player.m_localPlayer); ApplyLayout(); Tick(Player.m_localPlayer); } private void RefreshCosts(Player player) { _costsUnarmed = (((Object)(object)player != (Object)null) ? NdBridge.SkillLevel(player, (SkillType)11) : 0f); foreach (Slot slot in _slots) { slot.Eitr = AbilityView.Eitr(slot.Ability, player, _costsInfused); slot.EnergyNeeded = AbilityView.EnergyNeeded(slot.Ability, _costsInfused); if ((Object)(object)slot.CostText != (Object)null) { string text = ((slot.EnergyNeeded > 0) ? slot.EnergyNeeded.ToString() : string.Empty); if (slot.CostText.text != text) { slot.CostText.text = text; } if ((Object)(object)slot.CostBadge != (Object)null && ((Behaviour)slot.CostBadge).enabled != text.Length > 0) { ((Behaviour)slot.CostBadge).enabled = text.Length > 0; } } } } public void Destroy() { ShowCooldownsInStatusList(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; _slots.Clear(); Version++; _builtFor = null; _anyCooldown = false; } public void ApplyLayout() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { float value = Plugin.BarScale.Value; ((Transform)_root).localScale = new Vector3(value, value, 1f); _root.anchoredPosition = UiKit.OnScreen(_root, Plugin.BarOffset.Value); } } public void SetVisible(bool visible) { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf != visible) { ((Component)_root).gameObject.SetActive(visible); if (!visible) { ShowCooldownsInStatusList(); } } } private void ShowCooldownsInStatusList() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || _slots.Count == 0) { return; } SEMan sEMan = ((Character)localPlayer).GetSEMan(); foreach (Slot slot in _slots) { StatusEffect statusEffect = sEMan.GetStatusEffect(slot.CooldownHash); if ((Object)(object)statusEffect != (Object)null && statusEffect.m_hidden) { statusEffect.m_hidden = false; } } } public void Update(Player player, float dt) { if (!((Object)(object)_root == (Object)null) && ((Component)_root).gameObject.activeInHierarchy) { _tick -= dt; if (_tick <= 0f) { _tick = 0.1f; long start = Perf.Begin(); long mem = Perf.BeginMem(); Tick(player); Perf.End(Perf.Scope.BarTick, start, mem); } if (_anyCooldown) { long start2 = Perf.Begin(); long mem2 = Perf.BeginMem(); Sweep(); Perf.End(Perf.Scope.BarSweep, start2, mem2); } } } private void Tick(Player player) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) SE_Demigod val = NdBridge.StatusOf(player); if ((Object)(object)player == (Object)null || (Object)(object)val == (Object)null) { return; } int energy = val.Energy; float eitr = player.m_eitr; ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); SkillType skill = (SkillType)((currentWeapon == null) ? 11 : ((int)currentWeapon.m_shared.m_skillType)); SEMan sEMan = ((Character)player).GetSEMan(); _anyCooldown = false; bool flag = NdBridge.AbilitiesInfused(player); float num = NdBridge.SkillLevel(player, (SkillType)11); if (flag != _costsInfused || num != _costsUnarmed) { _costsInfused = flag; RefreshCosts(player); } foreach (Slot slot in _slots) { DemigodAbility ability = slot.Ability; StatusEffect statusEffect = sEMan.GetStatusEffect(slot.CooldownHash); if ((Object)(object)statusEffect != (Object)null && !statusEffect.m_hidden) { statusEffect.m_hidden = true; } if ((Object)(object)statusEffect != (Object)null && statusEffect.m_ttl > 0f) { slot.CooldownEnd = Time.time + statusEffect.GetRemaningTime(); slot.CooldownTotal = statusEffect.m_ttl; _anyCooldown = true; } else if (slot.CooldownEnd > 0f) { slot.CooldownEnd = 0f; SetSweep(slot, 0f, -1); } long start = Perf.Begin(); long mem = Perf.BeginMem(); bool flag2 = !AbilityView.WeaponFits(ability, skill); bool flag3 = energy < slot.EnergyNeeded || (slot.Eitr.Any && !slot.Eitr.Affordable(eitr)); Perf.End(Perf.Scope.BarTint, start, mem); if (flag2 != slot.Dim) { slot.Dim = flag2; ((Graphic)slot.Icon).color = (flag2 ? DimIcon : Color.white); } if (flag3 != slot.Short) { slot.Short = flag3; ((Behaviour)slot.Tint).enabled = flag3; } if (((Behaviour)slot.ActiveFrame).enabled != ability.IsActive) { ((Behaviour)slot.ActiveFrame).enabled = ability.IsActive; } } } private void Sweep() { float time = Time.time; bool anyCooldown = false; foreach (Slot slot in _slots) { if (!(slot.CooldownEnd <= 0f)) { float num = slot.CooldownEnd - time; if (num <= 0f) { slot.CooldownEnd = 0f; SetSweep(slot, 0f, -1); } else { anyCooldown = true; SetSweep(slot, (slot.CooldownTotal > 0f) ? (num / slot.CooldownTotal) : 0f, Mathf.CeilToInt(num)); } } } _anyCooldown = anyCooldown; } private static void SetSweep(Slot slot, float fill, int seconds) { int num = ((!(fill <= 0f)) ? Mathf.CeilToInt(Mathf.Clamp01(fill) * (float)slot.SweepSteps) : 0); if (num != slot.ShownStep) { slot.ShownStep = num; slot.Sweep.fillAmount = (float)num / (float)slot.SweepSteps; } if (seconds != slot.ShownSeconds) { slot.ShownSeconds = seconds; slot.CooldownText.text = ((seconds < 0) ? string.Empty : ((seconds < Seconds.Length) ? Seconds[seconds] : "99+")); } } private Slot BuildSlot(DemigodAbility ability, float x, float size, bool small) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: 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_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) RectTransform obj = UiKit.Box((Transform)(object)_root, ((object)ability).GetType().Name, x, 0f, size, size); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); obj.anchorMax = val; obj.anchorMin = val; obj.pivot = new Vector2(0f, 0f); obj.anchoredPosition = new Vector2(x, -22f); float num = size * 0.0711f; float margin = (0f - size) * 0.125f * 0.5f; UiKit.Fill(((Graphic)UiKit.Image((Transform)(object)obj, "Bg", SlotArt.Back, Color.white)).rectTransform, margin); Image val2 = UiKit.Image((Transform)(object)obj, "Icon", AbilityView.Icon(ability), Color.white); val2.preserveAspect = true; UiKit.Fill(((Graphic)val2).rectTransform, num); Image val3 = UiKit.Image((Transform)(object)obj, "NotEnough", SlotArt.Disc, ShortTint); UiKit.Fill(((Graphic)val3).rectTransform, num); ((Behaviour)val3).enabled = false; RectTransform val4 = UiKit.Box((Transform)(object)obj, "Live", 0f, 0f, size, size); UiKit.Fill(val4); ((Component)val4).gameObject.AddComponent(); Image val5 = UiKit.Image((Transform)(object)val4, "Cooldown", SlotArt.Disc, new Color(0f, 0f, 0f, 0.65f)); val5.type = (Type)3; val5.fillMethod = (FillMethod)4; val5.fillOrigin = 2; val5.fillClockwise = false; val5.fillAmount = 0f; UiKit.Fill(((Graphic)val5).rectTransform, num); UiKit.Fill(((Graphic)UiKit.Image((Transform)(object)val4, "Ring", SlotArt.Ring, Color.white)).rectTransform); Image val6 = UiKit.Image((Transform)(object)val4, "Active", SlotArt.Glow, Color.white); UiKit.Fill(((Graphic)val6).rectTransform, margin); ((Behaviour)val6).enabled = false; TextMeshProUGUI cooldownText = UiKit.Tmp((Transform)(object)val4, "Seconds", string.Empty, small ? 17f : 24f, Color.white, (TextAlignmentOptions)514, 0f, 0f, size, size); TextMeshProUGUI obj2 = UiKit.Tmp((Transform)(object)obj, "Key", AbilityView.KeyLabelOf(ability), small ? 11f : 13f, UiKit.Gold, (TextAlignmentOptions)258, -12f, size + 1f, size + 24f, 16f); ((TMP_Text)obj2).enableAutoSizing = true; ((TMP_Text)obj2).fontSizeMin = 7f; ((TMP_Text)obj2).fontSizeMax = (small ? 11f : 13f); TMP_Text costText = null; Image val7 = null; if (!small) { float num2 = Mathf.Round(size * 0.34f); val7 = UiKit.Image((Transform)(object)val4, "CostBadge", SlotArt.Badge, Color.white); RectTransform rectTransform = ((Graphic)val7).rectTransform; Vector2 val8 = (rectTransform.pivot = Vector2.one); val = (rectTransform.anchorMin = (rectTransform.anchorMax = val8)); rectTransform.anchoredPosition = new Vector2(2f, 2f); rectTransform.sizeDelta = new Vector2(num2, num2); ((Behaviour)val7).enabled = false; costText = (TMP_Text)(object)UiKit.Tmp((Transform)(object)rectTransform, "Cost", string.Empty, 14f, UiKit.Ice, (TextAlignmentOptions)514, 0f, 0f, num2, num2); } return new Slot { Ability = ability, CooldownHash = AbilityView.CooldownHash(ability), Small = small, Icon = val2, Tint = val3, Sweep = val5, SweepSteps = Mathf.Max(24, Mathf.CeilToInt((float)Math.PI * (size - 2f * num))), ActiveFrame = val6, CooldownText = (TMP_Text)(object)cooldownText, CostText = costText, CostBadge = val7 }; } private static string[] BuildSeconds() { string[] array = new string[100]; for (int i = 0; i < array.Length; i++) { array[i] = i.ToString(); } return array; } } internal sealed class BasicsView { private static readonly string[] Topics = new string[7] { "falls", "heavy", "cap", "energy", "switch", "burst", "unarmed" }; private readonly GameObject _root; private readonly Image[] _icons = (Image[])(object)new Image[Topics.Length]; private readonly TextMeshProUGUI[] _bodies = (TextMeshProUGUI[])(object)new TextMeshProUGUI[Topics.Length]; private readonly NumberSheet _sheet = new NumberSheet(); private int _shownLevel = -1; private int _shownTrophies = -1; private int _shownConfig = -1; private int _shownUnarmed = -1; public bool IsShown { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } public BasicsView(Transform parent, float x, float y, float w, float h) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown RectTransform val = UiKit.Box(parent, "DemigodBasics", x, y, w, h); _root = ((Component)val).gameObject; UiKit.Inset((Transform)(object)val, "Bg", 0f, 0f, w, h); UiKit.Text((Transform)(object)val, Loc.T("$dgp_basics_title"), 22, UiKit.Orange, (TextAnchor)0, 16f, 12f, w - 32f, 30f, bold: true); RectTransform val2 = UiKit.Box((Transform)(object)val, "Scroll", 8f, 48f, w - 16f, h - 56f); ((Component)val2).gameObject.AddComponent(); Image obj = ((Component)val2).gameObject.AddComponent(); obj.sprite = UiKit.White; ((Graphic)obj).color = new Color(0f, 0f, 0f, 0f); ScrollRect val3 = ((Component)val2).gameObject.AddComponent(); val3.horizontal = false; val3.movementType = (MovementType)2; val3.scrollSensitivity = 0f; WheelStep wheelStep = ((Component)val2).gameObject.AddComponent(); wheelStep.Scroll = val3; wheelStep.Step = 90f; RectTransform val4 = UiKit.Box((Transform)(object)val2, "Content", 0f, 0f, w - 30f, 10f); ((Component)val4).gameObject.AddComponent().verticalFit = (FitMode)2; VerticalLayoutGroup obj2 = ((Component)val4).gameObject.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = (((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true); ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 14f; ((LayoutGroup)obj2).padding = new RectOffset(4, 4, 4, 10); val3.content = val4; val3.viewport = val2; for (int i = 0; i < Topics.Length; i++) { BuildRow(val4, i, w - 38f); } _root.SetActive(false); } private void BuildRow(RectTransform content, int i, float width) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Topic_" + Topics[i], new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)content, false); HorizontalLayoutGroup obj = val.AddComponent(); bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth; ((HorizontalOrVerticalLayoutGroup)obj).spacing = 12f; GameObject val2 = new GameObject("Icon", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val2.transform.SetParent(val.transform, false); LayoutElement component = val2.GetComponent(); float num = (component.minHeight = 34f); float num3 = (component.minWidth = num); float preferredWidth = (component.preferredHeight = num3); component.preferredWidth = preferredWidth; _icons[i] = val2.GetComponent(); _icons[i].preserveAspect = true; ((Graphic)_icons[i]).raycastTarget = false; GameObject val3 = new GameObject("Text", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); val3.SetActive(false); val3.transform.SetParent(val.transform, false); val3.GetComponent().preferredWidth = width - 46f; TextMeshProUGUI val4 = val3.AddComponent(); if ((Object)(object)UiFonts.Body != (Object)null) { ((TMP_Text)val4).font = UiFonts.Body; } ((TMP_Text)val4).fontSize = 16f; ((Graphic)val4).color = Color.white; ((TMP_Text)val4).richText = true; ((TMP_Text)val4).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)val4).lineSpacing = 8f; ((Graphic)val4).raycastTarget = true; LinkHover linkHover = val3.AddComponent(); linkHover.Text = val4; linkHover.Detail = _sheet.Detail; val3.SetActive(true); _bodies[i] = val4; } public void Show(bool show) { if (_root.activeSelf != show) { _root.SetActive(show); } if (show) { Refresh(force: true); } } public void Refresh(bool force = false) { Player localPlayer = Player.m_localPlayer; if (IsShown && !((Object)(object)localPlayer == (Object)null)) { int num = Mathf.FloorToInt(NdBridge.Level(localPlayer)); int count = localPlayer.m_trophies.Count; int num2 = Mathf.FloorToInt(NdBridge.SkillLevel(localPlayer, (SkillType)11)); if (force || num != _shownLevel || count != _shownTrophies || num2 != _shownUnarmed || _shownConfig != NdEvents.ConfigVersion) { _shownUnarmed = num2; _shownLevel = num; _shownTrophies = count; _shownConfig = NdEvents.ConfigVersion; long start = Perf.Begin(); long mem = Perf.BeginMem(); RefreshTexts(localPlayer, num); Perf.End(Perf.Scope.Basics, start, mem); } } } private void RefreshTexts(Player player, int level) { _sheet.SetPlayer(player, asOtherGod: false); _sheet.Begin(); for (int i = 0; i < Topics.Length; i++) { string text = ((Topics[i] == "cap") ? CapLadder(player, level) : _sheet.Render(Loc.T("$dgp_basics_" + Topics[i]))); ((TMP_Text)_bodies[i]).text = NumberStyle.Tint(Texts.Header(Loc.T("$dgp_basics_" + Topics[i] + "_h")) + "\n" + text); if ((Object)(object)_icons[i].sprite == (Object)null) { _icons[i].sprite = IconOf(Topics[i], player); ((Behaviour)_icons[i]).enabled = (Object)(object)_icons[i].sprite != (Object)null; } } } private static string CapLadder(Player player, int level) { StringBuilder stringBuilder = new StringBuilder(512); stringBuilder.Append(Loc.T("$dgp_basics_cap")).Append('\n'); CapState capState = NdBridge.Cap(player, level); if (capState.Cap <= 0 && capState.NextTier < 0) { return stringBuilder.Append(Loc.T("$dgp_growth_nocap")).ToString(); } int capTierCount = NdBridge.CapTierCount; for (int i = 0; i < capTierCount; i++) { int num = NdBridge.CapOfTier(i); string value = ((i == 0) ? Loc.T("$dgp_cap_tier_none") : NdBridge.TrophyName(i)); string value2 = ((num > 0) ? num.ToString() : Loc.T("$dgp_no_cap")); bool flag = i == capState.Tier; bool flag2 = i == capState.NextTier; string value3 = (flag ? NumberStyle.Fixed : (flag2 ? NumberStyle.Scaling : NumberStyle.Muted)); stringBuilder.Append("') .Append((flag || flag2) ? "" : string.Empty) .Append(value) .Append(": ") .Append(value2) .Append(flag ? (" " + Loc.T("$dgp_basics_cap_now")) : (flag2 ? (" " + Loc.T("$dgp_basics_cap_next")) : string.Empty)) .Append((flag || flag2) ? "" : string.Empty) .Append("\n"); } return stringBuilder.ToString().TrimEnd(new char[1] { '\n' }); } private static Sprite IconOf(string topic, Player player) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Invalid comparison between Unknown and I4 switch (topic) { case "falls": return StatusIcon("SlowFall"); case "heavy": return ItemIcon("ArmorIronChest"); case "cap": return ItemIcon("TrophyEikthyr"); case "energy": return StatusIcon("Lightning"); case "switch": return ItemIcon("DemigodRunestone") ?? AbilityView.Fallback(); case "burst": return StatusIcon("Burning"); default: if ((Object)(object)player.m_skills != (Object)null) { foreach (SkillDef skill in player.m_skills.m_skills) { if ((int)skill.m_skill == 11) { return skill.m_icon; } } } return null; } } private static Sprite StatusIcon(string name) { StatusEffect val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(name)) : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.m_icon; } private static Sprite ItemIcon(string prefab) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent() : null); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.m_itemData.GetIcon(); } } internal sealed class CompanionBars { private enum Kind { Wolf, Minions, Ghost, Necks, Golem, Surtlings, Count } private sealed class Row { public RectTransform Rt; public Image Icon; public HudBar Bar; public int A = -1; public int B = -1; public int C = -1; public string Name; } private const float TickSeconds = 0.1f; private const float IconSize = 30f; private const float RowGap = 4f; private static readonly Color WolfColor = new Color(0.85f, 0.3f, 0.25f); private static readonly Color MinionColor = new Color(0.62f, 0.85f, 0.3f); private static readonly Color GhostColor = new Color(0.75f, 0.85f, 0.95f); private static readonly Color NeckColor = new Color(0.25f, 0.8f, 0.8f); private static readonly Color GolemColor = new Color(0.62f, 0.56f, 0.48f); private static readonly Color SurtlingColor = new Color(0.95f, 0.5f, 0.15f); private readonly Row[] _rows = new Row[6]; private RectTransform _root; private float _tick; private int _builtFor = -1; private bool _hasCompanions; private int _shownMask = -1; private string _wolfNameRaw; private string _wolfName; private string _neckActivityRaw; private string _neckActivity; private int _neckActivityStamp; public RectTransform Root { get { if (!((Object)(object)_root != (Object)null) || !((Component)_root).gameObject.activeInHierarchy || _shownMask <= 0) { return null; } return _root; } } public void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; for (int i = 0; i < _rows.Length; i++) { _rows[i] = null; } _builtFor = -1; _shownMask = -1; } public void ApplyLayout() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { float value = Plugin.CompanionsScale.Value; ((Transform)_root).localScale = new Vector3(value, value, 1f); _root.anchoredPosition = UiKit.OnScreen(_root, Plugin.CompanionsOffset.Value); } } public void Place(Vector2 offset) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null && _root.anchoredPosition != offset) { _root.anchoredPosition = offset; } } public void Update(Player player, Demigod god, int godVersion, float dt) { if (!((Object)(object)player != (Object)null) || !((Object)(object)god != (Object)null) || ((Character)player).IsDead() || !Plugin.ShowCompanionBars.Value || !NdMeters.OursReplaceNd) { SetVisible(visible: false); return; } if (godVersion != _builtFor) { Destroy(); _builtFor = godVersion; _hasCompanions = NdMeters.Minions(player) != null || HasAbility(player) || HasAbility(player) || HasAbility(player) || HasAbility(player); _shownMask = -1; } if (!_hasCompanions) { SetVisible(visible: false); return; } _tick -= dt; if (_tick > 0f) { AnimateRows(dt); return; } _tick = 0.1f; EnsureRoot(); if (!((Object)(object)_root == (Object)null)) { SetVisible(visible: true); int num = 0; long start = Perf.Begin(); long mem = Perf.BeginMem(); num |= (TickWolf(player, god) ? 1 : 0); Perf.End(Perf.Scope.CompanionWolf, start, mem); start = Perf.Begin(); mem = Perf.BeginMem(); num |= (TickMinions(player, god, out var ghost) ? 2 : 0); num |= (ghost ? 4 : 0); Perf.End(Perf.Scope.CompanionMinions, start, mem); start = Perf.Begin(); mem = Perf.BeginMem(); num |= (TickNecks(player, god) ? 8 : 0); Perf.End(Perf.Scope.CompanionNecks, start, mem); start = Perf.Begin(); mem = Perf.BeginMem(); num |= (TickGolem(player, god) ? 16 : 0); Perf.End(Perf.Scope.CompanionGolem, start, mem); start = Perf.Begin(); mem = Perf.BeginMem(); num |= (TickSurtlings(player, god) ? 32 : 0); Perf.End(Perf.Scope.CompanionSurtlings, start, mem); if (num != _shownMask) { _shownMask = num; Stack(num); } } } private static bool HasAbility(Player player) where T : DemigodAbility { T val = default(T); return Helper.TryGetDemigodAbility(player, ref val); } private bool TickWolf(Player player, Demigod god) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) AbilityWolf val = NdMeters.ActiveWolf(player); if (val == null) { return false; } Row row = RowFor(Kind.Wolf, (DemigodAbility)(object)val, god, "Wolf", WolfColor); if (row == null) { return false; } int num = Mathf.CeilToInt(val.WolfCharacter.GetHealthPercentage() * 100f); string text = WolfName(val); if (num != row.A || text != row.Name) { row.A = num; row.Name = text; row.Bar.Set((float)num / 100f, Loc.F("$dgp_pet_health", text ?? Loc.T("$dgp_pet_wolf"), num)); } return true; } private bool TickMinions(Player player, Demigod god, out bool ghost) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) ghost = false; AbilityMinions val = NdMeters.Minions(player); if (val == null) { return false; } int activeSkeletons = val.GetActiveSkeletons(); int maxSkeletons = val.GetMaxSkeletons(); Character ghostCharacter = val.ghostCharacter; ghost = (Object)(object)ghostCharacter != (Object)null; if (ghost) { Row row = RowFor(Kind.Ghost, (DemigodAbility)(object)val, god, "Ghost", GhostColor); int num = Mathf.CeilToInt(ghostCharacter.GetHealthPercentage() * 100f); if (row == null) { ghost = false; } else if (num != row.A) { row.A = num; row.Bar.Set((float)num / 100f, Loc.F("$dgp_pet_health", Loc.T("$dgp_pet_ghost"), num)); } } if (activeSkeletons <= 0) { return false; } Row row2 = RowFor(Kind.Minions, (DemigodAbility)(object)val, god, "Skeleton", MinionColor); if (row2 == null) { return false; } if (activeSkeletons != row2.A || maxSkeletons != row2.B) { row2.A = activeSkeletons; row2.B = maxSkeletons; row2.Bar.Set((maxSkeletons > 0) ? ((float)activeSkeletons / (float)maxSkeletons) : 0f, Loc.F("$dgp_pet_minions", activeSkeletons, maxSkeletons)); } return true; } private bool TickNecks(Player player, Demigod god) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) AbilityNeck val = NdMeters.Necks(player); if (val == null) { return false; } Row row = RowFor(Kind.Necks, (DemigodAbility)(object)val, god, "Neck", NeckColor); if (row == null) { return false; } int activeNecks = val.GetActiveNecks(); int maxNecks = val.GetMaxNecks(); string text = NeckActivity(val); if (activeNecks != row.A || maxNecks != row.B || _neckActivityStamp != row.C) { row.A = activeNecks; row.B = maxNecks; row.C = _neckActivityStamp; string text2 = ((text != null) ? Loc.F("$dgp_pet_necks_doing", activeNecks, maxNecks, text) : Loc.F("$dgp_pet_necks", activeNecks, maxNecks)); row.Bar.Set((maxNecks > 0) ? ((float)activeNecks / (float)maxNecks) : 0f, text2); } return true; } private string WolfName(AbilityWolf wolf) { ZNetView val = (((Object)(object)wolf.WolfTameable != (Object)null) ? wolf.WolfTameable.m_nview : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); string text = ((val2 != null) ? val2.GetString(ZDOVars.s_tamedName, "") : null); if ((object)text != _wolfNameRaw) { _wolfNameRaw = text; _wolfName = (string.IsNullOrEmpty(text) ? null : StringExtensionMethods.RemoveRichTextTags(text)); } if (!string.IsNullOrEmpty(_wolfName)) { return _wolfName; } if (wolf.DataProperties == null || string.IsNullOrEmpty(wolf.DataProperties.Name)) { return null; } return wolf.DataProperties.Name; } private string NeckActivity(AbilityNeck necks) { string text; try { text = necks.GetCurrentActivityText(); } catch (Exception) { text = null; } if ((object)text == _neckActivityRaw) { return _neckActivity; } _neckActivityRaw = text; _neckActivityStamp++; string text2 = ((string.IsNullOrEmpty(text) || Loc.Missing(text)) ? null : text); if (text2 != null) { string text3 = Loc.T("$dgp_neck_" + text2.ToLowerInvariant()); text2 = ((Loc.Missing(text3) || text3.StartsWith("$")) ? text2 : text3); } _neckActivity = text2; return text2; } private bool TickGolem(Player player, Demigod god) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) AbilityElementalGolem val = default(AbilityElementalGolem); if (!Helper.TryGetDemigodAbility(player, ref val)) { return false; } Character stoneGolemCharacter = val.StoneGolemCharacter; if ((Object)(object)stoneGolemCharacter == (Object)null || stoneGolemCharacter.IsDead()) { return false; } Row row = RowFor(Kind.Golem, (DemigodAbility)(object)val, god, "Golem", GolemColor); if (row == null) { return false; } int num = Mathf.CeilToInt(stoneGolemCharacter.GetHealthPercentage() * 100f); if (num != row.A) { row.A = num; row.Bar.Set((float)num / 100f, Loc.F("$dgp_pet_health", Loc.T("$dgp_pet_golem"), num)); } return true; } private bool TickSurtlings(Player player, Demigod god) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) AbilitySurtling val = default(AbilitySurtling); if (!Helper.TryGetDemigodAbility(player, ref val)) { return false; } int num = 0; float num2 = 0f; float num3 = 0f; foreach (Character surtlingCharacter in val.SurtlingCharacters) { if ((Object)(object)surtlingCharacter != (Object)null && !surtlingCharacter.IsDead()) { num++; num2 += surtlingCharacter.GetHealth(); num3 += surtlingCharacter.GetMaxHealth(); } } if (num == 0) { return false; } Row row = RowFor(Kind.Surtlings, (DemigodAbility)(object)val, god, "Surtling", SurtlingColor); if (row == null) { return false; } int num4 = ((num3 > 0f) ? Mathf.CeilToInt(num2 / num3 * 100f) : 0); if (num != row.A || num4 != row.B) { row.A = num; row.B = num4; row.Bar.Set((float)num4 / 100f, Loc.F("$dgp_pet_surtlings", num, num4)); } return true; } private void AnimateRows(float dt) { Row[] rows = _rows; foreach (Row row in rows) { if (row != null && row.Bar.Animating && ((Component)row.Rt).gameObject.activeSelf) { row.Bar.Animate(dt); } } } private void EnsureRoot() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_009d: 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) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { Hud instance = Hud.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_rootObject == (Object)null)) { GameObject val = new GameObject("DemigodCompanions", new Type[2] { typeof(RectTransform), typeof(Canvas) }); _root = (RectTransform)val.transform; ((Transform)_root).SetParent(instance.m_rootObject.transform, false); RectTransform root = _root; RectTransform root2 = _root; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0f); root2.anchorMax = val2; root.anchorMin = val2; _root.pivot = Vector2.zero; _root.sizeDelta = new Vector2(36f + (float)Plugin.CompanionBarWidth.Value, 30f); ApplyLayout(); } } } private Row RowFor(Kind kind, DemigodAbility ability, Demigod god, string art, Color color) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) Row row = _rows[(int)kind]; if (row != null) { return row; } RectTransform val = UiKit.Box((Transform)(object)_root, kind.ToString(), 0f, 0f, _root.sizeDelta.x, 30f); Vector2 val2 = (val.anchorMin = (val.anchorMax = Vector2.zero)); val.pivot = Vector2.zero; Image val4 = UiKit.Image((Transform)(object)val, "Icon", AbilityView.CompanionIcon(art, ((Object)(object)god != (Object)null) ? god.DemigodName : null) ?? AbilityView.Icon(ability), Color.white); val4.preserveAspect = true; RectTransform rectTransform = ((Graphic)val4).rectTransform; ((Vector2)(ref val2))..ctor(0f, 0.5f); rectTransform.anchorMax = val2; rectTransform.anchorMin = val2; rectTransform.pivot = new Vector2(0f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = new Vector2(30f, 30f); HudBar hudBar = HudBar.Create((Transform)(object)val, "Bar", HudBar.FillWidthFor(Plugin.CompanionBarWidth.Value), 20f, 13f); RectTransform root = hudBar.Root; RectTransform root2 = hudBar.Root; ((Vector2)(ref val2))..ctor(0f, 0.5f); root2.anchorMax = val2; root.anchorMin = val2; hudBar.Root.pivot = new Vector2(0f, 0.5f); hudBar.Root.anchoredPosition = new Vector2(36f, 0f); hudBar.SetColor(color); row = new Row { Rt = val, Icon = val4, Bar = hudBar }; ((Component)val).gameObject.SetActive(false); _rows[(int)kind] = row; return row; } private void Stack(int mask) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) float num = 0f; for (int i = 0; i < _rows.Length; i++) { Row row = _rows[i]; bool flag = (mask & (1 << i)) != 0; if (row != null) { if (((Component)row.Rt).gameObject.activeSelf != flag) { ((Component)row.Rt).gameObject.SetActive(flag); } if (flag) { row.Rt.anchoredPosition = new Vector2(0f, num); num += 34f; } } } float num2 = Mathf.Max(30f, num - 4f); if (_root.sizeDelta.y != num2) { _root.sizeDelta = new Vector2(_root.sizeDelta.x, num2); ApplyLayout(); } } private void SetVisible(bool visible) { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf != visible) { ((Component)_root).gameObject.SetActive(visible); } } } internal abstract class PanelTab { public GameObject Root; public abstract void Build(DemigodPanelView view, RectTransform root); public abstract void Rebuild(Demigod god); public abstract void Refresh(); public virtual void Tick() { } public virtual void Hidden() { } } internal sealed class DemigodPanelView { public const float Width = 1400f; public const float Height = 820f; public const float ContentY = 190f; public const float ContentH = 520f; public const float LeftX = 30f; public const float LeftW = 430f; public const float MidX = 475f; public const float MidW = 520f; public const float RightX = 1010f; public const float RightW = 360f; private const float RefreshSeconds = 0.5f; private GameObject _panel; private Text _godName; private Text _godSub; private Image _godIcon; private Button _change; private readonly Button[] _tabButtons = (Button[])(object)new Button[3]; private readonly Text[] _tabLabels = (Text[])(object)new Text[3]; private readonly PanelTab[] _tabs = new PanelTab[3]; private readonly TabStamps _built = new TabStamps(3); private int _tab; private Text _levelText; private Image _xpFill; private HudBar _xpBar; private Text _xpText; private Text _capText; private ConfirmDialog _confirm; private float _refresh; private int _builtVersion = -1; private Demigod _god; public const int TabAbilities = 0; public const int TabPerks = 1; public const int TabPantheon = 2; private bool _warming; private CanvasGroup _group; private int _toggledFrame = -1; private PanelInput _input; private bool _releaseBlock; private int _releaseFrame; private int _hfLevel = -1; private int _hfRaw = -1; private int _hfAcc = -1; private int _hfTrophies = -1; private int _hfTab = -1; private int _hfVersion = -1; private int _hfConfig = -1; private object _hfGod; private int _pendingTab = -1; public bool IsOpen { get { if ((Object)(object)_panel != (Object)null && _panel.activeSelf) { return !_warming; } return false; } } public bool ToggledThisFrame => _toggledFrame == Time.frameCount; public PantheonTab Pantheon => (PantheonTab)_tabs[2]; public void Build() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown _panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1400f, 820f, false); ((Object)_panel).name = "DemigodPanel"; _panel.SetActive(false); _group = _panel.AddComponent(); Transform transform = _panel.transform; UiKit.Text(transform, Loc.T("$dgp_title").ToUpperInvariant(), 38, UiKit.Orange, (TextAnchor)1, 0f, 14f, 1400f, 48f, bold: true, norse: true); _godName = UiKit.Text(transform, string.Empty, 28, Color.white, (TextAnchor)1, 300f, 62f, 800f, 36f, bold: true); _godSub = UiKit.Text(transform, string.Empty, 16, UiKit.Muted, (TextAnchor)1, 300f, 98f, 800f, 24f); _godIcon = UiKit.Image(transform, "GodIcon", null, Color.white); _godIcon.preserveAspect = true; Place(((Graphic)_godIcon).rectTransform, 0f, 64f, 52f, 52f); ((Behaviour)_godIcon).enabled = false; _change = UiKit.Button(transform, Loc.T("$dgp_change"), 1150f, 70f, 200f, 40f, delegate { ShowTab(2); }); UiKit.Button(transform, "X", 1338f, 18f, 40f, 40f, Close); string[] array = new string[3] { "$dgp_tab_abilities", "$dgp_tab_perks", "$dgp_tab_pantheon" }; for (int num = 0; num < 3; num++) { int index = num; _tabButtons[num] = UiKit.Button(transform, Loc.T(array[num]), 30f + (float)num * 220f, 132f, 210f, 40f, delegate { ShowTab(index); }); _tabLabels[num] = ((Component)_tabButtons[num]).GetComponentInChildren(); } Place(((Graphic)UiKit.Image(transform, "Divider", UiKit.White, new Color(1f, 0.85f, 0.6f, 0.15f))).rectTransform, 30f, 180f, 1340f, 2f); _tabs[0] = new AbilitiesTab(); _tabs[1] = new PerksTab(); _tabs[2] = new PantheonTab(); PanelTab[] tabs = _tabs; foreach (PanelTab panelTab in tabs) { RectTransform val = UiKit.Box(transform, panelTab.GetType().Name, 0f, 0f, 1400f, 820f); panelTab.Root = ((Component)val).gameObject; panelTab.Build(this, val); panelTab.Root.SetActive(false); } BuildFooter(transform); _confirm = new ConfirmDialog(GUIManager.CustomGUIFront.transform); GameObject val2 = new GameObject("DemigodPanelInput"); val2.transform.SetParent(GUIManager.CustomGUIFront.transform, false); _input = val2.AddComponent(); _input.View = this; } private void BuildFooter(Transform t) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) float num = 724f; _levelText = UiKit.Text(t, string.Empty, 22, UiKit.Orange, (TextAnchor)3, 30f, num, 200f, 30f, bold: true); _xpBar = HudBar.Create(t, "XpBar", HudBar.FillWidthFor(904f), 26f, 16f); if (_xpBar != null) { RectTransform root = _xpBar.Root; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); root.anchorMax = val; root.anchorMin = val; root.pivot = new Vector2(0f, 0.5f); root.anchoredPosition = new Vector2(228f, 0f - (num + 15f)); _xpBar.SetColor(ElementColors.Xp); _xpText = UiKit.Text(t, string.Empty, 18, Color.white, (TextAnchor)5, 1140f, num, 230f, 30f, bold: true); _capText = UiKit.Text(t, string.Empty, 16, UiKit.Muted, (TextAnchor)4, 30f, num + 36f, 1340f, 26f); } else { Image obj = UiKit.Image(t, "XpFrame", UiKit.White, new Color(0.55f, 0.42f, 0.26f, 0.9f)); Place(((Graphic)obj).rectTransform, 228f, num + 3f, 904f, 24f); Image val2 = UiKit.Image(((Component)obj).transform, "XpBg", UiKit.White, new Color(0.06f, 0.05f, 0.04f, 0.95f)); UiKit.Fill(((Graphic)val2).rectTransform, 2f); _xpFill = UiKit.Image(((Component)val2).transform, "XpFill", UiKit.White, new Color(0.95f, 0.7f, 0.25f, 0.95f)); _xpFill.type = (Type)3; _xpFill.fillMethod = (FillMethod)0; _xpFill.fillAmount = 0f; UiKit.Fill(((Graphic)_xpFill).rectTransform, 1f); _xpText = UiKit.Text(t, string.Empty, 18, Color.white, (TextAnchor)5, 1140f, num, 230f, 30f, bold: true); _capText = UiKit.Text(t, string.Empty, 16, UiKit.Muted, (TextAnchor)4, 30f, num + 36f, 1340f, 26f); } } public static void Place(RectTransform rt, float x, float y, float w, float h) { //IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, 0f - y); rt.sizeDelta = new Vector2(w, h); } public IEnumerator WarmUp() { if ((Object)(object)_panel == (Object)null || _panel.activeSelf || (Object)(object)Player.m_localPlayer == (Object)null) { yield break; } _warming = true; _group.alpha = 0f; _group.blocksRaycasts = false; _panel.SetActive(true); int[] array = new int[3] { 0, 1, 2 }; int[] array2 = array; foreach (int tab in array2) { if (!_warming) { yield break; } if (!WarmStep(tab)) { break; } yield return null; } EndWarmUp(); } private bool WarmStep(int tab) { long start = Perf.Begin(); long mem = Perf.BeginMem(); try { SyncGod(); ShowTab(tab); return true; } catch (Exception ex) { Plugin.Log.LogDebug((object)("Panel warm-up stopped: " + ex.Message)); return false; } finally { Perf.End(Perf.Scope.PanelWarm, start, mem); } } private void EndWarmUp() { if (_warming) { _warming = false; _panel.SetActive(false); _group.alpha = 1f; _group.blocksRaycasts = true; } } public void Open(int tab = -1) { if (!((Object)(object)_panel == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { long start = Perf.Begin(); long mem = Perf.BeginMem(); OpenInner(tab); Perf.End(Perf.Scope.PanelOpen, start, mem); } } private void OpenInner(int tab) { EndWarmUp(); if (!IsOpen) { _panel.SetActive(true); _toggledFrame = Time.frameCount; if (_releaseBlock) { _releaseBlock = false; } else { GUIManager.BlockInput(true); } } SyncGod(); ShowTab((tab >= 0) ? tab : (((Object)(object)_god == (Object)null) ? 2 : 0)); } public void Close() { Close(releaseLate: false); } private void Close(bool releaseLate) { _pendingTab = -1; _confirm?.Hide(); ValueTip.Hide(); if (IsOpen) { _tabs[_tab].Hidden(); _panel.SetActive(false); _toggledFrame = Time.frameCount; if (releaseLate) { _releaseBlock = true; _releaseFrame = Time.frameCount; return; } GUIManager.BlockInput(false); } ReleaseBlock(); } public void HandleCloseKeys() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (IsOpen && !ToggledThisFrame && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && (ZInput.GetKeyDown((KeyCode)27, false) || Utils.Pressed(Plugin.PanelKey.Value))) { Back(); } } public void LateRelease() { ReleaseBlock(); } private void ReleaseBlock() { if (_releaseBlock) { _releaseBlock = false; GUIManager.BlockInput(false); } } public void ShowTab(int index) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_god == (Object)null && index != 2) { index = 2; } _tab = index; EnsureBuilt(index); for (int i = 0; i < _tabs.Length; i++) { if (i != index && _tabs[i].Root.activeSelf) { _tabs[i].Hidden(); } _tabs[i].Root.SetActive(i == index); Text val = _tabLabels[i]; if ((Object)(object)val != (Object)null) { ((Graphic)val).color = ((i == index) ? UiKit.Orange : (((Object)(object)_god == (Object)null && i != 2) ? (UiKit.Muted * 0.7f) : Color.white)); } ((Selectable)_tabButtons[i]).interactable = (Object)(object)_god != (Object)null || i == 2; } RefreshNow(); } public void ShowBasics() { ShowTab(2); Pantheon.ShowBasics(); } public void Back() { if (_confirm != null && _confirm.IsOpen) { _confirm.Hide(); } else { Close(releaseLate: true); } } public void Update(Player player, float dt) { if (_releaseBlock && Time.frameCount != _releaseFrame) { ReleaseBlock(); } if (!IsOpen) { return; } if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { Close(); return; } long start = Perf.Begin(); long mem = Perf.BeginMem(); bool num = SyncGod(); Perf.End(Perf.Scope.PanelUpdate, start, mem); if (num) { int num2 = ((_pendingTab >= 0 && (Object)(object)_god != (Object)null) ? _pendingTab : _tab); if (num2 == _pendingTab) { _pendingTab = -1; } ShowTab(num2); } else { _tabs[_tab].Tick(); _refresh -= dt; if (_refresh <= 0f) { RefreshNow(); } } } private bool SyncGod() { if (NdEvents.Pending) { return false; } Demigod val = NdBridge.GodOf(Player.m_localPlayer); if (val == _god && _builtVersion == NdEvents.Version) { return false; } _god = val; _builtVersion = NdEvents.Version; return true; } private void EnsureBuilt(int index) { if (_built.Take(index, _god, _builtVersion)) { long start = Perf.Begin(); long mem = Perf.BeginMem(); try { _tabs[index].Rebuild(_god); } catch { _built.Forget(index); throw; } Perf.End(index switch { 1 => Perf.Scope.TabPerks, 0 => Perf.Scope.TabAbilities, _ => Perf.Scope.TabPantheon, }, start, mem); Perf.End(Perf.Scope.PanelRebuild, start, mem); } } private void RefreshNow() { long start = Perf.Begin(); long mem = Perf.BeginMem(); _refresh = 0.5f; RefreshHeaderAndFooter(); _tabs[_tab].Refresh(); Perf.End(Perf.Scope.PanelRefresh, start, mem); } private void RefreshHeaderAndFooter() { //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; NdBridge.RawSkill(localPlayer, out var level, out var accumulator); float num = NdBridge.Level(localPlayer); int num2 = Mathf.FloorToInt(num); if (level < 100f) { SetXpFill(XpMath.Percent(level, accumulator)); } int num3 = (((Object)(object)localPlayer != (Object)null) ? localPlayer.m_trophies.Count : 0); if (num2 != _hfLevel || (int)level != _hfRaw || Mathf.FloorToInt(accumulator) != _hfAcc || num3 != _hfTrophies || _tab != _hfTab || _god != _hfGod || _hfVersion != NdEvents.Version || _hfConfig != NdEvents.ConfigVersion) { _hfLevel = num2; _hfRaw = (int)level; _hfAcc = Mathf.FloorToInt(accumulator); _hfTrophies = num3; _hfTab = _tab; _hfGod = _god; _hfVersion = NdEvents.Version; _hfConfig = NdEvents.ConfigVersion; if ((Object)(object)_god == (Object)null) { Set(_godName, Loc.T("$dgp_no_god")); Set(_godSub, Loc.T("$dgp_no_god_sub")); UiKit.SetLabel(_change, Loc.T("$dgp_choose")); } else { Set(_godName, NdBridge.GodDisplayName(_god.DemigodName).ToUpperInvariant()); Set(_godSub, Loc.F("$dgp_header_sub", Texts.Lore(_god.DemigodName, "epithet") ?? string.Empty, num2)); UiKit.SetLabel(_change, Loc.T("$dgp_change")); } PlaceGodIcon(); ((Component)_change).gameObject.SetActive(_tab != 2); Set(_levelText, Loc.F("$dgp_level", num2)); if (level >= 100f) { SetXpFill(1f); Set(_xpText, Loc.T("$dgp_xp_max")); } else { Set(_xpText, Loc.F("$dgp_xp", Mathf.FloorToInt(accumulator), Mathf.CeilToInt(XpMath.Requirement(level)))); } Set(_capText, CapLine(localPlayer, num, level, out var capped)); ((Graphic)_capText).color = (capped ? UiKit.Warn : UiKit.Muted); _xpBar?.SetColor(capped ? ElementColors.XpCapped : ElementColors.Xp); } } private void PlaceGodIcon() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Sprite val = (((Object)(object)_god != (Object)null) ? AbilityView.GodIcon(_god.DemigodName) : null); ((Behaviour)_godIcon).enabled = (Object)(object)val != (Object)null; if (!((Object)(object)val == (Object)null)) { _godIcon.sprite = val; float num = Mathf.Max(_godName.preferredWidth, _godSub.preferredWidth) * 0.5f; RectTransform rectTransform = ((Graphic)_godIcon).rectTransform; rectTransform.anchoredPosition = new Vector2(Mathf.Max(24f, 700f - num - 14f - 52f), rectTransform.anchoredPosition.y); } } private void SetXpFill(float fraction) { if (_xpBar != null) { _xpBar.Set(fraction, string.Empty, trail: false); } else if ((Object)(object)_xpFill != (Object)null) { _xpFill.fillAmount = fraction; } } internal static string CapLine(Player player, float level, float rawLevel, out bool capped) { capped = false; if (rawLevel >= 100f) { return Loc.T("$dgp_peak"); } CapState capState = NdBridge.Cap(player, level); if (capState.Cap <= 0) { return Loc.T("$dgp_cap_none"); } string text = ((capState.NextTier >= 0) ? NdBridge.TrophyName(capState.NextTier) : null); if (capState.Capped) { capped = true; if (text == null) { return Loc.F("$dgp_capped_stuck", capState.Cap); } if (capState.NextCap <= 0) { return Loc.F("$dgp_capped_free", capState.Cap, text); } return Loc.F("$dgp_capped", capState.Cap, text, capState.NextCap); } if (text == null) { return Loc.F("$dgp_cap_only", capState.Cap); } if (capState.NextCap <= 0) { return Loc.F("$dgp_cap_line_free", capState.Cap, text); } return Loc.F("$dgp_cap_line", capState.Cap, text, capState.NextCap); } private static void Set(Text text, string value) { if (text.text != value) { text.text = value; } } public void AskBecome(GodInfo god) { if (god == null || god.Disabled) { return; } Player localPlayer = Player.m_localPlayer; string displayName = god.DisplayName; int levelsLostOnSwitch = NdBridge.LevelsLostOnSwitch; string title; string text; if ((Object)(object)_god == (Object)null) { title = Loc.F("$dgp_confirm_title_first", displayName); text = ((levelsLostOnSwitch > 0) ? Loc.F("$dgp_confirm_first", levelsLostOnSwitch) : Loc.T("$dgp_confirm_first_free")); if (NdBridge.SwitchUsesRunestone(localPlayer)) { text = text + "\n\n• " + Loc.T("$dgp_confirm_runestone"); } } else { string text2 = NdBridge.GodDisplayName(_god.DemigodName); int num = Mathf.FloorToInt(NdBridge.Level(localPlayer)); NdBridge.AfterSwitch(localPlayer, out var level, out var percent); title = Loc.F("$dgp_confirm_title_switch", text2, displayName); StringBuilder stringBuilder = new StringBuilder(512); stringBuilder.Append((level < num) ? Loc.F("$dgp_confirm_loss", num, level) : Loc.F("$dgp_confirm_keep_level", level)).Append(' ').Append(Loc.F("$dgp_confirm_progress", percent)) .Append("\n\n"); stringBuilder.Append("• ").Append(Loc.T("$dgp_confirm_energy")).Append('\n'); stringBuilder.Append("• ").Append(Loc.F("$dgp_confirm_lose_powers", text2)).Append('\n'); if (NdBridge.HasAbility(_god)) { stringBuilder.Append("• ").Append(Loc.T("$dgp_confirm_wolf")).Append('\n'); } if (NdBridge.HasAbility(_god)) { stringBuilder.Append("• ").Append(Loc.T("$dgp_confirm_teleport")).Append('\n'); } if (NdBridge.SwitchUsesRunestone(localPlayer)) { stringBuilder.Append("• ").Append(Loc.T("$dgp_confirm_runestone")).Append('\n'); } text = stringBuilder.ToString().TrimEnd(new char[1] { '\n' }); } _confirm.Show(title, text, Loc.F("$dgp_confirm_yes", displayName), delegate { Become(god); }); } private void Become(GodInfo god) { if (!NdBridge.Become(god, out var error, out var _)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, Loc.T(error), 0, (Sprite)null, false); } } else { NdEvents.MarkChanged(); _pendingTab = 0; } } public void LateUpdate() { ReleaseBlock(); if (_pendingTab >= 0 && IsOpen && !NdEvents.Pending && (Object)(object)NdBridge.GodOf(Player.m_localPlayer) != (Object)null) { SyncGod(); ShowTab(_pendingTab); _pendingTab = -1; } } public void Destroy() { EndWarmUp(); Close(); if ((Object)(object)_input != (Object)null) { Object.Destroy((Object)(object)((Component)_input).gameObject); } ValueTip.Destroy(); _confirm?.Destroy(); if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); } } } internal sealed class ConfirmDialog { private readonly GameObject _root; private readonly Text _title; private readonly Text _body; private readonly Button _yes; private Action _onYes; public bool IsOpen => _root.activeSelf; public ConfirmDialog(Transform parent) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) GameObject val = (_root = new GameObject("DemigodConfirm", new Type[2] { typeof(RectTransform), typeof(Image) })); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(parent, false); UiKit.Fill(val2); Image component = val.GetComponent(); component.sprite = UiKit.White; ((Graphic)component).color = new Color(0f, 0f, 0f, 0.55f); Transform transform = GUIManager.Instance.CreateWoodpanel((Transform)(object)val2, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 660f, 420f, false).transform; _title = UiKit.Text(transform, string.Empty, 24, UiKit.Orange, (TextAnchor)1, 20f, 22f, 620f, 34f, bold: true); _body = UiKit.Text(transform, string.Empty, 17, Color.white, (TextAnchor)0, 44f, 70f, 572f, 260f); _yes = UiKit.Button(transform, string.Empty, 70f, 350f, 250f, 44f, delegate { Action onYes = _onYes; Hide(); onYes?.Invoke(); }); UiKit.Button(transform, Loc.T("$dgp_confirm_no"), 340f, 350f, 250f, 44f, Hide); _root.SetActive(false); } public void Show(string title, string body, string yesLabel, Action onYes) { _title.text = title; _body.text = NumberStyle.Tint(body); UiKit.SetLabel(_yes, yesLabel); _onYes = onYes; _root.transform.SetAsLastSibling(); _root.SetActive(true); } public void Hide() { _onYes = null; if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } public void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } } internal sealed class PanelInput : MonoBehaviour { public DemigodPanelView View; private readonly Guard _guard = new Guard("Demigod panel keys", shared: false, keepTrying: true); private void Update() { if (View == null || !_guard.Ready || !View.IsOpen) { return; } try { View.HandleCloseKeys(); } catch (Exception ex) { _guard.Fail(ex); } } private void LateUpdate() { if (View == null) { return; } try { View.LateRelease(); } catch (Exception ex) { _guard.Fail(ex); } } } internal sealed class DetailsCard { private readonly Image _icon; private readonly RectTransform _iconBox; private readonly Image _roundBack; private readonly Image _roundRing; private bool _round; private readonly Text _title; private readonly Text _subtitle; private readonly RichBody _body; private readonly ScrollRect _scroll; private object _shown; private const float IconSide = 56f; public DetailsCard(Transform parent, float x, float y, float w, float h) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) UiKit.Inset(parent, "DetailsBg", x, y, w, h); _iconBox = UiKit.Box(parent, "DetailsIcon", x + 14f, y + 14f, 56f, 56f); if (SlotArt.Ready) { _roundBack = UiKit.Image((Transform)(object)_iconBox, "Bg", SlotArt.Back, Color.white); UiKit.Fill(((Graphic)_roundBack).rectTransform, -3.5f); ((Behaviour)_roundBack).enabled = false; } _icon = UiKit.Image((Transform)(object)_iconBox, "Icon", null, Color.white); _icon.preserveAspect = true; UiKit.Fill(((Graphic)_icon).rectTransform); if (SlotArt.Ready) { _roundRing = UiKit.Image((Transform)(object)_iconBox, "Ring", SlotArt.Ring, Color.white); UiKit.Fill(((Graphic)_roundRing).rectTransform); ((Behaviour)_roundRing).enabled = false; } _title = UiKit.Text(parent, string.Empty, 22, UiKit.Orange, (TextAnchor)0, x + 82f, y + 14f, w - 96f, 30f, bold: true); _subtitle = UiKit.Text(parent, string.Empty, 14, UiKit.Muted, (TextAnchor)0, x + 82f, y + 44f, w - 96f, 36f); _body = UiKit.ScrollBody(parent, x + 12f, y + 84f, w - 24f, h - 96f, 16, out _scroll); } public void Show(object subject, Sprite icon, string title, string subtitle, string body, NumberSheet sheet = null, string pulsed = null, bool round = false) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) _body.Detail = ((sheet != null) ? new Func(sheet.Detail) : null); _icon.sprite = icon; ((Behaviour)_icon).enabled = (Object)(object)icon != (Object)null; SetRound(round && (Object)(object)icon != (Object)null && (Object)(object)_roundRing != (Object)null); RectTransform rectTransform = ((Graphic)_title).rectTransform; float num = (((Object)(object)icon != (Object)null) ? 0f : (-68f)); if (!Mathf.Approximately(rectTransform.anchoredPosition.x, _iconBox.anchoredPosition.x + 68f + num)) { rectTransform.anchoredPosition = new Vector2(_iconBox.anchoredPosition.x + 68f + num, rectTransform.anchoredPosition.y); ((Graphic)_subtitle).rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, ((Graphic)_subtitle).rectTransform.anchoredPosition.y); } SetText(_title, title); SetText(_subtitle, subtitle); if (pulsed != null) { _body.Pulse(pulsed, body); } else { _body.Set(body); } if (!object.Equals(subject, _shown)) { _shown = subject; _scroll.verticalNormalizedPosition = 1f; } } private void SetRound(bool round) { if (round != _round) { _round = round; ((Behaviour)_roundBack).enabled = round; ((Behaviour)_roundRing).enabled = round; UiKit.Fill(((Graphic)_icon).rectTransform, round ? 3.9815998f : 0f); } } private static void SetText(Text text, string value) { if (value == null) { value = string.Empty; } if (text.text != value) { text.text = value; } } } internal sealed class FigureView { private static readonly Dictionary Portraits = new Dictionary(); private const float FrameH = 280f; private const float FrameBorder = 3f; private readonly Image _portrait; private readonly Vector2 _window; private readonly Text _name; private readonly Text _epithet; private readonly Text _element; private string _key = "-"; public FigureView(Transform parent, float x, float y, float w, float h) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) UiKit.Inset(parent, "FigureBg", x, y, w, h); Image obj = UiKit.Image(parent, "FigureFrame", UiKit.White, Color32.op_Implicit(new Color32((byte)17, (byte)8, (byte)7, byte.MaxValue))); RectTransform rectTransform = ((Graphic)obj).rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(x + w * 0.5f, 0f - (y + 20f)); rectTransform.sizeDelta = new Vector2(w - 60f, 280f); Image val2 = UiKit.Image(((Component)obj).transform, "PortraitWindow", UiKit.White, new Color(0.16f, 0.12f, 0.1f, 1f)); ((Component)val2).gameObject.AddComponent(); UiKit.Fill(((Graphic)val2).rectTransform, 3f); _window = new Vector2(w - 60f - 6f, 274f); _portrait = UiKit.Image(((Component)val2).transform, "Portrait", null, Color.white); _portrait.preserveAspect = true; RectTransform rectTransform2 = ((Graphic)_portrait).rectTransform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); rectTransform2.pivot = val3; val = (rectTransform2.anchorMin = (rectTransform2.anchorMax = val3)); _name = UiKit.Text(parent, string.Empty, 34, UiKit.Orange, (TextAnchor)1, x, y + 310f, w, 44f, bold: true, norse: true); _epithet = UiKit.Text(parent, string.Empty, 16, UiKit.Gold, (TextAnchor)1, x + 10f, y + 356f, w - 20f, 24f); _element = UiKit.Text(parent, string.Empty, 14, UiKit.Muted, (TextAnchor)1, x + 10f, y + 382f, w - 20f, 40f); _element.supportRichText = true; } public void Show(string key, string displayName) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (!(key == _key) || !(_name.text == (displayName ?? string.Empty))) { _key = key; _name.text = displayName ?? string.Empty; if (key == null) { _portrait.sprite = AbilityView.Fallback(); ((Graphic)_portrait).color = new Color(1f, 1f, 1f, 0.35f); FitPortrait(cover: false); _epithet.text = string.Empty; _element.text = string.Empty; } else { _portrait.sprite = Portrait(key); ((Graphic)_portrait).color = Color.white; FitPortrait(_portrait.sprite != AbilityView.Fallback()); _epithet.text = Texts.Lore(key, "epithet") ?? string.Empty; _element.text = NumberStyle.Tint(Texts.ElementLine(key) ?? string.Empty); } } } private void FitPortrait(bool cover) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) float num = (cover ? Mathf.Max(_window.x, _window.y) : (Mathf.Min(_window.x, _window.y) - 14f)); ((Graphic)_portrait).rectTransform.sizeDelta = new Vector2(num, num); } public static Sprite Portrait(string key) { if (Portraits.TryGetValue(key, out var value)) { return value; } long start = Perf.Begin(); long mem = Perf.BeginMem(); Sprite val = LoadPortrait("DemigodPanel.Assets.Portraits." + key.ToLowerInvariant() + ".dxt1") ?? AbilityView.Fallback(); Perf.End(Perf.Scope.PortraitLoad, start, mem); Portraits[key] = val; return val; } private static Sprite LoadPortrait(string resource) { //IL_0093: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown byte[] array = Utils.ReadResource(resource); if (array == null || array.Length < 16 || array[0] != 68 || array[1] != 71 || array[2] != 80 || array[3] != 84) { return null; } int num = BitConverter.ToInt32(array, 4); int num2 = BitConverter.ToInt32(array, 8); int num3 = BitConverter.ToInt32(array, 12); if (num <= 0 || num2 <= 0 || num3 <= 0 || PortraitFile.Dxt1Bytes(num, num2, num3) != array.Length - 16) { Plugin.Log.LogWarning((object)("Portrait " + resource + " has an unexpected size; the emblem shows instead.")); return null; } Texture2D val = null; GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned); try { val = new Texture2D(num, num2, (TextureFormat)10, num3, false) { name = resource, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)2 }; val.LoadRawTextureData(gCHandle.AddrOfPinnedObject() + 16, array.Length - 16); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Portrait " + resource + " could not be loaded: " + ex.Message)); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } return null; } finally { gCHandle.Free(); } val.Apply(false, true); return Utils.ToSprite(val); } } internal static class Texts { private static readonly StringBuilder Sb = new StringBuilder(1024); private static readonly NumberSheet HudSheet = new NumberSheet(); private static readonly string OrangeHex = UiKit.Hex(UiKit.Orange); private static readonly string IceHex = UiKit.Hex(UiKit.Ice); private static readonly string GoldHex = UiKit.Hex(UiKit.Gold); private static readonly string MutedHex = UiKit.Hex(UiKit.Muted); private static readonly string WarnHex = UiKit.Hex(UiKit.Warn); private static readonly NumberSheet ElementSheet = new NumberSheet(); private static readonly string StrengthHex = UiKit.Hex(new Color(0.56f, 0.82f, 0.42f)); private static readonly string WeaknessHex = UiKit.Hex(new Color(1f, 0.48f, 0.36f)); private static readonly string RiddleHex = UiKit.Hex(new Color(0.9f, 0.83f, 0.66f)); public static string Header(string title) { return "" + title + ""; } public static string Lore(string godKey, string field) { string text = "$dgp_god_" + godKey.ToLowerInvariant() + "_" + field; string text2 = Loc.T(text); if (!Loc.Missing(text2) && !(text2 == text)) { return text2; } return null; } public static string KindLabel(DemigodAbility ability) { switch (AbilityView.Kind(ability)) { case AbilityKind.Special: { string text = AbilityView.SpecialContext(ability); if (text == null) { return Loc.T("$dgp_kind_special"); } return Loc.T("$dgp_kind_special") + " · " + text; } case AbilityKind.Teleport: return Loc.T("$dgp_kind_teleport"); default: return Loc.T("$dgp_kind_slot"); } } public static string CostLine(DemigodAbility a, Player player, bool infused) { if ((Object)(object)player == (Object)null) { return TemplateCostLine(a); } List list = new List(); if (a.DrainsEnergy) { list.Add(Loc.F("$dgp_cost_drain", NumberFormat.Digits(a.EnergyDrainPeriod))); } else { int num = ((!infused || !(a is AbilityCharm)) ? a.EnergyCost : 0); int num2 = AbilityView.EnergyNeeded(a, infused); if (num > 0) { list.Add(Loc.F("$dgp_cost_energy", num)); } if (num2 > num) { list.Add(Loc.F("$dgp_cost_energy_needs", num2)); } } AddEitr(list, AbilityView.Eitr(a, player, infused)); float num3 = AbilityView.Cooldown(a, infused); if (num3 > 0f) { list.Add(Loc.F("$dgp_cost_cooldown", NumberFormat.Digits(num3))); } float num4 = AbilityView.Duration(a, infused); if (num4 > 0f) { list.Add(Loc.F("$dgp_cost_duration", NumberFormat.Digits(num4))); } if (a.IsChanneled) { list.Add(Loc.T("$dgp_cost_channel")); } if (list.Count != 0) { return string.Join(" · ", list); } return Loc.T("$dgp_cost_free"); } private static void AddEitr(List parts, EitrUse eitr) { if (eitr.Any) { parts.Add(eitr.TakesMore ? Loc.F("$dgp_cost_eitr_most", NumberFormat.Digits(eitr.Needed), NumberFormat.Digits(eitr.Most)) : Loc.F("$dgp_cost_eitr", NumberFormat.Digits(eitr.Needed))); } } public static string ElementLine(string key) { string text = Lore(key, "element"); if (text == null) { return null; } ElementSheet.Begin(); return ElementSheet.Render(text); } public static string Ours(object ndObject, string godKey, string suffix, NumberSheet sheet) { string text = ((ndObject is DemigodAbility) ? "$dgp_ab_" : "$dgp_tr_"); string name = ndObject.GetType().Name; string text2 = ((godKey != null) ? Find(text + name + "_" + godKey.ToLowerInvariant() + suffix) : null); if (text2 == null) { text2 = Find(text + name + suffix); } if (text2 == null) { return null; } return sheet.Render(text2); } private static string Find(string token) { string text = Loc.T(token); if (!Loc.Missing(text) && !(text == token)) { return text; } return null; } private static string TemplateCostLine(DemigodAbility a) { string name = ((object)a).GetType().Name; List list = new List(); NdSettings instance = NdSettings.Instance; double value2; if (instance.TryGet(name + ".EnergyDrainTimePeriod", out var value) && value > 0.0) { list.Add(Loc.F("$dgp_cost_drain", NumberFormat.Digits(value))); } else if (a.DrainsEnergy && a.EnergyDrainPeriod > 0f) { list.Add(Loc.F("$dgp_cost_drain", NumberFormat.Digits(a.EnergyDrainPeriod))); } else if (instance.TryGet(name + ".AbilityEnergyCost", out value2) && value2 > 0.0) { list.Add(Loc.F("$dgp_cost_energy", (int)value2)); } EitrUse eitr = AbilityView.Eitr(a, null, infused: false); if (!eitr.Any && instance.TryGet(name + ".AbilityEitrCost", out var value3)) { eitr = AbilityView.EitrFromSetting(name, value3, null); } AddEitr(list, eitr); if (instance.TryGet(name + ".AbilityCooldown", out var value4) && value4 > 0.0) { list.Add(Loc.F("$dgp_cost_cooldown", NumberFormat.Digits(value4))); } if (instance.TryGet(name + ".AbilityDuration", out var value5) && value5 > 0.0) { list.Add(Loc.F("$dgp_cost_duration", NumberFormat.Digits(value5))); } if (list.Count != 0) { return string.Join(" · ", list); } return Loc.T("$dgp_cost_free"); } public static string AbilityBody(DemigodAbility a, Player player, int level, bool infused, NumberSheet sheet) { string text = (((Object)(object)a.Demigod != (Object)null) ? a.Demigod.DemigodName : null); Sb.Clear(); Sb.Append(Header(Loc.T("$dgp_how_to_use"))).Append('\n').Append(AbilityView.KeyLabelOf(a)); string text2 = AbilityView.SpecialContext(a); if (text2 != null) { Sb.Append(" · ").Append(text2); } Sb.Append("\n\n"); Sb.Append(Header(Loc.T("$dgp_cost"))).Append('\n').Append(CostLine(a, player, infused)) .Append('\n'); if (a.IsActive) { Sb.Append(Loc.T("$dgp_active_now")).Append('\n'); } StatusEffect val = (((Object)(object)player != (Object)null) ? ((Character)player).GetSEMan().GetStatusEffect(AbilityView.CooldownHash(a)) : null); if ((Object)(object)val != (Object)null) { Sb.Append(Loc.F("$dgp_cooling", Mathf.CeilToInt(val.GetRemaningTime()))).Append('\n'); } string text3 = Ours(a, text, string.Empty, sheet); Sb.Append('\n').Append(Header(Loc.T("$dgp_description"))).Append('\n'); Sb.Append(text3 ?? AbilityView.Safe((Func)a.GetTooltip) ?? string.Empty).Append('\n'); AppendAbilityNote(a); string text4 = ((text3 == null) ? AbilityView.Safe((Func)a.GetStatusTooltip) : null); if (text4 != null) { Sb.Append('\n').Append(Header(Loc.F("$dgp_now", level))).Append('\n') .Append(text4) .Append('\n'); } string text5 = Ours(a, text, "_infused", sheet) ?? ((text3 == null) ? AbilityView.Safe((Func)a.GetInfusedTooltip) : null); if (text5 != null) { Sb.Append('\n').Append(Header(Loc.T("$dgp_infusion"))).Append('\n'); Sb.Append(Loc.T(infused ? "$dgp_infusion_on" : "$dgp_infusion_off")).Append('\n'); Sb.Append(text5).Append('\n'); string text6 = (infused ? null : InfusionHint(text)); if (text6 != null) { Sb.Append('\n').Append("") .Append(Loc.T("$dgp_infusion_clue")) .Append("\n") .Append(text6) .Append('\n'); } } return Sb.ToString(); } public static string AbilityTooltip(DemigodAbility a, Player player) { Sb.Clear(); Sb.Append("') .Append(AbilityView.KeyLabelOf(a)) .Append(" · ") .Append(CostLine(a, player, NdBridge.AbilitiesInfused(player))) .Append('\n'); if (a.IsActive) { Sb.Append(Loc.T("$dgp_active_now")).Append('\n'); } StatusEffect val = (((Object)(object)player != (Object)null) ? ((Character)player).GetSEMan().GetStatusEffect(AbilityView.CooldownHash(a)) : null); if ((Object)(object)val != (Object)null) { Sb.Append(Loc.F("$dgp_cooling", Mathf.CeilToInt(val.GetRemaningTime()))).Append('\n'); } HudSheet.SetPlayer(player, asOtherGod: false); HudSheet.Begin(); string text = Ours(a, ((Object)(object)a.Demigod != (Object)null) ? a.Demigod.DemigodName : null, string.Empty, HudSheet); string text2 = text ?? AbilityView.Safe((Func)a.GetTooltip); if (text2 != null) { Sb.Append('\n').Append(text2).Append('\n'); } string text3 = ((text == null) ? AbilityView.Safe((Func)a.GetStatusTooltip) : null); if (text3 != null) { int num = Mathf.FloorToInt(NdBridge.Level(player)); Sb.Append('\n').Append("') .Append(Loc.F("$dgp_now", num)) .Append("\n") .Append(text3); } return Sb.ToString().TrimEnd(new char[1] { '\n' }); } public static string EnergyTooltip(Player player) { SE_Demigod val = NdBridge.StatusOf(player); Sb.Clear(); Sb.Append(Loc.F("$dgp_vitals_energy_now", ((Object)(object)val != (Object)null) ? val.Energy : 0, NdBridge.MaxEnergy(player))).Append("\n\n"); float num = NdBridge.EnergyRegenPeriod(player); Sb.Append((num > 0f) ? Loc.F("$dgp_vitals_regen", NumberFormat.Digits(num)) : Loc.T("$dgp_vitals_regen_off")).Append("\n\n"); Sb.Append(Loc.F("$dgp_vitals_energy_from_level_plain", NdBridge.EnergyFromLevel(NdBridge.Level(player)))); return Sb.ToString(); } public static string XpTooltip(Player player) { NdBridge.RawSkill(player, out var level, out var accumulator); float num = NdBridge.Level(player); Sb.Clear(); Sb.Append("') .Append(Loc.F("$dgp_level", Mathf.FloorToInt(num))) .Append("\n"); Sb.Append((level >= 100f) ? Loc.T("$dgp_xp_max") : Loc.F("$dgp_xp", Mathf.FloorToInt(accumulator), Mathf.CeilToInt(XpMath.Requirement(level)))).Append("\n\n"); Sb.Append(DemigodPanelView.CapLine(player, num, level, out var _)); return Sb.ToString(); } private static void AppendAbilityNote(DemigodAbility a) { AbilityWolf val = (AbilityWolf)(object)((a is AbilityWolf) ? a : null); if (val != null) { int num = Mathf.RoundToInt((val.GetDamageFactor(false) - 1f) * 100f); if (num > 0) { Sb.Append("') .Append(Loc.F("$dgp_wolf_fed", num)) .Append("\n"); } } } public static string TraitBody(DemigodAttribute t, int level, bool live, string godKey, NumberSheet sheet) { Sb.Clear(); string text = Ours(t, godKey, string.Empty, sheet); Sb.Append(Header(Loc.T("$dgp_description"))).Append('\n'); Sb.Append(text ?? AbilityView.Safe((Func)t.GetTooltip) ?? string.Empty).Append('\n'); if (live && text == null) { string text2 = AbilityView.Safe((Func)t.GetStatusTooltip); if (text2 != null) { Sb.Append('\n').Append(Header(Loc.F("$dgp_now", level))).Append('\n') .Append(text2) .Append('\n'); } } return Sb.ToString(); } public static string GodBody(GodInfo god, NumberSheet sheet, bool otherGod) { long start = Perf.Begin(); long mem = Perf.BeginMem(); string result = GodBodyInner(god, sheet, otherGod); Perf.End(Perf.Scope.CardRender, start, mem); return result; } private static string GodBodyInner(GodInfo god, NumberSheet sheet, bool otherGod) { string key = god.Key; sheet.Begin(); StringBuilder stringBuilder = new StringBuilder(4096); string text = Lore(key, "role"); if (text != null) { stringBuilder.Append("").Append(text).Append("\n\n"); } AppendPlaystyle(stringBuilder, key, sheet); string text2 = Lore(key, "armor_kind"); string marker = UiFonts.Glyph('•', "-"); if (text2 != null) { Section(stringBuilder, "$dgp_element", sheet.Render(Lore(key, "element") ?? string.Empty), null, null); Section(stringBuilder, "$dgp_weapons", sheet.Render(Lore(key, "weapons") ?? string.Empty), marker, MutedHex); string first = "" + Loc.T("$dgp_armor_kind_" + text2) + ""; Section(stringBuilder, "$dgp_armor", sheet.Render(Lore(key, "armor") ?? string.Empty), marker, MutedHex, first); Section(stringBuilder, "$dgp_strengths", sheet.Render(Lore(key, "strengths") ?? string.Empty), "+", StrengthHex); Section(stringBuilder, "$dgp_weaknesses", sheet.Render(Lore(key, "weaknesses") ?? string.Empty), UiFonts.Glyph('–', "-"), WeaknessHex); Section(stringBuilder, "$dgp_level_section", AppendCap(sheet.Render(Lore(key, "level") ?? string.Empty), sheet), marker, IceHex); } else { string[] array = new string[5] { "element", "weapons", "armor", "strengths", "weaknesses" }; foreach (string text3 in array) { string text4 = Lore(key, text3); if (text4 != null) { stringBuilder.Append(Header(Loc.T("$dgp_" + text3))).Append('\n').Append(sheet.Render(text4)) .Append("\n\n"); } } } AppendPowers(stringBuilder, god, sheet); StringBuilder stringBuilder2 = new StringBuilder(256); if (otherGod) { stringBuilder2.Append("') .Append(Loc.F("$dgp_shown_at_level", (int)sheet.Context.Level, god.DisplayName)) .Append("\n"); } if (sheet.AnyScaling) { stringBuilder2.Append("").Append(Loc.F("$dgp_legend_scaling", "" + UiFonts.Up + "")).Append("\n"); } if (stringBuilder2.Length > 0) { stringBuilder2.Append('\n'); } return stringBuilder2.Append((object?)stringBuilder).ToString(); } private static string AppendCap(string levelLines, NumberSheet sheet) { if ((Object)(object)sheet.Player == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return levelLines; } float num = (float)sheet.Context.Level; bool capped; string text = DemigodPanelView.CapLine(sheet.Player, num, num, out capped); if (string.IsNullOrEmpty(text)) { return levelLines; } if (capped) { text = "" + text + ""; } if (levelLines.Length <= 0) { return text; } return levelLines + "\n" + text; } private static void Section(StringBuilder sb, string headerToken, string lines, string marker, string markerHex, string first = null) { if (string.IsNullOrEmpty(lines) && first == null) { return; } sb.Append(Header(Loc.T(headerToken))).Append('\n'); if (first != null) { sb.Append(first).Append('\n'); } string[] array = lines.Split(new char[1] { '\n' }); foreach (string text in array) { if (text.Length != 0) { if (marker == null) { sb.Append(text).Append('\n'); } else { sb.Append("") .Append(marker) .Append("") .Append(text) .Append("\n"); } } } sb.Append('\n'); } private static void AppendPowers(StringBuilder body, GodInfo god, NumberSheet sheet) { List list = AbilityView.Sorted(god.Defaults.DefaultAbilities); if (list.Count > 0) { body.Append(Header(Loc.T("$dgp_powers"))).Append('\n'); foreach (DemigodAbility item in list) { body.Append("") .Append(item.DisplayName) .Append(" (") .Append(AbilityView.KeyLabelOf(item)) .Append(")\n"); body.Append(Ours(item, god.Key, string.Empty, sheet) ?? AbilityView.Safe((Func)item.GetTooltip) ?? string.Empty).Append("\n\n"); } } List defaultAttributes = god.Defaults.DefaultAttributes; if (defaultAttributes != null && defaultAttributes.Count > 0) { body.Append(Header(Loc.T("$dgp_traits"))).Append('\n'); foreach (DemigodAttribute item2 in defaultAttributes) { body.Append("") .Append(item2.DisplayName) .Append("\n"); body.Append(Ours(item2, god.Key, string.Empty, sheet) ?? AbilityView.Safe((Func)item2.GetTooltip) ?? string.Empty).Append("\n\n"); } } string text = InfusionHint(god.Key); if (text != null) { body.Append(Header(Loc.T("$dgp_infusion_clue"))).Append('\n').Append(text) .Append('\n'); } } public static string InfusionHint(string key) { if (string.IsNullOrEmpty(key)) { return null; } string text = key.ToLowerInvariant(); if (Plugin.InfusionSpoilers != null && Plugin.InfusionSpoilers.Value) { string text2 = InfusionRecipe(text); if (text2 != null) { return text2; } } string text3 = Lore(text, "infusion_riddle") ?? NdBridge.NdText("$demigod_" + text + "_overview_ext")?.Replace("§ ", string.Empty).Trim(); if (text3 == null) { return null; } return "" + text3 + ""; } private static string InfusionRecipe(string god) { if (god == "kvasir") { string text = NdBridge.KvasirInfusionEnemy(); if (text == null) { return null; } return Loc.F("$dgp_infuse_kill", "" + text + ""); } if (!NdBridge.TryInfusionRecipe(Infusions.ItemOf(god), out string item, out List<(string, int)> ingredients, out string station, out int level)) { return null; } StringBuilder stringBuilder = new StringBuilder(256); stringBuilder.Append("") .Append(item) .Append("\n"); foreach (var (value, value2) in ingredients) { stringBuilder.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(value2) .Append(" × ") .Append(value) .Append('\n'); } if (station != null) { stringBuilder.Append("') .Append((level > 1) ? Loc.F("$dgp_infuse_station", station, level) : Loc.F("$dgp_infuse_station_any", station)) .Append("\n"); } stringBuilder.Append("') .Append(Loc.T("$dgp_infuse_eat")) .Append(""); return stringBuilder.ToString(); } private static void AppendPlaystyle(StringBuilder body, string key, NumberSheet sheet) { string text = Lore(key, "playstyle"); if (text != null) { body.Append(Header(Loc.T("$dgp_playstyle"))).Append('\n'); string text2 = Lore(key, "playstyle_role"); if (text2 != null) { body.Append("") .Append(text2) .Append("\n"); } string text3 = Lore(key, "playstyle_fit"); if (text3 != null) { body.Append("') .Append(text3) .Append("\n"); } body.Append(sheet.Render(text)).Append("\n\n"); } } } internal static class GearNotes { private static readonly string Green = UiKit.Hex(new Color(0.62f, 0.86f, 0.5f)); private static readonly string Amber = "ff9f5a"; private static readonly string Grey = NumberStyle.Muted; private static readonly string Ice = UiKit.Hex(UiKit.Ice); private static readonly List Names = new List(3); private static readonly List Kinds = new List(4); private static bool _countWarned; private static int HeavyPieces(Player player, List names) { names.Clear(); AddIfHeavy(((Humanoid)player).m_helmetItem, names); AddIfHeavy(((Humanoid)player).m_chestItem, names); AddIfHeavy(((Humanoid)player).m_legItem, names); int count = names.Count; int num = Helper.PlayerWearingHeavyArmorCount(player); if (count != num && !_countWarned) { _countWarned = true; Plugin.Log.LogWarning((object)$"Heavy armor count differs from Norse Demigods' ({count} vs {num}); the armor note may name the wrong pieces."); } return num; } private static void AddIfHeavy(ItemData item, List names) { if (item != null && GearIds.IsHeavy(item.m_shared.m_movementModifier)) { names.Add(Loc.T(item.m_shared.m_name)); } } public static void Armor(StringBuilder sb, Player player, string godKey, string godName, NumberSheet sheet) { GodGear godGear = GearRules.For(godKey); if (godGear == null) { return; } sb.Append(""); if (godGear.Armor.Length == 0) { Line(sb, Green, Mark('✔', "+"), Loc.F("$dgp_gear_armor_free", godName), headline: true); sb.Append("\n"); return; } SEMan sEMan = ((Character)player).GetSEMan(); ArmorState state = new ArmorState { Heavy = HeavyPieces(player, Names), FenrisSet = sEMan.HaveStatusEffect(Cache.s_statusEffectFenringArmor), BerserkerSet = sEMan.HaveStatusEffect(Cache.s_statusEffectBerserkerArmor) }; List list = GearRules.Armor(godGear, in state); bool flag = false; bool flag2 = false; bool flag3 = false; foreach (ArmorOutcome item in list) { if (!item.Active) { switch (item.Rule.Need) { case ArmorNeed.NoHeavy: flag = true; break; case ArmorNeed.TwoHeavy: flag = (flag3 = true); break; default: flag2 = true; break; } } } bool flag4 = false; foreach (ArmorOutcome item2 in list) { flag4 |= item2.Rule.Need == ArmorNeed.NoHeavy || item2.Rule.Need == ArmorNeed.TwoHeavy; } if (flag4) { Line(sb, flag ? Amber : Green, flag ? Mark('✖', "x") : Mark('✔', "+"), Loc.T(flag ? "$dgp_gear_armor_off" : "$dgp_gear_armor_on"), headline: true); } foreach (ArmorOutcome item3 in list) { string text = sheet.Render(Loc.T(item3.Rule.Line)); if (text.Length != 0) { bool flag5 = item3.Rule.Need == ArmorNeed.SetFenris || item3.Rule.Need == ArmorNeed.SetBerserker; if (item3.Active) { Line(sb, Green, Mark('✔', "+"), text, headline: false); } else if (flag5) { Line(sb, Grey, Mark('•', "-"), text, headline: false); } else { Line(sb, Amber, Mark('✖', "x"), text, headline: false); } } } if (flag && !flag3 && Names.Count > 0) { Line(sb, Ice, Mark('→', ">"), Loc.F("$dgp_gear_swap_heavy", string.Join(", ", Names)), headline: false); } else if (flag3) { int num = 2 - state.Heavy; Line(sb, Ice, Mark('→', ">"), (num == 1) ? Loc.T("$dgp_gear_more_heavy_one") : Loc.F("$dgp_gear_more_heavy", num), headline: false); } if (flag2 && !state.FenrisSet && !state.BerserkerSet) { Line(sb, Ice, Mark('→', ">"), Loc.T("$dgp_gear_set"), headline: false); } sb.Append("\n"); } public static void Weapon(StringBuilder sb, Player player, string godKey, string godName, NumberSheet sheet) { GodGear godGear = GearRules.For(godKey); if (godGear == null) { return; } WeaponProbe probe = Probe(player); bool noSpeed = ((Character)player).GetSEMan().HaveStatusEffect(Cache.s_statusEffectElectricWings); WeaponVerdict weaponVerdict = GearRules.Weapon(godGear, in probe, noSpeed); sb.Append(""); if (weaponVerdict.Favoured) { Line(sb, Green, Mark('✔', "+"), Loc.F("$dgp_gear_weapon_best", godName), headline: true); } else if (weaponVerdict.Gets.Count > 0) { Line(sb, Amber, Mark('◆', "*"), Loc.F("$dgp_gear_weapon_part", godName), headline: true); } else if (probe.Bare) { Line(sb, Grey, Mark('•', "-"), Loc.T("$dgp_gear_bare_none"), headline: true); } else { Line(sb, Amber, Mark('✖', "x"), Loc.F("$dgp_gear_weapon_none", godName), headline: true); } foreach (WeaponRule get in weaponVerdict.Gets) { Rendered(sb, Green, Mark('✔', "+"), sheet, get); } foreach (WeaponRule trade in weaponVerdict.Trades) { Rendered(sb, Amber, Mark('•', "-"), sheet, trade); } if (!weaponVerdict.Favoured && weaponVerdict.Missing.Count > 0) { Line(sb, Grey, string.Empty, Loc.T("$dgp_gear_better"), headline: false); Kinds.Clear(); foreach (WeaponRule item2 in weaponVerdict.Missing) { Rendered(sb, Grey, Mark('•', "-"), sheet, item2); string item = Loc.T(item2.Kind); if (!Kinds.Contains(item)) { Kinds.Add(item); } } Line(sb, Ice, Mark('→', ">"), Loc.F("$dgp_gear_try", Join(Kinds)), headline: false); } sb.Append("\n"); } private static WeaponProbe Probe(Player player) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected I4, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected I4, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); ItemData val = (((Object)(object)((Humanoid)player).m_unarmedWeapon != (Object)null) ? ((Humanoid)player).m_unarmedWeapon.m_itemData : null); if (currentWeapon == null) { return new WeaponProbe { Skill = 11, Bare = true, HandsFull = (((Humanoid)player).m_leftItem != null) }; } SharedData shared = currentWeapon.m_shared; WeaponProbe result = new WeaponProbe { Skill = (int)shared.m_skillType, ItemType = (int)shared.m_itemType, Himminafl = (shared.m_name == "$item_atgeir_himminafl"), Bare = (currentWeapon == val), HandsFull = (((Humanoid)player).m_leftItem != null) }; if (result.Skill == 9) { DamageTypes damages = shared.m_damages; float totalBlockableDamage = ((DamageTypes)(ref damages)).GetTotalBlockableDamage(); result.FrostStaff = totalBlockableDamage > 0f && damages.m_frost >= totalBlockableDamage * 0.75f; } return result; } private static void Rendered(StringBuilder sb, string colour, string glyph, NumberSheet sheet, WeaponRule rule) { string text = sheet.Render(Loc.T(rule.Line)); if (text.Length > 0) { Line(sb, colour, glyph, text, headline: false); } } private static string Mark(char c, string fallback) { return UiFonts.Glyph(c, fallback); } private static void Line(StringBuilder sb, string colour, string glyph, string text, bool headline) { if (glyph.Length > 0) { sb.Append("') .Append(glyph) .Append(" "); } else if (!headline) { sb.Append("') .Append(text) .Append("\n"); return; } if (headline) { sb.Append("") .Append(text) .Append(""); } else { sb.Append(text); } sb.Append('\n'); } private static string Join(List parts) { if (parts.Count == 1) { return parts[0]; } string text = Loc.T("$dgp_gear_or"); return string.Join(", ", parts.GetRange(0, parts.Count - 1)) + text + parts[parts.Count - 1]; } } internal sealed class HoverHold { private const float Grace = 0.15f; private float _clearAt = -1f; public void Enter() { _clearAt = -1f; } public void Exit() { _clearAt = Time.unscaledTime + 0.15f; } public bool Expired() { if (_clearAt < 0f || Time.unscaledTime < _clearAt) { return false; } _clearAt = -1f; return true; } } internal sealed class HudBar { private const float Inset = 2f; private const float FrameThinning = 3f; private const float SlowSpeed = 0.6f; private const int MaxSegments = 30; private static readonly Color Back = new Color(0.07f, 0.06f, 0.05f, 0.88f); private static readonly Color Mark = new Color(0f, 0f, 0f, 0.55f); private RectTransform _area; private RectTransform _fast; private RectTransform _slow; private Image _fastImage; private Image _slowImage; private TextMeshProUGUI _text; private readonly List _marks = new List(); private int _segments; private float _value = -1f; private float _slowValue; private string _shown; public RectTransform Root { get; private set; } public bool Animating { get { if (_value >= 0f) { return _slowValue > _value + 0.0005f; } return false; } } public static HudBar Create(Transform parent, string name, float fillWidth, float height = 18f, float fontSize = 12f) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) HudBar hudBar = new HudBar(); GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); hudBar.Root = (RectTransform)val.transform; ((Transform)hudBar.Root).SetParent(parent, false); Image obj = UiKit.Image((Transform)(object)hudBar.Root, "Frame", UiKit.Vanilla("item_background") ?? UiKit.White, Back, sliced: true); obj.pixelsPerUnitMultiplier = 3f; UiKit.Fill(((Graphic)obj).rectTransform); hudBar._area = UiKit.Box((Transform)(object)hudBar.Root, "Fill Area", 0f, 0f, 10f, 10f); UiKit.Fill(hudBar._area, 2f); hudBar._slowImage = UiKit.Image((Transform)(object)hudBar._area, "Trail", UiKit.White, Color.white); hudBar._slow = ((Graphic)hudBar._slowImage).rectTransform; hudBar._fastImage = UiKit.Image((Transform)(object)hudBar._area, "Fill", UiKit.White, Color.white); hudBar._fast = ((Graphic)hudBar._fastImage).rectTransform; Anchor(hudBar._slow, 0f); Anchor(hudBar._fast, 0f); hudBar._text = UiKit.Tmp((Transform)(object)hudBar.Root, "Text", string.Empty, fontSize, Color.white, (TextAlignmentOptions)514, 0f, 0f, 10f, 10f); UiKit.Fill(((TMP_Text)hudBar._text).rectTransform); hudBar.Root.sizeDelta = new Vector2(fillWidth + 4f, height); hudBar.SetColor(new Color(0.6f, 0.85f, 1f)); return hudBar; } public static float FillWidthFor(float outerWidth) { return Mathf.Max(10f, outerWidth - 4f); } public void SetWidth(float fillWidth) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Root.sizeDelta = new Vector2(fillWidth + 4f, Root.sizeDelta.y); } public void SetColor(Color color) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (((Graphic)_fastImage).color != color) { ((Graphic)_fastImage).color = color; Color color2 = Color.Lerp(color, Color.white, 0.55f); color2.a = 0.75f; ((Graphic)_slowImage).color = color2; } } public void SetSegments(int count) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) count = ((count <= 30) ? count : 0); if (count == _segments) { return; } _segments = count; int num = Mathf.Max(0, count - 1); while (_marks.Count < num) { Image item = UiKit.Image((Transform)(object)_area, "Mark", UiKit.White, Mark); _marks.Add(item); } for (int i = 0; i < _marks.Count; i++) { bool flag = i < num; Image val = _marks[i]; if (((Component)val).gameObject.activeSelf != flag) { ((Component)val).gameObject.SetActive(flag); } if (flag) { float num2 = ((float)i + 1f) / (float)count; RectTransform rectTransform = ((Graphic)val).rectTransform; rectTransform.anchorMin = new Vector2(num2, 0f); rectTransform.anchorMax = new Vector2(num2, 1f); rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.sizeDelta = new Vector2(1.5f, 0f); rectTransform.anchoredPosition = Vector2.zero; ((Transform)rectTransform).SetAsLastSibling(); } } } public void Set(float fraction, string text, bool trail = true) { fraction = Mathf.Clamp01(fraction); if (fraction != _value) { bool num = trail && _value >= 0f && fraction < _value; _value = fraction; Anchor(_fast, fraction); if (!num) { _slowValue = fraction; Anchor(_slow, fraction); } } if (text != _shown) { _shown = text; ((TMP_Text)_text).text = text; } } public void Animate(float dt) { _slowValue = Mathf.Max(_value, _slowValue - 0.6f * dt); Anchor(_slow, _slowValue); } public void SetActive(bool active) { if ((Object)(object)Root != (Object)null && ((Component)Root).gameObject.activeSelf != active) { ((Component)Root).gameObject.SetActive(active); } } private static void Anchor(RectTransform fill, float fraction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) fill.anchorMin = Vector2.zero; fill.anchorMax = new Vector2(fraction, 1f); fill.offsetMin = Vector2.zero; fill.offsetMax = Vector2.zero; } } internal static class ElementColors { private static readonly Dictionary ByGod = new Dictionary { { "Thor", new Color(0.45f, 0.75f, 1f) }, { "Fenrir", new Color(0.6f, 0.88f, 1f) }, { "Ullr", new Color(0.6f, 0.88f, 1f) }, { "Surtr", new Color(1f, 0.5f, 0.15f) }, { "Brokkr", new Color(1f, 0.62f, 0.25f) }, { "Eir", new Color(1f, 0.85f, 0.4f) }, { "Freyja", new Color(0.5f, 0.9f, 0.35f) }, { "Hel", new Color(0.62f, 0.85f, 0.3f) }, { "Kvasir", new Color(0.9f, 0.2f, 0.25f) }, { "Njord", new Color(0.25f, 0.8f, 0.8f) }, { "Hraesvelgr", new Color(0.85f, 0.92f, 1f) }, { "Saiyan", new Color(0.75f, 0.5f, 1f) } }; public static readonly Color Xp = new Color(0.95f, 0.72f, 0.25f); public static readonly Color XpCapped = new Color(0.95f, 0.42f, 0.25f); public static Color Of(string god) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (god == null || !ByGod.TryGetValue(god, out var value)) { return new Color(0.6f, 0.85f, 1f); } return value; } } internal static class XpReadout { private static int _capLevel = -1; private static int _capEffective = -1; private static int _capTrophies = -1; private static int _capConfig = -1; private static bool _capped; private static Player _capPlayer; public static void Read(Player player, out int level, out float fraction, out bool capped, out bool atMax) { NdBridge.RawSkill(player, out var level2, out var accumulator); float num = NdBridge.Level(player); level = Mathf.FloorToInt(num); atMax = level2 >= 100f; fraction = (atMax ? 1f : XpMath.Percent(level2, accumulator)); int num2 = (((Object)(object)player != (Object)null) ? player.m_trophies.Count : 0); if ((int)level2 != _capLevel || level != _capEffective || num2 != _capTrophies || NdEvents.ConfigVersion != _capConfig || player != _capPlayer) { _capPlayer = player; _capLevel = (int)level2; _capEffective = level; _capTrophies = num2; _capConfig = NdEvents.ConfigVersion; _capped = !atMax && (Object)(object)player != (Object)null && NdBridge.Cap(player, num).Capped; } capped = _capped; } } internal sealed class LayoutOverlay { private enum Part { Bar, Energy, Pets, Companions, Meters, Count } private sealed class Proxy { public Part Part; public RectTransform Rt; public RectTransform Target; public RectTransform Measure; public Camera Cam; } private sealed class DragHandle : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler { public LayoutOverlay Owner; public Proxy Proxy; public void OnBeginDrag(PointerEventData e) { if (!Dragging.Ready) { return; } try { Owner.BeginDrag(Proxy, e); } catch (Exception ex) { Dragging.Fail(ex); } } public void OnDrag(PointerEventData e) { if (!Dragging.Ready) { return; } try { Owner.Drag(Proxy, e); } catch (Exception ex) { Dragging.Fail(ex); } } public void OnEndDrag(PointerEventData e) { try { long start = Perf.Begin(); long mem = Perf.BeginMem(); Owner.EndDrag(Proxy); Perf.End(Perf.Scope.ConfigWrite, start, mem); } catch (Exception ex) { Dragging.Fail(ex); } } } private sealed class SlotTip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public LayoutOverlay Owner; public int Index; public RectTransform Rect; public void OnPointerEnter(PointerEventData e) { if (!Tooltips.Ready) { return; } try { long start = Perf.Begin(); long mem = Perf.BeginMem(); Owner.ShowCard(this); Perf.End(Perf.Scope.Tooltip, start, mem); } catch (Exception ex) { Tooltips.Fail(ex); Hide(); } } public void OnPointerExit(PointerEventData e) { Hide(); } private void OnDisable() { if (Owner != null) { Hide(); } } private void Hide() { try { Owner.HideCard(this); } catch (Exception ex) { Tooltips.Fail(ex); } } } private const int EnergyTip = -1; private const int XpTip = -2; private const float ResyncSeconds = 1f; private const float ScreenMargin = 24f; private static readonly Color Invisible = new Color(0f, 0f, 0f, 0f); private readonly AbilityBar _bar; private readonly CompanionBars _companions; private readonly MeterBars _meters; private readonly Proxy[] _proxies = new Proxy[5]; private SlotTip _energyTip; private SlotTip _xpTip; private readonly List _tips = new List(); private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; private RectTransform _root; private GameObject _tooltipPrefab; private GameObject _card; private RectTransform _cardPanel; private TMP_Text _cardTopic; private TMP_Text _cardText; private SlotTip _hovered; private bool _built; private bool _open; private float _resync; private int _stamp; private int _tipsVersion = -1; private Proxy _drag; private Vector2 _pressScreen; private Vector2 _startCenter; private Vector2 _startValue; private Vector2 _startAnchored; private Vector2 _startProxy; private Vector2 _delta; private static readonly Guard Dragging = new Guard("HUD dragging", shared: true); private static readonly Guard Tooltips = new Guard("Ability bar tooltips", shared: true); public LayoutOverlay(AbilityBar bar, MeterBars meters, CompanionBars companions) { _bar = bar; _meters = meters; _companions = companions; } public void Update(bool allowed) { bool flag = allowed && (InventoryGui.IsVisible() || Menu.IsVisible()); if (flag != _open) { SetOpen(flag); } if (_open && _drag == null) { long start = Perf.Begin(); long mem = Perf.BeginMem(); _resync -= Time.unscaledDeltaTime; int num = Stamp(); if (num != _stamp || _resync <= 0f) { _stamp = num; _resync = 1f; Sync(); } Perf.End(Perf.Scope.Overlay, start, mem); } } public void LateUpdate() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (_drag == null) { return; } if ((Object)(object)_drag.Target == (Object)null) { Commit(); return; } long start = Perf.Begin(); long mem = Perf.BeginMem(); Vector2 val = _startAnchored + _delta; if (IsOurs(_drag.Part)) { val = UiKit.OnScreen(_drag.Target, val); } PlaceTarget(_drag.Part, val); Perf.End(Perf.Scope.OverlayDrag, start, mem); } public void Close() { if (_open) { SetOpen(open: false); } } public void Destroy() { Close(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; _built = false; _card = null; _hovered = null; _energyTip = null; _xpTip = null; _tips.Clear(); _tipsVersion = -1; } private void SetOpen(bool open) { if (open) { if (!_built) { Build(); } if (!((Object)(object)_root == (Object)null)) { _open = true; _stamp = 0; _resync = 0f; ((Transform)_root).SetAsLastSibling(); ((Component)_root).gameObject.SetActive(true); } } else { if (_drag != null) { Commit(); } _open = false; HideCard(); if ((Object)(object)_root != (Object)null) { ((Component)_root).gameObject.SetActive(false); } } } private void Build() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null)) { _built = true; GameObject val = new GameObject("DemigodLayoutOverlay", new Type[3] { typeof(RectTransform), typeof(Canvas), typeof(GraphicRaycaster) }); _root = (RectTransform)val.transform; ((Transform)_root).SetParent(GUIManager.CustomGUIFront.transform, false); UiKit.Fill(_root); val.SetActive(false); _proxies[0] = MakeProxy(Part.Bar); if (NdMeters.EnergyPosition != null) { _proxies[1] = MakeProxy(Part.Energy); } if (NdMeters.PetPosition != null) { _proxies[2] = MakeProxy(Part.Pets); } _proxies[3] = MakeProxy(Part.Companions); _proxies[4] = MakeProxy(Part.Meters); } } private Proxy MakeProxy(Part part) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Move" + part, new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)_root, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = Vector2.zero; HitArea(val.GetComponent()); Proxy proxy = new Proxy { Part = part, Rt = val2 }; DragHandle dragHandle = val.AddComponent(); dragHandle.Owner = this; dragHandle.Proxy = proxy; val.SetActive(false); return proxy; } private static void HitArea(Image img) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) img.sprite = UiKit.White; ((Graphic)img).color = Invisible; ((Graphic)img).raycastTarget = true; ((Graphic)img).canvasRenderer.cullTransparentMesh = true; } private int Stamp() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) int num = (_bar.Version * 31 + (((Object)(object)_bar.Root != (Object)null) ? 1 : 0)) * 31 + (NdMeters.OursReplaceNd ? 1 : 0); RectTransform root = _companions.Root; int num2 = (((((num * 31 + (((Object)(object)root != (Object)null) ? ((object)root.sizeDelta/*cast due to .constrained prefix*/).GetHashCode() : 0)) * 31 + ((object)Plugin.CompanionsOffset.Value/*cast due to .constrained prefix*/).GetHashCode()) * 31 + Plugin.CompanionsScale.Value.GetHashCode()) * 31 + ((object)Plugin.MetersOffset.Value/*cast due to .constrained prefix*/).GetHashCode()) * 31 + Plugin.MetersScale.Value.GetHashCode()) * 31 + (((Object)(object)_meters.Root != (Object)null) ? 1 : 0) + (((Object)(object)_meters.EnergyRect != (Object)null) ? 2 : 0) + (((Object)(object)_meters.XpRect != (Object)null) ? 4 : 0); RectTransform root2 = _meters.Root; int num3 = ((num2 * 31 + (((Object)(object)root2 != (Object)null) ? ((object)root2.sizeDelta/*cast due to .constrained prefix*/).GetHashCode() : 0)) * 31 + ((object)Plugin.BarOffset.Value/*cast due to .constrained prefix*/).GetHashCode()) * 31 + Plugin.BarScale.Value.GetHashCode(); RectTransform energy = NdMeters.Energy; int num4 = num3 * 31 + (((Object)(object)energy != (Object)null) ? ((Object)energy).GetInstanceID() : 0); RectTransform pet = NdMeters.Pet; return ((((num4 * 31 + (((Object)(object)pet != (Object)null) ? ((Object)pet).GetInstanceID() : 0)) * 31 + ((NdMeters.EnergyPosition != null) ? ((object)NdMeters.EnergyPosition.Value/*cast due to .constrained prefix*/).GetHashCode() : 0)) * 31 + ((NdMeters.PetPosition != null) ? ((object)NdMeters.PetPosition.Value/*cast due to .constrained prefix*/).GetHashCode() : 0)) * 31 + Screen.width) * 31 + Screen.height; } private void Sync() { bool oursReplaceNd = NdMeters.OursReplaceNd; SyncProxy(_proxies[0], _bar.Root, _bar.Bounds); SyncProxy(_proxies[1], oursReplaceNd ? null : NdMeters.Energy); SyncProxy(_proxies[2], oursReplaceNd ? null : NdMeters.Pet); SyncProxy(_proxies[3], oursReplaceNd ? _companions.Root : null); SyncProxy(_proxies[4], oursReplaceNd ? _meters.Root : null); SyncTips(); } private void SyncProxy(Proxy proxy, RectTransform target, RectTransform measure = null) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (proxy != null) { if ((Object)(object)target != (Object)(object)proxy.Target) { proxy.Target = target; proxy.Cam = CameraOf(target); } proxy.Measure = (((Object)(object)target != (Object)null) ? (measure ?? target) : null); Vector2 min; Vector2 max; bool flag = (Object)(object)target != (Object)null && ScreenRect(proxy.Measure, proxy.Cam, out min, out max) && OnScreen(min, max) && Cover(proxy.Rt, _root, min, max); if (((Component)proxy.Rt).gameObject.activeSelf != flag) { ((Component)proxy.Rt).gameObject.SetActive(flag); } } } private void SyncTips() { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) Proxy proxy = _proxies[0]; if (_tipsVersion != _bar.Version) { RebuildTips(proxy); } Proxy proxy2 = _proxies[4]; if (((Component)proxy2.Rt).gameObject.activeSelf) { CoverInfo(_energyTip, _meters.EnergyRect, proxy2); CoverInfo(_xpTip, _meters.XpRect, proxy2); } if (!((Component)proxy.Rt).gameObject.activeSelf) { return; } int num = Mathf.Min(_bar.SlotCount, _tips.Count); for (int i = 0; i < num; i++) { SlotTip slotTip = _tips[i]; Vector2 min; Vector2 max; bool flag = ScreenRect(_bar.SlotRect(i), proxy.Cam, out min, out max) && Cover(slotTip.Rect, proxy.Rt, min, max); if (((Component)slotTip).gameObject.activeSelf != flag) { ((Component)slotTip).gameObject.SetActive(flag); } } } public void Warm() { if (!_built) { Build(); } if ((Object)(object)_root != (Object)null) { EnsureCard(); } } private void EnsureCard() { if ((Object)(object)_tooltipPrefab == (Object)null && (Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_playerGrid != (Object)null && (Object)(object)InventoryGui.instance.m_playerGrid.m_elementPrefab != (Object)null) { UITooltip componentInChildren = InventoryGui.instance.m_playerGrid.m_elementPrefab.GetComponentInChildren(true); _tooltipPrefab = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.m_tooltipPrefab : null); } if ((Object)(object)_tooltipPrefab != (Object)null && (Object)(object)_card == (Object)null) { BuildCard(); } } private void RebuildTips(Proxy barProxy) { EnsureCard(); if ((Object)(object)_tooltipPrefab != (Object)null) { _tipsVersion = _bar.Version; for (int i = _bar.SlotCount; i < _tips.Count; i++) { ((Component)_tips[i]).gameObject.SetActive(false); } while (_tips.Count < _bar.SlotCount) { _tips.Add(MakeTip(barProxy.Rt, _tips.Count)); } Proxy proxy = _proxies[4]; if (_energyTip == null) { _energyTip = MakeTip(proxy.Rt, -1); } if (_xpTip == null) { _xpTip = MakeTip(proxy.Rt, -2); } } } private void CoverInfo(SlotTip tip, RectTransform target, Proxy owner) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)tip == (Object)null)) { Vector2 min; Vector2 max; bool flag = (Object)(object)target != (Object)null && ScreenRect(target, owner.Cam, out min, out max) && Cover(tip.Rect, owner.Rt, min, max); if (((Component)tip).gameObject.activeSelf != flag) { ((Component)tip).gameObject.SetActive(flag); } } } private SlotTip MakeTip(RectTransform parent, int index) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Tip" + index, new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)parent, false); Vector2 anchorMin = (val2.anchorMax = Vector2.zero); val2.anchorMin = anchorMin; val2.pivot = Vector2.zero; HitArea(val.GetComponent()); SlotTip slotTip = val.AddComponent(); slotTip.Owner = this; slotTip.Index = index; slotTip.Rect = val2; return slotTip; } private void BuildCard() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown _card = Object.Instantiate(_tooltipPrefab, (Transform)(object)_root); ((Object)_card).name = "DemigodSlotTooltip"; _card.SetActive(false); CanvasGroup val = _card.GetComponent(); if ((Object)(object)val == (Object)null) { val = _card.AddComponent(); } val.blocksRaycasts = false; val.interactable = false; _cardPanel = (RectTransform)((_card.transform.childCount > 0) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)_cardPanel == (Object)null) { _cardPanel = (RectTransform)_card.transform; } _cardTopic = TextIn(_card.transform, "Topic"); _cardText = TextIn(_card.transform, "Text"); if ((Object)(object)_cardText == (Object)null) { Plugin.Log.LogWarning((object)"The vanilla tooltip prefab has no Text element; ability bar tooltips are off."); Object.Destroy((Object)(object)_card); _card = null; } } private static TMP_Text TextIn(Transform root, string name) { Transform val = Utils.FindChild(root, name, (IterativeSearchType)0); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent(); } private void ShowCard(SlotTip tip) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_card == (Object)null || _drag != null) { return; } Player localPlayer = Player.m_localPlayer; string text; string text2; if (tip.Index == -1) { text = Loc.T("$dgp_vitals_energy"); text2 = Texts.EnergyTooltip(localPlayer); } else if (tip.Index == -2) { text = Loc.T("$dgp_tip_xp"); text2 = Texts.XpTooltip(localPlayer); } else { DemigodAbility val = _bar.SlotAbility(tip.Index); if (val == null) { return; } text = val.DisplayName ?? string.Empty; text2 = Texts.AbilityTooltip(val, localPlayer); } _hovered = tip; if ((Object)(object)_cardTopic != (Object)null) { _cardTopic.text = text; } _cardText.text = NumberStyle.Tint(text2); _card.transform.SetAsLastSibling(); _card.SetActive(true); LayoutRebuilder.ForceRebuildLayoutImmediate(_cardPanel); tip.Rect.GetWorldCorners(_corners); Vector3 val2 = (_corners[1] + _corners[2]) * 0.5f + Vector3.up * (8f * ((Transform)_root).lossyScale.y); _cardPanel.GetWorldCorners(_corners); Transform transform = _card.transform; transform.position += val2 - (_corners[0] + _corners[3]) * 0.5f; _cardPanel.GetWorldCorners(_corners); Vector3 zero = Vector3.zero; if (_corners[0].x < 24f) { zero.x = 24f - _corners[0].x; } else if (_corners[2].x > (float)Screen.width - 24f) { zero.x = (float)Screen.width - 24f - _corners[2].x; } if (_corners[1].y > (float)Screen.height - 24f) { zero.y = (float)Screen.height - 24f - _corners[1].y; } Transform transform2 = _card.transform; transform2.position += zero; } private void HideCard(SlotTip tip = null) { if (!((Object)(object)tip != (Object)null) || !((Object)(object)tip != (Object)(object)_hovered)) { _hovered = null; if ((Object)(object)_card != (Object)null && _card.activeSelf) { _card.SetActive(false); } } } private static Camera CameraOf(RectTransform target) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) Canvas val = (((Object)(object)target != (Object)null) ? ((Component)target).GetComponentInParent() : null); Canvas val2 = (((Object)(object)val != (Object)null) ? val.rootCanvas : null); if (!((Object)(object)val2 == (Object)null) && (int)val2.renderMode != 0) { return val2.worldCamera; } return null; } private bool ScreenRect(RectTransform rt, Camera cam, out Vector2 min, out Vector2 max) { //IL_0015: 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) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) rt.GetWorldCorners(_corners); min = RectTransformUtility.WorldToScreenPoint(cam, _corners[0]); max = RectTransformUtility.WorldToScreenPoint(cam, _corners[2]); if (max.x > min.x) { return max.y > min.y; } return false; } private static bool OnScreen(Vector2 min, Vector2 max) { //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) //IL_0002: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = (min + max) * 0.5f; if (val.x >= 0f && val.y >= 0f && val.x <= (float)Screen.width) { return val.y <= (float)Screen.height; } return false; } private static bool Cover(RectTransform rt, RectTransform parent, Vector2 screenMin, Vector2 screenMax) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); Vector2 val2 = default(Vector2); if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, screenMin, (Camera)null, ref val) || !RectTransformUtility.ScreenPointToLocalPointInRectangle(parent, screenMax, (Camera)null, ref val2)) { return false; } Vector2 val3 = rt.anchoredPosition - val; if (((Vector2)(ref val3)).sqrMagnitude > 0.25f) { rt.anchoredPosition = val; } Vector2 val4 = val2 - val; val3 = rt.sizeDelta - val4; if (((Vector2)(ref val3)).sqrMagnitude > 0.25f) { rt.sizeDelta = val4; } return true; } private void BeginDrag(Proxy proxy, PointerEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((int)e.button != 0 || (Object)(object)proxy.Target == (Object)null || _drag != null || !ScreenRect(proxy.Measure ?? proxy.Target, proxy.Cam, out var min, out var max)) { e.pointerDrag = null; return; } HideCard(); _drag = proxy; _pressScreen = e.pressPosition; _startCenter = (min + max) * 0.5f; _startValue = (IsOurs(proxy.Part) ? Round(proxy.Target.anchoredPosition) : ReadValue(proxy.Part)); _startAnchored = proxy.Target.anchoredPosition; _startProxy = proxy.Rt.anchoredPosition; _delta = Vector2.zero; Drag(proxy, e); } private void Drag(Proxy proxy, PointerEventData e) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0074: Unknown result type (might be due to invalid IL or missing references) if (_drag == proxy && !((Object)(object)proxy.Target == (Object)null)) { Vector2 val = e.position - _pressScreen; if (!IsOurs(proxy.Part)) { val.x = Mathf.Clamp(val.x, 24f - _startCenter.x, (float)Screen.width - 24f - _startCenter.x); val.y = Mathf.Clamp(val.y, 24f - _startCenter.y, (float)Screen.height - 24f - _startCenter.y); } Vector2 to = _pressScreen + val; ref Vector2 delta = ref _delta; Transform parent = ((Transform)proxy.Target).parent; delta = Round(LocalDelta((RectTransform)(object)((parent is RectTransform) ? parent : null), proxy.Cam, _pressScreen, to)); proxy.Rt.anchoredPosition = _startProxy + LocalDelta(_root, null, _pressScreen, to); } } private void EndDrag(Proxy proxy) { if (_drag == proxy) { Commit(); } } private void Commit() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) Proxy drag = _drag; _drag = null; _resync = 0f; if (drag == null || _delta == Vector2.zero) { return; } Vector2 val = Round(_startValue + _delta); if (IsOurs(drag.Part)) { val = Round(UiKit.OnScreen(drag.Target, val)); } switch (drag.Part) { case Part.Bar: if (Plugin.BarOffset.Value != val) { Plugin.BarOffset.Value = val; } break; case Part.Energy: NdMeters.Save(NdMeters.EnergyPosition, val); break; case Part.Pets: NdMeters.Save(NdMeters.PetPosition, val); break; case Part.Companions: if (Plugin.CompanionsOffset.Value != val) { Plugin.CompanionsOffset.Value = val; } break; case Part.Meters: if (Plugin.MetersOffset.Value != val) { Plugin.MetersOffset.Value = val; } break; } } private static Vector2 ReadValue(Part part) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) return (Vector2)(part switch { Part.Bar => Plugin.BarOffset.Value, Part.Energy => Value(NdMeters.EnergyPosition), Part.Companions => Plugin.CompanionsOffset.Value, Part.Meters => Plugin.MetersOffset.Value, _ => Value(NdMeters.PetPosition), }); } private static bool IsOurs(Part part) { if (part != Part.Bar && part != Part.Companions) { return part == Part.Meters; } return true; } private static Vector2 Value(ConfigEntry entry) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) return entry?.Value ?? Vector2.zero; } private void PlaceTarget(Part part, Vector2 anchored) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) switch (part) { case Part.Bar: _bar.Place(anchored); break; case Part.Energy: NdMeters.PlaceEnergy(anchored); break; case Part.Pets: NdMeters.PlacePets(anchored); break; case Part.Companions: _companions.Place(anchored); break; case Part.Meters: _meters.Place(anchored); break; } } private static Vector2 LocalDelta(RectTransform space, Camera cam, Vector2 from, Vector2 to) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); Vector2 val2 = default(Vector2); if ((Object)(object)space == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(space, from, cam, ref val) || !RectTransformUtility.ScreenPointToLocalPointInRectangle(space, to, cam, ref val2)) { return Vector2.zero; } return val2 - val; } private static Vector2 Round(Vector2 v) { //IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references) return new Vector2(Mathf.Round(v.x), Mathf.Round(v.y)); } } internal sealed class MeterBars { private const float Gap = 8f; private const float Height = 22f; private const float TickSeconds = 0.1f; private RectTransform _root; private HudBar _energy; private HudBar _xp; private float _tick; private string _colouredFor; private int _shownEnergy = -1; private int _shownMaxEnergy = -1; private int _shownLevel = -1; private int _shownPercent = -1; private bool _shownCapped; private bool _layoutDirty = true; public RectTransform Root { get { if (!((Object)(object)_root != (Object)null) || !((Component)_root).gameObject.activeInHierarchy) { return null; } return _root; } } public RectTransform EnergyRect { get { if (!((Object)(object)Root != (Object)null) || _energy == null || !((Component)_energy.Root).gameObject.activeSelf) { return null; } return _energy.Root; } } public RectTransform XpRect { get { if (!((Object)(object)Root != (Object)null) || _xp == null || !((Component)_xp.Root).gameObject.activeSelf) { return null; } return _xp.Root; } } public void MarkLayoutDirty() { _layoutDirty = true; } public void ApplyLayout() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { float value = Plugin.MetersScale.Value; ((Transform)_root).localScale = new Vector3(value, value, 1f); _root.anchoredPosition = UiKit.OnScreen(_root, Plugin.MetersOffset.Value); } } public void Place(Vector2 offset) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null && _root.anchoredPosition != offset) { _root.anchoredPosition = offset; } } public void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; _energy = null; _xp = null; _colouredFor = null; _layoutDirty = true; ResetShown(); } public void Update(Player player, Demigod god, float dt) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) bool value = Plugin.ShowEnergyBar.Value; bool value2 = Plugin.ShowXpBar.Value; if (!((Object)(object)player != (Object)null) || !((Object)(object)god != (Object)null) || ((Character)player).IsDead() || !(value || value2) || !NdMeters.OursReplaceNd) { SetVisible(visible: false); } else if (!((Object)(object)_root == (Object)null) || Build()) { SetVisible(visible: true); if (_layoutDirty) { _layoutDirty = false; Layout(value, value2); } if (_colouredFor != god.DemigodName) { _colouredFor = god.DemigodName; _energy.SetColor(ElementColors.Of(god.DemigodName)); } _tick -= dt; if (_tick <= 0f) { _tick = 0.1f; Tick(player); } if (_energy.Animating) { _energy.Animate(dt); } if (_xp.Animating) { _xp.Animate(dt); } } } private bool Build() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_rootObject == (Object)null) { return false; } GameObject val = new GameObject("DemigodMeters", new Type[2] { typeof(RectTransform), typeof(Canvas) }); _root = (RectTransform)val.transform; ((Transform)_root).SetParent(instance.m_rootObject.transform, false); RectTransform root = _root; RectTransform root2 = _root; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0f); root2.anchorMax = val2; root.anchorMin = val2; _root.pivot = new Vector2(0.5f, 0.5f); _root.sizeDelta = new Vector2((float)Plugin.EnergyBarWidth.Value + 8f + (float)Plugin.XpBarWidth.Value, 22f); _energy = HudBar.Create((Transform)(object)_root, "Energy", 100f, 22f, 14f); _xp = HudBar.Create((Transform)(object)_root, "Xp", 100f, 22f, 14f); _xp.SetColor(ElementColors.Xp); _colouredFor = null; _layoutDirty = true; ApplyLayout(); return true; } private void Layout(bool energyOn, bool xpOn) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) float num = Plugin.EnergyBarWidth.Value; float num2 = Plugin.XpBarWidth.Value; float num3 = (energyOn ? num : 0f) + (xpOn ? num2 : 0f) + ((energyOn && xpOn) ? 8f : 0f); _root.sizeDelta = new Vector2(num3, 22f); _energy.SetActive(energyOn); _xp.SetActive(xpOn); float num4 = (0f - num3) * 0.5f; if (energyOn) { Seat(_energy, num, num4 + num * 0.5f); num4 += num + 8f; } if (xpOn) { Seat(_xp, num2, num4 + num2 * 0.5f); } ResetShown(); _tick = 0f; ApplyLayout(); } private static void Seat(HudBar bar, float outer, float centreX) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) bar.SetWidth(HudBar.FillWidthFor(outer)); RectTransform root = bar.Root; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); root.anchorMax = val; root.anchorMin = val; root.pivot = new Vector2(0.5f, 0.5f); root.anchoredPosition = new Vector2(centreX, 0f); } private void Tick(Player player) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) if (((Component)_energy.Root).gameObject.activeSelf) { SE_Demigod val = NdBridge.StatusOf(player); int num = (((Object)(object)val != (Object)null) ? val.Energy : 0); int num2 = NdBridge.MaxEnergy(player); if (num != _shownEnergy || num2 != _shownMaxEnergy) { if (num2 != _shownMaxEnergy) { _energy.SetSegments(num2); } _shownEnergy = num; _shownMaxEnergy = num2; _energy.Set((num2 > 0) ? ((float)num / (float)num2) : 0f, Loc.F("$dgp_bar_energy", num, num2)); } } if (((Component)_xp.Root).gameObject.activeSelf) { XpReadout.Read(player, out var level, out var fraction, out var capped, out var atMax); int num3 = Mathf.FloorToInt(fraction * 100f); if (level != _shownLevel || num3 != _shownPercent || capped != _shownCapped) { _shownLevel = level; _shownPercent = num3; _shownCapped = capped; string text = (atMax ? Loc.F("$dgp_bar_xp_max", level) : (capped ? Loc.F("$dgp_bar_xp_capped", level) : Loc.F("$dgp_bar_xp", level, num3))); _xp.SetColor(capped ? ElementColors.XpCapped : ElementColors.Xp); _xp.Set(atMax ? 1f : fraction, text, trail: false); } } } private void ResetShown() { _shownEnergy = (_shownMaxEnergy = (_shownLevel = (_shownPercent = -1))); _shownCapped = false; } private void SetVisible(bool visible) { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf != visible) { ((Component)_root).gameObject.SetActive(visible); } } } internal static class NumberStyle { public static readonly string Fixed = UiKit.Hex(new Color(0.95f, 0.82f, 0.55f)); public static readonly string Scaling = UiKit.Hex(new Color(0.42f, 0.86f, 0.8f)); public static readonly string Pulse = UiKit.Hex(Color.white); public static readonly string Infused = UiKit.Hex(UiKit.Ice); public static readonly string Muted = UiKit.Hex(UiKit.Muted); public static string Element(string id, bool capital) { string text = Loc.T("$dgp_el_" + id); if (text.Length > 0) { text = char.ToUpperInvariant(text[0]) + text.Substring(1); } if (ElementColours.Canonical(id) == null) { return text; } return "" + text + ""; } public static string Tint(string text) { return ElementWords.Tint(text); } } internal sealed class NumberSheet { private readonly List _found = new List(); private readonly Dictionary _lastValues = new Dictionary(); private HashSet _pulsing; public ValueContext Context; public int CapLevel; public string CapTrophy; public bool AnyScaling { get; private set; } public Player Player { get; private set; } public void SetPlayer(Player player, bool asOtherGod) { Player = player; float num = NdBridge.Level(player); bool flag = (Object)(object)NdBridge.GodOf(player) != (Object)null; if (asOtherGod && flag) { NdBridge.AfterSwitch(player, out var level, out var _); num = level; } Context = new ValueContext(Mathf.Floor(num), ((Object)(object)player != (Object)null) ? NdBridge.SkillLevel(player, (SkillType)11) : 0f, !asOtherGod && NdBridge.AbilitiesInfused(player)); CapState capState = NdBridge.Cap(player, num); CapLevel = (capState.Capped ? capState.Cap : 0); CapTrophy = ((capState.Capped && capState.NextTier >= 0) ? NdBridge.TrophyName(capState.NextTier) : null); } public void Begin() { _found.Clear(); AnyScaling = false; } public string Render(string template) { return CardTemplate.Render(template, NdSettings.Instance, Context, Markup, _found); } public string BuildWithPulse(Func build, out string pulsed) { Dictionary dictionary = new Dictionary(_lastValues); string result = build(); _pulsing = null; foreach (KeyValuePair lastValue in _lastValues) { if (dictionary.TryGetValue(lastValue.Key, out var value) && value != lastValue.Value) { (_pulsing ?? (_pulsing = new HashSet())).Add(lastValue.Key); } } pulsed = null; if (_pulsing != null) { pulsed = build(); _pulsing = null; } return result; } public void ForgetValues() { _lastValues.Clear(); } public string Detail(string linkId) { if (linkId == null || linkId.Length < 2 || linkId[0] != 'v' || !int.TryParse(linkId.Substring(1), out var result) || result < 0 || result >= _found.Count) { return null; } Placeholder placeholder = _found[result]; CardTemplate.DetailText text = new CardTemplate.DetailText { Now = Loc.T("$dgp_value_now"), Next = Loc.T("$dgp_value_next"), AtMax = Loc.T("$dgp_value_max"), Capped = Loc.T("$dgp_value_capped") }; return CardTemplate.Detail(placeholder.Id, placeholder.Unit, NdSettings.Instance, Context, text, CapLevel, CapTrophy); } private string Markup(Placeholder p) { if (p.IsTag) { return Tag(p.Id); } if (!p.Scales) { return "" + p.Text + ""; } AnyScaling = true; _lastValues[p.Id] = p.Text; string text = ((_pulsing != null && _pulsing.Contains(p.Id)) ? NumberStyle.Pulse : NumberStyle.Scaling); return "" + p.Text + "" + UiFonts.Up + ""; } private static string SetName(string effect) { StatusEffect val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(effect)) : null); if (!((Object)(object)val != (Object)null) || string.IsNullOrEmpty(val.m_name)) { return effect.Replace("SetEffect_", string.Empty); } return Loc.T(val.m_name); } private static string Tag(string id) { if (id == "@infused") { return "" + Loc.T("$dgp_tag_infused") + ""; } if (id.StartsWith("@el:")) { return NumberStyle.Element(id.Substring(4), capital: false); } if (id.StartsWith("@El:")) { return NumberStyle.Element(id.Substring(4), capital: true); } if (id.StartsWith("@item:")) { string text = id.Substring(6); if (!text.StartsWith("$")) { return text; } return Loc.T(text); } if (id.StartsWith("@set:")) { return SetName(id.Substring(5)); } return string.Empty; } } internal sealed class PantheonTab : PanelTab { private const float RowH = 44f; private const float IconSize = 38f; private DemigodPanelView _view; private RectTransform _list; private ScrollRect _listScroll; private RectTransform _icons; private DetailsCard _details; private FigureView _figure; private RectTransform _godView; private BasicsView _basics; private bool _basicsSelected; private Image _basicsRow; private Button _become; private Demigod _god; private GodInfo _selected; private DemigodAbility _hoveredAbility; private readonly HoverHold _hold = new HoverHold(); private readonly Dictionary _cards = new Dictionary(); private readonly Dictionary _sheets = new Dictionary(); private readonly NumberSheet _hoverSheet = new NumberSheet(); private int _stateLevel = -1; private int _stateUnarmed = -1; private int _stateTrophies = -1; private bool _stateInfused; private bool _pulseNext; private readonly List<(GodInfo God, Image Bg, TMP_Text Tag, TMP_Text Name, Image Icon)> _rows = new List<(GodInfo, Image, TMP_Text, TMP_Text, Image)>(); private int _listGeneration = -1; private string _iconsFor; private const float RowIconSize = 36f; private object _shownSelected; private object _shownHover; private object _shownGod; private long _shownSealed = -1L; private int _shownConfig = -1; public override void Build(DemigodPanelView view, RectTransform root) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) _view = view; UiKit.Inset((Transform)(object)root, "LeftBg", 30f, 190f, 430f, 520f); UiKit.Text((Transform)(object)root, Loc.T("$dgp_pantheon_intro"), 14, UiKit.Muted, (TextAnchor)0, 44f, 200f, 402f, 22f); _list = UiKit.ScrollList((Transform)(object)root, 30f, 226f, 430f, 480f, 88f, out _listScroll); _godView = UiKit.Box((Transform)(object)root, "GodView", 0f, 0f, 1400f, 820f); _details = new DetailsCard((Transform)(object)_godView, 475f, 190f, 520f, 520f); _figure = new FigureView((Transform)(object)_godView, 1010f, 190f, 360f, 520f); _icons = UiKit.Box((Transform)(object)_godView, "Powers", 1020f, 610f, 340f, 38f); _become = UiKit.Button((Transform)(object)_godView, string.Empty, 1040f, 660f, 300f, 44f, delegate { _view.AskBecome(_selected); }); _basics = new BasicsView((Transform)(object)root, 475f, 190f, 895f, 520f); } public override void Rebuild(Demigod god) { _god = god; _cards.Clear(); _shownSelected = null; List list = NdBridge.Gods(); if (_listGeneration != NdBridge.GodsGeneration) { _listGeneration = NdBridge.GodsGeneration; _iconsFor = null; BuildList(list); } GodInfo godInfo = null; foreach (GodInfo item in list) { if (_selected != null && item.Key == _selected.Key) { godInfo = item; } } if (godInfo == null) { foreach (GodInfo item2 in list) { if ((Object)(object)god != (Object)null && item2.Defaults.Type == ((object)god).GetType()) { godInfo = item2; } } } bool basicsSelected = _basicsSelected; Select(godInfo ?? ((list.Count > 0) ? list[0] : null)); if (basicsSelected) { ShowBasics(); } } public override void Tick() { if (_hold.Expired() && _hoveredAbility != null) { _hoveredAbility = null; Refresh(); } } public override void Hidden() { _hold.Enter(); _hoveredAbility = null; } private void BuildList(List gods) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) for (int num = ((Transform)_list).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_list).GetChild(num)).gameObject); } _rows.Clear(); int num2 = gods.Count + 1; RectTransform viewport = _listScroll.viewport; float num3 = (float)num2 * 44f - 4f; Rect rect = viewport.rect; bool flag = num3 > ((Rect)(ref rect)).height; float num4 = 430f - (flag ? 30f : 16f); _list.sizeDelta = new Vector2(430f, num3); _listScroll.verticalNormalizedPosition = 1f; BuildBasicsRow(num4); for (int i = 0; i < gods.Count; i++) { GodInfo g = gods[i]; RectTransform val = UiKit.Box((Transform)(object)_list, g.Key, 8f, (float)(i + 1) * 44f, num4, 40f); Image val2 = ((Component)val).gameObject.AddComponent(); val2.sprite = UiKit.White; ((Graphic)val2).color = UiKit.Row; float num5 = 12f; Image item = null; Sprite val3 = AbilityView.GodIcon(g.Key); if ((Object)(object)val3 != (Object)null) { item = RowIcon(val, "GodIcon", val3); num5 = 50f; } TextMeshProUGUI item2 = UiKit.PanelText((Transform)(object)val, "Name", g.DisplayName, 17f, Color.white, (TextAlignmentOptions)257, num5, 2f, num4 - num5 - 8f, 22f, bold: true); UiKit.PanelText((Transform)(object)val, "Epithet", Texts.Lore(g.Key, "epithet") ?? string.Empty, 13f, UiKit.Muted, (TextAlignmentOptions)257, num5, 22f, num4 - num5 - 8f, 17f); TextMeshProUGUI item3 = UiKit.PanelText((Transform)(object)val, "Tag", string.Empty, 13f, UiKit.Gold, (TextAlignmentOptions)4100, num4 - 140f, 0f, 130f, 40f, bold: true); _rows.Add((g, val2, (TMP_Text)(object)item3, (TMP_Text)(object)item2, item)); UiKit.Hover(((Component)val).gameObject, null, null, delegate { Select(g); }); } } private static Image RowIcon(RectTransform row, string name, Sprite sprite) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Image obj = UiKit.Image((Transform)(object)row, name, sprite, Color.white); obj.preserveAspect = true; RectTransform rectTransform = ((Graphic)obj).rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 0.5f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(0f, 0.5f); rectTransform.anchoredPosition = new Vector2(6f, 0f); rectTransform.sizeDelta = new Vector2(36f, 36f); return obj; } private void BuildBasicsRow(float rowW) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiKit.Box((Transform)(object)_list, "Basics", 8f, 0f, rowW, 40f); _basicsRow = ((Component)val).gameObject.AddComponent(); _basicsRow.sprite = UiKit.White; ((Graphic)_basicsRow).color = UiKit.Row; RowIcon(val, "Icon", AbilityView.Fallback()); float num = 50f; UiKit.PanelText((Transform)(object)val, "Name", Loc.T("$dgp_basics_title"), 17f, UiKit.Gold, (TextAlignmentOptions)257, num, 2f, rowW - num - 8f, 22f, bold: true); UiKit.PanelText((Transform)(object)val, "Epithet", Loc.T("$dgp_basics_row_sub"), 13f, UiKit.Muted, (TextAlignmentOptions)257, num, 22f, rowW - num - 8f, 17f); UiKit.Hover(((Component)val).gameObject, null, null, ShowBasics); } public void ShowBasics() { _basicsSelected = true; _hoveredAbility = null; ApplyBasics(); } private void ApplyBasics() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) ((Component)_godView).gameObject.SetActive(!_basicsSelected); _basics.Show(_basicsSelected); if ((Object)(object)_basicsRow != (Object)null) { ((Graphic)_basicsRow).color = (_basicsSelected ? UiKit.RowSelected : UiKit.Row); } if (!_basicsSelected) { return; } foreach (var row in _rows) { ((Graphic)row.Bg).color = UiKit.Row; } } private void Select(GodInfo god) { _basicsSelected = false; ApplyBasics(); _selected = god; _hoveredAbility = null; if (_iconsFor != god?.Key) { _iconsFor = god?.Key; BuildIcons(); } Refresh(); } private void BuildIcons() { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) for (int num = ((Transform)_icons).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_icons).GetChild(num)).gameObject); } if (_selected == null) { return; } List list = AbilityView.Sorted(_selected.Defaults.DefaultAbilities); float num2 = 44f; float num3 = (340f - ((float)list.Count * num2 - 6f)) * 0.5f; foreach (DemigodAbility item in list) { RectTransform obj = UiKit.Box((Transform)(object)_icons, ((object)item).GetType().Name, num3, 0f, 38f, 38f); Image obj2 = ((Component)obj).gameObject.AddComponent(); obj2.sprite = UiKit.White; ((Graphic)obj2).color = Color.clear; UiKit.Fill(SlotArt.Socket((Transform)(object)obj, "Socket", AbilityView.Icon(item, _selected.Key), 38f, out var _)); DemigodAbility ability = item; UiKit.Hover(((Component)obj).gameObject, delegate { _hold.Enter(); _hoveredAbility = ability; Refresh(); }, delegate { if (_hoveredAbility == ability) { _hold.Exit(); } }, null); num3 += num2; } } private void CheckPlayerState() { Player localPlayer = Player.m_localPlayer; int num = Mathf.FloorToInt(NdBridge.Level(localPlayer)); int num2 = (((Object)(object)localPlayer != (Object)null) ? Mathf.FloorToInt(NdBridge.SkillLevel(localPlayer, (SkillType)11)) : 0); int num3 = (((Object)(object)localPlayer != (Object)null) ? localPlayer.m_trophies.Count : 0); bool flag = NdBridge.AbilitiesInfused(localPlayer); if (num != _stateLevel || num2 != _stateUnarmed || num3 != _stateTrophies || flag != _stateInfused) { _pulseNext = _stateLevel >= 0 && num > _stateLevel; _stateLevel = num; _stateUnarmed = num2; _stateTrophies = num3; _stateInfused = flag; _cards.Clear(); _shownSelected = null; } } public override void Refresh() { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Root == (Object)null || !Root.activeInHierarchy) { return; } CheckPlayerState(); if (_basicsSelected) { _basics.Refresh(); return; } if (_shownConfig != NdEvents.ConfigVersion) { _shownConfig = NdEvents.ConfigVersion; _cards.Clear(); _shownSelected = null; NdBridge.Gods(); if (_listGeneration != NdBridge.GodsGeneration) { Rebuild(_god); return; } } long num = 0L; for (int i = 0; i < _rows.Count && i < 64; i++) { num |= (_rows[i].God.Disabled ? (1L << i) : 0); } if (_selected == _shownSelected && _hoveredAbility == _shownHover && _god == _shownGod && num == _shownSealed) { return; } _shownSelected = _selected; _shownHover = _hoveredAbility; _shownGod = _god; _shownSealed = num; foreach (var row in _rows) { bool flag = _selected != null && row.God.Key == _selected.Key; bool num2 = (Object)(object)_god != (Object)null && row.God.Defaults.Type == ((object)_god).GetType(); ((Graphic)row.Bg).color = (flag ? UiKit.RowSelected : UiKit.Row); ((Graphic)row.Name).color = (row.God.Disabled ? UiKit.Muted : Color.white); if ((Object)(object)row.Icon != (Object)null) { ((Graphic)row.Icon).color = (Color)(row.God.Disabled ? new Color(1f, 1f, 1f, 0.45f) : Color.white); } string text = (num2 ? Loc.T("$dgp_your_god") : (row.God.Disabled ? Loc.T("$dgp_sealed") : string.Empty)); if (row.Tag.text != text) { row.Tag.text = text; } } if (_selected == null) { _details.Show(null, null, string.Empty, string.Empty, string.Empty); _figure.Show(null, string.Empty); ((Component)_become).gameObject.SetActive(false); return; } _figure.Show(_selected.Key, _selected.DisplayName); if (_hoveredAbility != null) { DemigodAbility hoveredAbility = _hoveredAbility; bool asOtherGod = (Object)(object)_god == (Object)null || _selected.Defaults.Type != ((object)_god).GetType(); _hoverSheet.SetPlayer(Player.m_localPlayer, asOtherGod); _hoverSheet.Begin(); string text2 = Texts.Ours(hoveredAbility, _selected.Key, string.Empty, _hoverSheet); string text3 = Texts.Header(Loc.T("$dgp_cost")) + "\n" + Texts.CostLine(hoveredAbility, null, infused: false) + "\n\n" + Texts.Header(Loc.T("$dgp_description")) + "\n" + (text2 ?? AbilityView.Safe((Func)hoveredAbility.GetTooltip) ?? string.Empty); if (text2 == null) { text3 = text3 + "\n\n" + Loc.T("$dgp_template_note") + ""; } _details.Show(hoveredAbility, AbilityView.Icon(hoveredAbility, _selected.Key), hoveredAbility.DisplayName, Texts.KindLabel(hoveredAbility) + " · " + AbilityView.KeyLabelOf(hoveredAbility), text3, _hoverSheet, null, round: true); } else { bool otherGod = (Object)(object)_god == (Object)null || _selected.Defaults.Type != ((object)_god).GetType(); string pulsed = null; if (!_sheets.TryGetValue(_selected.Key, out var sheet)) { sheet = new NumberSheet(); _sheets[_selected.Key] = sheet; } if (!_cards.TryGetValue(_selected.Key, out var value)) { sheet.SetPlayer(Player.m_localPlayer, otherGod); GodInfo selected = _selected; value = (_pulseNext ? sheet.BuildWithPulse(() => Texts.GodBody(selected, sheet, otherGod), out pulsed) : Texts.GodBody(selected, sheet, otherGod)); _cards[_selected.Key] = value; } _pulseNext = false; _details.Show(_selected, null, _selected.DisplayName, Texts.Lore(_selected.Key, "epithet") ?? string.Empty, value, sheet, pulsed); } bool flag2 = (Object)(object)_god != (Object)null && _selected.Defaults.Type == ((object)_god).GetType(); ((Component)_become).gameObject.SetActive(true); ((Selectable)_become).interactable = !flag2 && !_selected.Disabled && NdBridge.CanSwitch; UiKit.SetLabel(_become, flag2 ? Loc.T("$dgp_current") : (_selected.Disabled ? Loc.T("$dgp_sealed_button") : Loc.F("$dgp_become", _selected.DisplayName))); } } internal sealed class PerksTab : PanelTab { private enum Topic { Vitals, Armor, Resist, Traits, Infusions, Growth } private static readonly Topic[] Topics = new Topic[6] { Topic.Vitals, Topic.Armor, Topic.Resist, Topic.Traits, Topic.Infusions, Topic.Growth }; private static readonly StringBuilder Sb = new StringBuilder(1024); private readonly NumberSheet _sheet = new NumberSheet(); private Topic _pulseTopic; private int _pulseLevel = -1; private readonly Text[] _summaries = (Text[])(object)new Text[Topics.Length]; private readonly Image[] _rows = (Image[])(object)new Image[Topics.Length]; private DetailsCard _details; private FigureView _figure; private Demigod _god; private Topic _topic; private int _hovered = -1; private readonly HoverHold _hold = new HoverHold(); private (int Topic, int Hover, int Level, int Raw, int Acc, int Energy, int Max, int Regen, (bool Infused, int Gear, int Dynamic, int Version, int Config, int Active) More, (int Unarmed, int Trophies, int Effects) Skill) _stamp; private bool _stamped; private static readonly (string Element, Func Get)[] DamageTypes = new(string, Func)[8] { ("blunt", (DamageModifiers m) => m.m_blunt), ("slash", (DamageModifiers m) => m.m_slash), ("pierce", (DamageModifiers m) => m.m_pierce), ("fire", (DamageModifiers m) => m.m_fire), ("frost", (DamageModifiers m) => m.m_frost), ("lightning", (DamageModifiers m) => m.m_lightning), ("poison", (DamageModifiers m) => m.m_poison), ("spirit", (DamageModifiers m) => m.m_spirit) }; public override void Tick() { if (_hold.Expired() && _hovered >= 0) { _hovered = -1; Refresh(); } } public override void Hidden() { _hold.Enter(); _hovered = -1; } public override void Build(DemigodPanelView view, RectTransform root) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) UiKit.Inset((Transform)(object)root, "LeftBg", 30f, 190f, 430f, 520f); string[] array = new string[6] { "$dgp_perk_vitals", "$dgp_perk_armor", "$dgp_perk_resist", "$dgp_perk_traits", "$dgp_perk_infusions", "$dgp_perk_growth" }; for (int i = 0; i < Topics.Length; i++) { int index = i; RectTransform val = UiKit.Box((Transform)(object)root, "Topic" + i, 40f, 202f + (float)i * 74f, 410f, 68f); Image val2 = ((Component)val).gameObject.AddComponent(); val2.sprite = UiKit.White; ((Graphic)val2).color = UiKit.Row; _rows[i] = val2; UiKit.Text((Transform)(object)val, Loc.T(array[i]), 19, UiKit.Orange, (TextAnchor)0, 14f, 10f, 382f, 26f, bold: true); _summaries[i] = UiKit.Text((Transform)(object)val, string.Empty, 14, UiKit.Muted, (TextAnchor)0, 14f, 40f, 382f, 30f); UiKit.Hover(((Component)val).gameObject, delegate { _hold.Enter(); _hovered = index; Refresh(); }, delegate { if (_hovered == index) { _hold.Exit(); } }, delegate { _topic = Topics[index]; Refresh(); }); } UiKit.Button((Transform)(object)root, Loc.T("$dgp_basics_link"), 40f, 656f, 410f, 42f, view.ShowBasics); _details = new DetailsCard((Transform)(object)root, 475f, 190f, 520f, 520f); _figure = new FigureView((Transform)(object)root, 1010f, 190f, 360f, 520f); } public override void Rebuild(Demigod god) { _god = god; _stamped = false; _figure.Show((god != null) ? god.DemigodName : null, ((Object)(object)god != (Object)null) ? NdBridge.GodDisplayName(god.DemigodName) : string.Empty); } public override void Refresh() { //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) Player player = Player.m_localPlayer; if ((Object)(object)_god == (Object)null || (Object)(object)player == (Object)null || (Object)(object)Root == (Object)null || !Root.activeInHierarchy) { return; } SE_Demigod val = NdBridge.StatusOf(player); NdBridge.RawSkill(player, out var rawLevel, out var acc); float level = NdBridge.Level(player); int energy = (((Object)(object)val != (Object)null) ? val.Energy : 0); int max = NdBridge.MaxEnergy(player); float regen = NdBridge.EnergyRegenPeriod(player); bool flag = NdBridge.AbilitiesInfused(player); (int, int, int, int, int, int, int, int, (bool, int, int, int, int, int), (int, int, int)) stamp = Stamp(player, level, rawLevel, acc, energy, max, regen, flag); if (!_stamped || !stamp.Equals(_stamp)) { _stamp = stamp; _stamped = true; ResistSummary(player, out var strong, out var weak); int num = CountInfusions(); _sheet.SetPlayer(player, asOtherGod: false); _sheet.Begin(); int num2 = CountXpLines(_sheet.Render(Texts.Lore(_god.DemigodName, "level") ?? string.Empty)); int num3 = _god.DefaultAttributes?.Count ?? 0; SetSummary(Topic.Vitals, Loc.F("$dgp_sum_vitals", energy, max, (regen > 0f) ? Loc.F("$dgp_every_s", NumberFormat.Digits(regen)) : Loc.T("$dgp_regen_off"))); SetSummary(Topic.Armor, Loc.F("$dgp_sum_armor", Helper.PlayerWearingHeavyArmorCount(player))); SetSummary(Topic.Resist, Loc.F("$dgp_sum_resist", strong, weak)); SetSummary(Topic.Traits, (num3 == 1) ? Loc.T("$dgp_sum_traits_one") : Loc.F("$dgp_sum_traits", num3)); SetSummary(Topic.Infusions, Loc.F("$dgp_sum_infusions", num, Loc.T(flag ? "$dgp_godinfusion_active" : "$dgp_godinfusion_notyet"))); SetSummary(Topic.Growth, (num2 == 1) ? Loc.T("$dgp_sum_growth_one") : Loc.F("$dgp_sum_growth", num2)); for (int i = 0; i < Topics.Length; i++) { ((Graphic)_rows[i]).color = ((Topics[i] == _topic) ? UiKit.RowSelected : ((i == _hovered) ? UiKit.RowHover : UiKit.Row)); } Topic topic = ((_hovered >= 0) ? Topics[_hovered] : _topic); string title = TitleOf(topic); int num4 = Mathf.FloorToInt(level); bool flag2 = topic == _pulseTopic && _pulseLevel >= 0 && num4 > _pulseLevel; if (!flag2) { _sheet.ForgetValues(); } _pulseTopic = topic; _pulseLevel = num4; string pulsed; string body = _sheet.BuildWithPulse(delegate { _sheet.Begin(); return topic switch { Topic.Vitals => Vitals(player, level, rawLevel, acc, energy, max, regen), Topic.Armor => Armor(player), Topic.Resist => Resist(player), Topic.Traits => Traits(level), Topic.Infusions => Infusions(player), _ => Growth(player, rawLevel), }; }, out pulsed); _details.Show(topic, null, title, NdBridge.GodDisplayName(_god.DemigodName), body, _sheet, flag2 ? pulsed : null); } } private (int, int, int, int, int, int, int, int, (bool, int, int, int, int, int), (int, int, int)) Stamp(Player player, float level, float rawLevel, float acc, int energy, int max, float regen, bool infused) { return ((int)_topic, _hovered, Mathf.FloorToInt(level * 100f), Mathf.FloorToInt(rawLevel), Mathf.FloorToInt(acc), energy, max, Mathf.RoundToInt(regen * 10f), (infused, AbilitiesTab.GearStamp(player), _god.DynamicAttributes?.Count ?? 0, NdEvents.Version, NdEvents.ConfigVersion, AbilitiesTab.ActiveMask(_god)), (Mathf.FloorToInt(NdBridge.SkillLevel(player, (SkillType)11)), player.m_trophies.Count, StatusStamp(player))); } private static int StatusStamp(Player player) { int num = 17; foreach (StatusEffect statusEffect in ((Character)player).GetSEMan().GetStatusEffects()) { if ((Object)(object)statusEffect != (Object)null && !(statusEffect is SE_Ability_Cooldown)) { num = num * 31 + statusEffect.NameHash(); } } return num; } private void SetSummary(Topic topic, string text) { Text val = _summaries[(int)topic]; text = NumberStyle.Tint(text); if (val.text != text) { val.text = text; } } private static string TitleOf(Topic topic) { return topic switch { Topic.Vitals => Loc.T("$dgp_perk_vitals"), Topic.Armor => Loc.T("$dgp_perk_armor"), Topic.Resist => Loc.T("$dgp_perk_resist"), Topic.Traits => Loc.T("$dgp_perk_traits"), Topic.Infusions => Loc.T("$dgp_perk_infusions"), _ => Loc.T("$dgp_perk_growth"), }; } private string Vitals(Player player, float level, float rawLevel, float acc, int energy, int max, float regen) { Sb.Clear(); Sb.Append(Texts.Header(Loc.T("$dgp_vitals_level"))).Append('\n').Append(Mathf.FloorToInt(level)) .Append('\n'); if (rawLevel < 100f) { Sb.Append(Loc.T("$dgp_vitals_xp")).Append(": ").Append(Loc.F("$dgp_xp", Mathf.FloorToInt(acc), Mathf.CeilToInt(XpMath.Requirement(rawLevel)))) .Append(" (") .Append(Mathf.FloorToInt(XpMath.Percent(rawLevel, acc) * 100f)) .Append("%)\n"); } int num = NdBridge.EnergyFromLevel(level); int num2 = (((Character)player).GetSEMan().HaveStatusEffect(Cache.s_statusEffectInfusedBeltStrength) ? Configs.InfusedMegingjordIncreasedEnergy.Value : 0); int num3 = Mathf.Max(0, max - num - num2); Sb.Append('\n').Append(Texts.Header(Loc.T("$dgp_vitals_energy"))).Append('\n'); Sb.Append(Loc.F("$dgp_vitals_energy_now", energy, max)).Append('\n'); Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(_sheet.Render(Loc.T("$dgp_vitals_energy_from_level"))) .Append('\n'); if (num2 > 0) { Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(Loc.F("$dgp_megingjord", num2)) .Append('\n'); } if (num3 > 0) { Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(Loc.F("$dgp_vitals_energy_bonus", num3)) .Append('\n'); } Sb.Append('\n').Append((regen > 0f) ? Loc.F("$dgp_vitals_regen", NumberFormat.Digits(regen)) : Loc.T("$dgp_vitals_regen_off")); return Sb.ToString(); } private string Armor(Player player) { Sb.Clear(); string text = Texts.Lore(_god.DemigodName, "armor_kind"); string text2 = Texts.Lore(_god.DemigodName, "armor"); if (text != null && text2 != null) { Sb.Append(Texts.Header(Loc.T("$dgp_armor_guide"))).Append('\n'); Sb.Append("").Append(Loc.T("$dgp_armor_kind_" + text)).Append("\n"); Bullets(_sheet.Render(text2)); Sb.Append('\n'); } string text3 = Texts.Lore(_god.DemigodName, "weapons"); if (text3 != null) { Sb.Append(Texts.Header(Loc.T("$dgp_weapon_guide"))).Append('\n'); Bullets(_sheet.Render(text3)); Sb.Append('\n'); } string godName = NdBridge.GodDisplayName(_god.DemigodName); Sb.Append(Texts.Header(Loc.T("$dgp_armor_now"))).Append('\n'); Piece("$dgp_slot_helmet", ((Humanoid)player).m_helmetItem); Piece("$dgp_slot_chest", ((Humanoid)player).m_chestItem); Piece("$dgp_slot_legs", ((Humanoid)player).m_legItem); GearNotes.Armor(Sb, player, _god.DemigodName, godName, _sheet); Sb.Append("").Append(Loc.T("$dgp_armor_rule")).Append("\n\n"); ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); ItemData val = (((Object)(object)((Humanoid)player).m_unarmedWeapon != (Object)null) ? ((Humanoid)player).m_unarmedWeapon.m_itemData : null); string value = ((currentWeapon == null || currentWeapon == val) ? Loc.T("$dgp_unarmed") : Loc.T(currentWeapon.m_shared.m_name)); Sb.Append(Texts.Header(Loc.T("$dgp_weapon_hand"))).Append('\n'); Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(value) .Append('\n'); GearNotes.Weapon(Sb, player, _god.DemigodName, godName, _sheet); return Sb.ToString(); } private static void Bullets(string rendered) { string[] array = rendered.Split(new char[1] { '\n' }); foreach (string text in array) { if (text.Length > 0) { Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(text) .Append('\n'); } } } private static void Piece(string slotToken, ItemData item) { Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(Loc.T(slotToken)) .Append(": "); if (item == null) { Sb.Append(Loc.T("$dgp_armor_empty")).Append('\n'); return; } bool flag = item.m_shared.m_movementModifier < -0.045f; Sb.Append(Loc.T(item.m_shared.m_name)).Append(" ') .Append(Loc.T(flag ? "$dgp_armor_heavy" : "$dgp_armor_light")) .Append("\n"); } private static DamageModifiers FinalModifiers(Player player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) try { return ((Character)player).GetDamageModifiers((WeakSpot)null); } catch (Exception) { return default(DamageModifiers); } } private static void ResistSummary(Player player, out string strong, out string weak) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) DamageModifiers arg = FinalModifiers(player); StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); (string, Func)[] damageTypes = DamageTypes; for (int i = 0; i < damageTypes.Length; i++) { (string, Func) tuple = damageTypes[i]; if (ModifierToken(tuple.Item2(arg), out var good) != null) { StringBuilder stringBuilder3 = (good ? stringBuilder : stringBuilder2); if (stringBuilder3.Length > 0) { stringBuilder3.Append(", "); } stringBuilder3.Append(NumberStyle.Element(tuple.Item1, capital: true)); } } strong = ((stringBuilder.Length > 0) ? stringBuilder.ToString() : Loc.T("$dgp_none")); weak = ((stringBuilder2.Length > 0) ? stringBuilder2.ToString() : Loc.T("$dgp_none")); } private static string Resist(Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Sb.Clear(); Sb.Append(Loc.T("$dgp_resist_intro")).Append("\n\n"); DamageModifiers arg = FinalModifiers(player); int num = 0; (string, Func)[] damageTypes = DamageTypes; for (int i = 0; i < damageTypes.Length; i++) { (string, Func) tuple = damageTypes[i]; bool good; string text = ModifierToken(tuple.Item2(arg), out good); if (text != null) { num++; Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(NumberStyle.Element(tuple.Item1, capital: true)) .Append(": ') .Append(Loc.T(text)) .Append("\n"); } } if (num == 0) { Sb.Append(Loc.T("$dgp_resist_none")); } return Sb.ToString(); } private static string ModifierToken(DamageModifier modifier, out bool good) { //IL_0003: 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_0027: Expected I4, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 good = true; switch (modifier - 1) { case 2: return "$inventory_immune"; case 4: return "$inventory_veryresistant"; case 0: return "$inventory_resistant"; case 6: return "$inventory_slightlyresistant"; default: good = false; if ((int)modifier != 2) { if ((int)modifier != 6) { if ((int)modifier == 8) { return "$inventory_slightlyweak"; } return null; } return "$inventory_veryweak"; } return "$inventory_weak"; } } private string Traits(float level) { Sb.Clear(); Sb.Append(Loc.T("$dgp_traits_intro")).Append("\n\n"); int num = 0; if (_god.DefaultAttributes != null) { foreach (DemigodAttribute value in _god.DefaultAttributes.Values) { string text = Texts.Ours(value, _god.DemigodName, string.Empty, _sheet) ?? AbilityView.Safe((Func)value.GetStatusTooltip); if (text != null) { num++; Sb.Append("").Append(value.DisplayName).Append("\n") .Append(text) .Append("\n\n"); } } } if (num == 0) { Sb.Append(Loc.T("$dgp_traits_none")); } return Sb.ToString(); } private int CountInfusions() { int num = 0; if (_god.DynamicAttributes != null) { foreach (DemigodAttribute value in _god.DynamicAttributes.Values) { if (!(value is AttributeInfusedAbilities)) { num++; } } } return num; } private string Infusions(Player player) { Sb.Clear(); Sb.Append(Texts.Header(Loc.T("$dgp_godinfusion"))).Append('\n'); bool flag = NdBridge.AbilitiesInfused(player); Sb.Append(Loc.T(flag ? "$dgp_infusion_on" : "$dgp_infusion_off")).Append('\n'); if (!flag) { string text = Texts.InfusionHint(_god.DemigodName); if (text != null) { Sb.Append(text).Append('\n'); } } Sb.Append('\n').Append(Texts.Header(Loc.T("$dgp_perk_infusions"))).Append('\n'); Sb.Append(Loc.T("$dgp_infusions_intro")).Append("\n\n"); int num = 0; if (_god.DynamicAttributes != null) { foreach (DemigodAttribute value in _god.DynamicAttributes.Values) { if (!(value is AttributeInfusedAbilities)) { num++; Sb.Append("" + UiFonts.Glyph('◆', "*") + " ").Append(value.DisplayName).Append(""); ILevelableAttribute val = (ILevelableAttribute)(object)((value is ILevelableAttribute) ? value : null); if (val != null) { Sb.Append(" ").Append(Loc.F("$dgp_infusion_level", val.AttributeLevel, val.AttributeMaxLevel)); } Sb.Append('\n').Append(AbilityView.Safe((Func)value.GetStatusTooltip) ?? AbilityView.Safe((Func)value.GetTooltip) ?? string.Empty).Append("\n\n"); } } } if (num == 0) { Sb.Append(Loc.T("$dgp_infusions_none")); } return Sb.ToString(); } private string Growth(Player player, float rawLevel) { Sb.Clear(); Sb.Append(Loc.F("$dgp_growth_intro", NdBridge.GodDisplayName(_god.DemigodName))).Append('\n'); string[] array = _sheet.Render(Texts.Lore(_god.DemigodName, "level") ?? string.Empty).Split(new char[1] { '\n' }); foreach (string text in array) { if (text.Length > 0) { Sb.Append(UiFonts.Glyph('•', "-")).Append(' ').Append(text) .Append('\n'); } } if (rawLevel < 100f) { Sb.Append('\n').Append(Loc.F("$dgp_growth_next", Mathf.CeilToInt(XpMath.Requirement(rawLevel)))).Append('\n'); } Sb.Append('\n'); CapLadder(player); return Sb.ToString(); } private static void CapLadder(Player player) { Sb.Append(Texts.Header(Loc.T("$dgp_growth_cap_h"))).Append('\n'); int num = Mathf.FloorToInt(NdBridge.Level(player)); CapState capState = NdBridge.Cap(player, num); if (capState.Cap <= 0 && capState.NextTier < 0) { Sb.Append(Loc.T("$dgp_growth_nocap")); return; } Sb.Append(Loc.T("$dgp_growth_cap_intro")).Append('\n'); int capTierCount = NdBridge.CapTierCount; for (int i = 0; i < capTierCount; i++) { int num2 = NdBridge.CapOfTier(i); bool flag = i == capState.Tier; bool flag2 = i == capState.NextTier; string value = (flag ? NumberStyle.Fixed : (flag2 ? NumberStyle.Scaling : NumberStyle.Muted)); string text = ((i == 0) ? Loc.T("$dgp_cap_tier_none") : NdBridge.TrophyName(i)); if (i == 0 && text.Length > 0) { text = char.ToUpperInvariant(text[0]) + text.Substring(1); } string value2 = (flag ? Loc.T("$dgp_basics_cap_now") : (flag2 ? Loc.T("$dgp_basics_cap_next") : string.Empty)); Sb.Append("') .Append((flag || flag2) ? "" : string.Empty) .Append(text) .Append("") .Append((num2 > 0) ? num2.ToString() : Loc.T("$dgp_no_cap")) .Append("") .Append(value2) .Append((flag || flag2) ? "" : string.Empty) .Append("\n"); } Sb.Length--; } private static int CountXpLines(string rendered) { int num = 0; string value = Loc.T("$dgp_xp_none_prefix"); string[] array = rendered.Split(new char[1] { '\n' }); foreach (string text in array) { if (text.StartsWith(value, StringComparison.Ordinal)) { break; } if (text.Length > 0) { num++; } } return num; } } internal static class UiFonts { private const string SymbolFontName = "DemigodPanelSymbols"; private static TMP_FontAsset _body; private static TMP_FontAsset _symbols; private static bool _resolved; private static readonly Dictionary Glyphs = new Dictionary(); private static bool _symbolsTried; public static TMP_FontAsset Body { get { Resolve(); return _body; } } public static string Up => Glyph('▲', "+"); public static void Warm() { Resolve(); Glyph('▲', "+"); Glyph('•', "-"); Glyph('–', "-"); Glyph('◆', "*"); Glyph('✔', "+"); Glyph('✖', "x"); Glyph('→', ">"); } public static string Glyph(char c, string fallback) { if (Glyphs.TryGetValue(c, out var value)) { return value; } Resolve(); string text = fallback; if ((Object)(object)_body != (Object)null && _body.HasCharacter(c, true, true)) { text = c.ToString(); } else if ((Object)(object)Symbols() != (Object)null && _symbols.HasCharacter(c, false, true)) { text = "" + c + ""; } Glyphs[c] = text; return text; } private static void Resolve() { if (_resolved) { return; } _resolved = true; TMP_FontAsset val = null; TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll(); foreach (TMP_FontAsset val2 in array) { string text = (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : null); if (text != null && text.IndexOf("AveriaSerif", StringComparison.OrdinalIgnoreCase) >= 0 && text.IndexOf("Bold", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Italic", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Light", StringComparison.OrdinalIgnoreCase) < 0) { if (text.IndexOf("Regular", StringComparison.OrdinalIgnoreCase) >= 0) { _body = val2; break; } if ((Object)(object)val == (Object)null || text.Length < ((Object)val).name.Length) { val = val2; } } } if (_body == null) { _body = val; } if ((Object)(object)_body == (Object)null && GUIManager.Instance != null) { _body = GUIManager.Instance.TMP_AveriaSansLibre; } } private static TMP_FontAsset Symbols() { if (_symbolsTried) { return _symbols; } _symbolsTried = true; string[] array = new string[4] { "Segoe UI Symbol", "Arial Unicode MS", "Arial", "DejaVu Sans" }; foreach (string text in array) { try { _symbols = TMP_FontAsset.CreateFontAsset(text, "Regular", 90); } catch (Exception ex) { Plugin.Log.LogDebug((object)("No symbol font " + text + ": " + ex.Message)); _symbols = null; } if ((Object)(object)_symbols != (Object)null) { ((Object)_symbols).name = "DemigodPanelSymbols"; ((TMP_Asset)_symbols).hashCode = TMP_TextUtilities.GetHashCode("DemigodPanelSymbols"); MaterialReferenceManager.AddFontAsset(_symbols); break; } } return _symbols; } } internal sealed class RichBody { private sealed class PulseRunner : MonoBehaviour { public RichBody Body; private void OnDisable() { Body?.EndPulse(); } } private static readonly string[] Separator = new string[1] { "\n\n" }; private readonly RectTransform _content; private readonly float _size; private readonly float _width; private readonly List _blocks = new List(); private readonly List _parts = new List(); private string _current; private Coroutine _pulse; public Func Detail; private string _pulseEnd; public RichBody(RectTransform content, float size, float width) { _content = content; _size = size; _width = width; } public void Set(string text) { if (_pulse != null) { StopPulse(); } Show(text); } public void Pulse(string pulsed, string normal) { StopPulse(); Show(pulsed); PulseRunner pulseRunner = ((Component)_content).GetComponent() ?? ((Component)_content).gameObject.AddComponent(); if (((Behaviour)pulseRunner).isActiveAndEnabled) { _pulseEnd = normal; pulseRunner.Body = this; _pulse = ((MonoBehaviour)pulseRunner).StartCoroutine(After(0.5f)); } else { Show(normal); } } private IEnumerator After(float seconds) { yield return (object)new WaitForSecondsRealtime(seconds); EndPulse(); } private void EndPulse() { _pulse = null; if (_pulseEnd != null) { string pulseEnd = _pulseEnd; _pulseEnd = null; Show(pulseEnd); } } private void StopPulse() { if (_pulse != null) { PulseRunner pulseRunner = (((Object)(object)_content != (Object)null) ? ((Component)_content).GetComponent() : null); if ((Object)(object)pulseRunner != (Object)null) { ((MonoBehaviour)pulseRunner).StopCoroutine(_pulse); } _pulse = null; } _pulseEnd = null; } private void Show(string text) { text = ElementWords.Tint(text ?? string.Empty); if (text == _current) { return; } _current = text; List list = Paragraphs(text); for (int i = 0; i < list.Count; i++) { if (i == _blocks.Count) { _blocks.Add(NewBlock()); } TextMeshProUGUI val = _blocks[i]; if (((TMP_Text)val).text != list[i]) { ((TMP_Text)val).text = list[i]; ((Component)val).GetComponent()?.Forget(); } if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } for (int j = list.Count; j < _blocks.Count; j++) { if (((Component)_blocks[j]).gameObject.activeSelf) { ((Component)_blocks[j]).gameObject.SetActive(false); } } } private TextMeshProUGUI NewBlock() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) Perf.CountCreated(); GameObject val = new GameObject("Paragraph", new Type[1] { typeof(RectTransform) }); val.SetActive(false); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)_content, false); val2.sizeDelta = new Vector2(_width, 10f); TextMeshProUGUI val3 = val.AddComponent(); TMP_FontAsset body = UiFonts.Body; if ((Object)(object)body != (Object)null) { ((TMP_Text)val3).font = body; } ((TMP_Text)val3).fontSize = _size; ((Graphic)val3).color = Color.white; ((TMP_Text)val3).richText = true; ((TMP_Text)val3).textWrappingMode = (TextWrappingModes)1; ((TMP_Text)val3).overflowMode = (TextOverflowModes)0; ((TMP_Text)val3).lineSpacing = 8f; ((Graphic)val3).raycastTarget = true; LinkHover linkHover = val.AddComponent(); linkHover.Body = this; linkHover.Text = val3; val.SetActive(true); return val3; } private List Paragraphs(string text) { _parts.Clear(); if (text.Length == 0) { return _parts; } StringBuilder stringBuilder = new StringBuilder(); string[] array = text.Split(Separator, StringSplitOptions.None); foreach (string value in array) { if (stringBuilder.Length > 0) { stringBuilder.Append("\n\n"); } stringBuilder.Append(value); if (OpenTags(stringBuilder) <= 0) { string text2 = stringBuilder.ToString().Trim('\n', ' '); stringBuilder.Clear(); if (text2.Length > 0) { _parts.Add(text2); } } } string text3 = stringBuilder.ToString().Trim('\n', ' '); if (text3.Length > 0) { _parts.Add(text3); } return _parts; } private static int OpenTags(StringBuilder sb) { string s = sb.ToString(); return Count(s, "") + Count(s, "") + Count(s, "") - Count(s, "") + Count(s, "") - Count(s, "") + Count(s, ""); } private static int Count(string s, string token) { int num = 0; for (int num2 = s.IndexOf(token, StringComparison.Ordinal); num2 >= 0; num2 = s.IndexOf(token, num2 + token.Length, StringComparison.Ordinal)) { num++; } return num; } } internal sealed class LinkHover : MonoBehaviour, IPointerMoveHandler, IEventSystemHandler, IPointerExitHandler { public RichBody Body; public Func Detail; public TextMeshProUGUI Text; private int _shown = -1; public void OnPointerMove(PointerEventData eventData) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Func func = ((Body != null) ? Body.Detail : Detail); if (func == null || (Object)(object)Text == (Object)null) { return; } try { Canvas canvas = ((Graphic)Text).canvas; Camera val = (((Object)(object)canvas == (Object)null || (int)canvas.renderMode == 0) ? null : canvas.worldCamera); int num = TMP_TextUtilities.FindIntersectingLink((TMP_Text)(object)Text, Vector2.op_Implicit(eventData.position), val); if (num == _shown) { if (num >= 0) { ValueTip.Move(eventData.position); } return; } _shown = num; string text = ((num >= 0) ? func(((TMP_LinkInfo)(ref ((TMP_Text)Text).textInfo.linkInfo[num])).GetLinkID()) : null); if (string.IsNullOrEmpty(text)) { ValueTip.Hide(); } else { ValueTip.Show(text, eventData.position); } } catch (Exception ex) { _shown = -1; ValueTip.Hide(); UiKit.Hovers.Fail(ex); } } public void OnPointerExit(PointerEventData eventData) { Clear(); } private void OnDisable() { Clear(); } public void Forget() { Clear(); } private void Clear() { if (_shown >= 0) { _shown = -1; ValueTip.Hide(); } } } internal static class ValueTip { private static RectTransform _root; private static TextMeshProUGUI _text; public static void Show(string text, Vector2 screen) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) long start = Perf.Begin(); long mem = Perf.BeginMem(); ShowInner(text, screen); Perf.End(Perf.Scope.Tooltip, start, mem); } private static void ShowInner(string text, Vector2 screen) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Ensure()) { ((TMP_Text)_text).text = ElementWords.Tint(text); ((Transform)_root).SetAsLastSibling(); ((Component)_root).gameObject.SetActive(true); LayoutRebuilder.ForceRebuildLayoutImmediate(_root); Move(screen); } } public static void Move(Vector2 screen) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && ((Component)_root).gameObject.activeSelf) { float num = ((((Transform)_root).lossyScale.x > 0f) ? ((Transform)_root).lossyScale.x : 1f); Rect rect = _root.rect; Vector2 val = ((Rect)(ref rect)).size * num; float num2 = Mathf.Min(screen.x + 16f, (float)Screen.width - val.x - 4f); float num3 = Mathf.Max(screen.y - 16f, val.y + 4f); ((Transform)_root).position = new Vector3(Mathf.Max(4f, num2), num3, 0f); } } public static void Hide() { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf) { ((Component)_root).gameObject.SetActive(false); } } public static void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; _text = null; } private static bool Ensure() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { return true; } GameObject customGUIFront = GUIManager.CustomGUIFront; if ((Object)(object)customGUIFront == (Object)null) { return false; } GameObject val = new GameObject("DemigodValueTip", new Type[2] { typeof(RectTransform), typeof(Image) }); _root = (RectTransform)val.transform; ((Transform)_root).SetParent(customGUIFront.transform, false); _root.pivot = new Vector2(0f, 1f); Image component = val.GetComponent(); component.sprite = UiKit.White; ((Graphic)component).color = new Color(0.08f, 0.06f, 0.05f, 0.96f); ((Graphic)component).raycastTarget = false; VerticalLayoutGroup obj = val.AddComponent(); ((LayoutGroup)obj).padding = new RectOffset(10, 10, 7, 7); bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth; ContentSizeFitter obj2 = val.AddComponent(); FitMode horizontalFit = (FitMode)2; obj2.verticalFit = (FitMode)2; obj2.horizontalFit = horizontalFit; GameObject val2 = new GameObject("Text", new Type[1] { typeof(RectTransform) }); val2.SetActive(false); val2.transform.SetParent((Transform)(object)_root, false); _text = val2.AddComponent(); if ((Object)(object)UiFonts.Body != (Object)null) { ((TMP_Text)_text).font = UiFonts.Body; } ((TMP_Text)_text).fontSize = 15f; ((Graphic)_text).color = Color.white; ((TMP_Text)_text).richText = true; ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0; val2.SetActive(true); val.SetActive(false); return true; } } internal static class SlotArt { public const float IconInset = 0.0711f; public const float Extra = 1.125f; private static bool _loaded; private static Sprite _ring; private static Sprite _back; private static Sprite _disc; private static Sprite _glow; private static Sprite _badge; public static Sprite Ring => Loaded(ref _ring); public static Sprite Back => Loaded(ref _back); public static Sprite Disc => Loaded(ref _disc); public static Sprite Glow => Loaded(ref _glow); public static Sprite Badge => Loaded(ref _badge); public static bool Ready { get { if ((Object)(object)Ring != (Object)null && (Object)(object)Back != (Object)null && (Object)(object)Disc != (Object)null && (Object)(object)Glow != (Object)null) { return (Object)(object)Badge != (Object)null; } return false; } } private static Sprite Loaded(ref Sprite sprite) { Load(); return sprite; } public static RectTransform Socket(Transform parent, string name, Sprite icon, float size, out Image image) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) RectTransform val = UiKit.Box(parent, name, 0f, 0f, size, size); UiKit.Fill(((Graphic)UiKit.Image((Transform)(object)val, "Bg", Back, Color.white)).rectTransform, (0f - size) * 0.125f * 0.5f); image = UiKit.Image((Transform)(object)val, "Icon", icon, Color.white); image.preserveAspect = true; UiKit.Fill(((Graphic)image).rectTransform, size * 0.0711f); UiKit.Fill(((Graphic)UiKit.Image((Transform)(object)val, "Ring", Ring, Color.white)).rectTransform); return val; } private static void Load() { if (!_loaded) { _loaded = true; _ring = Sprite("socket_ring"); _back = Sprite("socket_back"); _disc = Sprite("socket_disc"); _glow = Sprite("socket_glow"); _badge = Sprite("socket_badge"); } } private static Sprite Sprite(string name) { //IL_0039: 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) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown byte[] array = Utils.ReadResource("DemigodPanel.Assets.Slots." + name + ".png"); if (array == null) { Plugin.Log.LogWarning((object)("Slot art " + name + " is missing.")); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true) { name = "DemigodSlot_" + name, wrapMode = (TextureWrapMode)1 }; if (!AssetUtils.LoadImage(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = (FilterMode)2; ((Texture)val).mipMapBias = -0.5f; return Utils.ToSprite(val); } } internal sealed class UiHost : MonoBehaviour { private static UiHost _instance; private readonly AbilityBar _bar = new AbilityBar(); private readonly CompanionBars _companions = new CompanionBars(); private readonly MeterBars _meters = new MeterBars(); private LayoutOverlay _overlay; private DemigodPanelView _panel; private int _barVersion = -1; private bool _barDirty = true; private float _godIconTimer; private float _observeTimer; private float _hudSizeTimer; private readonly Guard _layoutGuard = new Guard("HUD placement"); private Vector2 _hudSize; private bool _metersRecovering; private readonly Guard _panelGuard = new Guard("Demigod panel"); private readonly Guard _barGuard = new Guard("Ability bar"); private readonly Guard _metersGuard = new Guard("Energy and XP bars"); private readonly Guard _companionsGuard = new Guard("Companion bars"); private readonly Guard _iconsGuard = new Guard("God icons"); private readonly Guard _overlayGuard = new Guard("HUD layout"); private readonly Guard _godCheckGuard = new Guard("God change check"); private readonly Guard _hostGuard = new Guard("Demigod Panel (frame)", shared: false, keepTrying: true); private readonly Guard _hostLateGuard = new Guard("Demigod Panel (late frame)", shared: false, keepTrying: true); public static bool Available { get { if ((Object)(object)_instance != (Object)null && _instance._panel != null && !_instance._panelGuard.Off) { return _instance._hostGuard.Ready; } return false; } } public static bool MetersAvailable { get { if ((Object)(object)_instance != (Object)null && !_instance._metersGuard.Off) { return !_instance._metersRecovering; } return false; } } public static bool BarShows(DemigodAbility ability) { if ((Object)(object)_instance != (Object)null && _instance._barGuard.Ready && Plugin.Enabled.Value) { return _instance._bar.Shows(ability); } return false; } public static bool OpenPantheon() { if (!Available || !_instance._panelGuard.Ready || !Plugin.Enabled.Value) { return false; } _instance._panel.Open(2); return _instance._panel.IsOpen; } private void Awake() { _instance = this; Guard.ResetShared(); _overlay = new LayoutOverlay(_bar, _meters, _companions); TryBuildPanel(); Plugin.Enabled.SettingChanged += OnEnabledChanged; Plugin.ShowSpecialAttacks.SettingChanged += MarkBarDirty; Plugin.BarOffset.SettingChanged += ApplyBarLayout; Plugin.BarScale.SettingChanged += ApplyBarLayout; Plugin.CompanionsOffset.SettingChanged += ApplyBarLayout; Plugin.CompanionsScale.SettingChanged += ApplyBarLayout; Plugin.MetersOffset.SettingChanged += ApplyBarLayout; Plugin.MetersScale.SettingChanged += ApplyBarLayout; Plugin.Meters.SettingChanged += OnMeterStyleChanged; Plugin.ShowEnergyBar.SettingChanged += OnMeterBarsChanged; Plugin.ShowXpBar.SettingChanged += OnMeterBarsChanged; Plugin.EnergyBarWidth.SettingChanged += OnMeterBarsChanged; Plugin.XpBarWidth.SettingChanged += OnMeterBarsChanged; Plugin.CompanionBarWidth.SettingChanged += OnCompanionWidthChanged; try { NdBridge.WatchNdConfig(OnNdConfigChanged); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not follow Norse Demigods' setting changes: " + ex.Message)); } RunestoneRules.Apply(); ApplyNdMeters(); ((MonoBehaviour)this).StartCoroutine(Prewarm()); } private IEnumerator Prewarm() { while ((Object)(object)Player.m_localPlayer == (Object)null || NdEvents.Pending || _panel == null) { yield return null; } try { UiFonts.Warm(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Prewarm fonts: " + ex.Message)); } yield return null; if (_panel != null && _panelGuard.Ready && Plugin.Enabled.Value) { yield return ((MonoBehaviour)this).StartCoroutine(_panel.WarmUp()); } try { Demigod val = NdBridge.GodOf(Player.m_localPlayer); if ((Object)(object)val != (Object)null) { FigureView.Portrait(val.DemigodName); } if (Plugin.Enabled.Value) { _overlay.Warm(); } } catch (Exception ex2) { Plugin.Log.LogDebug((object)("Prewarm: " + ex2.Message)); } List list = new List(); try { list.AddRange(NdBridge.Gods()); } catch (Exception ex3) { Plugin.Log.LogDebug((object)("Prewarm: " + ex3.Message)); } foreach (GodInfo g in list) { yield return null; if (!Plugin.Enabled.Value) { yield break; } try { AbilityView.GodIcon(g.Key); FigureView.Portrait(g.Key); } catch (Exception) { } DemigodDefaults defaults = g.Defaults; if (((defaults != null) ? defaults.DefaultAbilities : null) == null) { continue; } foreach (DemigodAbility a in g.Defaults.DefaultAbilities) { yield return null; try { AbilityView.Icon(a, g.Key); } catch (Exception) { } } } } private void TryBuildPanel() { DemigodPanelView demigodPanelView = new DemigodPanelView(); try { demigodPanelView.Build(); _panel = demigodPanelView; RunestoneRules.Apply(); } catch (Exception ex) { Quietly(demigodPanelView.Destroy); if (_panelGuard.Fail(ex)) { PanelLost(); } } } private void OnDestroy() { Plugin.Enabled.SettingChanged -= OnEnabledChanged; Plugin.ShowSpecialAttacks.SettingChanged -= MarkBarDirty; Plugin.BarOffset.SettingChanged -= ApplyBarLayout; Plugin.BarScale.SettingChanged -= ApplyBarLayout; Plugin.CompanionsOffset.SettingChanged -= ApplyBarLayout; Plugin.CompanionsScale.SettingChanged -= ApplyBarLayout; Plugin.MetersOffset.SettingChanged -= ApplyBarLayout; Plugin.MetersScale.SettingChanged -= ApplyBarLayout; Plugin.Meters.SettingChanged -= OnMeterStyleChanged; Plugin.ShowEnergyBar.SettingChanged -= OnMeterBarsChanged; Plugin.ShowXpBar.SettingChanged -= OnMeterBarsChanged; Plugin.EnergyBarWidth.SettingChanged -= OnMeterBarsChanged; Plugin.XpBarWidth.SettingChanged -= OnMeterBarsChanged; Plugin.CompanionBarWidth.SettingChanged -= OnCompanionWidthChanged; Quietly(UnwatchNd); Quietly(GodIcons.Restore); Quietly(_overlay.Destroy); Quietly(_companions.Destroy); Quietly(_meters.Destroy); Quietly(_bar.Destroy); if (_panel != null) { Quietly(_panel.Destroy); } if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } RunestoneRules.Apply(); GodChosenMessage.Restore(); Quietly(HuginTip.Restore); ApplyNdMeters(); } private void UnwatchNd() { NdBridge.UnwatchNdConfig(OnNdConfigChanged); } private static void Quietly(Action action) { try { action(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Cleanup step failed: " + ex.Message)); } } private static void ApplyNdMeters() { try { NdMeters.ApplyVisibility(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Norse Demigods' meters not updated: " + ex.Message)); } } private void OnEnabledChanged(object sender, EventArgs e) { if (!Plugin.Enabled.Value) { Quietly(GodIcons.Restore); GodChosenMessage.Restore(); Quietly(HuginTip.Restore); } RunestoneRules.Apply(); ApplyNdMeters(); _barDirty = true; } private void OnMeterStyleChanged(object sender, EventArgs e) { ApplyNdMeters(); } private void OnMeterBarsChanged(object sender, EventArgs e) { _meters.MarkLayoutDirty(); } private void OnCompanionWidthChanged(object sender, EventArgs e) { _companions.Destroy(); } private void MarkBarDirty(object sender, EventArgs e) { _barDirty = true; } private void ApplyBarLayout(object sender, EventArgs e) { _bar.ApplyLayout(); _meters.ApplyLayout(); _companions.ApplyLayout(); } private void OnNdConfigChanged(object sender, SettingChangedEventArgs e) { object obj; if (e == null) { obj = null; } else { ConfigEntryBase changedSetting = e.ChangedSetting; obj = ((changedSetting != null) ? changedSetting.Definition : null); } ConfigDefinition val = (ConfigDefinition)obj; if (!(val == (ConfigDefinition)null) && !val.Key.Contains("Meter")) { NdEvents.MarkConfigChanged(); if (val.Section == "(Hotkeys)" || val.Key.Contains("Cooldown") || val.Key.Contains("Energy Cost") || val.Key.Contains("Eitr Cost") || val.Key.StartsWith("Enable Teleport")) { _barDirty = true; } } } private void Update() { Perf.Frame(Time.time); if (!_hostGuard.Ready) { return; } try { long before = Perf.NetBegin(); Frame(); Perf.NetEnd(Perf.Scope.HostFrame, before); } catch (Exception ex) { _hostGuard.Fail(ex); } } private void Frame() { long start = Perf.Begin(); long mem = Perf.BeginMem(); Player localPlayer = Player.m_localPlayer; if (!Plugin.Enabled.Value || (Object)(object)localPlayer == (Object)null) { HideAll(); } else { Demigod god = GodOrNull(localPlayer); CheckGod(god); RunPanel(localPlayer); RunBar(localPlayer, god); if (!NdEvents.Pending) { RunMeters(localPlayer, god); RunCompanions(localPlayer, god); RunIcons(localPlayer, god); } RunOverlay(localPlayer); if (_layoutGuard.Ready) { try { CheckHudSize(); } catch (Exception ex) { _layoutGuard.Fail(ex); } } } Perf.End(Perf.Scope.HostFrame, start, mem); } private void LateUpdate() { if (_hostLateGuard.Ready) { try { long start = Perf.Begin(); long mem = Perf.BeginMem(); long before = Perf.NetBegin(); Late(); Perf.NetEnd(Perf.Scope.HostLate, before); Perf.End(Perf.Scope.HostLate, start, mem); } catch (Exception ex) { _hostLateGuard.Fail(ex); } } Perf.CountCanvasRebuilds(); } private void Late() { if (_panel != null && _panelGuard.Ready) { try { _panel.LateUpdate(); } catch (Exception ex) { PanelFailed(ex); } } if (_overlayGuard.Ready) { try { _overlay.LateUpdate(); } catch (Exception ex2) { OverlayFailed(ex2); } } } private void CheckGod(Demigod god) { _observeTimer -= Time.deltaTime; if (_observeTimer > 0f || !_godCheckGuard.Ready) { return; } _observeTimer = 0.1f; try { long start = Perf.Begin(); long mem = Perf.BeginMem(); NdEvents.Observe(god); Perf.End(Perf.Scope.GodCheck, start, mem); } catch (Exception ex) { _godCheckGuard.Fail(ex); } } private void CheckHudSize() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) _hudSizeTimer -= Time.deltaTime; if (_hudSizeTimer > 0f) { return; } _hudSizeTimer = 1f; RectTransform val = (RectTransform)(((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if (!((Object)(object)val == (Object)null)) { Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; if (size != _hudSize) { _hudSize = size; ApplyBarLayout(null, EventArgs.Empty); } } } private static Demigod GodOrNull(Player player) { try { return NdBridge.GodOf(player); } catch (Exception) { return null; } } private void RunPanel(Player player) { if (!_panelGuard.Ready) { return; } if (_panel == null) { TryBuildPanel(); return; } try { HandleKeys(); _panel.Update(player, Time.deltaTime); } catch (Exception ex) { PanelFailed(ex); } } private void RunBar(Player player, Demigod god) { if (!_barGuard.Ready) { return; } try { UpdateBar(player, god); } catch (Exception ex) { BarFailed(ex); } } private void BarFailed(Exception ex) { _barGuard.Fail(ex); _barDirty = true; Quietly(_bar.Destroy); } private void RunMeters(Player player, Demigod god) { if (!_metersGuard.Ready) { return; } try { long start = Perf.Begin(); long mem = Perf.BeginMem(); _meters.Update(player, god, Time.deltaTime); Perf.End(Perf.Scope.Meters, start, mem); if (_metersRecovering) { _metersRecovering = false; ApplyNdMeters(); } } catch (Exception ex) { MetersFailed(ex); } } private void MetersFailed(Exception ex) { _metersGuard.Fail(ex); Quietly(_meters.Destroy); _metersRecovering = true; ApplyNdMeters(); } private void RunCompanions(Player player, Demigod god) { if (!_companionsGuard.Ready) { return; } try { _companions.Update(player, god, NdEvents.Version, Time.deltaTime); } catch (Exception ex) { CompanionsFailed(ex); } } private void CompanionsFailed(Exception ex) { _companionsGuard.Fail(ex); Quietly(_companions.Destroy); } private void RunIcons(Player player, Demigod god) { _godIconTimer -= Time.deltaTime; if (_godIconTimer > 0f || !_iconsGuard.Ready) { return; } _godIconTimer = 0.5f; try { long start = Perf.Begin(); long mem = Perf.BeginMem(); GodIcons.Refresh(player, god); Perf.End(Perf.Scope.Icons, start, mem); } catch (Exception ex) { IconsFailed(ex); } } private void IconsFailed(Exception ex) { if (_iconsGuard.Fail(ex)) { Quietly(GodIcons.Restore); } } private void RunOverlay(Player player) { if (!_overlayGuard.Ready) { return; } try { _overlay.Update(!((Character)player).IsDead() && (_panel == null || !_panel.IsOpen)); } catch (Exception ex) { OverlayFailed(ex); } } private void HideAll() { if (_panel != null && _panel.IsOpen) { ClosePanel(); } try { _overlay.Close(); } catch (Exception ex) { OverlayFailed(ex); } if (_barGuard.Ready) { try { _bar.SetVisible(visible: false); } catch (Exception ex2) { BarFailed(ex2); } } if (_companionsGuard.Ready) { try { _companions.Update(null, null, NdEvents.Version, 0f); } catch (Exception ex3) { _companionsGuard.Fail(ex3); } } if (_metersGuard.Ready) { try { _meters.Update(null, null, 0f); } catch (Exception ex4) { _metersGuard.Fail(ex4); } } } private void PanelFailed(Exception ex) { if (_panel != null) { Quietly(_panel.Close); } if (_panelGuard.Fail(ex)) { PanelLost(); } } private static void PanelLost() { RunestoneRules.Apply(); GodChosenMessage.Restore(); Quietly(HuginTip.Restore); } private void OverlayFailed(Exception ex) { Quietly(_overlay.Close); _overlayGuard.Fail(ex); } private void HandleKeys() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!_panel.IsOpen && !_panel.ToggledThisFrame && Utils.Pressed(Plugin.PanelKey.Value) && Utils.HotkeysAllowed()) { OpenPanel(); } } private void OpenPanel() { Quietly(_overlay.Close); _panel.Open(); } private void ClosePanel() { Quietly(_panel.Close); } private void UpdateBar(Player player, Demigod god) { if (!NdEvents.Pending && (_barDirty || _barVersion != NdEvents.Version || (_bar.HasGod && (Object)(object)god == (Object)null))) { _barDirty = false; _barVersion = NdEvents.Version; _bar.Rebuild(god); } _bar.SetVisible(Plugin.ShowAbilityBar.Value && !((Character)player).IsDead()); _bar.Update(player, Time.deltaTime); } } internal static class UiKit { public static readonly Color Orange = new Color(1f, 0.631f, 0.235f, 1f); public static readonly Color Gold = new Color(0.95f, 0.82f, 0.55f, 1f); public static readonly Color Muted = new Color(0.72f, 0.7f, 0.66f, 1f); public static readonly Color Ice = new Color(0.62f, 0.85f, 1f, 1f); public static readonly Color Warn = new Color(1f, 0.45f, 0.3f, 1f); public static readonly Color InsetTint = new Color(0f, 0f, 0f, 0.38f); public static readonly Color Row = new Color(1f, 1f, 1f, 0.05f); public static readonly Color RowSelected = new Color(1f, 0.631f, 0.235f, 0.22f); public static readonly Color RowHover = new Color(1f, 0.85f, 0.6f, 0.1f); private static Sprite _white; private static Material _hudTextMaterial; internal static readonly Guard Clicks = new Guard("Panel buttons", shared: true); internal static readonly Guard Hovers = new Guard("Panel tooltips", shared: true); public static Sprite White { get { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_white == (Object)null) { _white = Sprite.Create(Texture2D.whiteTexture, new Rect(0f, 0f, 4f, 4f), new Vector2(0.5f, 0.5f)); } return _white; } } public static Sprite Vanilla(string name) { return GUIManager.Instance.GetSprite(name); } public static Vector2 OnScreen(RectTransform element, Vector2 offset) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(((Object)(object)element != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val == (Object)null) { return offset; } Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; rect = element.rect; Vector2 size2 = ((Rect)(ref rect)).size; Vector3 localScale = ((Transform)element).localScale; Vector2 pivot = element.pivot; HudClamp.Clamp(offset.x, offset.y, size2.x * Mathf.Abs(localScale.x), size2.y * Mathf.Abs(localScale.y), pivot.x, pivot.y, size.x, size.y, out var cx, out var cy); return new Vector2(cx, cy); } public static RectTransform Box(Transform parent, string name, float x, float y, float w, float h) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown Perf.CountCreated(); RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent(parent, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f, 1f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = new Vector2(0f, 1f); val.anchoredPosition = new Vector2(x, 0f - y); val.sizeDelta = new Vector2(w, h); return val; } public static RectTransform Fill(RectTransform rt, float margin = 0f) { //IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.pivot = new Vector2(0.5f, 0.5f); rt.offsetMin = new Vector2(margin, margin); rt.offsetMax = new Vector2(0f - margin, 0f - margin); return rt; } public static Image Image(Transform parent, string name, Sprite sprite, Color color, bool sliced = false) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) Perf.CountCreated(); GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); Image component = val.GetComponent(); component.sprite = sprite; ((Graphic)component).color = color; component.type = (Type)((sliced && (Object)(object)sprite != (Object)null && sprite.border != Vector4.zero) ? 1 : 0); ((Graphic)component).raycastTarget = false; return component; } public static Image Inset(Transform parent, string name, float x, float y, float w, float h) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)Box(parent, name, x, y, w, h)).gameObject.AddComponent(); obj.sprite = White; ((Graphic)obj).color = InsetTint; ((Graphic)obj).raycastTarget = false; return obj; } public static Text Text(Transform parent, string text, int size, Color color, TextAnchor align, float x, float y, float w, float h, bool bold = false, bool norse = false, bool outline = false) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) Perf.CountCreated(); GUIManager instance = GUIManager.Instance; Font val = ((!norse) ? (bold ? instance.AveriaSerifBold : instance.AveriaSerif) : (bold ? instance.NorseBold : instance.Norse)); GameObject obj = instance.CreateText(text, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, val, size, color, outline, Color.black, w, h, false); RectTransform val2 = (RectTransform)obj.transform; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); Text component = obj.GetComponent(); component.alignment = align; component.supportRichText = true; ((Graphic)component).raycastTarget = false; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; return component; } public static TextMeshProUGUI PanelText(Transform parent, string name, string text, float size, Color color, TextAlignmentOptions align, float x, float y, float w, float h, bool bold = false) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Perf.CountCreated(); GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(parent, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); val2.sizeDelta = new Vector2(w, h); TextMeshProUGUI val4 = val.AddComponent(); TMP_FontAsset body = UiFonts.Body; if ((Object)(object)body != (Object)null) { ((TMP_Text)val4).font = body; } ((TMP_Text)val4).fontSize = size; ((TMP_Text)val4).fontStyle = (FontStyles)(bold ? 1 : 0); ((Graphic)val4).color = color; ((TMP_Text)val4).alignment = align; ((TMP_Text)val4).richText = true; ((TMP_Text)val4).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val4).overflowMode = (TextOverflowModes)1; ((Graphic)val4).raycastTarget = false; ((TMP_Text)val4).text = text; val.SetActive(true); return val4; } public static TextMeshProUGUI Tmp(Transform parent, string name, string text, float size, Color color, TextAlignmentOptions align, float x, float y, float w, float h) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Perf.CountCreated(); GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(parent, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(x, 0f - y); val2.sizeDelta = new Vector2(w, h); TextMeshProUGUI val4 = val.AddComponent(); TMP_FontAsset tMP_AveriaSansLibre = GUIManager.Instance.TMP_AveriaSansLibre; if ((Object)(object)tMP_AveriaSansLibre != (Object)null) { ((TMP_Text)val4).font = tMP_AveriaSansLibre; Material val5 = HudTextMaterial(tMP_AveriaSansLibre); if (val5.HasProperty("_OutlineWidth")) { ((TMP_Text)val4).fontSharedMaterial = val5; } else { ((TMP_Text)val4).outlineWidth = 0.24f; ((TMP_Text)val4).outlineColor = Color32.op_Implicit(Color.black); } } ((TMP_Text)val4).fontSize = size; ((TMP_Text)val4).fontStyle = (FontStyles)1; ((Graphic)val4).color = color; ((TMP_Text)val4).alignment = align; ((TMP_Text)val4).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val4).overflowMode = (TextOverflowModes)0; ((Graphic)val4).raycastTarget = false; ((TMP_Text)val4).text = text; val.SetActive(true); return val4; } private static Material HudTextMaterial(TMP_FontAsset font) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hudTextMaterial != (Object)null && (Object)(object)_hudTextMaterial.mainTexture == (Object)(object)font.atlasTexture) { return _hudTextMaterial; } _hudTextMaterial = new Material(((TMP_Asset)font).material) { name = "DemigodPanel HUD Text" }; _hudTextMaterial.EnableKeyword("OUTLINE_ON"); _hudTextMaterial.SetFloat("_OutlineWidth", 0.24f); _hudTextMaterial.SetColor("_OutlineColor", Color.black); _hudTextMaterial.SetFloat("_FaceDilate", 0.12f); _hudTextMaterial.EnableKeyword("UNDERLAY_ON"); _hudTextMaterial.SetColor("_UnderlayColor", new Color(0f, 0f, 0f, 0.55f)); _hudTextMaterial.SetFloat("_UnderlayOffsetX", 0.5f); _hudTextMaterial.SetFloat("_UnderlayOffsetY", -0.6f); _hudTextMaterial.SetFloat("_UnderlaySoftness", 0.35f); return _hudTextMaterial; } public static Button Button(Transform parent, string label, float x, float y, float w, float h, Action onClick) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown Perf.CountCreated(); GameObject obj = GUIManager.Instance.CreateButton(label, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, w, h); RectTransform val = (RectTransform)obj.transform; val.pivot = new Vector2(0f, 1f); val.anchoredPosition = new Vector2(x, 0f - y); Button component = obj.GetComponent