diff --git a/Core/GameEngine/Include/GameNetwork/GameInfo.h b/Core/GameEngine/Include/GameNetwork/GameInfo.h index 419c90cc355..8b64aaac506 100644 --- a/Core/GameEngine/Include/GameNetwork/GameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/GameInfo.h @@ -301,6 +301,8 @@ class SkirmishGameInfo : public GameInfo, public Snapshot for (Int i = 0; i< MAX_SLOTS; ++i) setSlotPointer(i, &m_skirmishSlot[i]); } + + void handleOriginalSetups(); }; extern SkirmishGameInfo *TheSkirmishGameInfo; diff --git a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp index 5b05e9eb369..7ef2f63018a 100644 --- a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp +++ b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp @@ -1645,4 +1645,24 @@ void SkirmishGameInfo::loadPostProcess() { } +void SkirmishGameInfo::handleOriginalSetups() +{ + // TheSuperHackers @fix Caball009 19/03/2026 Random color, position and faction are based on the logical seed. For improved determinism, + // restarted games now set the original values so that the games start with the exact same logical seed values as the first time. + + for (size_t i = 0; i < ARRAY_SIZE(m_skirmishSlot); ++i) + { + GameSlot& slot = m_skirmishSlot[i]; + if (slot.hasSavedOriginalSetup()) + { + slot.setColor(slot.getOriginalColor()); + slot.setStartPos(slot.getOriginalStartPos()); + slot.setPlayerTemplate(slot.getOriginalPlayerTemplate()); + } + else + { + slot.saveOriginalSetup(); + } + } +} diff --git a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp index 9d71eb45b1b..87ecd1cc548 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp @@ -618,6 +618,8 @@ void RecorderClass::startRecording(GameDifficulty diff, Int originalGameMode, In { if(TheSkirmishGameInfo) { + TheSkirmishGameInfo->handleOriginalSetups(); + TheSkirmishGameInfo->setCRCInterval(REPLAY_CRC_INTERVAL); theSlotList = GameInfoToAsciiString(TheSkirmishGameInfo); DEBUG_LOG(("GameInfo String: %s",theSlotList.str())); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 60bae04f186..82a8ccc6a32 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -1283,28 +1283,18 @@ void GameLogic::tryStartNewGame( Bool loadingSaveGame ) Bool isSkirmishOrSkirmishReplay = FALSE; if (TheGameInfo) { - for (Int i=0; igetSlot(i); - if (!loadingSaveGame) { - if (slot->hasSavedOriginalSetup()) - { - DEBUG_ASSERTCRASH(m_gameMode == GAME_SKIRMISH, ("Expected GAME_SKIRMISH but got %s", toString(m_gameMode))); + TheSkirmishGameInfo->handleOriginalSetups(); + } - // TheSuperHackers @fix Caball009 19/03/2026 Random color, position and faction are based on the logical seed. For improved determinism, - // restarted games now set the original values so that the games start with the exact same logical seed values as the first time. - slot->setColor(slot->getOriginalColor()); - slot->setStartPos(slot->getOriginalStartPos()); - slot->setPlayerTemplate(slot->getOriginalPlayerTemplate()); - } - else - { - slot->saveOriginalSetup(); - } - } + for (Int i=0; igetSlot(i); if (slot->isAI()) { isSkirmishOrSkirmishReplay = TRUE; + break; } } } else {