diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp index 810cbb20aaf..8a9b3e94a6b 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp @@ -34,6 +34,7 @@ #include "Common/Thing.h" #include "Common/ThingFactory.h" #include "Common/GameAudio.h" +#include "Common/GameState.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" #include "GameLogic/Weapon.h" @@ -106,7 +107,12 @@ W3DTankDraw::W3DTankDraw( Thing *thing, const ModuleData* moduleData ) m_lastDirection.y=0.0f; m_lastDirection.z=0.0f; - createTreadEmitters(); + // TheSuperHackers @bugfix stephanmeesters 20/02/2026 + // If loading from savegame, delay non-saveable emitter creation until postProcess. + if (TheGameState == nullptr || TheGameState->isInLoadGame() == FALSE) + { + createTreadEmitters(); + } } //------------------------------------------------------------------------------------------------- @@ -435,8 +441,6 @@ void W3DTankDraw::loadPostProcess( void ) // extend base class W3DModelDraw::loadPostProcess(); - // toss any existing tread emitters and re-create 'em (since this module expects 'em to always be around) - tossTreadEmitters(); createTreadEmitters(); } diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp index d1dab26b26b..9844beab679 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp @@ -32,6 +32,7 @@ #include "Common/Thing.h" #include "Common/ThingFactory.h" #include "Common/GameAudio.h" +#include "Common/GameState.h" #include "Common/GlobalData.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" @@ -119,7 +120,12 @@ m_prevRenderObj(nullptr) m_treadCount=0; - createTreadEmitters(); + // TheSuperHackers @bugfix stephanmeesters 20/02/2026 + // If loading from savegame, delay non-saveable emitter creation until postProcess. + if (TheGameState == nullptr || TheGameState->isInLoadGame() == FALSE) + { + createTreadEmitters(); + } } //------------------------------------------------------------------------------------------------- @@ -761,8 +767,6 @@ void W3DTankTruckDraw::loadPostProcess( void ) // toss any existing wheel emitters (no need to re-create; we'll do that on demand) tossWheelEmitters(); - // toss any existing tread emitters and re-create 'em (since this module expects 'em to always be around) - tossTreadEmitters(); createTreadEmitters(); } diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AutoHealBehavior.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AutoHealBehavior.h index a05c750670d..9643bb02eba 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AutoHealBehavior.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AutoHealBehavior.h @@ -108,9 +108,7 @@ class AutoHealBehaviorModuleData : public UpdateModuleData //------------------------------------------------------------------------------------------------- class AutoHealBehavior : public UpdateModule, public UpgradeMux, - public DamageModuleInterface -{ - + public DamageModuleInterface { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AutoHealBehavior, "AutoHealBehavior" ) MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AutoHealBehavior, AutoHealBehaviorModuleData ) @@ -174,6 +172,7 @@ class AutoHealBehavior : public UpdateModule, private: void pulseHealObject( Object *obj ); + void createEmitters(); ParticleSystemID m_radiusParticleSystemID; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/GrantStealthBehavior.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/GrantStealthBehavior.h index d7863c4756f..b8bf166210c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/GrantStealthBehavior.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/GrantStealthBehavior.h @@ -101,6 +101,8 @@ class GrantStealthBehavior : public UpdateModule private: void grantStealthToObject( Object *obj ); + void createEmitters(); + ParticleSystemID m_radiusParticleSystemID; Real m_currentScanRadius; }; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp index 948120ac01e..91306bd8803 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp @@ -34,6 +34,7 @@ #include "Common/ThingTemplate.h" #include "Common/INI.h" #include "Common/Player.h" +#include "Common/GameState.h" #include "Common/Xfer.h" #include "GameClient/ParticleSys.h" #include "GameClient/Anim2D.h" @@ -94,20 +95,12 @@ AutoHealBehavior::AutoHealBehavior( Thing *thing, const ModuleData* moduleData ) m_radiusParticleSystemID = INVALID_PARTICLE_SYSTEM_ID; m_soonestHealFrame = 0; m_stopped = false; - Object *obj = getObject(); + // TheSuperHackers @bugfix stephanmeesters 20/02/2026 + // If loading from savegame, delay non-saveable emitter creation until postProcess. + if (TheGameState == nullptr || TheGameState->isInLoadGame() == FALSE) { - if( d->m_radiusParticleSystemTmpl ) - { - ParticleSystem *particleSystem; - - particleSystem = TheParticleSystemManager->createParticleSystem( d->m_radiusParticleSystemTmpl ); - if( particleSystem ) - { - particleSystem->setPosition( obj->getPosition() ); - m_radiusParticleSystemID = particleSystem->getSystemID(); - } - } + createEmitters(); } if (d->m_initiallyActive) @@ -373,4 +366,22 @@ void AutoHealBehavior::loadPostProcess( void ) // extend base class UpgradeMux::upgradeMuxLoadPostProcess(); + createEmitters(); + +} + +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +void AutoHealBehavior::createEmitters( void ) +{ + const AutoHealBehaviorModuleData *d = getAutoHealBehaviorModuleData(); + if( m_radiusParticleSystemID == INVALID_PARTICLE_SYSTEM_ID && d->m_radiusParticleSystemTmpl ) + { + ParticleSystem *particleSystem = TheParticleSystemManager->createParticleSystem(d->m_radiusParticleSystemTmpl); + if( particleSystem ) + { + particleSystem->setPosition( getObject()->getPosition() ); + m_radiusParticleSystemID = particleSystem->getSystemID(); + } + } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/GrantStealthBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/GrantStealthBehavior.cpp index 54a40ee733c..d50beb2c719 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/GrantStealthBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/GrantStealthBehavior.cpp @@ -33,6 +33,7 @@ #include "Common/ThingTemplate.h" #include "Common/INI.h" #include "Common/Player.h" +#include "Common/GameState.h" #include "Common/Xfer.h" #include "GameClient/ParticleSys.h" #include "GameClient/Anim2D.h" @@ -96,21 +97,11 @@ GrantStealthBehavior::GrantStealthBehavior( Thing *thing, const ModuleData* modu m_currentScanRadius = d->m_startRadius; - - Object *obj = getObject(); - + // TheSuperHackers @bugfix stephanmeesters 20/02/2026 + // If loading from savegame, delay non-saveable emitter creation until postProcess. + if ( TheGameState == nullptr || TheGameState->isInLoadGame() == FALSE ) { - if( d->m_radiusParticleSystemTmpl ) - { - ParticleSystem *particleSystem; - - particleSystem = TheParticleSystemManager->createParticleSystem( d->m_radiusParticleSystemTmpl ); - if( particleSystem ) - { - particleSystem->setPosition( obj->getPosition() ); - m_radiusParticleSystemID = particleSystem->getSystemID(); - } - } + createEmitters(); } setWakeFrame( getObject(), UPDATE_SLEEP_NONE ); @@ -246,5 +237,21 @@ void GrantStealthBehavior::loadPostProcess( void ) // extend base class UpdateModule::loadPostProcess(); + createEmitters(); +} +// ------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------ +void GrantStealthBehavior::createEmitters( void ) +{ + const GrantStealthBehaviorModuleData *d = getGrantStealthBehaviorModuleData(); + if( m_radiusParticleSystemID == INVALID_PARTICLE_SYSTEM_ID && d->m_radiusParticleSystemTmpl ) + { + ParticleSystem *particleSystem = TheParticleSystemManager->createParticleSystem(d->m_radiusParticleSystemTmpl); + if( particleSystem ) + { + particleSystem->setPosition( getObject()->getPosition() ); + m_radiusParticleSystemID = particleSystem->getSystemID(); + } + } }