Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Generals/Code/GameEngine/Include/GameLogic/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ class Object : public Thing, public Snapshot

Object* getNextObject() { return m_next; }
const Object* getNextObject() const { return m_next; }
Object* getPrevObject() { return m_prev; }
const Object* getPrevObject() const { return m_prev; }
void friend_setNextObject(Object* obj) { m_next = obj; }
void friend_setPrevObject(Object* obj) { m_prev = obj; }

void updateObjValuesFromMapProperties(Dict* properties); ///< Brings in properties set in the editor.

Expand Down
28 changes: 27 additions & 1 deletion Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4241,13 +4241,14 @@ void GameLogic::prepareLogicForObjectLoad( void )
* this version breaks compatibility with previous versions. (CBD)
* 5: Added xfering the BuildAssistant's sell list.
* 9: Added m_rankPointsToAddAtGameStart, or else on a load game, your RestartGame button will forget your exp
* 10: TheSuperHackers @tweak Save objects in reverse order so they load in correct order. Reverse object list for old saves.
*/
// ------------------------------------------------------------------------------------------------
void GameLogic::xfer( Xfer *xfer )
{

// version
const XferVersion currentVersion = 9;
const XferVersion currentVersion = 10;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );

Expand Down Expand Up @@ -4281,7 +4282,13 @@ void GameLogic::xfer( Xfer *xfer )
if( xfer->getXferMode() == XFER_SAVE )
{

// TheSuperHackers @fix bobtista 27/01/2026 Save objects in reverse order (newest first)
// so they load in the correct order (oldest objects at head of list).
Object *lastObj = nullptr;
for( obj = getFirstObject(); obj; obj = obj->getNextObject() )
lastObj = obj;

for( obj = lastObj; obj; obj = obj->getPrevObject() )
{

// get the object TOC entry for this template
Expand Down Expand Up @@ -4364,6 +4371,25 @@ void GameLogic::xfer( Xfer *xfer )

}

// TheSuperHackers @fix bobtista 27/01/2026 Reverse object list for old saves.
// Old saves stored objects oldest-first, which results in reversed order when loaded
// since objects are prepended during creation. Version 10+ saves in reverse order.
if ( version <= 9 )
{
Object *prev = nullptr;
Object *current = m_objList;
Object *next = nullptr;
while ( current != nullptr )
{
next = current->getNextObject();
current->friend_setNextObject( prev );
current->friend_setPrevObject( next );
prev = current;
current = next;
}
m_objList = prev;
}

}

// campaign info
Expand Down
4 changes: 4 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ class Object : public Thing, public Snapshot

Object* getNextObject() { return m_next; }
const Object* getNextObject() const { return m_next; }
Object* getPrevObject() { return m_prev; }
const Object* getPrevObject() const { return m_prev; }
void friend_setNextObject(Object* obj) { m_next = obj; }
void friend_setPrevObject(Object* obj) { m_prev = obj; }

void updateObjValuesFromMapProperties(Dict* properties); ///< Brings in properties set in the editor.

Expand Down
29 changes: 27 additions & 2 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4801,13 +4801,14 @@ void GameLogic::prepareLogicForObjectLoad( void )
* 5: Added xfering the BuildAssistant's sell list.
* 9: Added m_rankPointsToAddAtGameStart, or else on a load game, your RestartGame button will forget your exp
* 10: xfer m_superweaponRestriction
* 11: TheSuperHackers @tweak Save objects in reverse order so they load in correct order
*/
// ------------------------------------------------------------------------------------------------
void GameLogic::xfer( Xfer *xfer )
{

// version
const XferVersion currentVersion = 10;
const XferVersion currentVersion = 11;
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );

Expand Down Expand Up @@ -4840,8 +4841,13 @@ void GameLogic::xfer( Xfer *xfer )
ObjectTOCEntry *tocEntry;
if( xfer->getXferMode() == XFER_SAVE )
{

// TheSuperHackers @fix bobtista 27/01/2026 Save objects in reverse order (newest first)
// so they load in the correct order (oldest objects at head of list).
Object *lastObj = nullptr;
for( obj = getFirstObject(); obj; obj = obj->getNextObject() )
lastObj = obj;

for( obj = lastObj; obj; obj = obj->getPrevObject() )
{

// get the object TOC entry for this template
Expand Down Expand Up @@ -4924,6 +4930,25 @@ void GameLogic::xfer( Xfer *xfer )

}

// TheSuperHackers @fix bobtista 27/01/2026 Reverse object list for old saves.
// Old saves stored objects oldest-first, which results in reversed order when loaded
// since objects are prepended during creation. Version 11+ saves in reverse order.
if ( version <= 10 )
{
Object *prev = nullptr;
Object *current = m_objList;
Object *next = nullptr;
while ( current != nullptr )
{
next = current->getNextObject();
current->friend_setNextObject( prev );
current->friend_setPrevObject( next );
prev = current;
current = next;
}
m_objList = prev;
}

}

// campaign info
Expand Down
Loading