diff --git a/src/ui/GameWorldView.cpp b/src/ui/GameWorldView.cpp index 86679cd..8020246 100644 --- a/src/ui/GameWorldView.cpp +++ b/src/ui/GameWorldView.cpp @@ -194,7 +194,11 @@ void GameWorldView::onFrame() static_cast(elapsed), m_gameSpeedMultiplier); 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_replayPlayer->advanceTo(m_sim->currentTick()); } @@ -1314,7 +1318,11 @@ void GameWorldView::drawReplayOverlay(QPainter& painter) painter.setPen(QColor(255, 220, 80)); 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. 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(*desync)); 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 { message = tr("Replay ended");