| 620 | } |
| 621 | |
| 622 | bool ItemPushItem(ItemInfo* item0, ItemInfo* item1, CollisionInfo* coll, bool enableSpasm, char bigPushFlags) |
| 623 | { |
| 624 | constexpr auto SOFT_PUSH_LERP_ALPHA = 0.25f; |
| 625 | |
| 626 | const auto& object = Objects[item0->ObjectNumber]; |
| 627 | |
| 628 | auto deltaPos = item1->Pose.Position - item0->Pose.Position; |
| 629 | |
| 630 | // Rotate relative position into item frame. |
| 631 | auto rotMatrix = Matrix::CreateRotationY(TO_RAD(-item0->Pose.Orientation.y)); |
| 632 | auto relDeltaPos = Vector3i(Vector3::Transform(deltaPos.ToVector3(), rotMatrix)); |
| 633 | |
| 634 | const auto& bounds = (bigPushFlags & 2) ? GlobalCollisionBounds : GameBoundingBox(item0); |
| 635 | int minX = bounds.X1; |
| 636 | int maxX = bounds.X2; |
| 637 | int minZ = bounds.Z1; |
| 638 | int maxZ = bounds.Z2; |
| 639 | |
| 640 | if (bigPushFlags & 1) |
| 641 | { |
| 642 | minX -= coll->Setup.Radius; |
| 643 | maxX += coll->Setup.Radius; |
| 644 | minZ -= coll->Setup.Radius; |
| 645 | maxZ += coll->Setup.Radius; |
| 646 | } |
| 647 | |
| 648 | // Big enemies. |
| 649 | if (abs(deltaPos.x) > BLOCK(4.5f) || abs(deltaPos.z) > BLOCK(4.5f) || |
| 650 | relDeltaPos.x <= minX || relDeltaPos.x >= maxX || |
| 651 | relDeltaPos.z <= minZ || relDeltaPos.z >= maxZ) |
| 652 | { |
| 653 | return false; |
| 654 | } |
| 655 | |
| 656 | int front = maxZ - relDeltaPos.z; |
| 657 | int back = relDeltaPos.z - minZ; |
| 658 | int left = relDeltaPos.x - minX; |
| 659 | int right = maxX - relDeltaPos.x; |
| 660 | |
| 661 | // Account for collision radius. |
| 662 | if (right <= left && right <= front && right <= back) |
| 663 | { |
| 664 | relDeltaPos.x += right; |
| 665 | } |
| 666 | else if (left <= right && left <= front && left <= back) |
| 667 | { |
| 668 | relDeltaPos.x -= left; |
| 669 | } |
| 670 | else if (front <= left && front <= right && front <= back) |
| 671 | { |
| 672 | relDeltaPos.z += front; |
| 673 | } |
| 674 | else |
| 675 | { |
| 676 | relDeltaPos.z -= back; |
| 677 | } |
| 678 | |
| 679 | // Lerp to new position. |
no test coverage detected