From 0fd10237d3f471f9153fae47e25918488228bb81 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 21 Dec 2025 13:16:46 +0100 Subject: [PATCH 1/2] fix(xfer): Fix xfer retail compatibility code --- .../W3DDevice/GameClient/W3DTreeBuffer.cpp | 4 +- .../Module/ParticleUplinkCannonUpdate.h | 2 + .../GameEngine/Source/Common/RTS/Money.cpp | 5 ++- .../GameEngine/Source/GameClient/Drawable.cpp | 4 +- .../Object/Behavior/PoisonedBehavior.cpp | 7 ++-- .../Object/Update/FlammableUpdate.cpp | 6 +-- .../Update/ParticleUplinkCannonUpdate.cpp | 41 +++++++++++-------- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp index 1b5ba20336..26fafc2cbe 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp @@ -1924,7 +1924,9 @@ void W3DTreeBuffer::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: TheSuperHackers @tweak Serialize sink frames as float instead of integer + */ // ------------------------------------------------------------------------------------------------ void W3DTreeBuffer::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h index 015813b9a7..a022329ba1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h @@ -231,6 +231,8 @@ class ParticleUplinkCannonUpdate : public SpecialPowerUpdateModule UnsignedInt m_2ndLastDrivingClickFrame; UnsignedInt m_nextDestWaypointID; + XferVersion m_xferVersion; + Bool m_upBonesCached; Bool m_defaultInfoCached; Bool m_invalidSettings; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp index ed1a177ad3..7821340747 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp @@ -161,7 +161,8 @@ void Money::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Add saveload support for the cash per minute income tracking */ + * 2: TheSuperHackers @tweak Serialize income tracking + */ // ------------------------------------------------------------------------------------------------ void Money::xfer( Xfer *xfer ) { @@ -205,7 +206,7 @@ void Money::loadPostProcess( void ) // ------------------------------------------------------------------------------------------------ void Money::parseMoneyAmount( INI *ini, void *instance, void *store, const void* userData ) { - // Someday, maybe, have mulitple fields like Gold:10000 Wood:1000 Tiberian:10 + // Someday, maybe, have multiple fields like Gold:10000 Wood:1000 Tiberian:10 Money * money = (Money *)store; UnsignedInt moneyAmount; INI::parseUnsignedInt( ini, instance, &moneyAmount, userData ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp index 9f1f5f7eaf..468acf22cd 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -5615,7 +5615,9 @@ void TintEnvelope::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer Method * Version Info; - * 1: Initial version */ + * 1: Initial version + * 2: TheSuperHackers @tweak Serialize sustain counter as float instead of integer + */ // ------------------------------------------------------------------------------------------------ void TintEnvelope::xfer( Xfer *xfer ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp index 3c32fe58a7..d7887ce189 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp @@ -209,7 +209,10 @@ void PoisonedBehavior::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Serialize death type + * 3: TheSuperHackers @tweak Serialize poison source + */ // ------------------------------------------------------------------------------------------------ void PoisonedBehavior::xfer( Xfer *xfer ) { @@ -240,12 +243,10 @@ void PoisonedBehavior::xfer( Xfer *xfer ) xfer->xferUser(&m_deathType, sizeof(m_deathType)); } -#if !RETAIL_COMPATIBLE_XFER_SAVE if (version >= 3) { xfer->xferObjectID(&m_poisonSource); } -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp index a665abaaa4..98b046391f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp @@ -285,7 +285,9 @@ void FlammableUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2. TheSuperHackers @tweak Serialize flame source + */ // ------------------------------------------------------------------------------------------------ void FlammableUpdate::xfer( Xfer *xfer ) { @@ -320,12 +322,10 @@ void FlammableUpdate::xfer( Xfer *xfer ) // last flame damage dealt xfer->xferUnsignedInt( &m_lastFlameDamageDealt ); -#if !RETAIL_COMPATIBLE_XFER_SAVE if (version >= 2) { xfer->xferObjectID(&m_flameSource); } -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index d2d1d07928..bb41f47e12 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -174,6 +174,7 @@ ParticleUplinkCannonUpdate::ParticleUplinkCannonUpdate( Thing *thing, const Modu m_manualTargetMode = FALSE; m_scriptedWaypointMode = FALSE; m_nextDestWaypointID = 0; + m_xferVersion = 1; m_initialTargetPosition.zero(); m_currentTargetPosition.zero(); m_overrideTargetDestination.zero(); @@ -1392,7 +1393,11 @@ void ParticleUplinkCannonUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Serialize decay frames + * 3: Serialize scripted waypoints (Added for Zero Hour) + * 4: TheSuperHackers @tweak Serialize orbit to target laser radius + */ // ------------------------------------------------------------------------------------------------ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) { @@ -1406,6 +1411,7 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) #endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); + m_xferVersion = version; // extend base class UpdateModule::xfer( xfer ); @@ -1527,27 +1533,28 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); -#if RETAIL_COMPATIBLE_XFER_SAVE - // TheSuperHackers @info xezon 17/05/2025 - // For retail game compatibility, this transfers the loaded visual laser radius - // settings from the Drawable's LaserUpdate to the local LaserRadiusUpdate. - if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID ) + if (m_xferVersion <= 3) { - Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); - if( drawable != NULL ) + // TheSuperHackers @info xezon 17/05/2025 + // For retail game compatibility, this transfers the loaded visual laser radius + // settings from the Drawable's LaserUpdate to the local LaserRadiusUpdate. + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID ) { - static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" ); - LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); - if( update != NULL ) + Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); + if( drawable != NULL ) { - m_orbitToTargetLaserRadius = update->getLaserRadiusUpdate(); + static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" ); + LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); + if( update != NULL ) + { + m_orbitToTargetLaserRadius = update->getLaserRadiusUpdate(); + } + } + else + { + DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } - } - else - { - DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } } -#endif } From 21a219f13c47b55649a3039f2d31c79d0f7b1326 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 21 Dec 2025 13:21:33 +0100 Subject: [PATCH 2/2] Replicate in Generals --- .../Module/ParticleUplinkCannonUpdate.h | 2 + .../GameEngine/Source/Common/RTS/Money.cpp | 5 ++- .../GameEngine/Source/GameClient/Drawable.cpp | 4 +- .../Object/Behavior/PoisonedBehavior.cpp | 7 ++-- .../Object/Update/FlammableUpdate.cpp | 6 +-- .../Update/ParticleUplinkCannonUpdate.cpp | 40 +++++++++++-------- 6 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h index f313a06f55..9101cd2a58 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h @@ -228,6 +228,8 @@ class ParticleUplinkCannonUpdate : public UpdateModule, public SpecialPowerUpdat UnsignedInt m_lastDrivingClickFrame; UnsignedInt m_2ndLastDrivingClickFrame; + XferVersion m_xferVersion; + Bool m_upBonesCached; Bool m_defaultInfoCached; Bool m_invalidSettings; diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Money.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Money.cpp index 00237714f5..ee9932cb9c 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Money.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/Money.cpp @@ -152,7 +152,8 @@ void Money::crc( Xfer *xfer ) /** Xfer method * Version Info: * 1: Initial version - * 2: Add saveload support for the cash per minute income tracking */ + * 2: TheSuperHackers @tweak Serialize income tracking + */ // ------------------------------------------------------------------------------------------------ void Money::xfer( Xfer *xfer ) { @@ -196,7 +197,7 @@ void Money::loadPostProcess( void ) // ------------------------------------------------------------------------------------------------ void Money::parseMoneyAmount( INI *ini, void *instance, void *store, const void* userData ) { - // Someday, maybe, have mulitple fields like Gold:10000 Wood:1000 Tiberian:10 + // Someday, maybe, have multiple fields like Gold:10000 Wood:1000 Tiberian:10 Money * money = (Money *)store; UnsignedInt moneyAmount; INI::parseUnsignedInt( ini, instance, &moneyAmount, userData ); diff --git a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp index 10e680001b..a3042e3e76 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -4858,7 +4858,9 @@ void TintEnvelope::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer Method * Version Info; - * 1: Initial version */ + * 1: Initial version + * 2: TheSuperHackers @tweak Serialize sustain counter as float instead of integer + */ // ------------------------------------------------------------------------------------------------ void TintEnvelope::xfer( Xfer *xfer ) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp index d9c446f248..931c5d8078 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp @@ -208,7 +208,10 @@ void PoisonedBehavior::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Serialize death type + * 3: TheSuperHackers @tweak Serialize poison source + */ // ------------------------------------------------------------------------------------------------ void PoisonedBehavior::xfer( Xfer *xfer ) { @@ -239,12 +242,10 @@ void PoisonedBehavior::xfer( Xfer *xfer ) xfer->xferUser(&m_deathType, sizeof(m_deathType)); } -#if !RETAIL_COMPATIBLE_XFER_SAVE if (version >= 3) { xfer->xferObjectID(&m_poisonSource); } -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp index e8e8f750e7..acbdde07df 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp @@ -285,7 +285,9 @@ void FlammableUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2. TheSuperHackers @tweak Serialize flame source + */ // ------------------------------------------------------------------------------------------------ void FlammableUpdate::xfer( Xfer *xfer ) { @@ -320,12 +322,10 @@ void FlammableUpdate::xfer( Xfer *xfer ) // last flame damage dealt xfer->xferUnsignedInt( &m_lastFlameDamageDealt ); -#if !RETAIL_COMPATIBLE_XFER_SAVE if (version >= 2) { xfer->xferObjectID(&m_flameSource); } -#endif } // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index ad7614d1f1..70860c672b 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -173,6 +173,7 @@ ParticleUplinkCannonUpdate::ParticleUplinkCannonUpdate( Thing *thing, const Modu m_defaultInfoCached = false; m_invalidSettings = false; m_manualTargetMode = false; + m_xferVersion = 1; m_initialTargetPosition.zero(); m_currentTargetPosition.zero(); m_overrideTargetDestination.zero(); @@ -1308,7 +1309,10 @@ void ParticleUplinkCannonUpdate::crc( Xfer *xfer ) // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: - * 1: Initial version */ + * 1: Initial version + * 2: Serialize decay frames + * 4: TheSuperHackers @tweak Serialize orbit to target laser radius + */ // ------------------------------------------------------------------------------------------------ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) { @@ -1322,6 +1326,7 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) #endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); + m_xferVersion = version; // extend base class UpdateModule::xfer( xfer ); @@ -1436,27 +1441,28 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); -#if RETAIL_COMPATIBLE_XFER_SAVE - // TheSuperHackers @info xezon 17/05/2025 - // For retail game compatibility, this transfers the loaded visual laser radius - // settings from the Drawable's LaserUpdate to the local LaserRadiusUpdate. - if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID ) + if (m_xferVersion <= 3) { - Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); - if( drawable != NULL ) + // TheSuperHackers @info xezon 17/05/2025 + // For retail game compatibility, this transfers the loaded visual laser radius + // settings from the Drawable's LaserUpdate to the local LaserRadiusUpdate. + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID ) { - static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" ); - LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); - if( update != NULL ) + Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); + if( drawable != NULL ) { - m_orbitToTargetLaserRadius = update->getLaserRadiusUpdate(); + static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" ); + LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); + if( update != NULL ) + { + m_orbitToTargetLaserRadius = update->getLaserRadiusUpdate(); + } + } + else + { + DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } - } - else - { - DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID" )); } } -#endif }