Add death dispatches to monkey states; don't activate death sectors when airborne; temp. disable buggy non-monkey sector deflection; cleanup

This commit is contained in:
Sezz 2022-01-19 22:45:38 +11:00
parent 4f72e5e9b8
commit 1d17e833c5
6 changed files with 60 additions and 56 deletions

View file

@ -819,6 +819,9 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
// Temp. debug stuff // Temp. debug stuff
//--- //---
if (KeyMap[DIK_D])
item->hitPoints = 0;
static PHD_3DPOS posO = { 0, 0, 0, 0, 0, 0 }; static PHD_3DPOS posO = { 0, 0, 0, 0, 0, 0 };
static short roomNumO = item->roomNumber; static short roomNumO = item->roomNumber;
static CAMERA_INFO camO = Camera; static CAMERA_INFO camO = Camera;

View file

@ -78,22 +78,19 @@ void DoLaraStep(ITEM_INFO* item, COLL_INFO* coll)
void DoLaraMonkeyStep(ITEM_INFO* item, COLL_INFO* coll) void DoLaraMonkeyStep(ITEM_INFO* item, COLL_INFO* coll)
{ {
int y = item->pos.yPos - LARA_HEIGHT_MONKEY;
auto probe = GetCollisionResult(item);
constexpr int rate = 50; constexpr int rate = 50;
int threshold = std::max(abs(item->speed) / 3 * 2, (int)CLICK(1.25f) / 16); int threshold = std::max(abs(item->speed) / 3 * 2, (int)CLICK(1.25f) / 16);
int sign = std::copysign(1, probe.Position.Ceiling - y); int sign = std::copysign(1, coll->Middle.Ceiling);
if (abs(probe.Position.Ceiling - y) > (CLICK(1.25f) / 2)) // Outer range. if (abs(coll->Middle.Ceiling) > (CLICK(1.25f) / 2)) // Outer range.
item->pos.yPos += rate * sign; item->pos.yPos += rate * sign;
else if (abs(probe.Position.Ceiling - y) <= (CLICK(1.25f) / 2) && // Inner range. else if (abs(coll->Middle.Ceiling) <= (CLICK(1.25f) / 2) && // Inner range.
abs(probe.Position.Ceiling - y) >= threshold) abs(coll->Middle.Ceiling) >= threshold)
{ {
item->pos.yPos += std::max((int)abs((probe.Position.Ceiling - y) / 2.75), threshold) * sign; item->pos.yPos += std::max((int)abs(coll->Middle.Ceiling / 2.75), threshold) * sign;
} }
else else
item->pos.yPos = probe.Position.Ceiling + LARA_HEIGHT_MONKEY; item->pos.yPos += coll->Middle.Ceiling;
} }
void DoLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll) void DoLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll)

View file

@ -40,7 +40,8 @@ void lara_as_monkey_idle(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_IDLE; // TODO: Death state dispatches for all monkey states. item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -133,7 +134,7 @@ void lara_col_monkey_idle(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f); coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f); coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true; coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true; //coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle; coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD; coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_MONKEY; coll->Setup.Height = LARA_HEIGHT_MONKEY;
@ -169,7 +170,8 @@ void lara_as_monkey_forward(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -214,7 +216,7 @@ void lara_col_monkey_forward(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f); coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f); coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true; coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true; //coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle; coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD; coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_MONKEY; coll->Setup.Height = LARA_HEIGHT_MONKEY;
@ -236,7 +238,7 @@ void lara_col_monkey_forward(ITEM_INFO* item, COLL_INFO* coll)
} }
} }
// State: LS_MONKEY_BACK (143) // State: LS_MONKEY_BACK (TODO)
// Collision: lara_col_monkey_back() // Collision: lara_col_monkey_back()
void lara_as_monkey_back(ITEM_INFO* item, COLL_INFO* coll) void lara_as_monkey_back(ITEM_INFO* item, COLL_INFO* coll)
{ {
@ -251,7 +253,8 @@ void lara_as_monkey_back(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -296,7 +299,7 @@ void lara_col_monkey_back(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f); coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f); coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true; coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true; //coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle; coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD; coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_MONKEY; coll->Setup.Height = LARA_HEIGHT_MONKEY;
@ -333,7 +336,8 @@ void lara_as_monkey_shimmy_left(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -378,7 +382,7 @@ void lara_col_monkey_shimmy_left(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(0.5f); coll->Setup.BadCeilingHeightDown = CLICK(0.5f);
coll->Setup.BadCeilingHeightUp = -CLICK(0.5f); coll->Setup.BadCeilingHeightUp = -CLICK(0.5f);
coll->Setup.CeilingSlopesAreWalls = true; coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true; //coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle; coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD; coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_MONKEY; coll->Setup.Height = LARA_HEIGHT_MONKEY;
@ -415,7 +419,8 @@ void lara_as_monkey_shimmy_right(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -460,7 +465,7 @@ void lara_col_monkey_shimmy_right(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(0.5f); coll->Setup.BadCeilingHeightDown = CLICK(0.5f);
coll->Setup.BadCeilingHeightUp = -CLICK(0.5f); coll->Setup.BadCeilingHeightUp = -CLICK(0.5f);
coll->Setup.CeilingSlopesAreWalls = true; coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true; //coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle; coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD; coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_MONKEY; coll->Setup.Height = LARA_HEIGHT_MONKEY;
@ -515,7 +520,8 @@ void lara_as_monkey_turn_left(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
@ -534,14 +540,13 @@ void lara_as_monkey_turn_left(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_LEFT) if (TrInput & IN_LEFT)
{ {
item->goalAnimState = LS_MONKEY_TURN_LEFT;
// TODO: When an immediate dispatch out of this state becomes possible from any frame, // TODO: When an immediate dispatch out of this state becomes possible from any frame,
// move the following block right beneath the death check. @Sezz 2022.01.16 // move the following block right beneath the death check. @Sezz 2022.01.16
info->turnRate -= LARA_TURN_RATE; info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_MONKEY_TURN_MAX) if (info->turnRate < -LARA_MONKEY_TURN_MAX)
info->turnRate = -LARA_MONKEY_TURN_MAX; info->turnRate = -LARA_MONKEY_TURN_MAX;
item->goalAnimState = LS_MONKEY_TURN_LEFT;
return; return;
} }
@ -575,13 +580,13 @@ void lara_as_monkey_turn_right(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0) if (item->hitPoints <= 0)
{ {
item->goalAnimState = LS_MONKEY_IDLE; // item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return; return;
} }
if (TrInput & IN_ACTION && info->canMonkeySwing) if (TrInput & IN_ACTION && info->canMonkeySwing)
{ {
// TODO: Dispaches.
if (TrInput & IN_LSTEP && TestLaraMonkeyShimmyLeft(item, coll)) if (TrInput & IN_LSTEP && TestLaraMonkeyShimmyLeft(item, coll))
{ {
item->goalAnimState = LS_MONKEY_SHIMMY_LEFT; item->goalAnimState = LS_MONKEY_SHIMMY_LEFT;
@ -595,14 +600,13 @@ void lara_as_monkey_turn_right(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_RIGHT) if (TrInput & IN_RIGHT)
{ {
item->goalAnimState = LS_MONKEY_TURN_RIGHT;
// TODO: When an immediate dispatch out of this state becomes possible from any frame, // TODO: When an immediate dispatch out of this state becomes possible from any frame,
// move the following block right beneath the death check. @Sezz 2022.01.16 // move the following block right beneath the death check. @Sezz 2022.01.16
info->turnRate += LARA_TURN_RATE; info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_MONKEY_TURN_MAX) if (info->turnRate > LARA_MONKEY_TURN_MAX)
info->turnRate = LARA_MONKEY_TURN_MAX; info->turnRate = LARA_MONKEY_TURN_MAX;
item->goalAnimState = LS_MONKEY_TURN_RIGHT;
return; return;
} }

View file

@ -12,9 +12,9 @@ struct MoveTestData
struct MonkeyMoveTestData struct MonkeyMoveTestData
{ {
short angle; short Angle;
int lowerBound; int LowerBound;
int upperBound; int UpperBound;
}; };
struct VaultTestData struct VaultTestData
@ -48,7 +48,7 @@ struct CrawlVaultTestData
struct JumpTestData struct JumpTestData
{ {
short angle; short Angle;
int dist = CLICK(1.1f); int Dist = CLICK(0.85f);
bool checkWadeStatus = true; bool CheckWadeStatus = true;
}; };

View file

@ -1105,10 +1105,10 @@ bool TestLaraMonkeyFall(ITEM_INFO* item, COLL_INFO* coll)
int y = item->pos.yPos - LARA_HEIGHT_MONKEY; int y = item->pos.yPos - LARA_HEIGHT_MONKEY;
auto probe = GetCollisionResult(item); auto probe = GetCollisionResult(item);
if (!probe.BottomBlock->Flags.Monkeyswing || // Monkey swing sector not set. if (!probe.BottomBlock->Flags.Monkeyswing || // No monkey sector.
(probe.Position.Ceiling - y) > CLICK(1.25f) || // Lower bound. (probe.Position.Ceiling - y) > CLICK(1.25f) || // Lower bound.
(probe.Position.Ceiling - y) < -CLICK(1.25f) || // Upper bound. (probe.Position.Ceiling - y) < -CLICK(1.25f) || // Upper bound.
probe.Position.CeilingSlope || // Ceiling slope. probe.Position.CeilingSlope || // Ceiling slope.
probe.Position.Ceiling == NO_HEIGHT) probe.Position.Ceiling == NO_HEIGHT)
{ {
return true; return true;
@ -1434,9 +1434,9 @@ bool TestLaraMonkeyStep(ITEM_INFO* item, COLL_INFO* coll)
int y = item->pos.yPos - LARA_HEIGHT_MONKEY; int y = item->pos.yPos - LARA_HEIGHT_MONKEY;
auto probe = GetCollisionResult(item); auto probe = GetCollisionResult(item);
if ((probe.Position.Ceiling - y) <= CLICK(1.25f) || // Lower bound. if ((probe.Position.Ceiling - y) <= CLICK(1.25f) && // Lower bound.
(probe.Position.Ceiling - y) >= -CLICK(1.25f) || // Upper bound. (probe.Position.Ceiling - y) >= -CLICK(1.25f) && // Upper bound.
probe.Position.Ceiling == NO_HEIGHT) probe.Position.Ceiling != NO_HEIGHT)
{ {
return true; return true;
} }
@ -1730,12 +1730,12 @@ bool TestLaraCrouchRoll(ITEM_INFO* item, COLL_INFO* coll)
bool TestLaraMonkeyMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MonkeyMoveTestData testData) bool TestLaraMonkeyMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MonkeyMoveTestData testData)
{ {
int y = item->pos.yPos - LARA_HEIGHT_MONKEY; int y = item->pos.yPos - LARA_HEIGHT_MONKEY;
auto probe = GetCollisionResult(item, testData.angle, coll->Setup.Radius * sqrt(2) + 4); auto probe = GetCollisionResult(item, testData.Angle, coll->Setup.Radius * sqrt(2) + 4);
if (probe.BottomBlock->Flags.Monkeyswing && // Monkey swing sector flag set. if (//probe.BottomBlock->Flags.Monkeyswing && // Is monkey sector.
(probe.Position.Floor - y) > LARA_HEIGHT_MONKEY && // Highest floor boundary. (probe.Position.Floor - y) > LARA_HEIGHT_MONKEY && // Highest floor boundary.
(probe.Position.Ceiling - y) <= testData.lowerBound && // Lower ceiling boundary. (probe.Position.Ceiling - y) <= testData.LowerBound && // Lower ceiling boundary.
(probe.Position.Ceiling - y) >= testData.upperBound && // Lower ceiling boundary. TODO: Not working?? (probe.Position.Ceiling - y) >= testData.UpperBound && // Lower ceiling boundary. TODO: Not working??
abs(probe.Position.Ceiling - probe.Position.Floor) > LARA_HEIGHT_MONKEY && // Space is not a clamp. abs(probe.Position.Ceiling - probe.Position.Floor) > LARA_HEIGHT_MONKEY && // Space is not a clamp.
!probe.Position.CeilingSlope && // No ceiling slope. !probe.Position.CeilingSlope && // No ceiling slope.
probe.Position.Ceiling != NO_HEIGHT) probe.Position.Ceiling != NO_HEIGHT)
@ -2127,17 +2127,17 @@ bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestData testDa
LaraInfo*& info = item->data; LaraInfo*& info = item->data;
int y = item->pos.yPos; int y = item->pos.yPos;
auto probe = GetCollisionResult(item, testData.angle, testData.dist, -coll->Setup.Height); auto probe = GetCollisionResult(item, testData.Angle, testData.Dist, -coll->Setup.Height);
bool isWading = testData.checkWadeStatus ? (info->waterStatus == LW_WADE) : false; bool isWading = testData.CheckWadeStatus ? (info->waterStatus == LW_WADE) : false;
if (((probe.Position.Floor - y) >= -STEPUP_HEIGHT || // Highest floor bound... if (((probe.Position.Floor - y) >= -STEPUP_HEIGHT || // Highest floor bound...
probe.Position.FloorSlope) && // OR surface is a slope. probe.Position.FloorSlope) && // OR surface is a slope.
((probe.Position.Ceiling - y) < -(coll->Setup.Height + (LARA_HEADROOM * 0.7f)) || // Ceiling height is permissive... ((probe.Position.Ceiling - y) < -(coll->Setup.Height + (LARA_HEADROOM * 0.7f)) || // Ceiling height is permissive...
((probe.Position.Ceiling - y) < -coll->Setup.Height && // OR ceiling is level with Lara's head ((probe.Position.Ceiling - y) < -coll->Setup.Height && // OR ceiling is level with Lara's head
(probe.Position.Floor - y) >= CLICK(0.5f))) && // AND there is a drop below. (probe.Position.Floor - y) >= CLICK(0.5f))) && // AND there is a drop below.
!isWading && // Not wading in water (if applicable). !isWading && // Not wading in water (if applicable).
!TestLaraSwamp(item) && // No swamp. !TestLaraSwamp(item) && // No swamp.
!TestLaraFacingCorner(item, testData.angle, testData.dist) && // Avoid jumping through corners. !TestLaraFacingCorner(item, testData.Angle, testData.Dist) && // Avoid jumping through corners.
probe.Position.Floor != NO_HEIGHT) probe.Position.Floor != NO_HEIGHT)
{ {
return true; return true;

View file

@ -728,7 +728,7 @@ void ProcessSectorFlags(FLOOR_INFO* floor)
Lara.canMonkeySwing = floor->Flags.Monkeyswing; Lara.canMonkeySwing = floor->Flags.Monkeyswing;
// Burn Lara // Burn Lara
if (floor->Flags.Death && (LaraItem->pos.yPos == LaraItem->floor || Lara.waterStatus)) if (floor->Flags.Death && (LaraItem->pos.yPos == LaraItem->floor && !LaraItem->gravityStatus || Lara.waterStatus))
LavaBurn(LaraItem); LavaBurn(LaraItem);
// Set climb status // Set climb status
@ -736,4 +736,4 @@ void ProcessSectorFlags(FLOOR_INFO* floor)
Lara.climbStatus = true; Lara.climbStatus = true;
else else
Lara.climbStatus = false; Lara.climbStatus = false;
} }