Skip to content
Open
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 @@ -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"
Expand Down Expand Up @@ -287,6 +288,42 @@ UpdateSleepTime NeutronMissileSlowDeathBehavior::update()

}

static void debugDrawBlastCircle( const Coord3D *center, Real radius, Real tileWidth,
Int frameDuration, const RGBColor &color )
{
extern void addIcon(const Coord3D *pos, Real width, Int frameDuration, RGBColor color);

if( radius <= 0.0f )
return;

// space the icons roughly one tile apart along the circumference, within sane bounds
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 )
{
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, frameDuration, color );
}
Comment on lines +311 to +314

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Informational

2. Unclamped icon tile width 🐞 Bug ☼ Reliability

drawDebugRadiusRing() clamps tileWidth only for segment count, but passes the raw tileWidth into
addIcon(); if DebugProjectileTileWidth is configured as 0 or negative, icons become
degenerate/unintended and the ring can disappear or render incorrectly. This makes the new debug
feature fragile to configuration values.
Agent Prompt
## Issue description
`drawDebugRadiusRing()` uses `max(tileWidth, 1.0f)` to avoid divide-by-zero in segment calculation, but still calls `addIcon(..., tileWidth, ...)` with the original value.

## Issue Context
`DebugProjectileTileWidth` is parsed as a raw `Real` with no validation, and the renderer uses `width/2` directly when building quads.

## Fix Focus Areas
- Sanitize width once (e.g., `Real iconWidth = max(tileWidth, 1.0f);`) and use `iconWidth` for both segment calculation and the `addIcon()` call.
- file: GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp[293-316]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

Fixed

}

static void debugDrawBlastRadii( Object *missile, const BlastInfo *blastInfo, Real tileWidth, Int frameDuration )
{
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, frameDuration, innerColor );
debugDrawBlastCircle( missilePos, blastInfo->outerRadius, tileWidth, frameDuration, outerColor );
}

// ------------------------------------------------------------------------------------------------
/** Do a single blast for the bomb */
// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -314,6 +351,14 @@ 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 && (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,
blastInfo->outerRadius,
FROM_CENTER_2D,
Expand Down
Loading