Skip to content

Commit

Permalink
Auto-record outdoor.
Browse files Browse the repository at this point in the history
  • Loading branch information
awgil committed Oct 15, 2024
1 parent 9d476ec commit ef53c49
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 41 deletions.
7 changes: 7 additions & 0 deletions BossMod/BossModule/BossModuleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public sealed class BossModuleManager : IDisposable
public IReadOnlyList<BossModule> LoadedModules => _loadedModules;
public Event<BossModule> ModuleLoaded = new();
public Event<BossModule> ModuleUnloaded = new();
public Event<BossModule> ModuleActivated = new();
public Event<BossModule> ModuleDeactivated = new();

// drawn module among loaded modules; this can be changed explicitly if needed
// usually we don't have multiple concurrently active modules, since this prevents meaningful cd planning, raid cooldown tracking, etc.
Expand Down Expand Up @@ -79,6 +81,10 @@ public void Update()
isActive = false;
}

// if module was activated or deactivated, notify listeners
if (isActive != wasActive)
(isActive ? ModuleActivated : ModuleDeactivated).Fire(m);

// unload module either if it became deactivated or its primary actor disappeared without ever activating
if (!isActive && (wasActive || m.PrimaryActor.IsDestroyed))
{
Expand All @@ -89,6 +95,7 @@ public void Update()
// if module is active and wants to be reset, oblige
if (isActive && m.CheckReset())
{
ModuleDeactivated.Fire(m);
var actor = m.PrimaryActor;
UnloadModule(i--);
if (!actor.IsDestroyed)
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Framework/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public unsafe Plugin(IDalamudPluginInterface dalamud, ICommandManager commandMan
_configUI = new(Service.Config, _ws, replayDir, _rotationDB);
_wndBossmod = new(_bossmod, _zonemod);
_wndBossmodHints = new(_bossmod, _zonemod);
_wndReplay = new(_ws, _rotationDB, replayDir);
_wndReplay = new(_ws, _bossmod, _rotationDB, replayDir);
_wndRotation = new(_rotation, _amex, () => OpenConfigUI("Autorotation Presets"));
_wndAI = new(_ai);
_wndDebug = new(_ws, _rotation, _amex, _hintsBuilder, dalamud);
Expand Down
2 changes: 1 addition & 1 deletion BossMod/Replay/ReplayManagementConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class ReplayManagementConfig : ConfigNode
[PropertyDisplay("Show replay management UI")]
public bool ShowUI = false;

[PropertyDisplay("Auto record replays on duty start/end")]
[PropertyDisplay("Auto record replays on duty start/end or outdoor module start/end")]
public bool AutoRecord = true;

[PropertyDisplay("Max replays to keep before removal")]
Expand Down
114 changes: 75 additions & 39 deletions BossMod/Replay/ReplayManagementWindow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BossMod.Autorotation;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
Expand All @@ -16,12 +17,14 @@ public class ReplayManagementWindow : UIWindow
private readonly EventSubscriptions _subscriptions;
private ReplayRecorder? _recorder;
private string _message = "";
private bool _autoRecording;
private bool _recordingManual; // recording was started manually, and so should not be stopped automatically
private bool _recordingDuty; // recording was started automatically because we've entered duty
private int _recordingActiveModules; // recording was started automatically, because we've activated N modules
private string _lastErrorMessage = "";

private const string _windowID = "###Replay recorder";

public ReplayManagementWindow(WorldState ws, RotationDatabase rotationDB, DirectoryInfo logDir) : base(_windowID, false, new(300, 200))
public ReplayManagementWindow(WorldState ws, BossModuleManager bmm, RotationDatabase rotationDB, DirectoryInfo logDir) : base(_windowID, false, new(300, 200))
{
_ws = ws;
_logDir = logDir;
Expand All @@ -30,10 +33,12 @@ public class ReplayManagementWindow : UIWindow
_subscriptions = new
(
_config.Modified.ExecuteAndSubscribe(() => IsOpen = _config.ShowUI),
_ws.CurrentZoneChanged.Subscribe(op => UpdateAutoRecord(op.CFCID))
_ws.CurrentZoneChanged.Subscribe(op => OnZoneChange(op.CFCID)),
bmm.ModuleActivated.Subscribe(OnModuleActivation),
bmm.ModuleDeactivated.Subscribe(OnModuleDeactivation)
);

if (!UpdateAutoRecord(_ws.CurrentCFCID))
if (!OnZoneChange(_ws.CurrentCFCID))
UpdateTitle();

RespectCloseHotkey = false;
Expand Down Expand Up @@ -66,9 +71,14 @@ public override void Draw()
if (ImGui.Button(!IsRecording() ? "Start recording" : "Stop recording"))
{
if (!IsRecording())
StartRecording();
{
_recordingManual = true;
StartRecording("");
}
else
{
StopRecording();
}
}

if (_recorder != null)
Expand Down Expand Up @@ -97,7 +107,61 @@ public override void Draw()
_manager.Draw();
}

public void StartRecording()
public bool IsRecording() => _recorder != null;

public override void OnClose()
{
SetVisible(false);
}

private void UpdateTitle() => WindowName = $"Replay recording: {(_recorder != null ? "in progress..." : "idle")}{_windowID}";

private bool OnZoneChange(uint cfcId)
{
if (!_config.AutoRecord || _recordingManual)
return false; // don't care

var isDuty = cfcId != 0;
if (_recordingDuty == isDuty)
return false; // don't care
_recordingDuty = isDuty;

if (isDuty && !IsRecording())
{
StartRecording("");
return true;
}

if (!isDuty && _recordingActiveModules <= 0 && IsRecording())
{
StopRecording();
return true;
}

return false;
}

private void OnModuleActivation(BossModule m)
{
if (!_config.AutoRecord || _recordingManual)
return; // don't care

++_recordingActiveModules;
if (!IsRecording())
StartRecording($"{m.GetType().Name}-");
}

private void OnModuleDeactivation(BossModule m)
{
if (!_config.AutoRecord || _recordingManual || _recordingActiveModules <= 0)
return; // don't care

--_recordingActiveModules;
if (_recordingActiveModules <= 0 && !_recordingDuty && IsRecording())
StopRecording();
}

private void StartRecording(string prefix)
{
if (IsRecording())
return; // already recording
Expand All @@ -120,7 +184,7 @@ public void StartRecording()

try
{
_recorder = new(_ws, _config.WorldLogFormat, true, _logDir, GetPrefix());
_recorder = new(_ws, _config.WorldLogFormat, true, _logDir, prefix + GetPrefix());
}
catch (Exception ex)
{
Expand All @@ -130,44 +194,16 @@ public void StartRecording()
UpdateTitle();
}

public void StopRecording()
private void StopRecording()
{
_recordingManual = false;
_recordingDuty = false;
_recordingActiveModules = 0;
_recorder?.Dispose();
_recorder = null;
UpdateTitle();
}

public bool IsRecording() => _recorder != null;

public override void OnClose()
{
SetVisible(false);
}

private void UpdateTitle() => WindowName = $"Replay recording: {(_recorder != null ? "in progress..." : "idle")}{_windowID}";

private bool UpdateAutoRecord(uint cfcId)
{
if (!_config.AutoRecord)
return false; // don't care

if (!IsRecording() && _config.AutoRecord && cfcId != 0)
{
StartRecording();
_autoRecording = true;
return true;
}

if (IsRecording() && _autoRecording && cfcId == 0)
{
StopRecording();
_autoRecording = false;
return true;
}

return false;
}

private unsafe string GetPrefix()
{
string? prefix = null;
Expand Down

0 comments on commit ef53c49

Please sign in to comment.