@@ -333,19 +333,27 @@ void BulletExt::SimulatedFiringUnlimbo(BulletClass* pBullet, HouseClass* pHouse,
333333 // The target must exist during launch
334334 const auto targetCoords = pBullet->Target ->GetCenterCoords ();
335335 const auto gravity = BulletTypeExt::GetAdjustedGravity (pType);
336- const auto horizontalDistance = Point2D{targetCoords.X , targetCoords.Y }.DistanceFrom (Point2D{sourceCoords.X , sourceCoords.Y });
337-
338- if (horizontalDistance < 1e-10 || !pBullet->Speed )
336+ const auto distanceCoords = targetCoords - sourceCoords;
337+ const auto horizontalDistance = Point2D{distanceCoords.X , distanceCoords.Y }.Magnitude ();
338+ const bool lobber = pWeapon->Lobber || static_cast <int >(horizontalDistance) < distanceCoords.Z ; // 0x70D590
339+ // The lower the horizontal velocity, the higher the trajectory
340+ // WW calculates the launch angle (and limits it) before calculating the velocity
341+ // Here, some magic numbers are used to directly simulate its calculation
342+ const auto speedMult = (lobber ? 0.45 : (distanceCoords.Z > 0 ? 0.68 : 1.0 )); // Simulated 0x48A9D0
343+ const auto speed = static_cast <int >(speedMult * sqrt (horizontalDistance * gravity * 1.2 )); // 0x48AB90
344+
345+ // Simulate firing Arcing bullet
346+ if (horizontalDistance < 1e-10 || !speed)
339347 {
340- velocity.Z = pBullet->Speed ;
348+ // No solution
349+ velocity.Z = speed;
341350 }
342351 else
343352 {
344- const auto mult = pBullet->Speed / horizontalDistance;
345- const auto distanceCoords = targetCoords - sourceCoords;
353+ const auto mult = speed / horizontalDistance;
346354 velocity.X = static_cast <double >(distanceCoords.X ) * mult;
347355 velocity.Y = static_cast <double >(distanceCoords.Y ) * mult;
348- velocity.Z = static_cast <double >(distanceCoords.Z ) * mult + (gravity * horizontalDistance) / (2 * pBullet-> Speed );
356+ velocity.Z = static_cast <double >(distanceCoords.Z ) * mult + (gravity * horizontalDistance) / (2 * speed );
349357 }
350358 }
351359 else if (randomVelocity)
0 commit comments