From f14b5fed7b16c9694f3287e0044a1c51a5c1577c Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 19 Jul 2026 19:43:30 +0400 Subject: [PATCH 1/3] fix(savegame): serialize base StateMachine state in Turret and Dozer action state machines --- .../Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp | 9 ++++++++- .../GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp index 78395baf998..241cfc6bbed 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp @@ -150,10 +150,16 @@ void TurretStateMachine::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void TurretStateMachine::xfer( Xfer *xfer ) { - XferVersion cv = 1; + // TheSuperHackers @bugfix bobtista 19/07/2026 Bump to version 2 to serialize the base + // StateMachine state. Without this the turret reverts to its default state on load. + XferVersion cv = 2; XferVersion v = cv; xfer->xferVersion( &v, cv ); + if (v >= 2) + { + StateMachine::xfer(xfer); + } } // ------------------------------------------------------------------------------------------------ @@ -161,6 +167,7 @@ void TurretStateMachine::xfer( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void TurretStateMachine::loadPostProcess() { + StateMachine::loadPostProcess(); } //---------------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index 2ece830173a..c6c6ddb80a8 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -837,11 +837,18 @@ void DozerActionStateMachine::crc( Xfer *xfer ) void DozerActionStateMachine::xfer( Xfer *xfer ) { // version - XferVersion currentVersion = 1; + // TheSuperHackers @bugfix bobtista 19/07/2026 Bump to version 2 to serialize the base + // StateMachine state. Without this the dozer reverts to its default state on load. + XferVersion currentVersion = 2; XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); xfer->xferUser(&m_task, sizeof(m_task)); + + if (version >= 2) + { + StateMachine::xfer(xfer); + } } // ------------------------------------------------------------------------------------------------ @@ -849,6 +856,7 @@ void DozerActionStateMachine::xfer( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void DozerActionStateMachine::loadPostProcess() { + StateMachine::loadPostProcess(); } From 1bba86bb9d984c23f16eb30ff71afe4d06842fe2 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Mon, 20 Jul 2026 02:22:37 +0400 Subject: [PATCH 2/3] fix(savegame): gate Turret/Dozer StateMachine xfer version behind RETAIL_COMPATIBLE_XFER_SAVE --- .../Source/GameLogic/AI/TurretAI.cpp | 22 +++++++++++++------ .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 13 ++++++++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp index 241cfc6bbed..02d7291071a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp @@ -146,17 +146,25 @@ void TurretStateMachine::crc( Xfer *xfer ) } // ------------------------------------------------------------------------------------------------ -/** Xfer Method */ +/** Xfer Method + * Version Info: + * 1: Initial version + * 2: TheSuperHackers @bugfix bobtista 19/07/2026 Serialize the base StateMachine state. + * Without this the turret reverts to its default state on load. + */ // ------------------------------------------------------------------------------------------------ void TurretStateMachine::xfer( Xfer *xfer ) { - // TheSuperHackers @bugfix bobtista 19/07/2026 Bump to version 2 to serialize the base - // StateMachine state. Without this the turret reverts to its default state on load. - XferVersion cv = 2; - XferVersion v = cv; - xfer->xferVersion( &v, cv ); + // version +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif + XferVersion version = currentVersion; + xfer->xferVersion( &version, currentVersion ); - if (v >= 2) + if (version >= 2) { StateMachine::xfer(xfer); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index c6c6ddb80a8..2ccaaa00d38 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -832,14 +832,21 @@ void DozerActionStateMachine::crc( Xfer *xfer ) } // ------------------------------------------------------------------------------------------------ -/** Xfer Method */ +/** Xfer Method + * Version Info: + * 1: Initial version + * 2: TheSuperHackers @bugfix bobtista 19/07/2026 Serialize the base StateMachine state. + * Without this the dozer reverts to its default state on load. + */ // ------------------------------------------------------------------------------------------------ void DozerActionStateMachine::xfer( Xfer *xfer ) { // version - // TheSuperHackers @bugfix bobtista 19/07/2026 Bump to version 2 to serialize the base - // StateMachine state. Without this the dozer reverts to its default state on load. +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); From a2ead2cf73865fc24c0892367a653d30c102ad5c Mon Sep 17 00:00:00 2001 From: bobtista Date: Wed, 22 Jul 2026 13:07:59 -0400 Subject: [PATCH 3/3] fix(savegame): serialize base StateMachine state in Turret and Dozer action state machines (Generals) --- .../Source/GameLogic/AI/TurretAI.cpp | 23 +++++++++++++++---- .../Object/Update/AIUpdate/DozerAIUpdate.cpp | 17 +++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp index 651e2c4f2f0..ba41dd60151 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp @@ -146,14 +146,28 @@ void TurretStateMachine::crc( Xfer *xfer ) } // ------------------------------------------------------------------------------------------------ -/** Xfer Method */ +/** Xfer Method + * Version Info: + * 1: Initial version + * 2: TheSuperHackers @bugfix bobtista 19/07/2026 Serialize the base StateMachine state. + * Without this the turret reverts to its default state on load. + */ // ------------------------------------------------------------------------------------------------ void TurretStateMachine::xfer( Xfer *xfer ) { - XferVersion cv = 1; - XferVersion v = cv; - xfer->xferVersion( &v, cv ); + // version +#if RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif + XferVersion version = currentVersion; + xfer->xferVersion( &version, currentVersion ); + if (version >= 2) + { + StateMachine::xfer(xfer); + } } // ------------------------------------------------------------------------------------------------ @@ -161,6 +175,7 @@ void TurretStateMachine::xfer( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void TurretStateMachine::loadPostProcess() { + StateMachine::loadPostProcess(); } //---------------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index af6982fc7ba..c5a3eb001f2 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -827,16 +827,30 @@ void DozerActionStateMachine::crc( Xfer *xfer ) } // ------------------------------------------------------------------------------------------------ -/** Xfer Method */ +/** Xfer Method + * Version Info: + * 1: Initial version + * 2: TheSuperHackers @bugfix bobtista 19/07/2026 Serialize the base StateMachine state. + * Without this the dozer reverts to its default state on load. + */ // ------------------------------------------------------------------------------------------------ void DozerActionStateMachine::xfer( Xfer *xfer ) { // version +#if RETAIL_COMPATIBLE_XFER_SAVE XferVersion currentVersion = 1; +#else + XferVersion currentVersion = 2; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); xfer->xferUser(&m_task, sizeof(m_task)); + + if (version >= 2) + { + StateMachine::xfer(xfer); + } } // ------------------------------------------------------------------------------------------------ @@ -844,6 +858,7 @@ void DozerActionStateMachine::xfer( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ void DozerActionStateMachine::loadPostProcess() { + StateMachine::loadPostProcess(); }