From e04ef016aac381b70f8d1fd9ae23abcaf9b40071 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Sun, 12 Dec 2021 11:10:08 +0300 Subject: [PATCH 1/8] Partial fixes to corner laddering --- TR5Main/Game/Lara/lara_climb.cpp | 140 +++++++++++++------------------ TR5Main/Game/Lara/lara_tests.cpp | 8 +- 2 files changed, 63 insertions(+), 85 deletions(-) diff --git a/TR5Main/Game/Lara/lara_climb.cpp b/TR5Main/Game/Lara/lara_climb.cpp index 2c1860e5a..94fcbd81e 100644 --- a/TR5Main/Game/Lara/lara_climb.cpp +++ b/TR5Main/Game/Lara/lara_climb.cpp @@ -569,84 +569,75 @@ int LaraClimbRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) if (item->animNumber != LA_LADDER_RIGHT) return 0; - int oldYrot = item->pos.yRot; - int oldX = item->pos.xPos; - int oldY = item->pos.yPos; - int oldZ = item->pos.zPos; + auto oldPos = item->pos; + auto oldRot = Lara.moveAngle; short angle = GetQuadrant(item->pos.yRot); int x, z; if (angle && angle != SOUTH) { - x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos % 1024) + 1024; - z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos % 1024) + 1024; + x = (item->pos.xPos & -WALL_SIZE) - (item->pos.zPos % WALL_SIZE) + WALL_SIZE; + z = (item->pos.zPos & -WALL_SIZE) - (item->pos.xPos % WALL_SIZE) + WALL_SIZE; } else { - x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & (WALL_SIZE - 1); + z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & (WALL_SIZE - 1); } int shift = 0; if (GetClimbFlags(x, item->pos.yPos, z, item->roomNumber) & (short)LeftExtRightIntTab[angle]) { - item->pos.xPos = x; - item->pos.zPos = z; - Lara.nextCornerPos.xPos = x; + Lara.nextCornerPos.xPos = item->pos.xPos = x; Lara.nextCornerPos.yPos = item->pos.yPos; - Lara.nextCornerPos.zPos = z; - item->pos.yRot += ANGLE(90); - Lara.moveAngle = item->pos.yRot; + Lara.nextCornerPos.zPos = item->pos.zPos = z; + Lara.nextCornerPos.yRot = item->pos.yRot = Lara.moveAngle = item->pos.yRot + ANGLE(90); - result = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -512, 512, &shift); + result = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -CLICK(2), CLICK(2), &shift); + item->itemFlags[3] = result; } if (!result) { - item->pos.xPos = oldX; - Lara.moveAngle = oldYrot; - item->pos.yRot = oldYrot; - item->pos.zPos = oldZ; - - int newX, newZ; + item->pos = oldPos; + Lara.moveAngle = oldRot; switch (angle) { case NORTH: - newX = ((item->pos.xPos + 1024) & 0xFFFFFC00) - (item->pos.zPos % 1024) + 1024; - newZ = ((item->pos.zPos + 1024) & 0xFFFFFC00) - (item->pos.xPos % 1024) + 1024; + x = ((item->pos.xPos + WALL_SIZE) & -WALL_SIZE) - (item->pos.zPos % WALL_SIZE) + WALL_SIZE; + z = ((item->pos.zPos + WALL_SIZE) & -WALL_SIZE) - (item->pos.xPos % WALL_SIZE) + WALL_SIZE; break; case SOUTH: - newX = ((item->pos.xPos - 1024) & 0xFFFFFC00) - (item->pos.zPos % 1024) + 1024; - newZ = ((item->pos.zPos - 1024) & 0xFFFFFC00) - (item->pos.xPos % 1024) + 1024; + x = ((item->pos.xPos - WALL_SIZE) & -WALL_SIZE) - (item->pos.zPos % WALL_SIZE) + WALL_SIZE; + z = ((item->pos.zPos - WALL_SIZE) & -WALL_SIZE) - (item->pos.xPos % WALL_SIZE) + WALL_SIZE; break; case EAST: - newX = ((item->pos.zPos ^ item->pos.xPos) % 1024) ^ (item->pos.xPos + 1024); - newZ = (item->pos.zPos ^ ((item->pos.zPos ^ item->pos.xPos) % 1024)) - 1024; + x = ((item->pos.zPos ^ item->pos.xPos) % WALL_SIZE) ^ (item->pos.xPos + WALL_SIZE); + z = (item->pos.zPos ^ ((item->pos.zPos ^ item->pos.xPos) % WALL_SIZE)) - WALL_SIZE; break; case WEST: default: - newX = (item->pos.xPos ^ (item->pos.zPos ^ item->pos.xPos) % 1024) - 1024; - newZ = ((item->pos.zPos ^ item->pos.xPos) % 1024) ^ (item->pos.zPos + 1024); + x = (item->pos.xPos ^ (item->pos.zPos ^ item->pos.xPos) % WALL_SIZE) - WALL_SIZE; + z = ((item->pos.zPos ^ item->pos.xPos) % WALL_SIZE) ^ (item->pos.zPos + WALL_SIZE); break; } - if (GetClimbFlags(newX, item->pos.yPos, newZ, item->roomNumber) & (short)LeftIntRightExtTab[angle]) + if (GetClimbFlags(x, item->pos.yPos, z, item->roomNumber) & (short)LeftIntRightExtTab[angle]) { - item->pos.xPos = newX; - item->pos.zPos = newZ; - Lara.nextCornerPos.xPos = newX; + Lara.nextCornerPos.xPos = item->pos.xPos = x; Lara.nextCornerPos.yPos = item->pos.yPos; - Lara.nextCornerPos.zPos = newZ; - item->pos.yRot -= ANGLE(90); - Lara.moveAngle = item->pos.yRot; - result = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -512, 512, &shift) != 0; + Lara.nextCornerPos.zPos = item->pos.zPos = z; + Lara.nextCornerPos.yRot = item->pos.yRot = Lara.moveAngle = item->pos.yRot - ANGLE(90); + + result = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -CLICK(2), CLICK(2), &shift); + item->itemFlags[3] = result; } } else @@ -654,10 +645,8 @@ int LaraClimbRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) result = -1; } - item->pos.xPos = oldX; - item->pos.yRot = oldYrot; - item->pos.zPos = oldZ; - Lara.moveAngle = oldYrot; + item->pos = oldPos; + Lara.moveAngle = oldRot; return result; } @@ -669,83 +658,74 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) if (item->animNumber != LA_LADDER_LEFT) return 0; - int oldYrot = item->pos.yRot; - int oldX = item->pos.xPos; - int oldY = item->pos.yPos; - int oldZ = item->pos.zPos; + auto oldPos = item->pos; + auto oldRot = Lara.moveAngle; short angle = GetQuadrant(item->pos.yRot); int x, z; if (angle && angle != SOUTH) { - x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & (WALL_SIZE - 1); + z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & (WALL_SIZE - 1); } else { - x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + 1024; - z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + 1024; + x = (item->pos.xPos & -WALL_SIZE) - (item->pos.zPos & (WALL_SIZE - 1)) + WALL_SIZE; + z = (item->pos.zPos & -WALL_SIZE) - (item->pos.xPos & (WALL_SIZE - 1)) + WALL_SIZE; } int shift = 0; if (GetClimbFlags(x, item->pos.yPos, z, item->roomNumber) & (short)LeftIntRightExtTab[angle]) { - item->pos.xPos = x; - item->pos.zPos = z; - Lara.nextCornerPos.xPos = x; + Lara.nextCornerPos.xPos = item->pos.xPos = x; Lara.nextCornerPos.yPos = item->pos.yPos; - Lara.nextCornerPos.zPos = z; - item->pos.yRot -= ANGLE(90); - Lara.moveAngle = item->pos.yRot; + Lara.nextCornerPos.zPos = item->pos.zPos = z; + Lara.nextCornerPos.yRot = item->pos.yRot = Lara.moveAngle = item->pos.yRot - ANGLE(90); - result = LaraTestClimbPos(item, coll->Setup.Radius, -coll->Setup.Radius - 120, -512, 512, &shift); + result = LaraTestClimbPos(item, coll->Setup.Radius, -coll->Setup.Radius - CLICK(0.5f), -CLICK(2), CLICK(2), &shift); item->itemFlags[3] = result; } if (!result) { - item->pos.xPos = oldX; - Lara.moveAngle = oldYrot; - item->pos.yRot = oldYrot; - item->pos.zPos = oldZ; - - int newX, newZ; + item->pos = oldPos; + Lara.moveAngle = oldRot; switch (angle) { case NORTH: - newX = (item->pos.xPos ^ ((item->pos.zPos ^ item->pos.xPos) & 0x3FF)) - 1024; - newZ = ((item->pos.zPos ^ item->pos.xPos) & 0x3FF) ^ (item->pos.zPos + 1024); + x = (item->pos.xPos ^ ((item->pos.zPos ^ item->pos.xPos) & (WALL_SIZE - 1))) - WALL_SIZE; + z = ((item->pos.zPos ^ item->pos.xPos) & (WALL_SIZE - 1)) ^ (item->pos.zPos + WALL_SIZE); break; case SOUTH: - newX = ((item->pos.zPos ^ item->pos.xPos) & 0x3FF) ^ (item->pos.xPos + 1024); - newZ = ((item->pos.zPos ^ item->pos.xPos) & 0x3FF) ^ (item->pos.zPos - 1024); + x = ((item->pos.zPos ^ item->pos.xPos) & (WALL_SIZE - 1)) ^ (item->pos.xPos + WALL_SIZE); + z = ((item->pos.zPos ^ item->pos.xPos) & (WALL_SIZE - 1)) ^ (item->pos.zPos - WALL_SIZE); break; case EAST: - newX = ((item->pos.xPos + 1024) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + 1024; - newZ = ((item->pos.zPos + 1024) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + 1024; + x = ((item->pos.xPos + WALL_SIZE) & -WALL_SIZE) - (item->pos.zPos & (WALL_SIZE - 1)) + WALL_SIZE; + z = ((item->pos.zPos + WALL_SIZE) & -WALL_SIZE) - (item->pos.xPos & (WALL_SIZE - 1)) + WALL_SIZE; break; case WEST: default: - newX = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF); - newZ = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF); + x = (item->pos.xPos & -WALL_SIZE) - (item->pos.zPos & (WALL_SIZE - 1)); + z = (item->pos.zPos & -WALL_SIZE) - (item->pos.xPos & (WALL_SIZE - 1)); break; } - if (GetClimbFlags(newX, item->pos.yPos, newZ, item->roomNumber) & (short)LeftExtRightIntTab[angle]) + if (GetClimbFlags(x, item->pos.yPos, z, item->roomNumber) & (short)LeftExtRightIntTab[angle]) { - item->pos.xPos = Lara.nextCornerPos.xPos = newX; - item->pos.yPos = Lara.nextCornerPos.yPos = item->pos.yPos; - item->pos.zPos = Lara.nextCornerPos.zPos = newZ; - item->pos.yRot += ANGLE(90); - Lara.moveAngle = item->pos.yRot; - item->itemFlags[3] = LaraTestClimbPos(item, coll->Setup.Radius, -coll->Setup.Radius - 120, -512, 512, &shift); + Lara.nextCornerPos.xPos = item->pos.xPos = x; + Lara.nextCornerPos.yPos = item->pos.yPos; + Lara.nextCornerPos.zPos = item->pos.zPos = z; + Lara.nextCornerPos.yRot = item->pos.yRot = Lara.moveAngle = item->pos.yRot + ANGLE(90); + + item->itemFlags[3] = LaraTestClimbPos(item, coll->Setup.Radius, -coll->Setup.Radius - CLICK(0.5f), -CLICK(2), CLICK(2), &shift); result = item->itemFlags[3] != 0; } } @@ -754,10 +734,8 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) result = -1; } - item->pos.xPos = oldX; - item->pos.yRot = oldYrot; - item->pos.zPos = oldZ; - Lara.moveAngle = oldYrot; + item->pos = oldPos; + Lara.moveAngle = oldRot; return result; } diff --git a/TR5Main/Game/Lara/lara_tests.cpp b/TR5Main/Game/Lara/lara_tests.cpp index ded2c0794..edef85a12 100644 --- a/TR5Main/Game/Lara/lara_tests.cpp +++ b/TR5Main/Game/Lara/lara_tests.cpp @@ -697,8 +697,8 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng if (Lara.climbStatus) { - auto angleSet = testAngle > 0 ? LeftExtRightIntTab : LeftIntRightExtTab; - if (GetClimbFlags(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) + auto& angleSet = testAngle > 0 ? LeftExtRightIntTab : LeftIntRightExtTab; + if (GetClimbFlags(Lara.nextCornerPos.xPos, item->pos.yPos, Lara.nextCornerPos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) return CORNER_RESULT::INNER; } } @@ -749,8 +749,8 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng if (Lara.climbStatus) { - auto angleSet = testAngle > 0 ? LeftIntRightExtTab : LeftExtRightIntTab; - if (GetClimbFlags(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) + auto& angleSet = testAngle > 0 ? LeftIntRightExtTab : LeftExtRightIntTab; + if (GetClimbFlags(Lara.nextCornerPos.xPos, item->pos.yPos, Lara.nextCornerPos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) return CORNER_RESULT::OUTER; } } From d3ac4bae9c9444c9c3002525c0617cc2ac659cdc Mon Sep 17 00:00:00 2001 From: Lwmte Date: Sun, 12 Dec 2021 11:39:35 +0300 Subject: [PATCH 2/8] Fix ladder corner shimmy --- TR5Main/Game/Lara/lara_climb.cpp | 86 ++++++++++++++++---------------- TR5Main/Game/Lara/lara_tests.cpp | 6 +++ 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/TR5Main/Game/Lara/lara_climb.cpp b/TR5Main/Game/Lara/lara_climb.cpp index 94fcbd81e..570067e98 100644 --- a/TR5Main/Game/Lara/lara_climb.cpp +++ b/TR5Main/Game/Lara/lara_climb.cpp @@ -62,25 +62,25 @@ void lara_col_climbdown(ITEM_INFO* item, COLL_INFO* coll) case 28: case 29: - yShift = 256; + yShift = CLICK(1); break; case 57: - yShift = 512; + yShift = CLICK(2); break; default: return; } - item->pos.yPos += yShift + 256; + item->pos.yPos += yShift + CLICK(1); int shiftLeft = 0; int shiftRight = 0; - int resultRight = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -512, 512, &shiftRight); - int resultLeft = LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + 120), -512, 512, &shiftLeft); + int resultRight = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -CLICK(2), CLICK(2), &shiftRight); + int resultLeft = LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + CLICK(0.5f)), -CLICK(2), CLICK(2), &shiftLeft); - item->pos.yPos -= 256; + item->pos.yPos -= CLICK(1); if (resultRight != 0 && resultLeft != 0 && resultRight != -2 && resultLeft != -2 && @@ -147,23 +147,23 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll) } else if (frame == 28 || frame == 29) { - yShift = -256; + yShift = -CLICK(1); } else if (frame == 57) { - yShift = -512; + yShift = -CLICK(2); } else { return; } - item->pos.yPos += yShift - 256; + item->pos.yPos += yShift - CLICK(1); - resultRight = LaraTestClimbUpPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, &shiftRight, &ledgeRight); - resultLeft = LaraTestClimbUpPos(item, coll->Setup.Radius, -(coll->Setup.Radius + 120), &shiftLeft, &ledgeLeft); + resultRight = LaraTestClimbUpPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), &shiftRight, &ledgeRight); + resultLeft = LaraTestClimbUpPos(item, coll->Setup.Radius, -(coll->Setup.Radius + CLICK(0.5f)), &shiftLeft, &ledgeLeft); - item->pos.yPos += 256; + item->pos.yPos += CLICK(1); if (resultRight && resultLeft && TrInput & IN_FORWARD) { @@ -173,7 +173,7 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll) AnimateLara(item); - if (abs(ledgeRight - ledgeLeft) <= 120) + if (abs(ledgeRight - ledgeLeft) <= CLICK(0.5f)) { if (resultRight != -1 || resultLeft != -1) { @@ -183,7 +183,7 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll) else { item->goalAnimState = LS_GRABBING; - item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - 256; + item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - CLICK(1); } } } @@ -217,7 +217,7 @@ void lara_col_climbright(ITEM_INFO* item, COLL_INFO* coll) { int shift = 0; Lara.moveAngle = item->pos.yRot + ANGLE(90); - LaraDoClimbLeftRight(item, coll, LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -512, 512, &shift), shift); + LaraDoClimbLeftRight(item, coll, LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -CLICK(2), CLICK(2), &shift), shift); } } @@ -239,7 +239,7 @@ void lara_col_climbleft(ITEM_INFO* item, COLL_INFO* coll) { int shift = 0; Lara.moveAngle = item->pos.yRot - ANGLE(90); - LaraDoClimbLeftRight(item, coll, LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + 120), -512, 512, &shift), shift); + LaraDoClimbLeftRight(item, coll, LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + CLICK(0.5f)), -CLICK(2), CLICK(2), &shift), shift); } } @@ -274,12 +274,12 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) return; item->goalAnimState = LS_LADDER_IDLE; - item->pos.yPos += 256; + item->pos.yPos += CLICK(1); - resultRight = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -512, 512, &ledgeRight); - resultLeft = LaraTestClimbPos(item, coll->Setup.Radius, -120 - coll->Setup.Radius, -512, 512, &ledgeLeft); + resultRight = LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -CLICK(2), CLICK(2), &ledgeRight); + resultLeft = LaraTestClimbPos(item, coll->Setup.Radius, -CLICK(0.5f) - coll->Setup.Radius, -CLICK(2), CLICK(2), &ledgeLeft); - item->pos.yPos -= 256; + item->pos.yPos -= CLICK(1); if (!resultRight || !resultLeft || resultLeft == -2 || resultRight == -2) return; @@ -307,8 +307,8 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) else if (item->goalAnimState != LS_GRABBING) { item->goalAnimState = LS_LADDER_IDLE; - resultRight = LaraTestClimbUpPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, &shiftRight, &ledgeRight); - resultLeft = LaraTestClimbUpPos(item, coll->Setup.Radius, -120 - coll->Setup.Radius, &shiftLeft, &ledgeLeft); + resultRight = LaraTestClimbUpPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), &shiftRight, &ledgeRight); + resultLeft = LaraTestClimbUpPos(item, coll->Setup.Radius, -CLICK(0.5f) - coll->Setup.Radius, &shiftLeft, &ledgeLeft); if (!resultRight || !resultLeft) return; @@ -335,12 +335,12 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) item->goalAnimState = LS_LADDER_UP; item->pos.yPos += yShift; } - else if (abs(ledgeLeft - ledgeRight) <= 120) + else if (abs(ledgeLeft - ledgeRight) <= CLICK(0.5f)) { if (resultRight == -1 && resultLeft == -1) { item->goalAnimState = LS_GRABBING; - item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - 256; + item->pos.yPos += (ledgeRight + ledgeLeft) / 2 - CLICK(1); } else { @@ -425,26 +425,26 @@ int LaraTestClimbPos(ITEM_INFO* item, int front, int right, int origin, int heig case NORTH: x = item->pos.xPos + right; z = item->pos.zPos + front; - zFront = 256; + zFront = CLICK(1); break; case EAST: x = item->pos.xPos + front; z = item->pos.zPos - right; - xFront = 256; + xFront = CLICK(1); break; case SOUTH: x = item->pos.xPos - right; z = item->pos.zPos - front; - zFront = -256; + zFront = -CLICK(1); break; case WEST: default: x = item->pos.xPos - front; z = item->pos.zPos + right; - xFront = -256; + xFront = -CLICK(1); break; } @@ -748,12 +748,12 @@ int LaraTestClimb(int x, int y, int z, int xFront, int zFront, int itemHeight, i return 0; short roomNumber = itemRoom; - FLOOR_INFO* floor = GetFloor(x, y - 128, z, &roomNumber); + FLOOR_INFO* floor = GetFloor(x, y - CLICK(0.5f), z, &roomNumber); int height = GetFloorHeight(floor, x, y, z); if (height == NO_HEIGHT) return 0; - height -= (128 + y + itemHeight); + height -= (CLICK(0.5f) + y + itemHeight); if (height < -70) return 0; if (height < 0) @@ -802,25 +802,25 @@ int LaraTestClimb(int x, int y, int z, int xFront, int zFront, int itemHeight, i return 1; if (ceiling - y <= height) return 1; - if (ceiling - y >= 512) + if (ceiling - y >= CLICK(2)) return 1; if (ceiling - y <= 442) return -(hang != 0); if (*shift > 0) return -(hang != 0); - *shift = ceiling - y - 512; + *shift = ceiling - y - CLICK(2); return 1; } ceiling = GetCeiling(floor, dx, y, dz) - y; - if (ceiling >= 512) + if (ceiling >= CLICK(2)) return 1; if (ceiling > 442) { if (*shift > 0) return -(hang != 0); - *shift = ceiling - 512; + *shift = ceiling - CLICK(2); return 1; } @@ -871,7 +871,7 @@ int LaraTestClimbUpPos(ITEM_INFO* item, int front, int right, int* shift, int* l short roomNumber = item->roomNumber; FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber); - int ceiling = 256 - y + GetCeiling(floor, x, y, z); + int ceiling = CLICK(1) - y + GetCeiling(floor, x, y, z); if (ceiling > 70) return 0; @@ -892,18 +892,18 @@ int LaraTestClimbUpPos(ITEM_INFO* item, int front, int right, int* shift, int* l height -= y; *ledge = height; - if (height <= 128) + if (height <= CLICK(0.5f)) { if (height > 0 && height > *shift) *shift = height; roomNumber = item->roomNumber; - GetFloor(x, y + 512, z, &roomNumber); - floor = GetFloor(x + xFront, y + 512, z + zFront, &roomNumber); - ceiling = GetCeiling(floor, x + xFront, y + 512, z + zFront) - y; + GetFloor(x, y + CLICK(2), z, &roomNumber); + floor = GetFloor(x + xFront, y + CLICK(2), z + zFront, &roomNumber); + ceiling = GetCeiling(floor, x + xFront, y + CLICK(2), z + zFront) - y; if (ceiling <= height) return 1; - if (ceiling >= 512) + if (ceiling >= CLICK(2)) return 1; else return 0; @@ -911,11 +911,11 @@ int LaraTestClimbUpPos(ITEM_INFO* item, int front, int right, int* shift, int* l else { ceiling = GetCeiling(floor, x + xFront, y, z + zFront) - y; - if (ceiling < 512) + if (ceiling < CLICK(2)) { if (height - ceiling <= LARA_HEIGHT) { - if (height - ceiling < 512) + if (height - ceiling < CLICK(2)) return 0; *shift = height; return -2; @@ -943,7 +943,7 @@ int LaraCheckForLetGo(ITEM_INFO* item, COLL_INFO* coll) item->gravityStatus = false; item->fallspeed = 0; - if (TrInput & IN_ACTION && item->hitPoints > 0 || item->animNumber == LA_ONWATER_TO_LADDER)//can't let go on this anim + if (TrInput & IN_ACTION && item->hitPoints > 0 || item->animNumber == LA_ONWATER_TO_LADDER) // Can't let go on this anim return 0; Lara.torsoYrot = 0; diff --git a/TR5Main/Game/Lara/lara_tests.cpp b/TR5Main/Game/Lara/lara_tests.cpp index edef85a12..35342727f 100644 --- a/TR5Main/Game/Lara/lara_tests.cpp +++ b/TR5Main/Game/Lara/lara_tests.cpp @@ -699,7 +699,10 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng { auto& angleSet = testAngle > 0 ? LeftExtRightIntTab : LeftIntRightExtTab; if (GetClimbFlags(Lara.nextCornerPos.xPos, item->pos.yPos, Lara.nextCornerPos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) + { + Lara.nextCornerPos.yPos = item->pos.yPos; // Restore original Y pos for ladder tests because we don't snap to ledge height in such case. return CORNER_RESULT::INNER; + } } } @@ -751,7 +754,10 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng { auto& angleSet = testAngle > 0 ? LeftIntRightExtTab : LeftExtRightIntTab; if (GetClimbFlags(Lara.nextCornerPos.xPos, item->pos.yPos, Lara.nextCornerPos.zPos, item->roomNumber) & (short)angleSet[GetQuadrant(item->pos.yRot)]) + { + Lara.nextCornerPos.yPos = item->pos.yPos; // Restore original Y pos for ladder tests because we don't snap to ledge height in such case. return CORNER_RESULT::OUTER; + } } } From 5ba153f54b4ca6ae19019c313d3551c4c5e3a699 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Sun, 12 Dec 2021 11:55:11 +0300 Subject: [PATCH 3/8] Demagic TestLaraVault and TestLaraClimbStance --- TR5Main/Game/Lara/lara_tests.cpp | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/TR5Main/Game/Lara/lara_tests.cpp b/TR5Main/Game/Lara/lara_tests.cpp index 35342727f..3cee4ded8 100644 --- a/TR5Main/Game/Lara/lara_tests.cpp +++ b/TR5Main/Game/Lara/lara_tests.cpp @@ -91,20 +91,20 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) { bool success = false; - if (coll->Front.Floor < 0 && coll->Front.Floor >= -256) + if (coll->Front.Floor < 0 && coll->Front.Floor >= -CLICK(1)) { - if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < 256)) + if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < CLICK(1))) { item->animNumber = LA_VAULT_TO_CROUCH_1CLICK; item->currentAnimState = LS_GRABBING; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->goalAnimState = LS_CROUCH_IDLE; - item->pos.yPos += coll->Front.Floor + 256; + item->pos.yPos += coll->Front.Floor + CLICK(1); Lara.gunStatus = LG_HANDS_BUSY; success = true; } } - else if (coll->Front.Floor >= -640 && coll->Front.Floor <= -384) + else if (coll->Front.Floor >= -CLICK(2.5f) && coll->Front.Floor <= -CLICK(1.5f)) { if (coll->Front.Floor - coll->Front.Ceiling >= 0 && coll->FrontLeft.Floor - coll->FrontLeft.Ceiling >= 0 && @@ -114,22 +114,22 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) item->currentAnimState = LS_GRABBING; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->goalAnimState = LS_STOP; - item->pos.yPos += coll->Front.Floor + 512; + item->pos.yPos += coll->Front.Floor + CLICK(2); Lara.gunStatus = LG_HANDS_BUSY; success = true; } - else if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < 256)) + else if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < CLICK(1))) { item->animNumber = LA_VAULT_TO_CROUCH_2CLICK; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->currentAnimState = LS_GRABBING; item->goalAnimState = LS_CROUCH_IDLE; - item->pos.yPos += coll->Front.Floor + 512; + item->pos.yPos += coll->Front.Floor + CLICK(2); Lara.gunStatus = LG_HANDS_BUSY; success = true; } } - else if (coll->Front.Floor >= -896 && coll->Front.Floor <= -640) + else if (coll->Front.Floor >= -CLICK(3.5f) && coll->Front.Floor <= -CLICK(2.5f)) { if (coll->Front.Floor - coll->Front.Ceiling >= 0 && coll->FrontLeft.Floor - coll->FrontLeft.Ceiling >= 0 && @@ -139,22 +139,22 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) item->currentAnimState = LS_GRABBING; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->goalAnimState = LS_STOP; - item->pos.yPos += coll->Front.Floor + 768; + item->pos.yPos += coll->Front.Floor + CLICK(3); Lara.gunStatus = LG_HANDS_BUSY; success = true; } - else if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < 256)) + else if (g_GameFlow->Animations.CrawlExtra && (abs(coll->Front.Ceiling - coll->Front.Floor) < CLICK(1))) { item->animNumber = LA_VAULT_TO_CROUCH_3CLICK; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->currentAnimState = LS_GRABBING; item->goalAnimState = LS_CROUCH_IDLE; - item->pos.yPos += coll->Front.Floor + 768; + item->pos.yPos += coll->Front.Floor + CLICK(3); Lara.gunStatus = LG_HANDS_BUSY; success = true; } } - else if (coll->Front.Floor >= -1920 && coll->Front.Floor <= -896) + else if (coll->Front.Floor >= -CLICK(7.5f) && coll->Front.Floor <= -CLICK(3.5f)) { item->animNumber = LA_STAND_SOLID; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -174,9 +174,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) if (TestValidLedgeAngle(item, coll) && Lara.climbStatus) { - if (coll->Front.Floor > -1920 || Lara.waterStatus == LW_WADE || coll->FrontLeft.Floor > -1920 || coll->FrontRight.Floor > -2048 || coll->Middle.Ceiling > -1158) + if (coll->Front.Floor > -CLICK(7.5f) || Lara.waterStatus == LW_WADE || coll->FrontLeft.Floor > -CLICK(7.5f) || coll->FrontRight.Floor > -CLICK(8) || coll->Middle.Ceiling > -1158) { - if ((coll->Front.Floor < -1024 || coll->Front.Ceiling >= 506) && coll->Middle.Ceiling <= -518) + if ((coll->Front.Floor < -CLICK(4) || coll->Front.Ceiling >= 506) && coll->Middle.Ceiling <= -518) { if (TestLaraClimbStance(item, coll)) { @@ -787,7 +787,7 @@ bool TestLaraValidHangPos(ITEM_INFO* item, COLL_INFO* coll) // Setup new GCI call Lara.moveAngle = item->pos.yRot; coll->Setup.BadHeightDown = NO_BAD_POS; - coll->Setup.BadHeightUp = -512; + coll->Setup.BadHeightUp = -CLICK(2); coll->Setup.BadCeilingHeight = 0; coll->Setup.Mode = COLL_PROBE_MODE::FREE_FLAT; coll->Setup.ForwardAngle = Lara.moveAngle; @@ -806,10 +806,10 @@ bool TestLaraClimbStance(ITEM_INFO* item, COLL_INFO* coll) { int shift_r, shift_l; - if (LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + 120, -700, STOP_SIZE, &shift_r) != 1) + if (LaraTestClimbPos(item, coll->Setup.Radius, coll->Setup.Radius + CLICK(0.5f), -700, STOP_SIZE, &shift_r) != 1) return false; - if (LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + 120), -700, STOP_SIZE, &shift_l) != 1) + if (LaraTestClimbPos(item, coll->Setup.Radius, -(coll->Setup.Radius + CLICK(0.5f)), -700, STOP_SIZE, &shift_l) != 1) return false; if (shift_r) From 000d5c6b8f262f2cca125bc29bd2922c28bb3424 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Mon, 13 Dec 2021 01:10:53 +0300 Subject: [PATCH 4/8] Fix floor snapping when cornering ledges sitting on ceiling portals --- TR5Main/Game/Lara/lara_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TR5Main/Game/Lara/lara_tests.cpp b/TR5Main/Game/Lara/lara_tests.cpp index 3cee4ded8..70aec93fb 100644 --- a/TR5Main/Game/Lara/lara_tests.cpp +++ b/TR5Main/Game/Lara/lara_tests.cpp @@ -681,7 +681,7 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng // Store next position Lara.nextCornerPos.xPos = item->pos.xPos; - Lara.nextCornerPos.yPos = LaraCollisionAboveFront(item, item->pos.yRot, coll->Setup.Radius * 2, abs(bounds->Y1)).Position.Floor + abs(bounds->Y1); + Lara.nextCornerPos.yPos = LaraCollisionAboveFront(item, item->pos.yRot, coll->Setup.Radius * 2, abs(bounds->Y1) + LARA_HEADROOM).Position.Floor + abs(bounds->Y1); Lara.nextCornerPos.zPos = item->pos.zPos; Lara.nextCornerPos.yRot = item->pos.yRot; Lara.moveAngle = item->pos.yRot; @@ -736,7 +736,7 @@ CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAng // Store next position Lara.nextCornerPos.xPos = item->pos.xPos; - Lara.nextCornerPos.yPos = LaraCollisionAboveFront(item, item->pos.yRot, coll->Setup.Radius * 2, abs(bounds->Y1)).Position.Floor + abs(bounds->Y1); + Lara.nextCornerPos.yPos = LaraCollisionAboveFront(item, item->pos.yRot, coll->Setup.Radius * 2, abs(bounds->Y1) + LARA_HEADROOM).Position.Floor + abs(bounds->Y1); Lara.nextCornerPos.zPos = item->pos.zPos; Lara.nextCornerPos.yRot = item->pos.yRot; Lara.moveAngle = item->pos.yRot; From 758fe234c3cd8da45febee65e1a0c400cbee3a7b Mon Sep 17 00:00:00 2001 From: Lwmte Date: Mon, 13 Dec 2021 01:55:49 +0300 Subject: [PATCH 5/8] Fix CreatureMood crash if enemy is null --- TR5Main/Game/control/box.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/TR5Main/Game/control/box.cpp b/TR5Main/Game/control/box.cpp index e46c33f40..b12d3ad55 100644 --- a/TR5Main/Game/control/box.cpp +++ b/TR5Main/Game/control/box.cpp @@ -1579,18 +1579,16 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent) if (!item->data) return; - CREATURE_INFO* creature; - ITEM_INFO* enemy; - LOT_INFO* LOT; - int boxNumber, startBox, overlapIndex, nextBox, flags; - BOUNDING_BOX* bounds; + int boxNumber; - creature = (CREATURE_INFO*)item->data; - enemy = creature->enemy; - LOT = &creature->LOT; + auto creature = (CREATURE_INFO*)item->data; + auto enemy = creature->enemy; + auto LOT = &creature->LOT; - switch (creature->mood) + if (enemy != nullptr) { + switch (creature->mood) + { case BORED_MOOD: boxNumber = LOT->node[GetRandomControl() * LOT->zoneCount >> 15].boxNumber; if (ValidBox(item, info->zoneNumber, boxNumber) @@ -1616,7 +1614,7 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent) if (LOT->fly != NO_FLYING && Lara.waterStatus == LW_ABOVE_WATER) { - bounds = (BOUNDING_BOX*)GetBestFrame(enemy); + auto bounds = (BOUNDING_BOX*)GetBestFrame(enemy); LOT->target.y += bounds->Y1; } break; @@ -1656,12 +1654,13 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent) } } break; + } } if (LOT->targetBox == NO_BOX) TargetBox(LOT, item->boxNumber); -#ifdef CREATURE_AI_PRIORITY_OPTIMIZATION +#ifdef CREATURE_AI_PRIORITY_OPTIMIZATION bool shouldUpdateTarget = false; switch(creature->priority) { case CREATURE_AI_PRIORITY::HIGH: @@ -1697,12 +1696,13 @@ void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent) if (item->boxNumber != NO_BOX) { - startBox = LOT->node[item->boxNumber].exitBox; + auto startBox = LOT->node[item->boxNumber].exitBox; if (startBox != NO_BOX) { - overlapIndex = g_Level.Boxes[item->boxNumber].overlapIndex; - nextBox = 0; - flags = 0; + int overlapIndex = g_Level.Boxes[item->boxNumber].overlapIndex; + int nextBox = 0; + int flags = 0; + if (overlapIndex >= 0) { do From 197a72460b54b41e7fbf1d2f0437665f4574b614 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Mon, 13 Dec 2021 02:44:21 +0300 Subject: [PATCH 6/8] Clear killed bridge items --- TR5Main/Game/savegame.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TR5Main/Game/savegame.cpp b/TR5Main/Game/savegame.cpp index 755315e41..32143a87b 100644 --- a/TR5Main/Game/savegame.cpp +++ b/TR5Main/Game/savegame.cpp @@ -867,6 +867,9 @@ bool SaveGame::Load(int slot) // Kill immediately item if already killed and continue if (savedItem->flags() & IFLAG_KILLED) { + if (obj->floor != nullptr) + UpdateBridgeItem(itemNumber, true); + KillItem(i); item->status = ITEM_DEACTIVATED; item->flags |= ONESHOT; From 99311285659794fd47740cfc6ee79180e0188ee0 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Mon, 13 Dec 2021 02:46:22 +0300 Subject: [PATCH 7/8] Also prevent collision respawn for killed bridges when changing position/room --- TR5Main/Game/floordata.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TR5Main/Game/floordata.cpp b/TR5Main/Game/floordata.cpp index 51438440f..645042503 100644 --- a/TR5Main/Game/floordata.cpp +++ b/TR5Main/Game/floordata.cpp @@ -770,6 +770,10 @@ namespace TEN::Floordata { auto item = &g_Level.Items[itemNumber]; + // Force removal if object was killed + if (item->flags & IFLAG_KILLED) + forceRemoval = true; + // Get real OBB bounds of a bridge in world space auto bounds = GetBoundsAccurate(item); auto dxBounds = TO_DX_BBOX(item->pos, bounds); From 9d7defcc29b2452090c237da01ccb2d46ccae883 Mon Sep 17 00:00:00 2001 From: Lwmte Date: Mon, 13 Dec 2021 02:57:21 +0300 Subject: [PATCH 8/8] Fix epic bug --- TR5Main/Game/items.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TR5Main/Game/items.cpp b/TR5Main/Game/items.cpp index fb68bbf78..bba73abb0 100644 --- a/TR5Main/Game/items.cpp +++ b/TR5Main/Game/items.cpp @@ -74,7 +74,7 @@ void KillItem(short itemNum) if (item == Lara.target) Lara.target = NULL; - if (Objects[itemNum].floor != nullptr) + if (Objects[item->objectNumber].floor != nullptr) UpdateBridgeItem(itemNum, true); if (itemNum >= g_Level.NumItems)