| 548 | } |
| 549 | |
| 550 | void ChaseCamera(ItemInfo* item) |
| 551 | { |
| 552 | static const unsigned int maxSwivelSteps = 5; |
| 553 | |
| 554 | if (!Camera.targetElevation) |
| 555 | Camera.targetElevation = -ANGLE(10.0f); |
| 556 | |
| 557 | Camera.targetElevation += item->Pose.Orientation.x; |
| 558 | UpdateCameraElevation(); |
| 559 | |
| 560 | // Clamp X orientation. |
| 561 | if (Camera.actualElevation > ANGLE(85.0f)) |
| 562 | Camera.actualElevation = ANGLE(85.0f); |
| 563 | else if (Camera.actualElevation < ANGLE(-85.0f)) |
| 564 | Camera.actualElevation = ANGLE(-85.0f); |
| 565 | |
| 566 | // Force item position after exiting look mode to avoid weird movements near walls. |
| 567 | if (Camera.oldType == CameraType::Look) |
| 568 | { |
| 569 | Camera.target.x = item->Pose.Position.x; |
| 570 | Camera.target.z = item->Pose.Position.z; |
| 571 | } |
| 572 | |
| 573 | int distance = Camera.targetDistance * phd_cos(Camera.actualElevation); |
| 574 | |
| 575 | auto pointColl = GetPointCollision(Vector3i(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z), Camera.target.RoomNumber); |
| 576 | |
| 577 | if (TestEnvironment(ENV_FLAG_SWAMP, pointColl.GetRoomNumber())) |
| 578 | Camera.target.y = g_Level.Rooms[pointColl.GetRoomNumber()].TopHeight - CLICK(1); |
| 579 | |
| 580 | int y = Camera.target.y; |
| 581 | pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber); |
| 582 | if (((y < pointColl.GetCeilingHeight() || pointColl.GetFloorHeight() < y) || pointColl.GetFloorHeight() <= pointColl.GetCeilingHeight()) || |
| 583 | (pointColl.GetFloorHeight() == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT)) |
| 584 | { |
| 585 | TargetSnaps++; |
| 586 | Camera.target = LastTarget; |
| 587 | } |
| 588 | else |
| 589 | { |
| 590 | TargetSnaps = 0; |
| 591 | } |
| 592 | |
| 593 | for (int i = 0; i < maxSwivelSteps; i++) |
| 594 | Ideals[i].y = Camera.target.y + (Camera.targetDistance * phd_sin(Camera.actualElevation)); |
| 595 | |
| 596 | // Determine best player viewing angle. |
| 597 | float farthestDist = FLT_MAX; |
| 598 | int indexOfFarthestIdeal = 0; |
| 599 | GameVector temp[2]; |
| 600 | for (int i = 0; i < maxSwivelSteps; i++) |
| 601 | { |
| 602 | // Incrementally swivel camera position. |
| 603 | short angle = (i == 0) ? Camera.actualAngle : ((i - 1) * ANGLE(90.0f)); |
| 604 | |
| 605 | // Record ideal position at default distance for given swivel. |
| 606 | Ideals[i].x = Camera.target.x - (distance * phd_sin(angle)); |
| 607 | Ideals[i].z = Camera.target.z - (distance * phd_cos(angle)); |
no test coverage detected