Skip to content

Commit

Permalink
Added transient strategy overrides, to be set via IPC
Browse files Browse the repository at this point in the history
- also cleaned up unused IPCs
  • Loading branch information
awgil committed Oct 20, 2024
1 parent bb1f33a commit b368164
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 87 deletions.
24 changes: 17 additions & 7 deletions BossMod/Autorotation/Preset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,30 @@ public record struct ModuleSetting(Modifier Mod, int Track, StrategyValue Value)
public StrategyValue Value = Value;
}

public record class ModuleSettings
{
public readonly List<ModuleSetting> Settings = [];
public int NumSerialized; // entries above this are transient and are not serialized
}

public string Name = Name;
public Dictionary<Type, List<ModuleSetting>> Modules = [];
public Dictionary<Type, ModuleSettings> Modules = [];

public Preset MakeClone()
public Preset MakeClone(bool includeTransient)
{
var res = new Preset(Name);
foreach (var kv in Modules)
res.Modules[kv.Key] = [.. kv.Value];
{
var ms = res.Modules[kv.Key] = new() { NumSerialized = kv.Value.NumSerialized };
ms.Settings.AddRange(includeTransient ? kv.Value.Settings : kv.Value.Settings.Take(kv.Value.NumSerialized));
}
return res;
}

public StrategyValues ActiveStrategyOverrides(Type type, Modifier mods)
{
var res = new StrategyValues(RotationModuleRegistry.Modules[type].Definition.Configs);
foreach (ref var s in Modules[type].AsSpan())
foreach (ref var s in Modules[type].Settings.AsSpan())
if ((s.Mod & mods) == s.Mod)
res.Values[s.Track] = s.Value;
return res;
Expand Down Expand Up @@ -74,7 +83,7 @@ public class JsonPresetConverter : JsonConverter<Preset>
continue;
}

var m = res.Modules[mt] = [];
var m = res.Modules[mt] = new();
foreach (var js in jm.Value.EnumerateArray())
{
var s = new Preset.ModuleSetting() { Value = new() };
Expand Down Expand Up @@ -106,7 +115,8 @@ public class JsonPresetConverter : JsonConverter<Preset>
if (js.TryGetProperty(nameof(StrategyValue.Comment), out var jcomment))
s.Value.Comment = jcomment.GetString() ?? "";

m.Add(s);
m.Settings.Add(s);
++m.NumSerialized;
}
}
return res;
Expand All @@ -121,7 +131,7 @@ public override void Write(Utf8JsonWriter writer, Preset value, JsonSerializerOp
{
writer.WriteStartArray(m.Key.FullName!);
var md = RotationModuleRegistry.Modules[m.Key].Definition;
foreach (var s in m.Value)
foreach (ref var s in m.Value.Settings.AsSpan()[..m.Value.NumSerialized])
{
writer.WriteStartObject();
writer.WriteString(nameof(Preset.ModuleSetting.Track), md.Configs[s.Track].InternalName);
Expand Down
52 changes: 29 additions & 23 deletions BossMod/Autorotation/UIPresetEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public UIPresetEditor(PresetDatabase db, int index, bool isDefaultPreset, Type?
_sourcePresetDefault = isDefaultPreset;
if (index >= 0)
{
Preset = (isDefaultPreset ? db.DefaultPresets : db.UserPresets)[index].MakeClone();
Preset = (isDefaultPreset ? db.DefaultPresets : db.UserPresets)[index].MakeClone(false);
}
else
{
Expand Down Expand Up @@ -113,11 +113,11 @@ public void DrawModulesList()
{
if (list)
{
foreach (var m in Preset.Modules)
foreach (var m in Preset.Modules.Keys)
{
if (DrawModule(m.Key, RotationModuleRegistry.Modules[m.Key].Definition, m.Key == SelectedModuleType))
if (DrawModule(m, RotationModuleRegistry.Modules[m].Definition, m == SelectedModuleType))
{
SelectModule(m.Key);
SelectModule(m);
}
}
}
Expand Down Expand Up @@ -147,7 +147,7 @@ private void DrawModuleAddPopup()
{
if (DrawModule(m.Key, m.Value.Definition))
{
Preset.Modules[m.Key] = [];
Preset.Modules[m.Key] = new();
Modified = true;
SelectModule(m.Key);
}
Expand Down Expand Up @@ -187,23 +187,24 @@ private void DrawSettingsList()
{
if (list)
{
for (int i = 0; i < ms.Count; ++i)
for (int i = 0; i < ms.Settings.Count; ++i)
{
ref var m = ref ms.Ref(i);
var persistent = i < ms.NumSerialized;
ref var m = ref ms.Settings.Ref(i);
var cfg = md.Configs[m.Track];
if (ImGui.Selectable($"[{i + 1}] {cfg.UIName} [{m.Mod}] = {cfg.Options[m.Value.Option].UIName}###setting{_settingGuids[i]}", i == _selectedSettingIndex))
if (ImGui.Selectable($"[{i + 1}]{(persistent ? "" : " (transient)")} {cfg.UIName} [{m.Mod}] = {cfg.Options[m.Value.Option].UIName}###setting{_settingGuids[i]}", i == _selectedSettingIndex))
{
_selectedSettingIndex = i;
}

if (ImGui.IsItemActive() && !ImGui.IsItemHovered())
{
var j = ImGui.GetMouseDragDelta().Y < 0 ? i - 1 : i + 1;
if (j >= 0 && j < ms.Count)
if (j >= 0 && j < ms.Settings.Count && persistent == (j < ms.NumSerialized))
{
(ms[i], ms[j]) = (ms[j], ms[i]);
(ms.Settings[i], ms.Settings[j]) = (ms.Settings[j], ms.Settings[i]);
(_settingGuids[i], _settingGuids[j]) = (_settingGuids[j], _settingGuids[i]);
Modified = true;
Modified |= persistent;
if (_selectedSettingIndex == i)
_selectedSettingIndex = j;
else if (_selectedSettingIndex == j)
Expand All @@ -219,14 +220,18 @@ private void DrawSettingsList()

if (UIMisc.Button("Remove##setting", width.X, (_selectedSettingIndex < 0, "Select any strategy to remove"), (!ImGui.GetIO().KeyShift, "Hold shift")))
{
ms.RemoveAt(_selectedSettingIndex);
Modified = true;
ms.Settings.RemoveAt(_selectedSettingIndex);
if (_selectedSettingIndex < ms.NumSerialized)
{
--ms.NumSerialized;
Modified = true;
}
_selectedSettingIndex = -1;
RebuildSettingGuids();
}
}

private void DrawAddSettingPopup(List<Preset.ModuleSetting> ms, RotationModuleDefinition def)
private void DrawAddSettingPopup(Preset.ModuleSettings ms, RotationModuleDefinition def)
{
using var popup = ImRaii.Popup("add_setting");
if (!popup)
Expand All @@ -237,8 +242,8 @@ private void DrawAddSettingPopup(List<Preset.ModuleSetting> ms, RotationModuleDe
var cfg = def.Configs[i];
if (ImGui.Selectable(cfg.UIName))
{
_selectedSettingIndex = ms.Count;
ms.Add(new(Preset.Modifier.None, i, new() { Option = cfg.Options.Count > 1 ? 1 : 0 }));
_selectedSettingIndex = ms.NumSerialized++;
ms.Settings.Insert(_selectedSettingIndex, new(Preset.Modifier.None, i, new() { Option = cfg.Options.Count > 1 ? 1 : 0 }));
Modified = true;
RebuildSettingGuids();
}
Expand Down Expand Up @@ -274,17 +279,18 @@ private void DrawModulePreview(Type moduleType)
}
}

private void DrawSettingDetails(Type moduleType, List<Preset.ModuleSetting> ms)
private void DrawSettingDetails(Type moduleType, Preset.ModuleSettings ms)
{
using var d = ImRaii.Disabled(_sourcePresetDefault);
var md = RotationModuleRegistry.Modules[moduleType].Definition;
ref var s = ref ms.Ref(_selectedSettingIndex);
ref var s = ref ms.Settings.Ref(_selectedSettingIndex);
var cfg = md.Configs[s.Track];
ImGui.TextUnformatted($"Setting: {cfg.UIName}");
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Shift, "Shift");
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Ctrl, "Ctrl");
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Alt, "Alt");
Modified |= UIStrategyValue.DrawEditor(ref s.Value, cfg, null, null);
var persistent = _selectedSettingIndex < ms.NumSerialized;
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Shift, "Shift") && persistent;
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Ctrl, "Ctrl") && persistent;
Modified |= DrawModifier(ref s.Mod, Preset.Modifier.Alt, "Alt") && persistent;
Modified |= UIStrategyValue.DrawEditor(ref s.Value, cfg, null, null) && persistent;
}

private bool DrawModifier(ref Preset.Modifier mod, Preset.Modifier flag, string label)
Expand Down Expand Up @@ -313,6 +319,6 @@ private void RebuildSettingGuids()
{
_settingGuids.Clear();
if (SelectedModuleType != null && Preset.Modules.TryGetValue(SelectedModuleType, out var ms))
_settingGuids.AddRange(Enumerable.Range(0, ms.Count));
_settingGuids.AddRange(Enumerable.Range(0, ms.Settings.Count));
}
}
104 changes: 47 additions & 57 deletions BossMod/Framework/IPCProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using BossMod.AI;
using BossMod.Autorotation;
using Dalamud.Game.ClientState.Objects.Types;
using System.Text.Json;

namespace BossMod;
Expand All @@ -9,93 +8,77 @@ sealed class IPCProvider : IDisposable
{
private Action? _disposeActions;

private Preset? Deserialize(string p) => JsonSerializer.Deserialize<Preset>(p);
private string Serialize(Preset p) => JsonSerializer.Serialize(p);
private string? SerializeN(Preset? p) => p == null ? null : JsonSerializer.Serialize(p);
private List<string> Serialize(IEnumerable<Preset> p) => p.Select(Serialize).ToList();

public IPCProvider(RotationModuleManager autorotation, ActionManagerEx amex, MovementOverride movement, AIManager ai)
{
// TODO: this really needs to be reconsidered, this exposes implementation detail
// for usecase description, see PR 330 - really AI itself should handle heal range
Register("ActiveModuleComponentBaseList", () => autorotation.Bossmods.ActiveModule?.Components.Select(c => c.GetType().BaseType?.Name).ToList() ?? default);
Register("ActiveModuleComponentList", () => autorotation.Bossmods.ActiveModule?.Components.Select(c => c.GetType().Name).ToList() ?? default);
Register("ActiveModuleHasComponent", (string name) => autorotation.Bossmods.ActiveModule?.Components.Any(c => c.GetType().Name == name || c.GetType().BaseType?.Name == name) ?? false);

Register("HasModule", (IGameObject obj) => BossModuleRegistry.FindByOID(obj.DataId) != null);
Register("HasModuleByDataId", (uint dataId) => BossModuleRegistry.FindByOID(dataId) != null);
Register("IsMoving", movement.IsMoving);
Register("ForbiddenZonesCount", () => autorotation.Hints.ForbiddenZones.Count);
Register("Configuration", (IReadOnlyList<string> args, bool save) => Service.Config.ConsoleCommand(string.Join(' ', args), save));
//Register("InitiateCombat", () => autorotation.ClassActions?.UpdateAutoAction(CommonActions.AutoActionAIFight, float.MaxValue, true));
//Register("SetAutorotationState", (bool state) => Service.Config.Get<AutorotationConfig>().Enabled = state);

Register("Presets.List", () => Serialize(autorotation.Database.Presets.VisiblePresets));
Register("Presets.Get", (string name) => SerializeN(autorotation.Database.Presets.FindPresetByName(name)));
Register("Presets.ForClass", (byte classId) => Serialize(autorotation.Database.Presets.PresetsForClass((Class)classId)));
Register("Presets.Get", (string name) =>
{
var preset = autorotation.Database.Presets.FindPresetByName(name);
return preset != null ? JsonSerializer.Serialize(preset, Serialization.BuildSerializationOptions()) : null;
});
Register("Presets.Create", (string presetSerialized, bool overwrite) =>
{
var p = Deserialize(presetSerialized);
var p = JsonSerializer.Deserialize<Preset>(presetSerialized, Serialization.BuildSerializationOptions());
if (p == null)
return false;

var index = autorotation.Database.Presets.UserPresets.FindIndex(x => x.Name == p.Name);
if (index >= 0 && !overwrite)
return false;

autorotation.Database.Presets.Modify(index, p);
return true;
});
Register("Presets.Delete", (string name) =>
{
var i = autorotation.Database.Presets.UserPresets.FindIndex(x => x.Name == name);
if (i >= 0)
autorotation.Database.Presets.Modify(i, null);

return i >= 0;
var index = autorotation.Database.Presets.UserPresets.FindIndex(x => x.Name == name);
if (index < 0)
return false;
autorotation.Database.Presets.Modify(index, null);
return true;
});

Register("Presets.GetActive", () => autorotation.Preset?.Name);
Register("Presets.SetActive", (string name) =>
{
var preset = autorotation.Database.Presets.FindPresetByName(name);
if (preset != null)
{
autorotation.Preset = preset;
return true;
}

return false;
if (preset == null)
return false;
autorotation.Preset = preset;
return true;
});
Register("Presets.ClearActive", () =>
{
if (autorotation.Preset == null)
return false;

autorotation.Preset = null;
return true;
});
Register("Presets.GetForceDisabled", () => autorotation.Preset == RotationModuleManager.ForceDisable);
Register("Presets.SetForceDisabled", () =>
{
if (autorotation.Preset != RotationModuleManager.ForceDisable)
{
autorotation.Preset = RotationModuleManager.ForceDisable;
return true;
}

return false;
if (autorotation.Preset == RotationModuleManager.ForceDisable)
return false;
autorotation.Preset = RotationModuleManager.ForceDisable;
return true;
});

Register("AI.SetPreset", (string name) =>
Register("Presets.AddTransientStrategy", (string presetName, string moduleTypeName, string trackName, string value) =>
{
Service.Log($"calling deprecated method AI.SetPreset - use Presets.SetActive instead");
autorotation.Preset = autorotation.Database.Presets.FindPresetByName(name);
});
Register("AI.GetPreset", () =>
{
Service.Log($"calling deprecated method AI.GetPreset - use Presets.GetActive instead");
return autorotation.Preset?.Name ?? string.Empty;
var mt = Type.GetType(moduleTypeName);
if (mt == null || !RotationModuleRegistry.Modules.TryGetValue(mt, out var md))
return false;
var iTrack = md.Definition.Configs.FindIndex(td => td.InternalName == trackName);
if (iTrack < 0)
return false;
var iOpt = md.Definition.Configs[iTrack].Options.FindIndex(od => od.InternalName == value);
if (iOpt < 0)
return false;
var preset = autorotation.Database.Presets.FindPresetByName(presetName);
if (preset == null || !preset.Modules.TryGetValue(mt, out var ms))
return false;
ms.Settings.Add(new(default, iTrack, new() { Option = iOpt }));
return true;
});
}

Expand All @@ -122,17 +105,24 @@ private void Register<T1, T2, TRet>(string name, Func<T1, T2, TRet> func)
_disposeActions += p.UnregisterFunc;
}

private void Register<T1, T2, T3, T4, TRet>(string name, Func<T1, T2, T3, T4, TRet> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, T2, T3, T4, TRet>("BossMod." + name);
p.RegisterFunc(func);
_disposeActions += p.UnregisterFunc;
}

//private void Register(string name, Action func)
//{
// var p = Service.PluginInterface.GetIpcProvider<object>("BossMod." + name);
// p.RegisterAction(func);
// _disposeActions += p.UnregisterAction;
//}

private void Register<T1>(string name, Action<T1> func)
{
var p = Service.PluginInterface.GetIpcProvider<T1, object>("BossMod." + name);
p.RegisterAction(func);
_disposeActions += p.UnregisterAction;
}
//private void Register<T1>(string name, Action<T1> func)
//{
// var p = Service.PluginInterface.GetIpcProvider<T1, object>("BossMod." + name);
// p.RegisterAction(func);
// _disposeActions += p.UnregisterAction;
//}
}

0 comments on commit b368164

Please sign in to comment.