MCPcopy Create free account
hub / github.com/TombEngine/TombEngine / DropPickups

Function DropPickups

TombEngine/Game/pickup/pickup.cpp:865–981  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

863}
864
865void DropPickups(ItemInfo* item, bool disableAlignment)
866{
867 ItemInfo* pickup = nullptr;
868
869 auto bounds = GameBoundingBox(item);
870 auto extents = bounds.GetExtents();
871 auto origin = Geometry::TranslatePoint(item->Pose.Position.ToVector3(), item->Pose.Orientation, bounds.GetCenter());
872 auto yPos = GetPointCollision(*item).GetFloorHeight();
873
874 origin.y = yPos; // Initialize drop origin Y point as floor height at centerpoint, in case all corner tests fail.
875
876 auto collObjects = GetCollidedObjects(*item, true, true);
877
878 short startAngle = ANGLE(Random::GenerateInt(0, 3) * 90.0f); // Randomize start corner.
879
880 // Iterate through 4 corners and find best-fitting position, which is not inside a wall, not on a slope
881 // and also does not significantly differ in height to an object centerpoint height.
882 // If all corner tests will fail, a pickup will be spawned at bounding box centerpoint, as it does in tomb4.
883
884 if (!disableAlignment) for (int corner = 0; corner < 4; corner++)
885 {
886 auto angle = item->Pose.Orientation;
887 angle.y += startAngle + corner * ANGLE(90.0f);
888
889 // At first, do an inside-wall test at an extended extent point to make sure player can correctly align.
890 auto candidatePos = Geometry::TranslatePoint(origin, angle, extents * 1.2f);
891 candidatePos.y = yPos;
892 auto collPoint = GetPointCollision(candidatePos, item->RoomNumber);
893
894 // If position is inside a wall or on a slope, don't use it.
895 if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsSteepFloor() || collPoint.GetBottomSector().Flags.Death)
896 continue;
897
898 // Remember floor position for a tested point.
899 int candidateYPos = collPoint.GetFloorHeight();
900
901 // Now repeat the same test for original extent point to make sure it's also valid.
902 candidatePos = Geometry::TranslatePoint(origin, angle, extents);
903 candidatePos.y = yPos;
904 collPoint = GetPointCollision(candidatePos, item->RoomNumber);
905
906 // If position is inside a wall or on a slope, don't use it.
907 if (collPoint.GetFloorHeight() == NO_HEIGHT || collPoint.IsSteepFloor() || collPoint.GetBottomSector().Flags.Death)
908 continue;
909
910 // If position is not in the same room, don't use it.
911 if (collPoint.GetRoomNumber() != item->RoomNumber)
912 continue;
913
914 // Setup a dummy sphere with 1-click diameter for item and static mesh collision tests.
915 auto sphere = BoundingSphere(candidatePos, CLICK(0.5f));
916 bool collidedWithObject = false;
917
918 // Iterate through all found items and statics around, and determine if dummy sphere
919 // intersects any of those. If so, try other corner.
920
921 for (const auto* itemPtr : collObjects.Items)
922 {

Callers 4

ControlDragonFunction · 0.85
CyborgControlFunction · 0.85
ExplodeBossFunction · 0.85
CreatureDieFunction · 0.85

Calls 15

TranslatePointFunction · 0.85
GetPointCollisionFunction · 0.85
GetCollidedObjectsFunction · 0.85
ANGLEFunction · 0.85
GenerateIntFunction · 0.85
AlignEntityToSurfaceFunction · 0.85
ItemNewRoomFunction · 0.85
GetExtentsMethod · 0.80
GetCenterMethod · 0.80
ToBoundingOrientedBoxMethod · 0.80
IntersectsMethod · 0.80
GameBoundingBoxClass · 0.70

Tested by

no test coverage detected