Initial release: HSUI v1.0.0.0 - HUD replacement with configurable hotbars

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-01-30 23:52:46 -05:00
commit f37369cdda
202 changed files with 40137 additions and 0 deletions
+273
View File
@@ -0,0 +1,273 @@
using Dalamud.Game.ClientState.JobGauge.Enums;
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.Game;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class AstrologianHud : JobHud
{
private readonly SpellHelper _spellHelper = new();
private new AstrologianConfig Config => (AstrologianConfig)_config;
private static PluginConfigColor EmptyColor => GlobalColors.Instance.EmptyColor;
private static readonly List<uint> DotIDs = new() { 1881, 843, 838 };
private static readonly List<float> DotDuration = new() { 30f, 30f, 18f };
private const float STAR_MAX_DURATION = 10f;
private const float LIGHTSPEED_MAX_DURATION = 15f;
public AstrologianHud(JobConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.CardsBar.Enabled)
{
positions.Add(Config.Position + Config.CardsBar.Position);
sizes.Add(Config.CardsBar.Size);
}
if (Config.DotBar.Enabled)
{
positions.Add(Config.Position + Config.DotBar.Position);
sizes.Add(Config.DotBar.Size);
}
if (Config.StarBar.Enabled)
{
positions.Add(Config.Position + Config.StarBar.Position);
sizes.Add(Config.StarBar.Size);
}
if (Config.LightspeedBar.Enabled)
{
positions.Add(Config.Position + Config.LightspeedBar.Position);
sizes.Add(Config.LightspeedBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.CardsBar.Enabled)
{
DrawCardsBar(pos, player);
}
if (Config.DotBar.Enabled)
{
DrawDot(pos, player);
}
if (Config.LightspeedBar.Enabled)
{
DrawLightspeed(pos, player);
}
if (Config.StarBar.Enabled)
{
DrawStar(pos, player);
}
}
private unsafe void DrawCardsBar(Vector2 origin, IPlayerCharacter player)
{
AstrologianCardsBarConfig config = Config.CardsBar;
PluginConfigColor emptyColor = PluginConfigColor.Empty;
List<Tuple<PluginConfigColor, float, LabelConfig?>> chunks = new();
uint play1 = ActionManager.Instance()->GetAdjustedActionId(37019);
PluginConfigColor play1Color = play1 == 37023 ? config.TheBalanceColor : (play1 == 37026 ? config.TheSpearColor : emptyColor);
chunks.Add(new(play1Color, 1, null));
uint play2 = ActionManager.Instance()->GetAdjustedActionId(37020);
PluginConfigColor play2Color = play2 == 37024 ? config.TheArrowColor : (play2 == 37027 ? config.TheBoleColor : emptyColor);
chunks.Add(new(play2Color, 1, null));
uint play3 = ActionManager.Instance()->GetAdjustedActionId(37021);
PluginConfigColor play3Color = play3 == 37025 ? config.TheSpireColor : (play3 == 37028 ? config.TheEwerColor : emptyColor);
chunks.Add(new(play3Color, 1, null));
if (player.Level >= 70)
{
uint minorArcana = ActionManager.Instance()->GetAdjustedActionId(37022);
PluginConfigColor minorArcanaColor = minorArcana == 7444 ? config.TheLordOfCrownsColor : (minorArcana == 7445 ? config.TheLadyOfCrownsColor : emptyColor);
chunks.Add(new(minorArcanaColor, 1, null));
}
BarHud[] bars = BarUtilities.GetChunkedBars(config, chunks.ToArray(), player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private void DrawDot(Vector2 origin, IPlayerCharacter player)
{
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.DotBar, player, target, DotIDs, DotDuration);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DotBar.StrataLevel));
}
}
private void DrawLightspeed(Vector2 origin, IPlayerCharacter player)
{
float lightspeedDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 841 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (Config.LightspeedBar.HideWhenInactive && lightspeedDuration <= 0)
{
return;
}
Config.LightspeedBar.Label.SetValue(lightspeedDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.LightspeedBar, lightspeedDuration, LIGHTSPEED_MAX_DURATION, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.LightspeedBar.StrataLevel));
}
private void DrawStar(Vector2 origin, IPlayerCharacter player)
{
float starPreCookingBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1224 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
float starPostCookingBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1248 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (Config.StarBar.HideWhenInactive && starPostCookingBuff <= 0f && starPreCookingBuff <= 0f)
{
return;
}
float currentStarDuration = starPreCookingBuff > 0 ? STAR_MAX_DURATION - Math.Abs(starPreCookingBuff) : Math.Abs(starPostCookingBuff);
PluginConfigColor currentStarColor = starPreCookingBuff > 0 ? Config.StarBar.StarEarthlyColor : Config.StarBar.StarGiantColor;
Config.StarBar.Label.SetValue(currentStarDuration);
// Star Countdown after Star is ready
BarHud bar = BarUtilities.GetProgressBar(Config.StarBar, currentStarDuration, STAR_MAX_DURATION, 0f, player, currentStarColor, Config.StarBar.StarGlowConfig.Enabled && starPostCookingBuff > 0 ? Config.StarBar.StarGlowConfig : null);
AddDrawActions(bar.GetDrawActions(origin, Config.StarBar.StrataLevel));
}
}
[Section("Job Specific Bars")]
[SubSection("Healer", 0)]
[SubSection("Astrologian", 1)]
public class AstrologianConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.AST;
public new static AstrologianConfig DefaultConfig()
{
var config = new AstrologianConfig();
config.UseDefaultPrimaryResourceBar = true;
return config;
}
[NestedConfig("Cards Bar", 40)]
public AstrologianCardsBarConfig CardsBar = new(
new Vector2(0, 0),
new Vector2(254, 20)
);
[NestedConfig("Dot Bar", 40)]
public ProgressBarConfig DotBar = new(
new Vector2(-85, -29),
new Vector2(84, 14),
new PluginConfigColor(new Vector4(20f / 255f, 80f / 255f, 168f / 255f, 255f / 100f))
);
[NestedConfig("Star Bar", 45)]
public AstrologianStarBarConfig StarBar = new(
new Vector2(0, -29),
new Vector2(84, 14)
);
[NestedConfig("Lightspeed Bar", 50)]
public ProgressBarConfig LightspeedBar = new(
new Vector2(85, -29),
new Vector2(84, 14),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 173f / 255f, 100f / 100f))
);
}
[Exportable(false)]
[DisableParentSettings("FillColor", "UsePartialFillColor", "UseChunks", "PartialFillColor", "LabelMode", "HideWhenInactive")]
public class AstrologianCardsBarConfig : ChunkedBarConfig
{
[ColorEdit4("The Balance Color", spacing = true)]
[Order(201)]
public PluginConfigColor TheBalanceColor = PluginConfigColor.FromHex(0xFFBE423F);
[ColorEdit4("The Arrow Color")]
[Order(201)]
public PluginConfigColor TheArrowColor = PluginConfigColor.FromHex(0xFF628AA7);
[ColorEdit4("The Spire Color")]
[Order(201)]
public PluginConfigColor TheSpireColor = PluginConfigColor.FromHex(0xFFC8A348);
[ColorEdit4("The Spear Color")]
[Order(201)]
public PluginConfigColor TheSpearColor = PluginConfigColor.FromHex(0xFF5673DF);
[ColorEdit4("The Bole Color")]
[Order(201)]
public PluginConfigColor TheBoleColor = PluginConfigColor.FromHex(0xFF9ACB77);
[ColorEdit4("The Ewer Color")]
[Order(201)]
public PluginConfigColor TheEwerColor = PluginConfigColor.FromHex(0xFF7FBDFF);
[ColorEdit4("The Lord of Crowns Color")]
[Order(201)]
public PluginConfigColor TheLordOfCrownsColor = PluginConfigColor.FromHex(0xFFCA3640);
[ColorEdit4("The Lady of Crowns Color")]
[Order(201)]
public PluginConfigColor TheLadyOfCrownsColor = PluginConfigColor.FromHex(0xFF974A97);
public AstrologianCardsBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
[Exportable(false)]
[DisableParentSettings("FillColor")]
public class AstrologianStarBarConfig : ProgressBarConfig
{
[ColorEdit4("Earthly" + "##Star")]
[Order(402)]
public PluginConfigColor StarEarthlyColor = new(new Vector4(37f / 255f, 181f / 255f, 177f / 255f, 100f / 100f));
[ColorEdit4("Giant" + "##Star")]
[Order(403)]
public PluginConfigColor StarGiantColor = new(new Vector4(198f / 255f, 154f / 255f, 199f / 255f, 100f / 100f));
[NestedConfig("Giant Dominance Glow" + "##Star", 404, separator = false, spacing = true)]
public BarGlowConfig StarGlowConfig = new();
public AstrologianStarBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
}
+489
View File
@@ -0,0 +1,489 @@
using Dalamud.Game.ClientState.JobGauge.Enums;
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class BardHud : JobHud
{
private readonly SpellHelper _spellHelper = new();
private new BardConfig Config => (BardConfig)_config;
private PluginConfigColor EmptyColor => GlobalColors.Instance.EmptyColor;
public BardHud(BardConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.SongGaugeBar.Enabled)
{
positions.Add(Config.Position + Config.SongGaugeBar.Position);
sizes.Add(Config.SongGaugeBar.Size);
}
if (Config.SoulVoiceBar.Enabled)
{
positions.Add(Config.Position + Config.SoulVoiceBar.Position);
sizes.Add(Config.SoulVoiceBar.Size);
}
if (Config.StacksBar.Enabled)
{
positions.Add(Config.Position + Config.StacksBar.Position);
sizes.Add(Config.StacksBar.Size);
}
if (Config.CausticBiteDoTBar.Enabled)
{
positions.Add(Config.Position + Config.CausticBiteDoTBar.Position);
sizes.Add(Config.CausticBiteDoTBar.Size);
}
if (Config.StormbiteDoTBar.Enabled)
{
positions.Add(Config.Position + Config.StormbiteDoTBar.Position);
sizes.Add(Config.StormbiteDoTBar.Size);
}
if (Config.CodaBar.Enabled)
{
positions.Add(Config.Position + Config.CodaBar.Position);
sizes.Add(Config.CodaBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.CausticBiteDoTBar.Enabled)
{
DrawCausticBiteDoTBar(pos, player);
}
if (Config.StormbiteDoTBar.Enabled)
{
DrawStormbiteDoTBar(pos, player);
}
HandleCurrentSong(pos, player);
if (Config.SoulVoiceBar.Enabled)
{
DrawSoulVoiceBar(pos, player);
}
if (Config.CodaBar.Enabled)
{
DrawCodaBar(pos, player);
}
}
private void DrawCodaBar(Vector2 origin, IPlayerCharacter player)
{
BRDGauge gauge = Plugin.JobGauges.Get<BRDGauge>();
var containsCoda = new[] { gauge.Coda.Contains(Song.Wanderer) ? 1 : 0, gauge.Coda.Contains(Song.Mage) ? 1 : 0, gauge.Coda.Contains(Song.Army) ? 1 : 0 };
bool hasCoda = containsCoda.Any(o => o == 1);
if (!Config.CodaBar.HideWhenInactive || hasCoda)
{
var order = Config.CodaBar.CodaOrder;
var colors = new[] { Config.CodaBar.WMColor, Config.CodaBar.MBColor, Config.CodaBar.APColor };
var coda = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < 3; i++)
{
coda[i] = new Tuple<PluginConfigColor, float, LabelConfig?>(colors[order[i]], containsCoda[order[i]], null);
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.CodaBar, coda, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.CodaBar.StrataLevel));
}
}
}
private static List<uint> CausticBiteDoTIDs = new List<uint> { 124, 1200 };
private static List<float> CausticBiteDoTDurations = new List<float> { 45, 45 };
protected void DrawCausticBiteDoTBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.CausticBiteDoTBar, player, target, CausticBiteDoTIDs, CausticBiteDoTDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.CausticBiteDoTBar.StrataLevel));
}
}
private static List<uint> StormbiteDoTIDs = new List<uint> { 129, 1201 };
private static List<float> StormbiteDoTDurations = new List<float> { 45, 45 };
protected void DrawStormbiteDoTBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.StormbiteDoTBar, player, target, StormbiteDoTIDs, StormbiteDoTDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.StormbiteDoTBar.StrataLevel));
}
}
private void HandleCurrentSong(Vector2 origin, IPlayerCharacter player)
{
BRDGauge gauge = Plugin.JobGauges.Get<BRDGauge>();
byte songStacks = gauge.Repertoire;
Song song = gauge.Song;
ushort songTimer = gauge.SongTimer;
switch (song)
{
case Song.Wanderer:
if (Config.StacksBar.Enabled && Config.StacksBar.ShowWMStacks)
{
DrawStacksBar(
origin,
player,
songStacks,
3,
Config.StacksBar.WMStackColor,
Config.StacksBar.WMGlowConfig.Enabled && songStacks == 3 ? Config.StacksBar.WMGlowConfig : null
);
}
DrawSongTimerBar(origin, songTimer, Config.SongGaugeBar.WMColor, Config.SongGaugeBar.WMThreshold, player);
break;
case Song.Mage:
if (Config.StacksBar.Enabled && Config.StacksBar.ShowMBProc)
{
DrawBloodletterReady(origin, player);
}
DrawSongTimerBar(origin, songTimer, Config.SongGaugeBar.MBColor, Config.SongGaugeBar.MBThreshold, player);
break;
case Song.Army:
if (Config.StacksBar.Enabled && Config.StacksBar.ShowAPStacks)
{
DrawStacksBar(origin, player, songStacks, 4, Config.StacksBar.APStackColor);
}
DrawSongTimerBar(origin, songTimer, Config.SongGaugeBar.APColor, Config.SongGaugeBar.APThreshold, player);
break;
case Song.None:
if (Config.StacksBar.Enabled && !Config.StacksBar.HideWhenInactive)
{
DrawStacksBar(origin, player, 0, 3, Config.StacksBar.WMStackColor);
}
DrawSongTimerBar(origin, 0, EmptyColor, Config.SongGaugeBar.ThresholdConfig, player);
break;
default:
if (Config.StacksBar.Enabled && !Config.StacksBar.HideWhenInactive)
{
DrawStacksBar(origin, player, 0, 3, Config.StacksBar.WMStackColor);
}
DrawSongTimerBar(origin, 0, EmptyColor, Config.SongGaugeBar.ThresholdConfig, player);
break;
}
}
private void DrawBloodletterReady(Vector2 origin, IPlayerCharacter player)
{
int maxStacks = player.Level < 84 ? 2 : 3;
int maxCooldown = maxStacks * 15;
int cooldown = _spellHelper.GetSpellCooldownInt(110);
cooldown = player.Level < 84 ? Math.Max(0, cooldown - 15) : cooldown;
int stacks = (maxCooldown - cooldown) / 15;
DrawStacksBar(origin, player, stacks, maxStacks, Config.StacksBar.MBProcColor,
Config.StacksBar.MBGlowConfig.Enabled ? Config.StacksBar.MBGlowConfig : null);
}
protected void DrawSongTimerBar(Vector2 origin, ushort songTimer, PluginConfigColor songColor, ThresholdConfig songThreshold, IPlayerCharacter player)
{
if (Config.SongGaugeBar.HideWhenInactive && songTimer == 0 || !Config.SongGaugeBar.Enabled)
{
return;
}
float duration = Math.Abs(songTimer / 1000f);
Config.SongGaugeBar.Label.SetValue(duration);
Config.SongGaugeBar.ThresholdConfig = songThreshold;
BarHud bar = BarUtilities.GetProgressBar(Config.SongGaugeBar, duration, 45f, 0f, player, songColor);
AddDrawActions(bar.GetDrawActions(origin, Config.SongGaugeBar.StrataLevel));
}
protected void DrawSoulVoiceBar(Vector2 origin, IPlayerCharacter player)
{
BardSoulVoiceBarConfig config = Config.SoulVoiceBar;
byte soulVoice = Plugin.JobGauges.Get<BRDGauge>().SoulVoice;
if (config.HideWhenInactive && soulVoice == 0)
{
return;
}
config.Label.SetValue(soulVoice);
BarHud bar = BarUtilities.GetProgressBar(
config,
config.ThresholdConfig,
new LabelConfig[] { config.Label },
soulVoice,
100f,
0f,
player,
config.FillColor,
soulVoice == 100f && config.GlowConfig.Enabled ? config.GlowConfig : null
);
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
private void DrawStacksBar(Vector2 origin, IPlayerCharacter player, int amount, int max, PluginConfigColor stackColor, BarGlowConfig? glowConfig = null)
{
BardStacksBarConfig config = Config.StacksBar;
config.FillColor = stackColor;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.StacksBar, max, amount, max, 0f, player, glowConfig: glowConfig);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.CodaBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Ranged", 0)]
[SubSection("Bard", 1)]
public class BardConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.BRD;
public new static BardConfig DefaultConfig()
{
var config = new BardConfig();
config.SoulVoiceBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.StormbiteDoTBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.StormbiteDoTBar.Label.TextAnchor = DrawAnchor.Left;
config.StormbiteDoTBar.Label.FrameAnchor = DrawAnchor.Left;
config.StormbiteDoTBar.Label.Position = new Vector2(2, 0);
config.CausticBiteDoTBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.CausticBiteDoTBar.Label.TextAnchor = DrawAnchor.Right;
config.CausticBiteDoTBar.Label.FrameAnchor = DrawAnchor.Right;
config.CausticBiteDoTBar.Label.Position = new Vector2(-2, 0);
config.CausticBiteDoTBar.FillDirection = BarDirection.Left;
config.SoulVoiceBar.ThresholdConfig.Enabled = true;
config.SoulVoiceBar.ThresholdConfig.Value = 80;
config.SoulVoiceBar.ThresholdConfig.ThresholdType = ThresholdType.Above;
config.SoulVoiceBar.ThresholdConfig.ChangeColor = true;
config.SoulVoiceBar.ThresholdConfig.Color = new PluginConfigColor(new Vector4(150f / 255f, 0f / 255f, 255f / 255f, 100f / 100f));
return config;
}
[NestedConfig("Song Gauge Bar", 30)]
public BardSongBarConfig SongGaugeBar = new BardSongBarConfig(
new(0, -22),
new(254, 20),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 0f / 100f))
);
[NestedConfig("Soul Voice Bar", 35)]
public BardSoulVoiceBarConfig SoulVoiceBar = new BardSoulVoiceBarConfig(
new(0, -5),
new(254, 10),
new PluginConfigColor(new Vector4(248f / 255f, 227f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Stacks Bar", 40)]
public BardStacksBarConfig StacksBar = new BardStacksBarConfig(
new(0, -39),
new(254, 10),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 0f / 100f))
);
[NestedConfig("Caustic Bite Bar", 60)]
public ProgressBarConfig CausticBiteDoTBar = new ProgressBarConfig(
new(-64, -51),
new(126, 10),
new PluginConfigColor(new Vector4(182f / 255f, 68f / 255f, 235f / 255f, 100f / 100f))
);
[NestedConfig("Stormbite Bar", 65)]
public ProgressBarConfig StormbiteDoTBar = new ProgressBarConfig(
new(64, -51),
new(126, 10),
new PluginConfigColor(new Vector4(72f / 255f, 117f / 255f, 202f / 255f, 100f / 100f))
);
[NestedConfig("Coda Bar", 40)]
public BardCodaBarConfig CodaBar = new BardCodaBarConfig(
new(0, -63),
new(254, 10),
new PluginConfigColor(new Vector4(0, 0, 0, 0))
);
}
[DisableParentSettings("FillColor", "ThresholdConfig")]
[Exportable(false)]
public class BardSongBarConfig : ProgressBarConfig
{
[ColorEdit4("Wanderer's Minuet" + "##Song")]
[Order(31)]
public PluginConfigColor WMColor = new(new Vector4(158f / 255f, 157f / 255f, 36f / 255f, 100f / 100f));
[ColorEdit4("Mage's Ballad" + "##Song")]
[Order(32)]
public PluginConfigColor MBColor = new(new Vector4(143f / 255f, 90f / 255f, 143f / 255f, 100f / 100f));
[ColorEdit4("Army's Paeon" + "##Song")]
[Order(33)]
public PluginConfigColor APColor = new(new Vector4(207f / 255f, 205f / 255f, 52f / 255f, 100f / 100f));
[NestedConfig("Wanderer's Minuet Threshold", 36, separator = false, spacing = true)]
public ThresholdConfig WMThreshold = new ThresholdConfig()
{
ChangeColor = true,
Enabled = true,
ThresholdType = ThresholdType.Below,
Value = 3
};
[NestedConfig("Mage's Ballad Threshold", 37, separator = false, spacing = true)]
public ThresholdConfig MBThreshold = new ThresholdConfig()
{
ChangeColor = true,
Enabled = true,
ThresholdType = ThresholdType.Below,
Value = 14
};
[NestedConfig("Army's Paeon Threshold", 38, separator = false, spacing = true)]
public ThresholdConfig APThreshold = new ThresholdConfig()
{
ChangeColor = true,
Enabled = true,
ThresholdType = ThresholdType.Below,
Value = 3
};
public BardSongBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class BardSoulVoiceBarConfig : ProgressBarConfig
{
[NestedConfig("Show Glow", 39, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public BardSoulVoiceBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class BardStacksBarConfig : ChunkedBarConfig
{
[Checkbox("Wanderer's Minuet Stacks", separator = false, spacing = true)]
[Order(51)]
public bool ShowWMStacks = true;
[NestedConfig("Wanderer's Minuet Stacks Glow", 52, separator = false, spacing = true)]
public BarGlowConfig WMGlowConfig = new BarGlowConfig();
[Checkbox("Mage's Ballad Proc" + "##Stacks")]
[Order(53)]
public bool ShowMBProc = true;
[NestedConfig("Mage's Ballad Proc Glow", 54, separator = false, spacing = true)]
public BarGlowConfig MBGlowConfig = new BarGlowConfig();
[Checkbox("Army's Paeon Stacks" + "##Stacks")]
[Order(56)]
public bool ShowAPStacks = true;
[ColorEdit4("Wanderer's Minuet Stack" + "##Stacks")]
[Order(57)]
public PluginConfigColor WMStackColor = new(new Vector4(150f / 255f, 215f / 255f, 232f / 255f, 100f / 100f));
[ColorEdit4("Mage's Ballad Proc" + "##Stacks")]
[Order(58)]
public PluginConfigColor MBProcColor = new(new Vector4(199f / 255f, 46f / 255f, 46f / 255f, 100f / 100f));
[ColorEdit4("Army's Paeon Stack" + "##Stacks")]
[Order(59)]
public PluginConfigColor APStackColor = new(new Vector4(0f / 255f, 222f / 255f, 177f / 255f, 100f / 100f));
public BardStacksBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class BardCodaBarConfig : ChunkedBarConfig
{
[ColorEdit4("Wanderer's Minuet" + "##Coda", spacing = true)]
[Order(71)]
public PluginConfigColor WMColor = new(new Vector4(145f / 255f, 186f / 255f, 94f / 255f, 100f / 100f));
[ColorEdit4("Mage's Ballad" + "##Coda")]
[Order(72)]
public PluginConfigColor MBColor = new(new Vector4(143f / 255f, 90f / 255f, 143f / 255f, 100f / 100f));
[ColorEdit4("Army's Paeon" + "##Coda")]
[Order(73)]
public PluginConfigColor APColor = new(new Vector4(207f / 255f, 205f / 255f, 52f / 255f, 100f / 100f));
[DragDropHorizontal("Order", "Wanderer's Minuet", "Mage's Ballad", "Army's Paeon")]
[Order(74)]
public int[] CodaOrder = new int[] { 0, 1, 2 };
public BardCodaBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor, 2) { }
}
}
+60
View File
@@ -0,0 +1,60 @@
using HSUI.Helpers;
using Newtonsoft.Json;
namespace HSUI.Interface.Jobs
{
public class BaseJobsConfig : JobConfig
{
public override uint JobId => 0;
public BaseJobsConfig()
{
UseDefaultPrimaryResourceBar = true;
}
}
public class GladiatorConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.GLA;
}
public class MarauderConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.MRD;
}
public class PugilistConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.PGL;
}
public class LancerConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.LNC;
}
public class RogueConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.ROG;
}
public class ArcherConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.ARC;
}
public class ThaumaturgeConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.THM;
}
public class ArcanistConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.ACN;
}
public class ConjurerConfig : BaseJobsConfig
{
[JsonIgnore] public override uint JobId => JobIDs.CNJ;
}
}
+588
View File
@@ -0,0 +1,588 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.Game.Gauge;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
namespace HSUI.Interface.Jobs
{
public class BlackMageHud : JobHud
{
private new BlackMageConfig Config => (BlackMageConfig)_config;
private static readonly List<uint> ThunderDoTIDs = new() { 161, 162, 163, 1210, 3871, 3872 };
private static readonly List<float> ThunderDoTDurations = new() { 24, 18, 27, 21, 30, 24 };
public BlackMageHud(BlackMageConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.ManaBar.Enabled)
{
positions.Add(Config.Position + Config.ManaBar.Position);
sizes.Add(Config.ManaBar.Size);
}
if (Config.StacksBar.Enabled)
{
positions.Add(Config.Position + Config.StacksBar.Position);
sizes.Add(Config.StacksBar.Size);
}
if (Config.UmbralHeartBar.Enabled)
{
positions.Add(Config.Position + Config.UmbralHeartBar.Position);
sizes.Add(Config.UmbralHeartBar.Size);
}
if (Config.TriplecastBar.Enabled)
{
positions.Add(Config.Position + Config.TriplecastBar.Position);
sizes.Add(Config.TriplecastBar.Size);
}
if (Config.EnochianBar.Enabled)
{
positions.Add(Config.Position + Config.EnochianBar.Position);
sizes.Add(Config.EnochianBar.Size);
}
if (Config.PolyglotBar.Enabled)
{
positions.Add(Config.Position + Config.PolyglotBar.Position);
sizes.Add(Config.PolyglotBar.Size);
}
if (Config.ParadoxBar.Enabled)
{
positions.Add(Config.Position + Config.ParadoxBar.Position);
sizes.Add(Config.ParadoxBar.Size);
}
if (Config.ThunderDoTBar.Enabled && !Config.ThunderDoTBar.HideWhenInactive)
{
positions.Add(Config.Position + Config.ThunderDoTBar.Position);
sizes.Add(Config.ThunderDoTBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.ManaBar.Enabled)
{
DrawManaBar(pos, player);
}
if (Config.StacksBar.Enabled)
{
DrawStacksBar(pos);
}
if (Config.UmbralHeartBar.Enabled)
{
DrawUmbralHeartBar(pos);
}
if (Config.AstralSoulBar.Enabled)
{
DrawAstralSoulBar(pos);
}
if (Config.TriplecastBar.Enabled)
{
DrawTripleCastBar(pos, player);
}
if (Config.PolyglotBar.Enabled)
{
DrawPolyglotBar(pos, player);
}
if (Config.ParadoxBar.Enabled)
{
DrawParadoxBar(pos, player);
}
if (Config.EnochianBar.Enabled)
{
DrawEnochianBar(pos, player);
}
if (Config.ThunderDoTBar.Enabled)
{
DrawThunderDoTBar(pos, player);
}
}
protected unsafe void DrawManaBar(Vector2 origin, IPlayerCharacter player)
{
BlackMageManaBarConfig config = Config.ManaBar;
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
bool inUmbralIce = gauge->ElementStance < 0;
bool inAstralFire = gauge->ElementStance > 0;
if (config.HideWhenInactive && !inAstralFire && !inUmbralIce && player.CurrentMp == player.MaxMp)
{
return;
}
// value
config.ValueLabelConfig.SetValue(player.CurrentMp);
bool drawTreshold = inAstralFire || !config.ThresholdConfig.ShowOnlyDuringAstralFire;
PluginConfigColor fillColor = config.FillColor;
PluginConfigColor bgColor = config.BackgroundColor;
if (config.UseElementColor)
{
fillColor = inAstralFire ? config.FireColor : inUmbralIce ? config.IceColor : config.FillColor;
bgColor = inAstralFire ? config.FireBackgroundColor : inUmbralIce ? config.IceBackgroundColor : config.BackgroundColor;
}
BarHud bar = BarUtilities.GetProgressBar(
config,
drawTreshold ? config.ThresholdConfig : null,
[config.ValueLabelConfig],
player.CurrentMp,
player.MaxMp,
0,
player,
fillColor: fillColor,
backgroundColor: bgColor
);
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
protected unsafe void DrawStacksBar(Vector2 origin)
{
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
int umbralIceStacks = gauge->UmbralStacks;
int astralFireStacks = gauge->AstralStacks;
if (Config.StacksBar.HideWhenInactive && umbralIceStacks == 0 && astralFireStacks == 0)
{
return;
};
PluginConfigColor color = umbralIceStacks > 0 ? Config.StacksBar.IceColor : Config.StacksBar.FireColor;
int stacks = umbralIceStacks > 0 ? umbralIceStacks : astralFireStacks;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.StacksBar, 3, stacks, 3f, fillColor: color);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.StacksBar.StrataLevel));
}
}
protected unsafe void DrawUmbralHeartBar(Vector2 origin)
{
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
if (Config.UmbralHeartBar.HideWhenInactive && gauge->UmbralHearts == 0)
{
return;
};
BarHud[] bars = BarUtilities.GetChunkedBars(Config.UmbralHeartBar, 3, gauge->UmbralHearts, 3f);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.UmbralHeartBar.StrataLevel));
}
}
protected unsafe void DrawAstralSoulBar(Vector2 origin)
{
BLMGauge gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* internalGauge = (BlackMageGaugeTmp*)gauge.Address;
int stacks = internalGauge->AstralSoulStacks;
const int maxStacks = 6;
if (Config.AstralSoulBar.HideWhenInactive && stacks == 0)
{
return;
};
bool isFull = stacks == maxStacks;
BarGlowConfig? glow = isFull && Config.AstralSoulBar.GlowConfig.Enabled ? Config.AstralSoulBar.GlowConfig : null;
PluginConfigColor color = isFull ? Config.AstralSoulBar.FullStacksColor : Config.AstralSoulBar.FillColor;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AstralSoulBar, maxStacks, stacks, maxStacks, fillColor: color, glowConfig: glow);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AstralSoulBar.StrataLevel));
}
}
protected void DrawTripleCastBar(Vector2 origin, IPlayerCharacter player)
{
ushort stackCount = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1211)?.Param ?? 0;
int maxCount = 3;
if (Config.TriplecastBar.CountSwiftcast)
{
bool hasSwiftcast = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 167) != null;
if (hasSwiftcast)
{
stackCount++;
maxCount = stackCount == 4 ? 4 : 3;
}
}
if (Config.TriplecastBar.HideWhenInactive && stackCount == 0)
{
return;
};
BarHud[] bars = BarUtilities.GetChunkedBars(Config.TriplecastBar, maxCount, stackCount, maxCount);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.TriplecastBar.StrataLevel));
}
}
protected unsafe void DrawEnochianBar(Vector2 origin, IPlayerCharacter player)
{
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
if (Config.EnochianBar.HideWhenInactive && !gauge->EnochianActive)
{
return;
}
float timer = gauge->EnochianActive ? (30000f - gauge->EnochianTimer) : 0f;
Config.EnochianBar.Label.SetValue(timer / 1000);
BarHud bar = BarUtilities.GetProgressBar(Config.EnochianBar, timer / 1000, 30, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.EnochianBar.StrataLevel));
}
protected unsafe void DrawPolyglotBar(Vector2 origin, IPlayerCharacter player)
{
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
if (Config.PolyglotBar.HideWhenInactive && gauge->PolyglotStacks == 0)
{
return;
}
// only 1 stack before level 80
if (player.Level < 80)
{
BarGlowConfig? glow = gauge->PolyglotStacks == 1 && Config.PolyglotBar.GlowConfig.Enabled ? Config.PolyglotBar.GlowConfig : null;
BarHud bar = BarUtilities.GetBar(Config.PolyglotBar, gauge->PolyglotStacks, 1, 0, glowConfig: glow);
AddDrawActions(bar.GetDrawActions(origin, Config.PolyglotBar.StrataLevel));
}
// 2-3 stacks after
else
{
int stacks = player.Level < 98 ? 2 : 3;
BarGlowConfig? glow = Config.PolyglotBar.GlowConfig.Enabled ? Config.PolyglotBar.GlowConfig : null;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.PolyglotBar, stacks, gauge->PolyglotStacks, stacks, 0, glowConfig: glow);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.PolyglotBar.StrataLevel));
}
}
}
protected unsafe void DrawParadoxBar(Vector2 origin, IPlayerCharacter player)
{
BLMGauge _gauge = Plugin.JobGauges.Get<BLMGauge>();
BlackMageGaugeTmp* gauge = (BlackMageGaugeTmp*)_gauge.Address;
bool inUmbralIce = gauge->ElementStance < 0;
bool inAstralFire = gauge->ElementStance > 0;
if (Config.ParadoxBar.HideWhenInactive && !gauge->ParadoxActive)
{
return;
};
PluginConfigColor color = Config.ParadoxBar.FillColor;
if (Config.ParadoxBar.UseElementColor)
{
color = inUmbralIce ? Config.ParadoxBar.IceColor : (inAstralFire ? Config.ParadoxBar.FireColor : color);
}
BarGlowConfig? glow = gauge->ParadoxActive && Config.ParadoxBar.GlowConfig.Enabled ? Config.ParadoxBar.GlowConfig : null;
BarHud bar = BarUtilities.GetBar(Config.ParadoxBar, gauge->ParadoxActive ? 1 : 0, 1, 0, fillColor: color, glowConfig: glow);
AddDrawActions(bar.GetDrawActions(origin, Config.ParadoxBar.StrataLevel));
}
protected void DrawThunderDoTBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.ThunderDoTBar, player, target, ThunderDoTIDs, ThunderDoTDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ThunderDoTBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Caster", 0)]
[SubSection("Black Mage", 1)]
public class BlackMageConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.BLM;
public new static BlackMageConfig DefaultConfig()
{
var config = new BlackMageConfig();
config.EnochianBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.EnochianBar.Label.TextAnchor = DrawAnchor.Left;
config.EnochianBar.Label.FrameAnchor = DrawAnchor.Left;
config.EnochianBar.Label.Position = new Vector2(2, 0);
config.ThunderDoTBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.ThunderDoTBar.Label.TextAnchor = DrawAnchor.Left;
config.ThunderDoTBar.Label.FrameAnchor = DrawAnchor.Left;
config.ThunderDoTBar.Label.Position = new Vector2(2, 0);
return config;
}
[NestedConfig("Mana Bar", 30)]
public BlackMageManaBarConfig ManaBar = new BlackMageManaBarConfig(
new Vector2(0, -10),
new Vector2(254, 18),
new PluginConfigColor(new Vector4(234f / 255f, 95f / 255f, 155f / 255f, 100f / 100f))
);
[NestedConfig("Umbral Ice / Astral Fire Bar", 31)]
public BlackMageStacksBarConfig StacksBar = new BlackMageStacksBarConfig(
new(-67, -27),
new(120, 10)
);
[NestedConfig("Umbral Heart Bar", 32)]
public ChunkedBarConfig UmbralHeartBar = new ChunkedBarConfig(
new(67, -27),
new(120, 10),
new PluginConfigColor(new Vector4(125f / 255f, 195f / 255f, 205f / 255f, 100f / 100f))
);
[NestedConfig("Paradox Bar", 33)]
public BlackMageParadoxBarConfig ParadoxBar = new BlackMageParadoxBarConfig(
new(0, -27),
new(10, 10),
new PluginConfigColor(new Vector4(123f / 255f, 66f / 255f, 177f / 255f, 100f / 100f))
);
[NestedConfig("Enochian Bar", 40)]
public ProgressBarConfig EnochianBar = new ProgressBarConfig(
new(-16, -41),
new(222, 14),
new PluginConfigColor(new Vector4(234f / 255f, 95f / 255f, 155f / 255f, 100f / 100f))
);
[NestedConfig("Polyglot Bar", 45)]
public BlackMagePolyglotBarConfig PolyglotBar = new BlackMagePolyglotBarConfig(
new(112, -41),
new(30, 14),
new PluginConfigColor(new Vector4(234f / 255f, 95f / 255f, 155f / 255f, 100f / 100f))
);
[NestedConfig("Astral Soul Bar", 45)]
public BlackMageAstralSoulBarConfig AstralSoulBar = new BlackMageAstralSoulBarConfig(
new(112, -41),
new(30, 14),
new PluginConfigColor(new Vector4(220f / 255f, 180f / 255f, 180f / 255f, 100f / 100f))
);
[NestedConfig("Triplecast Bar", 50)]
public BlackMageTriplecastBarConfig TriplecastBar = new BlackMageTriplecastBarConfig(
new(0, -55),
new(254, 10),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Thunder DoT Bar", 60)]
public ProgressBarConfig ThunderDoTBar = new ProgressBarConfig(
new(64, -69),
new(126, 14),
new PluginConfigColor(new Vector4(67f / 255f, 187 / 255f, 255f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class BlackMageManaBarConfig : BarConfig
{
[Checkbox("Use Element Color" + "##MP", spacing = true)]
[Order(50)]
public bool UseElementColor = true;
[ColorEdit4("Ice Color" + "##MP")]
[Order(51, collapseWith = nameof(UseElementColor))]
public PluginConfigColor IceColor = new PluginConfigColor(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 100f / 100f));
[ColorEdit4("Ice Background Color" + "##MP")]
[Order(52, collapseWith = nameof(UseElementColor))]
public PluginConfigColor IceBackgroundColor = new PluginConfigColor(new Vector4(50f / 255f, 80f / 255f, 130f / 255f, 50f / 100f));
[ColorEdit4("Fire Color" + "##MP")]
[Order(53, collapseWith = nameof(UseElementColor))]
public PluginConfigColor FireColor = new PluginConfigColor(new Vector4(204f / 255f, 40f / 255f, 40f / 255f, 100f / 100f));
[ColorEdit4("Fire Background Color" + "##MP")]
[Order(54, collapseWith = nameof(UseElementColor))]
public PluginConfigColor FireBackgroundColor = new PluginConfigColor(new Vector4(120f / 255f, 30f / 255f, 30f / 255f, 50f / 100f));
[NestedConfig("Value Label", 60, separator = false, spacing = true)]
public NumericLabelConfig ValueLabelConfig = new NumericLabelConfig(new Vector2(2, 0), "", DrawAnchor.Left, DrawAnchor.Left);
[NestedConfig("Threshold", 70, separator = false, spacing = true)]
public BlackMakeManaBarThresholdConfig ThresholdConfig = new BlackMakeManaBarThresholdConfig();
public BlackMageManaBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class BlackMakeManaBarThresholdConfig : ThresholdConfig
{
[Checkbox("Show Only During Astral Fire")]
[Order(5)]
public bool ShowOnlyDuringAstralFire = true;
public BlackMakeManaBarThresholdConfig()
{
Enabled = true;
Value = 2400;
Color = new PluginConfigColor(new Vector4(240f / 255f, 120f / 255f, 10f / 255f, 100f / 100f));
ShowMarker = true;
MarkerColor = new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 100f / 100f));
}
}
[DisableParentSettings("FillColor", "FillDirection")]
[Exportable(false)]
public class BlackMageStacksBarConfig : ChunkedBarConfig
{
[ColorEdit4("Ice Color" + "##MP")]
[Order(26)]
public PluginConfigColor IceColor = new PluginConfigColor(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 100f / 100f));
[ColorEdit4("Fire Color" + "##MP")]
[Order(27)]
public PluginConfigColor FireColor = new PluginConfigColor(new Vector4(204f / 255f, 40f / 255f, 40f / 255f, 100f / 100f));
public BlackMageStacksBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
[Exportable(false)]
public class BlackMagePolyglotBarConfig : ChunkedBarConfig
{
[NestedConfig("Show Glow", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public BlackMagePolyglotBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class BlackMageParadoxBarConfig : BarConfig
{
[Checkbox("Use Element Color" + "##Paradox", spacing = true)]
[Order(50)]
public bool UseElementColor = true;
[ColorEdit4("Ice Color" + "##Paradox")]
[Order(51, collapseWith = nameof(UseElementColor))]
public PluginConfigColor IceColor = new PluginConfigColor(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 100f / 100f));
[ColorEdit4("Fire Color" + "##Paradox")]
[Order(52, collapseWith = nameof(UseElementColor))]
public PluginConfigColor FireColor = new PluginConfigColor(new Vector4(204f / 255f, 40f / 255f, 40f / 255f, 100f / 100f));
[NestedConfig("Show Glow" + "##Paradox", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public BlackMageParadoxBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class BlackMageTriplecastBarConfig : ChunkedBarConfig
{
[Checkbox("Count Swiftcast" + "##Triplecast", spacing = true)]
[Order(50)]
public bool CountSwiftcast = false;
public BlackMageTriplecastBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[DisableParentSettings("FillDirection")]
[Exportable(false)]
public class BlackMageAstralSoulBarConfig : ChunkedBarConfig
{
[ColorEdit4("Full Stacks Color")]
[Order(26)]
public PluginConfigColor FullStacksColor = new PluginConfigColor(new Vector4(255f / 255f, 200f / 255f, 160f / 255f, 100f / 100f));
[NestedConfig("Show Glow" + "##AstralSoul", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public BlackMageAstralSoulBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
public struct BlackMageGaugeTmp
{
[FieldOffset(0x08)] public short EnochianTimer;
[FieldOffset(0x0A)] public sbyte ElementStance;
[FieldOffset(0x0B)] public byte UmbralHearts;
[FieldOffset(0x0C)] public byte PolyglotStacks;
[FieldOffset(0x0D)] public EnochianFlags EnochianFlags;
public int UmbralStacks => ElementStance >= 0 ? 0 : ElementStance * -1;
public int AstralStacks => ElementStance <= 0 ? 0 : ElementStance;
public bool EnochianActive => EnochianFlags.HasFlag(EnochianFlags.Enochian);
public bool ParadoxActive => EnochianFlags.HasFlag(EnochianFlags.Paradox);
public int AstralSoulStacks => ((int)EnochianFlags >> 2) & 7;
}
+313
View File
@@ -0,0 +1,313 @@
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class BlueMageHud : JobHud
{
private new BlueMageConfig Config => (BlueMageConfig)_config;
public BlueMageHud(BlueMageConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.BleedBar.Enabled)
{
positions.Add(Config.Position + Config.BleedBar.Position);
sizes.Add(Config.BleedBar.Size);
}
if (Config.WindburnBar.Enabled)
{
positions.Add(Config.Position + Config.WindburnBar.Position);
sizes.Add(Config.WindburnBar.Size);
}
if (Config.SurpanakhaBar.Enabled)
{
positions.Add(Config.Position + Config.SurpanakhaBar.Position);
sizes.Add(Config.SurpanakhaBar.Size);
}
if (Config.OffGuardBar.Enabled)
{
positions.Add(Config.Position + Config.OffGuardBar.Position);
sizes.Add(Config.OffGuardBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.BleedBar.Enabled)
{
DrawBleedBar(pos, player);
}
if (Config.WindburnBar.Enabled)
{
DrawWindburnBar(pos, player);
}
if (Config.SurpanakhaBar.Enabled)
{
DrawSurpanakhaBar(pos, player);
}
if (Config.OffGuardBar.Enabled)
{
DrawOffGuardBar(pos, player);
}
if (Config.MoonFluteBar.Enabled)
{
DrawMoonFluteBar(pos, player);
}
if (Config.SpellAmpBar.Enabled)
{
DrawSpellAmpBar(pos, player);
}
if (Config.TingleBar.Enabled)
{
DrawTingleBar(pos, player);
}
}
private static List<uint> BleedID = new List<uint> { 1714 };
private static List<float> BleedDurations = new List<float> { 30, 60 };
protected void DrawBleedBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.BleedBar, player, target, BleedID, BleedDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.BleedBar.StrataLevel));
}
}
protected void DrawWindburnBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
bool dotExists = false;
if (target != null && target is IBattleChara targetChara)
{
dotExists = Utils.StatusListForBattleChara(targetChara).FirstOrDefault(o => o.SourceId == player.GameObjectId && o.StatusId == 1723) != null;
}
if (dotExists)
{
BarHud? bar = BarUtilities.GetDoTBar(Config.WindburnBar, player, target, 1723, 6f);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.WindburnBar.StrataLevel));
}
}
else
{
float featherRainCD = SpellHelper.Instance.GetSpellCooldown(11426);
float max = 30f;
float current = max - featherRainCD;
if (!Config.WindburnBar.HideWhenInactive || current < max)
{
Config.WindburnBar.Label.SetValue(max - current);
if (current == max)
{
Config.WindburnBar.Label.SetText("Ready");
}
BarHud bar = BarUtilities.GetProgressBar(Config.WindburnBar, current, max, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.WindburnBar.StrataLevel));
}
}
}
protected void DrawSurpanakhaBar(Vector2 origin, IPlayerCharacter player)
{
float surpanakhaCD = SpellHelper.Instance.GetSpellCooldown(18323);
float max = 120f;
float current = max - surpanakhaCD;
if (!Config.SurpanakhaBar.HideWhenInactive || current < max)
{
Config.SurpanakhaBar.Label.SetValue((max - current) % 30);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.SurpanakhaBar, 4, current, max, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.SurpanakhaBar.StrataLevel));
}
}
}
protected void DrawOffGuardBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.OffGuardBar, player, target, 1717, 15f);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.OffGuardBar.StrataLevel));
}
}
protected void DrawMoonFluteBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? buff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1718 or 1727 && o.RemainingTime > 0f);
if (!Config.MoonFluteBar.HideWhenInactive || buff is not null)
{
var buffColor = buff is not null ? buff.StatusId switch
{
1718 => Config.MoonFluteBar.WaxingCrescentColor,
1727 => Config.MoonFluteBar.WaningCrescentColor,
_ => Config.MoonFluteBar.WaxingCrescentColor
} : Config.MoonFluteBar.WaxingCrescentColor;
float buffDuration = buff?.RemainingTime ?? 0f;
Config.MoonFluteBar.Label.SetValue(buffDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.MoonFluteBar, buffDuration, 15f, 0, player, fillColor: buffColor);
AddDrawActions(bar.GetDrawActions(origin, Config.MoonFluteBar.StrataLevel));
}
}
protected void DrawSpellAmpBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? buff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2118 or 1716 && o.RemainingTime > 0f);
if (!Config.SpellAmpBar.HideWhenInactive || buff is not null)
{
var buffColor = buff is not null ? buff.StatusId switch
{
2118 => Config.SpellAmpBar.BristleColor,
1716 => Config.SpellAmpBar.WhistleColor,
_ => Config.SpellAmpBar.BristleColor
} : Config.SpellAmpBar.BristleColor;
float buffDuration = buff?.RemainingTime ?? 0f;
Config.SpellAmpBar.Label.SetValue(buffDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.SpellAmpBar, buffDuration, 30f, 0, player, fillColor: buffColor);
AddDrawActions(bar.GetDrawActions(origin, Config.SpellAmpBar.StrataLevel));
}
}
protected void DrawTingleBar(Vector2 origin, IPlayerCharacter player)
{
BarHud? bar = BarUtilities.GetProcBar(Config.TingleBar, player, 2492, 15f);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.TingleBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Caster", 0)]
[SubSection("Blue Mage", 1)]
public class BlueMageConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.BLU;
public new static BlueMageConfig DefaultConfig()
{
var config = new BlueMageConfig();
config.UseDefaultPrimaryResourceBar = true;
return config;
}
[NestedConfig("Bleed Bar", 40)]
public ProgressBarConfig BleedBar = new ProgressBarConfig(
new(-64, -55),
new(126, 14),
new PluginConfigColor(new Vector4(106f / 255f, 237f / 255f, 241f / 255f, 100f / 100f)),
BarDirection.Left
);
[NestedConfig("Windburn Bar", 45)]
public ProgressBarConfig WindburnBar = new ProgressBarConfig(
new(64, -55),
new(126, 14),
new PluginConfigColor(new Vector4(50f / 255f, 93f / 255f, 37f / 255f, 100f / 100f))
);
[NestedConfig("Surpanakha Bar", 50)]
public ChunkedProgressBarConfig SurpanakhaBar = new ChunkedProgressBarConfig(
new(0, -39),
new(254, 14),
new PluginConfigColor(new Vector4(202f / 255f, 228f / 255f, 246f / 242f, 100f / 100f))
);
[NestedConfig("Off-Guard Bar", 55)]
public ProgressBarConfig OffGuardBar = new ProgressBarConfig(
new(0, -23),
new(254, 14),
new PluginConfigColor(new Vector4(202f / 255f, 228f / 255f, 246f / 242f, 100f / 100f))
);
[NestedConfig("Moon Flute Bar", 60)]
public MoonFluteBarConfig MoonFluteBar = new MoonFluteBarConfig(
new(0, -7),
new(84, 14),
new(new Vector4(128f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Spell Amp Bar", 65)]
public SpellAmpBarConfig SpellAmpBar = new SpellAmpBarConfig(
new(-86, -7),
new(82, 14),
new(new Vector4(128f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Tingle Bar", 70)]
public ProgressBarConfig TingleBar = new ProgressBarConfig(
new(86, -7),
new(82, 14),
new(new Vector4(128f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class MoonFluteBarConfig : ProgressBarConfig
{
[ColorEdit4("Waning Crescent Color")]
[Order(26)]
public PluginConfigColor WaxingCrescentColor = new(new Vector4(0f / 255f, 255f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Waxing Crescent Color")]
[Order(27)]
public PluginConfigColor WaningCrescentColor = new(new Vector4(255f / 255f, 0f / 255f, 0f / 255f, 100f / 100f));
public MoonFluteBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class SpellAmpBarConfig : ProgressBarConfig
{
[ColorEdit4("Waning Crescent Color")]
[Order(26)]
public PluginConfigColor BristleColor = new(new Vector4(0f / 255f, 255f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Waxing Crescent Color")]
[Order(27)]
public PluginConfigColor WhistleColor = new(new Vector4(255f / 255f, 0f / 255f, 0f / 255f, 100f / 100f));
public SpellAmpBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
+56
View File
@@ -0,0 +1,56 @@
using HSUI.Helpers;
using Newtonsoft.Json;
namespace HSUI.Interface.Jobs
{
public class CraftersConfig : JobConfig
{
public override uint JobId => 0;
public CraftersConfig()
{
UseDefaultPrimaryResourceBar = true;
PrimaryResourceType = PrimaryResourceTypes.CP;
}
}
public class CarpenterConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.CRP;
}
public class BlacksmithConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.BSM;
}
public class ArmorerConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.ARM;
}
public class GoldsmithConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.GSM;
}
public class LeatherworkerConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.LTW;
}
public class WeaverConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.WVR;
}
public class AlchemistConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.ALC;
}
public class CulinarianConfig : CraftersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.CUL;
}
}
+430
View File
@@ -0,0 +1,430 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class DancerHud : JobHud
{
private new DancerConfig Config => (DancerConfig)_config;
public DancerHud(DancerConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.StandardFinishBar.Enabled)
{
positions.Add(Config.Position + Config.StandardFinishBar.Position);
sizes.Add(Config.StandardFinishBar.Size);
}
if (Config.TechnicalFinishBar.Enabled)
{
positions.Add(Config.Position + Config.TechnicalFinishBar.Position);
sizes.Add(Config.TechnicalFinishBar.Position);
}
if (Config.DevilmentBar.Enabled)
{
positions.Add(Config.Position + Config.DevilmentBar.Position);
sizes.Add(Config.DevilmentBar.Position);
}
if (Config.EspritGauge.Enabled)
{
positions.Add(Config.Position + Config.EspritGauge.Position);
sizes.Add(Config.EspritGauge.Size);
}
if (Config.FeatherGauge.Enabled)
{
positions.Add(Config.Position + Config.FeatherGauge.Position);
sizes.Add(Config.FeatherGauge.Size);
}
if (Config.CascadeBar.Enabled)
{
positions.Add(Config.Position + Config.CascadeBar.Position);
sizes.Add(Config.CascadeBar.Position);
}
if (Config.FountainBar.Enabled)
{
positions.Add(Config.Position + Config.FountainBar.Position);
sizes.Add(Config.FountainBar.Position);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.EspritGauge.Enabled)
{
DrawEspritBar(pos, player);
}
if (Config.FeatherGauge.Enabled)
{
DrawFeathersBar(pos, player);
}
if (Config.StandardFinishBar.Enabled)
{
DrawStandardBar(pos, player);
}
if (Config.TechnicalFinishBar.Enabled)
{
DrawTechnicalBar(pos, player);
}
if (Config.DevilmentBar.Enabled)
{
DrawDevilmentBar(pos, player);
}
bool showingStepBar = false;
if (Config.StepsBar.Enabled)
{
showingStepBar = DrawStepBar(pos, player);
}
if (!showingStepBar || !Config.StepsBar.HideProcs)
{
if (Config.CascadeBar.Enabled) { DrawProcBar(pos, player, Config.CascadeBar, 2693, 3017); }
if (Config.FountainBar.Enabled) { DrawProcBar(pos, player, Config.FountainBar, 2694, 3018); }
}
}
private void DrawProcBar(Vector2 origin, IPlayerCharacter player, DancerProcBarConfig config, params uint[] statusIDs)
{
List<float> durations = new List<float>();
for (int i = 0; i < statusIDs.Length; i++)
{
durations.Add(30f);
}
BarHud? bar = BarUtilities.GetProcBar(config, player, statusIDs.ToList(), durations, !config.IgnoreBuffDuration);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe bool DrawStepBar(Vector2 origin, IPlayerCharacter player)
{
DNCGauge gauge = Plugin.JobGauges.Get<DNCGauge>();
if (!gauge.IsDancing)
{
return false;
}
List<Tuple<PluginConfigColor, float, LabelConfig?>> chunks = new List<Tuple<PluginConfigColor, float, LabelConfig?>>();
List<bool> glows = new List<bool>();
bool danceReady = true;
for (var i = 0; i < 4; i++)
{
DNCStep step = (DNCStep)gauge.Steps[i];
if (step == DNCStep.None)
{
break;
}
if (gauge.CompletedSteps == i)
{
glows.Add(true);
danceReady = false;
}
else
{
glows.Add(false);
}
PluginConfigColor color = PluginConfigColor.Empty;
switch (step)
{
case DNCStep.Emboite:
color = Config.StepsBar.EmboiteColor;
break;
case DNCStep.Entrechat:
color = Config.StepsBar.EntrechatColor;
break;
case DNCStep.Jete:
color = Config.StepsBar.JeteColor;
break;
case DNCStep.Pirouette:
color = Config.StepsBar.PirouetteColor;
break;
}
var tuple = new Tuple<PluginConfigColor, float, LabelConfig?>(color, 1, null);
chunks.Add(tuple);
}
if (danceReady)
{
for (int i = 0; i < glows.Count; i++)
{
glows[i] = true;
}
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.StepsBar, chunks.ToArray(), player, Config.StepsBar.GlowConfig, glows.ToArray());
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.StepsBar.StrataLevel));
}
return true;
}
private void DrawEspritBar(Vector2 origin, IPlayerCharacter player)
{
DNCGauge gauge = Plugin.JobGauges.Get<DNCGauge>();
if (Config.EspritGauge.HideWhenInactive && gauge.Esprit is 0) { return; }
Config.EspritGauge.Label.SetValue(gauge.Esprit);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.EspritGauge, 2, gauge.Esprit, 100, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.EspritGauge.StrataLevel));
}
}
private void DrawFeathersBar(Vector2 origin, IPlayerCharacter player)
{
DNCGauge gauge = Plugin.JobGauges.Get<DNCGauge>();
bool hasFlourishingBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1820 or 2021) != null;
bool[]? glows = null;
if (Config.FeatherGauge.HideWhenInactive && gauge.Feathers is 0 && !hasFlourishingBuff)
{
return;
}
if (Config.FeatherGauge.GlowConfig.Enabled)
{
glows = new bool[] { hasFlourishingBuff, hasFlourishingBuff, hasFlourishingBuff, hasFlourishingBuff };
}
BarGlowConfig? config = hasFlourishingBuff ? Config.FeatherGauge.GlowConfig : null;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.FeatherGauge, 4, gauge.Feathers, 4, 0, player, glowConfig: config, chunksToGlow: glows);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.FeatherGauge.StrataLevel));
}
}
private void DrawTechnicalBar(Vector2 origin, IPlayerCharacter player)
{
IEnumerable<IStatus> devilmentBuff = Utils.StatusListForBattleChara(player).Where(o => o.StatusId is 1825 && o.SourceId == player.GameObjectId);
float technicalFinishDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1822 or 2050 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.TechnicalFinishBar.HideWhenInactive || technicalFinishDuration > 0)
{
Config.TechnicalFinishBar.Label.SetValue(Math.Abs(technicalFinishDuration));
BarHud bar = BarUtilities.GetProgressBar(Config.TechnicalFinishBar, technicalFinishDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.TechnicalFinishBar.StrataLevel));
}
}
private void DrawDevilmentBar(Vector2 origin, IPlayerCharacter player)
{
float devilmentDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1825 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.DevilmentBar.HideWhenInactive || devilmentDuration > 0)
{
Config.DevilmentBar.Label.SetValue(Math.Abs(devilmentDuration));
BarHud bar = BarUtilities.GetProgressBar(Config.DevilmentBar, devilmentDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.DevilmentBar.StrataLevel));
}
}
private void DrawStandardBar(Vector2 origin, IPlayerCharacter player)
{
float standardFinishDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1821 or 2024 or 2105 or 2113 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.StandardFinishBar.HideWhenInactive || standardFinishDuration > 0)
{
Config.StandardFinishBar.Label.SetValue(Math.Abs(standardFinishDuration));
BarHud bar = BarUtilities.GetProgressBar(Config.StandardFinishBar, standardFinishDuration, 60f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.StandardFinishBar.StrataLevel));
}
}
}
public enum DNCStep : uint
{
None = 15998,
Emboite = 15999,
Entrechat = 16000,
Jete = 16001,
Pirouette = 16002
}
[Section("Job Specific Bars")]
[SubSection("Ranged", 0)]
[SubSection("Dancer", 1)]
public class DancerConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.DNC;
public new static DancerConfig DefaultConfig()
{
var config = new DancerConfig();
config.EspritGauge.UseChunks = false;
config.EspritGauge.Label.Enabled = true;
config.CascadeBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.FountainBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
return config;
}
[NestedConfig("Standard Finish Bar", 30)]
public ProgressBarConfig StandardFinishBar = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new PluginConfigColor(new Vector4(0f / 255f, 193f / 255f, 95f / 255f, 100f / 100f))
);
[NestedConfig("Technical Finish Bar", 35)]
public ProgressBarConfig TechnicalFinishBar = new ProgressBarConfig(
new(-64, -32),
new(126, 20),
new PluginConfigColor(new Vector4(255f / 255f, 9f / 255f, 102f / 255f, 100f / 100f))
);
[NestedConfig("Devilment Bar", 40)]
public ProgressBarConfig DevilmentBar = new ProgressBarConfig(
new(64, -32),
new(126, 20),
new PluginConfigColor(new Vector4(52f / 255f, 78f / 255f, 29f / 255f, 100f / 100f))
);
[NestedConfig("Esprit Gauge", 45)]
public ChunkedProgressBarConfig EspritGauge = new ChunkedProgressBarConfig(
new(0, -54),
new(254, 20),
new PluginConfigColor(new Vector4(72f / 255f, 20f / 255f, 99f / 255f, 100f / 100f))
);
[NestedConfig("Feathers Gauge", 50)]
public DancerFeatherGaugeConfig FeatherGauge = new DancerFeatherGaugeConfig(
new(0, -71),
new(254, 10),
new PluginConfigColor(new Vector4(175f / 255f, 229f / 255f, 29f / 255f, 100f / 100f))
);
[NestedConfig("Flourishing Symmetry Bar", 60)]
public DancerProcBarConfig CascadeBar = new DancerProcBarConfig(
new(-96, -83),
new(62, 10),
new(new Vector4(0f / 255f, 255f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Flourishing Flow Bar", 65)]
public DancerProcBarConfig FountainBar = new DancerProcBarConfig(
new(-32, -83),
new(62, 10),
new(new Vector4(255f / 255f, 215f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Steps Bar", 80)]
public DancerStepsBarConfig StepsBar = new DancerStepsBarConfig(
new(0, -83),
new(254, 10)
);
}
[Exportable(false)]
public class DancerFeatherGaugeConfig : ChunkedBarConfig
{
[NestedConfig("Glow on Flourishing Fan Dance", 1000, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public DancerFeatherGaugeConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
GlowConfig.Color = new PluginConfigColor(new Vector4(255f / 255f, 215f / 255f, 0f / 255f, 100f / 100f));
}
}
[Exportable(false)]
public class DancerProcBarConfig : ProgressBarConfig
{
[Checkbox("Ignore Buff Duration")]
[Order(4)]
public bool IgnoreBuffDuration = true;
public DancerProcBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[DisableParentSettings("FillColor", "HideWhenInactive")]
[Exportable(false)]
public class DancerStepsBarConfig : ChunkedBarConfig
{
[Checkbox("Hide Procs When Active")]
[Order(50)]
public bool HideProcs = true;
[ColorEdit4("Emboite", spacing = true)]
[Order(55)]
public PluginConfigColor EmboiteColor = new(new Vector4(255f / 255f, 0f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Entrechat")]
[Order(60)]
public PluginConfigColor EntrechatColor = new(new Vector4(0f / 255f, 0f / 255f, 255f / 255f, 100f / 100f));
[ColorEdit4("Jete")]
[Order(65)]
public PluginConfigColor JeteColor = new(new Vector4(0f / 255f, 255f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Pirouette")]
[Order(70)]
public PluginConfigColor PirouetteColor = new(new Vector4(255f / 255f, 215f / 255f, 0f / 255f, 100f / 100f));
[NestedConfig("Glow", 75, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
public DancerStepsBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
}
+344
View File
@@ -0,0 +1,344 @@
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 HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Game.ClientState.Statuses;
namespace HSUI.Interface.Jobs
{
public class DarkKnightHud : JobHud
{
private new DarkKnightConfig Config => (DarkKnightConfig)_config;
public DarkKnightHud(DarkKnightConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.ManaBar.Enabled)
{
positions.Add(Config.Position + Config.ManaBar.Position);
sizes.Add(Config.ManaBar.Size);
}
if (Config.BloodGauge.Enabled)
{
positions.Add(Config.Position + Config.BloodGauge.Position);
sizes.Add(Config.BloodGauge.Size);
}
if (Config.DarksideBar.Enabled)
{
positions.Add(Config.Position + Config.DarksideBar.Position);
sizes.Add(Config.DarksideBar.Size);
}
if (Config.BloodWeaponBar.Enabled)
{
positions.Add(Config.Position + Config.BloodWeaponBar.Position);
sizes.Add(Config.BloodWeaponBar.Size);
}
if (Config.DeliriumBar.Enabled)
{
positions.Add(Config.Position + Config.DeliriumBar.Position);
sizes.Add(Config.DeliriumBar.Size);
}
if (Config.LivingShadowBar.Enabled)
{
positions.Add(Config.Position + Config.LivingShadowBar.Position);
sizes.Add(Config.LivingShadowBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.ManaBar.Enabled)
{
DrawManaBar(pos, player);
}
if (Config.BloodGauge.Enabled)
{
DrawBloodGauge(pos, player);
}
if (Config.DarksideBar.Enabled)
{
DrawDarkside(pos, player);
}
if (Config.BloodWeaponBar.Enabled)
{
DrawBloodWeaponBar(pos, player);
}
if (Config.DeliriumBar.Enabled)
{
DrawDeliriumBar(pos, player);
}
if (Config.LivingShadowBar.Enabled)
{
DrawLivingShadowBar(pos, player);
}
}
private unsafe void DrawManaBar(Vector2 origin, IPlayerCharacter player)
{
DRKGauge gauge = Plugin.JobGauges.Get<DRKGauge>();
if (Config.ManaBar.HideWhenInactive && !gauge.HasDarkArts && player.CurrentMp == player.MaxMp)
{
return;
}
Config.ManaBar.UsePartialFillColor = !gauge.HasDarkArts;
Config.ManaBar.Label.SetValue(player.CurrentMp);
// hardcoded 9k as maxMP so the chunks are each 3k since that's what a DRK wants to see
BarHud[] bars = BarUtilities.GetChunkedProgressBars(
Config.ManaBar,
gauge.HasDarkArts ? 1 : 3,
player.CurrentMp,
Config.ManaBar.ShowFullMana ? player.MaxMp : 9000,
0f,
player,
null,
gauge.HasDarkArts ? Config.ManaBar.DarkArtsColor : Config.ManaBar.FillColor
);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ManaBar.StrataLevel));
}
}
private void DrawDarkside(Vector2 origin, IPlayerCharacter player)
{
DRKGauge gauge = Plugin.JobGauges.Get<DRKGauge>();
if (Config.DarksideBar.HideWhenInactive && gauge.DarksideTimeRemaining == 0)
{
return;
};
float timer = Math.Abs(gauge.DarksideTimeRemaining) / 1000;
Config.DarksideBar.Label.SetValue(timer);
BarHud bar = BarUtilities.GetProgressBar(Config.DarksideBar, timer, 60, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.DarksideBar.StrataLevel));
}
private void DrawBloodGauge(Vector2 origin, IPlayerCharacter player)
{
DRKGauge gauge = Plugin.JobGauges.Get<DRKGauge>();
if (Config.BloodGauge.HideWhenInactive && gauge.Blood <= 0)
{
return;
}
Config.BloodGauge.Label.SetValue(gauge.Blood);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.BloodGauge, 2, gauge.Blood, 100, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.BloodGauge.StrataLevel));
}
}
private void DrawBloodWeaponBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? bloodWeaponBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 742);
float duration = bloodWeaponBuff?.RemainingTime ?? 0f;
int stacks = bloodWeaponBuff?.Param ?? 0;
if (Config.BloodWeaponBar.HideWhenInactive && duration <= 0)
{
return;
}
var chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < 3; i++)
{
chunks[i] = new(Config.BloodWeaponBar.FillColor, i < stacks ? 1 : 0, i == 1 ? Config.BloodWeaponBar.Label : null);
}
if(Config.BloodWeaponBar.FillDirection is BarDirection.Left or BarDirection.Up)
{
chunks = chunks.Reverse().ToArray();
}
Config.BloodWeaponBar.Label.SetValue(duration);
BarHud[] bars = BarUtilities.GetChunkedBars(Config.BloodWeaponBar, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.BloodWeaponBar.StrataLevel));
}
}
private void DrawDeliriumBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? deliriumBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1972);
float deliriumDuration = Math.Max(0f, deliriumBuff?.RemainingTime ?? 0f);
int stacks = deliriumBuff?.Param ?? 0;
if (Config.DeliriumBar.HideWhenInactive && deliriumDuration <= 0)
{
return;
}
var chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < 3; i++)
{
chunks[i] = new(Config.DeliriumBar.FillColor, i < stacks ? 1 : 0, i == 1 ? Config.DeliriumBar.Label : null);
}
if(Config.DeliriumBar.FillDirection is BarDirection.Left or BarDirection.Up)
{
chunks = chunks.Reverse().ToArray();
}
Config.DeliriumBar.Label.SetValue(deliriumDuration);
BarHud[] bars = BarUtilities.GetChunkedBars(Config.DeliriumBar, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DeliriumBar.StrataLevel));
}
}
private unsafe void DrawLivingShadowBar(Vector2 origin, IPlayerCharacter player)
{
DRKGauge gauge = Plugin.JobGauges.Get<DRKGauge>();
if (Config.LivingShadowBar.HideWhenInactive && gauge.ShadowTimeRemaining <= 0)
{
return;
}
float timer = Math.Abs(gauge.ShadowTimeRemaining) / 1000;
Config.LivingShadowBar.Label.SetValue(timer);
BarHud bar = BarUtilities.GetProgressBar(Config.LivingShadowBar, timer, 20, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.LivingShadowBar.StrataLevel));
}
}
[Section("Job Specific Bars")]
[SubSection("Tank", 0)]
[SubSection("Dark Knight", 1)]
public class DarkKnightConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.DRK;
public new static DarkKnightConfig DefaultConfig()
{
var config = new DarkKnightConfig();
config.ManaBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.ManaBar.UsePartialFillColor = true;
config.DarksideBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.DarksideBar.ThresholdConfig.Enabled = true;
config.BloodGauge.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.BloodGauge.UsePartialFillColor = true;
return config;
}
[NestedConfig("Mana Bar", 30)]
public DarkKnightManaBarConfig ManaBar = new DarkKnightManaBarConfig(
new Vector2(0, -61),
new Vector2(254, 10),
new PluginConfigColor(new Vector4(0f / 255f, 162f / 255f, 252f / 255f, 100f / 100f))
);
[NestedConfig("Blood Gauge", 35)]
public ChunkedProgressBarConfig BloodGauge = new ChunkedProgressBarConfig(
new Vector2(0, -49),
new Vector2(254, 10),
new PluginConfigColor(new Vector4(216f / 255f, 0f / 255f, 73f / 255f, 100f / 100f)),
2,
new PluginConfigColor(new Vector4(180f / 255f, 180f / 255f, 180f / 255f, 100f / 100f))
);
[NestedConfig("Darkside Bar", 40)]
public ProgressBarConfig DarksideBar = new ProgressBarConfig(
new Vector2(0, -73),
new Vector2(254, 10),
new PluginConfigColor(new Vector4(209f / 255f, 38f / 255f, 73f / 204f, 100f / 100f)),
BarDirection.Right,
new PluginConfigColor(new Vector4(160f / 255f, 0f / 255f, 0f / 255f, 100f / 100f)),
5
);
[NestedConfig("Blood Weapon Bar", 45)]
public DarkKnightChunkedBarConfig BloodWeaponBar = new DarkKnightChunkedBarConfig(
new Vector2(-64, -32),
new Vector2(126, 20),
new PluginConfigColor(new Vector4(160f / 255f, 0f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Delirium Bar", 50)]
public DarkKnightChunkedBarConfig DeliriumBar = new DarkKnightChunkedBarConfig(
new Vector2(64, -32),
new Vector2(126, 20),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Living Shadow Bar", 55)]
public ProgressBarConfig LivingShadowBar = new ProgressBarConfig(
new Vector2(0, -10),
new Vector2(254, 20),
new PluginConfigColor(new Vector4(255f / 255f, 105f / 255f, 205f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class DarkKnightManaBarConfig : ChunkedProgressBarConfig
{
[ColorEdit4("Dark Arts Color" + "##MP")]
[Order(26)]
public PluginConfigColor DarkArtsColor = new PluginConfigColor(new Vector4(210f / 255f, 33f / 255f, 33f / 255f, 100f / 100f));
[Checkbox("Show mana values up to 10k (will break thresholds)", spacing = true)]
[Order(27)]
public bool ShowFullMana = false;
public DarkKnightManaBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
[DisableParentSettings("UseChunks", "LabelMode")]
public class DarkKnightChunkedBarConfig : ChunkedProgressBarConfig
{
public DarkKnightChunkedBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
+172
View File
@@ -0,0 +1,172 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
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;
namespace HSUI.Interface.Jobs
{
public class DragoonHud : JobHud
{
private new DragoonConfig Config => (DragoonConfig)_config;
private static readonly List<uint> ChaosThrustIDs = new() { 118, 1312, 2719 };
private static readonly List<float> ChaosThrustDurations = new() { 24, 24, 24 };
public DragoonHud(DragoonConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.ChaosThrustBar.Enabled)
{
positions.Add(Config.Position + Config.ChaosThrustBar.Position);
sizes.Add(Config.ChaosThrustBar.Size);
}
if (Config.PowerSurgeBar.Enabled)
{
positions.Add(Config.Position + Config.PowerSurgeBar.Position);
sizes.Add(Config.PowerSurgeBar.Size);
}
if (Config.FirstmindsFocusBar.Enabled)
{
positions.Add(Config.Position + Config.FirstmindsFocusBar.Position);
sizes.Add(Config.FirstmindsFocusBar.Size);
}
if (Config.LifeOfTheDragonBar.Enabled)
{
positions.Add(Config.Position + Config.LifeOfTheDragonBar.Position);
sizes.Add(Config.LifeOfTheDragonBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
var position = origin + Config.Position;
if (Config.ChaosThrustBar.Enabled)
{
DrawChaosThrustBar(position, player);
}
if (Config.PowerSurgeBar.Enabled)
{
DrawPowerSurgeBar(position, player);
}
if (Config.FirstmindsFocusBar.Enabled)
{
DrawFirstmindsFocusBars(position, player);
}
if (Config.LifeOfTheDragonBar.Enabled)
{
DrawBloodOfTheDragonBar(position, player);
}
}
private void DrawChaosThrustBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.ChaosThrustBar, player, target, ChaosThrustIDs, ChaosThrustDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ChaosThrustBar.StrataLevel));
}
}
private void DrawFirstmindsFocusBars(Vector2 origin, IPlayerCharacter player)
{
DRGGauge gauge = Plugin.JobGauges.Get<DRGGauge>();
if (!Config.FirstmindsFocusBar.HideWhenInactive || gauge.FirstmindsFocusCount > 0)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.FirstmindsFocusBar, 2, gauge.FirstmindsFocusCount, 2, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.FirstmindsFocusBar.StrataLevel));
}
}
}
private void DrawBloodOfTheDragonBar(Vector2 origin, IPlayerCharacter player)
{
DRGGauge gauge = Plugin.JobGauges.Get<DRGGauge>();
float duration = gauge.LOTDTimer / 1000f;
if (!Config.LifeOfTheDragonBar.HideWhenInactive || duration > 0f)
{
Config.LifeOfTheDragonBar.Label.SetValue(duration);
BarHud bar = BarUtilities.GetProgressBar(Config.LifeOfTheDragonBar, duration, 20, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.LifeOfTheDragonBar.StrataLevel));
}
}
private void DrawPowerSurgeBar(Vector2 origin, IPlayerCharacter player)
{
var duration = Math.Abs(Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2720)?.RemainingTime ?? 0f);
if (!Config.PowerSurgeBar.HideWhenInactive || duration > 0f)
{
Config.PowerSurgeBar.Label.SetValue(duration);
BarHud bar = BarUtilities.GetProgressBar(Config.PowerSurgeBar, duration, 30f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.PowerSurgeBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Dragoon", 1)]
public class DragoonConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.DRG;
public new static DragoonConfig DefaultConfig() { return new DragoonConfig(); }
[NestedConfig("Chaos Thrust", 30)]
public ProgressBarConfig ChaosThrustBar = new ProgressBarConfig(
new(0, -76),
new(254, 20),
new(new Vector4(217f / 255f, 145f / 255f, 232f / 255f, 100f / 100f))
);
[NestedConfig("Power Surge", 35)]
public ProgressBarConfig PowerSurgeBar = new ProgressBarConfig(
new(0, -54),
new(254, 20),
new(new Vector4(244f / 255f, 206f / 255f, 191f / 255f, 100f / 100f))
);
[NestedConfig("Firstminds' Focus", 40)]
public ChunkedBarConfig FirstmindsFocusBar = new ChunkedBarConfig(
new(64, -32),
new(126, 20),
new PluginConfigColor(new(134f / 255f, 120f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Life of the Dragon", 45)]
public ProgressBarConfig LifeOfTheDragonBar = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new(new Vector4(185f / 255f, 0f / 255f, 25f / 255f, 100f / 100f))
);
}
}
+31
View File
@@ -0,0 +1,31 @@
using HSUI.Helpers;
using Newtonsoft.Json;
namespace HSUI.Interface.Jobs
{
public class GatherersConfig : JobConfig
{
public override uint JobId => 0;
public GatherersConfig()
{
UseDefaultPrimaryResourceBar = true;
PrimaryResourceType = PrimaryResourceTypes.GP;
}
}
public class MinerConfig : GatherersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.MIN;
}
public class BotanistConfig : GatherersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.BOT;
}
public class FisherConfig : GatherersConfig
{
[JsonIgnore] public override uint JobId => JobIDs.FSH;
}
}
+129
View File
@@ -0,0 +1,129 @@
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 HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class GunbreakerHud : JobHud
{
private new GunbreakerConfig Config => (GunbreakerConfig)_config;
public GunbreakerHud(GunbreakerConfig config, string? displayName = null) : base(config, displayName) { }
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.PowderGauge.Enabled)
{
positions.Add(Config.Position + Config.PowderGauge.Position);
sizes.Add(Config.PowderGauge.Size);
}
if (Config.NoMercy.Enabled)
{
positions.Add(Config.Position + Config.NoMercy.Position);
sizes.Add(Config.NoMercy.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
if (Config.PowderGauge.Enabled)
{
DrawPowderGauge(origin + Config.Position, player);
}
if (Config.NoMercy.Enabled)
{
DrawNoMercyBar(origin + Config.Position, player);
}
}
private void DrawPowderGauge(Vector2 origin, IPlayerCharacter player)
{
GNBGauge gauge = Plugin.JobGauges.Get<GNBGauge>();
if (Config.PowderGauge.HideWhenInactive && gauge.Ammo == 0)
{
return;
}
PluginConfigColor mainColor = Config.PowderGauge.FillColor;
PluginConfigColor extraColor = Config.PowderGauge.BloodfestExtraCartridgesColor;
int maxCartridges = player.Level >= 88 ? 3 : 2;
List<Tuple<PluginConfigColor, float, LabelConfig?>> chunks = new();
for (int i = 1; i < maxCartridges + 1; i++)
{
PluginConfigColor color = (gauge.Ammo < i || gauge.Ammo - maxCartridges < i) ? mainColor : extraColor;
chunks.Add(new(color, i <= gauge.Ammo ? 1 : 0, null));
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.PowderGauge, chunks.ToArray(), player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.PowderGauge.StrataLevel));
}
}
private void DrawNoMercyBar(Vector2 origin, IPlayerCharacter player)
{
float noMercyDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId == 1831 && o.RemainingTime > 0f)?.RemainingTime ?? 0f;
if (Config.NoMercy.HideWhenInactive && noMercyDuration <= 0)
{
return;
}
Config.NoMercy.Label.SetValue(noMercyDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.NoMercy, noMercyDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.NoMercy.StrataLevel));
}
}
[Section("Job Specific Bars")]
[SubSection("Tank", 0)]
[SubSection("Gunbreaker", 1)]
public class GunbreakerConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.GNB;
public new static GunbreakerConfig DefaultConfig() { return new GunbreakerConfig(); }
[NestedConfig("Powder Gauge", 30)]
public PowderGauge PowderGauge = new PowderGauge(
new(0, -32),
new(254, 20),
new(new Vector4(0f / 255f, 162f / 255f, 252f / 255f, 1f))
);
[NestedConfig("No Mercy", 35)]
public ProgressBarConfig NoMercy = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new(new Vector4(252f / 255f, 204f / 255f, 255f / 255f, 1f))
);
}
public class PowderGauge : ChunkedBarConfig
{
[ColorEdit4("Bloodfest Extra Cartridges Color")]
[Order(26)]
public PluginConfigColor BloodfestExtraCartridgesColor = new(new Vector4(240f / 255f, 200f / 255f, 0, 1));
public PowderGauge(Vector2 position, Vector2 size, PluginConfigColor fillColor, int padding = 2) : base(position, size, fillColor, padding)
{
}
}
}
+41
View File
@@ -0,0 +1,41 @@
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using Newtonsoft.Json;
using System;
using System.Reflection;
namespace HSUI.Interface.Jobs
{
public abstract class JobConfig : MovablePluginConfigObject
{
[JsonIgnore]
public abstract uint JobId { get; }
[Checkbox("Show Generic Mana Bar")]
[Order(20)]
public bool UseDefaultPrimaryResourceBar = false;
[NestedConfig("Visibility", 2000)]
public VisibilityConfig VisibilityConfig = new VisibilityConfig();
[JsonIgnore]
public PrimaryResourceTypes PrimaryResourceType = PrimaryResourceTypes.MP;
public new static JobConfig? DefaultConfig()
{
var type = MethodBase.GetCurrentMethod()?.DeclaringType;
if (type is null)
{
return null;
}
return (JobConfig?)Activator.CreateInstance(type);
}
public JobConfig()
{
Position.Y = HUDConstants.JobHudsBaseY;
}
}
}
+37
View File
@@ -0,0 +1,37 @@
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class JobHud : DraggableHudElement, IHudElementWithActor, IHudElementWithVisibilityConfig
{
protected IDalamudPluginInterface PluginInterface => Plugin.PluginInterface;
public JobConfig Config => (JobConfig)_config;
public VisibilityConfig VisibilityConfig => Config.VisibilityConfig;
public IGameObject? Actor { get; set; } = null;
protected IPlayerCharacter? Player => Actor is IPlayerCharacter ? (IPlayerCharacter)Actor : null;
public JobHud(JobConfig config, string? displayName = null) : base(config, displayName)
{
}
public override void DrawChildren(Vector2 origin)
{
if (Player == null || !_config.Enabled)
{
return;
}
DrawJobHud(origin, Player);
}
public virtual void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
// override
}
}
}
+257
View File
@@ -0,0 +1,257 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Logging;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class MachinistHud : JobHud
{
private bool _robotMaxDurationSet;
private float _robotMaxDuration;
private new MachinistConfig Config => (MachinistConfig)_config;
public MachinistHud(MachinistConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.OverheatChunkedGauge.Enabled)
{
positions.Add(Config.Position + Config.OverheatChunkedGauge.Position);
sizes.Add(Config.OverheatChunkedGauge.Size);
}
if (Config.HeatGauge.Enabled)
{
positions.Add(Config.Position + Config.HeatGauge.Position);
sizes.Add(Config.HeatGauge.Size);
}
if (Config.BatteryGauge.Enabled)
{
positions.Add(Config.Position + Config.BatteryGauge.Position);
sizes.Add(Config.BatteryGauge.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.OverheatChunkedGauge.Enabled)
{
DrawOverheatBar(pos, player);
}
if (Config.HeatGauge.Enabled)
{
DrawHeatGauge(pos, player);
}
if (Config.BatteryGauge.Enabled)
{
DrawBatteryGauge(pos, player);
}
if (Config.AutomatonBar.Enabled)
{
DrawAutomatonBar(pos, player);
}
if (Config.WildfireBar.Enabled)
{
DrawWildfireBar(pos, player);
}
}
private void DrawHeatGauge(Vector2 origin, IPlayerCharacter player)
{
MCHGauge gauge = Plugin.JobGauges.Get<MCHGauge>();
if (!Config.HeatGauge.HideWhenInactive || gauge.Heat > 0)
{
Config.HeatGauge.Label.SetValue(gauge.Heat);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.HeatGauge, 2, gauge.Heat, 100, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.HeatGauge.StrataLevel));
}
}
}
private void DrawBatteryGauge(Vector2 origin, IPlayerCharacter player)
{
MCHGauge gauge = Plugin.JobGauges.Get<MCHGauge>();
if (!Config.BatteryGauge.HideWhenInactive || gauge.Battery > 0)
{
Config.BatteryGauge.Label.SetValue(gauge.Battery);
BarHud bar = BarUtilities.GetProgressBar(Config.BatteryGauge, gauge.Battery, 100f, 0f, player, Config.BatteryGauge.BatteryColor);
AddDrawActions(bar.GetDrawActions(origin, Config.BatteryGauge.StrataLevel));
}
}
private void DrawAutomatonBar(Vector2 origin, IPlayerCharacter player)
{
MCHGauge gauge = Plugin.JobGauges.Get<MCHGauge>();
if (!gauge.IsRobotActive && _robotMaxDurationSet)
{
_robotMaxDurationSet = false;
}
if (!Config.AutomatonBar.HideWhenInactive || gauge.IsRobotActive)
{
float remaining = gauge.SummonTimeRemaining / 1000f;
if (!_robotMaxDurationSet && gauge.IsRobotActive)
{
_robotMaxDuration = remaining;
_robotMaxDurationSet = true;
}
Config.AutomatonBar.Label.SetValue(remaining);
BarHud bar = BarUtilities.GetProgressBar(Config.AutomatonBar, remaining, _robotMaxDuration > 0 ? _robotMaxDuration : 1f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.AutomatonBar.StrataLevel));
}
}
private void DrawOverheatBar(Vector2 origin, IPlayerCharacter player)
{
MCHGauge gauge = Plugin.JobGauges.Get<MCHGauge>();
ushort stackCount = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2688)?.Param ?? 0;
if (!Config.OverheatChunkedGauge.HideWhenInactive || stackCount > 0)
{
LabelConfig[]? labels = null;
if (Config.OverheatChunkedGauge.DurationLabel.Enabled)
{
Config.OverheatChunkedGauge.DurationLabel.SetValue(gauge.OverheatTimeRemaining / 1000f);
labels = new LabelConfig[5];
labels[2] = Config.OverheatChunkedGauge.DurationLabel;
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.OverheatChunkedGauge, 5, stackCount, 5, labels: labels );
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.OverheatChunkedGauge.StrataLevel));
}
}
}
private void DrawWildfireBar(Vector2 origin, IPlayerCharacter player)
{
float wildfireDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1946)?.RemainingTime ?? 0f;
if (!Config.WildfireBar.HideWhenInactive || wildfireDuration > 0)
{
Config.WildfireBar.Label.SetValue(wildfireDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.WildfireBar, wildfireDuration, 10, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.WildfireBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Ranged", 0)]
[SubSection("Machinist", 1)]
public class MachinistConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.MCH;
public new static MachinistConfig DefaultConfig()
{
var config = new MachinistConfig();
config.HeatGauge.UsePartialFillColor = true;
return config;
}
[NestedConfig("Overheat Gauge", 30)]
public MachinistOverheatBarConfig OverheatChunkedGauge = new MachinistOverheatBarConfig(
new Vector2(0, -54),
new Vector2(254, 20),
new PluginConfigColor(new Vector4(255f / 255f, 239f / 255f, 14f / 255f, 100f / 100f))
);
[NestedConfig("Heat Gauge", 35)]
public ChunkedProgressBarConfig HeatGauge = new ChunkedProgressBarConfig(
new Vector2(0, -32),
new Vector2(254, 20),
new PluginConfigColor(new Vector4(201f / 255f, 13f / 255f, 13f / 255f, 100f / 100f)),
2,
new PluginConfigColor(new Vector4(180f / 255f, 180f / 255f, 180f / 255f, 100f / 100f))
);
[NestedConfig("Battery Gauge", 40)]
public MachinistBatteryGaugeConfig BatteryGauge = new MachinistBatteryGaugeConfig(
new Vector2(-31, -10),
new Vector2(192, 20),
new PluginConfigColor(new Vector4(0, 0, 0, 0))
);
[NestedConfig("Automaton Queen Bar", 45)]
public ProgressBarConfig AutomatonBar = new ProgressBarConfig(
new Vector2(97, -10),
new Vector2(60, 20),
new PluginConfigColor(new Vector4(153f / 255f, 0f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Wildfire Bar", 50)]
public ProgressBarConfig WildfireBar = new ProgressBarConfig(
new Vector2(0, -76),
new Vector2(254, 20),
new PluginConfigColor(new Vector4(255f / 255f, 0f / 255f, 0f / 255f, 100f / 100f)),
BarDirection.Right,
new PluginConfigColor(new Vector4(180f / 255f, 180f / 255f, 180f / 255f, 100f / 100f)),
50
);
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class MachinistBatteryGaugeConfig : ProgressBarConfig
{
[ColorEdit4("Battery Color", spacing = true)]
[Order(55)]
public PluginConfigColor BatteryColor = new(new Vector4(106f / 255f, 255f / 255f, 255f / 255f, 100f / 100f));
public MachinistBatteryGaugeConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class MachinistOverheatBarConfig : ChunkedBarConfig
{
[NestedConfig("Duration Text", 1000)]
public NumericLabelConfig DurationLabel;
public MachinistOverheatBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
DurationLabel = new NumericLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
DurationLabel.HideIfZero = true;
}
}
}
+464
View File
@@ -0,0 +1,464 @@
using Dalamud.Game.ClientState.JobGauge.Enums;
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.Game;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class MonkHud : JobHud
{
private new MonkConfig Config => (MonkConfig)_config;
private string[] _chunkTexts = new string[] { "I", "II", "III" };
public MonkHud(MonkConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.ChakraBar.Enabled)
{
positions.Add(Config.Position + Config.ChakraBar.Position);
sizes.Add(Config.ChakraBar.Size);
}
if (Config.BeastChakraStacksBar.Enabled)
{
positions.Add(Config.Position + Config.BeastChakraStacksBar.Position);
sizes.Add(Config.BeastChakraStacksBar.Size);
}
if (Config.MastersGauge.Enabled)
{
positions.Add(Config.Position + Config.MastersGauge.Position);
sizes.Add(Config.MastersGauge.Size);
}
if (Config.StancesBar.Enabled)
{
positions.Add((Config.Position + Config.StancesBar.Position));
sizes.Add(Config.StancesBar.Size);
}
if (Config.PerfectBalanceBar.Enabled)
{
positions.Add(Config.Position + Config.PerfectBalanceBar.Position);
sizes.Add(Config.PerfectBalanceBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
var position = origin + Config.Position;
if (Config.ChakraBar.Enabled)
{
DrawChakraGauge(position, player);
}
if (Config.BeastChakraStacksBar.Enabled)
{
DrawBeastChakraStacksBar(position, player);
}
if (Config.MastersGauge.Enabled)
{
DrawMastersGauge(position, player);
}
if (Config.StancesBar.Enabled)
{
DrawFormsBar(position, player);
}
if (Config.PerfectBalanceBar.Enabled)
{
DrawPerfectBalanceBar(position, player);
}
}
private void DrawChakraGauge(Vector2 origin, IPlayerCharacter player)
{
MNKGauge gauge = Plugin.JobGauges.Get<MNKGauge>();
if (Config.ChakraBar.HideWhenInactive && gauge.Chakra == 0)
{
return;
}
PluginConfigColor mainColor = Config.ChakraBar.FillColor;
PluginConfigColor extraColor = Config.ChakraBar.BrotherhoodExtraCharkaColor;
List<Tuple<PluginConfigColor, float, LabelConfig?>> chunks = new();
for (int i = 1; i < 6; i++)
{
PluginConfigColor color = (gauge.Chakra < i || gauge.Chakra - 5 < i) ? mainColor : extraColor;
chunks.Add(new(color, i <= gauge.Chakra ? 1 : 0, null));
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.ChakraBar, chunks.ToArray(), player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ChakraBar.StrataLevel));
}
}
private unsafe void DrawBeastChakraStacksBar(Vector2 origin, IPlayerCharacter player)
{
MonkBeastChakraStacksBar config = Config.BeastChakraStacksBar;
MNKGauge gauge = Plugin.JobGauges.Get<MNKGauge>();
int stacks = gauge.OpoOpoFury + gauge.RaptorFury + gauge.CoeurlFury;
if (config.HideWhenInactive && stacks == 0)
{
return;
}
PluginConfigColor empty = PluginConfigColor.Empty;
Tuple<PluginConfigColor, float, LabelConfig?>[] chunks =
[
new(gauge.OpoOpoFury > 0 ? config.OpoopoColor : empty, 1, null),
new(gauge.RaptorFury > 0 ? config.RaptorColor : empty, 1, null),
new(gauge.CoeurlFury > 0 ? config.CoeurlColor : empty, 1, null),
new(gauge.CoeurlFury > 1 ? config.CoeurlColor : empty, 1, null),
];
BarHud[] bars = BarUtilities.GetChunkedBars(config, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawMastersGauge(Vector2 origin, IPlayerCharacter player)
{
MNKGauge gauge = Plugin.JobGauges.Get<MNKGauge>();
if (Config.MastersGauge.HideWhenInactive &&
gauge.Nadi == Nadi.None &&
gauge.BeastChakra[0] == BeastChakra.None &&
gauge.BeastChakra[1] == BeastChakra.None &&
gauge.BeastChakra[2] == BeastChakra.None)
{
return;
}
int[] order = Config.MastersGauge.ChakraOrder;
int[] hasChakra =
[
gauge.Nadi.HasFlag(Nadi.Lunar) ? 1 : 0,
gauge.BeastChakra[0] != BeastChakra.None ? 1 : 0,
gauge.BeastChakra[0] != BeastChakra.None ? 1 : 0,
gauge.BeastChakra[0] != BeastChakra.None ? 1 : 0,
gauge.Nadi.HasFlag(Nadi.Solar) ? 1 : 0,
];
PluginConfigColor[] colors = new[]
{
Config.MastersGauge.LunarNadiColor,
GetChakraColor(gauge.BeastChakra[0]),
GetChakraColor(gauge.BeastChakra[1]),
GetChakraColor(gauge.BeastChakra[2]),
Config.MastersGauge.SolarNadiColor
};
var chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[5];
for (int i = 0; i < chunks.Length; i++)
{
chunks[i] = new(colors[order[i]], hasChakra[order[i]], i == 2 ? Config.MastersGauge.BlitzTimerLabel : null);
}
Config.MastersGauge.BlitzTimerLabel.SetValue(gauge.BlitzTimeRemaining / 1000);
BarHud[] bars = BarUtilities.GetChunkedBars(Config.MastersGauge, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.MastersGauge.StrataLevel));
}
}
private void DrawFormsBar(Vector2 origin, IPlayerCharacter player)
{
// formless fist
IStatus? formlessFist = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId == 2513);
if (formlessFist != null)
{
float remaining = Math.Abs(formlessFist.RemainingTime);
BarHud bar = BarUtilities.GetProgressBar(
Config.StancesBar,
null,
new LabelConfig[] { Config.StancesBar.FormlessFistLabel },
remaining,
30f,
0,
player,
Config.StancesBar.FormlessFistColor
);
Config.StancesBar.FormlessFistLabel.SetValue(remaining);
AddDrawActions(bar.GetDrawActions(origin, Config.StancesBar.StrataLevel));
return;
}
// forms
IStatus? form = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 107 or 108 or 109);
if (Config.StancesBar.HideWhenInactive && form is null)
{
return;
}
int activeFormIndex = form != null ? (int)form.StatusId - 107 : -1;
PluginConfigColor[] chunkColors = new PluginConfigColor[]
{
Config.StancesBar.OpoOpoColor,
Config.StancesBar.RaptorColor,
Config.StancesBar.CoeurlColor
};
LabelConfig[] chunkLabels = new LabelConfig[]
{
Config.StancesBar.FormLabel.Clone(0),
Config.StancesBar.FormLabel.Clone(1),
Config.StancesBar.FormLabel.Clone(2)
};
var chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < chunks.Length; i++)
{
LabelConfig label = chunkLabels[i];
label.SetText(_chunkTexts[i]);
chunks[i] = new(chunkColors[i], activeFormIndex == i ? 1 : 0, label);
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.StancesBar, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.StancesBar.StrataLevel));
}
}
private void DrawPerfectBalanceBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? perfectBalance = Utils.StatusListForBattleChara(player).Where(o => o.StatusId is 110 && o.RemainingTime > 0f).FirstOrDefault();
float duration = perfectBalance?.RemainingTime ?? 0f;
float stacks = perfectBalance?.Param ?? 0f;
if (Config.PerfectBalanceBar.HideWhenInactive && duration <= 0)
{
return;
}
Tuple<PluginConfigColor, float, LabelConfig?>[] chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < chunks.Length; i++)
{
chunks[i] = new(
Config.PerfectBalanceBar.FillColor,
i < stacks ? 1f : 0,
i == 1 ? Config.PerfectBalanceBar.PerfectBalanceLabel : null
);
}
Config.PerfectBalanceBar.PerfectBalanceLabel.SetValue(duration);
BarHud[] bars = BarUtilities.GetChunkedBars(Config.PerfectBalanceBar, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.PerfectBalanceBar.StrataLevel));
}
}
private PluginConfigColor GetChakraColor(BeastChakra chakra) => chakra switch
{
BeastChakra.OpoOpo => Config.MastersGauge.OpoopoChakraColor,
BeastChakra.Raptor => Config.MastersGauge.RaptorChakraColor,
BeastChakra.Coeurl => Config.MastersGauge.CoeurlChakraColor,
_ => new PluginConfigColor(new(0, 0, 0, 0))
};
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Monk", 1)]
public class MonkConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.MNK;
public new static MonkConfig DefaultConfig()
{
var config = new MonkConfig();
config.StancesBar.Enabled = false;
config.MastersGauge.BlitzTimerLabel.HideIfZero = true;
config.PerfectBalanceBar.PerfectBalanceLabel.HideIfZero = true;
return config;
}
[NestedConfig("Chakra Bar", 35)]
public ChakraBar ChakraBar = new ChakraBar(
new(0, -32),
new(254, 20),
new(new Vector4(204f / 255f, 115f / 255f, 0f, 100f / 100f))
);
[NestedConfig("Fury Stacks Bar", 40)]
public MonkBeastChakraStacksBar BeastChakraStacksBar = new MonkBeastChakraStacksBar(
new(0, -32),
new(254, 20)
);
[NestedConfig("Masterful Blitz Bar", 45)]
public MastersGauge MastersGauge = new MastersGauge(
new(0, -54),
new(254, 20)
);
[NestedConfig("Forms Bar", 50)]
public MonkStancesBarConfig StancesBar = new MonkStancesBarConfig(
new(0, -98),
new(254, 20)
);
[NestedConfig("Perfect Balance Bar", 55)]
public PerfectBalanceBar PerfectBalanceBar = new PerfectBalanceBar(
new(0, -76),
new(254, 20),
new(new Vector4(150f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
}
public class ChakraBar: ChunkedBarConfig
{
[ColorEdit4("Brotherhood Extra Chakra Color")]
[Order(26)]
public PluginConfigColor BrotherhoodExtraCharkaColor = new(new Vector4(204f / 255f, 0, 0, 1));
public ChakraBar(Vector2 position, Vector2 size, PluginConfigColor fillColor, int padding = 2) : base(position, size, fillColor, padding)
{
}
}
public class PerfectBalanceBar : ChunkedBarConfig
{
[NestedConfig("Perfect Balance Duration Text", 50, spacing = true)]
public NumericLabelConfig PerfectBalanceLabel;
public PerfectBalanceBar(Vector2 position, Vector2 size, PluginConfigColor fillColor, int padding = 2) : base(position, size, fillColor, padding)
{
PerfectBalanceLabel = new NumericLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
}
}
[DisableParentSettings("FillColor", "FillDirection")]
public class MonkBeastChakraStacksBar : ChunkedBarConfig
{
[ColorEdit4("Opo-opo Color")]
[Order(19)]
public PluginConfigColor OpoopoColor = PluginConfigColor.FromHex(0xFFFFB3D3);
[ColorEdit4("Raptor Color")]
[Order(20)]
public PluginConfigColor RaptorColor = PluginConfigColor.FromHex(0xFFBF89E5);
[ColorEdit4("Coeurl Color")]
[Order(21)]
public PluginConfigColor CoeurlColor = PluginConfigColor.FromHex(0xFF9AE7C0);
public MonkBeastChakraStacksBar(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
[DisableParentSettings("FillColor", "FillDirection")]
public class MastersGauge : ChunkedBarConfig
{
[ColorEdit4("Lunar Nadi Color")]
[Order(19)]
public PluginConfigColor LunarNadiColor = PluginConfigColor.FromHex(0xFFDA87FF);
[ColorEdit4("Solar Nadi Color")]
[Order(20)]
public PluginConfigColor SolarNadiColor = PluginConfigColor.FromHex(0xFFFFFFCA);
[ColorEdit4("Opo-opo Color")]
[Order(21)]
public PluginConfigColor OpoopoChakraColor = PluginConfigColor.FromHex(0xFFC1527E);
[ColorEdit4("Raptor Color")]
[Order(22)]
public PluginConfigColor RaptorChakraColor = PluginConfigColor.FromHex(0xFF8C67BA);
[ColorEdit4("Coeurl Color")]
[Order(23)]
public PluginConfigColor CoeurlChakraColor = PluginConfigColor.FromHex(0xFF326D5A);
[DragDropHorizontal("Chakra Order", "Lunar Nadi", "Chakra 1", "Chakra 2", "Chakra 3", "Solar Nadi")]
[Order(24)]
public int[] ChakraOrder = new int[] { 0, 1, 2, 3, 4 };
[NestedConfig("Blitz Timer Text", 50, spacing = true)]
public NumericLabelConfig BlitzTimerLabel;
public MastersGauge(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
BlitzTimerLabel = new NumericLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
}
}
[DisableParentSettings("FillColor")]
public class MonkStancesBarConfig : ChunkedBarConfig
{
[ColorEdit4("Opo-opo Color")]
[Order(19)]
public PluginConfigColor OpoOpoColor = PluginConfigColor.FromHex(0xFFFFB3D3);
[ColorEdit4("Raptor Color")]
[Order(20)]
public PluginConfigColor RaptorColor = PluginConfigColor.FromHex(0xFFBF89E5);
[ColorEdit4("Coeurl Color")]
[Order(21)]
public PluginConfigColor CoeurlColor = PluginConfigColor.FromHex(0xFF9AE7C0);
[ColorEdit4("Formless Fist Color")]
[Order(22)]
public PluginConfigColor FormlessFistColor = PluginConfigColor.FromHex(0xFF514793);
[NestedConfig("Form Number Text", 500, spacing = true)]
public LabelConfig FormLabel;
[NestedConfig("Formless Fist Duration Text", 1000, separator = false, spacing = true)]
public NumericLabelConfig FormlessFistLabel;
public MonkStancesBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
FormLabel = new LabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
FormlessFistLabel = new NumericLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
FormlessFistLabel.Enabled = false;
}
}
}
+341
View File
@@ -0,0 +1,341 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.Game.Gauge;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class NinjaHud : JobHud
{
private new NinjaConfig Config => (NinjaConfig)_config;
public NinjaHud(NinjaConfig config, string? displayName = null) : base(config, displayName) { }
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.KazematoiBar.Enabled)
{
positions.Add(Config.Position + Config.KazematoiBar.Position);
sizes.Add(Config.KazematoiBar.Size);
}
if (Config.NinkiBar.Enabled)
{
positions.Add(Config.Position + Config.NinkiBar.Position);
sizes.Add(Config.NinkiBar.Size);
}
if (Config.TrickAttackBar.Enabled)
{
positions.Add(Config.Position + Config.TrickAttackBar.Position);
sizes.Add(Config.TrickAttackBar.Size);
}
if (Config.SuitonBar.Enabled)
{
positions.Add(Config.Position + Config.SuitonBar.Position);
sizes.Add(Config.SuitonBar.Size);
}
if (Config.MudraBar.Enabled)
{
positions.Add(Config.Position + Config.MudraBar.Position);
sizes.Add(Config.MudraBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
var pos = origin + Config.Position;
if (Config.MudraBar.Enabled)
{
DrawMudraBars(pos, player);
}
if (Config.KazematoiBar.Enabled)
{
DrawKazematoiBar(pos, player);
}
if (Config.NinkiBar.Enabled)
{
DrawNinkiGauge(pos, player);
}
if (Config.TrickAttackBar.Enabled)
{
DrawTrickAttackBar(pos, player);
}
if (Config.SuitonBar.Enabled)
{
DrawSuitonBar(pos, player);
}
}
public (bool, bool, bool) GetMudraBuffs(IPlayerCharacter? player, out IStatus? ninjutsuBuff, out IStatus? kassatsuBuff, out IStatus? tcjBuff)
{
ninjutsuBuff = null;
kassatsuBuff = null;
tcjBuff = null;
if (player is not null)
{
var statusList = Utils.StatusListForBattleChara(player);
foreach (IStatus status in statusList)
{
if (status.StatusId == 496) { ninjutsuBuff = status; }
if (status.StatusId == 497) { kassatsuBuff = status; }
if (status.StatusId == 1186) { tcjBuff = status; }
}
}
return (ninjutsuBuff is not null, kassatsuBuff is not null, tcjBuff is not null);
}
private void DrawMudraBars(Vector2 origin, IPlayerCharacter player)
{
var (hasNinjutsuBuff, hasKassatsuBuff, hasTCJBuff) = GetMudraBuffs(player, out IStatus? ninjutsuBuff, out IStatus? kassatsuBuff, out IStatus? tcjBuff);
int mudraStacks = SpellHelper.Instance.GetStackCount(2, 2259);
float mudraCooldown = SpellHelper.Instance.GetSpellCooldown(2259);
float current = 0f;
float max = 0f;
// For some reason, the mudras may be on cooldown before the "Mudra" buff is applied.
// Mudra stack count is set to -2 when a mudra is in the middle of its re-cast timer, so we can check for that instead.
bool inNinjutsu = mudraStacks == -2 || hasNinjutsuBuff;
if (hasTCJBuff || hasKassatsuBuff || inNinjutsu)
{
if (hasTCJBuff)
{
max = 6f;
current = tcjBuff is null || tcjBuff.RemainingTime < 0 ? max : tcjBuff.RemainingTime;
Config.MudraBar.Label.SetText(GenerateNinjutsuText(tcjBuff?.Param ?? 0, hasKassatsuBuff, hasTCJBuff));
}
else if (hasKassatsuBuff)
{
max = 15f;
current = kassatsuBuff is null || kassatsuBuff.RemainingTime < 0 ? max : kassatsuBuff.RemainingTime;
Config.MudraBar.Label.SetText("KASSATSU");
}
if (inNinjutsu)
{
max = 6f;
current = ninjutsuBuff is null || ninjutsuBuff.RemainingTime < 0 ? max : ninjutsuBuff.RemainingTime;
Config.MudraBar.Label.SetText(GenerateNinjutsuText(ninjutsuBuff?.Param ?? 0, hasKassatsuBuff, hasTCJBuff));
}
PluginConfigColor fillColor = hasTCJBuff ? Config.MudraBar.TCJBarColor : hasKassatsuBuff ? Config.MudraBar.KassatsuBarColor : Config.MudraBar.FillColor;
Rect foreground = BarUtilities.GetFillRect(Config.MudraBar.Position, Config.MudraBar.Size, Config.MudraBar.FillDirection, fillColor, current, max);
BarHud bar = new BarHud(Config.MudraBar, player);
bar.AddForegrounds(foreground);
bar.AddLabels(Config.MudraBar.Label);
AddDrawActions(bar.GetDrawActions(origin, Config.MudraBar.StrataLevel));
}
else
{
max = 40f;
current = max - mudraCooldown;
if (!Config.MudraBar.HideWhenInactive || current < max)
{
Config.MudraBar.Label.SetValue((max - current) % 20);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.MudraBar, 2, current, max, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.MudraBar.StrataLevel));
}
}
}
}
private unsafe void DrawKazematoiBar(Vector2 origin, IPlayerCharacter player)
{
NinjaGauge* gauge = (NinjaGauge*)Plugin.JobGauges.Get<NINGauge>().Address;
int stacks = gauge->Kazematoi;
if (Config.KazematoiBar.HideWhenInactive && stacks == 0)
{
return;
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.KazematoiBar, 5, stacks, 5, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.KazematoiBar.StrataLevel));
}
}
private unsafe void DrawNinkiGauge(Vector2 origin, IPlayerCharacter player)
{
NinjaGauge* gauge = (NinjaGauge*)Plugin.JobGauges.Get<NINGauge>().Address;
int ninki = gauge->Ninki;
if (Config.NinkiBar.HideWhenInactive && ninki == 0)
{
return;
}
Config.NinkiBar.Label.SetValue(ninki);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.NinkiBar, 2, ninki, 100, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.NinkiBar.StrataLevel));
}
}
private void DrawTrickAttackBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? actor = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
float trickDuration = Utils.StatusListForActor(actor).FirstOrDefault(
o => o.StatusId is 3254 or 3906 && o.SourceId == player.GameObjectId && o.RemainingTime > 0
)?.RemainingTime ?? 0f;
if (Config.TrickAttackBar.HideWhenInactive && trickDuration == 0)
{
return;
}
Config.TrickAttackBar.Label.SetValue(trickDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.TrickAttackBar, trickDuration, 15f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.TrickAttackBar.StrataLevel));
}
private void DrawSuitonBar(Vector2 origin, IPlayerCharacter player)
{
float suitonDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(
o => o.StatusId == 3848 && o.RemainingTime > 0
)?.RemainingTime ?? 0f;
if (Config.SuitonBar.HideWhenInactive && suitonDuration == 0)
{
return;
}
Config.SuitonBar.Label.SetValue(suitonDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.SuitonBar, suitonDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.SuitonBar.StrataLevel));
}
private string GenerateNinjutsuText(ushort param, bool haveKassatsuBuff, bool haveTCJBuff)
{
return param switch
{
1 or 2 or 3 => "FUMA SHURIKEN",
6 or 7 => haveKassatsuBuff ? "GOKA MEKKYAKU" : "KATON",
9 or 11 => "RAITON",
13 or 14 => haveKassatsuBuff ? "HYOSHO RANRYU" : "HYOTON",
27 or 30 => "HUTON",
39 or 45 => "DOTON",
54 or 57 => "SUITON",
_ => haveTCJBuff ? "TEN CHI JIN" : "",
};
}
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Ninja", 1)]
public class NinjaConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.NIN;
public new static NinjaConfig DefaultConfig()
{
var config = new NinjaConfig();
config.MudraBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.MudraBar.LabelMode = LabelMode.ActiveChunk;
config.TrickAttackBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.TrickAttackBar.Enabled = false;
config.SuitonBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.SuitonBar.Enabled = false;
config.NinkiBar.UsePartialFillColor = true;
return config;
}
[NestedConfig("Mudra Bar", 30)]
public NinjaMudraBarConfig MudraBar = new NinjaMudraBarConfig(
new(0, -50),
new(254, 10),
new PluginConfigColor(new Vector4(211f / 255f, 166f / 255f, 75f / 242f, 100f / 100f))
);
[NestedConfig("Kazematoi Bar", 35)]
public ChunkedBarConfig KazematoiBar = new ChunkedBarConfig(
new(0, -10),
new(254, 20),
PluginConfigColor.FromHex(0xFFABB6BD)
);
[NestedConfig("Ninki Bar", 40)]
public ChunkedProgressBarConfig NinkiBar = new ChunkedProgressBarConfig(
new(0, -32),
new(254, 20),
new PluginConfigColor(new Vector4(137f / 255f, 82f / 255f, 236f / 255f, 100f / 100f))
);
[NestedConfig("Trick Attack Bar", 45)]
public ProgressBarConfig TrickAttackBar = new ProgressBarConfig(
new(0, -63),
new(254, 10),
new PluginConfigColor(new Vector4(191f / 255f, 40f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Shadow Walker Bar", 50)]
public ProgressBarConfig SuitonBar = new ProgressBarConfig(
new(0, -75),
new(254, 10),
new PluginConfigColor(new Vector4(202f / 255f, 228f / 255f, 246f / 242f, 100f / 100f))
);
}
[Exportable(false)]
public class NinjaMudraBarConfig : ChunkedProgressBarConfig
{
[ColorEdit4("Kassatsu Color", spacing = true)]
[Order(60)]
public PluginConfigColor KassatsuBarColor = new(new Vector4(239 / 255f, 123 / 255f, 222 / 242f, 100f / 100f));
[ColorEdit4("Ten Chi Jin Color")]
[Order(65)]
public PluginConfigColor TCJBarColor = new(new Vector4(181 / 255f, 33 / 255f, 41 / 242f, 100f / 100f));
public NinjaMudraBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor, 2)
{
Label.Enabled = true;
UsePartialFillColor = true;
}
}
}
+164
View File
@@ -0,0 +1,164 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Security.Principal;
namespace HSUI.Interface.Jobs
{
public class PaladinHud : JobHud
{
private new PaladinConfig Config => (PaladinConfig)_config;
public PaladinHud(PaladinConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.OathGauge.Enabled)
{
positions.Add(Config.Position + Config.OathGauge.Position);
sizes.Add(Config.OathGauge.Size);
}
if (Config.FightOrFlightBar.Enabled)
{
positions.Add(Config.Position + Config.FightOrFlightBar.Position);
sizes.Add(Config.FightOrFlightBar.Size);
}
if (Config.RequiescatStacksBar.Enabled)
{
positions.Add(Config.Position + Config.RequiescatStacksBar.Position);
sizes.Add(Config.RequiescatStacksBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.OathGauge.Enabled)
{
DrawOathGauge(pos, player);
}
if (Config.FightOrFlightBar.Enabled)
{
DrawFightOrFlightBar(pos, player);
}
if (Config.RequiescatStacksBar.Enabled)
{
DrawRequiescatBar(pos, player);
}
}
private void DrawOathGauge(Vector2 origin, IPlayerCharacter player)
{
PLDGauge gauge = Plugin.JobGauges.Get<PLDGauge>();
if (!Config.OathGauge.HideWhenInactive || gauge.OathGauge > 0)
{
Config.OathGauge.Label.SetValue(gauge.OathGauge);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.OathGauge, 2, gauge.OathGauge, 100, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.OathGauge.StrataLevel));
}
}
}
private void DrawFightOrFlightBar(Vector2 origin, IPlayerCharacter player)
{
float fightOrFlightDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 76)?.RemainingTime ?? 0f;
if (!Config.FightOrFlightBar.HideWhenInactive || fightOrFlightDuration > 0)
{
Config.FightOrFlightBar.Label.SetValue(fightOrFlightDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.FightOrFlightBar, fightOrFlightDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.FightOrFlightBar.StrataLevel));
}
}
private void DrawRequiescatBar(Vector2 origin, IPlayerCharacter player)
{
IStatus? requiescatBuff = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1368);
float requiescatDuration = Math.Max(0f, requiescatBuff?.RemainingTime ?? 0f);
int stacks = requiescatBuff?.Param ?? 0;
if (!Config.RequiescatStacksBar.HideWhenInactive || requiescatDuration > 0)
{
Config.RequiescatStacksBar.Label.SetValue(requiescatDuration);
LabelConfig[] labels = new LabelConfig[4];
labels[2] = Config.RequiescatStacksBar.Label;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.RequiescatStacksBar, 4, stacks, 4, labels: labels);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.RequiescatStacksBar.StrataLevel));
}
}
}
}
[Section("Job Specific Bars")]
[SubSection("Tank", 0)]
[SubSection("Paladin", 1)]
public class PaladinConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.PLD;
public new static PaladinConfig DefaultConfig()
{
var config = new PaladinConfig();
config.UseDefaultPrimaryResourceBar = true;
config.OathGauge.UsePartialFillColor = true;
config.RequiescatStacksBar.Label.Enabled = true;
return config;
}
[NestedConfig("Oath Gauge", 35)]
public ChunkedProgressBarConfig OathGauge = new ChunkedProgressBarConfig(
new Vector2(0, -54),
new Vector2(254, 20),
new PluginConfigColor(new Vector4(24f / 255f, 80f / 255f, 175f / 255f, 100f / 100f)),
2,
new PluginConfigColor(new Vector4(180f / 255f, 180f / 255f, 180f / 255f, 100f / 100f))
);
[NestedConfig("Fight or Flight Bar", 40)]
public ProgressBarConfig FightOrFlightBar = new ProgressBarConfig(
new Vector2(-64, -32),
new Vector2(126, 20),
new PluginConfigColor(new Vector4(240f / 255f, 50f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Requiescat Bar", 45)]
public ChunkedProgressBarConfig RequiescatStacksBar = new ChunkedProgressBarConfig(
new Vector2(64, -32),
new Vector2(126, 20),
new PluginConfigColor(new Vector4(61f / 255f, 61f / 255f, 255f / 255f, 100f / 100f))
);
}
}
+537
View File
@@ -0,0 +1,537 @@
using Dalamud.Game.ClientState.JobGauge.Enums;
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Statuses;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text.Json.Serialization;
namespace HSUI.Interface.Jobs
{
public class PictomancerHud : JobHud
{
private new PictomancerConfig Config => (PictomancerConfig)_config;
private static PluginConfigColor EmptyColor => GlobalColors.Instance.EmptyColor;
public PictomancerHud(PictomancerConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.PaletteBar.Enabled)
{
positions.Add(Config.Position + Config.PaletteBar.Position);
sizes.Add(Config.PaletteBar.Size);
}
if (Config.PaintBar.Enabled)
{
positions.Add(Config.Position + Config.PaintBar.Position);
sizes.Add(Config.PaintBar.Size);
}
if (Config.CreatureCanvasBar.Enabled)
{
positions.Add(Config.Position + Config.CreatureCanvasBar.Position);
sizes.Add(Config.CreatureCanvasBar.Size);
}
if (Config.WeaponCanvasBar.Enabled)
{
positions.Add(Config.Position + Config.WeaponCanvasBar.Position);
sizes.Add(Config.WeaponCanvasBar.Size);
}
if (Config.LandscapeCanvasBar.Enabled)
{
positions.Add(Config.Position + Config.LandscapeCanvasBar.Position);
sizes.Add(Config.LandscapeCanvasBar.Size);
}
if (Config.HammerTimeBar.Enabled)
{
positions.Add(Config.Position + Config.HammerTimeBar.Position);
sizes.Add(Config.HammerTimeBar.Size);
}
if (Config.HyperphantasiaBar.Enabled)
{
positions.Add(Config.Position + Config.HyperphantasiaBar.Position);
sizes.Add(Config.HyperphantasiaBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.PaletteBar.Enabled)
{
DrawPaletteBar(pos, player);
}
if (Config.PaintBar.Enabled)
{
DrawPaintBar(pos, player);
}
if (Config.CreatureCanvasBar.Enabled)
{
DrawCreatureCanvasBar(pos, player);
}
if (Config.WeaponCanvasBar.Enabled)
{
DrawWeaponCanvasBar(pos, player);
}
if (Config.LandscapeCanvasBar.Enabled)
{
DrawLandscapeCanvasBar(pos, player);
}
if (Config.HammerTimeBar.Enabled)
{
DrawHammerTimeBar(pos, player);
}
if (Config.HyperphantasiaBar.Enabled)
{
DrawHyperphantasiaBar(pos, player);
}
}
protected unsafe void DrawPaletteBar(Vector2 origin, IPlayerCharacter player)
{
PictomancerPaletteBarConfig config = Config.PaletteBar;
PCTGauge gauge = Plugin.JobGauges.Get<PCTGauge>();
if (config.HideWhenInactive && gauge.PalleteGauge == 0)
{
return;
}
bool isSubstractive = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3674) != null;
config.Label = config.PaletteLabel;
config.PaletteLabel.SubtractiveMode = isSubstractive;
config.Label.SetValue(gauge.PalleteGauge);
PluginConfigColor fillColor = isSubstractive ? config.SubtractiveColor : config.FillColor;
BarHud[] bars = BarUtilities.GetChunkedProgressBars(
config,
2,
gauge.PalleteGauge,
100,
0,
player,
fillColor: fillColor
);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawPaintBar(Vector2 origin, IPlayerCharacter player)
{
PictomancerPaintBarConfig config = Config.PaintBar;
PCTGauge gauge = Plugin.JobGauges.Get<PCTGauge>();
if (config.HideWhenInactive && gauge.Paint == 0)
{
return;
}
bool hasBlackPaint = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3691) != null;
Tuple<PluginConfigColor, float, LabelConfig?>[] chunks = new Tuple<PluginConfigColor, float, LabelConfig?>[5];
for (int i = 0; i < 5; i++)
{
PluginConfigColor color = PluginConfigColor.Empty;
if (i < gauge.Paint)
{
color = i == gauge.Paint - 1 && hasBlackPaint ? config.BlackPaintColor : config.WhitePaintColor;
}
chunks[i] = new(color, 1, null);
}
BarHud[] bars = BarUtilities.GetChunkedBars(config, chunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawCreatureCanvasBar(Vector2 origin, IPlayerCharacter player)
{
PictomancerCreatureCanvasBarConfig config = Config.CreatureCanvasBar;
PCTGauge gauge = Plugin.JobGauges.Get<PCTGauge>();
if (config.HideWhenInactive && !gauge.CreatureMotifDrawn && gauge.CreatureFlags != 0)
{
return;
}
// canvas
PluginConfigColor? canvasColor = null;
if (gauge.CanvasFlags.HasFlag(CanvasFlags.Maw))
{
canvasColor = config.FangsColor;
}
else if (gauge.CanvasFlags.HasFlag(CanvasFlags.Claw))
{
canvasColor = config.ClawColor;
}
else if (gauge.CanvasFlags.HasFlag(CanvasFlags.Wing))
{
canvasColor = config.WingsColor;
}
else if(gauge.CanvasFlags.HasFlag(CanvasFlags.Pom))
{
canvasColor = config.PomColor;
}
Tuple<PluginConfigColor, float, LabelConfig?> canvas = new(
canvasColor ?? PluginConfigColor.Empty,
canvasColor != null ? 1 : 0,
null
);
// part drawing
PluginConfigColor? drawingColor = null;
if (gauge.CreatureFlags.HasFlag(CreatureFlags.Claw))
{
drawingColor = config.ClawColor;
}
else if (config.ShowEmptyPomWings &&
gauge.CreatureFlags.HasFlag(CreatureFlags.Pom) &&
gauge.CreatureFlags.HasFlag(CreatureFlags.Wings))
{
drawingColor = PluginConfigColor.Empty;
}
else if (gauge.CreatureFlags.HasFlag(CreatureFlags.Wings))
{
drawingColor = config.WingsColor;
}
else if(gauge.CreatureFlags.HasFlag(CreatureFlags.Pom))
{
drawingColor = config.PomColor;
}
Tuple<PluginConfigColor, float, LabelConfig?> drawing = new(
drawingColor ?? PluginConfigColor.Empty,
drawingColor != null ? 1 : 0,
null
);
// portrait
PluginConfigColor? portraitColor = null;
if (gauge.CreatureFlags.HasFlag(CreatureFlags.MooglePortait))
{
portraitColor = config.MoogleColor;
}
else if (gauge.CreatureFlags.HasFlag(CreatureFlags.MadeenPortrait))
{
portraitColor = config.MadeenColor;
}
Tuple<PluginConfigColor, float, LabelConfig?> portrait = new(
portraitColor ?? PluginConfigColor.Empty,
portraitColor != null ? 1 : 0,
null
);
var chunks = new List<Tuple<PluginConfigColor, float, LabelConfig?>>();
chunks.Add(canvas);
if (!config.DontShowDrawing)
{
chunks.Add(drawing);
}
chunks.Add(portrait);
BarHud[] bars = BarUtilities.GetChunkedBars(config, chunks.ToArray(), player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawWeaponCanvasBar(Vector2 origin, IPlayerCharacter player)
{
ChunkedBarConfig config = Config.WeaponCanvasBar;
PCTGauge gauge = Plugin.JobGauges.Get<PCTGauge>();
bool active = gauge.CanvasFlags.HasFlag(CanvasFlags.Weapon);
if (config.HideWhenInactive && !active)
{
return;
}
BarHud[] bars = BarUtilities.GetChunkedBars(config, 1, active ? 1 : 0, 1, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawLandscapeCanvasBar(Vector2 origin, IPlayerCharacter player)
{
ChunkedBarConfig config = Config.LandscapeCanvasBar;
PCTGauge gauge = Plugin.JobGauges.Get<PCTGauge>();
bool active = gauge.CanvasFlags.HasFlag(CanvasFlags.Landscape);
if (config.HideWhenInactive && !active)
{
return;
}
BarHud[] bars = BarUtilities.GetChunkedBars(config, 1, active ? 1 : 0, 1, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawHammerTimeBar(Vector2 origin, IPlayerCharacter player)
{
StacksWithDurationBarConfig config = Config.HammerTimeBar;
IStatus? status = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3680);
int stacks = status?.Param ?? 0;
float time = Math.Abs(status?.RemainingTime ?? 0f);
if (config.HideWhenInactive && stacks == 0)
{
return;
}
config.Label.SetValue(time);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(config, 3, stacks, 3, 0, player, forceLabelIndex: 1);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
private unsafe void DrawHyperphantasiaBar(Vector2 origin, IPlayerCharacter player)
{
StacksWithDurationBarConfig config = Config.HyperphantasiaBar;
IStatus? status = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3688);
int stacks = status?.Param ?? 0;
float time = Math.Abs(status?.RemainingTime ?? 0f);
if (config.HideWhenInactive && stacks == 0)
{
return;
}
config.Label.SetValue(time);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(config, 5, stacks, 5, 0, player, forceLabelIndex: 2);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, config.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Caster", 0)]
[SubSection("Pictomancer", 1)]
public class PictomancerConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.PCT;
public new static PictomancerConfig DefaultConfig()
{
var config = new PictomancerConfig();
config.PaletteBar.UseChunks = false;
config.PaletteBar.Label.Enabled = true;
return config;
}
[NestedConfig("Palette Bar", 30)]
public PictomancerPaletteBarConfig PaletteBar = new PictomancerPaletteBarConfig(
new Vector2(0, -10),
new Vector2(152, 18),
PluginConfigColor.FromHex(0xFFC8C89F)
);
[NestedConfig("Paint Bar", 35)]
public PictomancerPaintBarConfig PaintBar = new PictomancerPaintBarConfig(
new(0, -26),
new(254, 10)
);
[NestedConfig("Creature Canvas Bar", 40)]
public PictomancerCreatureCanvasBarConfig CreatureCanvasBar = new PictomancerCreatureCanvasBarConfig(
new(0, -38),
new(254, 10)
);
[NestedConfig("Weapon Canvas Bar", 40)]
public ChunkedBarConfig WeaponCanvasBar = new ChunkedBarConfig(
new(-102.5f, -10),
new(49, 18),
PluginConfigColor.FromHex(0xFFC5616C)
);
[NestedConfig("Landscape Canvas Bar", 40)]
public ChunkedBarConfig LandscapeCanvasBar = new ChunkedBarConfig(
new(102.5f, -10),
new(49, 18),
PluginConfigColor.FromHex(0xFF8690E5)
);
[NestedConfig("Hammer Time Bar", 40)]
public StacksWithDurationBarConfig HammerTimeBar = new StacksWithDurationBarConfig(
new(0, -50),
new(254, 10),
PluginConfigColor.FromHex(0xFFFFFFFF)
);
[NestedConfig("Hyperphantasia Bar", 45)]
public StacksWithDurationBarConfig HyperphantasiaBar = new StacksWithDurationBarConfig(
new(0, -50),
new(254, 10),
PluginConfigColor.FromHex(0xFFFFFFFF)
);
}
[DisableParentSettings("Label")]
[Exportable(false)]
public class PictomancerPaletteBarConfig : ChunkedProgressBarConfig
{
[ColorEdit4("Subtractive Fill Color")]
[Order(27)]
public PluginConfigColor SubtractiveColor = PluginConfigColor.FromHex(0xFFAF6BAE);
[NestedConfig("Bar Text", 1001, separator = false, spacing = true)]
public PictomancerPaletteLabelConfig PaletteLabel = new PictomancerPaletteLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
public PictomancerPaletteBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
Label = PaletteLabel;
}
}
[Exportable(false)]
public class PictomancerPaletteLabelConfig : NumericLabelConfig
{
[ColorEdit4("Subtractive Color")]
[Order(31)]
public PluginConfigColor SubtractiveColor = new PluginConfigColor(Vector4.UnitW);
[ColorEdit4("Subtractive Color ##Outline")]
[Order(41, collapseWith = nameof(ShowOutline))]
public PluginConfigColor SubtractiveOutlineColor = new PluginConfigColor(Vector4.One);
public PictomancerPaletteLabelConfig(Vector2 position, string text, DrawAnchor frameAnchor, DrawAnchor textAnchor)
: base(position, text, frameAnchor, textAnchor)
{
}
[JsonIgnore] public bool SubtractiveMode = false;
public override PluginConfigColor GetColor() => SubtractiveMode ? SubtractiveColor : Color;
public override PluginConfigColor GetOutlineColor() => SubtractiveMode ? SubtractiveOutlineColor : OutlineColor;
public override PictomancerPaletteLabelConfig Clone(int index) =>
new PictomancerPaletteLabelConfig(Position, _text, FrameAnchor, TextAnchor)
{
Color = Color,
SubtractiveColor = SubtractiveColor,
OutlineColor = OutlineColor,
SubtractiveOutlineColor = SubtractiveOutlineColor,
ShadowConfig = ShadowConfig,
ShowOutline = ShowOutline,
FontID = FontID,
UseJobColor = UseJobColor,
Enabled = Enabled,
HideIfZero = HideIfZero,
ID = ID + "_{index}"
};
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class PictomancerPaintBarConfig : ChunkedBarConfig
{
[ColorEdit4("White Paint Color")]
[Order(26)]
public PluginConfigColor WhitePaintColor = PluginConfigColor.FromHex(0xFF00FFFF);
[ColorEdit4("Black Paint Color")]
[Order(27)]
public PluginConfigColor BlackPaintColor = PluginConfigColor.FromHex(0xFFDB57DB);
public PictomancerPaintBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class PictomancerCreatureCanvasBarConfig : ChunkedBarConfig
{
[ColorEdit4("Pom Color")]
[Order(17)]
public PluginConfigColor PomColor = PluginConfigColor.FromHex(0xFFE69378);
[ColorEdit4("Wings Color")]
[Order(18)]
public PluginConfigColor WingsColor = PluginConfigColor.FromHex(0xFFD38BE4);
[ColorEdit4("Claw Color")]
[Order(19)]
public PluginConfigColor ClawColor = PluginConfigColor.FromHex(0xFFA16854);
[ColorEdit4("Fangs Color")]
[Order(20)]
public PluginConfigColor FangsColor = PluginConfigColor.FromHex(0xFF80BFBD);
[ColorEdit4("Moogle Color")]
[Order(21)]
public PluginConfigColor MoogleColor = PluginConfigColor.FromHex(0xFFA745C7);
[ColorEdit4("Madeen Color")]
[Order(22)]
public PluginConfigColor MadeenColor = PluginConfigColor.FromHex(0xFF93Cf7D);
[Checkbox("Don't Show Drawing", spacing = true, help = "When enabled, this hides the middle chunk that shows which creature parts were already drawn.")]
[Order(50)]
public bool DontShowDrawing = false;
[Checkbox("Show Empty Drawing for Pom + Wings")]
[Order(51)]
public bool ShowEmptyPomWings = false;
public PictomancerCreatureCanvasBarConfig(Vector2 position, Vector2 size)
: base(position, size, PluginConfigColor.Empty)
{
}
}
}
+246
View File
@@ -0,0 +1,246 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class ReaperHud : JobHud
{
private new ReaperConfig Config => (ReaperConfig)_config;
public ReaperHud(JobConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.DeathsDesignBar.Enabled)
{
positions.Add(Config.Position + Config.DeathsDesignBar.Position);
sizes.Add(Config.DeathsDesignBar.Size);
}
if (Config.SoulBar.Enabled)
{
positions.Add(Config.Position + Config.SoulBar.Position);
sizes.Add(Config.SoulBar.Size);
}
if (Config.ShroudBar.Enabled)
{
positions.Add(Config.Position + Config.ShroudBar.Position);
sizes.Add(Config.ShroudBar.Size);
}
if (Config.DeathGauge.Enabled)
{
positions.Add(Config.Position + Config.DeathGauge.Position);
sizes.Add(Config.DeathGauge.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
RPRGauge gauge = Plugin.JobGauges.Get<RPRGauge>();
if (Config.DeathsDesignBar.Enabled)
{
DrawDeathsDesignBar(pos, player);
}
if (Config.SoulBar.Enabled)
{
DrawSoulGauge(pos, gauge, player);
}
if (Config.ShroudBar.Enabled)
{
DrawShroudGauge(pos, gauge, player);
}
if (Config.DeathGauge.Enabled)
{
DrawDeathGauge(pos, gauge, player);
}
}
private void DrawDeathsDesignBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? actor = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
float duration = 0f;
if (actor is IBattleChara target)
{
duration = Utils.StatusListForBattleChara(target).FirstOrDefault(o => o.StatusId is 2586 && o.SourceId == player.GameObjectId && o.RemainingTime > 0)?.RemainingTime ?? 0f;
}
if (!Config.DeathsDesignBar.HideWhenInactive || duration > 0)
{
Config.DeathsDesignBar.Label.SetValue(duration);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.DeathsDesignBar, 2, duration, 60f, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DeathsDesignBar.StrataLevel));
}
}
}
private void DrawSoulGauge(Vector2 origin, RPRGauge gauge, IPlayerCharacter player)
{
float soul = gauge.Soul;
if (!Config.SoulBar.HideWhenInactive || soul > 0)
{
Config.SoulBar.Label.SetValue(soul);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.SoulBar, 2, soul, 100f, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.SoulBar.StrataLevel));
}
}
}
private void DrawShroudGauge(Vector2 origin, RPRGauge gauge, IPlayerCharacter player)
{
float shroud = gauge.Shroud;
if (!Config.ShroudBar.HideWhenInactive || shroud > 0)
{
Config.ShroudBar.Label.SetValue(shroud);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(Config.ShroudBar, 2, shroud, 100f, 0f, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ShroudBar.StrataLevel));
}
}
}
private void DrawDeathGauge(Vector2 origin, RPRGauge gauge, IPlayerCharacter player)
{
var lemureShroud = gauge.LemureShroud;
var voidShroud = gauge.VoidShroud;
if (!Config.DeathGauge.HideWhenInactive || gauge.EnshroudedTimeRemaining > 0)
{
var deathChunks = new Tuple<PluginConfigColor, float, LabelConfig?>[5];
int i = 0;
for (; i < lemureShroud && i < deathChunks.Length; i++)
{
deathChunks[i] = new(Config.DeathGauge.LemureShroudColor, 1f, i == 2 ? Config.DeathGauge.EnshroudTimerLabel : null);
}
for (; i < lemureShroud + voidShroud && i < deathChunks.Length; i++)
{
deathChunks[i] = new(Config.DeathGauge.VoidShroudColor, 1f, i == 2 ? Config.DeathGauge.EnshroudTimerLabel : null);
}
for (; i < deathChunks.Length; i++)
{
deathChunks[i] = new(Config.DeathGauge.VoidShroudColor, 0f, i == 2 ? Config.DeathGauge.EnshroudTimerLabel : null);
}
Config.DeathGauge.EnshroudTimerLabel.SetValue(gauge.EnshroudedTimeRemaining / 1000);
BarHud[] bars = BarUtilities.GetChunkedBars(Config.DeathGauge, deathChunks, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DeathGauge.StrataLevel));
}
}
}
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Reaper", 1)]
public class ReaperConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.RPR;
public new static ReaperConfig DefaultConfig()
{
var config = new ReaperConfig();
config.DeathsDesignBar.UseChunks = false;
config.DeathsDesignBar.Label.Enabled = true;
config.SoulBar.UseChunks = false;
config.SoulBar.Label.Enabled = true;
config.ShroudBar.UseChunks = false;
config.ShroudBar.Label.Enabled = true;
config.DeathGauge.EnshroudTimerLabel.HideIfZero = true;
return config;
}
[NestedConfig("Death's Design Bar", 35)]
public ChunkedProgressBarConfig DeathsDesignBar = new ChunkedProgressBarConfig(
new(0, -10),
new(254, 20),
new PluginConfigColor(new Vector4(145f / 255f, 0f / 255f, 25f / 255f, 100f / 100f))
);
[NestedConfig("Soul Bar", 40)]
public ChunkedProgressBarConfig SoulBar = new ChunkedProgressBarConfig(
new(0, -32),
new(254, 20),
new PluginConfigColor(new Vector4(254f / 255f, 21f / 255f, 94f / 255f, 100f / 100f))
);
[NestedConfig("Shroud Bar", 45)]
public ChunkedProgressBarConfig ShroudBar = new ChunkedProgressBarConfig(
new(0, -54),
new(254, 20),
new PluginConfigColor(new Vector4(0f / 255f, 176f / 255f, 196f / 255f, 100f / 100f))
);
[NestedConfig("Death Gauge", 50)]
public DeathGauge DeathGauge = new DeathGauge(
new(0, -76),
new(254, 20),
new PluginConfigColor(new(0, 0, 0, 0))
);
}
[DisableParentSettings("FillColor")]
public class DeathGauge : ChunkedBarConfig
{
[ColorEdit4("Lemure Shroud Color")]
[Order(21)]
public PluginConfigColor LemureShroudColor = new PluginConfigColor(new Vector4(0f / 255f, 176f / 255f, 196f / 255f, 100f / 100f));
[ColorEdit4("Void Shroud Color")]
[Order(22)]
public PluginConfigColor VoidShroudColor = new PluginConfigColor(new Vector4(150f / 255f, 90f / 255f, 144f / 255f, 100f / 100f));
[NestedConfig("Enshroud Duration Text", 50, spacing = true)]
public NumericLabelConfig EnshroudTimerLabel;
public DeathGauge(Vector2 position, Vector2 size, PluginConfigColor fillColor, int padding = 2) : base(position, size, fillColor, padding)
{
EnshroudTimerLabel = new NumericLabelConfig(Vector2.Zero, "", DrawAnchor.Center, DrawAnchor.Center);
}
}
}
+319
View File
@@ -0,0 +1,319 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class RedMageHud : JobHud
{
private new RedMageConfig Config => (RedMageConfig)_config;
public RedMageHud(RedMageConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.BalanceBar.Enabled)
{
positions.Add(Config.Position + Config.BalanceBar.Position);
sizes.Add(Config.BalanceBar.Size);
}
if (Config.WhiteManaBar.Enabled)
{
positions.Add(Config.Position + Config.WhiteManaBar.Position);
sizes.Add(Config.WhiteManaBar.Size);
}
if (Config.BlackManaBar.Enabled)
{
positions.Add(Config.Position + Config.BlackManaBar.Position);
sizes.Add(Config.BlackManaBar.Size);
}
if (Config.ManaStacksBar.Enabled)
{
positions.Add(Config.Position + Config.ManaStacksBar.Position);
sizes.Add(Config.ManaStacksBar.Size);
}
if (Config.DualcastBar.Enabled)
{
positions.Add(Config.Position + Config.DualcastBar.Position);
sizes.Add(Config.DualcastBar.Size);
}
if (Config.VerstoneBar.Enabled)
{
positions.Add(Config.Position + Config.VerstoneBar.Position);
sizes.Add(Config.VerstoneBar.Size);
}
if (Config.VerfireBar.Enabled)
{
positions.Add(Config.Position + Config.VerfireBar.Position);
sizes.Add(Config.VerfireBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.BalanceBar.Enabled)
{
DrawBalanceBar(pos, player);
}
if (Config.WhiteManaBar.Enabled)
{
DrawWhiteManaBar(pos, player);
}
if (Config.BlackManaBar.Enabled)
{
DrawBlackManaBar(pos, player);
}
if (Config.ManaStacksBar.Enabled)
{
DrawManaStacksBarBar(pos, player);
}
if (Config.DualcastBar.Enabled)
{
DrawDualCastBar(pos, player);
}
if (Config.VerstoneBar.Enabled)
{
DrawVerstoneBar(pos, player);
}
if (Config.VerfireBar.Enabled)
{
DrawVerfireBar(pos, player);
}
}
private void DrawBalanceBar(Vector2 origin, IPlayerCharacter player)
{
RDMGauge gauge = Plugin.JobGauges.Get<RDMGauge>();
float whiteGauge = (float)Plugin.JobGauges.Get<RDMGauge>().WhiteMana;
float blackGauge = (float)Plugin.JobGauges.Get<RDMGauge>().BlackMana;
int scale = gauge.WhiteMana - gauge.BlackMana;
PluginConfigColor color = Config.BalanceBar.FillColor;
int value = 0;
if (whiteGauge >= 50 && blackGauge >= 50)
{
value = 1;
}
else if (scale >= 30)
{
color = Config.WhiteManaBar.FillColor;
value = 1;
}
else if (scale <= -30)
{
color = Config.BlackManaBar.FillColor;
value = 1;
}
if (Config.BalanceBar.HideWhenInactive && value == 0)
{
return;
}
BarHud bar = BarUtilities.GetBar(Config.BalanceBar, value, 1, 0, player, color);
AddDrawActions(bar.GetDrawActions(origin, Config.BalanceBar.StrataLevel));
}
private void DrawWhiteManaBar(Vector2 origin, IPlayerCharacter player)
{
byte mana = Plugin.JobGauges.Get<RDMGauge>().WhiteMana;
if (Config.WhiteManaBar.HideWhenInactive && mana == 0)
{
return;
}
Config.WhiteManaBar.Label.SetValue(mana);
BarHud bar = BarUtilities.GetProgressBar(Config.WhiteManaBar, mana, 100, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.WhiteManaBar.StrataLevel));
}
private void DrawBlackManaBar(Vector2 origin, IPlayerCharacter player)
{
byte mana = Plugin.JobGauges.Get<RDMGauge>().BlackMana;
if (Config.BlackManaBar.HideWhenInactive && mana == 0)
{
return;
}
Config.BlackManaBar.Label.SetValue(mana);
BarHud bar = BarUtilities.GetProgressBar(Config.BlackManaBar, mana, 100, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.BlackManaBar.StrataLevel));
}
private void DrawManaStacksBarBar(Vector2 origin, IPlayerCharacter player)
{
byte manaStacks = Plugin.JobGauges.Get<RDMGauge>().ManaStacks;
if (Config.ManaStacksBar.HideWhenInactive && manaStacks == 0)
{
return;
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.ManaStacksBar, 3, manaStacks, 3f, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.ManaStacksBar.StrataLevel));
}
}
private void DrawDualCastBar(Vector2 origin, IPlayerCharacter player)
{
float duration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1249)?.RemainingTime ?? 0f;
if (Config.DualcastBar.HideWhenInactive && duration == 0)
{
return;
};
Config.DualcastBar.Label.SetValue(duration);
BarHud bar = BarUtilities.GetProgressBar(Config.DualcastBar, duration, 15f, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.DualcastBar.StrataLevel));
}
private void DrawVerstoneBar(Vector2 origin, IPlayerCharacter player)
{
BarHud? bar = BarUtilities.GetProcBar(Config.VerstoneBar, player, 1235, 30);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.VerstoneBar.StrataLevel));
}
}
private void DrawVerfireBar(Vector2 origin, IPlayerCharacter player)
{
BarHud? bar = BarUtilities.GetProcBar(Config.VerfireBar, player, 1234, 30);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.VerfireBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Caster", 0)]
[SubSection("Red Mage", 1)]
public class RedMageConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.RDM;
public new static RedMageConfig DefaultConfig()
{
var config = new RedMageConfig();
config.UseDefaultPrimaryResourceBar = true;
config.WhiteManaBar.ThresholdConfig.Enabled = true;
config.WhiteManaBar.ThresholdConfig.ChangeColor = false;
config.WhiteManaBar.ThresholdConfig.ShowMarker = true;
config.WhiteManaBar.Label.TextAnchor = DrawAnchor.Right;
config.WhiteManaBar.Label.FrameAnchor = DrawAnchor.Right;
config.WhiteManaBar.Label.Position = new Vector2(-2, 0);
config.BlackManaBar.ThresholdConfig.Enabled = true;
config.BlackManaBar.ThresholdConfig.ChangeColor = false;
config.BlackManaBar.ThresholdConfig.ShowMarker = true;
config.BlackManaBar.Label.TextAnchor = DrawAnchor.Left;
config.BlackManaBar.Label.FrameAnchor = DrawAnchor.Left;
config.BlackManaBar.Label.Position = new Vector2(2, 0);
config.DualcastBar.Label.Enabled = false;
config.VerstoneBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.VerstoneBar.Label.TextAnchor = DrawAnchor.Right;
config.VerstoneBar.Label.FrameAnchor = DrawAnchor.Right;
config.VerstoneBar.Label.Position = new Vector2(-2, 0);
config.VerfireBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.VerfireBar.Label.TextAnchor = DrawAnchor.Left;
config.VerfireBar.Label.FrameAnchor = DrawAnchor.Left;
config.VerfireBar.Label.Position = new Vector2(2, 0);
return config;
}
[NestedConfig("Balance Bar", 30)]
public BarConfig BalanceBar = new BarConfig(
new(0, -10),
new(20, 20),
new PluginConfigColor(new(195f / 255f, 35f / 255f, 35f / 255f, 100f / 100f))
);
[NestedConfig("White Mana Bar", 35)]
public ProgressBarConfig WhiteManaBar = new ProgressBarConfig(
new(-69.5f, -10),
new(115, 20),
new PluginConfigColor(new(221f / 255f, 212f / 255f, 212f / 255f, 100f / 100f)),
BarDirection.Left,
null,
80
);
[NestedConfig("Black Mana Bar", 40)]
public ProgressBarConfig BlackManaBar = new ProgressBarConfig(
new(69.5f, -10),
new(115, 20),
new PluginConfigColor(new(60f / 255f, 81f / 255f, 197f / 255f, 100f / 100f)),
threshold: 80
);
[NestedConfig("Mana Stacks Bar", 45)]
public ChunkedBarConfig ManaStacksBar = new ChunkedBarConfig(
new(0, -27),
new(254, 10),
new PluginConfigColor(new(200f / 255f, 45f / 255f, 40f / 255f, 100f / 100f))
);
[NestedConfig("Dualcast Bar", 50)]
public ProgressBarConfig DualcastBar = new ProgressBarConfig(
new(0, -41),
new(16, 14),
new PluginConfigColor(new(204f / 255f, 17f / 255f, 255f / 95f, 100f / 100f))
);
[NestedConfig("Verstone Ready Bar", 55)]
public ProgressBarConfig VerstoneBar = new ProgressBarConfig(
new(-68.5f, -41),
new(117, 14),
new PluginConfigColor(new(228f / 255f, 188f / 255f, 145 / 255f, 90f / 100f)),
BarDirection.Left
);
[NestedConfig("Verfire Ready Bar", 60)]
public ProgressBarConfig VerfireBar = new ProgressBarConfig(
new(68.5f, -41),
new(117, 14),
new PluginConfigColor(new(238f / 255f, 119f / 255f, 17 / 255f, 90f / 100f))
);
}
}
+246
View File
@@ -0,0 +1,246 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Logging;
namespace HSUI.Interface.Jobs
{
public class SageHud : JobHud
{
private new SageConfig Config => (SageConfig)_config;
private static readonly List<uint> DotIDs = new() { 2614, 2615, 2616, 3897 };
private static readonly List<float> DotDurations = new() { 30, 30, 30, 30 };
public SageHud(JobConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.AddersgallBar.Enabled)
{
positions.Add(Config.Position + Config.AddersgallBar.Position);
sizes.Add(Config.AddersgallBar.Size);
}
if (Config.DotBar.Enabled)
{
positions.Add(Config.Position + Config.DotBar.Position);
sizes.Add(Config.DotBar.Size);
}
if (Config.KeracholeBar.Enabled)
{
positions.Add(Config.Position + Config.KeracholeBar.Position);
sizes.Add(Config.KeracholeBar.Size);
}
if (Config.PhysisBar.Enabled)
{
positions.Add(Config.Position + Config.PhysisBar.Position);
sizes.Add(Config.PhysisBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.AddersgallBar.Enabled)
{
DrawAddersgallBar(pos, player);
}
if (Config.DotBar.Enabled)
{
DrawDotBar(pos, player);
}
if (Config.KeracholeBar.Enabled)
{
DrawKeracholeBar(pos, player);
}
if (Config.PhysisBar.Enabled)
{
DrawPhysisBar(pos, player);
}
}
private void DrawDotBar(Vector2 origin, IPlayerCharacter player)
{
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.DotBar, player, target, DotIDs, DotDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DotBar.StrataLevel));
}
}
private void DrawAddersgallBar(Vector2 origin, IPlayerCharacter player)
{
SGEGauge gauge = Plugin.JobGauges.Get<SGEGauge>();
const float addersgallCooldown = 20000f;
float GetScale(int num, float timer) => num + (timer / addersgallCooldown);
float adderScale = GetScale(gauge.Addersgall, gauge.AddersgallTimer);
BarGlowConfig? glow = gauge.Eukrasia && Config.EukrasiaGlow ? Config.AddersgallBar.GlowConfig : null;
if (!Config.AddersgallBar.HideWhenInactive || adderScale > 0)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AddersgallBar, 3, adderScale, 3, 0, player, partialFillColor: Config.AddersgallBar.PartialFillColor, glowConfig: glow, chunksToGlow: new[] { true, true, true });
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AddersgallBar.StrataLevel));
}
}
if (!Config.AdderstingBar.HideWhenInactive && Config.AdderstingBar.Enabled || gauge.Addersting > 0)
{
int adderstingStacks = player.Level > 65 ? gauge.Addersting : 0;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AdderstingBar, 3, adderstingStacks, 3, 0, player, glowConfig: glow, chunksToGlow: new[] { true, true, true });
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AdderstingBar.StrataLevel));
}
}
}
private void DrawPhysisBar(Vector2 origin, IPlayerCharacter player)
{
float physisDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2617 or 2620 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.PhysisBar.HideWhenInactive || physisDuration > 0)
{
Config.PhysisBar.Label.SetValue(physisDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.PhysisBar, physisDuration, 15f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.PhysisBar.StrataLevel));
}
}
private void DrawKeracholeBar(Vector2 origin, IPlayerCharacter player)
{
float keracholeDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 2618 or 2938 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
float holosDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3003 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.KeracholeBar.HideWhenInactive || keracholeDuration > 0 || holosDuration > 0)
{
float duration = holosDuration > 0 ? holosDuration : keracholeDuration;
float maxDuration = holosDuration > 0 ? 20f : 15f;
Config.KeracholeBar.Label.SetValue(duration);
BarHud bar = BarUtilities.GetProgressBar(Config.KeracholeBar, duration, maxDuration, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.KeracholeBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Healer", 0)]
[SubSection("Sage", 1)]
public class SageConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.SGE;
public new static SageConfig DefaultConfig()
{
var config = new SageConfig();
config.UseDefaultPrimaryResourceBar = true;
config.DotBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
return config;
}
[Checkbox("Enable Eukrasia Glow", spacing = true)]
[Order(30)]
public bool EukrasiaGlow = true;
[NestedConfig("Addersgall Bar", 35)]
public AddersgallBarConfig AddersgallBar = new AddersgallBarConfig(
new(-64, -32),
new(126, 20),
new PluginConfigColor(new(197f / 255f, 247f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Addersting Bar", 40)]
public AdderstingBarConfig AdderstingBar = new AdderstingBarConfig(
new(64, -32),
new(126, 20),
new PluginConfigColor(new(255f / 255f, 232f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Eukrasian Dosis Bar", 45)]
public ProgressBarConfig DotBar = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new PluginConfigColor(new(41f / 255f, 142f / 255f, 144f / 255f, 100f / 100f))
);
[NestedConfig("Kerachole / Holos Bar", 50)]
public ProgressBarConfig KeracholeBar = new ProgressBarConfig(
new(64, -52),
new(126, 15),
new PluginConfigColor(new(100f / 255f, 207f / 255f, 211f / 255f, 100f / 100f))
);
[NestedConfig("Physis Bar", 55)]
public ProgressBarConfig PhysisBar = new ProgressBarConfig(
new(-64, -52),
new(126, 15),
new PluginConfigColor(new(26f / 255f, 167f / 255f, 109f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class AddersgallBarConfig : ChunkedBarConfig
{
[NestedConfig("Glow Color (when Eukrasia active)", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new();
[Checkbox("Use Partial Fill Color", spacing = true)]
[Order(65)]
public bool UsePartialFillColor = false;
[ColorEdit4("Partial Fill Color")]
[Order(66, collapseWith = nameof(UsePartialFillColor))]
public PluginConfigColor PartialFillColor;
public AddersgallBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
GlowConfig.Color = new PluginConfigColor(new(247f / 255f, 177f / 255f, 67f / 255f, 100f / 100f));
PartialFillColor = new PluginConfigColor(new(197 / 255f, 247f / 255f, 255f / 255f, 50f / 100f));
}
}
[Exportable(false)]
public class AdderstingBarConfig : ChunkedBarConfig
{
[NestedConfig("Glow Color (when Eukrasia active)", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new();
public AdderstingBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
GlowConfig.Color = new PluginConfigColor(new(247f / 255f, 177f / 255f, 67f / 255f, 100f / 100f));
}
}
}
+274
View File
@@ -0,0 +1,274 @@
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 HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class SamuraiHud : JobHud
{
private new SamuraiConfig Config => (SamuraiConfig)_config;
private static readonly List<uint> HiganbanaIDs = new() { 1228, 1319 };
private static readonly List<float> HiganabaDurations = new() { 60f, 60f };
public SamuraiHud(SamuraiConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.KenkiBar.Enabled)
{
positions.Add(Config.Position + Config.KenkiBar.Position);
sizes.Add(Config.KenkiBar.Size);
}
if (Config.ShifuBar.Enabled)
{
positions.Add(Config.Position + Config.ShifuBar.Position);
sizes.Add(Config.ShifuBar.Size);
}
if (Config.JinpuBar.Enabled)
{
positions.Add(Config.Position + Config.JinpuBar.Position);
sizes.Add(Config.JinpuBar.Size);
}
if (Config.HiganbanaBar.Enabled)
{
positions.Add(Config.Position + Config.HiganbanaBar.Position);
sizes.Add(Config.HiganbanaBar.Size);
}
if (Config.SenBar.Enabled)
{
positions.Add(Config.Position + Config.SenBar.Position);
sizes.Add(Config.SenBar.Size);
}
if (Config.MeditationBar.Enabled)
{
positions.Add(Config.Position + Config.MeditationBar.Position);
sizes.Add(Config.MeditationBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
if (Config.KenkiBar.Enabled)
{
DrawKenkiBar(origin + Config.Position, player);
}
if (Config.ShifuBar.Enabled)
{
DrawShifuBar(origin + Config.Position, player);
}
if (Config.JinpuBar.Enabled)
{
DrawJinpuBar(origin + Config.Position, player);
}
if (Config.SenBar.Enabled)
{
DrawSenBar(origin + Config.Position, player);
}
if (Config.MeditationBar.Enabled)
{
DrawMeditationBar(origin + Config.Position, player);
}
if (Config.HiganbanaBar.Enabled)
{
DrawHiganbanaBar(origin + Config.Position, player);
}
}
private void DrawKenkiBar(Vector2 origin, IPlayerCharacter player)
{
SAMGauge gauge = Plugin.JobGauges.Get<SAMGauge>();
if (!Config.KenkiBar.HideWhenInactive || gauge.Kenki > 0)
{
Config.KenkiBar.Label.SetValue(gauge.Kenki);
BarHud bar = BarUtilities.GetProgressBar(Config.KenkiBar, gauge.Kenki, 100f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.KenkiBar.StrataLevel));
}
}
private void DrawShifuBar(Vector2 origin, IPlayerCharacter player)
{
float shifuDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1299)?.RemainingTime ?? 0f;
if (!Config.ShifuBar.HideWhenInactive || shifuDuration > 0)
{
Config.ShifuBar.Label.SetValue(shifuDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.ShifuBar, shifuDuration, 40f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.ShifuBar.StrataLevel));
}
}
private void DrawJinpuBar(Vector2 origin, IPlayerCharacter player)
{
float jinpuDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1298)?.RemainingTime ?? 0f;
if (!Config.JinpuBar.HideWhenInactive || jinpuDuration > 0)
{
Config.JinpuBar.Label.SetValue(jinpuDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.JinpuBar, jinpuDuration, 40f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.JinpuBar.StrataLevel));
}
}
private void DrawHiganbanaBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.HiganbanaBar, player, target, HiganbanaIDs, HiganabaDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.HiganbanaBar.StrataLevel));
}
}
private void DrawSenBar(Vector2 origin, IPlayerCharacter player)
{
SAMGauge gauge = Plugin.JobGauges.Get<SAMGauge>();
if (!Config.SenBar.HideWhenInactive || gauge.HasSetsu || gauge.HasGetsu || gauge.HasKa)
{
var order = Config.SenBar.SenOrder;
var hasSen = new[] { gauge.HasSetsu ? 1 : 0, gauge.HasGetsu ? 1 : 0, gauge.HasKa ? 1 : 0 };
var colors = new[] { Config.SenBar.SetsuColor, Config.SenBar.GetsuColor, Config.SenBar.KaColor };
var sen = new Tuple<PluginConfigColor, float, LabelConfig?>[3];
for (int i = 0; i < 3; i++)
{
sen[i] = new Tuple<PluginConfigColor, float, LabelConfig?>(colors[order[i]], hasSen[order[i]], null);
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.SenBar, sen, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.SenBar.StrataLevel));
}
}
}
private void DrawMeditationBar(Vector2 origin, IPlayerCharacter player)
{
SAMGauge gauge = Plugin.JobGauges.Get<SAMGauge>();
if (!Config.MeditationBar.HideWhenInactive || gauge.MeditationStacks > 0)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.MeditationBar, 3, gauge.MeditationStacks, 3f, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.MeditationBar.StrataLevel));
}
}
}
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Samurai", 1)]
public class SamuraiConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.SAM;
public new static SamuraiConfig DefaultConfig()
{
var config = new SamuraiConfig();
config.HiganbanaBar.ThresholdConfig.Enabled = true;
return config;
}
[NestedConfig("Sen Bar", 40)]
public SamuraiSenBarConfig SenBar = new SamuraiSenBarConfig(
new(0, -17),
new(254, 10),
new PluginConfigColor(new Vector4(0, 0, 0, 0))
);
[NestedConfig("Fuka Bar", 45)]
public ProgressBarConfig ShifuBar = new ProgressBarConfig(
new(-64, -56),
new(126, 20),
new PluginConfigColor(new(219f / 255f, 211f / 255f, 136f / 255f, 100f / 100f))
);
[NestedConfig("Fugetsu Bar", 50)]
public ProgressBarConfig JinpuBar = new ProgressBarConfig(
new(64, -56),
new(126, 20),
new PluginConfigColor(new(136f / 255f, 146f / 255f, 219f / 255f, 100f / 100f))
);
[NestedConfig("Kenki Bar", 55)]
public ProgressBarConfig KenkiBar = new ProgressBarConfig(
new(0, -34),
new(254, 20),
new PluginConfigColor(new(255f / 255f, 82f / 255f, 82f / 255f, 53f / 100f))
);
[NestedConfig("Higanbana Bar", 60)]
public ProgressBarConfig HiganbanaBar = new ProgressBarConfig(
new(0, -78),
new(254, 20),
new PluginConfigColor(new(237f / 255f, 141f / 255f, 7f / 255f, 100f / 100f)),
BarDirection.Right,
new PluginConfigColor(new(230f / 255f, 33f / 255f, 33f / 255f, 53f / 100f)),
15f
);
[NestedConfig("Meditation Bar", 65)]
public ChunkedBarConfig MeditationBar = new ChunkedBarConfig(
new(0, -5),
new(254, 10),
new PluginConfigColor(new(247f / 255f, 163f / 255f, 89f / 255f, 100f / 100f))
);
}
[DisableParentSettings("FillColor")]
[Exportable(false)]
public class SamuraiSenBarConfig : ChunkedBarConfig
{
[ColorEdit4("Setsu", spacing = true)]
[Order(60)]
public PluginConfigColor SetsuColor = new PluginConfigColor(new(89f / 255f, 234f / 255f, 247f / 255f, 100f / 100f));
[ColorEdit4("Getsu")]
[Order(65)]
public PluginConfigColor GetsuColor = new PluginConfigColor(new(89f / 255f, 126f / 255f, 247f / 255f, 100f / 100f));
[ColorEdit4("Ka")]
[Order(70)]
public PluginConfigColor KaColor = new PluginConfigColor(new(247f / 255f, 89f / 255f, 89f / 255f, 100f / 100f));
[DragDropHorizontal("Order", "Setsu", "Getsu", "Ka")]
[Order(75)]
public int[] SenOrder = new int[] { 0, 1, 2 };
public SamuraiSenBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor) : base(position, size, fillColor, 2) { }
}
}
+209
View File
@@ -0,0 +1,209 @@
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;
namespace HSUI.Interface.Jobs
{
public class ScholarHud : JobHud
{
private new ScholarConfig Config => (ScholarConfig)_config;
private static readonly List<uint> BioDoTIDs = new() { 179, 189, 1895 };
private static readonly List<float> BioDoTDurations = new() { 30, 30, 30 };
public ScholarHud(ScholarConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.AetherflowBar.Enabled)
{
positions.Add(Config.Position + Config.AetherflowBar.Position);
sizes.Add(Config.AetherflowBar.Size);
}
if (Config.FairyGaugeBar.Enabled)
{
positions.Add(Config.Position + Config.FairyGaugeBar.Position);
sizes.Add(Config.FairyGaugeBar.Size);
}
if (Config.BioBar.Enabled)
{
positions.Add(Config.Position + Config.BioBar.Position);
sizes.Add(Config.BioBar.Size);
}
if (Config.SacredSoilBar.Enabled)
{
positions.Add(Config.Position + Config.SacredSoilBar.Position);
sizes.Add(Config.SacredSoilBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.BioBar.Enabled)
{
DrawBioBar(pos, player);
}
if (Config.FairyGaugeBar.Enabled)
{
DrawFairyGaugeBar(pos, player);
}
if (Config.AetherflowBar.Enabled)
{
DrawAetherBar(pos, player);
}
if (Config.SacredSoilBar.Enabled)
{
DrawSacredSoilBar(pos, player);
}
}
private void DrawBioBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.BioBar, player, target, BioDoTIDs, BioDoTDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.BioBar.StrataLevel));
}
}
private unsafe void DrawFairyGaugeBar(Vector2 origin, IPlayerCharacter player)
{
SCHGauge gauge = Plugin.JobGauges.Get<SCHGauge>();
byte fairyGauge = gauge.FairyGauge;
float seraphDuration = gauge.SeraphTimer;
if (Config.FairyGaugeBar.HideWhenInactive && fairyGauge == 0 && (seraphDuration == 0 || !Config.FairyGaugeBar.ShowSeraph))
{
return;
}
if (Config.FairyGaugeBar.ShowSeraph && seraphDuration > 0)
{
Config.FairyGaugeBar.Label.SetValue(seraphDuration / 1000);
BarHud bar = BarUtilities.GetProgressBar(Config.FairyGaugeBar, seraphDuration / 1000, 22, 0, player, Config.FairyGaugeBar.SeraphColor);
AddDrawActions(bar.GetDrawActions(origin, Config.FairyGaugeBar.StrataLevel));
}
else
{
Config.FairyGaugeBar.Label.SetValue(fairyGauge);
BarHud bar = BarUtilities.GetProgressBar(Config.FairyGaugeBar, fairyGauge, 100, 0, player);
AddDrawActions(bar.GetDrawActions(origin, Config.FairyGaugeBar.StrataLevel));
}
}
private void DrawAetherBar(Vector2 origin, IPlayerCharacter player)
{
ushort stackCount = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 304)?.Param ?? 0;
if (Config.AetherflowBar.HideWhenInactive && stackCount == 0)
{
return;
};
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AetherflowBar, 3, stackCount, 3, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AetherflowBar.StrataLevel));
}
}
private void DrawSacredSoilBar(Vector2 origin, IPlayerCharacter player)
{
float sacredSoilDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 298 or 1944 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.SacredSoilBar.HideWhenInactive || sacredSoilDuration > 0)
{
Config.SacredSoilBar.Label.SetValue(sacredSoilDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.SacredSoilBar, sacredSoilDuration, 15f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.SacredSoilBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Healer", 0)]
[SubSection("Scholar", 1)]
public class ScholarConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.SCH;
public new static ScholarConfig DefaultConfig()
{
var config = new ScholarConfig();
config.UseDefaultPrimaryResourceBar = true;
return config;
}
[NestedConfig("Bio Bar", 30)]
public ProgressBarConfig BioBar = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new(new Vector4(50f / 255f, 93f / 255f, 37f / 255f, 1f))
);
[NestedConfig("Fairy Gauge", 35)]
public ScholarFairyGaugeBarConfig FairyGaugeBar = new ScholarFairyGaugeBarConfig(
new(0, -32),
new(254, 20),
new(new Vector4(69f / 255f, 199 / 255f, 164f / 255f, 100f / 100f))
);
[NestedConfig("Aetherflow Bar", 40)]
public ChunkedBarConfig AetherflowBar = new ChunkedBarConfig(
new(0, -54),
new(254, 20),
new(new Vector4(0f / 255f, 255f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Sacred Soil Bar", 45)]
public ProgressBarConfig SacredSoilBar = new ProgressBarConfig(
new(-0, -76),
new(254, 20),
new PluginConfigColor(new(241f / 255f, 217f / 255f, 125f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class ScholarFairyGaugeBarConfig : ProgressBarConfig
{
[Checkbox("Show Seraph", spacing = true)]
[Order(50)]
public bool ShowSeraph = true;
[ColorEdit4("Color" + "##SeraphColor")]
[Order(55)]
public PluginConfigColor SeraphColor = new(new Vector4(232f / 255f, 255f / 255f, 255f / 255f, 100f / 100f));
public ScholarFairyGaugeBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
+429
View File
@@ -0,0 +1,429 @@
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 HSUI.Interface.GeneralElements;
using FFXIVClientStructs.FFXIV.Client.Game.Gauge;
using FFXIVClientStructs.FFXIV.Common.Lua;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class SummonerHud : JobHud
{
private new SummonerConfig Config => (SummonerConfig)_config;
public SummonerHud(SummonerConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.AetherflowBar.Enabled)
{
positions.Add(Config.Position + Config.AetherflowBar.Position);
sizes.Add(Config.AetherflowBar.Size);
}
if (Config.TranceBar.Enabled)
{
positions.Add(Config.Position + Config.TranceBar.Position);
sizes.Add(Config.TranceBar.Size);
}
if (Config.IfritBar.Enabled)
{
positions.Add(Config.Position + Config.IfritBar.Position);
sizes.Add(Config.IfritBar.Size);
}
if (Config.TitanBar.Enabled)
{
positions.Add(Config.Position + Config.TitanBar.Position);
sizes.Add(Config.TitanBar.Size);
}
if (Config.GarudaBar.Enabled)
{
positions.Add(Config.Position + Config.GarudaBar.Position);
sizes.Add(Config.GarudaBar.Size);
}
if (Config.StacksBar.Enabled)
{
positions.Add(Config.Position + Config.StacksBar.Position);
sizes.Add(Config.StacksBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.AetherflowBar.Enabled)
{
DrawAetherBar(pos, player);
}
if (Config.TranceBar.Enabled)
{
DrawTranceBar(pos, player);
}
if (Config.IfritBar.Enabled)
{
DrawIfritBar(pos, player);
}
if (Config.TitanBar.Enabled)
{
DrawTitanBar(pos, player);
}
if (Config.GarudaBar.Enabled)
{
DrawGarudaBar(pos, player);
}
if (Config.StacksBar.Enabled)
{
HandleAttunementStacks(pos, player);
}
}
private unsafe void DrawIfritBar(Vector2 origin, IPlayerCharacter player)
{
SMNGauge gauge = Plugin.JobGauges.Get<SMNGauge>();
int stackCount = gauge.IsIfritReady ? 1 : 0;
if (!Config.IfritBar.HideWhenInactive || stackCount > 1)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.IfritBar, 1, stackCount, 1, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.IfritBar.StrataLevel));
}
}
}
private void DrawTitanBar(Vector2 origin, IPlayerCharacter player)
{
SMNGauge gauge = Plugin.JobGauges.Get<SMNGauge>();
int stackCount = gauge.IsTitanReady ? 1 : 0;
if (!Config.TitanBar.HideWhenInactive || stackCount > 1)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.TitanBar, 1, stackCount, 1, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.TitanBar.StrataLevel));
}
}
}
private void DrawGarudaBar(Vector2 origin, IPlayerCharacter player)
{
SMNGauge gauge = Plugin.JobGauges.Get<SMNGauge>();
int stackCount = gauge.IsGarudaReady ? 1 : 0;
if (!Config.GarudaBar.HideWhenInactive || stackCount > 1)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.GarudaBar, 1, stackCount, 1, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.GarudaBar.StrataLevel));
}
}
}
private enum Primal
{
None = 0,
Ifrit = 1,
Titan = 2,
Garuda = 3
}
private unsafe void HandleAttunementStacks(Vector2 origin, IPlayerCharacter player)
{
SMNGauge gauge = Plugin.JobGauges.Get<SMNGauge>();
byte value = *((byte*)(new IntPtr(gauge.Address) + 0xE));
Primal primal = (Primal)(value & 3);
int stacks = ((value >> 2) & 7);
if (primal == Primal.Ifrit && Config.StacksBar.ShowIfritStacks)
{
DrawStacksBar(origin, player, stacks, 2, Config.StacksBar.IfritStackColor);
}
else if (primal == Primal.Titan && Config.StacksBar.ShowTitanStacks)
{
DrawStacksBar(origin, player, stacks, 4, Config.StacksBar.TitanStackColor);
}
else if (primal == Primal.Garuda && Config.StacksBar.ShowGarudaStacks)
{
DrawStacksBar(origin, player, stacks, 4, Config.StacksBar.GarudaStackColor);
}
else if (!Config.StacksBar.HideWhenInactive)
{
DrawStacksBar(origin, player, 0, 1, Config.StacksBar.FillColor);
}
}
private void DrawAetherBar(Vector2 origin, IPlayerCharacter player)
{
ushort stackCount = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId == 304)?.Param ?? 0;
if (Config.AetherflowBar.HideWhenInactive && stackCount == 0)
{
return;
}
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AetherflowBar, 2, stackCount, 2, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AetherflowBar.StrataLevel));
}
}
private unsafe void DrawTranceBar(Vector2 origin, IPlayerCharacter player)
{
SMNGauge gauge = Plugin.JobGauges.Get<SMNGauge>();
PluginConfigColor tranceColor;
uint spellID = 0;
float maxDuration = 0f;
float currentCooldown = 0f;
float tranceDuration = 0f;
tranceColor = Config.TranceBar.FillColor;
// Dawntrail Fixes
bool isSolarBahamutReady = gauge.AetherFlags.HasFlag(AetherFlags.None + 0x8) || // 0x8 Formerly Titan Attuned
gauge.AetherFlags.HasFlag(AetherFlags.None + 0xC); // 0xC Formerly Garuda Attuned
bool isPhoenixReady = gauge.AetherFlags.HasFlag(AetherFlags.None + 0x4); // 0x4 Formerly Ifrit Attuned
bool isNormalBahamutReady = !isSolarBahamutReady && !isPhoenixReady; // You'd think it would be 0x10, but thats unused now
byte summonedPrimal = *((byte*)(new IntPtr(gauge.Address) + 0xE)); // Formally Attunement, now...?
Primal primal = (Primal)(summonedPrimal & 3);
if (primal != Primal.None)
{
tranceColor = primal == Primal.Ifrit ? Config.TranceBar.IfritColor : primal == Primal.Titan ? Config.TranceBar.TitanColor : primal == Primal.Garuda ? Config.TranceBar.GarudaColor : Config.TranceBar.FillColor;
tranceDuration = gauge.AttunementTimerRemaining;
maxDuration = 30f;
}
else
{
if (isSolarBahamutReady)
{
tranceColor = Config.TranceBar.SolarBahamutColor;
tranceDuration = gauge.SummonTimerRemaining;
spellID = 36992;
maxDuration = 15f;
}
else if (isNormalBahamutReady)
{
tranceColor = Config.TranceBar.BahamutColor;
tranceDuration = gauge.SummonTimerRemaining;
spellID = 7427;
maxDuration = 15f;
}
else if (isPhoenixReady)
{
tranceColor = Config.TranceBar.PhoenixColor;
tranceDuration = gauge.SummonTimerRemaining;
spellID = 25831;
maxDuration = 15f;
}
}
if (tranceDuration != 0)
{
if (gauge.AttunementTimerRemaining > 0 && Config.TranceBar.HidePrimals)
{
return;
}
Config.TranceBar.Label.SetValue(tranceDuration / 1000f);
BarHud bar = BarUtilities.GetProgressBar(Config.TranceBar, tranceDuration / 1000f, maxDuration, 0, player, tranceColor);
AddDrawActions(bar.GetDrawActions(origin, Config.TranceBar.StrataLevel));
}
else
{
if (!Config.TranceBar.HideWhenInactive)
{
if (gauge.AttunementTimerRemaining == 0)
{
maxDuration = SpellHelper.Instance.GetRecastTime(spellID);
float tranceCooldown = SpellHelper.Instance.GetSpellCooldown(spellID);
currentCooldown = maxDuration - tranceCooldown;
Config.TranceBar.Label.SetValue(maxDuration - currentCooldown);
if (currentCooldown == maxDuration)
{
Config.TranceBar.Label.SetText("READY");
}
BarHud bar = BarUtilities.GetProgressBar(Config.TranceBar, currentCooldown, maxDuration, 0, player, tranceColor);
AddDrawActions(bar.GetDrawActions(origin, Config.TranceBar.StrataLevel));
}
}
}
}
private void DrawStacksBar(Vector2 origin, IPlayerCharacter player, int amount, int max, PluginConfigColor stackColor, BarGlowConfig? glowConfig = null)
{
SummonerStacksBarConfig config = Config.StacksBar;
config.FillColor = stackColor;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.StacksBar, max, amount, max, 0f, player, glowConfig: glowConfig);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.StacksBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Caster", 0)]
[SubSection("Summoner", 1)]
public class SummonerConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.SMN;
public new static SummonerConfig DefaultConfig()
{
var config = new SummonerConfig();
config.TranceBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.UseDefaultPrimaryResourceBar = true;
return config;
}
[NestedConfig("Aetherflow Bar", 40)]
public ChunkedBarConfig AetherflowBar = new ChunkedBarConfig(
new(-0, -7),
new(254, 14),
new(new Vector4(255f / 255f, 177f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Trance Bar", 45)]
public SummonerTranceBarConfig TranceBar = new SummonerTranceBarConfig(
new(0, -23),
new(254, 14),
new(new Vector4(128f / 255f, 255f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Ifrit Bar", 50)]
public ChunkedBarConfig IfritBar = new ChunkedBarConfig(
new(-85, -39),
new(84, 14),
new(new Vector4(200f / 255f, 40f / 255f, 0f / 255f, 100f / 100f))
);
[NestedConfig("Titan Bar", 55)]
public ChunkedBarConfig TitanBar = new ChunkedBarConfig(
new(0, -39),
new(84, 14),
new(new Vector4(210f / 255f, 150f / 255f, 26f / 255f, 100f / 100f))
);
[NestedConfig("Garuda Bar", 60)]
public ChunkedBarConfig GarudaBar = new ChunkedBarConfig(
new(85, -39),
new(84, 14),
new(new Vector4(60f / 255f, 160f / 255f, 100f / 255f, 100f / 100f))
);
[NestedConfig("Attunement Stacks Bar", 65)]
public SummonerStacksBarConfig StacksBar = new SummonerStacksBarConfig(
new(0, -55),
new(254, 14),
new PluginConfigColor(new Vector4(255f / 255f, 255f / 255f, 255f / 255f, 0f / 100f))
);
}
[Exportable(false)]
public class SummonerTranceBarConfig : ProgressBarConfig
{
[ColorEdit4("Bahamut Color")]
[Order(26)]
public PluginConfigColor BahamutColor = new(new Vector4(128f / 255f, 255f / 255f, 255f / 255f, 100f / 100f));
[ColorEdit4("Phoenix Color")]
[Order(27)]
public PluginConfigColor PhoenixColor = new(new Vector4(240f / 255f, 100f / 255f, 10f / 255f, 100f / 100f));
[ColorEdit4("Solar Bahamut Color")]
[Order(28)]
public PluginConfigColor SolarBahamutColor = new(new Vector4(235f / 255f, 241f / 255f, 252f / 255f, 100f / 100f));
[ColorEdit4("Ifrit Color")]
[Order(29)]
public PluginConfigColor IfritColor = new(new Vector4(200f / 255f, 40f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Titan Color")]
[Order(30)]
public PluginConfigColor TitanColor = new(new Vector4(210f / 255f, 150f / 255f, 26f / 255f, 100f / 100f));
[ColorEdit4("Garuda Color")]
[Order(31)]
public PluginConfigColor GarudaColor = new(new Vector4(60f / 255f, 160f / 255f, 100f / 255f, 100f / 100f));
[Checkbox("Hide Primals")]
[Order(45)]
public bool HidePrimals = false;
public SummonerTranceBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class SummonerStacksBarConfig : ChunkedBarConfig
{
[Checkbox("Ifrit Stacks", separator = false, spacing = false)]
[Order(51)]
public bool ShowIfritStacks = true;
[Checkbox("Titan Stacks", separator = false, spacing = false)]
[Order(53)]
public bool ShowTitanStacks = true;
[Checkbox("Garuda Stacks", separator = false, spacing = false)]
[Order(55)]
public bool ShowGarudaStacks = true;
[ColorEdit4("Ifrit Stacks Color")]
[Order(56)]
public PluginConfigColor IfritStackColor = new(new Vector4(200f / 255f, 40f / 255f, 0f / 255f, 100f / 100f));
[ColorEdit4("Titan Stacks Color")]
[Order(57)]
public PluginConfigColor TitanStackColor = new(new Vector4(210f / 255f, 150f / 255f, 26f / 255f, 100f / 100f));
[ColorEdit4("Garuda Stacks Color")]
[Order(58)]
public PluginConfigColor GarudaStackColor = new(new Vector4(60f / 255f, 160f / 255f, 100f / 255f, 100f / 100f));
public SummonerStacksBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
+373
View File
@@ -0,0 +1,373 @@
using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using HSUI.Config;
using HSUI.Config.Attributes;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class ViperHud : JobHud
{
private new ViperConfig Config => (ViperConfig)_config;
public ViperHud(ViperConfig config, string? displayName = null) : base(config, displayName) { }
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new List<Vector2>();
List<Vector2> sizes = new List<Vector2>();
if (Config.RattlingCoilGauge.Enabled)
{
positions.Add(Config.Position + Config.RattlingCoilGauge.Position);
sizes.Add(Config.RattlingCoilGauge.Size);
}
if (Config.Vipersight.Enabled)
{
positions.Add(Config.Position + Config.Vipersight.Position);
sizes.Add(Config.Vipersight.Size);
}
if (Config.AnguineTribute.Enabled)
{
positions.Add(Config.Position + Config.AnguineTribute.Position);
sizes.Add(Config.AnguineTribute.Size);
}
if (Config.SerpentOfferings.Enabled)
{
positions.Add(Config.Position + Config.SerpentOfferings.Position);
sizes.Add(Config.SerpentOfferings.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
if (Config.RattlingCoilGauge.Enabled)
{
DrawRattlingCoilGauge(origin + Config.Position, player);
}
if (Config.Vipersight.Enabled)
{
DrawVipersightBar(origin + Config.Position, player);
}
if (Config.SerpentOfferings.Enabled)
{
DrawSerpentOfferingsBar(origin + Config.Position, player);
}
if (Config.AnguineTribute.Enabled)
{
DrawAnguineTributeGauge(origin + Config.Position, player);
}
}
private unsafe void DrawVipersightBar(Vector2 origin, IPlayerCharacter player)
{
ViperCombo lastUsedActionId = (ViperCombo)SpellHelper.Instance.GetLastUsedActionId();
ViperComboState comboState;
bool isAoE = false;
switch (lastUsedActionId)
{
case ViperCombo.SteelMaw:
case ViperCombo.DreadMaw:
isAoE = true;
comboState = ViperComboState.Started;
break;
case ViperCombo.SteelFangs:
case ViperCombo.DreadFangs:
comboState = ViperComboState.Started;
break;
case ViperCombo.HuntersBite:
case ViperCombo.SwiftskinsBite:
isAoE = true;
comboState = ViperComboState.Finisher;
break;
case ViperCombo.HuntersSting:
case ViperCombo.SwiftskinsSting:
comboState = ViperComboState.Finisher;
break;
default:
comboState = ViperComboState.None;
break;
}
if (Config.Vipersight.HideWhenInactive && comboState == ViperComboState.None)
{
return;
}
uint leftId = SpellHelper.Instance.GetSpellActionId(isAoE ? (uint)ViperCombo.SteelMaw : (uint)ViperCombo.SteelFangs);
bool isLeftGlowing = SpellHelper.Instance.IsActionHighlighted(leftId);
uint rightId = SpellHelper.Instance.GetSpellActionId(isAoE ? (uint)ViperCombo.DreadMaw : (uint)ViperCombo.DreadFangs);
bool isRightGlowing = SpellHelper.Instance.IsActionHighlighted(rightId);
List<Tuple<PluginConfigColor, float, LabelConfig?>> chunks = new();
List<bool> glows = new();
Tuple<PluginConfigColor, float, LabelConfig?> empty = new(PluginConfigColor.Empty, 1, null);
Tuple<PluginConfigColor, float, LabelConfig?> start = new(Config.Vipersight.ComboStartColor, 1, null);
Tuple<PluginConfigColor, float, LabelConfig?> endFlank = new(Config.Vipersight.ComboEndFlankColor, 1, null);
Tuple<PluginConfigColor, float, LabelConfig?> endHind = new(Config.Vipersight.ComboEndHindColor, 1, null);
Tuple<PluginConfigColor, float, LabelConfig?> endAoE = new(Config.Vipersight.ComboEndAOEColor, 1, null);
bool isFlankEnder = Utils.StatusListForBattleChara(player).Any(o => o.StatusId is 3645 or 3646);
bool isHindEnder = Utils.StatusListForBattleChara(player).Any(o => o.StatusId is 3647 or 3648);
bool noEnder = !isFlankEnder && !isHindEnder;
switch (comboState)
{
case ViperComboState.None:
{
chunks = [empty, empty, empty, empty];
glows = [false, isLeftGlowing, isRightGlowing, false];
break;
}
case ViperComboState.Started:
{
chunks = [empty, start, start, empty];
glows = [false, isLeftGlowing || isAoE, isRightGlowing || isAoE, false];
break;
}
case ViperComboState.Finisher:
{
bool isFlankChain = lastUsedActionId == ViperCombo.HuntersSting;
bool isHindChain = lastUsedActionId == ViperCombo.SwiftskinsSting;
Tuple<PluginConfigColor, float, LabelConfig?> end;
if (isFlankEnder)
{
end = isHindChain ? endHind : endFlank;
}
else if (isHindEnder)
{
end = isFlankChain ? endFlank : endHind;
}
else
{
end = isFlankChain ? endFlank : isHindChain ? endHind : endAoE;
}
chunks = [end, start, start, end];
glows = [isLeftGlowing, isLeftGlowing, isRightGlowing, isRightGlowing];
break;
}
}
if (Config.Vipersight.Invert)
{
chunks.Reverse();
glows.Reverse();
}
BarHud[] bars = BarUtilities.GetChunkedBars(
Config.Vipersight,
chunks.ToArray(),
player,
Config.Vipersight.GlowConfig,
glows.ToArray()
);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.Vipersight.StrataLevel));
}
}
private unsafe void DrawRattlingCoilGauge(Vector2 origin, IPlayerCharacter player)
{
VPRGauge gauge = Plugin.JobGauges.Get<VPRGauge>();
if (Config.RattlingCoilGauge.HideWhenInactive && gauge.RattlingCoilStacks <= 0)
{
return;
}
int maxStacks = player.Level >= 88 ? 3 : 2;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.RattlingCoilGauge, maxStacks, gauge.RattlingCoilStacks, maxStacks, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.RattlingCoilGauge.StrataLevel));
}
}
private unsafe void DrawAnguineTributeGauge(Vector2 origin, IPlayerCharacter player)
{
VPRGauge gauge = Plugin.JobGauges.Get<VPRGauge>();
if (Config.AnguineTribute.HideWhenInactive && gauge.AnguineTribute <= 0)
{
return;
}
int maxStacks = player.Level >= 96 ? 5 : 4;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.AnguineTribute, maxStacks, gauge.AnguineTribute, maxStacks, 0, player);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.AnguineTribute.StrataLevel));
}
}
private unsafe void DrawSerpentOfferingsBar(Vector2 origin, IPlayerCharacter player)
{
ViperConfig.SerpentOfferingsBarConfig config = Config.SerpentOfferings;
VPRGauge gauge = Plugin.JobGauges.Get<VPRGauge>();
float reawakenedDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 3670 or 4094 && o.RemainingTime > 0f)?.RemainingTime ?? 0f;
bool reAwakenedReady = Utils.StatusListForBattleChara(player).Any(o => o.StatusId is 3671) || gauge.SerpentOffering >= 50;
bool isReawakened = reawakenedDuration > 0;
bool showReawakened = isReawakened && config.EnableAwakenedTimer;
float serpentOffering = showReawakened && isReawakened ? reawakenedDuration : gauge.SerpentOffering;
if (Config.SerpentOfferings.HideWhenInactive && gauge.SerpentOffering <= 0)
{
return;
}
Config.SerpentOfferings.Label.SetValue(serpentOffering);
BarHud[] bars = BarUtilities.GetChunkedProgressBars(
config,
showReawakened ? 1 : 2,
showReawakened ? reawakenedDuration : serpentOffering,
showReawakened ? 30f : 100f,
fillColor: reAwakenedReady ? config.AwakenedColor : config.FillColor
); ;
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.SerpentOfferings.StrataLevel));
}
}
}
public enum ViperCombo
{
SteelFangs = 34606,
DreadFangs = 34607,
HuntersSting = 34608,
SwiftskinsSting = 34609,
SteelMaw = 34614,
DreadMaw = 34615,
HuntersBite = 34616,
SwiftskinsBite = 34617
}
public enum ViperComboState
{
None,
Started,
Finisher
}
[Section("Job Specific Bars")]
[SubSection("Melee", 0)]
[SubSection("Viper", 1)]
public class ViperConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.VPR;
public new static ViperConfig DefaultConfig()
{
var config = new ViperConfig();
config.SerpentOfferings.UseChunks = false;
return config;
}
[NestedConfig("Vipersight Bar", 30)]
public VipersightBarConfig Vipersight = new VipersightBarConfig(
new(0, -10),
new(254, 10),
new(new Vector4(237f / 255f, 141f / 255f, 7f / 255f, 100f / 100f))
);
[NestedConfig("Rattling Coil Bar", 40)]
public ChunkedBarConfig RattlingCoilGauge = new ChunkedBarConfig(
new(0, -34),
new(254, 10),
new(new Vector4(204f / 255f, 40f / 255f, 40f / 255f, 1f))
);
[NestedConfig("Serpent Offerings Bar", 45)]
public SerpentOfferingsBarConfig SerpentOfferings = new SerpentOfferingsBarConfig(
new(0, -46),
new(254, 10),
new(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 1f))
);
[NestedConfig("Anguine Tribute Bar", 50)]
public ChunkedBarConfig AnguineTribute = new ChunkedBarConfig(
new(0, -58),
new(254, 10),
new(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 1f))
);
[Exportable(false)]
public class VipersightBarConfig : ChunkedBarConfig
{
[NestedConfig("Show Glow", 39, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new BarGlowConfig();
[ColorEdit4("Combo Start", spacing = true)]
[Order(41)]
public PluginConfigColor ComboStartColor = new(new Vector4(230f / 255f, 33f / 255f, 33f / 255f, 100f / 100f));
[ColorEdit4("Flank Ender")]
[Order(42)]
public PluginConfigColor ComboEndFlankColor = new(new Vector4(46f / 255f, 228f / 255f, 42f / 255f, 1f));
[ColorEdit4("Hind Ender")]
[Order(43)]
public PluginConfigColor ComboEndHindColor = new(new Vector4(230f / 255f, 33f / 255f, 33f / 255f, 1f));
[ColorEdit4("Grim/Default Ender")]
[Order(44)]
public PluginConfigColor ComboEndAOEColor = new(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 1f));
[Checkbox("Invert", spacing = true)]
[Order(45)]
public bool Invert = false;
public VipersightBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
[Exportable(false)]
public class SerpentOfferingsBarConfig : ChunkedProgressBarConfig
{
[Checkbox("Enable Awakened Timer", spacing = true)]
[Order(46)]
public bool EnableAwakenedTimer = true;
[ColorEdit4("Ready to Reawaken Color")]
[Order(47)]
public PluginConfigColor AwakenedColor = new(new Vector4(69f / 255f, 115f / 255f, 202f / 255f, 1f));
public SerpentOfferingsBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
}
}
}
}
+279
View File
@@ -0,0 +1,279 @@
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<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> 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<WARGauge>();
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<PluginConfigColor, float, LabelConfig?>[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)
{
}
}
}
+298
View File
@@ -0,0 +1,298 @@
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 HSUI.Interface.GeneralElements;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace HSUI.Interface.Jobs
{
public class WhiteMageHud : JobHud
{
private new WhiteMageConfig Config => (WhiteMageConfig)_config;
private static readonly List<uint> DiaIDs = new() { 143, 144, 1871 };
private static readonly List<float> DiaDurations = new() { 30, 30, 30 };
public WhiteMageHud(WhiteMageConfig config, string? displayName = null) : base(config, displayName)
{
}
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
{
List<Vector2> positions = new();
List<Vector2> sizes = new();
if (Config.LilyBar.Enabled)
{
positions.Add(Config.Position + Config.LilyBar.Position);
sizes.Add(Config.LilyBar.Size);
}
if (Config.DiaBar.Enabled)
{
positions.Add(Config.Position + Config.DiaBar.Position);
sizes.Add(Config.DiaBar.Size);
}
if (Config.AsylumBar.Enabled)
{
positions.Add(Config.Position + Config.AsylumBar.Position);
sizes.Add(Config.AsylumBar.Size);
}
if (Config.PresenceOfMindBar.Enabled)
{
positions.Add(Config.Position + Config.PresenceOfMindBar.Position);
sizes.Add(Config.PresenceOfMindBar.Size);
}
if (Config.PlenaryBar.Enabled)
{
positions.Add(Config.Position + Config.PlenaryBar.Position);
sizes.Add(Config.PlenaryBar.Size);
}
if (Config.TemperanceBar.Enabled)
{
positions.Add(Config.Position + Config.TemperanceBar.Position);
sizes.Add(Config.TemperanceBar.Size);
}
return (positions, sizes);
}
public override void DrawJobHud(Vector2 origin, IPlayerCharacter player)
{
Vector2 pos = origin + Config.Position;
if (Config.LilyBar.Enabled)
{
DrawLilyBar(pos, player);
}
if (Config.DiaBar.Enabled)
{
DrawDiaBar(pos, player);
}
if (Config.AsylumBar.Enabled)
{
DrawAsylumBar(pos, player);
}
if (Config.PresenceOfMindBar.Enabled)
{
DrawPresenceOfMindBar(pos, player);
}
if (Config.PlenaryBar.Enabled)
{
DrawPlenaryBar(pos, player);
}
if (Config.TemperanceBar.Enabled)
{
DrawTemperanceBar(pos, player);
}
}
private void DrawDiaBar(Vector2 origin, IPlayerCharacter player)
{
var target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
BarHud? bar = BarUtilities.GetDoTBar(Config.DiaBar, player, target, DiaIDs, DiaDurations);
if (bar != null)
{
AddDrawActions(bar.GetDrawActions(origin, Config.DiaBar.StrataLevel));
}
}
private void DrawLilyBar(Vector2 origin, IPlayerCharacter player)
{
WHMGauge gauge = Plugin.JobGauges.Get<WHMGauge>();
const float lilyCooldown = 20000f;
float GetScale(int num, float timer) => num + (timer / lilyCooldown);
float lilyScale = GetScale(gauge.Lily, gauge.LilyTimer);
if (!Config.LilyBar.HideWhenInactive || lilyScale > 0)
{
BarHud[] bars = BarUtilities.GetChunkedBars(Config.LilyBar, 3, lilyScale, 3, 0, player, partialFillColor: Config.LilyBar.PartialFillColor);
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.LilyBar.StrataLevel));
}
}
if (!Config.BloodLilyBar.HideWhenInactive && Config.BloodLilyBar.Enabled || gauge.BloodLily > 0)
{
BarGlowConfig? glow = gauge.BloodLily == 3 ? Config.BloodLilyBar.GlowConfig : null;
BarHud[] bars = BarUtilities.GetChunkedBars(Config.BloodLilyBar, 3, gauge.BloodLily, 3, 0, player, glowConfig: glow, chunksToGlow: new[] { true, true, true });
foreach (BarHud bar in bars)
{
AddDrawActions(bar.GetDrawActions(origin, Config.BloodLilyBar.StrataLevel));
}
}
}
private void DrawAsylumBar(Vector2 origin, IPlayerCharacter player)
{
float asylymDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 739 or 1911 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.AsylumBar.HideWhenInactive || asylymDuration > 0)
{
Config.AsylumBar.Label.SetValue(asylymDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.AsylumBar, asylymDuration, 24f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.AsylumBar.StrataLevel));
}
}
private void DrawPresenceOfMindBar(Vector2 origin, IPlayerCharacter player)
{
float presenceOfMindDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 157 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.PresenceOfMindBar.HideWhenInactive || presenceOfMindDuration > 0)
{
Config.PresenceOfMindBar.Label.SetValue(presenceOfMindDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.PresenceOfMindBar, presenceOfMindDuration, 15f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.PresenceOfMindBar.StrataLevel));
}
}
private void DrawPlenaryBar(Vector2 origin, IPlayerCharacter player)
{
float plenaryDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1219 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.PlenaryBar.HideWhenInactive || plenaryDuration > 0)
{
Config.PlenaryBar.Label.SetValue(plenaryDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.PlenaryBar, plenaryDuration, 10f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.PlenaryBar.StrataLevel));
}
}
private void DrawTemperanceBar(Vector2 origin, IPlayerCharacter player)
{
float temperanceDuration = Utils.StatusListForBattleChara(player).FirstOrDefault(o => o.StatusId is 1872 && o.SourceId == player.GameObjectId)?.RemainingTime ?? 0f;
if (!Config.TemperanceBar.HideWhenInactive || temperanceDuration > 0)
{
Config.TemperanceBar.Label.SetValue(temperanceDuration);
BarHud bar = BarUtilities.GetProgressBar(Config.TemperanceBar, temperanceDuration, 20f, 0f, player);
AddDrawActions(bar.GetDrawActions(origin, Config.TemperanceBar.StrataLevel));
}
}
}
[Section("Job Specific Bars")]
[SubSection("Healer", 0)]
[SubSection("White Mage", 1)]
public class WhiteMageConfig : JobConfig
{
[JsonIgnore] public override uint JobId => JobIDs.WHM;
public new static WhiteMageConfig DefaultConfig()
{
var config = new WhiteMageConfig();
config.UseDefaultPrimaryResourceBar = true;
config.AsylumBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.PresenceOfMindBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.PlenaryBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
config.TemperanceBar.Label.FontID = FontsConfig.DefaultMediumFontKey;
return config;
}
[NestedConfig("Lily Bar", 30)]
public LilyBarConfig LilyBar = new LilyBarConfig(
new(-64, -32),
new(126, 20),
new PluginConfigColor(new(0f / 255f, 64f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Blood Lily Bar", 35)]
public BloodLilyBarConfig BloodLilyBar = new BloodLilyBarConfig(
new(64, -32),
new(126, 20),
new PluginConfigColor(new(199f / 255f, 40f / 255f, 9f / 255f, 100f / 100f))
);
[NestedConfig("Dia Bar", 40)]
public ProgressBarConfig DiaBar = new ProgressBarConfig(
new(0, -10),
new(254, 20),
new PluginConfigColor(new(0f / 255f, 64f / 255f, 255f / 255f, 100f / 100f))
);
[NestedConfig("Asylum Bar", 45)]
public ProgressBarConfig AsylumBar = new ProgressBarConfig(
new(-96, -52),
new(62, 15),
new PluginConfigColor(new(241f / 255f, 217f / 255f, 125f / 255f, 100f / 100f))
);
[NestedConfig("Presence of Mind Bar", 50)]
public ProgressBarConfig PresenceOfMindBar = new ProgressBarConfig(
new(-32, -52),
new(62, 15),
new PluginConfigColor(new(213f / 255f, 124f / 255f, 97f / 255f, 100f / 100f))
);
[NestedConfig("Plenary Bar", 55)]
public ProgressBarConfig PlenaryBar = new ProgressBarConfig(
new(32, -52),
new(62, 15),
new PluginConfigColor(new(26f / 255f, 167f / 255f, 109f / 255f, 100f / 100f))
);
[NestedConfig("Temperance Bar", 60)]
public ProgressBarConfig TemperanceBar = new ProgressBarConfig(
new(96, -52),
new(62, 15),
new PluginConfigColor(new(100f / 255f, 207f / 255f, 211f / 255f, 100f / 100f))
);
}
[Exportable(false)]
public class LilyBarConfig : ChunkedBarConfig
{
[Checkbox("Use Partial Fill Color", spacing = true)]
[Order(65)]
public bool UsePartialFillColor = false;
[ColorEdit4("Partial Fill Color")]
[Order(66, collapseWith = nameof(UsePartialFillColor))]
public PluginConfigColor PartialFillColor;
public LilyBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
PartialFillColor = new PluginConfigColor(new(0f / 255f, 64f / 255f, 255f / 255f, 50f / 100f));
}
}
[Exportable(false)]
public class BloodLilyBarConfig : ChunkedBarConfig
{
[NestedConfig("Glow Color (when Misery ready)", 60, separator = false, spacing = true)]
public BarGlowConfig GlowConfig = new();
public BloodLilyBarConfig(Vector2 position, Vector2 size, PluginConfigColor fillColor)
: base(position, size, fillColor)
{
GlowConfig.Color = new PluginConfigColor(new(247f / 255f, 177f / 255f, 67f / 255f, 100f / 100f));
}
}
}