11b4c268f0
Co-authored-by: Cursor <cursoragent@cursor.com>
286 lines
12 KiB
C#
286 lines
12 KiB
C#
using Dalamud.Game.ClientState.Objects.Types;
|
|
using Dalamud.Bindings.ImGui;
|
|
using HSUI.Config;
|
|
using HSUI.Enums;
|
|
using HSUI.Helpers;
|
|
using HSUI.Interface.GeneralElements;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
|
|
namespace HSUI.Interface.Party
|
|
{
|
|
public class AllianceFramesHud : DraggableHudElement, IHudElementWithMouseOver, IHudElementWithPreview, IHudElementWithVisibilityConfig
|
|
{
|
|
private AllianceFramesConfigBase Config => (AllianceFramesConfigBase)_config;
|
|
public VisibilityConfig VisibilityConfig => Config.VisibilityConfig;
|
|
private PartyFramesConfigs Configs;
|
|
|
|
private Vector2 _contentMargin = new Vector2(2, 2);
|
|
private static readonly int MaxMemberCount = 8;
|
|
|
|
private Vector2 _origin;
|
|
private LayoutInfo _layoutInfo;
|
|
private uint _memberCount = 0;
|
|
private bool _layoutDirty = true;
|
|
|
|
private readonly List<PartyFramesBar> bars;
|
|
private LabelHud _titleLabelHud;
|
|
|
|
public AllianceFramesHud(AllianceFramesConfigBase config, string displayName) : base(config, displayName)
|
|
{
|
|
Configs = PartyFramesConfigs.GetAllianceConfigs();
|
|
|
|
config.ValueChangeEvent += OnLayoutPropertyChanged;
|
|
Configs.HealthBar.ValueChangeEvent += OnLayoutPropertyChanged;
|
|
Configs.HealthBar.ColorsConfig.ValueChangeEvent += OnLayoutPropertyChanged;
|
|
|
|
bars = new List<PartyFramesBar>(MaxMemberCount);
|
|
for (int i = 0; i < bars.Capacity; i++)
|
|
{
|
|
var bar = new PartyFramesBar("HSUI_allianceFramesBar_" + Config.SlotIndex + "_" + i, Configs);
|
|
bars.Add(bar);
|
|
}
|
|
|
|
_titleLabelHud = new LabelHud(Config.TitleLabelConfig);
|
|
|
|
AllianceManager.Instance.MembersChangedEvent += OnMembersChanged;
|
|
}
|
|
|
|
protected override void InternalDispose()
|
|
{
|
|
foreach (var bar in bars)
|
|
{
|
|
try { bar.Dispose(); }
|
|
catch (Exception ex) { Plugin.Logger.Error($"Error disposing AllianceFramesBar: {ex.Message}"); }
|
|
}
|
|
bars.Clear();
|
|
|
|
_config.ValueChangeEvent -= OnLayoutPropertyChanged;
|
|
Configs.HealthBar.ValueChangeEvent -= OnLayoutPropertyChanged;
|
|
Configs.HealthBar.ColorsConfig.ValueChangeEvent -= OnLayoutPropertyChanged;
|
|
AllianceManager.Instance.MembersChangedEvent -= OnMembersChanged;
|
|
}
|
|
|
|
private void OnLayoutPropertyChanged(object sender, OnChangeBaseArgs args)
|
|
{
|
|
if (args.PropertyName == "Size" || args.PropertyName == "FillRowsFirst" ||
|
|
args.PropertyName == "BarsAnchor" || args.PropertyName == "Padding" ||
|
|
args.PropertyName == "Rows" || args.PropertyName == "Columns")
|
|
{
|
|
_layoutDirty = true;
|
|
}
|
|
}
|
|
|
|
private void OnMembersChanged(AllianceManager sender)
|
|
{
|
|
_layoutDirty = true;
|
|
}
|
|
|
|
private void UpdateBars(Vector2 contentStartPos)
|
|
{
|
|
var members = AllianceManager.Instance.GetMembersForOtherAlliance(Config.SlotIndex);
|
|
uint memberCount = (uint)members.Count;
|
|
uint row = 0, col = 0;
|
|
|
|
CalculateBarPosition(contentStartPos, Size, out float x, out float y);
|
|
|
|
for (int i = 0; i < bars.Count; i++)
|
|
{
|
|
var bar = bars[i];
|
|
if (i >= memberCount)
|
|
{
|
|
bar.Visible = false;
|
|
continue;
|
|
}
|
|
|
|
bar.Member = members[i];
|
|
bar.Visible = true;
|
|
|
|
bar.Position = new Vector2(
|
|
x + Configs.HealthBar.Size.X * col + (Configs.HealthBar.Padding.X - 1) * col,
|
|
y + Configs.HealthBar.Size.Y * row + (Configs.HealthBar.Padding.Y - 1) * row
|
|
);
|
|
|
|
if (Config.FillRowsFirst)
|
|
{
|
|
col++;
|
|
if (col >= _layoutInfo.TotalColCount) { col = 0; row++; }
|
|
}
|
|
else
|
|
{
|
|
row++;
|
|
if (row >= _layoutInfo.TotalRowCount) { row = 0; col++; }
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateBarsPosition(Vector2 delta)
|
|
{
|
|
foreach (var bar in bars)
|
|
bar.Position = bar.Position + delta;
|
|
}
|
|
|
|
private void CalculateBarPosition(Vector2 position, Vector2 spaceSize, out float x, out float y)
|
|
{
|
|
x = position.X;
|
|
y = position.Y;
|
|
if (Config.BarsAnchor == DrawAnchor.Top || Config.BarsAnchor == DrawAnchor.Center || Config.BarsAnchor == DrawAnchor.Bottom)
|
|
x += (spaceSize.X - _layoutInfo.ContentSize.X) / 2f;
|
|
else if (Config.BarsAnchor == DrawAnchor.TopRight || Config.BarsAnchor == DrawAnchor.Right || Config.BarsAnchor == DrawAnchor.BottomRight)
|
|
x += spaceSize.X - _layoutInfo.ContentSize.X;
|
|
if (Config.BarsAnchor == DrawAnchor.Left || Config.BarsAnchor == DrawAnchor.Center || Config.BarsAnchor == DrawAnchor.Right)
|
|
y += (spaceSize.Y - _layoutInfo.ContentSize.Y) / 2f;
|
|
else if (Config.BarsAnchor == DrawAnchor.BottomLeft || Config.BarsAnchor == DrawAnchor.Bottom || Config.BarsAnchor == DrawAnchor.BottomRight)
|
|
y += spaceSize.Y - _layoutInfo.ContentSize.Y;
|
|
}
|
|
|
|
private Vector2 Size => new Vector2(
|
|
Config.Columns * Configs.HealthBar.Size.X + (Config.Columns - 1) * Configs.HealthBar.Padding.X,
|
|
Config.Rows * Configs.HealthBar.Size.Y + (Config.Rows - 1) * Configs.HealthBar.Padding.Y
|
|
);
|
|
|
|
private void UpdateLayout(Vector2 origin)
|
|
{
|
|
var members = AllianceManager.Instance.GetMembersForOtherAlliance(Config.SlotIndex);
|
|
uint count = (uint)members.Count;
|
|
Vector2 contentStartPos = origin + Config.Position;
|
|
|
|
if (_layoutDirty || _memberCount != count)
|
|
{
|
|
_layoutInfo = LayoutHelper.CalculateLayout(
|
|
Size, Configs.HealthBar.Size, count, Configs.HealthBar.Padding, Config.FillRowsFirst
|
|
);
|
|
UpdateBars(contentStartPos);
|
|
}
|
|
else if (_origin != contentStartPos)
|
|
{
|
|
UpdateBarsPosition(contentStartPos - _origin);
|
|
}
|
|
|
|
_layoutDirty = false;
|
|
_origin = contentStartPos;
|
|
_memberCount = count;
|
|
}
|
|
|
|
public void StopPreview()
|
|
{
|
|
Config.Preview = false;
|
|
foreach (var bar in bars)
|
|
bar.StopPreview();
|
|
}
|
|
|
|
protected override (List<Vector2>, List<Vector2>) ChildrenPositionsAndSizes()
|
|
{
|
|
return (new List<Vector2>() { Config.Position + Size / 2f }, new List<Vector2>() { Size });
|
|
}
|
|
|
|
public void StopMouseover()
|
|
{
|
|
foreach (var bar in bars)
|
|
bar.StopMouseover();
|
|
}
|
|
|
|
public override void DrawChildren(Vector2 origin)
|
|
{
|
|
if (!_config.Enabled)
|
|
return;
|
|
|
|
bool inRaid = AllianceManager.Instance.IsInAllianceRaid;
|
|
var members = AllianceManager.Instance.GetMembersForOtherAlliance(Config.SlotIndex);
|
|
|
|
if (!inRaid && !Config.Preview && !Config.ShowWhenNotInRaid)
|
|
return;
|
|
|
|
if (members.Count < 1 && !Config.Preview && !Config.ShowWhenNotInRaid)
|
|
return;
|
|
|
|
// Show placeholder when not in raid (for positioning) or when Preview is on
|
|
if ((Config.Preview || Config.ShowWhenNotInRaid) && members.Count < 1)
|
|
{
|
|
_layoutInfo = LayoutHelper.CalculateLayout(Size, Configs.HealthBar.Size, 8, Configs.HealthBar.Padding, Config.FillRowsFirst);
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
bars[i].Member = new FakePartyFramesMember(i);
|
|
bars[i].Visible = true;
|
|
}
|
|
for (int i = 8; i < bars.Count; i++)
|
|
bars[i].Visible = false;
|
|
CalculateBarPosition(origin + Config.Position, Size, out float px, out float py);
|
|
uint row = 0, col = 0;
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
bars[i].Position = new Vector2(
|
|
px + Configs.HealthBar.Size.X * col + (Configs.HealthBar.Padding.X - 1) * col,
|
|
py + Configs.HealthBar.Size.Y * row + (Configs.HealthBar.Padding.Y - 1) * row
|
|
);
|
|
if (Config.FillRowsFirst) { col++; if (col >= _layoutInfo.TotalColCount) { col = 0; row++; } }
|
|
else { row++; if (row >= _layoutInfo.TotalRowCount) { row = 0; col++; } }
|
|
}
|
|
AddDrawAction(StrataLevel.LOWEST, () =>
|
|
{
|
|
var drawList = ImGui.GetWindowDrawList();
|
|
Vector2 bgPos = origin + Config.Position - _contentMargin;
|
|
Vector2 bgSize = Size + _contentMargin * 2;
|
|
drawList.AddRectFilled(bgPos, bgPos + bgSize, 0x66000000);
|
|
drawList.AddRect(bgPos, bgPos + bgSize, 0x66FFFFFF);
|
|
});
|
|
for (int i = 0; i < 8; i++)
|
|
AddDrawActions(bars[i].GetBarDrawActions(origin));
|
|
foreach (var bar in bars)
|
|
AddDrawActions(bar.GetElementsDrawActions(origin));
|
|
Config.TitleLabelConfig.SetText(Config.FramesLabel + " (Preview)");
|
|
AddDrawAction(Config.TitleLabelConfig.StrataLevel, () => _titleLabelHud.Draw(origin + Config.Position));
|
|
return;
|
|
}
|
|
|
|
if (Config.Preview)
|
|
{
|
|
AddDrawAction(StrataLevel.LOWEST, () =>
|
|
{
|
|
var drawList = ImGui.GetWindowDrawList();
|
|
Vector2 bgPos = origin + Config.Position - _contentMargin;
|
|
Vector2 bgSize = Size + _contentMargin * 2;
|
|
drawList.AddRectFilled(bgPos, bgPos + bgSize, 0x66000000);
|
|
drawList.AddRect(bgPos, bgPos + bgSize, 0x66FFFFFF);
|
|
});
|
|
}
|
|
|
|
UpdateLayout(origin);
|
|
|
|
IGameObject? target = Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target;
|
|
int targetIndex = -1;
|
|
|
|
for (int i = 0; i < members.Count; i++)
|
|
{
|
|
var member = bars[i].Member;
|
|
if (member != null && target != null && member.ObjectId == target.GameObjectId)
|
|
{
|
|
targetIndex = i;
|
|
continue;
|
|
}
|
|
AddDrawActions(bars[i].GetBarDrawActions(origin));
|
|
}
|
|
|
|
if (targetIndex >= 0)
|
|
AddDrawActions(bars[targetIndex].GetBarDrawActions(origin, Configs.HealthBar.ColorsConfig.TargetBordercolor));
|
|
|
|
foreach (var bar in bars)
|
|
AddDrawActions(bar.GetElementsDrawActions(origin));
|
|
|
|
string titleText = Config.FramesLabel;
|
|
if (inRaid && AllianceManager.Instance.TryGetAllianceIndexForSlot(Config.SlotIndex, out int allianceIdx)
|
|
&& AllianceManager.Instance.TryGetAllianceLetter(allianceIdx, out string letter))
|
|
{
|
|
titleText = $"Alliance {letter}";
|
|
}
|
|
Config.TitleLabelConfig.SetText(titleText);
|
|
AddDrawAction(Config.TitleLabelConfig.StrataLevel, () =>
|
|
{
|
|
_titleLabelHud.Draw(origin + Config.Position);
|
|
});
|
|
}
|
|
}
|
|
}
|