using Dalamud.Game.ClientState.JobGauge.Types; using Dalamud.Game.ClientState.Objects.SubKinds; using HSUI.Config; using HSUI.Config.Attributes; using HSUI.Helpers; using HSUI.Interface.Bars; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using HSUI.Interface.GeneralElements; namespace HSUI.Interface.Jobs { public class WarriorHud : JobHud { private new WarriorConfig Config => (WarriorConfig)_config; public WarriorHud(WarriorConfig config, string? displayName = null) : base(config, displayName) { } protected override (List, List) ChildrenPositionsAndSizes() { List positions = new(); List sizes = new(); if (Config.SurgingTempestBar.Enabled) { positions.Add(Config.Position + Config.SurgingTempestBar.Position); sizes.Add(Config.SurgingTempestBar.Size); } if (Config.BeastGauge.Enabled) { positions.Add(Config.Position + Config.BeastGauge.Position); sizes.Add(Config.BeastGauge.Size); } if (Config.InnerReleaseBar.Enabled) { positions.Add(Config.Position + Config.InnerReleaseBar.Position); sizes.Add(Config.InnerReleaseBar.Size); } return (positions, sizes); } public override void DrawJobHud(Vector2 origin, IPlayerCharacter player) { Vector2 pos = origin + Config.Position; if (Config.SurgingTempestBar.Enabled) { DrawSurgingTempestBar(pos, player); } if (Config.BeastGauge.Enabled) { DrawBeastGauge(pos, player); } if (Config.InnerReleaseBar.Enabled) { DrawInnerReleaseBar(pos, player); } } private void DrawSurgingTempestBar(Vector2 origin, IPlayerCharacter player) { float surgingTempestDuration = Math.Abs(Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2677)?.RemainingTime ?? 0f); if (!Config.SurgingTempestBar.HideWhenInactive || surgingTempestDuration > 0) { Config.SurgingTempestBar.Label.SetValue(surgingTempestDuration); BarHud bar = BarUtilities.GetProgressBar(Config.SurgingTempestBar, surgingTempestDuration, 60f, 0, player); AddDrawActions(bar.GetDrawActions(origin, Config.SurgingTempestBar.StrataLevel)); } } private void DrawBeastGauge(Vector2 origin, IPlayerCharacter player) { WARGauge gauge = Plugin.JobGauges.Get(); var nascentChaosDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1897)?.RemainingTime ?? 0f; if (!Config.BeastGauge.HideWhenInactive || gauge.BeastGauge > 0 || nascentChaosDuration > 0) { Config.BeastGauge.Label.SetValue(gauge.BeastGauge); var color = nascentChaosDuration == 0 ? Config.BeastGauge.BeastGaugeColor : Config.BeastGauge.NascentChaosColor; BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.BeastGauge, 2, gauge.BeastGauge, 100, 0, player, fillColor: color); foreach (BarHud bar in bars) { AddDrawActions(bar.GetDrawActions(origin, Config.BeastGauge.StrataLevel)); } } } private void DrawInnerReleaseBar(Vector2 origin, IPlayerCharacter player) { var innerReleaseStatus = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1177 or 86); float innerReleaseDuration = Math.Max(innerReleaseStatus?.RemainingTime ?? 0f, 0f); int innerReleaseStacks = innerReleaseStatus?.Param ?? 0; BarGlowConfig? primalRendGlow = null; if (Config.InnerReleaseBar.PrimalRendReadyGlowConfig.Enabled) { bool isPrimalRendReady = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2624)?.RemainingTime > 0; if (isPrimalRendReady) { primalRendGlow = Config.InnerReleaseBar.PrimalRendReadyGlowConfig; } } if (innerReleaseStacks == 0 && Config.InnerReleaseBar.ShowCooldown) { uint spellID = 7389; float maxDuration = SpellHelper.Instance.GetRecastTime(spellID); float cooldown = SpellHelper.Instance.GetSpellCooldown(spellID); float currentCooldown = maxDuration - cooldown; Config.InnerReleaseBar.Label.SetValue(maxDuration - currentCooldown); if (currentCooldown == maxDuration) { if (!Config.InnerReleaseBar.HideWhenInactive) { BarHud[] bars = BarUtilities.GetChunkedProgressBars( Config.InnerReleaseBar, 1, 1, 1, 0, player, fillColor: Config.InnerReleaseBar.CooldownFinishedColor, glowConfig: primalRendGlow, chunksToGlow: new[] { true } ); foreach (BarHud bar in bars) { AddDrawActions(bar.GetDrawActions(origin, Config.InnerReleaseBar.StrataLevel)); } } } else { BarHud[] bars = BarUtilities.GetChunkedProgressBars( Config.InnerReleaseBar, 1, currentCooldown, maxDuration, 0, player, fillColor: Config.InnerReleaseBar.CooldownInProgressColor, glowConfig: primalRendGlow, chunksToGlow: new[] { true } ); foreach (BarHud bar in bars) { AddDrawActions(bar.GetDrawActions(origin, Config.InnerReleaseBar.StrataLevel)); } } return; } if (!Config.InnerReleaseBar.HideWhenInactive || innerReleaseStacks > 0) { float innerReleaseMaxDuration = 15f; var chunks = new Tuple[3]; for (int i = 0; i < 3; i++) { chunks[i] = new(Config.InnerReleaseBar.FillColor, i < innerReleaseStacks ? 1 : 0, i == 1 ? Config.InnerReleaseBar.Label : null); } innerReleaseDuration = !Config.InnerReleaseBar.ShowBuffTimerOnActiveChunk ? innerReleaseMaxDuration : Math.Min(innerReleaseDuration, innerReleaseMaxDuration); Config.InnerReleaseBar.Label.SetValue(innerReleaseDuration); BarHud[] bars = BarUtilities.GetChunkedBars(Config.InnerReleaseBar, chunks, player, primalRendGlow, new[] { true, true, true }); foreach (BarHud bar in bars) { AddDrawActions(bar.GetDrawActions(origin, Config.InnerReleaseBar.StrataLevel)); } } } } [Section("Job Specific Bars")] [SubSection("Tank", 0)] [SubSection("Warrior", 1)] public class WarriorConfig : JobConfig { [JsonIgnore] public override uint JobId => JobIDs.WAR; public new static WarriorConfig DefaultConfig() { var config = new WarriorConfig(); config.BeastGauge.UsePartialFillColor = true; config.InnerReleaseBar.LabelMode = LabelMode.ActiveChunk; config.InnerReleaseBar.PrimalRendReadyGlowConfig.Color = new PluginConfigColor(new Vector4(246f / 255f, 30f / 255f, 136f / 255f, 100f / 100f)); return config; } [NestedConfig("Surging Tempest Bar", 30)] public ProgressBarConfig SurgingTempestBar = new ProgressBarConfig( new(0, -32), new(254, 20), new PluginConfigColor(new Vector4(255f / 255f, 136f / 255f, 146f / 255f, 100f / 100f)) ); [NestedConfig("Beast Gauge", 35)] public WarriorBeastGaugeConfig BeastGauge = new WarriorBeastGaugeConfig( new(0, -10), new(254, 20), new PluginConfigColor(new Vector4(0, 0, 0, 0)) ); [NestedConfig("Inner Release Bar", 40)] public WarriorInnerReleaseBarConfig InnerReleaseBar = new WarriorInnerReleaseBarConfig( new(0, -54), new(254, 20), new PluginConfigColor(new Vector4(255f / 255f, 136f / 255f, 146f / 255f, 100f / 100f)) ); } [DisableParentSettings("FillColor")] [Exportable(false)] public class WarriorBeastGaugeConfig : ChunkedProgressBarConfig { [ColorEdit4("Beast Gauge Color", spacing = true)] [Order(65)] public PluginConfigColor BeastGaugeColor = new(new Vector4(201f / 255f, 13f / 255f, 13f / 255f, 100f / 100f)); [ColorEdit4("Nascent Chaos Color")] [Order(70)] public PluginConfigColor NascentChaosColor = new(new Vector4(240f / 255f, 176f / 255f, 0f / 255f, 100f / 100f)); public WarriorBeastGaugeConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor) { } } [Exportable(false)] public class WarriorInnerReleaseBarConfig : ChunkedProgressBarConfig { [Checkbox("Show Buff Timer On Active Chunk", spacing = true)] [Order(80)] public bool ShowBuffTimerOnActiveChunk; [Checkbox("Show Inner Release Cooldown", spacing = true)] [Order(85)] public bool ShowCooldown; [ColorEdit4("Inner Release On Cooldown Color")] [Order(90)] public PluginConfigColor CooldownInProgressColor = new(new Vector4(240f / 255f, 176f / 255f, 0f / 255f, 100f / 100f)); [ColorEdit4("Inner Release Ready Color")] [Order(95)] public PluginConfigColor CooldownFinishedColor = new(new Vector4(38f / 255f, 192f / 255f, 94f / 255f, 100f / 100f)); [NestedConfig("Glow Color (when Primal Rend is ready)", 100, separator = false, spacing = true)] public BarGlowConfig PrimalRendReadyGlowConfig = new(); public WarriorInnerReleaseBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor) { } } }