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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Core/GameEngine/Source/GameClient/System/ParticleSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3346,6 +3346,8 @@ void ParticleSystemManager::xfer( Xfer *xfer )
}
else
{
DEBUG_ASSERTCRASH(m_allParticleSystemList.size()==0, ("ParticleSystemManager: particle systems list must be empty at start of xfer-load."));

const ParticleSystemTemplate *systemTemplate;

// read each particle system
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ W3DTankDraw::W3DTankDraw( Thing *thing, const ModuleData* moduleData )
m_lastDirection.y=0.0f;
m_lastDirection.z=0.0f;

createTreadEmitters();
}

//-------------------------------------------------------------------------------------------------
Expand All @@ -126,27 +125,33 @@ void W3DTankDraw::tossTreadEmitters()

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void W3DTankDraw::createTreadEmitters()
static ParticleSystemID createParticleSystem( const AsciiString &name, const Drawable *drawable )
{
const AsciiString *treadDebrisNames[2];
static_assert(ARRAY_SIZE(treadDebrisNames) == ARRAY_SIZE(m_treadDebrisIDs), "Array size must match");
treadDebrisNames[0] = &getW3DTankDrawModuleData()->m_treadDebrisNameLeft;
treadDebrisNames[1] = &getW3DTankDrawModuleData()->m_treadDebrisNameRight;
const ParticleSystemTemplate *sysTemplate = TheParticleSystemManager->findTemplate(name);
ParticleSystem *particleSys = TheParticleSystemManager->createParticleSystem( sysTemplate );
if (!particleSys)
return INVALID_PARTICLE_SYSTEM_ID;

particleSys->attachToDrawable(drawable);
// important: mark it as do-not-save, since we'll just re-create it when we reload.
particleSys->setSaveable(FALSE);
// they come into being stopped.
particleSys->stop();

return particleSys->getSystemID();
}

for (size_t i = 0; i < ARRAY_SIZE(m_treadDebrisIDs); ++i)
void W3DTankDraw::createTreadEmitters()
{
if (getW3DTankDrawModuleData())
{
if (m_treadDebrisIDs[i] == INVALID_PARTICLE_SYSTEM_ID)
if (m_treadDebrisIDs[0] == INVALID_PARTICLE_SYSTEM_ID)
{
if (const ParticleSystemTemplate *sysTemplate = TheParticleSystemManager->findTemplate(*treadDebrisNames[i]))
{
ParticleSystem *particleSys = TheParticleSystemManager->createParticleSystem( sysTemplate );
particleSys->attachToDrawable(getDrawable());
// important: mark it as do-not-save, since we'll just re-create it when we reload.
particleSys->setSaveable(FALSE);
// they come into being stopped.
particleSys->stop();
m_treadDebrisIDs[i] = particleSys->getSystemID();
}
m_treadDebrisIDs[0] = createParticleSystem(getW3DTankDrawModuleData()->m_treadDebrisNameLeft, getDrawable());
}
if (m_treadDebrisIDs[1] == INVALID_PARTICLE_SYSTEM_ID)
{
m_treadDebrisIDs[1] = createParticleSystem(getW3DTankDrawModuleData()->m_treadDebrisNameRight, getDrawable());
}
}
}
Expand Down Expand Up @@ -310,6 +315,9 @@ void W3DTankDraw::doDrawModule(const Matrix3D* transformMtx)
if (obj == nullptr)
return;

// TheSuperHackers @bugfix stephanmeesters 14/03/2026 Delay emitter creation until draw
createTreadEmitters();

// get object physics state
PhysicsBehavior *physics = obj->getPhysics();
if (physics == nullptr)
Expand Down Expand Up @@ -435,8 +443,6 @@ void W3DTankDraw::loadPostProcess()
// 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();

}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ m_prevRenderObj(nullptr)

m_treadCount=0;

createTreadEmitters();
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -182,30 +181,33 @@ void W3DTankTruckDraw::setFullyObscuredByShroud(Bool fullyObscured)

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
static ParticleSystemID createParticleSystem( const AsciiString &name, const Drawable *drawable )
{
const ParticleSystemTemplate *sysTemplate = TheParticleSystemManager->findTemplate(name);
ParticleSystem *particleSys = TheParticleSystemManager->createParticleSystem( sysTemplate );
if (!particleSys)
return INVALID_PARTICLE_SYSTEM_ID;

particleSys->attachToDrawable(drawable);
// important: mark it as do-not-save, since we'll just re-create it when we reload.
particleSys->setSaveable(FALSE);
// they come into being stopped.
particleSys->stop();

return particleSys->getSystemID();
}

void W3DTankTruckDraw::createTreadEmitters()
{
if (getW3DTankTruckDrawModuleData())
{
const AsciiString *treadDebrisNames[2];
static_assert(ARRAY_SIZE(treadDebrisNames) == ARRAY_SIZE(m_treadDebrisIDs), "Array size must match");
treadDebrisNames[0] = &getW3DTankTruckDrawModuleData()->m_treadDebrisNameLeft;
treadDebrisNames[1] = &getW3DTankTruckDrawModuleData()->m_treadDebrisNameRight;

for (size_t i = 0; i < ARRAY_SIZE(m_treadDebrisIDs); ++i)
if (m_treadDebrisIDs[0] == INVALID_PARTICLE_SYSTEM_ID)
{
if (m_treadDebrisIDs[i] == INVALID_PARTICLE_SYSTEM_ID)
{
if (const ParticleSystemTemplate *sysTemplate = TheParticleSystemManager->findTemplate(*treadDebrisNames[i]))
{
ParticleSystem *particleSys = TheParticleSystemManager->createParticleSystem( sysTemplate );
particleSys->attachToDrawable(getDrawable());
// important: mark it as do-not-save, since we'll just re-create it when we reload.
particleSys->setSaveable(FALSE);
// they come into being stopped.
particleSys->stop();
m_treadDebrisIDs[i] = particleSys->getSystemID();
}
}
m_treadDebrisIDs[0] = createParticleSystem(getW3DTankTruckDrawModuleData()->m_treadDebrisNameLeft, getDrawable());
}
if (m_treadDebrisIDs[1] == INVALID_PARTICLE_SYSTEM_ID)
{
m_treadDebrisIDs[1] = createParticleSystem(getW3DTankTruckDrawModuleData()->m_treadDebrisNameRight, getDrawable());
}
}
}
Expand Down Expand Up @@ -504,6 +506,9 @@ void W3DTankTruckDraw::doDrawModule(const Matrix3D* transformMtx)
if (obj == nullptr)
return;

// TheSuperHackers @bugfix stephanmeesters 14/03/2026 Delay emitter creation until draw
createTreadEmitters();

if (getRenderObject()==nullptr) return;
if (getRenderObject() != m_prevRenderObj) {
updateBones();
Expand Down Expand Up @@ -761,8 +766,6 @@ void W3DTankTruckDraw::loadPostProcess()
// 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();

}
Original file line number Diff line number Diff line change
Expand Up @@ -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 )

Expand Down Expand Up @@ -174,6 +172,7 @@ class AutoHealBehavior : public UpdateModule,
private:

void pulseHealObject( Object *obj );
void createEmitters();

ParticleSystemID m_radiusParticleSystemID;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class GrantStealthBehavior : public UpdateModule
private:

void grantStealthToObject( Object *obj );
void createEmitters();

ParticleSystemID m_radiusParticleSystemID;
Real m_currentScanRadius;
};
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,6 @@ AutoHealBehavior::AutoHealBehavior( Thing *thing, const ModuleData* moduleData )
m_radiusParticleSystemID = INVALID_PARTICLE_SYSTEM_ID;
m_soonestHealFrame = 0;
m_stopped = false;
Object *obj = getObject();

{
if( d->m_radiusParticleSystemTmpl )
{
ParticleSystem *particleSystem;

particleSystem = TheParticleSystemManager->createParticleSystem( d->m_radiusParticleSystemTmpl );
if( particleSystem )
{
particleSystem->setPosition( obj->getPosition() );
m_radiusParticleSystemID = particleSystem->getSystemID();
}
}
}

if (d->m_initiallyActive)
{
Expand Down Expand Up @@ -194,6 +179,9 @@ UpdateSleepTime AutoHealBehavior::update()
return UPDATE_SLEEP_FOREVER;
}

// TheSuperHackers @bugfix stephanmeesters 14/03/2026 Delay emitter creation until update
createEmitters();

//DEBUG_LOG(("doing auto heal %d",TheGameLogic->getFrame()));

if( d->m_affectsWholePlayer )
Expand Down Expand Up @@ -373,4 +361,22 @@ void AutoHealBehavior::loadPostProcess()
// extend base class
UpgradeMux::upgradeMuxLoadPostProcess();

createEmitters();

}

// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
void AutoHealBehavior::createEmitters()
{
if( m_radiusParticleSystemID == INVALID_PARTICLE_SYSTEM_ID )
{
const AutoHealBehaviorModuleData *d = getAutoHealBehaviorModuleData();
ParticleSystem *particleSystem = TheParticleSystemManager->createParticleSystem(d->m_radiusParticleSystemTmpl);
if( particleSystem )
{
particleSystem->setPosition( getObject()->getPosition() );
m_radiusParticleSystemID = particleSystem->getSystemID();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,7 @@ GrantStealthBehavior::GrantStealthBehavior( Thing *thing, const ModuleData* modu

m_currentScanRadius = d->m_startRadius;


Object *obj = getObject();

{
if( d->m_radiusParticleSystemTmpl )
{
ParticleSystem *particleSystem;

particleSystem = TheParticleSystemManager->createParticleSystem( d->m_radiusParticleSystemTmpl );
if( particleSystem )
{
particleSystem->setPosition( obj->getPosition() );
m_radiusParticleSystemID = particleSystem->getSystemID();
}
}
}

setWakeFrame( getObject(), UPDATE_SLEEP_NONE );
setWakeFrame( getObject(), UPDATE_SLEEP_NONE );
}

//-------------------------------------------------------------------------------------------------
Expand All @@ -139,6 +122,9 @@ UpdateSleepTime GrantStealthBehavior::update()
if ( self->isEffectivelyDead())
return UPDATE_SLEEP_FOREVER;

// TheSuperHackers @bugfix stephanmeesters 14/03/2026 Delay emitter creation until update
createEmitters();

const GrantStealthBehaviorModuleData *d = getGrantStealthBehaviorModuleData();
// setup scan filters
PartitionFilterRelationship relationship( self, PartitionFilterRelationship::ALLOW_ALLIES );
Expand Down Expand Up @@ -246,5 +232,21 @@ void GrantStealthBehavior::loadPostProcess()
// extend base class
UpdateModule::loadPostProcess();

createEmitters();
}

// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
void GrantStealthBehavior::createEmitters()
{
if( m_radiusParticleSystemID == INVALID_PARTICLE_SYSTEM_ID )
{
const GrantStealthBehaviorModuleData *d = getGrantStealthBehaviorModuleData();
ParticleSystem *particleSystem = TheParticleSystemManager->createParticleSystem(d->m_radiusParticleSystemTmpl);
if( particleSystem )
{
particleSystem->setPosition( getObject()->getPosition() );
m_radiusParticleSystemID = particleSystem->getSystemID();
}
}
}
Loading