Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -211,16 +211,16 @@ void ParticleUplinkCannonUpdate::killEverything()
removeAllEffects();

//This laser is independent from the other effects and needs to be specially handled.
if( m_orbitToTargetBeamID )
if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
}
m_orbitToTargetLaserRadius = LaserRadiusUpdate();

TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() );
TheAudio->removeAudioEvent( m_unpackToReadySound.getPlayingHandle() );
Expand Down Expand Up @@ -410,40 +410,43 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
break;
case LASERSTATUS_BORN:
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if( orbitalDecayStart <= now )
{
//m_annihilationSound.setPosition( beam->getPosition() );
if( orbitalDecayStart <= now )
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
//m_annihilationSound.setPosition( beam->getPosition() );
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
{
update->setDecayFrames( data->m_widthGrowFrames );
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
}
m_laserStatus = LASERSTATUS_DECAYING;
}
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
m_laserStatus = LASERSTATUS_DECAYING;
}
break;
}
case LASERSTATUS_DECAYING:
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if( orbitalDeathFrame <= now )
{
//m_annihilationSound.setPosition( beam->getPosition() );
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
if( orbitalDeathFrame <= now )
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
TheGameClient->destroyDrawable( beam );
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
//m_annihilationSound.setPosition( beam->getPosition() );
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_laserStatus = LASERSTATUS_DEAD;
m_startAttackFrame = 0;
setLogicalStatus( STATUS_IDLE );
}
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_laserStatus = LASERSTATUS_DEAD;
m_startAttackFrame = 0;
setLogicalStatus( STATUS_IDLE );
}
break;
}
Expand All @@ -452,8 +455,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
break;
}

Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam && orbitalBirthFrame <= now && now <= orbitalDeathFrame )
if( orbitalBirthFrame <= now && now < orbitalDeathFrame )

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to change this condition from now <= orbitalDeathFrame to now < orbitalDeathFrame.

now <= orbitalDeathFrame is slightly incorrect and mismatches with retail (when the drawable test is gone), because it contradicts the condition above:

case LASERSTATUS_DECAYING:
{
  if( orbitalDeathFrame <= now )

{

if( !m_manualTargetMode )
Expand Down Expand Up @@ -548,27 +550,35 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()

Real scorchRadius = 0.0f;
Real damageRadius = 0.0f;
Real templateLaserRadius = 13.0f;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This magic value refers to the diameter in

Object ParticleUplinkCannon_OrbitalLaser
  Draw = W3DLaserDraw ModuleTag_01
    OuterBeamWidth = 26.0            ;The total width of beam

Real visualLaserRadius = 0.0f;

//Reset the laser position
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if ( beam )
{
update->initLaser( NULL, &orbitPosition, &m_currentTargetPosition );
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_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
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
{
update->initLaser( NULL, &orbitPosition, &m_currentTargetPosition );
// TheSuperHackers @logic-client-separation The GameLogic has a dependency on this drawable.
// The logical laser radius for the damage should probably be part of ParticleUplinkCannonUpdateModuleData.
templateLaserRadius = update->getTemplateLaserRadius();
visualLaserRadius = update->getCurrentLaserRadius();
}
}
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
// Originally the damageRadius was calculated with a value updated by LaserUpdate::clientUpdate.
// To no longer rely on GameClient updates, this class now maintains a copy of the LaserRadiusUpdate.
m_orbitToTargetLaserRadius.updateRadius();
const Real logicalLaserRadius = templateLaserRadius * m_orbitToTargetLaserRadius.getWidthScale();
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
scorchRadius = logicalLaserRadius * data->m_scorchMarkScalar;
#if defined(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

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

Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
TheGameClient->destroyDrawable( beam );
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
}

if( data->m_particleBeamLaserName.isNotEmpty() )
Expand All @@ -943,7 +955,6 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
orbitPosition.set( &m_initialTargetPosition );
orbitPosition.z += 500.0f;
update->initLaser( NULL, &orbitPosition, &m_initialTargetPosition, growthFrames );
m_orbitToTargetLaserRadius.initRadius( growthFrames );
}
}
}
Expand All @@ -954,6 +965,9 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) );
}
}

m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_orbitToTargetLaserRadius.initRadius( growthFrames );
}

//-------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,16 @@ void ParticleUplinkCannonUpdate::killEverything()
removeAllEffects();

//This laser is independent from the other effects and needs to be specially handled.
if( m_orbitToTargetBeamID )
if( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
}
m_orbitToTargetLaserRadius = LaserRadiusUpdate();

TheAudio->removeAudioEvent( m_powerupSound.getPlayingHandle() );
TheAudio->removeAudioEvent( m_unpackToReadySound.getPlayingHandle() );
Expand Down Expand Up @@ -457,40 +457,43 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
break;
case LASERSTATUS_BORN:
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if( orbitalDecayStart <= now )
{
//m_annihilationSound.setPosition( beam->getPosition() );
if( orbitalDecayStart <= now )
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
//m_annihilationSound.setPosition( beam->getPosition() );
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
{
update->setDecayFrames( data->m_widthGrowFrames );
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
}
m_laserStatus = LASERSTATUS_DECAYING;
}
m_orbitToTargetLaserRadius.setDecayFrames( data->m_widthGrowFrames );
m_laserStatus = LASERSTATUS_DECAYING;
}
break;
}
case LASERSTATUS_DECAYING:
{
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if( orbitalDeathFrame <= now )
{
//m_annihilationSound.setPosition( beam->getPosition() );
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
if( orbitalDeathFrame <= now )
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
TheGameClient->destroyDrawable( beam );
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
//m_annihilationSound.setPosition( beam->getPosition() );
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_laserStatus = LASERSTATUS_DEAD;
m_startAttackFrame = 0;
setLogicalStatus( STATUS_IDLE );
}
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_laserStatus = LASERSTATUS_DEAD;
m_startAttackFrame = 0;
setLogicalStatus( STATUS_IDLE );
}
break;
}
Expand All @@ -499,8 +502,7 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()
break;
}

Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam && orbitalBirthFrame <= now && now <= orbitalDeathFrame )
if( orbitalBirthFrame <= now && now < orbitalDeathFrame )
{

if( !m_manualTargetMode && !m_scriptedWaypointMode )
Expand Down Expand Up @@ -609,27 +611,35 @@ UpdateSleepTime ParticleUplinkCannonUpdate::update()

Real scorchRadius = 0.0f;
Real damageRadius = 0.0f;
Real templateLaserRadius = 13.0f;
Real visualLaserRadius = 0.0f;

//Reset the laser position
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if ( beam )
{
update->initLaser( NULL, NULL, &orbitPosition, &m_currentTargetPosition, "" );
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
static NameKeyType nameKeyClientUpdate = NAMEKEY( "LaserUpdate" );
LaserUpdate *update = (LaserUpdate*)beam->findClientUpdateModule( nameKeyClientUpdate );
if( update )
{
update->initLaser( NULL, NULL, &orbitPosition, &m_currentTargetPosition, "" );
// TheSuperHackers @logic-client-separation The GameLogic has a dependency on this drawable.
// The logical laser radius for the damage should probably be part of ParticleUplinkCannonUpdateModuleData.
templateLaserRadius = update->getTemplateLaserRadius();
visualLaserRadius = update->getCurrentLaserRadius();
}
}
// TheSuperHackers @refactor helmutbuhler/xezon 17/05/2025
// Originally the damageRadius was calculated with a value updated by LaserUpdate::clientUpdate.
// To no longer rely on GameClient updates, this class now maintains a copy of the LaserRadiusUpdate.
m_orbitToTargetLaserRadius.updateRadius();
const Real logicalLaserRadius = templateLaserRadius * m_orbitToTargetLaserRadius.getWidthScale();
damageRadius = logicalLaserRadius * data->m_damageRadiusScalar;
scorchRadius = logicalLaserRadius * data->m_scorchMarkScalar;
#if defined(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

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

Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
if ( m_orbitToTargetBeamID != INVALID_DRAWABLE_ID )
{
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
TheGameClient->destroyDrawable( beam );
Drawable *beam = TheGameClient->findDrawableByID( m_orbitToTargetBeamID );
if( beam )
{
TheAudio->removeAudioEvent( m_annihilationSound.getPlayingHandle() );
TheGameClient->destroyDrawable( beam );
}
m_orbitToTargetBeamID = INVALID_DRAWABLE_ID;
m_orbitToTargetLaserRadius = LaserRadiusUpdate();
}

if( data->m_particleBeamLaserName.isNotEmpty() )
Expand All @@ -1014,7 +1026,6 @@ 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 );
}
}
}
Expand All @@ -1025,6 +1036,9 @@ void ParticleUplinkCannonUpdate::createOrbitToTargetLaser( UnsignedInt growthFra
m_annihilationSound.setPlayingHandle( TheAudio->addAudioEvent( &m_annihilationSound ) );
}
}

m_orbitToTargetLaserRadius = LaserRadiusUpdate();
m_orbitToTargetLaserRadius.initRadius( growthFrames );
}

//-------------------------------------------------------------------------------------------------
Expand Down
Loading