Files

465 lines
17 KiB
C#

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;
}
}
}