From 2608bb0530e8cc24c5f517bc7815701c3daef951 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 17 May 2025 14:40:23 +0200 Subject: [PATCH 01/14] [GEN][ZH] Separate ParticleUplinkCannonUpdate's damage radius calculation from LaserUpdate's client update --- .../Include/GameLogic/Module/LaserUpdate.h | 61 ++++++--- .../Module/ParticleUplinkCannonUpdate.h | 2 + .../GameLogic/Object/Update/LaserUpdate.cpp | 124 ++++++++++++------ .../Update/ParticleUplinkCannonUpdate.cpp | 40 +++++- 4 files changed, 168 insertions(+), 59 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index 8e08e1d1e05..28b8a70dae0 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -59,11 +59,47 @@ class LaserUpdateModuleData : public ClientUpdateModuleData }; +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +class LaserRadiusUpdateBase +{ +protected: + LaserRadiusUpdateBase(); + + void initRadius( Int sizeDeltaFrames ); + bool updateRadius(); + void setDecayFrames( UnsignedInt decayFrames ); + void xfer( Xfer *xfer ); + void setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other); + Real getWidthScale() const { return m_currentWidthScalar; } + +private: + Bool m_widening; + Bool m_decaying; + UnsignedInt m_widenStartFrame; + UnsignedInt m_widenFinishFrame; + Real m_currentWidthScalar; + UnsignedInt m_decayStartFrame; + UnsignedInt m_decayFinishFrame; +}; //------------------------------------------------------------------------------------------------- -/** The default update module */ //------------------------------------------------------------------------------------------------- -class LaserUpdate : public ClientUpdateModule +class LaserRadiusUpdate : private LaserRadiusUpdateBase +{ +public: + using LaserRadiusUpdateBase::initRadius; + using LaserRadiusUpdateBase::updateRadius; + using LaserRadiusUpdateBase::setDecayFrames; + using LaserRadiusUpdateBase::xfer; + using LaserRadiusUpdateBase::setLaserRadiusUpdateBase; + using LaserRadiusUpdateBase::getWidthScale; +}; + +//------------------------------------------------------------------------------------------------- +/** The laser update module */ +//------------------------------------------------------------------------------------------------- +class LaserUpdate : public ClientUpdateModule, private LaserRadiusUpdateBase { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LaserUpdate, "LaserUpdate" ) @@ -76,17 +112,19 @@ class LaserUpdate : public ClientUpdateModule //Actually puts the laser in the world. void initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames = 0 ); - void setDecayFrames( UnsignedInt decayFrames ); - const Coord3D* getStartPos() { return &m_startPos; } - const Coord3D* getEndPos() { return &m_endPos; } + const LaserRadiusUpdateBase& getLaserRadiusUpdateBase() const; + using LaserRadiusUpdateBase::setDecayFrames; + using LaserRadiusUpdateBase::getWidthScale; + const Coord3D* getStartPos() const { return &m_startPos; } + const Coord3D* getEndPos() const { return &m_endPos; } + + Real getTemplateLaserRadius() const; Real getCurrentLaserRadius() const; void setDirty( Bool dirty ) { m_dirty = dirty; } - Bool isDirty() { return m_dirty; } - - Real getWidthScale() const { return m_currentWidthScalar; } + Bool isDirty() const { return m_dirty; } virtual void clientUpdate(); @@ -105,13 +143,6 @@ class LaserUpdate : public ClientUpdateModule Bool m_dirty; ParticleSystemID m_particleSystemID; ParticleSystemID m_targetParticleSystemID; - Bool m_widening; - Bool m_decaying; - UnsignedInt m_widenStartFrame; - UnsignedInt m_widenFinishFrame; - Real m_currentWidthScalar; - UnsignedInt m_decayStartFrame; - UnsignedInt m_decayFinishFrame; AsciiString m_parentBoneName; }; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h index dbebd57eb3d..19c6c157ad5 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h @@ -35,6 +35,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "Common/KindOf.h" #include "Common/Science.h" +#include "GameLogic/Module/LaserUpdate.h" #include "GameLogic/Module/SpecialPowerUpdateModule.h" // FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// @@ -218,6 +219,7 @@ class ParticleUplinkCannonUpdate : public SpecialPowerUpdateModule DrawableID m_laserBeamIDs[ MAX_OUTER_NODES ]; DrawableID m_groundToOrbitBeamID; DrawableID m_orbitToTargetBeamID; + LaserRadiusUpdate m_orbitToTargetLaserRadius; ParticleSystemID m_connectorSystemID; ParticleSystemID m_laserBaseSystemID; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp index ec092e782f9..447179374c5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp @@ -71,6 +71,20 @@ LaserUpdateModuleData::LaserUpdateModuleData() p.add(dataFieldParse); } + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +LaserRadiusUpdateBase::LaserRadiusUpdateBase() +{ + m_widening = false; + m_widenStartFrame = 0; + m_widenFinishFrame = 0; + m_currentWidthScalar = 1.0f; + m_decaying = false; + m_decayStartFrame = 0; + m_decayFinishFrame = 0; +} + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- LaserUpdate::LaserUpdate( Thing *thing, const ModuleData* moduleData ) : ClientUpdateModule( thing, moduleData ) @@ -83,13 +97,6 @@ LaserUpdate::LaserUpdate( Thing *thing, const ModuleData* moduleData ) : ClientU // m_particleSystemID = INVALID_PARTICLE_SYSTEM_ID; m_targetParticleSystemID = INVALID_PARTICLE_SYSTEM_ID; - m_widening = false; - m_widenStartFrame = 0; - m_widenFinishFrame = 0; - m_currentWidthScalar = 1.0f; - m_decaying = false; - m_decayStartFrame = 0; - m_decayFinishFrame = 0; m_parentID = INVALID_DRAWABLE_ID; m_targetID = INVALID_DRAWABLE_ID; m_parentBoneName.clear(); @@ -201,19 +208,22 @@ void LaserUpdate::clientUpdate( void ) { updateStartPos(); updateEndPos(); + m_dirty |= updateRadius(); +} +//------------------------------------------------------------------------------------------------- +bool LaserRadiusUpdateBase::updateRadius() +{ + bool updated = false; if( m_decaying ) { UnsignedInt now = TheGameLogic->getFrame(); m_currentWidthScalar = 1.0f - (Real)(now - m_decayStartFrame) / (Real)(m_decayFinishFrame - m_decayStartFrame); - m_dirty = true; + updated = true; if( m_currentWidthScalar <= 0.0f ) { m_currentWidthScalar = 0.0f; - - //When decay is finished... delete the laser. - //TheGameLogic->destroyObject( getObject() ); - return; + //m_decaying = false // ????? } } else if( m_widening ) @@ -221,17 +231,19 @@ void LaserUpdate::clientUpdate( void ) //We need to resize our laser width based on the growth ratio completed. UnsignedInt now = TheGameLogic->getFrame(); m_currentWidthScalar = (Real)(now - m_widenStartFrame) / (Real)(m_widenFinishFrame - m_widenStartFrame); - m_dirty = true; + updated = true; if( m_currentWidthScalar >= 1.0f ) { m_currentWidthScalar = 1.0f; m_widening = false; } } - return; + + return updated; } -void LaserUpdate::setDecayFrames( UnsignedInt decayFrames ) +//------------------------------------------------------------------------------------------------- +void LaserRadiusUpdateBase::setDecayFrames( UnsignedInt decayFrames ) { if( decayFrames > 0 ) { @@ -242,12 +254,9 @@ void LaserUpdate::setDecayFrames( UnsignedInt decayFrames ) } } - //------------------------------------------------------------------------------------------------- -void LaserUpdate::initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames ) +void LaserRadiusUpdateBase::initRadius( Int sizeDeltaFrames ) { - const LaserUpdateModuleData *data = getLaserUpdateModuleData(); - ParticleSystem *system; if( sizeDeltaFrames > 0 ) { m_widening = true; @@ -262,6 +271,52 @@ void LaserUpdate::initLaser( const Object *parent, const Object *target, const C m_decayFinishFrame = m_decayStartFrame - sizeDeltaFrames; m_currentWidthScalar = 1.0f; } +} + +//------------------------------------------------------------------------------------------------- +void LaserRadiusUpdateBase::xfer( Xfer *xfer ) +{ + // widening + xfer->xferBool( &m_widening ); + + // decaying + xfer->xferBool( &m_decaying ); + + // widen start frame + xfer->xferUnsignedInt( &m_widenStartFrame ); + + // widen finish frame + xfer->xferUnsignedInt( &m_widenFinishFrame ); + + // current width scalar + xfer->xferReal( &m_currentWidthScalar ); + + // decay start frame + xfer->xferUnsignedInt( &m_decayStartFrame ); + + // decay finish frame + xfer->xferUnsignedInt( &m_decayFinishFrame ); +} + +//------------------------------------------------------------------------------------------------- +void LaserRadiusUpdateBase::setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other) +{ + static_cast(*this) = other; +} + +//------------------------------------------------------------------------------------------------- +const LaserRadiusUpdateBase& LaserUpdate::getLaserRadiusUpdateBase() const +{ + return static_cast(*this); +} + +//------------------------------------------------------------------------------------------------- +void LaserUpdate::initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames ) +{ + const LaserUpdateModuleData *data = getLaserUpdateModuleData(); + ParticleSystem *system; + + initRadius( sizeDeltaFrames ); // Write down the bone name override m_parentBoneName = parentBoneName; @@ -393,7 +448,7 @@ void LaserUpdate::initLaser( const Object *parent, const Object *target, const C } //------------------------------------------------------------------------------------------------- -Real LaserUpdate::getCurrentLaserRadius() const +Real LaserUpdate::getTemplateLaserRadius() const { const Drawable *draw = getDrawable(); const LaserDrawInterface* ldi = NULL; @@ -406,12 +461,18 @@ Real LaserUpdate::getCurrentLaserRadius() const //While it appears the logic is accessing client data, it is actually accessing template module //data from the client. This value is INI constant thus can't change. It's grouped with other //laser defining attributes and having it there makes it easier for artists. - return ldi->getLaserTemplateWidth() * m_currentWidthScalar; + return ldi->getLaserTemplateWidth(); } } return 0.0f; } +//------------------------------------------------------------------------------------------------- +Real LaserUpdate::getCurrentLaserRadius() const +{ + return getTemplateLaserRadius() * getWidthScale(); +} + // ------------------------------------------------------------------------------------------------ /** CRC */ // ------------------------------------------------------------------------------------------------ @@ -454,26 +515,7 @@ void LaserUpdate::xfer( Xfer *xfer ) // target particle system id xfer->xferUser( &m_targetParticleSystemID, sizeof( ParticleSystemID ) ); - // widening - xfer->xferBool( &m_widening ); - - // decaying - xfer->xferBool( &m_decaying ); - - // widen start frame - xfer->xferUnsignedInt( &m_widenStartFrame ); - - // widen finish frame - xfer->xferUnsignedInt( &m_widenFinishFrame ); - - // current width scalar - xfer->xferReal( &m_currentWidthScalar ); - - // decay start frame - xfer->xferUnsignedInt( &m_decayStartFrame ); - - // decay finish frame - xfer->xferUnsignedInt( &m_decayFinishFrame ); + LaserRadiusUpdateBase::xfer( xfer ); xfer->xferDrawableID(&m_parentID); xfer->xferDrawableID(&m_targetID); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 971066dcbbe..47869fb5908 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -55,7 +55,6 @@ #include "GameLogic/Module/SpecialPowerModule.h" #include "GameLogic/Module/ParticleUplinkCannonUpdate.h" #include "GameLogic/Module/PhysicsUpdate.h" -#include "GameLogic/Module/LaserUpdate.h" #include "GameLogic/Module/ActiveBody.h" #ifdef RTS_INTERNAL @@ -221,6 +220,7 @@ void ParticleUplinkCannonUpdate::killEverything() TheGameClient->destroyDrawable( beam ); } m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); } TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() ); @@ -468,6 +468,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() if( update ) { update->setDecayFrames( data->m_widthGrowFrames ); + m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames ); } m_laserStatus = LASERSTATUS_DECAYING; } @@ -485,6 +486,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() { TheGameClient->destroyDrawable( beam ); m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); m_laserStatus = LASERSTATUS_DEAD; m_startAttackFrame = 0; setLogicalStatus( STATUS_IDLE ); @@ -614,8 +616,17 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() if( update ) { update->initLaser( NULL, NULL, &orbitPosition, &m_currentTargetPosition, "" ); - scorchRadius = update->getCurrentLaserRadius() * data->m_scorchMarkScalar; - damageRadius = update->getCurrentLaserRadius() * data->m_damageRadiusScalar; + const Real visualLaserRadius = update->getCurrentLaserRadius(); + scorchRadius = visualLaserRadius * data->m_scorchMarkScalar; + + // TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025 + // Originally the damage radius was calculated with a value updated by LaserUpdate::clientUpdate(). + // To no longer rely on client updates, this class now maintains a logical copy of the visual laser radius. + m_orbitToTargetLaserRadius.updateRadius(); + const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale(); + damageRadius = logicalLaserRadius * data->m_damageRadiusScalar; + DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius, + ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds")); } //Create scorch marks periodically @@ -981,6 +992,7 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() ); TheGameClient->destroyDrawable( beam ); m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); } if( data->m_particleBeamLaserName.isNotEmpty() ) @@ -1000,6 +1012,7 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra orbitPosition.set( &m_initialTargetPosition ); orbitPosition.z += 500.0f; update->initLaser( NULL, NULL, &orbitPosition, &m_initialTargetPosition, "", growthFrames ); + m_orbitToTargetLaserRadius.initRadius( growthFrames ); } } } @@ -1472,4 +1485,25 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); + // TheSuperHackers @info xezon 17/05/2025 + // For legacy compatibility, this transfers the loaded visual laser radius settings + // from the Drawable's LaserUpdate to the local LaserRadiusUpdate. + if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID ) + { + Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); + if( drawable != NULL ) + { + static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" ); + LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); + if( update != NULL ) + { + m_orbitToTargetLaserRadius.setLaserRadiusUpdateBase(update->getLaserRadiusUpdateBase()); + } + } + else + { + DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID\n" )); + } + } + } // end loadPostProcess From 9a9ee02fa0f38594db95ce9694cbf957f0bcc505 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 17 May 2025 23:30:28 +0200 Subject: [PATCH 02/14] Simplify setLaserRadiusUpdateBase, getLaserRadiusUpdateBase --- .../Include/GameLogic/Module/LaserUpdate.h | 4 ++-- .../Source/GameLogic/Object/Update/LaserUpdate.cpp | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index 28b8a70dae0..7e3971a6a12 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -70,7 +70,7 @@ class LaserRadiusUpdateBase bool updateRadius(); void setDecayFrames( UnsignedInt decayFrames ); void xfer( Xfer *xfer ); - void setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other); + void setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other) { *this = other; } Real getWidthScale() const { return m_currentWidthScalar; } private: @@ -113,7 +113,7 @@ class LaserUpdate : public ClientUpdateModule, private LaserRadiusUpdateBase //Actually puts the laser in the world. void initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames = 0 ); - const LaserRadiusUpdateBase& getLaserRadiusUpdateBase() const; + const LaserRadiusUpdateBase& getLaserRadiusUpdateBase() const { return *this; } using LaserRadiusUpdateBase::setDecayFrames; using LaserRadiusUpdateBase::getWidthScale; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp index 447179374c5..aebf08db1c9 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp @@ -298,18 +298,6 @@ void LaserRadiusUpdateBase::xfer( Xfer *xfer ) xfer->xferUnsignedInt( &m_decayFinishFrame ); } -//------------------------------------------------------------------------------------------------- -void LaserRadiusUpdateBase::setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other) -{ - static_cast(*this) = other; -} - -//------------------------------------------------------------------------------------------------- -const LaserRadiusUpdateBase& LaserUpdate::getLaserRadiusUpdateBase() const -{ - return static_cast(*this); -} - //------------------------------------------------------------------------------------------------- void LaserUpdate::initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames ) { From 11f213185bc1973e9f04d62feb0242a56a26a0a0 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 08:59:34 +0200 Subject: [PATCH 03/14] Simplify LaserRadiusUpdate, use composition instead of inheritance --- .../Include/GameLogic/Module/LaserUpdate.h | 31 ++++++------------- .../GameLogic/Object/Update/LaserUpdate.cpp | 16 +++++----- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index 7e3971a6a12..cff3bf24589 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -61,16 +61,16 @@ class LaserUpdateModuleData : public ClientUpdateModuleData //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- -class LaserRadiusUpdateBase +class LaserRadiusUpdate { -protected: - LaserRadiusUpdateBase(); +public: + LaserRadiusUpdate(); void initRadius( Int sizeDeltaFrames ); bool updateRadius(); void setDecayFrames( UnsignedInt decayFrames ); void xfer( Xfer *xfer ); - void setLaserRadiusUpdateBase(const LaserRadiusUpdateBase& other) { *this = other; } + void setLaserRadiusUpdateBase(const LaserRadiusUpdate& other) { *this = other; } Real getWidthScale() const { return m_currentWidthScalar; } private: @@ -83,23 +83,10 @@ class LaserRadiusUpdateBase UnsignedInt m_decayFinishFrame; }; -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -class LaserRadiusUpdate : private LaserRadiusUpdateBase -{ -public: - using LaserRadiusUpdateBase::initRadius; - using LaserRadiusUpdateBase::updateRadius; - using LaserRadiusUpdateBase::setDecayFrames; - using LaserRadiusUpdateBase::xfer; - using LaserRadiusUpdateBase::setLaserRadiusUpdateBase; - using LaserRadiusUpdateBase::getWidthScale; -}; - //------------------------------------------------------------------------------------------------- /** The laser update module */ //------------------------------------------------------------------------------------------------- -class LaserUpdate : public ClientUpdateModule, private LaserRadiusUpdateBase +class LaserUpdate : public ClientUpdateModule { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LaserUpdate, "LaserUpdate" ) @@ -113,9 +100,9 @@ class LaserUpdate : public ClientUpdateModule, private LaserRadiusUpdateBase //Actually puts the laser in the world. void initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames = 0 ); - const LaserRadiusUpdateBase& getLaserRadiusUpdateBase() const { return *this; } - using LaserRadiusUpdateBase::setDecayFrames; - using LaserRadiusUpdateBase::getWidthScale; + const LaserRadiusUpdate& getLaserRadiusUpdateBase() const { return m_laserRadius; } + void setDecayFrames( UnsignedInt decayFrames ) { m_laserRadius.setDecayFrames(decayFrames); } + Real getWidthScale() const { return m_laserRadius.getWidthScale(); } const Coord3D* getStartPos() const { return &m_startPos; } const Coord3D* getEndPos() const { return &m_endPos; } @@ -144,6 +131,8 @@ class LaserUpdate : public ClientUpdateModule, private LaserRadiusUpdateBase ParticleSystemID m_particleSystemID; ParticleSystemID m_targetParticleSystemID; AsciiString m_parentBoneName; + + LaserRadiusUpdate m_laserRadius; }; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp index aebf08db1c9..d03fd4b6597 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp @@ -74,7 +74,7 @@ LaserUpdateModuleData::LaserUpdateModuleData() //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- -LaserRadiusUpdateBase::LaserRadiusUpdateBase() +LaserRadiusUpdate::LaserRadiusUpdate() { m_widening = false; m_widenStartFrame = 0; @@ -208,11 +208,11 @@ void LaserUpdate::clientUpdate( void ) { updateStartPos(); updateEndPos(); - m_dirty |= updateRadius(); + m_dirty |= m_laserRadius.updateRadius(); } //------------------------------------------------------------------------------------------------- -bool LaserRadiusUpdateBase::updateRadius() +bool LaserRadiusUpdate::updateRadius() { bool updated = false; if( m_decaying ) @@ -243,7 +243,7 @@ bool LaserRadiusUpdateBase::updateRadius() } //------------------------------------------------------------------------------------------------- -void LaserRadiusUpdateBase::setDecayFrames( UnsignedInt decayFrames ) +void LaserRadiusUpdate::setDecayFrames( UnsignedInt decayFrames ) { if( decayFrames > 0 ) { @@ -255,7 +255,7 @@ void LaserRadiusUpdateBase::setDecayFrames( UnsignedInt decayFrames ) } //------------------------------------------------------------------------------------------------- -void LaserRadiusUpdateBase::initRadius( Int sizeDeltaFrames ) +void LaserRadiusUpdate::initRadius( Int sizeDeltaFrames ) { if( sizeDeltaFrames > 0 ) { @@ -274,7 +274,7 @@ void LaserRadiusUpdateBase::initRadius( Int sizeDeltaFrames ) } //------------------------------------------------------------------------------------------------- -void LaserRadiusUpdateBase::xfer( Xfer *xfer ) +void LaserRadiusUpdate::xfer( Xfer *xfer ) { // widening xfer->xferBool( &m_widening ); @@ -304,7 +304,7 @@ void LaserUpdate::initLaser( const Object *parent, const Object *target, const C const LaserUpdateModuleData *data = getLaserUpdateModuleData(); ParticleSystem *system; - initRadius( sizeDeltaFrames ); + m_laserRadius.initRadius( sizeDeltaFrames ); // Write down the bone name override m_parentBoneName = parentBoneName; @@ -503,7 +503,7 @@ void LaserUpdate::xfer( Xfer *xfer ) // target particle system id xfer->xferUser( &m_targetParticleSystemID, sizeof( ParticleSystemID ) ); - LaserRadiusUpdateBase::xfer( xfer ); + m_laserRadius.xfer( xfer ); xfer->xferDrawableID(&m_parentID); xfer->xferDrawableID(&m_targetID); From 15c3af366ee17a4c7397ba7531186e98bb0e82a7 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 09:35:19 +0200 Subject: [PATCH 04/14] Add RETAIL_COMPATIBLE_LOGIC macro to make intent crystal clear --- Core/GameEngine/CMakeLists.txt | 1 + GeneralsMD/Code/GameEngine/CMakeLists.txt | 1 + .../GameEngine/Include/Common/GameMacros.h | 23 +++++++++++++++++++ .../GameEngine/Include/Precompiled/PreRTS.h | 1 + .../Update/ParticleUplinkCannonUpdate.cpp | 14 ++++++++--- 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index e9c017dc985..1b081af5384 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -44,6 +44,7 @@ set(GAMEENGINE_SRC # Include/Common/GameCommon.h # Include/Common/GameEngine.h # Include/Common/GameLOD.h +# Include/Common/GameMacros.h # Include/Common/GameMemory.h # Include/Common/GameMusic.h # Include/Common/GameSounds.h diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 0dfc0dbfa62..3f8d1d2c592 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -44,6 +44,7 @@ set(GAMEENGINE_SRC Include/Common/GameCommon.h Include/Common/GameEngine.h Include/Common/GameLOD.h + Include/Common/GameMacros.h Include/Common/GameMemory.h Include/Common/GameMusic.h Include/Common/GameSounds.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h b/GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h new file mode 100644 index 00000000000..0b9ad8612eb --- /dev/null +++ b/GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h @@ -0,0 +1,23 @@ +/* +** Command & Conquer Generals Zero Hour(tm) +** Copyright 2025 TheSuperHackers +** +** This program is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +*/ + +#pragma once + +#ifndef RETAIL_COMPATIBLE_LOGIC +#define RETAIL_COMPATIBLE_LOGIC (1) // Game is expected to be compatible with retail Generals 1.08, Zero Hour 1.04 +#endif diff --git a/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h b/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h index c9db802fb0d..da64376e316 100644 --- a/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h +++ b/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h @@ -111,6 +111,7 @@ class STLSpecialAlloc; #include "Common/SubsystemInterface.h" #include "Common/GameCommon.h" +#include "Common/GameMacros.h" #include "Common/GameMemory.h" #include "Common/GameType.h" #include "Common/GlobalData.h" diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 47869fb5908..0e2464cfff6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -625,8 +625,10 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() m_orbitToTargetLaserRadius.updateRadius(); const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale(); damageRadius = logicalLaserRadius * data->m_damageRadiusScalar; +#if RETAIL_COMPATIBLE_LOGIC DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius, - ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds")); + ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n")); +#endif } //Create scorch marks periodically @@ -1397,6 +1399,10 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) // orbit to target beam xfer->xferDrawableID( &m_orbitToTargetBeamID ); +#if !RETAIL_COMPATIBLE_LOGIC + m_orbitToTargetLaserRadius.xfer( xfer ); +#endif + // connector system ID xfer->xferUser( &m_connectorSystemID, sizeof( ParticleSystemID ) ); @@ -1485,9 +1491,10 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); +#if RETAIL_COMPATIBLE_LOGIC // TheSuperHackers @info xezon 17/05/2025 - // For legacy compatibility, this transfers the loaded visual laser radius settings - // from the Drawable's LaserUpdate to the local LaserRadiusUpdate. + // 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 ) { Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); @@ -1505,5 +1512,6 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) DEBUG_CRASH(( "ParticleUplinkCannonUpdate::loadPostProcess - Unable to find drawable for m_orbitToTargetBeamID\n" )); } } +#endif } // end loadPostProcess From 0d4891e0c791b6f2fd5a623f6fba49ed2ac0d101 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 10:56:22 +0200 Subject: [PATCH 05/14] Remove superfluous function LaserRadiusUpdate::setLaserRadiusUpdateBase --- .../Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h | 1 - .../GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index cff3bf24589..2f548e18235 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -70,7 +70,6 @@ class LaserRadiusUpdate bool updateRadius(); void setDecayFrames( UnsignedInt decayFrames ); void xfer( Xfer *xfer ); - void setLaserRadiusUpdateBase(const LaserRadiusUpdate& other) { *this = other; } Real getWidthScale() const { return m_currentWidthScalar; } private: diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 0e2464cfff6..2e61358ea5f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1504,7 +1504,7 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); if( update != NULL ) { - m_orbitToTargetLaserRadius.setLaserRadiusUpdateBase(update->getLaserRadiusUpdateBase()); + m_orbitToTargetLaserRadius = update->getLaserRadiusUpdateBase(); } } else From d4475b5ee9cae4a6393be21bac61e32c5f7cdae7 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 11:48:07 +0200 Subject: [PATCH 06/14] Fix xfer versioning --- .../Object/Update/ParticleUplinkCannonUpdate.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 2e61358ea5f..0f1e0c281c4 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1368,7 +1368,11 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData(); // version +#if RETAIL_COMPATIBLE_LOGIC XferVersion currentVersion = 3; +#else + XferVersion currentVersion = 4; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1399,10 +1403,6 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) // orbit to target beam xfer->xferDrawableID( &m_orbitToTargetBeamID ); -#if !RETAIL_COMPATIBLE_LOGIC - m_orbitToTargetLaserRadius.xfer( xfer ); -#endif - // connector system ID xfer->xferUser( &m_connectorSystemID, sizeof( ParticleSystemID ) ); @@ -1480,6 +1480,11 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) xfer->xferUnsignedInt( &m_nextDestWaypointID ); } + if( currentVersion >= 4 ) + { + m_orbitToTargetLaserRadius.xfer( xfer ); + } + } // end xfer // ------------------------------------------------------------------------------------------------ From ada2ffef8dae2183f5aadd5beec8ff051155c14a Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 11:51:55 +0200 Subject: [PATCH 07/14] Rename GameMacros.h to GameDefines.h --- Core/GameEngine/CMakeLists.txt | 2 +- GeneralsMD/Code/GameEngine/CMakeLists.txt | 2 +- .../GameEngine/Include/Common/{GameMacros.h => GameDefines.h} | 0 GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename GeneralsMD/Code/GameEngine/Include/Common/{GameMacros.h => GameDefines.h} (100%) diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index 1b081af5384..4d9b9ff3a18 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -42,9 +42,9 @@ set(GAMEENGINE_SRC # Include/Common/FunctionLexicon.h # Include/Common/GameAudio.h # Include/Common/GameCommon.h +# Include/Common/GameDefines.h # Include/Common/GameEngine.h # Include/Common/GameLOD.h -# Include/Common/GameMacros.h # Include/Common/GameMemory.h # Include/Common/GameMusic.h # Include/Common/GameSounds.h diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 3f8d1d2c592..5ecb8da0462 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -42,9 +42,9 @@ set(GAMEENGINE_SRC Include/Common/FunctionLexicon.h Include/Common/GameAudio.h Include/Common/GameCommon.h + Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h - Include/Common/GameMacros.h Include/Common/GameMemory.h Include/Common/GameMusic.h Include/Common/GameSounds.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/GameMacros.h rename to GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h diff --git a/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h b/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h index da64376e316..1ecc85d85c4 100644 --- a/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h +++ b/GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h @@ -111,7 +111,7 @@ class STLSpecialAlloc; #include "Common/SubsystemInterface.h" #include "Common/GameCommon.h" -#include "Common/GameMacros.h" +#include "Common/GameDefines.h" #include "Common/GameMemory.h" #include "Common/GameType.h" #include "Common/GlobalData.h" From 992d56e32dbba95425ccaffd45a764ad2337bfca Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 11:54:48 +0200 Subject: [PATCH 08/14] Fix getLaserRadiusUpdate function name --- .../Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h | 2 +- .../GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index 2f548e18235..acd185f223a 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -99,7 +99,7 @@ class LaserUpdate : public ClientUpdateModule //Actually puts the laser in the world. void initLaser( const Object *parent, const Object *target, const Coord3D *startPos, const Coord3D *endPos, AsciiString parentBoneName, Int sizeDeltaFrames = 0 ); - const LaserRadiusUpdate& getLaserRadiusUpdateBase() const { return m_laserRadius; } + const LaserRadiusUpdate& getLaserRadiusUpdate() const { return m_laserRadius; } void setDecayFrames( UnsignedInt decayFrames ) { m_laserRadius.setDecayFrames(decayFrames); } Real getWidthScale() const { return m_laserRadius.getWidthScale(); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 0f1e0c281c4..c9003eec483 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1509,7 +1509,7 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) LaserUpdate *update = (LaserUpdate*)drawable->findClientUpdateModule( nameKeyClientUpdate ); if( update != NULL ) { - m_orbitToTargetLaserRadius = update->getLaserRadiusUpdateBase(); + m_orbitToTargetLaserRadius = update->getLaserRadiusUpdate(); } } else From c0f1743f71ccb0f1c29be898e8ea8514022eee51 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 11:57:04 +0200 Subject: [PATCH 09/14] Fix xfer versioning 2 --- .../GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index c9003eec483..1b1cdbd4e74 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -1369,9 +1369,9 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) // version #if RETAIL_COMPATIBLE_LOGIC - XferVersion currentVersion = 3; + const XferVersion currentVersion = 3; #else - XferVersion currentVersion = 4; + const XferVersion currentVersion = 4; #endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1480,7 +1480,7 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) xfer->xferUnsignedInt( &m_nextDestWaypointID ); } - if( currentVersion >= 4 ) + if( version >= 4 ) { m_orbitToTargetLaserRadius.xfer( xfer ); } From de81b5d5d9b2a900f8ed6790326ddf22e4adf93c Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 15:47:05 +0200 Subject: [PATCH 10/14] Change RETAIL_COMPATIBLE_LOGIC to RETAIL_COMPATIBLE_XFER_CRC + RETAIL_COMPATIBLE_XFER_SAVE --- GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h | 8 ++++++-- .../Object/Update/ParticleUplinkCannonUpdate.cpp | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h index 0b9ad8612eb..58a8a57311f 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h @@ -18,6 +18,10 @@ #pragma once -#ifndef RETAIL_COMPATIBLE_LOGIC -#define RETAIL_COMPATIBLE_LOGIC (1) // Game is expected to be compatible with retail Generals 1.08, Zero Hour 1.04 +#ifndef RETAIL_COMPATIBLE_XFER_CRC +#define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 +#endif + +#ifndef RETAIL_COMPATIBLE_XFER_SAVE +#define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04 #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 1b1cdbd4e74..bbe396864d3 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -625,7 +625,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() m_orbitToTargetLaserRadius.updateRadius(); const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale(); damageRadius = logicalLaserRadius * data->m_damageRadiusScalar; -#if RETAIL_COMPATIBLE_LOGIC +#if RETAIL_COMPATIBLE_XFER_CRC DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius, ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n")); #endif @@ -1368,7 +1368,7 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData(); // version -#if RETAIL_COMPATIBLE_LOGIC +#if RETAIL_COMPATIBLE_XFER_SAVE const XferVersion currentVersion = 3; #else const XferVersion currentVersion = 4; @@ -1496,7 +1496,7 @@ void ParticleUplinkCannonUpdate::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); -#if RETAIL_COMPATIBLE_LOGIC +#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. From 07b35586759a78bc9b758e6f5299d10defe2cb87 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 18 May 2025 16:30:44 +0200 Subject: [PATCH 11/14] Replicate in Generals --- Generals/Code/GameEngine/CMakeLists.txt | 1 + .../GameEngine/Include/Common/GameDefines.h | 27 +++++ .../Include/GameLogic/Module/LaserUpdate.h | 47 +++++--- .../Module/ParticleUplinkCannonUpdate.h | 2 + .../GameEngine/Include/Precompiled/PreRTS.h | 1 + .../GameLogic/Object/Update/LaserUpdate.cpp | 114 +++++++++++------- .../Update/ParticleUplinkCannonUpdate.cpp | 55 ++++++++- 7 files changed, 187 insertions(+), 60 deletions(-) create mode 100644 Generals/Code/GameEngine/Include/Common/GameDefines.h diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 6dcfa740edd..759337ae206 100644 --- a/Generals/Code/GameEngine/CMakeLists.txt +++ b/Generals/Code/GameEngine/CMakeLists.txt @@ -39,6 +39,7 @@ set(GAMEENGINE_SRC Include/Common/FunctionLexicon.h Include/Common/GameAudio.h Include/Common/GameCommon.h + Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h Include/Common/GameMemory.h diff --git a/Generals/Code/GameEngine/Include/Common/GameDefines.h b/Generals/Code/GameEngine/Include/Common/GameDefines.h new file mode 100644 index 00000000000..58a8a57311f --- /dev/null +++ b/Generals/Code/GameEngine/Include/Common/GameDefines.h @@ -0,0 +1,27 @@ +/* +** Command & Conquer Generals Zero Hour(tm) +** Copyright 2025 TheSuperHackers +** +** This program is free software: you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program. If not, see . +*/ + +#pragma once + +#ifndef RETAIL_COMPATIBLE_XFER_CRC +#define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 +#endif + +#ifndef RETAIL_COMPATIBLE_XFER_SAVE +#define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04 +#endif diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h index 1e1d9d1bc8e..351e5ce54e5 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/LaserUpdate.h @@ -59,9 +59,31 @@ class LaserUpdateModuleData : public ClientUpdateModuleData }; +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +class LaserRadiusUpdate +{ +public: + LaserRadiusUpdate(); + + void initRadius( Int sizeDeltaFrames ); + bool updateRadius(); + void setDecayFrames( UnsignedInt decayFrames ); + void xfer( Xfer *xfer ); + Real getWidthScale() const { return m_currentWidthScalar; } + +private: + Bool m_widening; + Bool m_decaying; + UnsignedInt m_widenStartFrame; + UnsignedInt m_widenFinishFrame; + Real m_currentWidthScalar; + UnsignedInt m_decayStartFrame; + UnsignedInt m_decayFinishFrame; +}; //------------------------------------------------------------------------------------------------- -/** The default update module */ +/** The laser update module */ //------------------------------------------------------------------------------------------------- class LaserUpdate : public ClientUpdateModule { @@ -76,17 +98,19 @@ class LaserUpdate : public ClientUpdateModule //Actually puts the laser in the world. void initLaser( const Object *parent, const Coord3D *startPos, const Coord3D *endPos, Int sizeDeltaFrames = 0 ); - void setDecayFrames( UnsignedInt decayFrames ); - const Coord3D* getStartPos() { return &m_startPos; } - const Coord3D* getEndPos() { return &m_endPos; } + const LaserRadiusUpdate& getLaserRadiusUpdate() const { return m_laserRadius; } + void setDecayFrames( UnsignedInt decayFrames ) { m_laserRadius.setDecayFrames(decayFrames); } + Real getWidthScale() const { return m_laserRadius.getWidthScale(); } + const Coord3D* getStartPos() const { return &m_startPos; } + const Coord3D* getEndPos() const { return &m_endPos; } + + Real getTemplateLaserRadius() const; Real getCurrentLaserRadius() const; void setDirty( Bool dirty ) { m_dirty = dirty; } - Bool isDirty() { return m_dirty; } - - Real getWidthScale() const { return m_currentWidthScalar; } + Bool isDirty() const { return m_dirty; } virtual void clientUpdate(); @@ -98,13 +122,8 @@ class LaserUpdate : public ClientUpdateModule Bool m_dirty; ParticleSystemID m_particleSystemID; ParticleSystemID m_targetParticleSystemID; - Bool m_widening; - Bool m_decaying; - UnsignedInt m_widenStartFrame; - UnsignedInt m_widenFinishFrame; - Real m_currentWidthScalar; - UnsignedInt m_decayStartFrame; - UnsignedInt m_decayFinishFrame; + + LaserRadiusUpdate m_laserRadius; }; diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h index 33a7200c25c..b8b1b8c3e96 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/ParticleUplinkCannonUpdate.h @@ -34,6 +34,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "Common/KindOf.h" +#include "GameLogic/Module/LaserUpdate.h" #include "GameLogic/Module/SpecialPowerUpdateModule.h" // FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// @@ -216,6 +217,7 @@ class ParticleUplinkCannonUpdate : public UpdateModule, public SpecialPowerUpdat DrawableID m_laserBeamIDs[ MAX_OUTER_NODES ]; DrawableID m_groundToOrbitBeamID; DrawableID m_orbitToTargetBeamID; + LaserRadiusUpdate m_orbitToTargetLaserRadius; ParticleSystemID m_connectorSystemID; ParticleSystemID m_laserBaseSystemID; diff --git a/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h b/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h index 361876de401..cd2daff73a2 100644 --- a/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h +++ b/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h @@ -111,6 +111,7 @@ class STLSpecialAlloc; #include "Common/SubsystemInterface.h" #include "Common/GameCommon.h" +#include "Common/GameDefines.h" #include "Common/GameMemory.h" #include "Common/GameType.h" #include "Common/GlobalData.h" diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp index 00b90a3b41b..90a69e20a3c 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp @@ -63,6 +63,20 @@ LaserUpdateModuleData::LaserUpdateModuleData() p.add(dataFieldParse); } + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +LaserRadiusUpdate::LaserRadiusUpdate() +{ + m_widening = false; + m_widenStartFrame = 0; + m_widenFinishFrame = 0; + m_currentWidthScalar = 1.0f; + m_decaying = false; + m_decayStartFrame = 0; + m_decayFinishFrame = 0; +} + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- LaserUpdate::LaserUpdate( Thing *thing, const ModuleData* moduleData ) : ClientUpdateModule( thing, moduleData ) @@ -75,13 +89,6 @@ LaserUpdate::LaserUpdate( Thing *thing, const ModuleData* moduleData ) : ClientU // m_particleSystemID = INVALID_PARTICLE_SYSTEM_ID; m_targetParticleSystemID = INVALID_PARTICLE_SYSTEM_ID; - m_widening = false; - m_widenStartFrame = 0; - m_widenFinishFrame = 0; - m_currentWidthScalar = 1.0f; - m_decaying = false; - m_decayStartFrame = 0; - m_decayFinishFrame = 0; } //------------------------------------------------------------------------------------------------- @@ -101,19 +108,22 @@ LaserUpdate::~LaserUpdate( void ) //------------------------------------------------------------------------------------------------- void LaserUpdate::clientUpdate( void ) { -/// @todo srj use SLEEPY_UPDATE here + m_dirty |= m_laserRadius.updateRadius(); +} + +//------------------------------------------------------------------------------------------------- +bool LaserRadiusUpdate::updateRadius() +{ + bool updated = false; if( m_decaying ) { UnsignedInt now = TheGameLogic->getFrame(); m_currentWidthScalar = 1.0f - (Real)(now - m_decayStartFrame) / (Real)(m_decayFinishFrame - m_decayStartFrame); - m_dirty = true; + updated = true; if( m_currentWidthScalar <= 0.0f ) { m_currentWidthScalar = 0.0f; - - //When decay is finished... delete the laser. - //TheGameLogic->destroyObject( getObject() ); - return; + //m_decaying = false // ????? } } else if( m_widening ) @@ -121,17 +131,19 @@ void LaserUpdate::clientUpdate( void ) //We need to resize our laser width based on the growth ratio completed. UnsignedInt now = TheGameLogic->getFrame(); m_currentWidthScalar = (Real)(now - m_widenStartFrame) / (Real)(m_widenFinishFrame - m_widenStartFrame); - m_dirty = true; + updated = true; if( m_currentWidthScalar >= 1.0f ) { m_currentWidthScalar = 1.0f; m_widening = false; } } - return; + + return updated; } -void LaserUpdate::setDecayFrames( UnsignedInt decayFrames ) +//------------------------------------------------------------------------------------------------- +void LaserRadiusUpdate::setDecayFrames( UnsignedInt decayFrames ) { if( decayFrames > 0 ) { @@ -142,12 +154,9 @@ void LaserUpdate::setDecayFrames( UnsignedInt decayFrames ) } } - //------------------------------------------------------------------------------------------------- -void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, const Coord3D *endPos, Int sizeDeltaFrames ) +void LaserRadiusUpdate::initRadius( Int sizeDeltaFrames ) { - const LaserUpdateModuleData *data = getLaserUpdateModuleData(); - ParticleSystem *system; if( sizeDeltaFrames > 0 ) { m_widening = true; @@ -162,6 +171,40 @@ void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, cons m_decayFinishFrame = m_decayStartFrame - sizeDeltaFrames; m_currentWidthScalar = 1.0f; } +} + +//------------------------------------------------------------------------------------------------- +void LaserRadiusUpdate::xfer( Xfer *xfer ) +{ + // widening + xfer->xferBool( &m_widening ); + + // decaying + xfer->xferBool( &m_decaying ); + + // widen start frame + xfer->xferUnsignedInt( &m_widenStartFrame ); + + // widen finish frame + xfer->xferUnsignedInt( &m_widenFinishFrame ); + + // current width scalar + xfer->xferReal( &m_currentWidthScalar ); + + // decay start frame + xfer->xferUnsignedInt( &m_decayStartFrame ); + + // decay finish frame + xfer->xferUnsignedInt( &m_decayFinishFrame ); +} + +//------------------------------------------------------------------------------------------------- +void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, const Coord3D *endPos, Int sizeDeltaFrames ) +{ + const LaserUpdateModuleData *data = getLaserUpdateModuleData(); + ParticleSystem *system; + + m_laserRadius.initRadius( sizeDeltaFrames ); //Compute startPos if( parent && data->m_parentFireBoneName.isNotEmpty() ) @@ -277,7 +320,7 @@ void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, cons } //------------------------------------------------------------------------------------------------- -Real LaserUpdate::getCurrentLaserRadius() const +Real LaserUpdate::getTemplateLaserRadius() const { const Drawable *draw = getDrawable(); const LaserDrawInterface* ldi = NULL; @@ -290,12 +333,18 @@ Real LaserUpdate::getCurrentLaserRadius() const //While it appears the logic is accessing client data, it is actually accessing template module //data from the client. This value is INI constant thus can't change. It's grouped with other //laser defining attributes and having it there makes it easier for artists. - return ldi->getLaserTemplateWidth() * m_currentWidthScalar; + return ldi->getLaserTemplateWidth(); } } return 0.0f; } +//------------------------------------------------------------------------------------------------- +Real LaserUpdate::getCurrentLaserRadius() const +{ + return getTemplateLaserRadius() * getWidthScale(); +} + // ------------------------------------------------------------------------------------------------ /** CRC */ // ------------------------------------------------------------------------------------------------ @@ -338,26 +387,7 @@ void LaserUpdate::xfer( Xfer *xfer ) // target particle system id xfer->xferUser( &m_targetParticleSystemID, sizeof( ParticleSystemID ) ); - // widening - xfer->xferBool( &m_widening ); - - // decaying - xfer->xferBool( &m_decaying ); - - // widen start frame - xfer->xferUnsignedInt( &m_widenStartFrame ); - - // widen finish frame - xfer->xferUnsignedInt( &m_widenFinishFrame ); - - // current width scalar - xfer->xferReal( &m_currentWidthScalar ); - - // decay start frame - xfer->xferUnsignedInt( &m_decayStartFrame ); - - // decay finish frame - xfer->xferUnsignedInt( &m_decayFinishFrame ); + m_laserRadius.xfer( xfer ); } // end xfer diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 0db895b4d30..82aafa525ea 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -56,7 +56,6 @@ #include "GameLogic/Module/SpecialPowerModule.h" #include "GameLogic/Module/ParticleUplinkCannonUpdate.h" #include "GameLogic/Module/PhysicsUpdate.h" -#include "GameLogic/Module/LaserUpdate.h" #include "GameLogic/Module/ActiveBody.h" #ifdef RTS_INTERNAL @@ -220,6 +219,7 @@ void ParticleUplinkCannonUpdate::killEverything() TheGameClient->destroyDrawable( beam ); } m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); } TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() ); @@ -421,6 +421,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() if( update ) { update->setDecayFrames( data->m_widthGrowFrames ); + m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames ); } m_laserStatus = LASERSTATUS_DECAYING; } @@ -438,6 +439,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() { TheGameClient->destroyDrawable( beam ); m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); m_laserStatus = LASERSTATUS_DEAD; m_startAttackFrame = 0; setLogicalStatus( STATUS_IDLE ); @@ -553,8 +555,19 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() if( update ) { update->initLaser( NULL, &orbitPosition, &m_currentTargetPosition ); - scorchRadius = update->getCurrentLaserRadius() * data->m_scorchMarkScalar; - damageRadius = update->getCurrentLaserRadius() * data->m_damageRadiusScalar; + const Real visualLaserRadius = update->getCurrentLaserRadius(); + scorchRadius = visualLaserRadius * data->m_scorchMarkScalar; + + // TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025 + // Originally the damage radius was calculated with a value updated by LaserUpdate::clientUpdate(). + // To no longer rely on client updates, this class now maintains a logical copy of the visual laser radius. + m_orbitToTargetLaserRadius.updateRadius(); + const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale(); + damageRadius = logicalLaserRadius * data->m_damageRadiusScalar; +#if RETAIL_COMPATIBLE_XFER_CRC + DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius, + ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n")); +#endif } //Create scorch marks periodically @@ -910,6 +923,7 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() ); TheGameClient->destroyDrawable( beam ); m_orbitToTargetBeamID = INVALID_DRAWABLE_ID; + m_orbitToTargetLaserRadius = LaserRadiusUpdate(); } if( data->m_particleBeamLaserName.isNotEmpty() ) @@ -929,6 +943,7 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra orbitPosition.set( &m_initialTargetPosition ); orbitPosition.z += 500.0f; update->initLaser( NULL, &orbitPosition, &m_initialTargetPosition, growthFrames ); + m_orbitToTargetLaserRadius.initRadius( growthFrames ); } } } @@ -1282,7 +1297,11 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData(); // version - XferVersion currentVersion = 2; +#if RETAIL_COMPATIBLE_XFER_SAVE + const XferVersion currentVersion = 2; +#else + const XferVersion currentVersion = 4; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1383,6 +1402,11 @@ void ParticleUplinkCannonUpdate::xfer( Xfer *xfer ) // the time of the 2nd last manual target click xfer->xferUnsignedInt( &m_2ndLastDrivingClickFrame ); + if( version >= 4 ) + { + m_orbitToTargetLaserRadius.xfer( xfer ); + } + } // end xfer // ------------------------------------------------------------------------------------------------ @@ -1394,4 +1418,27 @@ 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 ) + { + Drawable* drawable = TheGameClient->findDrawableByID( m_orbitToTargetBeamID ); + if( drawable != NULL ) + { + 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\n" )); + } + } +#endif + } // end loadPostProcess From 1b4b319cacfd104dcfdbf6a211ac9258f39d68e6 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 19 May 2025 22:11:49 +0200 Subject: [PATCH 12/14] Add additional comment to GameDefines.h --- Generals/Code/GameEngine/Include/Common/GameDefines.h | 3 +++ GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Generals/Code/GameEngine/Include/Common/GameDefines.h b/Generals/Code/GameEngine/Include/Common/GameDefines.h index 58a8a57311f..adf7f742976 100644 --- a/Generals/Code/GameEngine/Include/Common/GameDefines.h +++ b/Generals/Code/GameEngine/Include/Common/GameDefines.h @@ -18,6 +18,9 @@ #pragma once +// Note: Retail compatibility must not be broken before this project officially does. +// Use RETAIL_COMPATIBLE_XFER_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. + #ifndef RETAIL_COMPATIBLE_XFER_CRC #define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 #endif diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h index 58a8a57311f..adf7f742976 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h @@ -18,6 +18,9 @@ #pragma once +// Note: Retail compatibility must not be broken before this project officially does. +// Use RETAIL_COMPATIBLE_XFER_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. + #ifndef RETAIL_COMPATIBLE_XFER_CRC #define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 #endif From c0e5400c2647f6b6ef0ea799c1714bf6089e7072 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 19 May 2025 22:14:54 +0200 Subject: [PATCH 13/14] Move GameDefines.h to Core --- Core/GameEngine/CMakeLists.txt | 2 +- .../GameEngine/Include/Common/GameDefines.h | 0 Generals/Code/GameEngine/CMakeLists.txt | 2 +- GeneralsMD/Code/GameEngine/CMakeLists.txt | 2 +- .../GameEngine/Include/Common/GameDefines.h | 30 ------------------- 5 files changed, 3 insertions(+), 33 deletions(-) rename {Generals/Code => Core}/GameEngine/Include/Common/GameDefines.h (100%) delete mode 100644 GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index 4d9b9ff3a18..35fc9a97d1e 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -42,7 +42,7 @@ set(GAMEENGINE_SRC # Include/Common/FunctionLexicon.h # Include/Common/GameAudio.h # Include/Common/GameCommon.h -# Include/Common/GameDefines.h + Include/Common/GameDefines.h # Include/Common/GameEngine.h # Include/Common/GameLOD.h # Include/Common/GameMemory.h diff --git a/Generals/Code/GameEngine/Include/Common/GameDefines.h b/Core/GameEngine/Include/Common/GameDefines.h similarity index 100% rename from Generals/Code/GameEngine/Include/Common/GameDefines.h rename to Core/GameEngine/Include/Common/GameDefines.h diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 759337ae206..f1fe224b5b2 100644 --- a/Generals/Code/GameEngine/CMakeLists.txt +++ b/Generals/Code/GameEngine/CMakeLists.txt @@ -39,7 +39,7 @@ set(GAMEENGINE_SRC Include/Common/FunctionLexicon.h Include/Common/GameAudio.h Include/Common/GameCommon.h - Include/Common/GameDefines.h +# Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h Include/Common/GameMemory.h diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 5ecb8da0462..343a0fe28f4 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -42,7 +42,7 @@ set(GAMEENGINE_SRC Include/Common/FunctionLexicon.h Include/Common/GameAudio.h Include/Common/GameCommon.h - Include/Common/GameDefines.h +# Include/Common/GameDefines.h Include/Common/GameEngine.h Include/Common/GameLOD.h Include/Common/GameMemory.h diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h b/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h deleted file mode 100644 index adf7f742976..00000000000 --- a/GeneralsMD/Code/GameEngine/Include/Common/GameDefines.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -** Command & Conquer Generals Zero Hour(tm) -** Copyright 2025 TheSuperHackers -** -** This program is free software: you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation, either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program. If not, see . -*/ - -#pragma once - -// Note: Retail compatibility must not be broken before this project officially does. -// Use RETAIL_COMPATIBLE_XFER_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. - -#ifndef RETAIL_COMPATIBLE_XFER_CRC -#define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 -#endif - -#ifndef RETAIL_COMPATIBLE_XFER_SAVE -#define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04 -#endif From 83f8c8b644b3222fcd8a24900b72571594ba9a85 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Wed, 28 May 2025 19:46:23 +0200 Subject: [PATCH 14/14] Rename RETAIL_COMPATIBLE_CRC --- Core/GameEngine/Include/Common/GameDefines.h | 6 +++--- .../GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/GameEngine/Include/Common/GameDefines.h b/Core/GameEngine/Include/Common/GameDefines.h index adf7f742976..0cc57e7b299 100644 --- a/Core/GameEngine/Include/Common/GameDefines.h +++ b/Core/GameEngine/Include/Common/GameDefines.h @@ -19,10 +19,10 @@ #pragma once // Note: Retail compatibility must not be broken before this project officially does. -// Use RETAIL_COMPATIBLE_XFER_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. +// Use RETAIL_COMPATIBLE_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. -#ifndef RETAIL_COMPATIBLE_XFER_CRC -#define RETAIL_COMPATIBLE_XFER_CRC (1) // Game is expected to be Xfer CRC compatible with retail Generals 1.08, Zero Hour 1.04 +#ifndef RETAIL_COMPATIBLE_CRC +#define RETAIL_COMPATIBLE_CRC (1) // Game is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04 #endif #ifndef RETAIL_COMPATIBLE_XFER_SAVE diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp index 82aafa525ea..b3c2038a9e5 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp @@ -564,7 +564,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update() m_orbitToTargetLaserRadius.updateRadius(); const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale(); damageRadius = logicalLaserRadius * data->m_damageRadiusScalar; -#if RETAIL_COMPATIBLE_XFER_CRC +#if RETAIL_COMPATIBLE_CRC DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius, ("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n")); #endif