TombEngine/TR5Main/Game/collide.h

176 lines
No EOL
5.9 KiB
C++

#pragma once
#include "Specific\phd_global.h"
#include "trmath.h"
struct ITEM_INFO;
struct COLL_INFO;
struct FLOOR_INFO;
struct MESH_INFO;
constexpr auto NO_BAD_POS = (-NO_HEIGHT); // used by coll->Setup.BadHeightDown
constexpr auto NO_BAD_NEG = NO_HEIGHT; // used by coll->Setup.BadHeightUp
constexpr auto MAX_COLLIDED_OBJECTS = 1024;
constexpr auto COLLISION_CHECK_DISTANCE = WALL_SIZE * 8;
constexpr auto ITEM_RADIUS_YMAX = SECTOR(3);
extern BOUNDING_BOX GlobalCollisionBounds;
extern ITEM_INFO* CollidedItems[MAX_COLLIDED_OBJECTS];
extern MESH_INFO* CollidedMeshes[MAX_COLLIDED_OBJECTS];
enum COLL_TYPE
{
CT_NONE = 0, // 0x00
CT_FRONT = (1 << 0), // 0x01
CT_LEFT = (1 << 1), // 0x02
CT_RIGHT = (1 << 2), // 0x04
CT_TOP = (1 << 3), // 0x08
CT_TOP_FRONT = (1 << 4), // 0x10
CT_CLAMP = (1 << 5) // 0x20
};
enum class COLL_PROBE_MODE
{
QUADRANTS,
FREE_FORWARD,
FREE_FLAT
};
enum class SPLAT_COLL
{
NONE,
WALL,
STEP
};
enum class CORNER_RESULT
{
NONE,
INNER,
OUTER
};
struct COLL_POSITION
{
int Floor;
int Ceiling;
int Bridge;
float SplitAngle;
bool Slope;
bool DiagonalStep;
bool HasDiagonalSplit() { return SplitAngle == 45.0f * RADIAN || SplitAngle == 135.0f * RADIAN; }
bool HasFlippedDiagonalSplit() { return HasDiagonalSplit() && SplitAngle != 45.0f * RADIAN; }
};
struct COLL_RESULT
{
int RoomNumber;
FLOOR_INFO* Block;
FLOOR_INFO* BottomBlock;
COLL_POSITION Position;
int TiltX;
int TiltZ;
};
struct COLL_SETUP
{
COLL_PROBE_MODE Mode; // Probe rotation mode
bool SlopesAreWalls; // Treat steep slopes as walls
bool SlopesArePits; // Treat steep slopes as pits
bool DeathFlagIsPit; // Treat death sectors as pits
bool EnableObjectPush; // Can be pushed by objects
bool EnableSpaz; // Push is treated as hurt
int Radius; // Collision bounds horizontal size
int Height; // Collision bounds vertical size
short ForwardAngle; // Forward angle direction
int BadHeightDown; // Borderline step-up height
int BadHeightUp; // Borderline step-down height
int BadCeilingHeight; // Borderline ceiling height
PHD_VECTOR OldPosition; // Preserve old parameters to restore later
short OldAnimState;
short OldAnimNumber;
short OldFrameNumber;
};
struct COLL_INFO
{
COLL_SETUP Setup; // In parameters
COLL_POSITION Middle;
COLL_POSITION MiddleLeft;
COLL_POSITION MiddleRight;
COLL_POSITION Front;
COLL_POSITION FrontLeft;
COLL_POSITION FrontRight;
PHD_VECTOR Shift;
COLL_TYPE CollisionType;
short NearestLedgeAngle;
float NearestLedgeDistance;
int TiltX;
int TiltZ;
bool HitStatic;
bool HitTallObject;
bool TriangleAtRight() { return MiddleRight.SplitAngle != 0.0f && MiddleRight.SplitAngle == Middle.SplitAngle; }
bool TriangleAtLeft() { return MiddleLeft.SplitAngle != 0.0f && MiddleLeft.SplitAngle == Middle.SplitAngle; }
bool DiagonalStepAtRight() { return MiddleRight.DiagonalStep && TriangleAtRight() && (NearestLedgeAngle % ANGLE(90)); }
bool DiagonalStepAtLeft() { return MiddleLeft.DiagonalStep && TriangleAtLeft() && (NearestLedgeAngle % ANGLE(90)); }
};
struct OBJECT_COLLISION_BOUNDS
{
BOUNDING_BOX boundingBox;
short rotX1;
short rotX2;
short rotY1;
short rotY2;
short rotZ1;
short rotZ2;
};
void GenericSphereBoxCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll);
bool GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int flag1, ITEM_INFO** collidedItems, MESH_INFO** collidedMeshes, int flag2);
bool TestWithGlobalCollisionBounds(ITEM_INFO* item, ITEM_INFO* lara, COLL_INFO* coll);
void TrapCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c);
void TestForObjectOnLedge(ITEM_INFO* item, COLL_INFO* coll);
void ShiftItem(ITEM_INFO* item, COLL_INFO* coll);
void MoveItem(ITEM_INFO* item, short angle, int x, int y = 0);
void SnapItemToLedge(ITEM_INFO* item, COLL_INFO* coll, float offsetMultiplier = 0.0f);
void SnapItemToLedge(ITEM_INFO* item, COLL_INFO* coll, short angle, float offsetMultiplier = 0.0f);
void SnapItemToGrid(ITEM_INFO* item, COLL_INFO* coll);
COLL_RESULT GetCollisionResult(ITEM_INFO* item, short angle, int dist, int height);
COLL_RESULT GetCollisionResult(FLOOR_INFO* floor, int x, int y, int z);
COLL_RESULT GetCollisionResult(int x, int y, int z, short roomNumber);
COLL_RESULT GetCollisionResult(ITEM_INFO* item);
int FindGridShift(int x, int z);
bool TestBoundsCollideStatic(ITEM_INFO* item, MESH_INFO* mesh, int radius);
bool ItemPushItem(ITEM_INFO* item, ITEM_INFO* l, COLL_INFO* coll, bool spazon, char bigpush);
bool ItemPushStatic(ITEM_INFO* l, MESH_INFO* mesh, COLL_INFO* coll);
void AIPickupCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c);
void ObjectCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* c);
void AlignLaraPosition(PHD_VECTOR* vec, ITEM_INFO* item, ITEM_INFO* l);
bool TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ITEM_INFO* item, ITEM_INFO* l);
bool Move3DPosTo3DPos(PHD_3DPOS* src, PHD_3DPOS* dest, int velocity, short angAdd);
bool MoveLaraPosition(PHD_VECTOR* pos, ITEM_INFO* item, ITEM_INFO* l);
bool TestBoundsCollide(ITEM_INFO* item, ITEM_INFO* l, int radius);
void CreatureCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll);
void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool resetRoom = false);
void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, bool resetRoom = false);
void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, int zv);
void DoObjectCollision(ITEM_INFO* item, COLL_INFO* coll);
bool ItemNearLara(PHD_3DPOS* pos, int radius);
bool ItemNearTarget(PHD_3DPOS* src, ITEM_INFO* target, int radius);
int GetQuadrant(short angle);
void CalcItemToFloorRotation(ITEM_INFO* item, int radiusDivide = 1);
short GetNearestLedgeAngle(ITEM_INFO* item, COLL_INFO* coll, float& dist);
bool CollideSolidBounds(ITEM_INFO* item, BOUNDING_BOX box, PHD_3DPOS pos, COLL_INFO* coll);
void CollideSolidStatics(ITEM_INFO* item, COLL_INFO* coll);
std::set<int> CollectConnectedRooms(int roomNumber);