| 486 | } |
| 487 | |
| 488 | int SpeedboatDynamics(short itemNumber, ItemInfo* laraItem) |
| 489 | { |
| 490 | auto* speedboatItem = &g_Level.Items[itemNumber]; |
| 491 | auto* speedboat = GetSpeedboatInfo(speedboatItem); |
| 492 | auto* lara = GetLaraInfo(laraItem); |
| 493 | |
| 494 | speedboatItem->Pose.Orientation.z -= speedboat->LeanAngle; |
| 495 | |
| 496 | Vector3i old, frontLeftOld, frontRightOld, backLeftOld, backRightOld, frontOld; |
| 497 | int heightFrontLeftOld = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, -SPEEDBOAT_SIDE, true, &frontLeftOld); |
| 498 | int heightFrontRightOld = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, SPEEDBOAT_SIDE, true, &frontRightOld); |
| 499 | int heightBackLeftOld = GetVehicleWaterHeight(speedboatItem, -SPEEDBOAT_FRONT, -SPEEDBOAT_SIDE, true, &backLeftOld); |
| 500 | int heightBackRightOld = GetVehicleWaterHeight(speedboatItem, -SPEEDBOAT_FRONT, SPEEDBOAT_SIDE, true, &backRightOld); |
| 501 | int heightFrontOld = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_TIP, 0, true, &frontOld); |
| 502 | |
| 503 | old.x = speedboatItem->Pose.Position.x; |
| 504 | old.y = speedboatItem->Pose.Position.y; |
| 505 | old.z = speedboatItem->Pose.Position.z; |
| 506 | |
| 507 | speedboatItem->Pose.Orientation.y += speedboat->TurnRate + speedboat->ExtraRotation; |
| 508 | speedboat->LeanAngle = speedboat->TurnRate * 6; |
| 509 | |
| 510 | speedboatItem->Pose.Position.x += speedboatItem->Animation.Velocity.z * phd_sin(speedboatItem->Pose.Orientation.y); |
| 511 | speedboatItem->Pose.Position.z += speedboatItem->Animation.Velocity.z * phd_cos(speedboatItem->Pose.Orientation.y); |
| 512 | |
| 513 | int slip = SPEEDBOAT_SLIP_SIDE * phd_sin(speedboatItem->Pose.Orientation.z); |
| 514 | if (!slip && speedboatItem->Pose.Orientation.z) |
| 515 | slip = (speedboatItem->Pose.Orientation.z > 0) ? 1 : -1; |
| 516 | speedboatItem->Pose.Position.x += slip * phd_sin(speedboatItem->Pose.Orientation.y); |
| 517 | speedboatItem->Pose.Position.z -= slip * phd_cos(speedboatItem->Pose.Orientation.y); |
| 518 | |
| 519 | slip = SPEEDBOAT_SLIP * phd_sin(speedboatItem->Pose.Orientation.x); |
| 520 | if (!slip && speedboatItem->Pose.Orientation.x) |
| 521 | slip = (speedboatItem->Pose.Orientation.x > 0) ? 1 : -1; |
| 522 | speedboatItem->Pose.Position.x -= slip * phd_sin(speedboatItem->Pose.Orientation.y); |
| 523 | speedboatItem->Pose.Position.z -= slip * phd_cos(speedboatItem->Pose.Orientation.y); |
| 524 | |
| 525 | auto moved = Vector3i(speedboatItem->Pose.Position.x, 0, speedboatItem->Pose.Position.z); |
| 526 | |
| 527 | SpeedboatDoBoatShift(speedboatItem, itemNumber); |
| 528 | |
| 529 | Vector3i fl, fr, br, bl, f; |
| 530 | short rotation = 0; |
| 531 | auto heightBackLeft = GetVehicleWaterHeight(speedboatItem, -SPEEDBOAT_FRONT, -SPEEDBOAT_SIDE, false, &bl); |
| 532 | if (heightBackLeft < (backLeftOld.y - CLICK(0.5f))) |
| 533 | rotation = SpeedboatDoShift(speedboatItem, &bl, &backLeftOld); |
| 534 | |
| 535 | auto heightBackRight = GetVehicleWaterHeight(speedboatItem, -SPEEDBOAT_FRONT, SPEEDBOAT_SIDE, false, &br); |
| 536 | if (heightBackRight < (backRightOld.y - CLICK(0.5f))) |
| 537 | rotation += SpeedboatDoShift(speedboatItem, &br, &backRightOld); |
| 538 | |
| 539 | auto heightFrontLeft = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, -SPEEDBOAT_SIDE, false, &fl); |
| 540 | if (heightFrontLeft < (frontLeftOld.y - CLICK(0.5f))) |
| 541 | rotation += SpeedboatDoShift(speedboatItem, &fl, &frontLeftOld); |
| 542 | |
| 543 | auto heightFrontRight = GetVehicleWaterHeight(speedboatItem, SPEEDBOAT_FRONT, SPEEDBOAT_SIDE, false, &fr); |
| 544 | if (heightFrontRight < (frontRightOld.y - CLICK(0.5f))) |
| 545 | rotation += SpeedboatDoShift(speedboatItem, &fr, &frontRightOld); |
no test coverage detected