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
//---
if (KeyMap[DIK_D])
item->hitPoints = 0;
static PHD_3DPOS posO = { 0, 0, 0, 0, 0, 0 };
static short roomNumO = item->roomNumber;
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)
{
int y = item->pos.yPos - LARA_HEIGHT_MONKEY;
auto probe = GetCollisionResult(item);
constexpr int rate = 50;
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;
else if (abs(probe.Position.Ceiling - y) <= (CLICK(1.25f) / 2) && // Inner range.
abs(probe.Position.Ceiling - y) >= threshold)
else if (abs(coll->Middle.Ceiling) <= (CLICK(1.25f) / 2) && // Inner range.
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
item->pos.yPos = probe.Position.Ceiling + LARA_HEIGHT_MONKEY;
item->pos.yPos += coll->Middle.Ceiling;
}
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)
{
item->goalAnimState = LS_IDLE; // TODO: Death state dispatches for all monkey states.
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return;
}
@ -133,7 +134,7 @@ void lara_col_monkey_idle(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true;
//coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD;
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)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return;
}
@ -214,7 +216,7 @@ void lara_col_monkey_forward(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true;
//coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD;
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()
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)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return;
}
@ -296,7 +299,7 @@ void lara_col_monkey_back(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.BadCeilingHeightDown = CLICK(1.25f);
coll->Setup.BadCeilingHeightUp = -CLICK(1.25f);
coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true;
//coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD;
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)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
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.BadCeilingHeightUp = -CLICK(0.5f);
coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true;
//coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD;
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)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
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.BadCeilingHeightUp = -CLICK(0.5f);
coll->Setup.CeilingSlopesAreWalls = true;
coll->Setup.NoMonkeyFlagIsWall = true;
//coll->Setup.NoMonkeyFlagIsWall = true;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = LARA_RAD;
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)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return;
}
@ -534,14 +540,13 @@ void lara_as_monkey_turn_left(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_MONKEY_TURN_LEFT;
// 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
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_MONKEY_TURN_MAX)
info->turnRate = -LARA_MONKEY_TURN_MAX;
item->goalAnimState = LS_MONKEY_TURN_LEFT;
return;
}
@ -575,13 +580,13 @@ void lara_as_monkey_turn_right(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_MONKEY_IDLE; //
item->goalAnimState = LS_DEATH;
SetLaraMonkeyRelease(item);
return;
}
if (TrInput & IN_ACTION && info->canMonkeySwing)
{
// TODO: Dispaches.
if (TrInput & IN_LSTEP && TestLaraMonkeyShimmyLeft(item, coll))
{
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)
{
item->goalAnimState = LS_MONKEY_TURN_RIGHT;
// 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
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_MONKEY_TURN_MAX)
info->turnRate = LARA_MONKEY_TURN_MAX;
item->goalAnimState = LS_MONKEY_TURN_RIGHT;
return;
}

View file

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

View file

@ -728,7 +728,7 @@ void ProcessSectorFlags(FLOOR_INFO* floor)
Lara.canMonkeySwing = floor->Flags.Monkeyswing;
// 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);
// Set climb status
@ -736,4 +736,4 @@ void ProcessSectorFlags(FLOOR_INFO* floor)
Lara.climbStatus = true;
else
Lara.climbStatus = false;
}
}