| 39 | }; |
| 40 | |
| 41 | VehicleMountType GetVehicleMountType(ItemInfo* vehicleItem, ItemInfo* laraItem, CollisionInfo* coll, std::vector<VehicleMountType> allowedMountTypes, float maxDistance2D, float maxVerticalDistance) |
| 42 | { |
| 43 | auto* lara = GetLaraInfo(laraItem); |
| 44 | |
| 45 | // Assess vehicle usability. |
| 46 | if (vehicleItem->Flags & IFLAG_INVISIBLE) |
| 47 | return VehicleMountType::None; |
| 48 | |
| 49 | // Assess hand status. |
| 50 | if (lara->Control.HandStatus != HandStatus::Free) |
| 51 | return VehicleMountType::None; |
| 52 | |
| 53 | // Assess vertical distance to vehicle. |
| 54 | if (abs(laraItem->Pose.Position.y - vehicleItem->Pose.Position.y) > maxVerticalDistance) |
| 55 | return VehicleMountType::None; |
| 56 | |
| 57 | // Do interaction highlight before bounds testing to give player more visual tolerance. |
| 58 | g_Hud.InteractionHighlighter.Test(*laraItem, *vehicleItem); |
| 59 | |
| 60 | // Assess 2D distance to vehicle. |
| 61 | float distance2D = Vector2::Distance( |
| 62 | Vector2(laraItem->Pose.Position.x, laraItem->Pose.Position.z), |
| 63 | Vector2(vehicleItem->Pose.Position.x, vehicleItem->Pose.Position.z)); |
| 64 | if (distance2D > maxDistance2D) |
| 65 | return VehicleMountType::None; |
| 66 | |
| 67 | // Assess object collision. |
| 68 | if (!TestBoundsCollide(vehicleItem, laraItem, coll->Setup.Radius) || !HandleItemSphereCollision(*vehicleItem, *laraItem)) |
| 69 | return VehicleMountType::None; |
| 70 | |
| 71 | bool hasInputAction = IsHeld(In::Action); |
| 72 | |
| 73 | short deltaHeadingAngle = vehicleItem->Pose.Orientation.y - laraItem->Pose.Orientation.y; |
| 74 | short angleBetweenPositions = vehicleItem->Pose.Orientation.y - Geometry::GetOrientToPoint(laraItem->Pose.Position.ToVector3(), vehicleItem->Pose.Position.ToVector3()).y; |
| 75 | bool onCorrectSide = abs(deltaHeadingAngle - angleBetweenPositions) < ANGLE(45.0f); |
| 76 | |
| 77 | // Assess mount types allowed for vehicle. |
| 78 | for (auto mountType : allowedMountTypes) |
| 79 | { |
| 80 | switch (mountType) |
| 81 | { |
| 82 | case VehicleMountType::LevelStart: |
| 83 | if (!laraItem->Animation.Velocity.z && |
| 84 | !laraItem->Animation.Velocity.y && |
| 85 | laraItem->Pose.Position == vehicleItem->Pose.Position) |
| 86 | { |
| 87 | break; |
| 88 | } |
| 89 | |
| 90 | continue; |
| 91 | |
| 92 | case VehicleMountType::Front: |
| 93 | if (hasInputAction && |
| 94 | deltaHeadingAngle > ANGLE(135.0f) && deltaHeadingAngle < -ANGLE(135.0f) && |
| 95 | onCorrectSide && |
| 96 | !laraItem->Animation.IsAirborne) |
| 97 | { |
| 98 | break; |
no test coverage detected