Freeze replay at the run's terminal state (win/defeat)
Playback only stopped when the recorded command stream ran out, so a run that ended on the artifact win (e.g. 3/3) kept ticking during replay because win and game-over are gated off in replay mode and the recording ran a few ticks past the win. Stop advancing when m_sim->isWon() || isGameOver() (in addition to the stream end), and show it in the replay overlay: "Replay ended — Victory" / "— Defeat" (desync still takes priority). This matches where the real game froze. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
This commit is contained in:
@@ -194,7 +194,11 @@ void GameWorldView::onFrame()
|
|||||||
static_cast<double>(elapsed), m_gameSpeedMultiplier);
|
static_cast<double>(elapsed), m_gameSpeedMultiplier);
|
||||||
for (int i = 0; i < ticks; ++i)
|
for (int i = 0; i < ticks; ++i)
|
||||||
{
|
{
|
||||||
if (m_replayPlayer->isFinished()) { break; }
|
// Stop at the recorded stream's end, or at the run's terminal state:
|
||||||
|
// the real game froze when it was won or lost, so the replay does too
|
||||||
|
// (the recording may run a few ticks past that point).
|
||||||
|
if (m_replayPlayer->isFinished()
|
||||||
|
|| m_sim->isWon() || m_sim->isGameOver()) { break; }
|
||||||
m_sim->tick();
|
m_sim->tick();
|
||||||
m_replayPlayer->advanceTo(m_sim->currentTick());
|
m_replayPlayer->advanceTo(m_sim->currentTick());
|
||||||
}
|
}
|
||||||
@@ -1314,7 +1318,11 @@ void GameWorldView::drawReplayOverlay(QPainter& painter)
|
|||||||
painter.setPen(QColor(255, 220, 80));
|
painter.setPen(QColor(255, 220, 80));
|
||||||
painter.drawText(QRect(0, 8, width(), 24), Qt::AlignHCenter | Qt::AlignTop, tr("REPLAY"));
|
painter.drawText(QRect(0, 8, width(), 24), Qt::AlignHCenter | Qt::AlignTop, tr("REPLAY"));
|
||||||
|
|
||||||
if (m_replayPlayer->isFinished())
|
// The replay is over once the recorded stream is exhausted or the run reached
|
||||||
|
// its terminal state (win / defeat) — matching where playback freezes above.
|
||||||
|
const bool ended = m_replayPlayer->isFinished()
|
||||||
|
|| m_sim->isWon() || m_sim->isGameOver();
|
||||||
|
if (ended)
|
||||||
{
|
{
|
||||||
// Dim the world so the end message reads clearly over it.
|
// Dim the world so the end message reads clearly over it.
|
||||||
painter.fillRect(rect(), QColor(0, 0, 0, 140));
|
painter.fillRect(rect(), QColor(0, 0, 0, 140));
|
||||||
@@ -1326,6 +1334,16 @@ void GameWorldView::drawReplayOverlay(QPainter& painter)
|
|||||||
message = tr("Desync at tick %1").arg(static_cast<qlonglong>(*desync));
|
message = tr("Desync at tick %1").arg(static_cast<qlonglong>(*desync));
|
||||||
painter.setPen(QColor(255, 90, 90));
|
painter.setPen(QColor(255, 90, 90));
|
||||||
}
|
}
|
||||||
|
else if (m_sim->isWon())
|
||||||
|
{
|
||||||
|
message = tr("Replay ended — Victory");
|
||||||
|
painter.setPen(QColor(120, 255, 120));
|
||||||
|
}
|
||||||
|
else if (m_sim->isGameOver())
|
||||||
|
{
|
||||||
|
message = tr("Replay ended — Defeat");
|
||||||
|
painter.setPen(QColor(255, 255, 255));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message = tr("Replay ended");
|
message = tr("Replay ended");
|
||||||
|
|||||||
Reference in New Issue
Block a user