diff --git a/TR5Main/Game/Lara/lara.cpp b/TR5Main/Game/Lara/lara.cpp index b8ee8db7f..e0fa1c74f 100644 --- a/TR5Main/Game/Lara/lara.cpp +++ b/TR5Main/Game/Lara/lara.cpp @@ -1,5 +1,6 @@ #include "framework.h" #include "Lara.h" +#include "lara_tests.h" #include "control.h" #include "items.h" #include "inventory.h" @@ -32,28 +33,15 @@ #include "kayak.h" #include "minecart.h" using std::function; -static short LeftClimbTab[4] = // offset 0xA0638 -{ - 0x0200, 0x0400, 0x0800, 0x0100 -}; - -static short RightClimbTab[4] = // offset 0xA0640 -{ - 0x0800, 0x0100, 0x0200, 0x0400 -}; extern Inventory g_Inventory; short elevation = 57346; bool doJump = false; -short OldAngle = 1; int RopeSwing = 0; LaraInfo Lara; ITEM_INFO* LaraItem; byte LaraNodeUnderwater[NUM_LARA_MESHES]; -bool EnableCrouchRoll, EnableFeetHang, EnableMonkeyVault, EnableMonkeyRoll, EnableCrawlFlex1click, EnableCrawlFlex2click, EnableCrawlFlex3click; -bool EnableCrawlFlex1clickE, EnableCrawlFlex2clickE, EnableCrawlFlex3clickE, EnableCrawlFlex1clickup, EnableCrawlFlex1clickdown; -bool TR12_OSCILLATE_HANG; function lara_control_routines[NUM_LARA_STATES + 1] = { lara_as_walk, @@ -2327,51 +2315,6 @@ void lara_as_extcornerl(ITEM_INFO* item, COLL_INFO* coll)//1A1F0(<), 1A324(<) (F item->animNumber == LA_LADDER_LEFT_CORNER_OUTER_END); } -void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip)//1A090, 1A1C4 (F) -{ - if (item->hitPoints <= 0) - { - item->goalAnimState = LS_JUMP_FORWARD; - item->currentAnimState = LS_JUMP_FORWARD; - item->animNumber = LA_FALL_START; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - - item->gravityStatus = true; - item->speed = 2; - item->pos.yPos += 256; - item->fallspeed = 1; - - Lara.gunStatus = LG_NO_ARMS; - - item->pos.yRot += rot / 2; - } - else if (flip) - { - if (Lara.isClimbing) - { - item->animNumber = LA_LADDER_IDLE; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_LADDER_IDLE; - item->currentAnimState = LS_LADDER_IDLE; - } - else - { - item->animNumber = LA_REACH_TO_HANG; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; - item->goalAnimState = LS_HANG; - item->currentAnimState = LS_HANG; - } - - coll->old.x = Lara.cornerX; - item->pos.xPos = Lara.cornerX; - - coll->old.z = Lara.cornerZ; - item->pos.zPos = Lara.cornerZ; - - item->pos.yRot += rot; - } -} - void lara_col_hangright(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) { Lara.moveAngle = ANGLE(90); @@ -2572,47 +2515,6 @@ void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll)//19A28, 19B5C (F) Camera.targetElevation = -ANGLE(45.0f); } -int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle)//19930, 19A64 (F) -{ - int oldx = item->pos.xPos; - int oldz = item->pos.zPos; - int x = item->pos.xPos; - int z = item->pos.zPos; - int res; - - Lara.moveAngle = angle; - - switch (GetQuadrant(item->pos.yRot + Lara.moveAngle)) - { - case 0: - z += 16; - break; - case 1: - x += 16; - break; - case 2: - z -= 16; - break; - case 3: - x -= 16; - break; - } - - item->pos.xPos = x; - item->pos.zPos = z; - - coll->old.y = item->pos.yPos; - - res = LaraHangTest(item, coll); - - item->pos.xPos = oldx; - item->pos.zPos = oldz; - - Lara.moveAngle = angle; - - return !res; -} - void lara_void_func(ITEM_INFO* item, COLL_INFO* coll)//19928(<), 19A5C(<) (F) { return; @@ -2981,7 +2883,7 @@ void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)//18D0C, 18E40 (F) { if (TestHangSwingIn(item, angle)) { - if (TR12_OSCILLATE_HANG == true) +/* if (TR12_OSCILLATE_HANG == true) { Lara.headYrot = 0; Lara.headXrot = 0; @@ -2993,7 +2895,7 @@ void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)//18D0C, 18E40 (F) item->goalAnimState = LS_HANG; } else - { + { */ Lara.headYrot = 0; Lara.headXrot = 0; Lara.torsoYrot = 0; @@ -3002,7 +2904,7 @@ void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)//18D0C, 18E40 (F) item->frameNumber = g_Level.Anims[item->animNumber].frameBase; item->currentAnimState = LS_MONKEYSWING_IDLE; item->goalAnimState = LS_MONKEYSWING_IDLE; - } +// } } else { @@ -4128,7 +4030,7 @@ void lara_col_hang2(ITEM_INFO* item, COLL_INFO* coll)//163DC, 16510 (F) GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600); // FOR DEBUG PURPOSES UNTIL SCRIPTING IS READY- - EnableMonkeyRoll = true; +// EnableMonkeyRoll = true; if (TrInput & IN_FORWARD && coll->collType != CT_FRONT && abs(coll->midCeiling - coll->frontCeiling) < 50) @@ -4151,7 +4053,7 @@ void lara_col_hang2(ITEM_INFO* item, COLL_INFO* coll)//163DC, 16510 (F) { item->goalAnimState = LS_MONKEYSWING_TURN_RIGHT; } - else if ((TrInput & IN_ROLL) && EnableMonkeyRoll == true) + else if ((TrInput & IN_ROLL))// && EnableMonkeyRoll == true) { item->currentAnimState = LS_MONKEYSWING_TURN_180; item->goalAnimState = LS_MONKEYSWING_IDLE; @@ -4244,79 +4146,6 @@ void lara_as_hang2(ITEM_INFO* item, COLL_INFO* coll)//1630C(<), 16440(<) (F) LookUpDown(); } -short TestMonkeyRight(ITEM_INFO* item, COLL_INFO* coll)//161EC(<), 16320(<) (F) -{ - short oct; - - coll->badPos = NO_BAD_POS; - coll->badNeg = -STEPUP_HEIGHT; - coll->badCeiling = 0; - Lara.moveAngle = ANGLE(90); - coll->slopesAreWalls = 0; - coll->facing = Lara.moveAngle; - coll->radius = 100; - - GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600); - - if (abs(coll->midCeiling - coll->frontCeiling) > 50) - return 0; - - if (!coll->collType) - return 1; - - oct = GetDirOctant(item->pos.yRot); - if (oct) - { - if (oct != 1) - return 1; - if (coll->collType != CT_FRONT && coll->collType != CT_RIGHT && coll->collType != CT_LEFT) - return 1; - } - else if (coll->collType != CT_FRONT) - { - return 1; - } - - return 0; -} - -short TestMonkeyLeft(ITEM_INFO* item, COLL_INFO* coll)//160CC(<), 16200(<) (F) -{ - short oct; - - coll->badPos = NO_BAD_POS; - coll->badNeg = NO_HEIGHT; - coll->badCeiling = 0; - Lara.moveAngle = -ANGLE(90); - coll->slopesAreWalls = 0; - coll->facing = Lara.moveAngle; - coll->radius = 100; - - GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600); - - if (abs(coll->midCeiling - coll->frontCeiling) > 50) - return 0; - - if (!coll->collType) - return 1; - - oct = GetDirOctant(item->pos.yRot); - if (oct) - { - if (oct != 1) - return 1; - if (coll->collType != CT_RIGHT && coll->collType != CT_LEFT) - return 1; - } - else - { - if (coll->collType != CT_FRONT && coll->collType != CT_LEFT) - return 1; - } - - return 0; -} - short GetDirOctant(int rot)//160B4(<), 161E8(<) (F) { return abs(rot) >= ANGLE(45) && abs(rot) <= ANGLE(135.0f); @@ -5028,11 +4857,11 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) } // FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED - EnableCrawlFlex1clickdown = true; - EnableCrawlFlex1clickup = true; - EnableCrawlFlex3clickE = true; - EnableCrawlFlex2clickE = true; - EnableCrawlFlex1clickE = true; +// EnableCrawlFlex1clickdown = true; +// EnableCrawlFlex1clickup = true; +// EnableCrawlFlex3clickE = true; +// EnableCrawlFlex2clickE = true; +// EnableCrawlFlex1clickE = true; @@ -5084,7 +4913,7 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) d.y = s.y + 160; d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT); - if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE && EnableCrawlFlex3clickE == true) + if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex3clickE == true) { item->animNumber = LA_CRAWL_JUMP_DOWN_23CLICK; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -5108,7 +4937,7 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) d.y = s.y + 160; d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT); - if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE && EnableCrawlFlex2clickE == true) + if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex2clickE == true) { item->animNumber = LA_CRAWL_JUMP_DOWN_23CLICK; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -5131,7 +4960,7 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) d.y = s.y + 160; d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT); - if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE && EnableCrawlFlex1clickE == true) + if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex1clickE == true) { item->animNumber = LA_CRAWL_JUMP_DOWN_1CLICK; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -5148,8 +4977,8 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) { if (LaraFloorFront(item, item->pos.yRot, 256) == -256 && LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT && - LaraCeilingFront(item, item->pos.yRot, 256, 256) <= -512 && - EnableCrawlFlex1clickup == true) + LaraCeilingFront(item, item->pos.yRot, 256, 256) <= -512)// && +// EnableCrawlFlex1clickup == true) { item->animNumber = LA_CRAWL_UP_STEP; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -5159,8 +4988,8 @@ void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F) else if (LaraFloorFront(item, item->pos.yRot, 256) == 256 && LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT && - LaraCeilingFront(item, item->pos.yRot, 256, -256) <= -512 && - EnableCrawlFlex1clickdown == true) + LaraCeilingFront(item, item->pos.yRot, 256, -256) <= -512)// && +// EnableCrawlFlex1clickdown == true) { item->animNumber = LA_CRAWL_DOWN_STEP; item->frameNumber = g_Level.Anims[item->animNumber].frameBase; @@ -5264,7 +5093,7 @@ void lara_as_duck(ITEM_INFO* item, COLL_INFO* coll)//14688, 14738 (F) GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &roomNum); // FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED- - EnableCrouchRoll = true; +// EnableCrouchRoll = true; if ((TrInput & IN_FORWARD || TrInput & IN_BACK) @@ -5291,8 +5120,8 @@ void lara_as_duck(ITEM_INFO* item, COLL_INFO* coll)//14688, 14738 (F) && Lara.gunStatus == LG_NO_ARMS && Lara.waterStatus != LW_WADE || Lara.waterSurfaceDist == 256 - && !(Lara.waterSurfaceDist > 256) - && EnableCrouchRoll == true) + && !(Lara.waterSurfaceDist > 256)) +// && EnableCrouchRoll == true) { if (LaraFloorFront(item, item->pos.yRot, 1024) >= 384 || //4 clicks away from holes in the floor TestWall(item, 1024, 0, -256)) //4 clicks away from walls @@ -5390,411 +5219,6 @@ void lara_as_duckl(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) item->pos.yRot -= ANGLE(1.5f); } -int TestHangSwingIn(ITEM_INFO* item, short angle)//14104, 141B4 (F) -{ - int x = item->pos.xPos; - int y = item->pos.yPos; - int z = item->pos.zPos; - short roomNum = item->roomNumber; - FLOOR_INFO* floor; - int h, c; - - //debug till scripting be ready -// TR12_OSCILLATE_HANG = true; - - /*if (angle == ANGLE(180.0f)) - { - z -= 256; - } - else if (angle == -ANGLE(90)) - { - x -= 256; - } - else if (angle == ANGLE(90)) - { - x += 256; - } - else if (angle == ANGLE(0)) - { - z += 256; - }*/ - - z += (phd_cos(angle) * STEP_SIZE) >> W2V_SHIFT; - x += (phd_sin(angle) * STEP_SIZE) >> W2V_SHIFT; - - floor = GetFloor(x, y, z, &roomNum); - h = GetFloorHeight(floor, x, y, z); - c = GetCeiling(floor, x, y, z); - - if (h != NO_HEIGHT) - { - if (TR12_OSCILLATE_HANG == true) - { - if (((h - y) > 0) - && ((c - y) < -400)) - return(1); - } - else - { - if (((h - y) > 0) - && ((c - y) < -400) - && ((y - 819 - c) > -72)) - return(1); - } - } - return(0); - -} - -int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE) - return 0; - - if (coll->hitStatic) - return 0; - - int x; - int z; - - int oldXpos = item->pos.xPos; - int oldZpos = item->pos.zPos; - short oldYrot = item->pos.yRot; - int oldFrontFloor = coll->frontFloor; - - short angle = GetQuadrant(item->pos.yRot); - if (angle != NORTH && angle != SOUTH) - { - x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - } - else - { - x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); - z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); - } - - item->pos.xPos = x; - Lara.cornerX = x; - item->pos.zPos = z; - Lara.cornerZ = z; - item->pos.yRot -= ANGLE(90.0f); - - int result = -IsValidHangPos(item, coll); - if (result) - { - if (Lara.climbStatus) - { - if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle]) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - } - else - { - if (abs(oldFrontFloor - coll->frontFloor) <= 60) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - } - } - - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - - if (LaraFloorFront(item, oldYrot - ANGLE(90.0f), 116) < 0) - return 0; - - switch (angle) - { - case NORTH: - x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.xPos - SECTOR(1); - z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.zPos + SECTOR(1); - break; - - case SOUTH: - x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1)); - z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1)); - break; - - case WEST: - x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF); - z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF); - break; - - default: - x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); - z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); - break; - - } - - item->pos.xPos = x; - Lara.cornerX = x; - item->pos.zPos = z; - Lara.cornerZ = z; - item->pos.yRot += ANGLE(90.0f); - - result = IsValidHangPos(item, coll); - if (!result) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - - if (!Lara.climbStatus) - { - if (abs(oldFrontFloor - coll->frontFloor) <= 60) - { - switch (angle) - { - case NORTH: - if ((oldXpos & 0x3FF) > 512) - result = 0; - break; - case EAST: - if ((oldZpos & 0x3FF) < 512) - result = 0; - break; - case SOUTH: - if ((oldXpos & 0x3FF) < 512) - result = 0; - break; - case WEST: - if ((oldZpos & 0x3FF) > 512) - result = 0; - break; - } - return result; - } - return 0; - } - - if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle]) - return result; - - short front = LaraFloorFront(item, item->pos.yRot, 116); - if (abs(front - coll->frontFloor) > 60) - return 0; - - if (front < -768) - return 0; - - return result; -} - -int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE) - return 0; - - if (coll->hitStatic) - return 0; - - int x; - int z; - - int oldXpos = item->pos.xPos; - int oldZpos = item->pos.zPos; - short oldYrot = item->pos.yRot; - int oldFrontFloor = coll->frontFloor; - - short angle = GetQuadrant(item->pos.yRot); - if (angle != NORTH && angle != SOUTH) - { - x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); - z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); - } - else - { - x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; - } - - item->pos.xPos = x; - Lara.cornerX = x; - item->pos.zPos = z; - Lara.cornerZ = z; - item->pos.yRot += ANGLE(90.0f); - - int result = -IsValidHangPos(item, coll); - if (result) - { - if (Lara.climbStatus) - { - if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle]) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - } - else - { - if (abs(oldFrontFloor - coll->frontFloor) <= 60) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - } - } - - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - - if (LaraFloorFront(item, oldYrot + ANGLE(90.0f), 116) < 0) - return 0; - - switch (angle) - { - case NORTH: - x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); - z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); - break; - - case SOUTH: - x = ((item->pos.xPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); - z = ((item->pos.zPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); - break; - - case WEST: - x = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.xPos - SECTOR(1)); - z = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.zPos + SECTOR(1)); - break; - - default: - x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1)); - z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1)); - break; - - } - - item->pos.xPos = x; - Lara.cornerX = x; - item->pos.zPos = z; - Lara.cornerZ = z; - item->pos.yRot -= ANGLE(90.0f); - - result = IsValidHangPos(item, coll); - if (!result) - { - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - return result; - } - - item->pos.xPos = oldXpos; - item->pos.zPos = oldZpos; - item->pos.yRot = oldYrot; - Lara.moveAngle = 0; - - if (!Lara.climbStatus) - { - if (abs(oldFrontFloor - coll->frontFloor) <= 60) - { - switch (angle) - { - case NORTH: - if ((oldXpos & 0x3FF) < 512) - result = 0; - break; - case EAST: - if ((oldZpos & 0x3FF) > 512) - result = 0; - break; - case SOUTH: - if ((oldXpos & 0x3FF) > 512) - result = 0; - break; - case WEST: - if ((oldZpos & 0x3FF) < 512) - result = 0; - break; - } - return result; - } - return 0; - } - - if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle]) - return result; - - short front = LaraFloorFront(item, item->pos.yRot, 116); - if (abs(front - coll->frontFloor) > 60) - return 0; - - if (front < -768) - return 0; - - return result; -} - -int IsValidHangPos(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (LaraFloorFront(item, item->pos.yRot + Lara.moveAngle, 100) < 200) - return 0; - - short angle = GetQuadrant(item->pos.yRot); - switch (angle) - { - case NORTH: - item->pos.zPos += 4; - break; - case EAST: - item->pos.xPos += 4; - break; - case SOUTH: - item->pos.zPos -= 4; - break; - case WEST: - item->pos.xPos -= 4; - break; - default: - break; - } - - coll->badPos = NO_BAD_POS; - coll->badNeg = -512; - coll->badCeiling = 0; - - Lara.moveAngle = 0; - - coll->facing = Lara.moveAngle; - GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE); - - if (coll->midCeiling >= 0 || coll->collType != CT_FRONT || coll->hitStatic) - return 0; - - return abs(coll->frontFloor - coll->rightFloor2) < 60; -} - void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle) // (F) (D) { if (item->currentAnimState == LS_SHIMMY_RIGHT) @@ -5878,60 +5302,6 @@ void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle) // (F) } } -int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - BOUNDING_BOX* bounds; - int shift, result; - - if (Lara.climbStatus == 0) - return 0; - - if (item->fallspeed < 0) - return 0; - - switch (GetQuadrant(item->pos.yRot)) - { - case NORTH: - case SOUTH: - item->pos.zPos += coll->shift.z; - break; - - case EAST: - case WEST: - item->pos.xPos += coll->shift.x; - break; - - default: - break; - } - - - bounds = GetBoundsAccurate(item); - - if (Lara.moveAngle) - { - short l = LaraCeilingFront(item, item->pos.yRot, 0, 0); - short r = LaraCeilingFront(item, item->pos.yRot + Lara.moveAngle, 128, 0); - - if (abs(l - r) > 60) - return 0; - } - - if (LaraTestClimbPos(item, coll->radius, coll->radius, bounds->Y1, bounds->Y2 - bounds->Y1, &shift) && - LaraTestClimbPos(item, coll->radius, -coll->radius, bounds->Y1, bounds->Y2 - bounds->Y1, &shift)) - { - result = LaraTestClimbPos(item, coll->radius, 0, bounds->Y1, bounds->Y2 - bounds->Y1, &shift); - if (result) - { - if (result != 1) - item->pos.yPos += shift; - return 1; - } - } - - return 0; -} - void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F) { ShiftItem(item, coll); @@ -5967,69 +5337,6 @@ void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F) } } -void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F) -{ - ShiftItem(item, coll); - - switch (coll->collType) - { - case CT_FRONT: - case CT_TOP_FRONT: - if (!Lara.climbStatus || item->speed != 2) - { - if (coll->midFloor <= 512) - { - if (coll->midFloor <= 128) - { - item->goalAnimState = LS_GRAB_TO_FALL; - item->currentAnimState = LS_GRAB_TO_FALL; - - item->animNumber = LA_JUMP_UP_LAND; - item->frameNumber = g_Level.Anims[LA_JUMP_UP_LAND].frameBase; - } - } - else - { - item->goalAnimState = LS_FREEFALL; - item->currentAnimState = LS_FREEFALL; - - item->animNumber = LA_JUMP_WALL_SMASH_START; - item->frameNumber = g_Level.Anims[LA_JUMP_WALL_SMASH_START].frameBase + 1; - } - - item->speed /= 4; - Lara.moveAngle += ANGLE(180); - - if (item->fallspeed <= 0) - item->fallspeed = 1; - } - - break; - case CT_TOP: - if (item->fallspeed <= 0) - item->fallspeed = 1; - - break; - case CT_LEFT: - item->pos.yRot += ANGLE(5.0f); - break; - case CT_RIGHT: - item->pos.yRot -= ANGLE(5.0f); - break; - case CT_CLAMP: - item->pos.xPos -= (100 * 4 * phd_sin(coll->facing)) >> W2V_SHIFT; - item->pos.zPos -= (100 * 4 * phd_cos(coll->facing)) >> W2V_SHIFT; - - item->speed = 0; - coll->midFloor = 0; - - if (item->fallspeed <= 0) - item->fallspeed = 16; - - break; - } -} - void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll)//127BC, 1286C (F) { coll->badPos = NO_BAD_POS; @@ -6119,480 +5426,6 @@ void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)//126F0(<), 127A0(<) (F) } } -int TestWall(ITEM_INFO* item, int front, int right, int down)//12550, 12600 (F) -{ - int x = item->pos.xPos; - int y = item->pos.yPos + down; - int z = item->pos.zPos; - - short angle = GetQuadrant(item->pos.yRot); - short roomNum = item->roomNumber; - - FLOOR_INFO* floor; - int h, c; - - switch (angle) - { - case NORTH: - x -= right; - break; - case EAST: - z -= right; - break; - case SOUTH: - x += right; - break; - case WEST: - z += right; - break; - default: - break; - } - - GetFloor(x, y, z, &roomNum); - - switch (angle) - { - case NORTH: - z += front; - break; - case EAST: - x += front; - break; - case SOUTH: - z -= front; - break; - case WEST: - x -= front; - break; - default: - break; - } - - floor = GetFloor(x, y, z, &roomNum); - h = GetFloorHeight(floor, x, y, z); - c = GetCeiling(floor, x, y, z); - - if (h == NO_HEIGHT) - return 1; - - if (y >= h || y <= c) - return 2; - - return 0; -} - -int LaraTestClimbStance(ITEM_INFO* item, COLL_INFO* coll)//11F78, 12028 -{ - int shift_r, shift_l; - - if (LaraTestClimbPos(item, coll->radius, coll->radius + 120, -700, 512, &shift_r) != 1) - return false; - - if (LaraTestClimbPos(item, coll->radius, -(coll->radius + 120), -700, 512, &shift_l) != 1) - return false; - - if (shift_r) - { - if (shift_l) - { - if (shift_r < 0 != shift_l < 0) - return false; - - if ((shift_r < 0 && shift_l < shift_r) || - (shift_r > 0 && shift_l > shift_r)) - { - item->pos.yPos += shift_l; - return true; - } - } - - item->pos.yPos += shift_r; - } - else if (shift_l) - { - item->pos.yPos += shift_l; - } - - return true; -} - -int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge) // (F) (D) -{ - - BOUNDING_BOX* bounds = GetBoundsAccurate(item); - int hdif = coll->frontFloor - bounds->Y1; - - if (hdif < 0 == hdif + item->fallspeed < 0) - { - hdif = item->pos.yPos + bounds->Y1; - - if ((hdif + item->fallspeed & 0xFFFFFF00) != (hdif & 0xFFFFFF00)) - { - if (item->fallspeed > 0) - *edge = (hdif + item->fallspeed) & 0xFFFFFF00; - else - *edge = hdif & 0xFFFFFF00; - - return -1; - } - - return 0; - } - - if (abs(coll->leftFloor2 - coll->rightFloor2) >= SLOPE_DIF) - return 0; - - return 1; -} - -int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT) - { - ShiftItem(item, coll); - - item->gravityStatus = false; - item->speed = 0; - - return 1; - } - - if (coll->collType == CT_LEFT) - { - ShiftItem(item, coll); - item->pos.yRot += ANGLE(2.0f); - } - else if (coll->collType == CT_RIGHT) - { - ShiftItem(item, coll); - item->pos.yRot -= ANGLE(2.0f); - } - - return 0; -} - -int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT) - { - ShiftItem(item, coll); - - item->goalAnimState = LS_STOP; - item->speed = 0; - item->gravityStatus = false; - - return 1; - } - - if (coll->collType == CT_LEFT) - { - ShiftItem(item, coll); - item->pos.yRot += ANGLE(5.0f); - } - else if (coll->collType == CT_RIGHT) - { - ShiftItem(item, coll); - item->pos.yRot -= ANGLE(5.0f); - } - - return 0; -} - -int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (coll->collType == CT_TOP || coll->collType == CT_CLAMP) - { - item->pos.xPos = coll->old.x; - item->pos.yPos = coll->old.y; - item->pos.zPos = coll->old.z; - - item->goalAnimState = LS_STOP; - item->currentAnimState = LS_STOP; - - item->animNumber = LA_STAND_SOLID; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - - item->speed = 0; - item->fallspeed = 0; - item->gravityStatus = false; - - return 1; - } - return 0; -} - -int LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - int landspeed = item->fallspeed - 140; - - if (landspeed > 0) - { - if (landspeed <= 14) - { - item->hitPoints -= 1000 * SQUARE(landspeed) / 196; - return item->hitPoints <= 0; - } - else - { - item->hitPoints = -1; - return 1; - } - } - - return 0; -} - -int LaraFallen(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (Lara.waterStatus == LW_WADE || coll->midFloor <= STEPUP_HEIGHT) - { - return 0; - } - - item->animNumber = LA_FALL_START; - item->currentAnimState = LS_JUMP_FORWARD; - item->goalAnimState = LS_JUMP_FORWARD; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->fallspeed = 0; - item->gravityStatus = true; - return 1; -} - -short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h) // (F) (D) -{ - short room = item->roomNumber; - - int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT); - int y = item->pos.yPos - h; - int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT); - - int height = GetCeiling(GetFloor(x, y, z, &room), x, y, z); - - if (height != NO_HEIGHT) - height += h - item->pos.yPos; - - return height; -} - -short LaraFloorFront(ITEM_INFO* item, short ang, int dist) // (F) (D) -{ - short room = item->roomNumber; - - int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT); - int y = item->pos.yPos - 762; - int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT); - - int height = GetFloorHeight(GetFloor(x, y, z, &room), x, y, z); - - if (height != NO_HEIGHT) - height -= item->pos.yPos; - - return height; -} - -int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_NO_ARMS) - return 0; - - EnableCrawlFlex1click = true; - EnableCrawlFlex2click = true; - EnableCrawlFlex3click = true; - EnableMonkeyVault = true; - - if (coll->collType == CT_FRONT) - { - short angle = item->pos.yRot; - bool result; - - if (coll->midSplitFloor) - { - if (coll->frontSplitFloor != coll->midSplitFloor) - return 0; - result = SnapToDiagonal(angle, 30); - } - else - { - result = SnapToQuadrant(angle, 30); - } - - if (!result) - return 0; - - int slope = abs(coll->leftFloor2 - coll->rightFloor2) >= 60; - - if (coll->frontFloor < 0 && coll->frontFloor >= -256) - { - if (!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256) && EnableCrawlFlex1click == true) - { - 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->frontFloor + 256; - Lara.gunStatus = LG_HANDS_BUSY; - } - } - else if (coll->frontFloor >= -640 && coll->frontFloor <= -384) - { - if (!slope && - coll->frontFloor - coll->frontCeiling >= 0 && - coll->leftFloor2 - coll->leftCeiling2 >= 0 && - coll->rightFloor2 - coll->rightCeiling2 >= 0) - { -#if 0 - if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768) - return 0; -#endif - - item->animNumber = LA_VAULT_TO_STAND_2CLICK_START; - item->currentAnimState = LS_GRABBING; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_STOP; - item->pos.yPos += coll->frontFloor + 512; - Lara.gunStatus = LG_HANDS_BUSY; - } - else if ((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256)) && EnableCrawlFlex2click == true) - { - 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->frontFloor + 512; - Lara.gunStatus = LG_HANDS_BUSY; - } - else - { - return 0; - } - } - else if (coll->frontFloor >= -896 && coll->frontFloor <= -640) - { - if (!slope && - coll->frontFloor - coll->frontCeiling >= 0 && - coll->leftFloor2 - coll->leftCeiling2 >= 0 && - coll->rightFloor2 - coll->rightCeiling2 >= 0) - { -#if 0 - if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768) - return 0; -#endif - - item->animNumber = LA_VAULT_TO_STAND_3CLICK; - item->currentAnimState = LS_GRABBING; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_STOP; - item->pos.yPos += coll->frontFloor + 768; - Lara.gunStatus = LG_HANDS_BUSY; - } - else if ((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256) && EnableCrawlFlex3click == true)) - { - 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->frontFloor + 768; - Lara.gunStatus = LG_HANDS_BUSY; - } - else - { - return 0; - } - } - else if (!slope && coll->frontFloor >= -1920 && coll->frontFloor <= -896) - { -#if 0 - if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) - return 0; -#endif - - item->animNumber = LA_STAND_SOLID; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_JUMP_UP; - item->currentAnimState = LS_STOP; - Lara.calcFallSpeed = -3 - sqrt(-9600 - 12 * coll->frontFloor); - AnimateLara(item); - } - else - { - if (!Lara.climbStatus) - return 0; - - if (coll->frontFloor > -1920 || Lara.waterStatus == LW_WADE || coll->leftFloor2 > -1920 || coll->rightFloor2 > -2048 || coll->midCeiling > -1158) - { - if ((coll->frontFloor < -1024 || coll->frontCeiling >= 506) && coll->midCeiling <= -518) - { - ShiftItem(item, coll); - - if (LaraTestClimbStance(item, coll)) - { - item->animNumber = LA_STAND_SOLID; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_LADDER_IDLE; - item->currentAnimState = LS_STOP; - AnimateLara(item); - item->pos.yRot = angle; - Lara.gunStatus = LG_HANDS_BUSY; - return 1; - } - } - return 0; - } - - item->animNumber = LA_STAND_SOLID; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_JUMP_UP; - item->currentAnimState = LS_STOP; - Lara.calcFallSpeed = -116; - AnimateLara(item); - } - - item->pos.yRot = angle; - ShiftItem(item, coll); - - if (coll->midSplitFloor) // diagonal alignment - { - Vector2 v = GetDiagonalIntersect(item->pos.xPos, item->pos.zPos, coll->midSplitFloor, LARA_RAD, item->pos.yRot); - item->pos.xPos = v.x; - item->pos.zPos = v.y; - } - else // regular aligment - { - Vector2 v = GetOrthogonalIntersect(item->pos.xPos, item->pos.zPos, LARA_RAD, item->pos.yRot); - item->pos.xPos = v.x; - item->pos.zPos = v.y; - } - return 1; - } - else if (EnableMonkeyVault == true) - { - if (Lara.canMonkeySwing) - { - FLOOR_INFO* F; - int c, h; - short roomNum = item->roomNumber; - F = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNum); - c = GetCeiling(F, item->pos.xPos, item->pos.yPos, item->pos.zPos); - h = (c)-(item->pos.yPos); - if (h > 1792 || - h < -1792 || - abs(h) == 768) - { - return 0; - } - item->animNumber = LA_STAND_IDLE; - item->frameNumber = g_Level.Anims[LA_STAND_IDLE].frameBase; - item->goalAnimState = LS_JUMP_UP; - item->currentAnimState = LS_TEST_1; - AnimateLara(item); - return 1; - } - } - else - return 0; -} - void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) { if (!(TrInput & IN_ACTION)) @@ -6640,232 +5473,6 @@ void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) item->goalAnimState = LS_ROPE_IDLE; } } - -int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2) - return 0; - - short angle = ANGLE(0.0f); - if (coll->tiltX > 2) - angle = -ANGLE(90.0f); - else if (coll->tiltX < -2) - angle = ANGLE(90.0f); - - if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX)) - angle = ANGLE(180.0f); - else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX)) - angle = ANGLE(0.0f); - - short delta = angle - item->pos.yRot; - - ShiftItem(item, coll); - - if (delta < -ANGLE(90.0f) || delta > ANGLE(90.0f)) - { - if (item->currentAnimState == LS_SLIDE_BACK && OldAngle == angle) - return 1; - - item->animNumber = LA_SLIDE_BACK_START; - item->goalAnimState = LS_SLIDE_BACK; - item->currentAnimState = LS_SLIDE_BACK; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->pos.yRot = angle + ANGLE(180.0f); - Lara.moveAngle = ANGLE(180); - } - else - { - if (item->currentAnimState == LS_SLIDE_FORWARD && OldAngle == angle) - return 1; - - item->animNumber = LA_SLIDE_FORWARD; - item->goalAnimState = LS_SLIDE_FORWARD; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->currentAnimState = LS_SLIDE_FORWARD; - item->pos.yRot = angle; - Lara.moveAngle = 0; - } - - OldAngle = angle; - - return 1; -} - -int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) -{ - int delta, flag, flag2, front, dfront, x, z, result; - short angle, hdif, cdif, dir; - ANIM_FRAME* frame; - - delta = 0; - flag = 0; - angle = Lara.moveAngle; - if (angle == -ANGLE(90)) - { - delta = -100; - } - else if (angle == ANGLE(90)) - { - delta = 100; - } - hdif = LaraFloorFront(item, item->pos.yRot + angle, 100); - if (hdif < 200) - flag = 1; - cdif = LaraCeilingFront(item, item->pos.yRot + angle, 100, 0); - dir = GetQuadrant(item->pos.yRot); - switch (dir) - { - case NORTH: - item->pos.zPos += 4; - break; - case EAST: - item->pos.xPos += 4; - break; - case SOUTH: - item->pos.zPos -= 4; - break; - case WEST: - item->pos.xPos -= 4; - break; - } - coll->badPos = NO_BAD_POS; - coll->badNeg = -STEPUP_HEIGHT; - coll->badCeiling = 0; - Lara.moveAngle = 0; - coll->facing = Lara.moveAngle; - GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE); - result = 0; - if (Lara.climbStatus) - { - if (TrInput & IN_ACTION && item->hitPoints > 0) - { - Lara.moveAngle = angle; - if (!LaraTestHangOnClimbWall(item, coll)) - { - if (item->animNumber != LA_LADDER_TO_HANG_RIGHT && item->animNumber != LA_LADDER_TO_HANG_LEFT) - { - SnapLaraToEdgeOfBlock(item, coll, dir); - item->pos.yPos = coll->old.y; - item->currentAnimState = LS_HANG; - item->goalAnimState = LS_HANG; - item->animNumber = LA_REACH_TO_HANG; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; - } - result = 1; - } - else - { - if (item->animNumber == LA_REACH_TO_HANG && item->frameNumber == g_Level.Anims[LA_REACH_TO_HANG].frameBase + 21 && LaraTestClimbStance(item, coll)) - item->goalAnimState = LS_LADDER_IDLE; - } - } - else - { - item->animNumber = LA_FALL_START; - item->currentAnimState = LS_JUMP_FORWARD; - item->goalAnimState = LS_JUMP_FORWARD; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->pos.yPos += 256; - item->gravityStatus = true; - item->speed = 2; - item->fallspeed = 1; - Lara.gunStatus = LG_NO_ARMS; - } - } - else - { - if (TrInput & IN_ACTION && item->hitPoints > 0 && coll->frontFloor <= 0) - { - if (flag && hdif > 0 && delta > 0 == coll->leftFloor > coll->rightFloor) - flag = 0; - frame = (ANIM_FRAME*)GetBoundsAccurate(item); - front = coll->frontFloor; - dfront = coll->frontFloor - frame->boundingBox.Y1; - flag2 = 0; - x = item->pos.xPos; - z = item->pos.zPos; - switch (dir) - { - case NORTH: - x += delta; - break; - case EAST: - z -= delta; - break; - case SOUTH: - x -= delta; - break; - case WEST: - z += delta; - break; - } - Lara.moveAngle = angle; - if (256 << dir & GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber)) - { - if (!LaraTestHangOnClimbWall(item, coll)) - dfront = 0; - } - else if (abs(coll->leftFloor2 - coll->rightFloor2) >= 60) - { - if (delta < 0 && coll->leftFloor2 != coll->frontFloor || delta > 0 && coll->rightFloor2 != coll->frontFloor) - flag2 = 1; - } - coll->frontFloor = front; - if (!flag2 && coll->midCeiling < 0 && coll->collType == CT_FRONT && !flag && !coll->hitStatic && cdif <= -950 && dfront >= -60 && dfront <= 60) - { - switch (dir) - { - case NORTH: - case SOUTH: - item->pos.zPos += coll->shift.z; - break; - case EAST: - case WEST: - item->pos.xPos += coll->shift.x; - break; - } - item->pos.yPos += dfront; - } - else - { - item->pos.xPos = coll->old.x; - item->pos.yPos = coll->old.y; - item->pos.zPos = coll->old.z; - if (item->currentAnimState == LS_SHIMMY_LEFT || item->currentAnimState == LS_SHIMMY_RIGHT) - { - item->currentAnimState = LS_HANG; - item->goalAnimState = LS_HANG; - item->animNumber = LA_REACH_TO_HANG; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; - } - else if (item->currentAnimState == LS_SHIMMY_FEET_LEFT || item->currentAnimState == LS_SHIMMY_FEET_RIGHT) - { - item->currentAnimState = LS_HANG_FEET; - item->goalAnimState = LS_HANG_FEET; - item->animNumber = LA_HANG_FEET_IDLE; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - } - result = 1; - } - } - else - { - item->currentAnimState = LS_JUMP_UP; - item->goalAnimState = LS_JUMP_UP; - item->animNumber = LA_JUMP_UP; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 9; - frame = (ANIM_FRAME*) GetBoundsAccurate(item); - item->pos.xPos += coll->shift.x; - item->pos.yPos += frame->boundingBox.Y2; - item->pos.zPos += coll->shift.z; - item->gravityStatus = true; - item->speed = 2; - item->fallspeed = 1; - Lara.gunStatus = LG_NO_ARMS; - } - } - return result; -} /********************** NEW FEET HANGING STUFF ////obviously, not all animations were made yet, we still need: @@ -6873,72 +5480,6 @@ NEW FEET HANGING STUFF -corner anims (works well, tested with placeholder anim) -handstand (not tested) ***********************/ -int TestHangFeet(ITEM_INFO* item, short angle) -{ - if (Lara.climbStatus) - return 0; - - // EnableFeetHang = true; - - - if (!EnableFeetHang) - return 0; - - int x = item->pos.xPos; - int y = item->pos.yPos; - int z = item->pos.zPos; - short roomNum = item->roomNumber; - FLOOR_INFO* floor; - int h, c, g, m, j; - - if (angle == ANGLE(180.0f)) - { - z -= 256; - } - else if (angle == -ANGLE(90.0f)) - { - x -= 256; - } - else if (angle == ANGLE(90.0f)) - { - x += 256; - } - else if (angle == ANGLE(0.0f)) - { - z += 256; - } - - floor = GetFloor(x, y, z, &roomNum); - h = GetFloorHeight(floor, x, y, z); - c = GetCeiling(floor, x, y, z); - g = h - y; - m = c - y; - j = y - 128 - c; - - if (item->currentAnimState == LS_CRAWL_TO_HANG) - { - if (h != NO_HEIGHT) - { - if (((g) > 0) - && ((m) < -128) - && ((j) > -72)) - return(1); - } - return(0); - } - else - { - if (h != NO_HEIGHT) - { - if (((g) > 0) - && ((m) < -128) - && ((j) > -72)) - return(0); - } - return(1); - } -} - void lara_as_hang_feet(ITEM_INFO* item, COLL_INFO* coll) { Lara.isClimbing = false; @@ -7151,39 +5692,3 @@ void lara_as_hang_feet_outLcorner(ITEM_INFO* item, COLL_INFO* coll) SetCornerAnimFeet(item, coll, ANGLE(90.0f), item->animNumber = LA_SHIMMY_FEET_LEFT_CORNER_OUTER); } - -void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip) -{ - if (item->hitPoints <= 0) - { - item->goalAnimState = LS_JUMP_FORWARD; - item->currentAnimState = LS_JUMP_FORWARD; - item->animNumber = LA_FALL_START; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - - item->gravityStatus = true; - item->speed = 2; - item->pos.yPos += 256; - item->fallspeed = 1; - - Lara.gunStatus = LG_NO_ARMS; - - item->pos.yRot += rot / 2; - } - else if (flip) - { - - item->animNumber = LA_HANG_FEET_IDLE; - item->frameNumber = g_Level.Anims[item->animNumber].frameBase; - item->goalAnimState = LS_HANG_FEET; - item->currentAnimState = LS_HANG_FEET; - - coll->old.x = Lara.cornerX; - item->pos.xPos = Lara.cornerX; - - coll->old.z = Lara.cornerZ; - item->pos.zPos = Lara.cornerZ; - - item->pos.yRot += rot; - } -} \ No newline at end of file diff --git a/TR5Main/Game/Lara/lara.h b/TR5Main/Game/Lara/lara.h index 53f9b200f..db56ff4ca 100644 --- a/TR5Main/Game/Lara/lara.h +++ b/TR5Main/Game/Lara/lara.h @@ -26,7 +26,6 @@ extern byte LaraNodeUnderwater[NUM_LARA_MESHES]; #define LaraRoutineFunction void(ITEM_INFO* item, COLL_INFO* coll) extern std::function lara_control_routines[NUM_LARA_STATES + 1]; extern std::function lara_collision_routines[NUM_LARA_STATES + 1]; -///extern function lara_camera_routines[NUM_LARA_STATES + 1]; void lara_as_pbleapoff(ITEM_INFO* item, COLL_INFO* coll); void lara_as_parallelbars(ITEM_INFO* item, COLL_INFO* coll); @@ -171,43 +170,21 @@ void GetTighRopeFallOff(int Regularity); void LookLeftRight(); void LookUpDown(); void ResetLook(); -void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip); -int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle); void UpdateRopeSwing(ITEM_INFO* item); void JumpOffRope(ITEM_INFO* item); void FallFromRope(ITEM_INFO* item); short GetDirOctant(int rot); -short TestMonkeyRight(ITEM_INFO* item, COLL_INFO* coll); -short TestMonkeyLeft(ITEM_INFO* item, COLL_INFO* coll); void MonkeySwingSnap(ITEM_INFO* item, COLL_INFO* coll); void MonkeySwingFall(ITEM_INFO* item); void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll); int TestHangSwingIn(ITEM_INFO* item, short angle); -int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll); -int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll); -int IsValidHangPos(ITEM_INFO* item, COLL_INFO* coll); -int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll); void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle); -int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll); void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll); void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll); void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll); void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll); -int TestWall(ITEM_INFO* item, int front, int right, int down); -int LaraTestClimbStance(ITEM_INFO* item, COLL_INFO* coll); -int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge); -int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll); -int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll); -int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll); -int LaraLandedBad(ITEM_INFO* l, COLL_INFO* coll); -int LaraFallen(ITEM_INFO* item, COLL_INFO* coll); -int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll); -short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h); -short LaraFloorFront(ITEM_INFO* item, short ang, int dist); -int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll); int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll); void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll); -int TestHangFeet(ITEM_INFO* item, short angle); void lara_as_hang_feet(ITEM_INFO* item, COLL_INFO* coll); void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll); void lara_as_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll); @@ -218,4 +195,3 @@ void lara_as_hang_feet_inRcorner(ITEM_INFO* item, COLL_INFO* coll); void lara_as_hang_feet_inLcorner(ITEM_INFO* item, COLL_INFO* coll); void lara_as_hang_feet_outRcorner(ITEM_INFO* item, COLL_INFO* coll); void lara_as_hang_feet_outLcorner(ITEM_INFO* item, COLL_INFO* coll); -void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip); \ No newline at end of file diff --git a/TR5Main/Game/Lara/lara_tests.cpp b/TR5Main/Game/Lara/lara_tests.cpp new file mode 100644 index 000000000..02ee22402 --- /dev/null +++ b/TR5Main/Game/Lara/lara_tests.cpp @@ -0,0 +1,1508 @@ +#include "framework.h" +#include "lara.h" +#include "lara_tests.h" +#include "input.h" +#include "laramisc.h" +#include "draw.h" +#include "laraclmb.h" + +static short LeftClimbTab[4] = // offset 0xA0638 +{ + 0x0200, 0x0400, 0x0800, 0x0100 +}; + +static short RightClimbTab[4] = // offset 0xA0640 +{ + 0x0800, 0x0100, 0x0200, 0x0400 +}; + +short OldAngle = 1; +//bool EnableCrawlFlex1click, EnableCrawlFlex2click, EnableCrawlFlex3click, EnableMonkeyVault; +//bool TR12_OSCILLATE_HANG, EnableFeetHang; + + +int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_NO_ARMS) + return 0; + +// EnableCrawlFlex1click = true; +// EnableCrawlFlex2click = true; +// EnableCrawlFlex3click = true; +// EnableMonkeyVault = true; + + if (coll->collType == CT_FRONT) + { + short angle = item->pos.yRot; + bool result; + + if (coll->midSplitFloor) + { + if (coll->frontSplitFloor != coll->midSplitFloor) + return 0; + result = SnapToDiagonal(angle, 30); + } + else + { + result = SnapToQuadrant(angle, 30); + } + + if (!result) + return 0; + + int slope = abs(coll->leftFloor2 - coll->rightFloor2) >= 60; + + if (coll->frontFloor < 0 && coll->frontFloor >= -256) + { + if (!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256))// && EnableCrawlFlex1click == true) + { + 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->frontFloor + 256; + Lara.gunStatus = LG_HANDS_BUSY; + } + } + else if (coll->frontFloor >= -640 && coll->frontFloor <= -384) + { + if (!slope && + coll->frontFloor - coll->frontCeiling >= 0 && + coll->leftFloor2 - coll->leftCeiling2 >= 0 && + coll->rightFloor2 - coll->rightCeiling2 >= 0) + { +#if 0 + if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768) + return 0; +#endif + + item->animNumber = LA_VAULT_TO_STAND_2CLICK_START; + item->currentAnimState = LS_GRABBING; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_STOP; + item->pos.yPos += coll->frontFloor + 512; + Lara.gunStatus = LG_HANDS_BUSY; + } + else if ((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256)))// && EnableCrawlFlex2click == true) + { + 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->frontFloor + 512; + Lara.gunStatus = LG_HANDS_BUSY; + } + else + { + return 0; + } + } + else if (coll->frontFloor >= -896 && coll->frontFloor <= -640) + { + if (!slope && + coll->frontFloor - coll->frontCeiling >= 0 && + coll->leftFloor2 - coll->leftCeiling2 >= 0 && + coll->rightFloor2 - coll->rightCeiling2 >= 0) + { +#if 0 + if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768) + return 0; +#endif + + item->animNumber = LA_VAULT_TO_STAND_3CLICK; + item->currentAnimState = LS_GRABBING; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_STOP; + item->pos.yPos += coll->frontFloor + 768; + Lara.gunStatus = LG_HANDS_BUSY; + } + else if ((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256)))// && EnableCrawlFlex3click == true)) + { + 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->frontFloor + 768; + Lara.gunStatus = LG_HANDS_BUSY; + } + else + { + return 0; + } + } + else if (!slope && coll->frontFloor >= -1920 && coll->frontFloor <= -896) + { +#if 0 + if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) + return 0; +#endif + + item->animNumber = LA_STAND_SOLID; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_JUMP_UP; + item->currentAnimState = LS_STOP; + Lara.calcFallSpeed = -3 - sqrt(-9600 - 12 * coll->frontFloor); + AnimateLara(item); + } + else + { + if (!Lara.climbStatus) + return 0; + + if (coll->frontFloor > -1920 || Lara.waterStatus == LW_WADE || coll->leftFloor2 > -1920 || coll->rightFloor2 > -2048 || coll->midCeiling > -1158) + { + if ((coll->frontFloor < -1024 || coll->frontCeiling >= 506) && coll->midCeiling <= -518) + { + ShiftItem(item, coll); + + if (LaraTestClimbStance(item, coll)) + { + item->animNumber = LA_STAND_SOLID; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_LADDER_IDLE; + item->currentAnimState = LS_STOP; + AnimateLara(item); + item->pos.yRot = angle; + Lara.gunStatus = LG_HANDS_BUSY; + return 1; + } + } + return 0; + } + + item->animNumber = LA_STAND_SOLID; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_JUMP_UP; + item->currentAnimState = LS_STOP; + Lara.calcFallSpeed = -116; + AnimateLara(item); + } + + item->pos.yRot = angle; + ShiftItem(item, coll); + + if (coll->midSplitFloor) // diagonal alignment + { + Vector2 v = GetDiagonalIntersect(item->pos.xPos, item->pos.zPos, coll->midSplitFloor, LARA_RAD, item->pos.yRot); + item->pos.xPos = v.x; + item->pos.zPos = v.y; + } + else // regular aligment + { + Vector2 v = GetOrthogonalIntersect(item->pos.xPos, item->pos.zPos, LARA_RAD, item->pos.yRot); + item->pos.xPos = v.x; + item->pos.zPos = v.y; + } + return 1; + } + else// if (EnableMonkeyVault == true) + { + if (Lara.canMonkeySwing) + { + FLOOR_INFO* F; + int c, h; + short roomNum = item->roomNumber; + F = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNum); + c = GetCeiling(F, item->pos.xPos, item->pos.yPos, item->pos.zPos); + h = (c)-(item->pos.yPos); + if (h > 1792 || + h < -1792 || + abs(h) == 768) + { + return 0; + } + item->animNumber = LA_STAND_IDLE; + item->frameNumber = g_Level.Anims[LA_STAND_IDLE].frameBase; + item->goalAnimState = LS_JUMP_UP; + item->currentAnimState = LS_TEST_1; + AnimateLara(item); + return 1; + } + } +// else + return 0; +} + +int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2) + return 0; + + short angle = ANGLE(0.0f); + if (coll->tiltX > 2) + angle = -ANGLE(90.0f); + else if (coll->tiltX < -2) + angle = ANGLE(90.0f); + + if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX)) + angle = ANGLE(180.0f); + else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX)) + angle = ANGLE(0.0f); + + short delta = angle - item->pos.yRot; + + ShiftItem(item, coll); + + if (delta < -ANGLE(90.0f) || delta > ANGLE(90.0f)) + { + if (item->currentAnimState == LS_SLIDE_BACK && OldAngle == angle) + return 1; + + item->animNumber = LA_SLIDE_BACK_START; + item->goalAnimState = LS_SLIDE_BACK; + item->currentAnimState = LS_SLIDE_BACK; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->pos.yRot = angle + ANGLE(180.0f); + Lara.moveAngle = ANGLE(180); + } + else + { + if (item->currentAnimState == LS_SLIDE_FORWARD && OldAngle == angle) + return 1; + + item->animNumber = LA_SLIDE_FORWARD; + item->goalAnimState = LS_SLIDE_FORWARD; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->currentAnimState = LS_SLIDE_FORWARD; + item->pos.yRot = angle; + Lara.moveAngle = 0; + } + + OldAngle = angle; + + return 1; +} + +int TestWall(ITEM_INFO* item, int front, int right, int down)//12550, 12600 (F) +{ + int x = item->pos.xPos; + int y = item->pos.yPos + down; + int z = item->pos.zPos; + + short angle = GetQuadrant(item->pos.yRot); + short roomNum = item->roomNumber; + + FLOOR_INFO* floor; + int h, c; + + switch (angle) + { + case NORTH: + x -= right; + break; + case EAST: + z -= right; + break; + case SOUTH: + x += right; + break; + case WEST: + z += right; + break; + default: + break; + } + + GetFloor(x, y, z, &roomNum); + + switch (angle) + { + case NORTH: + z += front; + break; + case EAST: + x += front; + break; + case SOUTH: + z -= front; + break; + case WEST: + x -= front; + break; + default: + break; + } + + floor = GetFloor(x, y, z, &roomNum); + h = GetFloorHeight(floor, x, y, z); + c = GetCeiling(floor, x, y, z); + + if (h == NO_HEIGHT) + return 1; + + if (y >= h || y <= c) + return 2; + + return 0; +} + +int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + int delta, flag, flag2, front, dfront, x, z, result; + short angle, hdif, cdif, dir; + ANIM_FRAME* frame; + + delta = 0; + flag = 0; + angle = Lara.moveAngle; + if (angle == -ANGLE(90)) + { + delta = -100; + } + else if (angle == ANGLE(90)) + { + delta = 100; + } + hdif = LaraFloorFront(item, item->pos.yRot + angle, 100); + if (hdif < 200) + flag = 1; + cdif = LaraCeilingFront(item, item->pos.yRot + angle, 100, 0); + dir = GetQuadrant(item->pos.yRot); + switch (dir) + { + case NORTH: + item->pos.zPos += 4; + break; + case EAST: + item->pos.xPos += 4; + break; + case SOUTH: + item->pos.zPos -= 4; + break; + case WEST: + item->pos.xPos -= 4; + break; + } + coll->badPos = NO_BAD_POS; + coll->badNeg = -STEPUP_HEIGHT; + coll->badCeiling = 0; + Lara.moveAngle = 0; + coll->facing = Lara.moveAngle; + GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE); + result = 0; + if (Lara.climbStatus) + { + if (TrInput & IN_ACTION && item->hitPoints > 0) + { + Lara.moveAngle = angle; + if (!LaraTestHangOnClimbWall(item, coll)) + { + if (item->animNumber != LA_LADDER_TO_HANG_RIGHT && item->animNumber != LA_LADDER_TO_HANG_LEFT) + { + SnapLaraToEdgeOfBlock(item, coll, dir); + item->pos.yPos = coll->old.y; + item->currentAnimState = LS_HANG; + item->goalAnimState = LS_HANG; + item->animNumber = LA_REACH_TO_HANG; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; + } + result = 1; + } + else + { + if (item->animNumber == LA_REACH_TO_HANG && item->frameNumber == g_Level.Anims[LA_REACH_TO_HANG].frameBase + 21 && LaraTestClimbStance(item, coll)) + item->goalAnimState = LS_LADDER_IDLE; + } + } + else + { + item->animNumber = LA_FALL_START; + item->currentAnimState = LS_JUMP_FORWARD; + item->goalAnimState = LS_JUMP_FORWARD; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->pos.yPos += 256; + item->gravityStatus = true; + item->speed = 2; + item->fallspeed = 1; + Lara.gunStatus = LG_NO_ARMS; + } + } + else + { + if (TrInput & IN_ACTION && item->hitPoints > 0 && coll->frontFloor <= 0) + { + if (flag && hdif > 0 && delta > 0 == coll->leftFloor > coll->rightFloor) + flag = 0; + frame = (ANIM_FRAME*)GetBoundsAccurate(item); + front = coll->frontFloor; + dfront = coll->frontFloor - frame->boundingBox.Y1; + flag2 = 0; + x = item->pos.xPos; + z = item->pos.zPos; + switch (dir) + { + case NORTH: + x += delta; + break; + case EAST: + z -= delta; + break; + case SOUTH: + x -= delta; + break; + case WEST: + z += delta; + break; + } + Lara.moveAngle = angle; + if (256 << dir & GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber)) + { + if (!LaraTestHangOnClimbWall(item, coll)) + dfront = 0; + } + else if (abs(coll->leftFloor2 - coll->rightFloor2) >= 60) + { + if (delta < 0 && coll->leftFloor2 != coll->frontFloor || delta > 0 && coll->rightFloor2 != coll->frontFloor) + flag2 = 1; + } + coll->frontFloor = front; + if (!flag2 && coll->midCeiling < 0 && coll->collType == CT_FRONT && !flag && !coll->hitStatic && cdif <= -950 && dfront >= -60 && dfront <= 60) + { + switch (dir) + { + case NORTH: + case SOUTH: + item->pos.zPos += coll->shift.z; + break; + case EAST: + case WEST: + item->pos.xPos += coll->shift.x; + break; + } + item->pos.yPos += dfront; + } + else + { + item->pos.xPos = coll->old.x; + item->pos.yPos = coll->old.y; + item->pos.zPos = coll->old.z; + if (item->currentAnimState == LS_SHIMMY_LEFT || item->currentAnimState == LS_SHIMMY_RIGHT) + { + item->currentAnimState = LS_HANG; + item->goalAnimState = LS_HANG; + item->animNumber = LA_REACH_TO_HANG; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; + } + else if (item->currentAnimState == LS_SHIMMY_FEET_LEFT || item->currentAnimState == LS_SHIMMY_FEET_RIGHT) + { + item->currentAnimState = LS_HANG_FEET; + item->goalAnimState = LS_HANG_FEET; + item->animNumber = LA_HANG_FEET_IDLE; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + } + result = 1; + } + } + else + { + item->currentAnimState = LS_JUMP_UP; + item->goalAnimState = LS_JUMP_UP; + item->animNumber = LA_JUMP_UP; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 9; + frame = (ANIM_FRAME*)GetBoundsAccurate(item); + item->pos.xPos += coll->shift.x; + item->pos.yPos += frame->boundingBox.Y2; + item->pos.zPos += coll->shift.z; + item->gravityStatus = true; + item->speed = 2; + item->fallspeed = 1; + Lara.gunStatus = LG_NO_ARMS; + } + } + return result; +} + +int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE) + return 0; + + if (coll->hitStatic) + return 0; + + int x; + int z; + + int oldXpos = item->pos.xPos; + int oldZpos = item->pos.zPos; + short oldYrot = item->pos.yRot; + int oldFrontFloor = coll->frontFloor; + + short angle = GetQuadrant(item->pos.yRot); + if (angle != NORTH && angle != SOUTH) + { + x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + } + else + { + x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); + z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); + } + + item->pos.xPos = x; + Lara.cornerX = x; + item->pos.zPos = z; + Lara.cornerZ = z; + item->pos.yRot -= ANGLE(90.0f); + + int result = -IsValidHangPos(item, coll); + if (result) + { + if (Lara.climbStatus) + { + if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle]) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + } + else + { + if (abs(oldFrontFloor - coll->frontFloor) <= 60) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + } + } + + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + + if (LaraFloorFront(item, oldYrot - ANGLE(90.0f), 116) < 0) + return 0; + + switch (angle) + { + case NORTH: + x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.xPos - SECTOR(1); + z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.zPos + SECTOR(1); + break; + + case SOUTH: + x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1)); + z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1)); + break; + + case WEST: + x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF); + z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF); + break; + + default: + x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); + z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); + break; + + } + + item->pos.xPos = x; + Lara.cornerX = x; + item->pos.zPos = z; + Lara.cornerZ = z; + item->pos.yRot += ANGLE(90.0f); + + result = IsValidHangPos(item, coll); + if (!result) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + + if (!Lara.climbStatus) + { + if (abs(oldFrontFloor - coll->frontFloor) <= 60) + { + switch (angle) + { + case NORTH: + if ((oldXpos & 0x3FF) > 512) + result = 0; + break; + case EAST: + if ((oldZpos & 0x3FF) < 512) + result = 0; + break; + case SOUTH: + if ((oldXpos & 0x3FF) < 512) + result = 0; + break; + case WEST: + if ((oldZpos & 0x3FF) > 512) + result = 0; + break; + } + return result; + } + return 0; + } + + if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle]) + return result; + + short front = LaraFloorFront(item, item->pos.yRot, 116); + if (abs(front - coll->frontFloor) > 60) + return 0; + + if (front < -768) + return 0; + + return result; +} + +int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE) + return 0; + + if (coll->hitStatic) + return 0; + + int x; + int z; + + int oldXpos = item->pos.xPos; + int oldZpos = item->pos.zPos; + short oldYrot = item->pos.yRot; + int oldFrontFloor = coll->frontFloor; + + short angle = GetQuadrant(item->pos.yRot); + if (angle != NORTH && angle != SOUTH) + { + x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); + z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); + } + else + { + x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF; + } + + item->pos.xPos = x; + Lara.cornerX = x; + item->pos.zPos = z; + Lara.cornerZ = z; + item->pos.yRot += ANGLE(90.0f); + + int result = -IsValidHangPos(item, coll); + if (result) + { + if (Lara.climbStatus) + { + if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle]) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + } + else + { + if (abs(oldFrontFloor - coll->frontFloor) <= 60) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + } + } + + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + + if (LaraFloorFront(item, oldYrot + ANGLE(90.0f), 116) < 0) + return 0; + + switch (angle) + { + case NORTH: + x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); + z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); + break; + + case SOUTH: + x = ((item->pos.xPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1); + z = ((item->pos.zPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1); + break; + + case WEST: + x = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.xPos - SECTOR(1)); + z = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.zPos + SECTOR(1)); + break; + + default: + x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1)); + z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1)); + break; + + } + + item->pos.xPos = x; + Lara.cornerX = x; + item->pos.zPos = z; + Lara.cornerZ = z; + item->pos.yRot -= ANGLE(90.0f); + + result = IsValidHangPos(item, coll); + if (!result) + { + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + return result; + } + + item->pos.xPos = oldXpos; + item->pos.zPos = oldZpos; + item->pos.yRot = oldYrot; + Lara.moveAngle = 0; + + if (!Lara.climbStatus) + { + if (abs(oldFrontFloor - coll->frontFloor) <= 60) + { + switch (angle) + { + case NORTH: + if ((oldXpos & 0x3FF) < 512) + result = 0; + break; + case EAST: + if ((oldZpos & 0x3FF) > 512) + result = 0; + break; + case SOUTH: + if ((oldXpos & 0x3FF) > 512) + result = 0; + break; + case WEST: + if ((oldZpos & 0x3FF) < 512) + result = 0; + break; + } + return result; + } + return 0; + } + + if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle]) + return result; + + short front = LaraFloorFront(item, item->pos.yRot, 116); + if (abs(front - coll->frontFloor) > 60) + return 0; + + if (front < -768) + return 0; + + return result; +} + +int IsValidHangPos(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (LaraFloorFront(item, item->pos.yRot + Lara.moveAngle, 100) < 200) + return 0; + + short angle = GetQuadrant(item->pos.yRot); + switch (angle) + { + case NORTH: + item->pos.zPos += 4; + break; + case EAST: + item->pos.xPos += 4; + break; + case SOUTH: + item->pos.zPos -= 4; + break; + case WEST: + item->pos.xPos -= 4; + break; + default: + break; + } + + coll->badPos = NO_BAD_POS; + coll->badNeg = -512; + coll->badCeiling = 0; + + Lara.moveAngle = 0; + + coll->facing = Lara.moveAngle; + GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE); + + if (coll->midCeiling >= 0 || coll->collType != CT_FRONT || coll->hitStatic) + return 0; + + return abs(coll->frontFloor - coll->rightFloor2) < 60; +} + +int LaraTestClimbStance(ITEM_INFO* item, COLL_INFO* coll)//11F78, 12028 +{ + int shift_r, shift_l; + + if (LaraTestClimbPos(item, coll->radius, coll->radius + 120, -700, 512, &shift_r) != 1) + return false; + + if (LaraTestClimbPos(item, coll->radius, -(coll->radius + 120), -700, 512, &shift_l) != 1) + return false; + + if (shift_r) + { + if (shift_l) + { + if (shift_r < 0 != shift_l < 0) + return false; + + if ((shift_r < 0 && shift_l < shift_r) || + (shift_r > 0 && shift_l > shift_r)) + { + item->pos.yPos += shift_l; + return true; + } + } + + item->pos.yPos += shift_r; + } + else if (shift_l) + { + item->pos.yPos += shift_l; + } + + return true; +} + +int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + BOUNDING_BOX* bounds; + int shift, result; + + if (Lara.climbStatus == 0) + return 0; + + if (item->fallspeed < 0) + return 0; + + switch (GetQuadrant(item->pos.yRot)) + { + case NORTH: + case SOUTH: + item->pos.zPos += coll->shift.z; + break; + + case EAST: + case WEST: + item->pos.xPos += coll->shift.x; + break; + + default: + break; + } + + + bounds = GetBoundsAccurate(item); + + if (Lara.moveAngle) + { + short l = LaraCeilingFront(item, item->pos.yRot, 0, 0); + short r = LaraCeilingFront(item, item->pos.yRot + Lara.moveAngle, 128, 0); + + if (abs(l - r) > 60) + return 0; + } + + if (LaraTestClimbPos(item, coll->radius, coll->radius, bounds->Y1, bounds->Y2 - bounds->Y1, &shift) && + LaraTestClimbPos(item, coll->radius, -coll->radius, bounds->Y1, bounds->Y2 - bounds->Y1, &shift)) + { + result = LaraTestClimbPos(item, coll->radius, 0, bounds->Y1, bounds->Y2 - bounds->Y1, &shift); + if (result) + { + if (result != 1) + item->pos.yPos += shift; + return 1; + } + } + + return 0; +} + +int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge) // (F) (D) +{ + + BOUNDING_BOX* bounds = GetBoundsAccurate(item); + int hdif = coll->frontFloor - bounds->Y1; + + if (hdif < 0 == hdif + item->fallspeed < 0) + { + hdif = item->pos.yPos + bounds->Y1; + + if ((hdif + item->fallspeed & 0xFFFFFF00) != (hdif & 0xFFFFFF00)) + { + if (item->fallspeed > 0) + *edge = (hdif + item->fallspeed) & 0xFFFFFF00; + else + *edge = hdif & 0xFFFFFF00; + + return -1; + } + + return 0; + } + + if (abs(coll->leftFloor2 - coll->rightFloor2) >= SLOPE_DIF) + return 0; + + return 1; +} + +int TestHangSwingIn(ITEM_INFO* item, short angle)//14104, 141B4 (F) +{ + int x = item->pos.xPos; + int y = item->pos.yPos; + int z = item->pos.zPos; + short roomNum = item->roomNumber; + FLOOR_INFO* floor; + int h, c; + + //debug till scripting be ready +// TR12_OSCILLATE_HANG = true; + + /*if (angle == ANGLE(180.0f)) + { + z -= 256; + } + else if (angle == -ANGLE(90)) + { + x -= 256; + } + else if (angle == ANGLE(90)) + { + x += 256; + } + else if (angle == ANGLE(0)) + { + z += 256; + }*/ + + z += (phd_cos(angle) * STEP_SIZE) >> W2V_SHIFT; + x += (phd_sin(angle) * STEP_SIZE) >> W2V_SHIFT; + + floor = GetFloor(x, y, z, &roomNum); + h = GetFloorHeight(floor, x, y, z); + c = GetCeiling(floor, x, y, z); + + if (h != NO_HEIGHT) + { +/* if (TR12_OSCILLATE_HANG == true) + { + if (((h - y) > 0) + && ((c - y) < -400)) + return(1); + } + else + {*/ + if (((h - y) > 0) + && ((c - y) < -400) + && ((y - 819 - c) > -72)) + return(1); +// } + } + return(0); +} + +int TestHangFeet(ITEM_INFO* item, short angle) +{ + return 0; + if (Lara.climbStatus) + return 0; + + // EnableFeetHang = true; + + +// if (!EnableFeetHang) +// return 0; + + int x = item->pos.xPos; + int y = item->pos.yPos; + int z = item->pos.zPos; + short roomNum = item->roomNumber; + FLOOR_INFO* floor; + int h, c, g, m, j; + + if (angle == ANGLE(180.0f)) + { + z -= 256; + } + else if (angle == -ANGLE(90.0f)) + { + x -= 256; + } + else if (angle == ANGLE(90.0f)) + { + x += 256; + } + else if (angle == ANGLE(0.0f)) + { + z += 256; + } + + floor = GetFloor(x, y, z, &roomNum); + h = GetFloorHeight(floor, x, y, z); + c = GetCeiling(floor, x, y, z); + g = h - y; + m = c - y; + j = y - 128 - c; + + if (item->currentAnimState == LS_CRAWL_TO_HANG) + { + if (h != NO_HEIGHT) + { + if (((g) > 0) + && ((m) < -128) + && ((j) > -72)) + return(1); + } + return(0); + } + else + { + if (h != NO_HEIGHT) + { + if (((g) > 0) + && ((m) < -128) + && ((j) > -72)) + return(0); + } + return(1); + } +} + +int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle)//19930, 19A64 (F) +{ + int oldx = item->pos.xPos; + int oldz = item->pos.zPos; + int x = item->pos.xPos; + int z = item->pos.zPos; + int res; + + Lara.moveAngle = angle; + + switch (GetQuadrant(item->pos.yRot + Lara.moveAngle)) + { + case 0: + z += 16; + break; + case 1: + x += 16; + break; + case 2: + z -= 16; + break; + case 3: + x -= 16; + break; + } + + item->pos.xPos = x; + item->pos.zPos = z; + + coll->old.y = item->pos.yPos; + + res = LaraHangTest(item, coll); + + item->pos.xPos = oldx; + item->pos.zPos = oldz; + + Lara.moveAngle = angle; + + return !res; +} + +void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip)//1A090, 1A1C4 (F) +{ + if (item->hitPoints <= 0) + { + item->goalAnimState = LS_JUMP_FORWARD; + item->currentAnimState = LS_JUMP_FORWARD; + item->animNumber = LA_FALL_START; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + + item->gravityStatus = true; + item->speed = 2; + item->pos.yPos += 256; + item->fallspeed = 1; + + Lara.gunStatus = LG_NO_ARMS; + + item->pos.yRot += rot / 2; + } + else if (flip) + { + if (Lara.isClimbing) + { + item->animNumber = LA_LADDER_IDLE; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_LADDER_IDLE; + item->currentAnimState = LS_LADDER_IDLE; + } + else + { + item->animNumber = LA_REACH_TO_HANG; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 21; + item->goalAnimState = LS_HANG; + item->currentAnimState = LS_HANG; + } + + coll->old.x = Lara.cornerX; + item->pos.xPos = Lara.cornerX; + + coll->old.z = Lara.cornerZ; + item->pos.zPos = Lara.cornerZ; + + item->pos.yRot += rot; + } +} + +void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip) +{ + if (item->hitPoints <= 0) + { + item->goalAnimState = LS_JUMP_FORWARD; + item->currentAnimState = LS_JUMP_FORWARD; + item->animNumber = LA_FALL_START; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + + item->gravityStatus = true; + item->speed = 2; + item->pos.yPos += 256; + item->fallspeed = 1; + + Lara.gunStatus = LG_NO_ARMS; + + item->pos.yRot += rot / 2; + } + else if (flip) + { + + item->animNumber = LA_HANG_FEET_IDLE; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->goalAnimState = LS_HANG_FEET; + item->currentAnimState = LS_HANG_FEET; + + coll->old.x = Lara.cornerX; + item->pos.xPos = Lara.cornerX; + + coll->old.z = Lara.cornerZ; + item->pos.zPos = Lara.cornerZ; + + item->pos.yRot += rot; + } +} + +short TestMonkeyRight(ITEM_INFO* item, COLL_INFO* coll)//161EC(<), 16320(<) (F) +{ + short oct; + + coll->badPos = NO_BAD_POS; + coll->badNeg = -STEPUP_HEIGHT; + coll->badCeiling = 0; + Lara.moveAngle = ANGLE(90); + coll->slopesAreWalls = 0; + coll->facing = Lara.moveAngle; + coll->radius = 100; + + GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600); + + if (abs(coll->midCeiling - coll->frontCeiling) > 50) + return 0; + + if (!coll->collType) + return 1; + + oct = GetDirOctant(item->pos.yRot); + if (oct) + { + if (oct != 1) + return 1; + if (coll->collType != CT_FRONT && coll->collType != CT_RIGHT && coll->collType != CT_LEFT) + return 1; + } + else if (coll->collType != CT_FRONT) + { + return 1; + } + + return 0; +} + +short TestMonkeyLeft(ITEM_INFO* item, COLL_INFO* coll)//160CC(<), 16200(<) (F) +{ + short oct; + + coll->badPos = NO_BAD_POS; + coll->badNeg = NO_HEIGHT; + coll->badCeiling = 0; + Lara.moveAngle = -ANGLE(90); + coll->slopesAreWalls = 0; + coll->facing = Lara.moveAngle; + coll->radius = 100; + + GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600); + + if (abs(coll->midCeiling - coll->frontCeiling) > 50) + return 0; + + if (!coll->collType) + return 1; + + oct = GetDirOctant(item->pos.yRot); + if (oct) + { + if (oct != 1) + return 1; + if (coll->collType != CT_RIGHT && coll->collType != CT_LEFT) + return 1; + } + else + { + if (coll->collType != CT_FRONT && coll->collType != CT_LEFT) + return 1; + } + + return 0; +} + +short LaraFloorFront(ITEM_INFO* item, short ang, int dist) // (F) (D) +{ + short room = item->roomNumber; + + int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT); + int y = item->pos.yPos - 762; + int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT); + + int height = GetFloorHeight(GetFloor(x, y, z, &room), x, y, z); + + if (height != NO_HEIGHT) + height -= item->pos.yPos; + + return height; +} + +short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h) // (F) (D) +{ + short room = item->roomNumber; + + int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT); + int y = item->pos.yPos - h; + int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT); + + int height = GetCeiling(GetFloor(x, y, z, &room), x, y, z); + + if (height != NO_HEIGHT) + height += h - item->pos.yPos; + + return height; +} + +int LaraFallen(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (Lara.waterStatus == LW_WADE || coll->midFloor <= STEPUP_HEIGHT) + { + return 0; + } + + item->animNumber = LA_FALL_START; + item->currentAnimState = LS_JUMP_FORWARD; + item->goalAnimState = LS_JUMP_FORWARD; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + item->fallspeed = 0; + item->gravityStatus = true; + return 1; +} + +int LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + int landspeed = item->fallspeed - 140; + + if (landspeed > 0) + { + if (landspeed <= 14) + { + item->hitPoints -= 1000 * SQUARE(landspeed) / 196; + return item->hitPoints <= 0; + } + else + { + item->hitPoints = -1; + return 1; + } + } + + return 0; +} + +int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (coll->collType == CT_TOP || coll->collType == CT_CLAMP) + { + item->pos.xPos = coll->old.x; + item->pos.yPos = coll->old.y; + item->pos.zPos = coll->old.z; + + item->goalAnimState = LS_STOP; + item->currentAnimState = LS_STOP; + + item->animNumber = LA_STAND_SOLID; + item->frameNumber = g_Level.Anims[item->animNumber].frameBase; + + item->speed = 0; + item->fallspeed = 0; + item->gravityStatus = false; + + return 1; + } + return 0; +} + +/*Maybe move these 3 to lara_collide if it's ever made*/ + +int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT) + { + ShiftItem(item, coll); + + item->goalAnimState = LS_STOP; + item->speed = 0; + item->gravityStatus = false; + + return 1; + } + + if (coll->collType == CT_LEFT) + { + ShiftItem(item, coll); + item->pos.yRot += ANGLE(5.0f); + } + else if (coll->collType == CT_RIGHT) + { + ShiftItem(item, coll); + item->pos.yRot -= ANGLE(5.0f); + } + + return 0; +} + +void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F) +{ + ShiftItem(item, coll); + + switch (coll->collType) + { + case CT_FRONT: + case CT_TOP_FRONT: + if (!Lara.climbStatus || item->speed != 2) + { + if (coll->midFloor <= 512) + { + if (coll->midFloor <= 128) + { + item->goalAnimState = LS_GRAB_TO_FALL; + item->currentAnimState = LS_GRAB_TO_FALL; + + item->animNumber = LA_JUMP_UP_LAND; + item->frameNumber = g_Level.Anims[LA_JUMP_UP_LAND].frameBase; + } + } + else + { + item->goalAnimState = LS_FREEFALL; + item->currentAnimState = LS_FREEFALL; + + item->animNumber = LA_JUMP_WALL_SMASH_START; + item->frameNumber = g_Level.Anims[LA_JUMP_WALL_SMASH_START].frameBase + 1; + } + + item->speed /= 4; + Lara.moveAngle += ANGLE(180); + + if (item->fallspeed <= 0) + item->fallspeed = 1; + } + + break; + case CT_TOP: + if (item->fallspeed <= 0) + item->fallspeed = 1; + + break; + case CT_LEFT: + item->pos.yRot += ANGLE(5.0f); + break; + case CT_RIGHT: + item->pos.yRot -= ANGLE(5.0f); + break; + case CT_CLAMP: + item->pos.xPos -= (100 * 4 * phd_sin(coll->facing)) >> W2V_SHIFT; + item->pos.zPos -= (100 * 4 * phd_cos(coll->facing)) >> W2V_SHIFT; + + item->speed = 0; + coll->midFloor = 0; + + if (item->fallspeed <= 0) + item->fallspeed = 16; + + break; + } +} + +int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll) // (F) (D) +{ + if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT) + { + ShiftItem(item, coll); + + item->gravityStatus = false; + item->speed = 0; + + return 1; + } + + if (coll->collType == CT_LEFT) + { + ShiftItem(item, coll); + item->pos.yRot += ANGLE(2.0f); + } + else if (coll->collType == CT_RIGHT) + { + ShiftItem(item, coll); + item->pos.yRot -= ANGLE(2.0f); + } + + return 0; +} +/************************************/ diff --git a/TR5Main/Game/Lara/lara_tests.h b/TR5Main/Game/Lara/lara_tests.h new file mode 100644 index 000000000..a46e09cd1 --- /dev/null +++ b/TR5Main/Game/Lara/lara_tests.h @@ -0,0 +1,28 @@ +#pragma once +#include "lara_struct.h" + +int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll); +int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll); +int TestWall(ITEM_INFO* item, int front, int right, int down); +int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll); +int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll); +int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll); +int LaraTestClimbStance(ITEM_INFO* item, COLL_INFO* coll); +int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll); +int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge); +int IsValidHangPos(ITEM_INFO* item, COLL_INFO* coll); +int TestHangSwingIn(ITEM_INFO* item, short angle); +int TestHangFeet(ITEM_INFO* item, short angle); +int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle); +void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip); +void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip); +short TestMonkeyRight(ITEM_INFO* item, COLL_INFO* coll); +short TestMonkeyLeft(ITEM_INFO* item, COLL_INFO* coll); +short LaraFloorFront(ITEM_INFO* item, short ang, int dist); +short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h); +int LaraFallen(ITEM_INFO* item, COLL_INFO* coll); +int LaraLandedBad(ITEM_INFO* l, COLL_INFO* coll); +int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll); +int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll); +void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll); +int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll); diff --git a/TR5Main/Game/Lara/larasurf.cpp b/TR5Main/Game/Lara/larasurf.cpp index 4f31c5e4c..d2671a23f 100644 --- a/TR5Main/Game/Lara/larasurf.cpp +++ b/TR5Main/Game/Lara/larasurf.cpp @@ -1,5 +1,6 @@ #include "framework.h" #include "larasurf.h" +#include "lara_tests.h" #include "control.h" #include "camera.h" #include "collide.h" diff --git a/TR5Main/TR5Main.vcxproj b/TR5Main/TR5Main.vcxproj index f2bd12370..33daf02d2 100644 --- a/TR5Main/TR5Main.vcxproj +++ b/TR5Main/TR5Main.vcxproj @@ -15,14 +15,14 @@ {15AB0220-541C-4DA1-94EB-ED3C47E4582E} Win32Proj TR5Main - 10.0 + 10.0.17134.0 Application true MultiByte - v142 + v141 Application @@ -136,6 +136,7 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts" + @@ -415,6 +416,7 @@ xcopy /Y "$(ProjectDir)Scripting\Scripts\*.lua" "$(TargetDir)\Scripts" + diff --git a/TR5Main/TR5Main.vcxproj.filters b/TR5Main/TR5Main.vcxproj.filters index 512fb38ab..a3d78f28b 100644 --- a/TR5Main/TR5Main.vcxproj.filters +++ b/TR5Main/TR5Main.vcxproj.filters @@ -849,6 +849,9 @@ File di intestazione + + File di intestazione + @@ -1547,6 +1550,9 @@ File di origine + + File di origine +