Files
HSUI/Interface/Party/PartyFramesBar.cs
T

752 lines
33 KiB
C#

using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Statuses;
using Dalamud.Interface.Textures.TextureWraps;
using HSUI.Config;
using HSUI.Enums;
using HSUI.Helpers;
using HSUI.Interface.Bars;
using HSUI.Interface.GeneralElements;
using HSUI.Interface.StatusEffects;
using Dalamud.Bindings.ImGui;
using System;
using System.Collections.Generic;
using System.Numerics;
namespace HSUI.Interface.Party
{
public class PartyFramesBar
{
public delegate void PartyFramesBarEventHandler(PartyFramesBar bar);
public PartyFramesBarEventHandler? OpenContextMenuEvent;
private PartyFramesConfigs _configs;
private LabelHud _nameLabelHud;
private LabelHud _healthLabelHud;
private LabelHud _orderLabelHud;
private LabelHud _statusLabelHud;
private LabelHud _raiseLabelHud;
private LabelHud _invulnLabelHud;
private PrimaryResourceHud _manaBarHud;
private CastbarHud _castbarHud;
private StatusEffectsListHud _buffsListHud;
private StatusEffectsListHud _debuffsListHud;
private PartyFramesCooldownListHud _cooldownListHud;
private IDalamudTextureWrap? _readyCheckTexture =>
TexturesHelper.GetTextureFromPath("ui/uld/ReadyCheck_hr1.tex") ??
TexturesHelper.GetTextureFromPath("ui/uld/ReadyCheck.tex");
public bool Visible = false;
public Vector2 Position;
private SmoothHPHelper _smoothHPHelper = new SmoothHPHelper();
private bool _wasHovering = false;
public IPartyFramesMember? Member;
public PartyFramesBar(string id, PartyFramesConfigs configs)
{
_configs = configs;
_nameLabelHud = new LabelHud(_configs.HealthBar.NameLabelConfig);
_healthLabelHud = new LabelHud(_configs.HealthBar.HealthLabelConfig);
_orderLabelHud = new LabelHud(_configs.HealthBar.OrderNumberConfig);
_statusLabelHud = new LabelHud(PlayerStatus.Label);
_raiseLabelHud = new LabelHud(RaiseTracker.Icon.NumericLabel);
_invulnLabelHud = new LabelHud(InvulnTracker.Icon.NumericLabel);
_manaBarHud = new PrimaryResourceHud(_configs.ManaBar);
_castbarHud = new CastbarHud(_configs.CastBar);
_buffsListHud = new StatusEffectsListHud(_configs.Buffs);
_debuffsListHud = new StatusEffectsListHud(_configs.Debuffs);
_cooldownListHud = new PartyFramesCooldownListHud(_configs.CooldownList);
}
public PluginConfigColor GetColor(float scale)
{
if (Member == null || Member.MaxHP <= 0)
{
return _configs.HealthBar.ColorsConfig.OutOfReachBackgroundColor;
}
bool cleanseCheck = true;
if (CleanseTracker.CleanseJobsOnly)
{
cleanseCheck = Utils.IsOnCleanseJob();
}
if (CleanseTracker.Enabled && CleanseTracker.ChangeHealthBarCleanseColor && Member.HasDispellableDebuff && cleanseCheck)
{
return CleanseTracker.HealthBarColor;
}
else if (_configs.HealthBar.ColorsConfig.ColorByHealth.Enabled)
{
if (_configs.HealthBar.ColorsConfig.ColorByHealth.UseJobColorAsMaxHealth)
{
return ColorUtils.GetColorByScale(scale, _configs.HealthBar.ColorsConfig.ColorByHealth.LowHealthColorThreshold / 100f, _configs.HealthBar.ColorsConfig.ColorByHealth.FullHealthColorThreshold / 100f, _configs.HealthBar.ColorsConfig.ColorByHealth.LowHealthColor, _configs.HealthBar.ColorsConfig.ColorByHealth.FullHealthColor,
GlobalColors.Instance.SafeColorForJobId(Member.JobId), _configs.HealthBar.ColorsConfig.ColorByHealth.UseMaxHealthColor, _configs.HealthBar.ColorsConfig.ColorByHealth.BlendMode);
}
else if (_configs.HealthBar.ColorsConfig.ColorByHealth.UseRoleColorAsMaxHealth)
{
return ColorUtils.GetColorByScale(scale, _configs.HealthBar.ColorsConfig.ColorByHealth.LowHealthColorThreshold / 100f, _configs.HealthBar.ColorsConfig.ColorByHealth.FullHealthColorThreshold / 100f, _configs.HealthBar.ColorsConfig.ColorByHealth.LowHealthColor, _configs.HealthBar.ColorsConfig.ColorByHealth.FullHealthColor,
GlobalColors.Instance.SafeRoleColorForJobId(Member.JobId), _configs.HealthBar.ColorsConfig.ColorByHealth.UseMaxHealthColor, _configs.HealthBar.ColorsConfig.ColorByHealth.BlendMode);
}
return ColorUtils.GetColorByScale(scale, _configs.HealthBar.ColorsConfig.ColorByHealth);
}
else if (Member.JobId > 0)
{
return _configs.HealthBar.ColorsConfig.UseRoleColors switch
{
true => GlobalColors.Instance.SafeRoleColorForJobId(Member.JobId),
_ => GlobalColors.Instance.SafeColorForJobId(Member.JobId)
};
}
return Member.Character?.ObjectKind switch
{
ObjectKind.BattleNpc => GlobalColors.Instance.NPCFriendlyColor,
_ => _configs.HealthBar.ColorsConfig.OutOfReachBackgroundColor
};
}
public void StopPreview()
{
_castbarHud.StopPreview();
_buffsListHud.StopPreview();
_debuffsListHud.StopPreview();
_cooldownListHud.StopPreview();
_configs.HealthBar.MouseoverAreaConfig.Preview = false;
}
public void StopMouseover()
{
if (_wasHovering)
{
InputsHelper.Instance.ClearTarget();
_wasHovering = false;
}
}
public void Dispose()
{
_cooldownListHud.Dispose();
}
public List<(StrataLevel, Action)> GetBarDrawActions(Vector2 origin, PluginConfigColor? borderColor = null)
{
List<(StrataLevel, Action)> drawActions = new List<(StrataLevel, Action)>();
if (!Visible || Member is null)
{
StopMouseover();
return drawActions;
}
// click
var (areaStart, areaEnd) = _configs.HealthBar.MouseoverAreaConfig.GetArea(Position, _configs.HealthBar.Size);
bool isHovering = ImGui.IsMouseHoveringRect(areaStart, areaEnd);
bool ignoreMouseover = _configs.HealthBar.MouseoverAreaConfig.Enabled && _configs.HealthBar.MouseoverAreaConfig.Ignore;
ICharacter? character = Member.Character;
if (isHovering)
{
_wasHovering = true;
InputsHelper.Instance.SetTarget(character, ignoreMouseover);
// left click
if (InputsHelper.Instance.LeftButtonClicked && character != null)
{
Plugin.TargetManager.Target = character;
}
// right click (context menu)
else if (InputsHelper.Instance.RightButtonClicked)
{
OpenContextMenuEvent?.Invoke(this);
}
}
else if (_wasHovering)
{
InputsHelper.Instance.ClearTarget();
_wasHovering = false;
}
// bg
PluginConfigColor bgColor = _configs.HealthBar.ColorsConfig.BackgroundColor;
if (Member.RaiseTime != null && RaiseTracker.Enabled && RaiseTracker.ChangeBackgroundColorWhenRaised)
{
bgColor = RaiseTracker.BackgroundColor;
}
else if (Member.InvulnStatus?.InvulnTime != null && InvulnTracker.Enabled && InvulnTracker.ChangeBackgroundColorWhenInvuln)
{
bgColor = Member.InvulnStatus?.InvulnId == 811 ? InvulnTracker.WalkingDeadBackgroundColor : InvulnTracker.BackgroundColor;
}
else if (_configs.HealthBar.ColorsConfig.UseDeathIndicatorBackgroundColor && Member.HP <= 0 && character != null)
{
bgColor = _configs.HealthBar.RangeConfig.Enabled
? GetDistanceColor(character, _configs.HealthBar.ColorsConfig.DeathIndicatorBackgroundColor)
: _configs.HealthBar.ColorsConfig.DeathIndicatorBackgroundColor;
}
else if (_configs.HealthBar.ColorsConfig.UseJobColorAsBackgroundColor && character is IBattleChara)
{
bgColor = GlobalColors.Instance.SafeColorForJobId(character.ClassJob.RowId);
}
else if (_configs.HealthBar.ColorsConfig.UseRoleColorAsBackgroundColor && character is IBattleChara)
{
bgColor = _configs.HealthBar.RangeConfig.Enabled
? GetDistanceColor(character, GlobalColors.Instance.SafeRoleColorForJobId(character.ClassJob.RowId))
: GlobalColors.Instance.SafeRoleColorForJobId(character.ClassJob.RowId);
}
Rect background = new Rect(Position, _configs.HealthBar.Size, bgColor);
// hp
uint currentHp = Member.HP;
uint maxHp = Member.MaxHP;
if (_configs.HealthBar.SmoothHealthConfig.Enabled)
{
currentHp = _smoothHPHelper.GetNextHp((int)currentHp, (int)maxHp, _configs.HealthBar.SmoothHealthConfig.Velocity);
}
float hpScale = maxHp > 0 ? (float)currentHp / (float)maxHp : 1;
PluginConfigColor? hpColor = _configs.HealthBar.RangeConfig.Enabled && character != null
? GetDistanceColor(character, GetColor(hpScale))
: GetColor(hpScale);
Rect healthFill = BarUtilities.GetFillRect(Position, _configs.HealthBar.Size, _configs.HealthBar.FillDirection, hpColor, currentHp, maxHp);
// bar
int thickness = borderColor != null ? _configs.HealthBar.ColorsConfig.ActiveBorderThickness : _configs.HealthBar.ColorsConfig.InactiveBorderThickness;
if (WhosTalkingIcon.ChangeBorders && Member.WhosTalkingState != WhosTalkingState.None)
{
thickness = WhosTalkingIcon.BorderThickness;
}
borderColor = borderColor ?? GetBorderColor(character);
BarHud bar = new BarHud(
_configs.HealthBar.ID,
_configs.HealthBar.ColorsConfig.ShowBorder,
borderColor,
thickness,
actor: character,
current: currentHp,
max: maxHp,
shadowConfig: _configs.HealthBar.ShadowConfig,
barTextureName: _configs.HealthBar.BarTextureName,
barTextureDrawMode: _configs.HealthBar.BarTextureDrawMode
);
bar.NeedsInputs = true;
bar.SetBackground(background);
bar.AddForegrounds(healthFill);
// missing health
if (_configs.HealthBar.ColorsConfig.UseMissingHealthBar)
{
Vector2 healthMissingSize = _configs.HealthBar.Size - BarUtilities.GetFillDirectionOffset(healthFill.Size, _configs.HealthBar.FillDirection);
Vector2 healthMissingPos = _configs.HealthBar.FillDirection.IsInverted() ? Position : Position + BarUtilities.GetFillDirectionOffset(healthFill.Size, _configs.HealthBar.FillDirection);
PluginConfigColor? missingHealthColor = _configs.HealthBar.ColorsConfig.UseJobColorAsMissingHealthColor && character is IBattleChara
? GlobalColors.Instance.SafeColorForJobId(character!.ClassJob.RowId)
: _configs.HealthBar.ColorsConfig.UseRoleColorAsMissingHealthColor && character is IBattleChara
? GlobalColors.Instance.SafeRoleColorForJobId(character!.ClassJob.RowId)
: _configs.HealthBar.ColorsConfig.HealthMissingColor;
if (_configs.HealthBar.ColorsConfig.UseDeathIndicatorBackgroundColor && Member.HP <= 0 && character != null)
{
missingHealthColor = _configs.HealthBar.ColorsConfig.DeathIndicatorBackgroundColor;
}
if (_configs.Trackers.Invuln.ChangeBackgroundColorWhenInvuln && character is IBattleChara battleChara)
{
IStatus? tankInvuln = Utils.GetTankInvulnerabilityID(battleChara);
if (tankInvuln is not null)
{
missingHealthColor = _configs.Trackers.Invuln.BackgroundColor;
}
}
if (_configs.HealthBar.RangeConfig.Enabled)
{
missingHealthColor = GetDistanceColor(character, missingHealthColor);
}
bar.AddForegrounds(new Rect(healthMissingPos, healthMissingSize, missingHealthColor));
}
// shield
if (_configs.HealthBar.ShieldConfig.Enabled)
{
if (Member.Shield > 0f)
{
bar.AddForegrounds(
BarUtilities.GetShieldForeground(
_configs.HealthBar.ShieldConfig,
Position,
_configs.HealthBar.Size,
healthFill.Size,
_configs.HealthBar.FillDirection,
Member.Shield,
currentHp,
maxHp
)
);
}
}
// highlight
bool isSoftTarget = character != null && character == Plugin.TargetManager.SoftTarget;
if (_configs.HealthBar.ColorsConfig.ShowHighlight && (isHovering || isSoftTarget))
{
Rect highlight = new Rect(Position, _configs.HealthBar.Size, _configs.HealthBar.ColorsConfig.HighlightColor);
bar.AddForegrounds(highlight);
}
drawActions = bar.GetDrawActions(Vector2.Zero, _configs.HealthBar.StrataLevel);
// mouseover area
BarHud? mouseoverAreaBar = _configs.HealthBar.MouseoverAreaConfig.GetBar(
Position,
_configs.HealthBar.Size,
_configs.HealthBar.ID + "_mouseoverArea"
);
if (mouseoverAreaBar != null)
{
drawActions.AddRange(mouseoverAreaBar.GetDrawActions(Vector2.Zero, StrataLevel.HIGHEST));
}
return drawActions;
}
private PluginConfigColor GetBorderColor(ICharacter? character)
{
IGameObject? target = Plugin.TargetManager.Target ?? Plugin.TargetManager.SoftTarget;
return character != null && character == target ? _configs.HealthBar.ColorsConfig.TargetBordercolor : _configs.HealthBar.ColorsConfig.BorderColor;
}
private PluginConfigColor GetDistanceColor(ICharacter? character, PluginConfigColor color)
{
byte distance = character != null ? character.YalmDistanceX : byte.MaxValue;
float currentAlpha = color.Vector.W * 100f;
float alpha = _configs.HealthBar.RangeConfig.AlphaForDistance(distance, currentAlpha) / 100f;
return color.WithAlpha(alpha);
}
// need to separate elements that have their own window so clipping doesn't get messy
public List<(StrataLevel, Action)> GetElementsDrawActions(Vector2 origin)
{
List<(StrataLevel, Action)> drawActions = new List<(StrataLevel, Action)>();
IPlayerCharacter? player = Plugin.ObjectTable.LocalPlayer;
if (!Visible || Member is null || player == null)
{
StopMouseover();
return drawActions;
}
ICharacter? character = Member.Character;
// who's talking
bool drawingWhosTalking = false;
if (WhosTalkingIcon.Enabled && WhosTalkingIcon.Icon.Enabled && WhosTalkingIcon.EnabledForState(Member.WhosTalkingState))
{
IDalamudTextureWrap? texture = WhosTalkingHelper.Instance.GetTextureForState(Member.WhosTalkingState);
if (texture != null)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, WhosTalkingIcon.Icon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + WhosTalkingIcon.Icon.Position, WhosTalkingIcon.Icon.Size, WhosTalkingIcon.Icon.Anchor);
drawActions.Add((WhosTalkingIcon.Icon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(WhosTalkingIcon.Icon.ID, iconPos, WhosTalkingIcon.Icon.Size, false, (drawList) =>
{
ImGui.SetCursorPos(iconPos);
ImGui.Image(texture.Handle, WhosTalkingIcon.Icon.Size);
});
}
));
drawingWhosTalking = true;
}
}
// role/job icon
if (RoleIcon.Enabled && (!drawingWhosTalking || !WhosTalkingIcon.ReplaceRoleJobIcon))
{
uint iconId = 0;
// chocobo icon
if (character is IBattleNpc battleNpc && battleNpc.BattleNpcKind == BattleNpcSubKind.Chocobo)
{
iconId = JobsHelper.RoleIconIDForBattleCompanion + (uint)RoleIcon.Style * 100;
}
// role/job icon
else if (Member.JobId > 0)
{
iconId = RoleIcon.UseRoleIcons ?
JobsHelper.RoleIconIDForJob(Member.JobId, RoleIcon.UseSpecificDPSRoleIcons) :
JobsHelper.IconIDForJob(Member.JobId, (uint)RoleIcon.Style);
}
if (iconId > 0)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, RoleIcon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + RoleIcon.Position, RoleIcon.Size, RoleIcon.Anchor);
drawActions.Add((RoleIcon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(RoleIcon.ID, iconPos, RoleIcon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(iconId, iconPos, RoleIcon.Size, false, drawList);
});
}
));
}
}
// sign icon
if (SignIcon.Enabled)
{
uint? iconId = SignIcon.IconID(character);
if (iconId.HasValue)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, SignIcon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + SignIcon.Position, SignIcon.Size, SignIcon.Anchor);
drawActions.Add((SignIcon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(SignIcon.ID, iconPos, SignIcon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(iconId.Value, iconPos, SignIcon.Size, false, drawList);
});
}
));
}
}
// leader icon
if (LeaderIcon.Enabled && Member.IsPartyLeader)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, LeaderIcon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + LeaderIcon.Position, LeaderIcon.Size, LeaderIcon.Anchor);
drawActions.Add((LeaderIcon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(LeaderIcon.ID, iconPos, LeaderIcon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(61521, iconPos, LeaderIcon.Size, false, drawList);
});
}
));
}
// player status icon
if (PlayerStatus.Enabled && PlayerStatus.Icon.Enabled)
{
uint? iconId = IconIdForStatus(Member.Status);
if (iconId.HasValue)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, PlayerStatus.Icon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + PlayerStatus.Icon.Position, PlayerStatus.Icon.Size, PlayerStatus.Icon.Anchor);
drawActions.Add((PlayerStatus.Icon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(PlayerStatus.Icon.ID, iconPos, PlayerStatus.Icon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(iconId.Value, iconPos, PlayerStatus.Icon.Size, false, drawList);
});
}
));
}
}
// ready check status icon
if (Member.ReadyCheckStatus != ReadyCheckStatus.None && ReadyCheckIcon.Enabled && ReadyCheckIcon.Icon.Enabled && _readyCheckTexture != null)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, ReadyCheckIcon.Icon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + ReadyCheckIcon.Icon.Position, ReadyCheckIcon.Icon.Size, ReadyCheckIcon.Icon.Anchor);
drawActions.Add((ReadyCheckIcon.Icon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(ReadyCheckIcon.Icon.ID, iconPos, ReadyCheckIcon.Icon.Size, false, (drawList) =>
{
Vector2 uv0 = new Vector2(0.5f * (int)Member.ReadyCheckStatus, 0f);
Vector2 uv1 = new Vector2(0.5f + 0.5f * (int)Member.ReadyCheckStatus, 1f);
drawList.AddImage(_readyCheckTexture.Handle, iconPos, iconPos + ReadyCheckIcon.Icon.Size, uv0, uv1);
});
}
));
}
// raise icon
bool showingRaise = ShowingRaise();
if (showingRaise && RaiseTracker.Icon.Enabled)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, RaiseTracker.Icon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + RaiseTracker.Icon.Position, RaiseTracker.Icon.Size, RaiseTracker.Icon.Anchor);
drawActions.Add((RaiseTracker.Icon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(RaiseTracker.Icon.ID, iconPos, RaiseTracker.Icon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(411, iconPos, RaiseTracker.Icon.Size, true, drawList);
});
}
));
}
// invuln icon
bool showingInvuln = ShowingInvuln();
if (showingInvuln && InvulnTracker.Icon.Enabled)
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, InvulnTracker.Icon.FrameAnchor);
Vector2 iconPos = Utils.GetAnchoredPosition(parentPos + InvulnTracker.Icon.Position, InvulnTracker.Icon.Size, InvulnTracker.Icon.Anchor);
drawActions.Add((InvulnTracker.Icon.StrataLevel, () =>
{
DrawHelper.DrawInWindow(InvulnTracker.Icon.ID, iconPos, InvulnTracker.Icon.Size, false, (drawList) =>
{
DrawHelper.DrawIcon(Member.InvulnStatus!.InvulnIcon, iconPos, InvulnTracker.Icon.Size, true, drawList);
});
}
));
}
// mana
if (ShowMana())
{
Vector2 parentPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, _configs.ManaBar.HealthBarAnchor);
drawActions.Add((_configs.ManaBar.StrataLevel, () =>
{
_manaBarHud.Actor = character;
_manaBarHud.PartyMember = Member;
_manaBarHud.PrepareForDraw(parentPos);
_manaBarHud.Draw(parentPos);
}
));
}
// buffs / debuffs
Vector2 buffsPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, _configs.Buffs.HealthBarAnchor);
drawActions.Add((_configs.Buffs.StrataLevel, () =>
{
_buffsListHud.Actor = character;
_buffsListHud.PrepareForDraw(buffsPos);
_buffsListHud.Draw(buffsPos);
}
));
Vector2 debuffsPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, _configs.Debuffs.HealthBarAnchor);
drawActions.Add((_configs.Debuffs.StrataLevel, () =>
{
_debuffsListHud.Actor = character;
_debuffsListHud.PrepareForDraw(debuffsPos);
_debuffsListHud.Draw(debuffsPos);
}
));
// cooldown list
Vector2 cooldownListPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, _configs.CooldownList.HealthBarAnchor);
drawActions.Add((_configs.CooldownList.StrataLevel, () =>
{
_cooldownListHud.Actor = character;
_cooldownListHud.PrepareForDraw(cooldownListPos);
_cooldownListHud.Draw(cooldownListPos);
}
));
// castbar
Vector2 castbarPos = Utils.GetAnchoredPosition(Position, -_configs.HealthBar.Size, _configs.CastBar.HealthBarAnchor);
drawActions.Add((_configs.CastBar.StrataLevel, () =>
{
_castbarHud.Actor = character;
_castbarHud.PrepareForDraw(castbarPos);
_castbarHud.Draw(castbarPos);
}
));
if (_configs.HealthBar.ShowLabels)
{
// name
bool drawName = ShouldDrawName(character, showingRaise, showingInvuln);
if (drawName)
{
drawActions.Add((_configs.HealthBar.NameLabelConfig.StrataLevel, () =>
{
bool? playerName = null;
if (character == null || character.ObjectKind == ObjectKind.Player)
{
playerName = true;
}
_nameLabelHud.Draw(Position, _configs.HealthBar.Size, character, Member.Name, isPlayerName: playerName);
}
));
}
// health label
if (Member.MaxHP > 0)
{
drawActions.Add((_configs.HealthBar.HealthLabelConfig.StrataLevel, () =>
{
_healthLabelHud.Draw(Position, _configs.HealthBar.Size, character, null, Member.HP, Member.MaxHP);
}
));
}
// order
if (character == null || character?.ObjectKind != ObjectKind.BattleNpc)
{
string str = char.ConvertFromUtf32(0xE090 + Member.Order).ToString();
drawActions.Add((_configs.HealthBar.OrderNumberConfig.StrataLevel, () =>
{
_configs.HealthBar.OrderNumberConfig.SetText(str);
_orderLabelHud.Draw(Position, _configs.HealthBar.Size, character);
}
));
}
// status
string? statusString = StringForStatus(Member.Status);
if (PlayerStatus.Enabled && PlayerStatus.Label.Enabled && statusString != null)
{
drawActions.Add((PlayerStatus.Label.StrataLevel, () =>
{
PlayerStatus.Label.SetText(statusString);
_statusLabelHud.Draw(Position, _configs.HealthBar.Size);
}
));
}
// raise label
if (showingRaise)
{
float duration = Math.Abs(Member.RaiseTime!.Value);
drawActions.Add((RaiseTracker.Icon.NumericLabel.StrataLevel, () =>
{
RaiseTracker.Icon.NumericLabel.SetValue(duration);
_raiseLabelHud.Draw(Position, _configs.HealthBar.Size);
}
));
}
// invuln label
if (showingInvuln)
{
float duration = Math.Abs(Member.InvulnStatus!.InvulnTime);
drawActions.Add((InvulnTracker.Icon.NumericLabel.StrataLevel, () =>
{
InvulnTracker.Icon.NumericLabel.SetValue(duration);
_invulnLabelHud.Draw(Position, _configs.HealthBar.Size);
}
));
}
}
return drawActions;
}
private bool ShouldDrawName(ICharacter? character, bool showingRaise, bool showingInvuln)
{
if (showingRaise && RaiseTracker.HideNameWhenRaised)
{
return false;
}
if (showingInvuln && InvulnTracker.HideNameWhenInvuln)
{
return false;
}
if (Member != null && PlayerStatus.Enabled && PlayerStatus.HideName && Member.Status != PartyMemberStatus.None)
{
return false;
}
if (Member != null && ReadyCheckIcon.Enabled && ReadyCheckIcon.HideName && Member.ReadyCheckStatus != ReadyCheckStatus.None)
{
return false;
}
if (Utils.IsActorCasting(character) && _configs.CastBar.Enabled && _configs.CastBar.HideNameWhenCasting)
{
return false;
}
return true;
}
private bool ShowingRaise() =>
Member != null && Member.RaiseTime.HasValue && RaiseTracker.Enabled &&
(Member.RaiseTime.Value > 0 || RaiseTracker.KeepIconAfterCastFinishes);
private bool ShowingInvuln() => Member != null && Member.InvulnStatus != null && InvulnTracker.Enabled && Member.InvulnStatus.InvulnTime > 0;
private bool ShowMana()
{
if (Member == null)
{
return false;
}
var isHealer = JobsHelper.IsJobHealer(Member.JobId);
return _configs.ManaBar.Enabled && Member.MaxHP > 0 && _configs.ManaBar.ManaBarDisplayMode switch
{
PartyFramesManaBarDisplayMode.Always => true,
PartyFramesManaBarDisplayMode.HealersOnly => isHealer,
PartyFramesManaBarDisplayMode.HealersAndRaiseJobs => isHealer || JobsHelper.IsJobWithRaise(Member.JobId, Member.Level),
_ => true
};
}
private static uint? IconIdForStatus(PartyMemberStatus status)
{
return status switch
{
PartyMemberStatus.ViewingCutscene => 61508,
PartyMemberStatus.Offline => 61504,
PartyMemberStatus.Dead => 61502,
_ => null
};
}
private static string? StringForStatus(PartyMemberStatus status)
{
return status switch
{
PartyMemberStatus.ViewingCutscene => "[Viewing Cutscene]",
PartyMemberStatus.Offline => "[Offline]",
PartyMemberStatus.Dead => "[Dead]",
_ => null
};
}
#region convenience
private PartyFramesRoleIconConfig RoleIcon => _configs.Icons.Role;
private SignIconConfig SignIcon => _configs.Icons.Sign;
private PartyFramesLeaderIconConfig LeaderIcon => _configs.Icons.Leader;
private PartyFramesPlayerStatusConfig PlayerStatus => _configs.Icons.PlayerStatus;
private PartyFramesReadyCheckStatusConfig ReadyCheckIcon => _configs.Icons.ReadyCheckStatus;
private PartyFramesWhosTalkingConfig WhosTalkingIcon => _configs.Icons.WhosTalking;
private PartyFramesRaiseTrackerConfig RaiseTracker => _configs.Trackers.Raise;
private PartyFramesInvulnTrackerConfig InvulnTracker => _configs.Trackers.Invuln;
private PartyFramesCleanseTrackerConfig CleanseTracker => _configs.Trackers.Cleanse;
#endregion
}
}