From ee50e97dc2ac3649e6a000a42c2492220714e1a5 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:36:18 +0100 Subject: [PATCH 1/3] Added 'toString' function. --- .../GameEngine/Include/GameLogic/GameLogic.h | 2 ++ .../Source/GameLogic/System/GameLogic.cpp | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h index b1711c5afca..ac733f5c299 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h @@ -79,6 +79,8 @@ enum GameMode CPP_11(: Int) GAME_NONE }; +const char* toString(GameMode mode); + enum { CRC_CACHED, diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 14a4b7ef7fe..889de0ddb77 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -213,6 +213,30 @@ void setFPMode() _controlfp(newVal, _MCW_PC | _MCW_RC); } +//------------------------------------------------------------------------------------------------- +const char* toString(GameMode mode) +{ + switch (mode) + { + case GAME_SINGLE_PLAYER: + return "GAME_SINGLE_PLAYER"; + case GAME_LAN: + return "GAME_LAN"; + case GAME_SKIRMISH: + return "GAME_SKIRMISH"; + case GAME_REPLAY: + return "GAME_REPLAY"; + case GAME_SHELL: + return "GAME_SHELL"; + case GAME_INTERNET: + return "GAME_INTERNET"; + case GAME_NONE: + return "GAME_NONE"; + default: + return "GAME_UNKNOWN"; + } +} + // ------------------------------------------------------------------------------------------------ /** GameLogic class constructor */ // ------------------------------------------------------------------------------------------------ From d5597b7611b449dd264ef007d2eadd3bd31eb858 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:55:45 +0100 Subject: [PATCH 2/3] Changed function name from 'saveOffOriginalInfo' to 'saveOriginalSetup'. --- Core/GameEngine/Include/GameNetwork/GameInfo.h | 2 +- Core/GameEngine/Source/GameNetwork/GameInfo.cpp | 8 ++++---- .../Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/GameEngine/Include/GameNetwork/GameInfo.h b/Core/GameEngine/Include/GameNetwork/GameInfo.h index 0b67a2f47fc..ffef6282c83 100644 --- a/Core/GameEngine/Include/GameNetwork/GameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/GameInfo.h @@ -100,7 +100,7 @@ class GameSlot void setNATBehavior( FirewallHelperClass::FirewallBehaviorType NATBehavior) { m_NATBehavior = NATBehavior; } FirewallHelperClass::FirewallBehaviorType getNATBehavior() const { return m_NATBehavior; } - void saveOffOriginalInfo(); + void saveOriginalSetup(); Int getOriginalPlayerTemplate() const { return m_origPlayerTemplate; } Int getOriginalColor() const { return m_origColor; } Int getOriginalStartPos() const { return m_origStartPos; } diff --git a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp index 475f51a8683..9da95e97882 100644 --- a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp +++ b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp @@ -75,14 +75,14 @@ void GameSlot::reset() m_origColor = -1; } -void GameSlot::saveOffOriginalInfo() +void GameSlot::saveOriginalSetup() { - DEBUG_LOG(("GameSlot::saveOffOriginalInfo() - orig was color=%d, pos=%d, house=%d", + DEBUG_LOG(("GameSlot::saveOriginalSetup() - orig was color=%d, pos=%d, house=%d", m_origColor, m_origStartPos, m_origPlayerTemplate)); m_origPlayerTemplate = m_playerTemplate; m_origStartPos = m_startPos; m_origColor = m_color; - DEBUG_LOG(("GameSlot::saveOffOriginalInfo() - color=%d, pos=%d, house=%d", + DEBUG_LOG(("GameSlot::saveOriginalSetup() - color=%d, pos=%d, house=%d", m_color, m_startPos, m_playerTemplate)); } @@ -1597,7 +1597,7 @@ void SkirmishGameInfo::xfer( Xfer *xfer ) m_slot[slot]->setPlayerTemplate(origPlayerTemplate); m_slot[slot]->setStartPos(origStartPos); m_slot[slot]->setColor(origColor); - m_slot[slot]->saveOffOriginalInfo(); + m_slot[slot]->saveOriginalSetup(); m_slot[slot]->setTeamNumber(teamNumber); m_slot[slot]->setColor(color); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 889de0ddb77..7cb3e6b9353 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -1265,7 +1265,7 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) { GameSlot *slot = TheGameInfo->getSlot(i); if (!loadingSaveGame) { - slot->saveOffOriginalInfo(); + slot->saveOriginalSetup(); } if (slot->isAI()) { From 023942870ca56a852eb5aca4bf6d6492b7bbbc1b Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Fri, 27 Mar 2026 16:18:33 +0100 Subject: [PATCH 3/3] Reset randomized slot values. --- Core/GameEngine/Include/GameNetwork/GameInfo.h | 2 ++ Core/GameEngine/Source/GameNetwork/GameInfo.cpp | 3 +++ .../Source/GameLogic/System/GameLogic.cpp | 15 ++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Core/GameEngine/Include/GameNetwork/GameInfo.h b/Core/GameEngine/Include/GameNetwork/GameInfo.h index ffef6282c83..9009b79be05 100644 --- a/Core/GameEngine/Include/GameNetwork/GameInfo.h +++ b/Core/GameEngine/Include/GameNetwork/GameInfo.h @@ -101,6 +101,7 @@ class GameSlot FirewallHelperClass::FirewallBehaviorType getNATBehavior() const { return m_NATBehavior; } void saveOriginalSetup(); + Bool getSaveOriginalSetup() const { return m_saveOriginalSetup; } Int getOriginalPlayerTemplate() const { return m_origPlayerTemplate; } Int getOriginalColor() const { return m_origColor; } Int getOriginalStartPos() const { return m_origStartPos; } @@ -130,6 +131,7 @@ class GameSlot Bool m_isAccepted; Bool m_hasMap; Bool m_isMuted; + Bool m_saveOriginalSetup; Int m_color; ///< color, or -1 for random Int m_startPos; ///< start position, or -1 for random Int m_playerTemplate; ///< PlayerTemplate diff --git a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp index 9da95e97882..44f1139a87d 100644 --- a/Core/GameEngine/Source/GameNetwork/GameInfo.cpp +++ b/Core/GameEngine/Source/GameNetwork/GameInfo.cpp @@ -70,6 +70,7 @@ void GameSlot::reset() m_disconnected = FALSE; m_port = 0; m_isMuted = FALSE; + m_saveOriginalSetup = TRUE; m_origPlayerTemplate = -1; m_origStartPos = -1; m_origColor = -1; @@ -84,6 +85,8 @@ void GameSlot::saveOriginalSetup() m_origColor = m_color; DEBUG_LOG(("GameSlot::saveOriginalSetup() - color=%d, pos=%d, house=%d", m_color, m_startPos, m_playerTemplate)); + + m_saveOriginalSetup = FALSE; } static Int getSlotIndex(const GameSlot *slot) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 7cb3e6b9353..c40546bae29 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -1265,7 +1265,20 @@ void GameLogic::startNewGame( Bool loadingSaveGame ) { GameSlot *slot = TheGameInfo->getSlot(i); if (!loadingSaveGame) { - slot->saveOriginalSetup(); + if (!slot->getSaveOriginalSetup()) + { + DEBUG_ASSERTCRASH(m_gameMode == GAME_SKIRMISH, ("Expected GAME_SKIRMISH but got %s", toString(m_gameMode))); + + // 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(); + } } if (slot->isAI()) {