Skip to content

Commit ef17abf

Browse files
authored
[GEN][ZH] Decouple the Game Logic update in ParticleUplinkCannonUpdate from the Orbit To Ground Laser drawable (#976)
1 parent 08b06e3 commit ef17abf

File tree

2 files changed

+112
-84
lines changed

2 files changed

+112
-84
lines changed

Generals/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp

Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -211,16 +211,16 @@ void ParticleUplinkCannonUpdate::killEverything()
211211
removeAllEffects();
212212

213213
//This laser is independent from the other effects and needs to be specially handled.
214-
if( m_orbitToTargetBeamID )
214+
if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
215215
{
216216
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
217217
if( beam )
218218
{
219219
TheGameClient->destroyDrawable( beam );
220220
}
221221
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
222-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
223222
}
223+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
224224

225225
TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() );
226226
TheAudio->removeAudioEvent( m_unpackToReadySound.getPlayingHandle() );
@@ -410,40 +410,43 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
410410
break;
411411
case LASERSTATUS_BORN:
412412
{
413-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
414-
if( beam )
413+
if( orbitalDecayStart <= now )
415414
{
416-
//m_annihilationSound.setPosition( beam->getPosition() );
417-
if( orbitalDecayStart <= now )
415+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
416+
if( beam )
418417
{
418+
//m_annihilationSound.setPosition( beam->getPosition() );
419419
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
420420
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
421421
if( update )
422422
{
423423
update->setDecayFrames( data->m_widthGrowFrames );
424-
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
425424
}
426-
m_laserStatus = LASERSTATUS_DECAYING;
427425
}
426+
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
427+
m_laserStatus = LASERSTATUS_DECAYING;
428428
}
429429
break;
430430
}
431431
case LASERSTATUS_DECAYING:
432432
{
433-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
434-
if( beam )
433+
if( orbitalDeathFrame <= now )
435434
{
436-
//m_annihilationSound.setPosition( beam->getPosition() );
437435
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
438-
if( orbitalDeathFrame <= now )
436+
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
439437
{
440-
TheGameClient->destroyDrawable( beam );
438+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
439+
if( beam )
440+
{
441+
//m_annihilationSound.setPosition( beam->getPosition() );
442+
TheGameClient->destroyDrawable( beam );
443+
}
441444
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
442-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
443-
m_laserStatus = LASERSTATUS_DEAD;
444-
m_startAttackFrame = 0;
445-
setLogicalStatus( STATUS_IDLE );
446445
}
446+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
447+
m_laserStatus = LASERSTATUS_DEAD;
448+
m_startAttackFrame = 0;
449+
setLogicalStatus( STATUS_IDLE );
447450
}
448451
break;
449452
}
@@ -452,8 +455,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
452455
break;
453456
}
454457

455-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
456-
if( beam && orbitalBirthFrame <= now && now <= orbitalDeathFrame )
458+
if( orbitalBirthFrame <= now && now < orbitalDeathFrame )
457459
{
458460

459461
if( !m_manualTargetMode )
@@ -548,27 +550,35 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
548550

549551
Real scorchRadius = 0.0f;
550552
Real damageRadius = 0.0f;
553+
Real templateLaserRadius = 13.0f;
554+
Real visualLaserRadius = 0.0f;
551555

552556
//Reset the laser position
553-
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
554-
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
555-
if( update )
557+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
558+
if ( beam )
556559
{
557-
update->initLaser( NULL, &orbitPosition, &m_currentTargetPosition );
558-
const Real visualLaserRadius = update->getCurrentLaserRadius();
559-
scorchRadius = visualLaserRadius * data->m_scorchMarkScalar;
560-
561-
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
562-
// Originally the damage radius was calculated with a value updated by LaserUpdate::clientUpdate().
563-
// To no longer rely on client updates, this class now maintains a logical copy of the visual laser radius.
564-
m_orbitToTargetLaserRadius.updateRadius();
565-
const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale();
566-
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
567-
#if RETAIL_COMPATIBLE_CRC
568-
DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius,
569-
("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n"));
570-
#endif
560+
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
561+
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
562+
if( update )
563+
{
564+
update->initLaser( NULL, &orbitPosition, &m_currentTargetPosition );
565+
// TheSuperHackers @logic-client-separation The GameLogic has a dependency on this drawable.
566+
// The logical laser radius for the damage should probably be part of ParticleUplinkCannonUpdateModuleData.
567+
templateLaserRadius = update->getTemplateLaserRadius();
568+
visualLaserRadius = update->getCurrentLaserRadius();
569+
}
571570
}
571+
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
572+
// Originally the damageRadius was calculated with a value updated by LaserUpdate::clientUpdate.
573+
// To no longer rely on GameClient updates, this class now maintains a copy of the LaserRadiusUpdate.
574+
m_orbitToTargetLaserRadius.updateRadius();
575+
const Real logicalLaserRadius = templateLaserRadius * m_orbitToTargetLaserRadius.getWidthScale();
576+
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
577+
scorchRadius = logicalLaserRadius * data->m_scorchMarkScalar;
578+
#if defined(RETAIL_COMPATIBLE_CRC)
579+
DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius,
580+
("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n"));
581+
#endif
572582

573583
//Create scorch marks periodically
574584
if( m_nextScorchMarkFrame <= now )
@@ -917,13 +927,15 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
917927
{
918928
const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData();
919929

920-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
921-
if( beam )
930+
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
922931
{
923-
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
924-
TheGameClient->destroyDrawable( beam );
932+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
933+
if( beam )
934+
{
935+
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
936+
TheGameClient->destroyDrawable( beam );
937+
}
925938
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
926-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
927939
}
928940

929941
if( data->m_particleBeamLaserName.isNotEmpty() )
@@ -943,7 +955,6 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
943955
orbitPosition.set( &m_initialTargetPosition );
944956
orbitPosition.z += 500.0f;
945957
update->initLaser( NULL, &orbitPosition, &m_initialTargetPosition, growthFrames );
946-
m_orbitToTargetLaserRadius.initRadius( growthFrames );
947958
}
948959
}
949960
}
@@ -954,6 +965,9 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
954965
m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) );
955966
}
956967
}
968+
969+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
970+
m_orbitToTargetLaserRadius.initRadius( growthFrames );
957971
}
958972

959973
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ParticleUplinkCannonUpdate.cpp

Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,16 @@ void ParticleUplinkCannonUpdate::killEverything()
212212
removeAllEffects();
213213

214214
//This laser is independent from the other effects and needs to be specially handled.
215-
if( m_orbitToTargetBeamID )
215+
if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
216216
{
217217
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
218218
if( beam )
219219
{
220220
TheGameClient->destroyDrawable( beam );
221221
}
222222
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
223-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
224223
}
224+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
225225

226226
TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() );
227227
TheAudio->removeAudioEvent( m_unpackToReadySound.getPlayingHandle() );
@@ -457,40 +457,43 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
457457
break;
458458
case LASERSTATUS_BORN:
459459
{
460-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
461-
if( beam )
460+
if( orbitalDecayStart <= now )
462461
{
463-
//m_annihilationSound.setPosition( beam->getPosition() );
464-
if( orbitalDecayStart <= now )
462+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
463+
if( beam )
465464
{
465+
//m_annihilationSound.setPosition( beam->getPosition() );
466466
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
467467
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
468468
if( update )
469469
{
470470
update->setDecayFrames( data->m_widthGrowFrames );
471-
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
472471
}
473-
m_laserStatus = LASERSTATUS_DECAYING;
474472
}
473+
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
474+
m_laserStatus = LASERSTATUS_DECAYING;
475475
}
476476
break;
477477
}
478478
case LASERSTATUS_DECAYING:
479479
{
480-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
481-
if( beam )
480+
if( orbitalDeathFrame <= now )
482481
{
483-
//m_annihilationSound.setPosition( beam->getPosition() );
484482
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
485-
if( orbitalDeathFrame <= now )
483+
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
486484
{
487-
TheGameClient->destroyDrawable( beam );
485+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
486+
if( beam )
487+
{
488+
//m_annihilationSound.setPosition( beam->getPosition() );
489+
TheGameClient->destroyDrawable( beam );
490+
}
488491
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
489-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
490-
m_laserStatus = LASERSTATUS_DEAD;
491-
m_startAttackFrame = 0;
492-
setLogicalStatus( STATUS_IDLE );
493492
}
493+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
494+
m_laserStatus = LASERSTATUS_DEAD;
495+
m_startAttackFrame = 0;
496+
setLogicalStatus( STATUS_IDLE );
494497
}
495498
break;
496499
}
@@ -499,8 +502,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
499502
break;
500503
}
501504

502-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
503-
if( beam && orbitalBirthFrame <= now && now <= orbitalDeathFrame )
505+
if( orbitalBirthFrame <= now && now < orbitalDeathFrame )
504506
{
505507

506508
if( !m_manualTargetMode && !m_scriptedWaypointMode )
@@ -609,27 +611,35 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
609611

610612
Real scorchRadius = 0.0f;
611613
Real damageRadius = 0.0f;
614+
Real templateLaserRadius = 13.0f;
615+
Real visualLaserRadius = 0.0f;
612616

613617
//Reset the laser position
614-
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
615-
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
616-
if( update )
618+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
619+
if ( beam )
617620
{
618-
update->initLaser( NULL, NULL, &orbitPosition, &m_currentTargetPosition, "" );
619-
const Real visualLaserRadius = update->getCurrentLaserRadius();
620-
scorchRadius = visualLaserRadius * data->m_scorchMarkScalar;
621-
622-
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
623-
// Originally the damage radius was calculated with a value updated by LaserUpdate::clientUpdate().
624-
// To no longer rely on client updates, this class now maintains a logical copy of the visual laser radius.
625-
m_orbitToTargetLaserRadius.updateRadius();
626-
const Real logicalLaserRadius = update->getTemplateLaserRadius() * m_orbitToTargetLaserRadius.getWidthScale();
627-
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
628-
#if RETAIL_COMPATIBLE_XFER_CRC
629-
DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius,
630-
("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n"));
631-
#endif
621+
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
622+
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
623+
if( update )
624+
{
625+
update->initLaser( NULL, NULL, &orbitPosition, &m_currentTargetPosition, "" );
626+
// TheSuperHackers @logic-client-separation The GameLogic has a dependency on this drawable.
627+
// The logical laser radius for the damage should probably be part of ParticleUplinkCannonUpdateModuleData.
628+
templateLaserRadius = update->getTemplateLaserRadius();
629+
visualLaserRadius = update->getCurrentLaserRadius();
630+
}
632631
}
632+
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
633+
// Originally the damageRadius was calculated with a value updated by LaserUpdate::clientUpdate.
634+
// To no longer rely on GameClient updates, this class now maintains a copy of the LaserRadiusUpdate.
635+
m_orbitToTargetLaserRadius.updateRadius();
636+
const Real logicalLaserRadius = templateLaserRadius * m_orbitToTargetLaserRadius.getWidthScale();
637+
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
638+
scorchRadius = logicalLaserRadius * data->m_scorchMarkScalar;
639+
#if defined(RETAIL_COMPATIBLE_CRC)
640+
DEBUG_ASSERTCRASH(logicalLaserRadius == visualLaserRadius,
641+
("ParticleUplinkCannonUpdate's laser radius does not match LaserUpdate's laser radius - will cause mismatch in VS6 retail compatible builds\n"));
642+
#endif
633643

634644
//Create scorch marks periodically
635645
if( m_nextScorchMarkFrame <= now )
@@ -988,13 +998,15 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
988998
{
989999
const ParticleUplinkCannonUpdateModuleData *data = getParticleUplinkCannonUpdateModuleData();
9901000

991-
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
992-
if( beam )
1001+
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
9931002
{
994-
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
995-
TheGameClient->destroyDrawable( beam );
1003+
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
1004+
if( beam )
1005+
{
1006+
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
1007+
TheGameClient->destroyDrawable( beam );
1008+
}
9961009
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
997-
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
9981010
}
9991011

10001012
if( data->m_particleBeamLaserName.isNotEmpty() )
@@ -1014,7 +1026,6 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
10141026
orbitPosition.set( &m_initialTargetPosition );
10151027
orbitPosition.z += 500.0f;
10161028
update->initLaser( NULL, NULL, &orbitPosition, &m_initialTargetPosition, "", growthFrames );
1017-
m_orbitToTargetLaserRadius.initRadius( growthFrames );
10181029
}
10191030
}
10201031
}
@@ -1025,6 +1036,9 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
10251036
m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) );
10261037
}
10271038
}
1039+
1040+
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
1041+
m_orbitToTargetLaserRadius.initRadius( growthFrames );
10281042
}
10291043

10301044
//-------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)