diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp index f53b524ee03..e18bdd1bf5d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp @@ -446,7 +446,10 @@ Bool DumbProjectileBehavior::calcFlightPath(Bool recalcNumSegments) Real flightDistance = flightCurve.getApproximateLength(); m_flightPathSegments = ceil( flightDistance / m_flightPathSpeed ); } - flightCurve.getSegmentPoints( m_flightPathSegments, &m_flightPath ); + + // TheSuperHackers @info The way flight paths are used requires at least two curve points. + // DumbProjectileBehavior::update has been modified to handle cases where the flight path consists of one or zero curve points. + flightCurve.getSegmentPoints(m_flightPathSegments, &m_flightPath); DEBUG_ASSERTCRASH(m_flightPathSegments == m_flightPath.size(), ("m_flightPathSegments mismatch")); #if defined(RTS_DEBUG) @@ -584,6 +587,7 @@ UpdateSleepTime DumbProjectileBehavior::update() return UPDATE_SLEEP_NONE; } + // TheSuperHackers @info This check also covers the case where the flight path consists of zero curve points. if( m_currentFlightPathStep >= m_flightPath.size() ) { // No more steps to use. Would go out of bounds on vector, so have to do something. @@ -648,8 +652,28 @@ UpdateSleepTime DumbProjectileBehavior::update() //long, blurry projectile graphics which look badly oriented on step 0 of the flight path // so lets orient it the same as if it were on frame 1! { - Coord3D prevPos = m_flightPath[0]; - Coord3D curPos = m_flightPath[1]; + // TheSuperHackers @bugfix Caball009 10/01/2026 Check vector size before accessing the second element to prevent out of bounds access. + // The non-deterministic behavior for retail clients cannot be fixed, so this will remain a source of potential mismatches in retail compatibility mode. + // Use the flight path start and end coordinates if needed, so that the behavior is deterministic for patched clients. + Coord3D prevPos; + Coord3D curPos; + + if (m_flightPath.size() >= 2) + { + prevPos = m_flightPath[0]; + curPos = m_flightPath[1]; + } + else + { +#if RETAIL_COMPATIBLE_CRC + DEBUG_CRASH(("A mismatch is likely to happen if this code path is used in a match with unpatched clients." + " Vector is expected to contain two or more elements; check the weapon speed value.")); +#endif + + prevPos = m_flightPathStart; + curPos = m_flightPathEnd; + flightStep = m_flightPathEnd; + } Vector3 curDir(curPos.x - prevPos.x, curPos.y - prevPos.y, curPos.z - prevPos.z); curDir.Normalize(); // buildTransformMatrix wants it this way