COLL_RESULT conversion in progress (broken)

This commit is contained in:
Lwmte 2021-08-22 01:39:14 +03:00
parent ef2ff5bf51
commit b7d014080b
6 changed files with 359 additions and 476 deletions

View file

@ -399,7 +399,7 @@ void lara_col_all4s(ITEM_INFO* item, COLL_INFO* coll)
{ {
if (TrInput & IN_FORWARD) if (TrInput & IN_FORWARD)
{ {
if (abs(LaraFloorFront(item, item->pos.yRot, 256)) < 127 && HeightType != BIG_SLOPE) if (abs(LaraFloorFront(item, item->pos.yRot, 256)) < 127 && HeightType != BIG_SLOPE) // FIXME: UNDEFINED HEIGHT TYPE!!!!!!!!!!!!!!!!!!!!!!!!!!
item->goalAnimState = LS_CRAWL_FORWARD; item->goalAnimState = LS_CRAWL_FORWARD;
} }
else if (TrInput & IN_BACK) else if (TrInput & IN_BACK)

View file

@ -33,7 +33,6 @@ char LM[] =
LM_HEAD, LM_HEAD,
}; };
extern int SplitFloor, SplitCeiling;
int hitSoundTimer; int hitSoundTimer;
int XFront, ZFront; int XFront, ZFront;
BOUNDING_BOX GlobalCollisionBounds; BOUNDING_BOX GlobalCollisionBounds;
@ -1060,13 +1059,25 @@ void CreatureCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
} }
} }
void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z) COLL_RESULT GetCollisionResult(ITEM_INFO* item)
{ {
TiltYOffset = 0; auto roomNumber = item->roomNumber;
TiltXOffset = 0; auto floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
OnObject = 0; return GetCollisionResult(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
HeightType = WALL; }
SplitFloor = 0;
COLL_RESULT GetCollisionResult(int x, int y, int z, short roomNumber)
{
auto room = roomNumber;
auto floor = GetFloor(x, y, z, &room);
return GetCollisionResult(floor, x, y, z);
}
COLL_RESULT GetCollisionResult(FLOOR_INFO* floor, int x, int y, int z)
{
COLL_RESULT result = {};
result.Block = floor;
ROOM_INFO* r; ROOM_INFO* r;
while (floor->pitRoom != NO_ROOM) while (floor->pitRoom != NO_ROOM)
@ -1077,18 +1088,19 @@ void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z)
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z); floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
} }
result.FloorHeight = GetFloorHeight(ROOM_VECTOR{ floor->Room, y }, x, z).value_or(NO_HEIGHT);
if (floor->floor * 256 == NO_HEIGHT || floor->index == 0)
return result; // No floordata, block is flat.
int height = floor->floor * 256; int height = floor->floor * 256;
if (height != NO_HEIGHT)
{
if (floor->index != 0)
{
short* data = &g_Level.FloorData[floor->index]; short* data = &g_Level.FloorData[floor->index];
short type, hadj; short type, hadj;
int xOff, yOff, trigger; int xOff, yOff, trigger;
ITEM_INFO* item;
OBJECT_INFO* obj;
int tilts, t0, t1, t2, t3, t4, dx, dz, h1, h2; int tilts, t0, t1, t2, t3, t4, dx, dz, h1, h2;
do do
{ {
type = *(data++); type = *(data++);
@ -1097,23 +1109,27 @@ void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z)
{ {
case DOOR_TYPE: case DOOR_TYPE:
case ROOF_TYPE: case ROOF_TYPE:
data++;
break;
case SPLIT3: case SPLIT3:
case SPLIT4: case SPLIT4:
case NOCOLC1T: case NOCOLC1T:
case NOCOLC1B: case NOCOLC1B:
case NOCOLC2T: case NOCOLC2T:
case NOCOLC2B: case NOCOLC2B:
result.SplitCeiling = type & DATA_TYPE;
data++; data++;
break; break;
case TILT_TYPE: case TILT_TYPE:
TiltXOffset = xOff = (*data >> 8); result.TiltX = xOff = (*data >> 8);
TiltYOffset = yOff = *(char*)data; result.TiltZ = yOff = *(char*)data;
if ((abs(xOff)) > 2 || (abs(yOff)) > 2) if ((abs(xOff)) > 2 || (abs(yOff)) > 2)
HeightType = BIG_SLOPE; result.HeightType = BIG_SLOPE;
else else
HeightType = SMALL_SLOPE; result.HeightType = SMALL_SLOPE;
if (xOff >= 0) if (xOff >= 0)
height += (xOff * ((-1 - z) & 1023) >> 2); height += (xOff * ((-1 - z) & 1023) >> 2);
@ -1163,8 +1179,8 @@ void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z)
xOff = yOff = 0; xOff = yOff = 0;
HeightType = SPLIT_TRI; result.HeightType = SPLIT_TRI;
SplitFloor = (type & DATA_TYPE); result.SplitFloor = (type & DATA_TYPE);
if ((type & DATA_TYPE) == SPLIT1 || if ((type & DATA_TYPE) == SPLIT1 ||
(type & DATA_TYPE) == NOCOLF1T || (type & DATA_TYPE) == NOCOLF1T ||
@ -1211,13 +1227,13 @@ void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z)
} }
} }
TiltXOffset = xOff; result.TiltX = xOff;
TiltYOffset = yOff; result.TiltZ = yOff;
if ((abs(xOff)) > 2 || (abs(yOff)) > 2) if ((abs(xOff)) > 2 || (abs(yOff)) > 2)
HeightType = DIAGONAL; result.HeightType = DIAGONAL;
else if (HeightType != SPLIT_TRI) else if (result.HeightType != SPLIT_TRI)
HeightType = SMALL_SLOPE; result.HeightType = SMALL_SLOPE;
if (xOff >= 0) if (xOff >= 0)
height += xOff * ((-1 - z) & 1023) >> 2; height += xOff * ((-1 - z) & 1023) >> 2;
@ -1236,8 +1252,8 @@ void DoFloorThings(FLOOR_INFO* floor, int x, int y, int z)
break; break;
} }
} while (!(type & END_BIT)); } while (!(type & END_BIT));
}
} return result;
} }
void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNumber, int objectHeight) void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNumber, int objectHeight)
@ -1264,12 +1280,11 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
int yTop = y - 160; int yTop = y - 160;
int z = zPos; int z = zPos;
short tRoomNumber = roomNumber;
FLOOR_INFO* floor = GetFloor(x, yTop, z, &tRoomNumber);
ROOM_VECTOR tfLocation = GetRoom(LaraItem->location, x, yTop, z); ROOM_VECTOR tfLocation = GetRoom(LaraItem->location, x, yTop, z);
DoFloorThings(floor, x, yTop, z); // DoFloorThings(floor, x, yTop, z);
auto collResult = GetCollisionResult(x, yTop, z, roomNumber);
int height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT); int height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
height -= yPos; height -= yPos;
@ -1282,13 +1297,27 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->midCeiling = ceiling; coll->midCeiling = ceiling;
coll->midFloor = height; coll->midFloor = height;
coll->midType = HeightType; coll->midType = collResult.HeightType;
coll->midSplitFloor = SplitFloor; coll->midSplitFloor = collResult.SplitFloor;
coll->midSplitCeil = SplitCeiling; coll->midSplitCeil = collResult.SplitCeiling;
int tilt = GetTiltType(floor, x, LaraItem->pos.yPos, z); short tRoomNumber = roomNumber;
int tilt = GetTiltType(GetFloor(x, yTop, z, &tRoomNumber), x, LaraItem->pos.yPos, z);
// ||| remove upper thingy if equal
collResult = GetCollisionResult(x, LaraItem->pos.yPos, z, roomNumber);
// FIXME REPLACE WITH GetCollisionResult
coll->tiltX = tilt; coll->tiltX = tilt;
coll->tiltZ = tilt / 256; coll->tiltZ = tilt / 256;
// FIXME REPLACE WITH GetCollisionResult
// FIXME REPLACE WITH GetCollisionResult
if (collResult.TiltX != coll->tiltX || collResult.TiltZ != coll->tiltZ)
{
auto shit = 1;
}
// FIXME REPLACE WITH GetCollisionResult
int xright, xleft, zright, zleft; int xright, xleft, zright, zleft;
@ -1356,8 +1385,10 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
tfLocation = GetRoom(tfLocation, x, yTop, z); tfLocation = GetRoom(tfLocation, x, yTop, z);
floor = GetFloor(x, yTop, z, &tRoomNumber); //floor = GetFloor(x, yTop, z, &tRoomNumber);
DoFloorThings(floor, x, yTop, z); //DoFloorThings(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT); height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
height -= yPos; height -= yPos;
@ -1370,12 +1401,13 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->frontCeiling = ceiling; coll->frontCeiling = ceiling;
coll->frontFloor = height; coll->frontFloor = height;
coll->frontType = HeightType; coll->frontType = collResult.HeightType;
coll->frontSplitFloor = SplitFloor; coll->frontSplitFloor = collResult.SplitFloor;
coll->frontSplitCeil = SplitCeiling; coll->frontSplitCeil = collResult.SplitCeiling;
floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber); //DoFloorThings(floor, x + XFront, yTop, z + ZFront);
DoFloorThings(floor, x + XFront, yTop, z + ZFront); //floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber);
collResult = GetCollisionResult(x + XFront, yTop, z + ZFront, roomNumber);
tfLocation = GetRoom(tfLocation, x + XFront, yTop, z + ZFront); tfLocation = GetRoom(tfLocation, x + XFront, yTop, z + ZFront);
height = GetFloorHeight(tfLocation, x + XFront, z + ZFront).value_or(NO_HEIGHT); height = GetFloorHeight(tfLocation, x + XFront, z + ZFront).value_or(NO_HEIGHT);
@ -1398,7 +1430,7 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
} }
else if ((coll->lavaIsPit) else if ((coll->lavaIsPit)
&& (coll->frontFloor > 0) && (coll->frontFloor > 0)
&& floor->Flags.Death) && collResult.Block->Flags.Death)
{ {
coll->frontFloor = 512; coll->frontFloor = 512;
} }
@ -1408,9 +1440,10 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
ROOM_VECTOR lrfLocation = GetRoom(LaraItem->location, x, yTop, z); ROOM_VECTOR lrfLocation = GetRoom(LaraItem->location, x, yTop, z);
short lrRoomNumber = roomNumber; //short lrRoomNumber = roomNumber;
floor = GetFloor(x, yTop, z, &lrRoomNumber); //floor = GetFloor(x, yTop, z, &lrRoomNumber);
DoFloorThings(floor, x, yTop, z); //DoFloorThings(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT); height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
@ -1424,21 +1457,22 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->leftFloor = height; coll->leftFloor = height;
coll->leftCeiling = ceiling; coll->leftCeiling = ceiling;
coll->leftType = HeightType; coll->leftType = collResult.HeightType;
coll->leftSplitFloor = SplitFloor; coll->leftSplitFloor = collResult.SplitFloor;
coll->leftSplitCeil = SplitCeiling; coll->leftSplitCeil = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor < 0) if (coll->slopesAreWalls == 1 && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor < 0)
coll->leftFloor = -32767; coll->leftFloor = -32767;
else if (coll->slopesArePits && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor > 0) else if (coll->slopesArePits && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor > 0)
coll->leftFloor = 512; coll->leftFloor = 512;
else if (coll->lavaIsPit && coll->leftFloor > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->leftFloor > 0 && collResult.Block->Flags.Death)
coll->leftFloor = 512; coll->leftFloor = 512;
tfLocation = GetRoom(tfLocation, x, yTop, z); tfLocation = GetRoom(tfLocation, x, yTop, z);
floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber); //floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber); // WRONG COPYPASTE BY CHOCO
DoFloorThings(floor, x, yTop, z); //DoFloorThings(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber); // We use plain x/z values here, proposed by Choco
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT); height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
@ -1452,15 +1486,15 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->leftFloor2 = height; coll->leftFloor2 = height;
coll->leftCeiling2 = ceiling; coll->leftCeiling2 = ceiling;
coll->leftType2 = HeightType; coll->leftType2 = collResult.HeightType;
coll->leftSplitFloor2 = SplitFloor; coll->leftSplitFloor2 = collResult.SplitFloor;
coll->leftSplitCeil2 = SplitCeiling; coll->leftSplitCeil2 = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 < 0) if (coll->slopesAreWalls == 1 && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 < 0)
coll->leftFloor2 = -32767; coll->leftFloor2 = -32767;
else if (coll->slopesArePits && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 > 0) else if (coll->slopesArePits && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 > 0)
coll->leftFloor2 = 512; coll->leftFloor2 = 512;
else if (coll->lavaIsPit && coll->leftFloor2 > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->leftFloor2 > 0 && collResult.Block->Flags.Death)
coll->leftFloor2 = 512; coll->leftFloor2 = 512;
x = xPos + xright; x = xPos + xright;
@ -1468,9 +1502,10 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
lrfLocation = GetRoom(LaraItem->location, x, yTop, z); lrfLocation = GetRoom(LaraItem->location, x, yTop, z);
lrRoomNumber = roomNumber; //lrRoomNumber = roomNumber;
floor = GetFloor(x, yTop, z, &lrRoomNumber); //floor = GetFloor(x, yTop, z, &lrRoomNumber);
DoFloorThings(floor, x, yTop, z); //DoFloorThings(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT); height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
@ -1484,21 +1519,22 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->rightFloor = height; coll->rightFloor = height;
coll->rightCeiling = ceiling; coll->rightCeiling = ceiling;
coll->rightType = HeightType; coll->rightType = collResult.HeightType;
coll->rightSplitFloor = SplitFloor; coll->rightSplitFloor = collResult.SplitFloor;
coll->rightSplitCeil = SplitCeiling; coll->rightSplitCeil = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor < 0) if (coll->slopesAreWalls == 1 && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor < 0)
coll->rightFloor = -32767; coll->rightFloor = -32767;
else if (coll->slopesArePits && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor > 0) else if (coll->slopesArePits && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor > 0)
coll->rightFloor = 512; coll->rightFloor = 512;
else if (coll->lavaIsPit && coll->rightFloor > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->rightFloor > 0 && collResult.Block->Flags.Death)
coll->rightFloor = 512; coll->rightFloor = 512;
tfLocation = GetRoom(tfLocation, x, yTop, z); tfLocation = GetRoom(tfLocation, x, yTop, z);
floor = GetFloor(x, yTop, z, &tRoomNumber); //floor = GetFloor(x, yTop, z, &tRoomNumber);
DoFloorThings(floor, x, yTop, z); //DoFloorThings(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT); height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
@ -1512,18 +1548,18 @@ void GetCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int roomNum
coll->rightFloor2 = height; coll->rightFloor2 = height;
coll->rightCeiling2 = ceiling; coll->rightCeiling2 = ceiling;
coll->rightType2 = HeightType; coll->rightType2 = collResult.HeightType;
coll->rightSplitFloor2 = SplitFloor; coll->rightSplitFloor2 = collResult.SplitFloor;
coll->rightSplitCeil2 = SplitCeiling; coll->rightSplitCeil2 = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 < 0) if (coll->slopesAreWalls == 1 && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 < 0)
coll->rightFloor2 = -32767; coll->rightFloor2 = -32767;
else if (coll->slopesArePits && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 > 0) else if (coll->slopesArePits && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 > 0)
coll->rightFloor2 = 512; coll->rightFloor2 = 512;
else if (coll->lavaIsPit && coll->rightFloor2 > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->rightFloor2 > 0 && collResult.Block->Flags.Death)
coll->rightFloor2 = 512; coll->rightFloor2 = 512;
CollideStaticObjects(coll, xPos, yPos, zPos, tRoomNumber, objectHeight); CollideStaticObjects(coll, xPos, yPos, zPos, roomNumber, objectHeight); // check if bugged with roomNumber insted of tRoomNumber
if (coll->midFloor == NO_HEIGHT) if (coll->midFloor == NO_HEIGHT)
{ {
@ -1725,26 +1761,37 @@ void GetObjectCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int r
int yTop = y - 160; int yTop = y - 160;
int z = zPos; int z = zPos;
short tRoomNumber = roomNumber; //short tRoomNumber = roomNumber;
FLOOR_INFO* floor = GetFloor(x, yTop, z, &tRoomNumber); //FLOOR_INFO* floor = GetFloor(x, yTop, z, &tRoomNumber);
//int height = GetFloorHeight(floor, x, yTop, z);
auto collResult = GetCollisionResult(x, yTop, z, roomNumber);
int height = GetFloorHeight(floor, x, yTop, z); if (collResult.FloorHeight != NO_HEIGHT)
if (height != NO_HEIGHT) collResult.FloorHeight -= yPos;
height -= yPos;
int ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z); int ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->midCeiling = ceiling; coll->midCeiling = ceiling;
coll->midFloor = height; coll->midFloor = collResult.FloorHeight;
coll->midType = HeightType; coll->midType = collResult.HeightType;
coll->midSplitFloor = SplitFloor; coll->midSplitFloor = collResult.SplitFloor;
coll->midSplitCeil = SplitCeiling; coll->midSplitCeil = collResult.SplitCeiling;
int tilt = GetTiltType(floor, x, LaraItem->pos.yPos, z); // FIXME REPLACE WITH GetCollisionResult
// collResult = GetCollisionResult(x, LaraItem->pos.yPos, z, roomNumber); // uncomment this line if yes
int tilt = GetTiltType(collResult.Block, x, LaraItem->pos.yPos, z); // CHECK IF SAME
coll->tiltX = tilt; coll->tiltX = tilt;
coll->tiltZ = tilt / 256; coll->tiltZ = tilt / 256;
// FIXME REPLACE WITH GetCollisionResult
// FIXME REPLACE WITH GetCollisionResult
if (collResult.TiltX != coll->tiltX || collResult.TiltZ != coll->tiltZ)
{
auto shit = 1;
}
// FIXME REPLACE WITH GetCollisionResult
int xright, xleft, zright, zleft; int xright, xleft, zright, zleft;
@ -1803,34 +1850,38 @@ void GetObjectCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int r
x = XFront + xPos; x = XFront + xPos;
z = ZFront + zPos; z = ZFront + zPos;
if (resetRoom) //if (resetRoom)
tRoomNumber = roomNumber; // tRoomNumber = roomNumber;
//
//floor = GetFloor(x, yTop, z, &tRoomNumber);
//
//height = GetFloorHeight(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
floor = GetFloor(x, yTop, z, &tRoomNumber); if (collResult.FloorHeight != NO_HEIGHT)
collResult.FloorHeight -= yPos;
height = GetFloorHeight(floor, x, yTop, z); ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (height != NO_HEIGHT)
height -= yPos;
ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->frontCeiling = ceiling; coll->frontCeiling = ceiling;
coll->frontFloor = height; coll->frontFloor = collResult.FloorHeight;
coll->frontType = HeightType; coll->frontType = collResult.HeightType;
coll->frontSplitFloor = SplitFloor; coll->frontSplitFloor = collResult.SplitFloor;
coll->frontSplitCeil = SplitCeiling; coll->frontSplitCeil = collResult.SplitCeiling;
floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber); //floor = GetFloor(x + XFront, yTop, z + ZFront, &tRoomNumber);
height = GetFloorHeight(floor, x + XFront, yTop, z + ZFront); //height = GetFloorHeight(floor, x + XFront, yTop, z + ZFront);
if (height != NO_HEIGHT) collResult = GetCollisionResult(x + XFront, yTop, z + ZFront, roomNumber);
height -= yPos;
if (collResult.FloorHeight != NO_HEIGHT)
collResult.FloorHeight -= yPos;
if ((coll->slopesAreWalls) if ((coll->slopesAreWalls)
&& ((coll->frontType == BIG_SLOPE) || (coll->frontType == DIAGONAL)) && ((coll->frontType == BIG_SLOPE) || (coll->frontType == DIAGONAL))
&& (coll->frontFloor < coll->midFloor) && (coll->frontFloor < coll->midFloor)
&& (height < coll->frontFloor) && (collResult.FloorHeight < coll->frontFloor)
&& (coll->frontFloor < 0)) && (coll->frontFloor < 0))
{ {
coll->frontFloor = -32767; coll->frontFloor = -32767;
@ -1843,110 +1894,119 @@ void GetObjectCollisionInfo(COLL_INFO* coll, int xPos, int yPos, int zPos, int r
} }
else if ((coll->lavaIsPit) else if ((coll->lavaIsPit)
&& (coll->frontFloor > 0) && (coll->frontFloor > 0)
&& floor->Flags.Death) && collResult.Block->Flags.Death)
{ {
coll->frontFloor = 512; coll->frontFloor = 512;
} }
x = xPos + xleft; x = xPos + xleft;
z = zPos + zleft; z = zPos + zleft;
short lrRoomNumber = roomNumber; //short lrRoomNumber = roomNumber;
floor = GetFloor(x, yTop, z, &lrRoomNumber); //floor = GetFloor(x, yTop, z, &lrRoomNumber);
//
//height = GetFloorHeight(floor, x, yTop, z);
collResult = GetCollisionResult(x + XFront, yTop, z + ZFront, roomNumber);
height = GetFloorHeight(floor, x, yTop, z); if (collResult.FloorHeight != NO_HEIGHT)
if (height != NO_HEIGHT) collResult.FloorHeight -= yPos;
height -= yPos;
ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z); ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->leftFloor = height; coll->leftFloor = collResult.FloorHeight;
coll->leftCeiling = ceiling; coll->leftCeiling = ceiling;
coll->leftType = HeightType; coll->leftType = collResult.HeightType;
coll->leftSplitFloor = SplitFloor; coll->leftSplitFloor = collResult.SplitFloor;
coll->leftSplitCeil = SplitCeiling; coll->leftSplitCeil = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor < 0) if (coll->slopesAreWalls == 1 && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor < 0)
coll->leftFloor = -32767; coll->leftFloor = -32767;
else if (coll->slopesArePits && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor > 0) else if (coll->slopesArePits && (coll->leftType == BIG_SLOPE || coll->leftType == DIAGONAL) && coll->leftFloor > 0)
coll->leftFloor = 512; coll->leftFloor = 512;
else if (coll->lavaIsPit && coll->leftFloor > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->leftFloor > 0 && collResult.Block->Flags.Death)
coll->leftFloor = 512; coll->leftFloor = 512;
floor = GetFloor(x, yTop, z, &tRoomNumber); //floor = GetFloor(x, yTop, z, &tRoomNumber);
//
//height = GetFloorHeight(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(floor, x, yTop, z); if (collResult.FloorHeight != NO_HEIGHT)
if (height != NO_HEIGHT) collResult.FloorHeight -= yPos;
height -= yPos;
ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z); ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->leftFloor2 = height; coll->leftFloor2 = collResult.FloorHeight;
coll->leftCeiling2 = ceiling; coll->leftCeiling2 = ceiling;
coll->leftType2 = HeightType; coll->leftType2 = collResult.HeightType;
coll->leftSplitFloor2 = SplitFloor; coll->leftSplitFloor2 = collResult.SplitFloor;
coll->leftSplitCeil2 = SplitCeiling; coll->leftSplitCeil2 = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 < 0) if (coll->slopesAreWalls == 1 && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 < 0)
coll->leftFloor2 = -32767; coll->leftFloor2 = -32767;
else if (coll->slopesArePits && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 > 0) else if (coll->slopesArePits && (coll->leftType2 == BIG_SLOPE || coll->leftType2 == DIAGONAL) && coll->leftFloor2 > 0)
coll->leftFloor2 = 512; coll->leftFloor2 = 512;
else if (coll->lavaIsPit && coll->leftFloor2 > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->leftFloor2 > 0 && collResult.Block->Flags.Death)
coll->leftFloor2 = 512; coll->leftFloor2 = 512;
x = xPos + xright; x = xPos + xright;
z = zPos + zright; z = zPos + zright;
lrRoomNumber = roomNumber;
floor = GetFloor(x, yTop, z, &lrRoomNumber);
height = GetFloorHeight(floor, x, yTop, z); //lrRoomNumber = roomNumber;
if (height != NO_HEIGHT) //floor = GetFloor(x, yTop, z, &lrRoomNumber);
height -= yPos; //
//height = GetFloorHeight(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z); if (collResult.FloorHeight != NO_HEIGHT)
collResult.FloorHeight -= yPos;
ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->rightFloor = height; coll->rightFloor = collResult.FloorHeight;
coll->rightCeiling = ceiling; coll->rightCeiling = ceiling;
coll->rightType = HeightType; coll->rightType = collResult.HeightType;
coll->rightSplitFloor = SplitFloor; coll->rightSplitFloor = collResult.SplitFloor;
coll->rightSplitCeil = SplitCeiling; coll->rightSplitCeil = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor < 0) if (coll->slopesAreWalls == 1 && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor < 0)
coll->rightFloor = -32767; coll->rightFloor = -32767;
else if (coll->slopesArePits && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor > 0) else if (coll->slopesArePits && (coll->rightType == BIG_SLOPE || coll->rightType == DIAGONAL) && coll->rightFloor > 0)
coll->rightFloor = 512; coll->rightFloor = 512;
else if (coll->lavaIsPit && coll->rightFloor > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->rightFloor > 0 && collResult.Block->Flags.Death)
coll->rightFloor = 512; coll->rightFloor = 512;
floor = GetFloor(x, yTop, z, &tRoomNumber); //floor = GetFloor(x, yTop, z, &tRoomNumber);
//
//height = GetFloorHeight(floor, x, yTop, z);
collResult = GetCollisionResult(x, yTop, z, roomNumber);
height = GetFloorHeight(floor, x, yTop, z); if (collResult.FloorHeight != NO_HEIGHT)
if (height != NO_HEIGHT) collResult.FloorHeight -= yPos;
height -= yPos;
ceiling = GetCeiling(floor, x, yTop - LaraItem->fallspeed, z); ceiling = GetCeiling(collResult.Block, x, yTop - LaraItem->fallspeed, z);
if (ceiling != NO_HEIGHT) if (ceiling != NO_HEIGHT)
ceiling -= y; ceiling -= y;
coll->rightFloor2 = height; coll->rightFloor2 = collResult.FloorHeight;
coll->rightCeiling2 = ceiling; coll->rightCeiling2 = ceiling;
coll->rightType2 = HeightType; coll->rightType2 = collResult.HeightType;
coll->rightSplitFloor2 = SplitFloor; coll->rightSplitFloor2 = collResult.SplitFloor;
coll->rightSplitCeil2 = SplitCeiling; coll->rightSplitCeil2 = collResult.SplitCeiling;
if (coll->slopesAreWalls == 1 && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 < 0) if (coll->slopesAreWalls == 1 && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 < 0)
coll->rightFloor2 = -32767; coll->rightFloor2 = -32767;
else if (coll->slopesArePits && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 > 0) else if (coll->slopesArePits && (coll->rightType2 == BIG_SLOPE || coll->rightType2 == DIAGONAL) && coll->rightFloor2 > 0)
coll->rightFloor2 = 512; coll->rightFloor2 = 512;
else if (coll->lavaIsPit && coll->rightFloor2 > 0 && floor->Flags.Death) else if (coll->lavaIsPit && coll->rightFloor2 > 0 && collResult.Block->Flags.Death)
coll->rightFloor2 = 512; coll->rightFloor2 = 512;
CollideStaticObjects(coll, xPos, yPos, zPos, tRoomNumber, objectHeight); CollideStaticObjects(coll, xPos, yPos, zPos, roomNumber, objectHeight); // check if bugged with roomNumber insted of tRoomNumber
if (coll->midFloor == NO_HEIGHT) if (coll->midFloor == NO_HEIGHT)
{ {

View file

@ -9,6 +9,21 @@
#define MAX_COLLIDED_OBJECTS 1024 #define MAX_COLLIDED_OBJECTS 1024
struct COLL_RESULT
{
FLOOR_INFO* Block;
int FloorHeight;
int HeightType;
int TiltX;
int TiltZ;
int SplitFloor;
int CeilingHeight;
int SplitCeiling;
};
struct COLL_FLOOR struct COLL_FLOOR
{ {
int floor; int floor;
@ -113,6 +128,9 @@ void TestForObjectOnLedge(ITEM_INFO* item, COLL_INFO* coll);
void ShiftItem(ITEM_INFO* item, COLL_INFO* coll); void ShiftItem(ITEM_INFO* item, COLL_INFO* coll);
void UpdateLaraRoom(ITEM_INFO* item, int height); void UpdateLaraRoom(ITEM_INFO* item, int height);
short GetTiltType(FLOOR_INFO* floor, int x, int y, int z); short GetTiltType(FLOOR_INFO* floor, int x, int y, int z);
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); int FindGridShift(int x, int z);
int TestBoundsCollideStatic(BOUNDING_BOX* bounds, PHD_3DPOS* pos, int radius); int TestBoundsCollideStatic(BOUNDING_BOX* bounds, PHD_3DPOS* pos, int radius);
int ItemPushLaraStatic(ITEM_INFO* item, BOUNDING_BOX* bounds, PHD_3DPOS* pos, COLL_INFO* coll); int ItemPushLaraStatic(ITEM_INFO* item, BOUNDING_BOX* bounds, PHD_3DPOS* pos, COLL_INFO* coll);

View file

@ -160,12 +160,6 @@ short FlashFadeG;
short FlashFadeB; short FlashFadeB;
short FlashFader; short FlashFader;
HEIGHT_TYPES HeightType;
int SplitFloor;
int SplitCeiling;
int TiltXOffset;
int TiltYOffset;
std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE]; std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
short IsRoomOutsideNo; short IsRoomOutsideNo;
@ -1835,192 +1829,6 @@ short* GetTriggerIndex(FLOOR_INFO* floor, int x, int y, int z)
int GetFloorHeight(FLOOR_INFO *floor, int x, int y, int z) int GetFloorHeight(FLOOR_INFO *floor, int x, int y, int z)
{ {
TiltYOffset = 0;
TiltXOffset = 0;
OnObject = 0;
HeightType = WALL;
SplitFloor = 0;
ROOM_INFO *r;
while (floor->pitRoom != NO_ROOM)
{
if (CheckNoColFloorTriangle(floor, x, z) == 1)
break;
r = &g_Level.Rooms[floor->pitRoom];
floor = &XZ_GET_SECTOR(r, x - r->x, z - r->z);
}
int height = floor->floor * 256;
if (height != NO_HEIGHT)
{
if (floor->index != 0)
{
short* data = &g_Level.FloorData[floor->index];
short type, hadj;
int xOff, yOff, trigger;
ITEM_INFO* item;
OBJECT_INFO* obj;
int tilts, t0, t1, t2, t3, t4, dx, dz, h1, h2;
do
{
type = *(data++);
switch (type & DATA_TYPE)
{
case LAVA_TYPE:
case CLIMB_TYPE:
case MONKEY_TYPE:
case TRIGTRIGGER_TYPE:
case MINER_TYPE:
break;
case DOOR_TYPE:
case ROOF_TYPE:
case SPLIT3:
case SPLIT4:
case NOCOLC1T:
case NOCOLC1B:
case NOCOLC2T:
case NOCOLC2B:
data++;
break;
case TILT_TYPE:
TiltXOffset = xOff = (*data >> 8);
TiltYOffset = yOff = *(char*)data;
if ((abs(xOff)) > 2 || (abs(yOff)) > 2)
HeightType = BIG_SLOPE;
else
HeightType = SMALL_SLOPE;
if (xOff >= 0)
height += (xOff * ((-1 - z) & 1023) >> 2);
else
height -= (xOff * (z & 1023) >> 2);
if (yOff >= 0)
height += yOff * ((-1 - x) & 1023) >> 2;
else
height -= yOff * (x & 1023) >> 2;
data++;
break;
case TRIGGER_TYPE:
data++;
do
{
trigger = *(data++);
if (TRIG_BITS(trigger) != TO_OBJECT)
{
if (TRIG_BITS(trigger) == TO_CAMERA ||
TRIG_BITS(trigger) == TO_FLYBY)
{
trigger = *(data++);
}
}
} while (!(trigger & END_BIT));
break;
case SPLIT1:
case SPLIT2:
case NOCOLF1T:
case NOCOLF1B:
case NOCOLF2T:
case NOCOLF2B:
tilts = *data;
t0 = tilts & 15;
t1 = (tilts >> 4) & 15;
t2 = (tilts >> 8) & 15;
t3 = (tilts >> 12) & 15;
dx = x & 1023;
dz = z & 1023;
xOff = yOff = 0;
HeightType = SPLIT_TRI;
SplitFloor = (type & DATA_TYPE);
if ((type & DATA_TYPE) == SPLIT1 ||
(type & DATA_TYPE) == NOCOLF1T ||
(type & DATA_TYPE) == NOCOLF1B)
{
if (dx <= (1024 - dz))
{
hadj = (type >> 10) & 0x1F;
if (hadj & 0x10)
hadj |= 0xfff0;
height += 256 * hadj;
xOff = t2 - t1;
yOff = t0 - t1;
}
else
{
hadj = (type >> 5) & 0x1F;
if (hadj & 0x10)
hadj |= 0xFFF0;
height += 256 * hadj;
xOff = t3 - t0;
yOff = t3 - t2;
}
}
else
{
if (dx <= dz)
{
hadj = (type >> 10) & 0x1f;
if (hadj & 0x10)
hadj |= 0xfff0;
height += 256 * hadj;
xOff = t2 - t1;
yOff = t3 - t2;
}
else
{
hadj = (type >> 5) & 0x1f;
if (hadj & 0x10)
hadj |= 0xfff0;
height += 256 * hadj;
xOff = t3 - t0;
yOff = t0 - t1;
}
}
TiltXOffset = xOff;
TiltYOffset = yOff;
if ((abs(xOff)) > 2 || (abs(yOff)) > 2)
HeightType = DIAGONAL;
else if (HeightType != SPLIT_TRI)
HeightType = SMALL_SLOPE;
if (xOff >= 0)
height += xOff * ((-1 - z) & 1023) >> 2;
else
height -= xOff * (z & 1023) >> 2;
if (yOff >= 0)
height += yOff * ((-1 - x) & 1023) >> 2;
else
height -= yOff * (x & 1023) >> 2;
data++;
break;
default:
break;
}
} while (!(type & END_BIT));
}
}
/*return height;*/
return GetFloorHeight(ROOM_VECTOR{floor->Room, y}, x, z).value_or(NO_HEIGHT); return GetFloorHeight(ROOM_VECTOR{floor->Room, y}, x, z).value_or(NO_HEIGHT);
} }

View file

@ -100,7 +100,6 @@ extern int InitialiseGame;
extern int RequiredStartPos; extern int RequiredStartPos;
extern int WeaponDelay; extern int WeaponDelay;
extern int WeaponEnemyTimer; extern int WeaponEnemyTimer;
extern HEIGHT_TYPES HeightType;
extern int HeavyTriggered; extern int HeavyTriggered;
extern short SkyPos1; extern short SkyPos1;
extern short SkyPos2; extern short SkyPos2;
@ -131,8 +130,6 @@ extern short FlashFadeR;
extern short FlashFadeG; extern short FlashFadeG;
extern short FlashFadeB; extern short FlashFadeB;
extern short FlashFader; extern short FlashFader;
extern int TiltXOffset;
extern int TiltYOffset;
extern std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE]; extern std::vector<short> OutsideRoomTable[OUTSIDE_SIZE][OUTSIDE_SIZE];
extern short IsRoomOutsideNo; extern short IsRoomOutsideNo;
extern bool g_CollidedVolume; extern bool g_CollidedVolume;

View file

@ -234,16 +234,16 @@ bool SkidooCheckGetOffOK(int direction)
short roomNumber = skidoo->roomNumber; short roomNumber = skidoo->roomNumber;
FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber); FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber);
int height = GetFloorHeight(floor, x, y, z); auto collResult = GetCollisionResult(floor, x, y, z);
if (HeightType == BIG_SLOPE || height == NO_HEIGHT || HeightType == DIAGONAL) if (collResult.HeightType == BIG_SLOPE || collResult.HeightType == DIAGONAL || collResult.FloorHeight == NO_HEIGHT)
return false; return false;
if (abs(height - skidoo->pos.yPos) > WALL_SIZE / 2) if (abs(collResult.FloorHeight - skidoo->pos.yPos) > WALL_SIZE / 2)
return false; return false;
int ceiling = GetCeiling(floor, x, y, z); int ceiling = GetCeiling(floor, x, y, z);
if (ceiling - skidoo->pos.yPos > -LARA_HITE || height - ceiling < LARA_HITE) if (ceiling - skidoo->pos.yPos > -LARA_HITE || collResult.FloorHeight - ceiling < LARA_HITE)
return false; return false;
return true; return true;