From a2db1909538d3e03871681a326e60fe6c425df6b Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 16 Aug 2026 17:49:41 +0200 Subject: [PATCH 1/6] test(neutronmissile): Add debug draw for nuke missile radius Can be toggled with particle path debug CTRL+SHIFT+B --- .../Update/NeutronMissileSlowDeathUpdate.cpp | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index 55d59777358..aa093f71bf1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -30,6 +30,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine #include "Common/GameState.h" +#include "Common/GlobalData.h" #include "Common/Player.h" #include "Common/Xfer.h" #include "GameClient/FXList.h" @@ -287,6 +288,55 @@ UpdateSleepTime NeutronMissileSlowDeathBehavior::update() } +#if defined(RTS_DEBUG) + +static void drawDebugRadiusRing( const Coord3D *center, Real radius, Real tileWidth, + Int numFramesDuration, const RGBColor &color ) +{ + extern void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color); + + if( radius <= 0.0f ) + return; + + // space the icons roughly one tile apart along the circumference, within sane bounds + Int segments = (Int)ceilf( (2.0f * PI * radius) / max( tileWidth, 1.0f ) * 0.5f ); + segments = clamp(1, segments, 256); + + for( Int i = 0; i < segments; ++i ) + { + Real angle = (2.0f * PI * i) / segments; + Coord3D pos; + + pos.x = center->x + radius * cosf( angle ); + pos.y = center->y + radius * sinf( angle ); + pos.z = TheTerrainLogic->getGroundHeight( pos.x, pos.y ); + + addIcon( &pos, tileWidth, numFramesDuration, color ); + } +} + +static void displayBlastRadii( Object *missile, const BlastInfo *blastInfo ) +{ + const Int duration = 60 * LOGICFRAMES_PER_SECOND; + const Real tileWidth = TheGlobalData->m_debugProjectileTileWidth; + constexpr const RGBColor innerColor = { 0.0f, 1.0f, 1.0f }; // cyan, everything in here takes full damage + constexpr const RGBColor outerColor = { 1.0f, 1.0f, 0.0f }; // yellow, damage falls off out here + + const Coord3D *missilePos = missile->getPosition(); + + if (blastInfo->maxDamage > 0.0f) + { + drawDebugRadiusRing( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); + } + + if (blastInfo->minDamage > 0.0f) + { + drawDebugRadiusRing( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); + } +} + +#endif // defined(RTS_DEBUG) + // ------------------------------------------------------------------------------------------------ /** Do a single blast for the bomb */ // ------------------------------------------------------------------------------------------------ @@ -314,6 +364,11 @@ void NeutronMissileSlowDeathBehavior::doBlast( const BlastInfo *blastInfo ) // scan objects around us and do damage to objects we have "passed over" and are behind us if( blastInfo->outerRadius ) { +#if defined(RTS_DEBUG) + if( TheGlobalData->m_debugProjectilePath ) + displayBlastRadii( missile, blastInfo ); +#endif + ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange( missilePos, blastInfo->outerRadius, FROM_CENTER_2D, From 7d8fadfe46edcb88fd610ff6d6211f27623c6bec Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 17 Aug 2026 18:48:42 +0200 Subject: [PATCH 2/6] Fix tileWidth clamp --- .../GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index aa093f71bf1..88da1685295 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -299,7 +299,8 @@ static void drawDebugRadiusRing( const Coord3D *center, Real radius, Real tileWi return; // space the icons roughly one tile apart along the circumference, within sane bounds - Int segments = (Int)ceilf( (2.0f * PI * radius) / max( tileWidth, 1.0f ) * 0.5f ); + tileWidth = max( tileWidth, 1.0f ); + Int segments = (Int)ceilf( (2.0f * PI * radius) / tileWidth * 0.5f ); segments = clamp(1, segments, 256); for( Int i = 0; i < segments; ++i ) From e07473096356c397ae56d2676bc737eed13586a1 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 17 Aug 2026 18:49:46 +0200 Subject: [PATCH 3/6] Fix blast debug draw condition --- .../Object/Update/NeutronMissileSlowDeathUpdate.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index 88da1685295..d96be4f3cde 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -325,12 +325,8 @@ static void displayBlastRadii( Object *missile, const BlastInfo *blastInfo ) const Coord3D *missilePos = missile->getPosition(); - if (blastInfo->maxDamage > 0.0f) - { drawDebugRadiusRing( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); - } - - if (blastInfo->minDamage > 0.0f) + if (blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f) { drawDebugRadiusRing( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); } From 329a7d56338a633a9b3ab0bfa0c99c50bb4fe901 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 17 Aug 2026 18:50:42 +0200 Subject: [PATCH 4/6] Remove RTS_DEBUG and rename debug functions --- .../Update/NeutronMissileSlowDeathUpdate.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index d96be4f3cde..229131925ca 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -288,9 +288,7 @@ UpdateSleepTime NeutronMissileSlowDeathBehavior::update() } -#if defined(RTS_DEBUG) - -static void drawDebugRadiusRing( const Coord3D *center, Real radius, Real tileWidth, +static void debugDrawBlastCircle( const Coord3D *center, Real radius, Real tileWidth, Int numFramesDuration, const RGBColor &color ) { extern void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color); @@ -316,7 +314,7 @@ static void drawDebugRadiusRing( const Coord3D *center, Real radius, Real tileWi } } -static void displayBlastRadii( Object *missile, const BlastInfo *blastInfo ) +static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo ) { const Int duration = 60 * LOGICFRAMES_PER_SECOND; const Real tileWidth = TheGlobalData->m_debugProjectileTileWidth; @@ -325,15 +323,13 @@ static void displayBlastRadii( Object *missile, const BlastInfo *blastInfo ) const Coord3D *missilePos = missile->getPosition(); - drawDebugRadiusRing( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); if (blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f) { - drawDebugRadiusRing( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); + debugDrawBlastCircle( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); + debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); } } -#endif // defined(RTS_DEBUG) - // ------------------------------------------------------------------------------------------------ /** Do a single blast for the bomb */ // ------------------------------------------------------------------------------------------------ @@ -363,7 +359,7 @@ void NeutronMissileSlowDeathBehavior::doBlast( const BlastInfo *blastInfo ) { #if defined(RTS_DEBUG) if( TheGlobalData->m_debugProjectilePath ) - displayBlastRadii( missile, blastInfo ); + debugDrawBlastRadii( missile, blastInfo ); #endif ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange( missilePos, From a4b8eb88274b2896c599bce84e254a2687aa15f2 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 17 Aug 2026 18:51:59 +0200 Subject: [PATCH 5/6] Return early in debugDrawBlastRadii --- .../Object/Update/NeutronMissileSlowDeathUpdate.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index 229131925ca..4422625280b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -316,6 +316,9 @@ static void debugDrawBlastCircle( const Coord3D *center, Real radius, Real tileW static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo ) { + if (!(blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f)) + return; + const Int duration = 60 * LOGICFRAMES_PER_SECOND; const Real tileWidth = TheGlobalData->m_debugProjectileTileWidth; constexpr const RGBColor innerColor = { 0.0f, 1.0f, 1.0f }; // cyan, everything in here takes full damage @@ -323,11 +326,8 @@ static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo ) const Coord3D *missilePos = missile->getPosition(); - if (blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f) - { - debugDrawBlastCircle( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); - debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); - } + debugDrawBlastCircle( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); + debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); } // ------------------------------------------------------------------------------------------------ From 025eb3384092d16df629c4773169d168495eba88 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Mon, 17 Aug 2026 19:06:18 +0200 Subject: [PATCH 6/6] Fix compile error and refactor the new code --- .../Update/NeutronMissileSlowDeathUpdate.cpp | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp index 4422625280b..8a3e971fea4 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp @@ -289,9 +289,9 @@ UpdateSleepTime NeutronMissileSlowDeathBehavior::update() } static void debugDrawBlastCircle( const Coord3D *center, Real radius, Real tileWidth, - Int numFramesDuration, const RGBColor &color ) + Int frameDuration, const RGBColor &color ) { - extern void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color); + extern void addIcon(const Coord3D *pos, Real width, Int frameDuration, RGBColor color); if( radius <= 0.0f ) return; @@ -310,24 +310,18 @@ static void debugDrawBlastCircle( const Coord3D *center, Real radius, Real tileW pos.y = center->y + radius * sinf( angle ); pos.z = TheTerrainLogic->getGroundHeight( pos.x, pos.y ); - addIcon( &pos, tileWidth, numFramesDuration, color ); + addIcon( &pos, tileWidth, frameDuration, color ); } } -static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo ) +static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo, Real tileWidth, Int frameDuration ) { - if (!(blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f)) - return; - - const Int duration = 60 * LOGICFRAMES_PER_SECOND; - const Real tileWidth = TheGlobalData->m_debugProjectileTileWidth; constexpr const RGBColor innerColor = { 0.0f, 1.0f, 1.0f }; // cyan, everything in here takes full damage constexpr const RGBColor outerColor = { 1.0f, 1.0f, 0.0f }; // yellow, damage falls off out here - const Coord3D *missilePos = missile->getPosition(); - debugDrawBlastCircle( missilePos, blastInfo->innerRadius, tileWidth, duration, innerColor ); - debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, duration, outerColor ); + debugDrawBlastCircle( missilePos, blastInfo->innerRadius, tileWidth, frameDuration, innerColor ); + debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, frameDuration, outerColor ); } // ------------------------------------------------------------------------------------------------ @@ -358,8 +352,11 @@ void NeutronMissileSlowDeathBehavior::doBlast( const BlastInfo *blastInfo ) if( blastInfo->outerRadius ) { #if defined(RTS_DEBUG) - if( TheGlobalData->m_debugProjectilePath ) - debugDrawBlastRadii( missile, blastInfo ); + if( TheGlobalData->m_debugProjectilePath && (blastInfo->maxDamage > 0.0f || blastInfo->minDamage > 0.0f) ) + { + constexpr const Int frameDuration = 60 * LOGICFRAMES_PER_SECOND; + debugDrawBlastRadii( missile, blastInfo, TheGlobalData->m_debugProjectileTileWidth, frameDuration ); + } #endif ObjectIterator *iter = ThePartitionManager->iterateObjectsInRange( missilePos,