Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion RunReplays/Commands/SelectHandCardsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,16 @@ public override ExecuteResult Execute()
HandSelectionCapture.PressHolder(nHand, holder);
}

HandSelectionCapture.ConfirmSelection(nHand);
try
{
HandSelectionCapture.ConfirmSelection(nHand);
}
catch (System.Reflection.TargetInvocationException)
{
// Single-card selections auto-complete when PressHolder toggles the
// card, so the TaskCompletionSource is already resolved. Swallow the
// "task already completed" exception — the selection succeeded.
}
HandSelectionCapture.ActiveHand = null;
return ExecuteResult.Ok();
}
Expand Down
17 changes: 14 additions & 3 deletions RunReplays/Commands/TreasureCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,20 @@ public TakeChestRelicCommand() : base("") { }
public override ExecuteResult Execute()
{
var sync = RunManager.Instance.TreasureRoomRelicSynchronizer;
PlayerActionBuffer.LogDispatcher("[TakeChestRelic] PickRelicLocally(0)");
Callable.From(() => sync.PickRelicLocally(0)).CallDeferred();
return ExecuteResult.Ok();

var relics = sync.CurrentRelics;
if (relics == null || relics.Count == 0)
return ExecuteResult.Retry(200);

try
{
sync.PickRelicLocally(0);
return ExecuteResult.Ok();
}
catch (System.InvalidOperationException)
{
return ExecuteResult.Retry(200);
}
}

public static TakeChestRelicCommand? TryParse(string raw)
Expand Down
44 changes: 35 additions & 9 deletions RunReplays/ReplayDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,21 @@ public static bool Paused
/// </summary>
public static void Step()
{
if (!ReplayEngine.IsActive)
return;

if (!_paused) Paused = true;

if (_dispatchInProgress
|| ReplayState.ActionInFlight
|| ReplayState.CardPlayInFlight
|| ReplayState.PotionInFlight
|| CardPlayReplayPatch.IsAwaitingEndTurnCompletion
|| MapMoveInFlight)
return;

_stepping = true;
DispatchNow();
Callable.From(ExecuteNext).CallDeferred();
}
private static float _delayBetweenCommands = 1.0f;
/// <summary>
Expand Down Expand Up @@ -878,14 +890,18 @@ private static void WatchdogTick()
&& ReplayEngine.PeekNext(out ReplayCommand? cmd) && cmd != null
&& cmd is MapMoveCommand)
{
// Force-clear blockers so dispatch can proceed.
ReplayState.ClearActionInFlight();
MapMoveInFlight = false;
_dispatchInProgress = false;
_lastDispatchedCmd = null;
NMapScreen.Instance?.Open();
NMapScreen.Instance?.SetTravelEnabled(true);
DispatchNow();
var room = GetCurrentRoom();
if (room == null)
{
// Force-clear blockers so dispatch can proceed.
ReplayState.ClearActionInFlight();
MapMoveInFlight = false;
_dispatchInProgress = false;
_lastDispatchedCmd = null;
NMapScreen.Instance?.Open();
NMapScreen.Instance?.SetTravelEnabled(true);
DispatchNow();
}
}

ScheduleWatchdogTick();
Expand Down Expand Up @@ -918,6 +934,16 @@ internal static void TryDispatch([System.Runtime.CompilerServices.CallerMemberNa
GD.Print($"[RunReplays] TryDispatch miss — cmd={cmd.GetType().Name} dispatchable=[{dispatchableNames}]");
DiagnosticLog.Write("Dispatch",
$"miss — cmd={cmd.GetType().Name}({cmd}) dispatchable=[{dispatchableNames}]");
if (cmd is MapMoveCommand && GetCurrentRoom() is TreasureRoom)
{
var sync = RunManager.Instance.TreasureRoomRelicSynchronizer;
var relics = sync.CurrentRelics;
if (relics != null && relics.Count > 0)
{
try { sync.PickRelicLocally(0); }
catch (InvalidOperationException) { }
}
}
return;
}

Expand Down