Skip to content

Commit

Permalink
Split modules by category in 'add to preset' ui.
Browse files Browse the repository at this point in the history
  • Loading branch information
awgil committed Oct 20, 2024
1 parent b368164 commit d67f730
Show file tree
Hide file tree
Showing 62 changed files with 109 additions and 71 deletions.
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyBRD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum BloodletterStrategy { Automatic, Delay, Force, KeepOneCharge, KeepTw
public static RotationModuleDefinition Definition()
{
// TODO: think about target overrides where they make sense
var res = new RotationModuleDefinition("Legacy BRD", "Old pre-refactoring module", "veyn", RotationModuleQuality.WIP, BitMask.Build((int)Class.BRD), 100);
var res = new RotationModuleDefinition("Legacy BRD", "Old pre-refactoring module", "Legacy (pre-DT)", "veyn", RotationModuleQuality.WIP, BitMask.Build((int)Class.BRD), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 110)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target actions")
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyDNC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public enum PartnerStrategy { Automatic, Manual }
public static RotationModuleDefinition Definition()
{
// TODO: think about target overrides where they make sense
var res = new RotationModuleDefinition("Legacy DNC", "Old pre-refactoring module", "xan", RotationModuleQuality.WIP, BitMask.Build((int)Class.DNC), 100);
var res = new RotationModuleDefinition("Legacy DNC", "Old pre-refactoring module", "Legacy (pre-DT)", "xan", RotationModuleQuality.WIP, BitMask.Build((int)Class.DNC), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 90)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target actions")
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyDRG.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum SpineshatterStrategy { Automatic, Forbid, Force, ForceReserve, UseOu
public static RotationModuleDefinition Definition()
{
// TODO: think about target overrides where they make sense
var res = new RotationModuleDefinition("Legacy DRG", "Old pre-refactoring module", "veyn, lazylemo", RotationModuleQuality.WIP, BitMask.Build((int)Class.DRG), 100);
var res = new RotationModuleDefinition("Legacy DRG", "Old pre-refactoring module", "Legacy (pre-DT)", "veyn, lazylemo", RotationModuleQuality.WIP, BitMask.Build((int)Class.DRG), 100);

// TODO: 'force' flavour for continuing vs breaking combo?
res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 90)
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyGNB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static RotationModuleDefinition Definition()
{
// TODO: add in "Hold Double Down" option?
// TODO: think about target overrides where they make sense (ST stuff, esp things like onslaught?)
var res = new RotationModuleDefinition("Legacy GNB", "Old pre-refactoring module", "LazyLemo, Akechi-kun", RotationModuleQuality.WIP, BitMask.Build((int)Class.GNB), 100);
var res = new RotationModuleDefinition("Legacy GNB", "Old pre-refactoring module", "Legacy (pre-DT)", "LazyLemo, Akechi-kun", RotationModuleQuality.WIP, BitMask.Build((int)Class.GNB), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 90)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target rotation")
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyRPR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public enum PotionStrategy { Manual, Opener, Burst, Force, Special }
public static RotationModuleDefinition Definition()
{
// TODO: think about target overrides where they make sense
var res = new RotationModuleDefinition("Legacy RPR", "Old pre-refactoring module", "lazylemo", RotationModuleQuality.WIP, BitMask.Build((int)Class.RPR), 100);
var res = new RotationModuleDefinition("Legacy RPR", "Old pre-refactoring module", "Legacy (pre-DT)", "lazylemo", RotationModuleQuality.WIP, BitMask.Build((int)Class.RPR), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 100)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target actions")
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Legacy/LegacyWAR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public enum OnslaughtStrategy { Automatic, Forbid, NoReserve, Force, ForceReserv
public static RotationModuleDefinition Definition()
{
// TODO: think about target overrides where they make sense (ST stuff, esp things like onslaught?)
var res = new RotationModuleDefinition("Legacy WAR", "Old pre-refactoring module", "veyn", RotationModuleQuality.WIP, BitMask.Build((int)Class.WAR), 100);
var res = new RotationModuleDefinition("Legacy WAR", "Old pre-refactoring module", "Legacy (pre-DT)", "veyn", RotationModuleQuality.WIP, BitMask.Build((int)Class.WAR), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 90)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target rotation")
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/MiscAI/StayCloseToTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public sealed class StayCloseToTarget(RotationModuleManager manager, Actor player) : RotationModule(manager, player)
{
public static RotationModuleDefinition Definition() => new("Misc AI: Stay within 10m of target", "Module for use by AutoDuty preset.", "veyn", RotationModuleQuality.Basic, new(~0ul), 1000);
public static RotationModuleDefinition Definition() => new("Misc AI: Stay within 10m of target", "Module for use by AutoDuty preset.", "AI Behaviours", "veyn", RotationModuleQuality.Basic, new(~0ul), 1000);

public override void Execute(StrategyValues strategy, Actor? primaryTarget, float estimatedAnimLockDelay, bool isMoving)
{
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/RotationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public enum RotationModuleQuality
// the configuration part of the rotation module
// importantly, it defines constraints (supported classes and level ranges) and strategy configs (with their sets of possible options) used by the module to make its decisions
// rotation modules can optionally be constrained to a specific boss module, if they are used to implement custom encounter-specific logic - these would only be available in plans for that module
public sealed record class RotationModuleDefinition(string DisplayName, string Description, string Author, RotationModuleQuality Quality, BitMask Classes, int MaxLevel, int MinLevel = 1, Type? RelatedBossModule = null, bool CanUseWhileRoleplaying = false)
public sealed record class RotationModuleDefinition(string DisplayName, string Description, string Category, string Author, RotationModuleQuality Quality, BitMask Classes, int MaxLevel, int MinLevel = 1, Type? RelatedBossModule = null, bool CanUseWhileRoleplaying = false)
{
public readonly BitMask Classes = Classes;
public readonly List<StrategyConfig> Configs = [];
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Standard/StandardWAR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public enum BozjaStrategy { None, WithIR, BloodRage }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Standard WAR", "Standard rotation module", "veyn", RotationModuleQuality.Good, BitMask.Build((int)Class.WAR, (int)Class.MRD), 100);
var res = new RotationModuleDefinition("Standard WAR", "Standard rotation module", "Standard rotation (veyn)", "veyn", RotationModuleQuality.Good, BitMask.Build((int)Class.WAR, (int)Class.MRD), 100);

res.Define(Track.AOE).As<AOEStrategy>("AOE", uiPriority: 90)
.AddOption(AOEStrategy.SingleTarget, "ST", "Use single-target rotation")
Expand Down
58 changes: 48 additions & 10 deletions BossMod/Autorotation/UIPresetEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ namespace BossMod.Autorotation;

public sealed class UIPresetEditor
{
private class ModuleCategory
{
public SortedDictionary<string, ModuleCategory> Subcategories = [];
public List<Type> Leafs = [];
}

private readonly PresetDatabase _db;
private int _sourcePresetIndex;
private bool _sourcePresetDefault;
Expand All @@ -15,12 +21,14 @@ public sealed class UIPresetEditor
private int _selectedSettingIndex = -1;
private readonly List<int> _orderedTrackList = []; // for current module, by UI order
private readonly List<int> _settingGuids = []; // a hack to keep track of held item during drag-n-drop
private readonly ModuleCategory _modulesByCategory;

public UIPresetEditor(PresetDatabase db, int index, bool isDefaultPreset, Type? initiallySelectedModuleType)
{
_db = db;
_sourcePresetIndex = index;
_sourcePresetDefault = isDefaultPreset;
_modulesByCategory = SplitModulesByCategory();
if (index >= 0)
{
Preset = (isDefaultPreset ? db.DefaultPresets : db.UserPresets)[index].MakeClone(false);
Expand All @@ -39,6 +47,7 @@ public UIPresetEditor(PresetDatabase db, Preset preset, Type? initiallySelectedM
{
_db = db;
_sourcePresetIndex = -1;
_modulesByCategory = SplitModulesByCategory();
Preset = preset;
NameConflict = CheckNameConflict();
Modified = true;
Expand Down Expand Up @@ -106,7 +115,9 @@ public void MakeNameUnique()

public void DrawModulesList()
{
DrawModuleAddPopup();
using (var popup = ImRaii.Popup("add_module"))
if (popup)
DrawModuleAddPopup(_modulesByCategory);

var width = new Vector2(ImGui.GetContentRegionAvail().X, 0);
using (var list = ImRaii.ListBox("###modules", width))
Expand Down Expand Up @@ -136,20 +147,29 @@ public void DrawModulesList()
}
}

private void DrawModuleAddPopup()
private void DrawModuleAddPopup(ModuleCategory cat)
{
using var popup = ImRaii.Popup("add_module");
if (!popup)
return;
foreach (var m in RotationModuleRegistry.Modules)
foreach (var sub in cat.Subcategories)
{
if (HaveModulesToAddInCategory(sub.Value))
{
if (ImGui.BeginMenu(sub.Key))
{
DrawModuleAddPopup(sub.Value);
ImGui.EndMenu();
}
}
}

foreach (var leaf in cat.Leafs)
{
if (m.Value.Definition.RelatedBossModule == null && !Preset.Modules.ContainsKey(m.Key))
if (!Preset.Modules.ContainsKey(leaf))
{
if (DrawModule(m.Key, m.Value.Definition))
if (DrawModule(leaf, RotationModuleRegistry.Modules[leaf].Definition))
{
Preset.Modules[m.Key] = new();
Preset.Modules[leaf] = new();
Modified = true;
SelectModule(m.Key);
SelectModule(leaf);
}
}
}
Expand Down Expand Up @@ -321,4 +341,22 @@ private void RebuildSettingGuids()
if (SelectedModuleType != null && Preset.Modules.TryGetValue(SelectedModuleType, out var ms))
_settingGuids.AddRange(Enumerable.Range(0, ms.Settings.Count));
}

private ModuleCategory SplitModulesByCategory()
{
ModuleCategory res = new();
foreach (var m in RotationModuleRegistry.Modules)
{
if (m.Value.Definition.RelatedBossModule != null)
continue; // don't care about boss-specific modules for presets

var cat = res;
foreach (var part in m.Value.Definition.Category.Split('|', StringSplitOptions.RemoveEmptyEntries))
cat = cat.Subcategories.GetOrAdd(part);
cat.Leafs.Add(m.Key);
}
return res;
}

private bool HaveModulesToAddInCategory(ModuleCategory cat) => cat.Leafs.Any(leaf => !Preset.Modules.ContainsKey(leaf)) || cat.Subcategories.Values.Any(HaveModulesToAddInCategory);
}
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassASTUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum HeliosOption { None, Use, UseEx }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: AST", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Akechi", RotationModuleQuality.Ok, BitMask.Build((int)Class.AST), 100);
var res = new RotationModuleDefinition("Utility: AST", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Akechi", RotationModuleQuality.Ok, BitMask.Build((int)Class.AST), 100);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.Helios, "Helios", "", 140, AST.AID.Helios);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassBLMUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public enum DashStrategy { None, Force }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: BLM", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.BLM), 100);
var res = new RotationModuleDefinition("Utility: BLM", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.BLM), 100);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.Manaward, "Manaward", "", 600, BLM.AID.Manaward, 20);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassBLUUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public enum Track { Bristle = SharedTrack.Count, WhiteWind, IceSpikes, OffGuard,

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: BLU", "Planner support for utility actions\nNOTE: There are a lot of Utility actions for Blue Mage.\nFor better accessibility:\n 1. Select 'Column Visibility' tab\n 2. Choose which skills you would like to keep visible or invisible", "Akechi", RotationModuleQuality.Basic, BitMask.Build((int)Class.BLU), 80);
var res = new RotationModuleDefinition("Utility: BLU", "Planner support for utility actions\nNOTE: There are a lot of Utility actions for Blue Mage.\nFor better accessibility:\n 1. Select 'Column Visibility' tab\n 2. Choose which skills you would like to keep visible or invisible", "Utility for planner", "Akechi", RotationModuleQuality.Basic, BitMask.Build((int)Class.BLU), 80);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.Bristle, "Bristle", "Bristle", 100, BLU.AID.Bristle, 30);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassBRDUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public enum TroubOption { None, Use87, Use88 }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: BRD", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "veyn", RotationModuleQuality.Excellent, BitMask.Build((int)Class.BRD), 100);
var res = new RotationModuleDefinition("Utility: BRD", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "veyn", RotationModuleQuality.Excellent, BitMask.Build((int)Class.BRD), 100);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.WardensPaean, "WardensPaean", "Dispel", -10, BRD.AID.WardensPaean, 30);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassDNCUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public enum Track { CuringWaltz = SharedTrack.Count, ShieldSamba, Improvisation

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: DNC", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "xan", RotationModuleQuality.Excellent, BitMask.Build((int)Class.DNC), 100);
var res = new RotationModuleDefinition("Utility: DNC", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "xan", RotationModuleQuality.Excellent, BitMask.Build((int)Class.DNC), 100);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.CuringWaltz, "CuringWaltz", "Waltz", 400, DNC.AID.CuringWaltz);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassDRGUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public enum DashStrategy { None, GapClose }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: DRG", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Akechi", RotationModuleQuality.Excellent, BitMask.Build((int)Class.DRG), 100);
var res = new RotationModuleDefinition("Utility: DRG", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Akechi", RotationModuleQuality.Excellent, BitMask.Build((int)Class.DRG), 100);
DefineShared(res, IDLimitBreak3);

res.Define(Track.WingedGlide).As<DashStrategy>("Winged Glide", "Dash", 20)
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassDRKUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public enum DashStrategy { None, GapClose } //GapCloser strategy

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: DRK", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.DRK), 100);
var res = new RotationModuleDefinition("Utility: DRK", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.DRK), 100);
DefineShared(res, IDLimitBreak3, IDStanceApply, IDStanceRemove);

DefineSimpleConfig(res, Track.DarkMind, "DarkMind", "DMind", 450, DRK.AID.DarkMind, 10); //120s CD, 15s duration
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassGNBUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public enum DashStrategy { None, GapClose } //Gapcloser purposes

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: GNB", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.GNB), 100); //How we plan our use of Utility skills
var res = new RotationModuleDefinition("Utility: GNB", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Akechi", RotationModuleQuality.Good, BitMask.Build((int)Class.GNB), 100); //How we plan our use of Utility skills
DefineShared(res, IDLimitBreak3, IDStanceApply, IDStanceRemove); //Stance & LB

DefineSimpleConfig(res, Track.Camouflage, "Camouflage", "Camo", 500, GNB.AID.Camouflage, 20); //90s CD, 20s duration
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassMCHUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public enum TactOption { None, Use87, Use88 }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: MCH", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Aimsucks", RotationModuleQuality.Excellent, BitMask.Build((int)Class.MCH), 100);
var res = new RotationModuleDefinition("Utility: MCH", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "Aimsucks", RotationModuleQuality.Excellent, BitMask.Build((int)Class.MCH), 100);
DefineShared(res, IDLimitBreak3);

// Add track for Tactician: 15s long, 15% player damage received reduction
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Autorotation/Utility/ClassMNKUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public enum DashStrategy { None, Force, GapClose }

public static RotationModuleDefinition Definition()
{
var res = new RotationModuleDefinition("Utility: MNK", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "xan", RotationModuleQuality.Excellent, BitMask.Build((int)Class.MNK), 100);
var res = new RotationModuleDefinition("Utility: MNK", "Cooldown Planner support for Utility Actions.\nNOTE: This is NOT a rotation preset! All Utility modules are STRICTLY for cooldown-planning usage.", "Utility for planner", "xan", RotationModuleQuality.Excellent, BitMask.Build((int)Class.MNK), 100);
DefineShared(res, IDLimitBreak3);

DefineSimpleConfig(res, Track.Mantra, "Mantra", "", 100, MNK.AID.Mantra, 15);
Expand Down
Loading

0 comments on commit d67f730

Please sign in to comment.