From 29372ca5c373064a663b243f17f7c3a4a63bee71 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 25 Jan 2026 14:24:14 +0100 Subject: [PATCH 1/3] bugfix(ghostobject): Add ghost objects to the scene correctly after loading a savegame --- .../W3DDevice/GameLogic/W3DGhostObject.cpp | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp index 8224425dbe1..aada984e9e9 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp @@ -729,22 +729,10 @@ void W3DGhostObject::xfer( Xfer *xfer ) // xfer data xfer->xferSnapshot( objectSnapshot ); - - // add snapshot to the scene - objectSnapshot->addToScene(); } } } - // - // since there is a snapshot for this object, there cannot be a regular object/drawable - // in the world, we need to remove it - // - if( m_parentObject && - m_parentSnapshots[TheGhostObjectManager->getLocalPlayerIndex()] != nullptr && - xfer->getXferMode() == XFER_LOAD ) - removeParentObject(); - // count of partition shroudedness info to follow UnsignedByte shroudednessCount = 0; UnsignedByte playerIndex; @@ -805,6 +793,15 @@ void W3DGhostObject::loadPostProcess( void ) { // extend base class GhostObject::loadPostProcess(); + + const Int playerIndex = TheGhostObjectManager->getLocalPlayerIndex(); + + // TheSuperHackers @bugfix Only add the local player snapshot to the world and then remove the + // regular object. + if (addToScene(playerIndex)) + { + removeParentObject(); + } } // ------------------------------------------------------------------------------------------------ From 4977455c15987425414cfc0c08a3996d9e8d4313 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 27 Jan 2026 22:05:34 +0100 Subject: [PATCH 2/3] Preserve EA code comment --- .../Source/W3DDevice/GameLogic/W3DGhostObject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp index aada984e9e9..4e8a78c5498 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp @@ -796,10 +796,12 @@ void W3DGhostObject::loadPostProcess( void ) const Int playerIndex = TheGhostObjectManager->getLocalPlayerIndex(); - // TheSuperHackers @bugfix Only add the local player snapshot to the world and then remove the - // regular object. + // add snapshot to the scene + // TheSuperHackers @bugfix But only for the local player if (addToScene(playerIndex)) { + // since there is a snapshot for this object, there cannot be a regular object/drawable + // in the world, we need to remove it removeParentObject(); } } From 17a70228c8c0796726dff05438507c8ab08bc640 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 27 Jan 2026 22:05:57 +0100 Subject: [PATCH 3/3] Replicate in Generals --- .../W3DDevice/GameLogic/W3DGhostObject.cpp | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp index b4f35ec3602..736dc2b2b08 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp @@ -725,22 +725,10 @@ void W3DGhostObject::xfer( Xfer *xfer ) // xfer data xfer->xferSnapshot( objectSnapshot ); - - // add snapshot to the scene - objectSnapshot->addToScene(); } } } - // - // since there is a snapshot for this object, there cannot be a regular object/drawable - // in the world, we need to remove it - // - if( m_parentObject && - m_parentSnapshots[TheGhostObjectManager->getLocalPlayerIndex()] != nullptr && - xfer->getXferMode() == XFER_LOAD ) - removeParentObject(); - // count of partition shroudedness info to follow UnsignedByte shroudednessCount = 0; UnsignedByte playerIndex; @@ -801,6 +789,17 @@ void W3DGhostObject::loadPostProcess( void ) { // extend base class GhostObject::loadPostProcess(); + + const Int playerIndex = TheGhostObjectManager->getLocalPlayerIndex(); + + // add snapshot to the scene + // TheSuperHackers @bugfix But only for the local player + if (addToScene(playerIndex)) + { + // since there is a snapshot for this object, there cannot be a regular object/drawable + // in the world, we need to remove it + removeParentObject(); + } } // ------------------------------------------------------------------------------------------------