bugfix(neutronmissile): Fix and improve Nuke Missile damage for large objects inside the outer blast radius - #3161
Conversation
… objects inside the outer blast radius Large structures are now properly damaged if they reach into the outer blast radius and more damage is applied by taking the closest edge into the damage calculation
PR Summary by QodoFix Nuke Missile outer-radius targeting and improve large-object damage sampling
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Nuke falloff fix disabled
|
| forceVector.x = (forceVector.x + toCenterVector.x) * 0.5f; | ||
| forceVector.y = (forceVector.y + toCenterVector.y) * 0.5f; | ||
| forceVector.z = 0.0f; | ||
| #endif |
There was a problem hiding this comment.
2. Z dropped from distance 🐞 Bug ≡ Correctness
When the non-retail outer-radius damage path is enabled, doBlast() forces forceVector.z = 0, so damage falloff (dist = forceVector.length()) becomes purely 2D and differs from the retail path that includes Z. This can over-apply damage/topple to airborne or differently-elevated objects compared to the existing behavior.
Agent Prompt
### Issue description
In `NeutronMissileSlowDeathBehavior::doBlast()`, the new outer-radius damage sampling branch computes an adjusted XY vector but then sets `forceVector.z = 0.0f`. A few lines later, damage falloff uses `dist = forceVector.length()`, so this change makes damage distance purely 2D in that branch, unlike the retail-compatible branch which includes Z.
### Issue Context
- This impacts both the `topple()` vector and the damage falloff distance.
- The new branch is intended to adjust *horizontal* sampling toward the closest edge for large objects, but it shouldn’t implicitly change vertical distance behavior.
### Fix Focus Areas
- Ensure the adjusted vector retains a meaningful Z component (e.g., set `forceVector.z = otherPos->z - missilePos->z` after averaging XY), or split vectors: use a 2D vector for topple if desired and a 3D vector for damage falloff.
- GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileSlowDeathUpdate.cpp[342-390]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| // take average between min and max force | ||
| forceVector.x = (forceVector.x + toCenterVector.x) * 0.5f; | ||
| forceVector.y = (forceVector.y + toCenterVector.y) * 0.5f; | ||
| forceVector.z = 0.0f; |
There was a problem hiding this comment.
forceVector.z = 0 has effect on helicopters and planes that are flying. Previously the blast was modeled as a (half) sphere, while now it is modeled as a cylinder.
Helicopters and planes that are within the outer radius at ground level now always receive damage, while previously, they could have been undamaged due to still being outside the sphere.
If this change is intentional, it may need documentation.
There was a problem hiding this comment.
The nuke missile explodes 15 units or so above the ground. I dediced to model the damage as 2D, because everything else is 2D here, and if not treated as 2D, then the damage radii are not perfectly accurate on the ground.
I have not considered aircraft. I will think about whether it needs returning to sphere.
| toCenterVector.x = otherPos->x - missilePos->x; | ||
| toCenterVector.y = otherPos->y - missilePos->y; | ||
|
|
||
| ThePartitionManager->getVectorTo(other, missilePos, FROM_BOUNDINGSPHERE_2D, forceVector); |
There was a problem hiding this comment.
I would prefer a fromBoundVector rather than reusing the forceVector variable.
| forceVector.y = -forceVector.y; | ||
|
|
||
| // take average between min and max force | ||
| forceVector.x = (forceVector.x + toCenterVector.x) * 0.5f; |
There was a problem hiding this comment.
With the proper comment (and renaming to fromBoundVector, the flipping and average can be consolidated into one statement.
There was a problem hiding this comment.
I would like to keep the flip separate, because it is only necessary because ThePartitionManager->getVectorTo gives us the direction in reverse of what we need.
Large structures are now properly damaged if they reach into the outer blast radius and more damage is applied by taking the closest edge into the damage calculation.
Original behavior 1
The China Nuke Missile applies no damage to the edges of buildings (and units). This is mostly noticeable with large structures, such as the Airfield. The blast radius needs to reach the center of every building (and unit).
Note that the Nuke Missile has an outer and inner damage radius. The outer radius applies less damage than the inner radius. The damage transition from inner to outer radius is linear.
Firing the Nuke Missile as follows applies NO damage to the structure:
Fixed behavior 1
The China Nuke Missile now applies damage to the edges of a building like all other weapons do.
This is a BUFF, but a very small one, because the building will receive the SMALLEST damage of the outer blast radius.
This is how much damage is applied to the Airfield after fixing the bug:
Rationale
The China Nuke blast radius is already not competitive compared to the SCUD Storm. The Nuke Missile needs buffing anyway and this bug fix is a good step into this direction.
Original behavior 2
Structures that are located between the inner and outer radii of the Nuke Missile do receive an interpolated damage between the max (inner) and min (outer) damages. This works well enough for small structures like a Gattling Cannon or Tunnel Network, but does not work well for large structures, such as the Airfield or SCUD Storm, because the damage sample point will be the center of the structure instead of a point closer to the actual damage radius of the Nuke Missile.
In practice this means that large structures at the egdes of the Nuke Missile will receive rather tiny damages, even if they reach reasonably far into the outer damage radius.
To fix this, the damage sample point needs to be moved closer to the Nuke Missile origins.
Showcase
The Nuke Missile applies little damage to large structures at the outer edge
generalszh.2026-08-16.11-29-18-88.mp4
Improved behavior 2
The logic now samples the damage point from the center to half of the outer edge of the object closest to the Nuke Missile origin. This works well for small and large objects.
BUFF for China. Does NOT make the Nuke Missile any better against small buildings and units, nor against targets inside the inner damage radius. The Nuke Missile will still perform worse than the SCUD Storm.
Showcase
The Nuke Missile applies considerably more damage to large structures at the outer edge
generalszh.2026-08-16.11-13-29-30.mp4
The SCUD Storm still applies more damage to large structures at the outer edge, because it applies around 20% more damage overall.
generalszh.2026-08-16.11-14-02-24.mp4
TODO