Skip to content

Commit 6744f2d

Browse files
committed
Hide cooldowns of unavailable actions
1 parent 46dc3df commit 6744f2d

File tree

6 files changed

+106
-5
lines changed

6 files changed

+106
-5
lines changed

JobBars/Cooldowns/CooldownPartyMember.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace JobBars.Cooldowns {
88
public unsafe class CooldownPartyMember {
99
private JobIds PartyMemberCurrentJob = JobIds.OTHER;
10+
private byte PartyMemberLevel = 0;
1011
private readonly List<CooldownTracker> Trackers = new();
1112
private readonly uint ObjectId;
1213

@@ -15,8 +16,9 @@ public CooldownPartyMember(uint objectId) {
1516
}
1617

1718
public void Tick(AtkCooldown ui, CurrentPartyMember partyMember, float percent) {
18-
if (PartyMemberCurrentJob != partyMember.Job) {
19+
if (PartyMemberCurrentJob != partyMember.Job || PartyMemberLevel != partyMember.Level) {
1920
PartyMemberCurrentJob = partyMember.Job;
21+
PartyMemberLevel = partyMember.Level;
2022
SetupTrackers();
2123
}
2224

@@ -53,7 +55,7 @@ public void ProcessAction(Item action, uint objectId) {
5355
private void SetupTrackers() {
5456
Trackers.Clear();
5557

56-
var trackerProps = JobBars.CooldownManager.GetCooldownConfigs(PartyMemberCurrentJob);
58+
var trackerProps = JobBars.CooldownManager.GetCooldownConfigs(PartyMemberCurrentJob, PartyMemberLevel);
5759
var count = 0;
5860
foreach (var prop in trackerProps.OrderBy(x => x.Order)) {
5961
if (!prop.Enabled) continue;

JobBars/Cooldowns/Manager/CooldownManager.UI.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ protected override void DrawSettings() {
7171
ResetUi();
7272
}
7373

74+
if (ImGui.Checkbox("Hide cooldowns of unavailable actions" + Id, ref JobBars.Configuration.CooldownsHideUnavailableActions)) {
75+
JobBars.Configuration.Save();
76+
ResetUi();
77+
}
78+
7479
ImGui.SetNextItemWidth(50f);
7580
if (ImGui.InputFloat("Opacity when on cooldown" + Id, ref JobBars.Configuration.CooldownsOnCDOpacity)) JobBars.Configuration.Save();
7681
}

JobBars/Cooldowns/Manager/CooldownManager.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@ public CooldownManager() : base( "##JobBars_Cooldowns" ) {
2626
}
2727
}
2828

29-
public CooldownConfig[] GetCooldownConfigs( JobIds job ) {
29+
public CooldownConfig[] GetCooldownConfigs( JobIds job, byte level ) {
3030
List<CooldownConfig> configs = new();
3131
if( JobToValue.TryGetValue( job, out var props ) ) configs.AddRange( props );
3232
if( CustomCooldowns.TryGetValue( job, out var customProps ) ) configs.AddRange( customProps );
33+
if( JobBars.Configuration.CooldownsHideUnavailableActions ) {
34+
configs = configs.FindAll( config => config.Triggers.Any( item => {
35+
if( item.Type != ItemType.Action ) return true;
36+
return AtkHelper.IsActionAvailableAtLevel(item.Id, level);
37+
} ) );
38+
}
3339
return configs.ToArray();
3440
}
3541

JobBars/Data/Configuration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ public class Configuration : IPluginConfiguration {
126126
public bool CooldownsHideWeaponSheathed = false;
127127
public bool CooldownsHideActiveBuffDuration = false;
128128
public bool CooldownsShowPartyMembers = true;
129+
public bool CooldownsHideUnavailableActions = true;
129130
public float CooldownsOnCDOpacity = 1.0f;
130131

131132
public bool CooldownsStateShowDefault = true;

JobBars/Helper/UiHelper.Data.cs

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ public override readonly int GetHashCode() {
4040
}
4141
}
4242

43+
public struct ClassJobActionInfo {
44+
public uint ActionId;
45+
public byte Level;
46+
public bool IsRoleAction;
47+
}
48+
49+
public struct ClassJobActionEvolution {
50+
public uint ActionId;
51+
/// <summary>
52+
/// Action ID of the greatest ancestor.
53+
/// </summary>
54+
public uint BaseActionId;
55+
}
56+
57+
public class ClassJobActionLevelRange {
58+
public byte MinLevel;
59+
public byte ReplacedLevel;
60+
}
61+
4362
public unsafe partial class AtkHelper {
4463
public static bool OutOfCombat => !Dalamud.Condition[ConditionFlag.InCombat];
4564
public static bool WeaponSheathed => Dalamud.ClientState.LocalPlayer != null && !Dalamud.ClientState.LocalPlayer.StatusFlags.HasFlag(StatusFlags.WeaponOut);
@@ -71,6 +90,14 @@ public static void ZoneChanged(ushort e) {
7190
public static int GetIcon(ActionIds action) => GetIcon((uint)action);
7291
public static int GetIcon(uint action) => (int)ActionToIcon[action];
7392

93+
public static bool IsActionAvailableAtLevel(ActionIds action, byte level) => IsActionAvailableAtLevel((uint)action, level);
94+
public static bool IsActionAvailableAtLevel(uint action, byte level) {
95+
if (level == 0) return true;
96+
if (ClassJobActionIdToInfo.GetValueOrDefault(action).IsRoleAction) return true;
97+
if (!ClassJobActionToLevelRange.TryGetValue(action, out var levelRange)) return true;
98+
return level >= levelRange.MinLevel && (levelRange.ReplacedLevel == 0 || level < levelRange.ReplacedLevel);
99+
}
100+
74101
public static JobIds IdToJob(uint job) => job < 19 ? JobIds.OTHER : (JobIds)job;
75102

76103
private static IEnumerable<ClassJob> JobSheet;
@@ -80,6 +107,8 @@ public static void ZoneChanged(ushort e) {
80107
// Cache converted strings
81108
private static Dictionary<JobIds, string> JobToString;
82109
private static Dictionary<Item, string> ItemToString;
110+
private static Dictionary<uint, ClassJobActionInfo> ClassJobActionIdToInfo = new();
111+
private static Dictionary<uint, ClassJobActionLevelRange> ClassJobActionToLevelRange = new();
83112

84113
public static string Localize(JobIds job) {
85114
if (JobToString.TryGetValue(job, out var jobString)) return jobString;
@@ -143,10 +172,10 @@ private static void SetupSheets() {
143172
foreach (var item in ActionSheet) {
144173
var name = item.Name.ToString();
145174
var attackType = item.ActionCategory.Value.Name.ToString();
146-
var actionId = item.ActionCategory.Value.RowId;
175+
var categoryId = item.ActionCategory.Value.RowId;
147176
if (item.Icon != 405 && item.Icon != 0) ActionToIcon[item.RowId] = item.Icon;
148177

149-
if (actionId == 2 || actionId == 3) { // spell or weaponskill
178+
if (categoryId == 2 || categoryId == 3) { // spell or weaponskill
150179
if (item.CooldownGroup == 58 || item.AdditionalCooldownGroup == 58) GCDs.Add(item.RowId); // not actually a gcd
151180
}
152181

@@ -158,6 +187,12 @@ private static void SetupSheets() {
158187
Type = ItemType.Action
159188
}
160189
});
190+
191+
ClassJobActionIdToInfo.Add(item.RowId, new ClassJobActionInfo {
192+
ActionId = item.RowId,
193+
Level = item.ClassJobLevel,
194+
IsRoleAction = item.IsRoleAction
195+
});
161196
}
162197

163198
StatusSheet = Dalamud.DataManager.GetExcelSheet<Lumina.Excel.GeneratedSheets.Status>().Where(x => !string.IsNullOrEmpty(x.Name));
@@ -173,6 +208,55 @@ private static void SetupSheets() {
173208
}
174209

175210
JobSheet = Dalamud.DataManager.GetExcelSheet<ClassJob>().Where(x => x.Name != null);
211+
212+
SetupClassJobActionLevelRanges(ClassJobActionIdToInfo);
213+
}
214+
215+
private static void SetupClassJobActionLevelRanges(Dictionary<uint, ClassJobActionInfo> classJobActionIdToInfo) {
216+
var actionEvoBases = Dalamud.DataManager.GetExcelSheet<ClassJobActionSort>()
217+
.Where(row =>
218+
row.Unknown1/*BaseActionId*/ != 0 &&
219+
classJobActionIdToInfo.ContainsKey(row.Unknown0/*ActionId*/))
220+
.Select(row => row.Unknown1/*BaseActionId*/)
221+
.ToHashSet();
222+
223+
var actionEvos = Dalamud.DataManager.GetExcelSheet<ClassJobActionSort>()
224+
.Where(row => actionEvoBases.Contains(row.Unknown1/*BaseActionId*/))
225+
.Select(row => new ClassJobActionEvolution {
226+
ActionId = row.Unknown0,
227+
BaseActionId = row.Unknown1
228+
})
229+
.ToList();
230+
231+
Dictionary<uint, List<uint>> baseActionToActionGroup = new();
232+
foreach (var evo in actionEvos) {
233+
if (!classJobActionIdToInfo.ContainsKey(evo.ActionId)) continue;
234+
if (!baseActionToActionGroup.TryGetValue(evo.BaseActionId, out var actionGroup)) {
235+
actionGroup = new();
236+
baseActionToActionGroup.Add(evo.BaseActionId, actionGroup);
237+
}
238+
actionGroup.Add(evo.ActionId);
239+
}
240+
241+
foreach (var actionGroup in baseActionToActionGroup.Values) {
242+
actionGroup.Sort((a1, a2) => {
243+
var a1Level = classJobActionIdToInfo.GetValueOrDefault(a1).Level;
244+
var a2Level = classJobActionIdToInfo.GetValueOrDefault(a2).Level;
245+
return a1Level - a2Level;
246+
});
247+
248+
for (int i=0; i < actionGroup.Count; i++) {
249+
byte minLevel = classJobActionIdToInfo.GetValueOrDefault(actionGroup[i]).Level;
250+
byte replacedLevel = 0;
251+
if (i < actionGroup.Count - 1) {
252+
replacedLevel = classJobActionIdToInfo.GetValueOrDefault(actionGroup[i+1]).Level;
253+
}
254+
ClassJobActionToLevelRange.Add(actionGroup[i], new ClassJobActionLevelRange {
255+
MinLevel = minLevel,
256+
ReplacedLevel = replacedLevel
257+
});
258+
}
259+
}
176260
}
177261

178262
public static float TimeLeft(float defaultDuration, Dictionary<Item, Status> buffDict, Item lastActiveTrigger, DateTime lastActiveTime) {

JobBars/JobBars.Party.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace JobBars {
1111
public class CurrentPartyMember {
1212
public uint ObjectId;
1313
public JobIds Job;
14+
public byte Level;
1415
public uint CurrentHP;
1516
public uint MaxHP;
1617
public Dictionary<Item, Status> BuffDict;
@@ -55,6 +56,7 @@ private static List<CurrentPartyMember> GetPartyMembers() {
5556
ObjectId = localPlayer.ObjectId,
5657
CurrentHP = localPlayer.CurrentHp,
5758
MaxHP = localPlayer.MaxHp,
59+
Level = localPlayer.Level,
5860
Job = AtkHelper.IdToJob(localPlayer.ClassJob.Id),
5961
BuffDict = new()
6062
};
@@ -76,6 +78,7 @@ private static List<CurrentPartyMember> GetPartyMembers() {
7678
ObjectId = info->ObjectID,
7779
CurrentHP = info->CurrentHP,
7880
MaxHP = info->MaxHP,
81+
Level = info->Level,
7982
Job = AtkHelper.IdToJob(info->ClassJob),
8083
BuffDict = new()
8184
};

0 commit comments

Comments
 (0)