Merge branch 'vault_without_embedding' into state_cleaning_tier_2

This commit is contained in:
Sezz 2022-01-27 14:16:38 +11:00
commit 2cc228ee45
4 changed files with 196 additions and 196 deletions

View file

@ -1,54 +1,61 @@
#pragma once #pragma once
struct MoveTestData struct MoveTestSetup
{ {
short angle; short Angle;
int lowerBound; int LowerBound;
int upperBound; int UpperBound;
bool checkSlopeDown = true; bool CheckSlopeDown = true;
bool checkSlopeUp = true; bool CheckSlopeUp = true;
bool checkDeath = true; bool CheckDeath = true;
}; };
struct MonkeyMoveTestData struct MonkeyMoveTestSetup
{ {
short Angle; short Angle;
int LowerBound; int LowerBound;
int UpperBound; int UpperBound;
}; };
struct VaultTestData struct VaultTestSetup
{ {
int lowerBound; int LowerBound;
int upperBound; int UpperBound;
int clampMin; int ClampMin;
int clampMax; int ClampMax;
int gapMin; int GapMin;
bool checkSwampDepth = true; bool CheckSwampDepth = true;
}; };
struct VaultTestResultData struct VaultTestResult
{ {
bool success; bool Success;
int height; int Height;
}; };
struct CrawlVaultTestData struct CrawlVaultTestSetup
{ {
int lowerBound; int LowerBound;
int upperBound; int UpperBound;
int clampMin; int ClampMin;
int gapMin; int GapMin;
int crossDist; int CrossDist;
int destDist; int DestDist;
int probeDeltaMax; int ProbeHeightDifMax;
bool checkSlope = true; bool CheckSlope = true;
bool checkDeath = true; bool CheckDeath = true;
}; };
struct JumpTestData struct JumpTestSetup
{ {
short Angle; short Angle;
int Dist = CLICK(0.85f); int Dist = CLICK(0.85f);
bool CheckWadeStatus = true; bool CheckWadeStatus = true;
}; };
struct CornerTestResult
{
bool Success;
PHD_3DPOS ProbeResult;
PHD_3DPOS RealPositionResult;
};

View file

@ -21,14 +21,6 @@
using namespace TEN::Renderer; using namespace TEN::Renderer;
using namespace TEN::Floordata; using namespace TEN::Floordata;
// TODO: Move to lara_test_structs.h after merge of Sezz vaults branch
struct CornerTestResult
{
bool Success;
PHD_3DPOS ProbeResult;
PHD_3DPOS RealPositionResult;
};
// ----------------------------- // -----------------------------
// TEST FUNCTIONS // TEST FUNCTIONS
// For State Control & Collision // For State Control & Collision
@ -82,7 +74,7 @@ bool TestValidLedge(ITEM_INFO* item, COLL_INFO* coll, bool ignoreHeadroom, bool
return false; return false;
// Discard if ledge is not within distance threshold // Discard if ledge is not within distance threshold
if (abs(coll->NearestLedgeDistance) > coll->Setup.Radius * sqrt(2) + 4) if (abs(coll->NearestLedgeDistance) > OFFSET_RADIUS(coll->Setup.Radius))
return false; return false;
// Discard if ledge is not within angle threshold // Discard if ledge is not within angle threshold
@ -123,9 +115,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
// Vault to crouch up one step. // Vault to crouch up one step.
auto vaultResult = TestLaraVault1StepToCrouch(item, coll); auto vaultResult = TestLaraVault1StepToCrouch(item, coll);
if (vaultResult.success && !success) if (vaultResult.Success && !success)
{ {
item->pos.yPos = vaultResult.height + CLICK(1); item->pos.yPos = vaultResult.Height + CLICK(1);
item->animNumber = LA_VAULT_TO_CROUCH_1CLICK; item->animNumber = LA_VAULT_TO_CROUCH_1CLICK;
item->currentAnimState = LS_GRABBING; item->currentAnimState = LS_GRABBING;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
@ -136,9 +128,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
// Vault to stand up two steps. // Vault to stand up two steps.
vaultResult = TestLaraVault2Steps(item, coll); vaultResult = TestLaraVault2Steps(item, coll);
if (vaultResult.success && !success) if (vaultResult.Success && !success)
{ {
item->pos.yPos = vaultResult.height + CLICK(2); item->pos.yPos = vaultResult.Height + CLICK(2);
item->animNumber = LA_VAULT_TO_STAND_2CLICK_START; item->animNumber = LA_VAULT_TO_STAND_2CLICK_START;
item->currentAnimState = LS_GRABBING; item->currentAnimState = LS_GRABBING;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
@ -148,10 +140,10 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
} }
// Vault to crouch up two steps. // Vault to crouch up two steps.
vaultResult = TestLaraVault2StepsToCrouch(item, coll); vaultResult = TestLaraVault2StepsToCrouch(item, coll);
if (vaultResult.success && !success && if (vaultResult.Success && !success &&
g_GameFlow->Animations.CrawlExtended) g_GameFlow->Animations.CrawlExtended)
{ {
item->pos.yPos = vaultResult.height + CLICK(2); item->pos.yPos = vaultResult.Height + CLICK(2);
item->animNumber = LA_VAULT_TO_CROUCH_2CLICK; item->animNumber = LA_VAULT_TO_CROUCH_2CLICK;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
item->currentAnimState = LS_GRABBING; item->currentAnimState = LS_GRABBING;
@ -162,9 +154,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
// Vault to stand up three steps. // Vault to stand up three steps.
vaultResult = TestLaraVault3Steps(item, coll); vaultResult = TestLaraVault3Steps(item, coll);
if (vaultResult.success && !success) if (vaultResult.Success && !success)
{ {
item->pos.yPos = vaultResult.height + CLICK(3); item->pos.yPos = vaultResult.Height + CLICK(3);
item->animNumber = LA_VAULT_TO_STAND_3CLICK; item->animNumber = LA_VAULT_TO_STAND_3CLICK;
item->currentAnimState = LS_GRABBING; item->currentAnimState = LS_GRABBING;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
@ -174,10 +166,10 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
} }
// Vault to crouch up three steps. // Vault to crouch up three steps.
vaultResult = TestLaraVault3StepsToCrouch(item, coll); vaultResult = TestLaraVault3StepsToCrouch(item, coll);
if (vaultResult.success && !success && if (vaultResult.Success && !success &&
g_GameFlow->Animations.CrawlExtended) g_GameFlow->Animations.CrawlExtended)
{ {
item->pos.yPos = vaultResult.height + CLICK(3); item->pos.yPos = vaultResult.Height + CLICK(3);
item->animNumber = LA_VAULT_TO_CROUCH_3CLICK; item->animNumber = LA_VAULT_TO_CROUCH_3CLICK;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
item->currentAnimState = LS_GRABBING; item->currentAnimState = LS_GRABBING;
@ -188,9 +180,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
// Auto jump to hang. // Auto jump to hang.
vaultResult = TestLaraVaultAutoJump(item, coll); vaultResult = TestLaraVaultAutoJump(item, coll);
if (vaultResult.success && !success) if (vaultResult.Success && !success)
{ {
info->calcFallSpeed = -3 - sqrt(-9600 - 12 * (vaultResult.height - item->pos.yPos)); info->calcFallSpeed = -3 - sqrt(-9600 - 12 * (vaultResult.Height - item->pos.yPos));
item->animNumber = LA_STAND_SOLID; item->animNumber = LA_STAND_SOLID;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
item->goalAnimState = LS_JUMP_UP; item->goalAnimState = LS_JUMP_UP;
@ -209,9 +201,9 @@ bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll)
// Auto jump to ladder. // Auto jump to ladder.
auto ladderAutoJumpResult = TestLaraLadderAutoJump(item, coll); auto ladderAutoJumpResult = TestLaraLadderAutoJump(item, coll);
if (ladderAutoJumpResult.success) if (ladderAutoJumpResult.Success)
{ {
info->calcFallSpeed = -3 - sqrt(-9600 - 12 * std::max((ladderAutoJumpResult.height - item->pos.yPos + CLICK(0.2f)), -CLICK(7.1f))); info->calcFallSpeed = -3 - sqrt(-9600 - 12 * std::max((ladderAutoJumpResult.Height - item->pos.yPos + CLICK(0.2f)), -CLICK(7.1f)));
item->animNumber = LA_STAND_SOLID; item->animNumber = LA_STAND_SOLID;
item->frameNumber = GetFrameNumber(item, 0); item->frameNumber = GetFrameNumber(item, 0);
item->goalAnimState = LS_JUMP_UP; item->goalAnimState = LS_JUMP_UP;
@ -1444,18 +1436,18 @@ bool TestLaraStepDown(ITEM_INFO* item, COLL_INFO* coll)
// TODO: This function and its clone TestLaraCrawlMoveTolerance() should become obsolete with more accurate and accessible collision detection in the future. // TODO: This function and its clone TestLaraCrawlMoveTolerance() should become obsolete with more accurate and accessible collision detection in the future.
// For now, it supercedes old probes and is used alongside COLL_INFO. @Sezz 2021.10.24 // For now, it supercedes old probes and is used alongside COLL_INFO. @Sezz 2021.10.24
bool TestLaraMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestData testData) bool TestLaraMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestSetup testSetup)
{ {
int y = item->pos.yPos; int y = item->pos.yPos;
auto probe = GetCollisionResult(item, testData.angle, coll->Setup.Radius * sqrt(2) + 4, -coll->Setup.Height); // Offset required to account for gap between Lara and the wall. Results in slight overshoot, but avoids oscillation. auto probe = GetCollisionResult(item, testSetup.Angle, OFFSET_RADIUS(LARA_RAD_CRAWL), -LARA_HEIGHT_CRAWL);
bool isSlopeDown = testData.checkSlopeDown ? (probe.Position.FloorSlope && probe.Position.Floor > y) : false; bool isSlopeDown = testSetup.CheckSlopeDown ? (probe.Position.FloorSlope && probe.Position.Floor > y) : false;
bool isSlopeUp = testData.checkSlopeUp ? (probe.Position.FloorSlope && probe.Position.Floor < y) : false; bool isSlopeUp = testSetup.CheckSlopeUp ? (probe.Position.FloorSlope && probe.Position.Floor < y) : false;
bool isDeath = testData.checkDeath ? probe.Block->Flags.Death : false; bool isDeath = testSetup.CheckDeath ? probe.Block->Flags.Death : false;
if ((probe.Position.Floor - y) <= testData.lowerBound && // Lower floor bound. if ((probe.Position.Floor - y) <= testSetup.LowerBound && // Lower floor bound.
(probe.Position.Floor - y) >= testData.upperBound && // Upper floor bound. (probe.Position.Floor - y) >= testSetup.UpperBound && // Upper floor bound.
(probe.Position.Ceiling - y) < -coll->Setup.Height && // Lowest ceiling bound. (probe.Position.Ceiling - y) < -LARA_HEIGHT_CRAWL && // Lowest ceiling bound.
abs(probe.Position.Ceiling - probe.Position.Floor) > coll->Setup.Height && // Space is not a clamp. abs(probe.Position.Ceiling - probe.Position.Floor) > LARA_HEIGHT_CRAWL && // Space is not a clamp.
!isSlopeDown && !isSlopeUp && !isDeath && // No slope or death sector (if applicable). !isSlopeDown && !isSlopeUp && !isDeath && // No slope or death sector (if applicable).
probe.Position.Floor != NO_HEIGHT) probe.Position.Floor != NO_HEIGHT)
{ {
@ -1469,7 +1461,7 @@ bool TestLaraRunForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in run state collision function. // Using BadFloorHeightUp/Down defined in run state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
NO_BAD_POS, NO_BAD_POS,
@ -1477,84 +1469,84 @@ bool TestLaraRunForward(ITEM_INFO* item, COLL_INFO* coll)
false, true, false false, true, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraWalkForward(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraWalkForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in walk state collision function. // Using BadFloorHeightUp/Down defined in walk state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
STEPUP_HEIGHT, STEPUP_HEIGHT,
-STEPUP_HEIGHT -STEPUP_HEIGHT
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraWalkBack(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraWalkBack(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in walk back state collision function. // Using BadFloorHeightUp/Down defined in walk back state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f), item->pos.yRot + ANGLE(180.0f),
STEPUP_HEIGHT, STEPUP_HEIGHT,
-STEPUP_HEIGHT -STEPUP_HEIGHT
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraRunBack(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraRunBack(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in hop back state collision function. // Using BadFloorHeightUp/Down defined in hop back state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f), item->pos.yRot + ANGLE(180.0f),
NO_BAD_POS, -STEPUP_HEIGHT, NO_BAD_POS, -STEPUP_HEIGHT,
false, false, false false, false, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraStepLeft(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraStepLeft(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in step left state collision function. // Using BadFloorHeightUp/Down defined in step left state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot - ANGLE(90.0f), item->pos.yRot - ANGLE(90.0f),
CLICK(0.8f), CLICK(0.8f),
-CLICK(0.8f) -CLICK(0.8f)
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraStepRight(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraStepRight(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in step right state collision function. // Using BadFloorHeightUp/Down defined in step right state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(90.0f), item->pos.yRot + ANGLE(90.0f),
CLICK(0.8f), CLICK(0.8f),
-CLICK(0.8f) -CLICK(0.8f)
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraWadeForwardSwamp(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraWadeForwardSwamp(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in wade forward state collision function. // Using BadFloorHeightUp/Down defined in wade forward state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
NO_BAD_POS, NO_BAD_POS,
@ -1562,14 +1554,14 @@ bool TestLaraWadeForwardSwamp(ITEM_INFO* item, COLL_INFO* coll)
false, false, false false, false, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraWalkBackSwamp(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraWalkBackSwamp(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp defined in walk back state collision function. // Using BadFloorHeightUp defined in walk back state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f), item->pos.yRot + ANGLE(180.0f),
NO_BAD_POS, NO_BAD_POS,
@ -1577,14 +1569,14 @@ bool TestLaraWalkBackSwamp(ITEM_INFO* item, COLL_INFO* coll)
false, false, false false, false, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp defined in step left state collision function. // Using BadFloorHeightUp defined in step left state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot - ANGLE(90.0f), item->pos.yRot - ANGLE(90.0f),
NO_BAD_POS, NO_BAD_POS,
@ -1592,14 +1584,14 @@ bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll)
false, false, false false, false, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp defined in step right state collision function. // Using BadFloorHeightUp defined in step right state collision function.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(90.0f), item->pos.yRot + ANGLE(90.0f),
NO_BAD_POS, NO_BAD_POS,
@ -1607,7 +1599,7 @@ bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll)
false, false, false false, false, false
}; };
return TestLaraMoveTolerance(item, coll, testData); return TestLaraMoveTolerance(item, coll, testSetup);
} }
// HACK: coll->Setup.Radius and coll->Setup.Height are only set // HACK: coll->Setup.Radius and coll->Setup.Height are only set
@ -1615,16 +1607,16 @@ bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll)
// This means they will store the wrong values for tests called in crawl CONTROL functions. // This means they will store the wrong values for tests called in crawl CONTROL functions.
// When states become objects, collision setup should occur at the beginning of each state, eliminating the need // When states become objects, collision setup should occur at the beginning of each state, eliminating the need
// for this clone function. @Sezz 2021.12.05 // for this clone function. @Sezz 2021.12.05
bool TestLaraCrawlMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestData testData) bool TestLaraCrawlMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestSetup testSetup)
{ {
int y = item->pos.yPos; int y = item->pos.yPos;
auto probe = GetCollisionResult(item, testData.angle, LARA_RAD_CRAWL * sqrt(2) + 4, -LARA_HEIGHT_CRAWL); auto probe = GetCollisionResult(item, testSetup.Angle, OFFSET_RADIUS(LARA_RAD_CRAWL), -LARA_HEIGHT_CRAWL);
bool isSlopeDown = testData.checkSlopeDown ? (probe.Position.FloorSlope && probe.Position.Floor > y) : false; bool isSlopeDown = testSetup.CheckSlopeDown ? (probe.Position.FloorSlope && probe.Position.Floor > y) : false;
bool isSlopeUp = testData.checkSlopeUp ? (probe.Position.FloorSlope && probe.Position.Floor < y) : false; bool isSlopeUp = testSetup.CheckSlopeUp ? (probe.Position.FloorSlope && probe.Position.Floor < y) : false;
bool isDeath = testData.checkDeath ? probe.Block->Flags.Death : false; bool isDeath = testSetup.CheckDeath ? probe.Block->Flags.Death : false;
if ((probe.Position.Floor - y) <= testData.lowerBound && // Lower floor bound. if ((probe.Position.Floor - y) <= testSetup.LowerBound && // Lower floor bound.
(probe.Position.Floor - y) >= testData.upperBound && // Upper floor bound. (probe.Position.Floor - y) >= testSetup.UpperBound && // Upper floor bound.
(probe.Position.Ceiling - y) < -LARA_HEIGHT_CRAWL && // Lowest ceiling bound. (probe.Position.Ceiling - y) < -LARA_HEIGHT_CRAWL && // Lowest ceiling bound.
abs(probe.Position.Ceiling - probe.Position.Floor) > LARA_HEIGHT_CRAWL && // Space is not a clamp. abs(probe.Position.Ceiling - probe.Position.Floor) > LARA_HEIGHT_CRAWL && // Space is not a clamp.
!isSlopeDown && !isSlopeUp && !isDeath && // No slope or death sector (if applicable). !isSlopeDown && !isSlopeUp && !isDeath && // No slope or death sector (if applicable).
@ -1640,28 +1632,28 @@ bool TestLaraCrawlForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in crawl state collision functions. // Using BadFloorHeightUp/Down defined in crawl state collision functions.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
CLICK(1) - 1, CLICK(1) - 1,
-(CLICK(1) - 1) -(CLICK(1) - 1)
}; };
return TestLaraCrawlMoveTolerance(item, coll, testData); return TestLaraCrawlMoveTolerance(item, coll, testSetup);
} }
bool TestLaraCrawlBack(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraCrawlBack(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Using BadFloorHeightUp/Down defined in crawl state collision functions. // Using BadFloorHeightUp/Down defined in crawl state collision functions.
MoveTestData testData MoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f), item->pos.yRot + ANGLE(180.0f),
CLICK(1) - 1, CLICK(1) - 1,
-(CLICK(1) - 1) -(CLICK(1) - 1)
}; };
return TestLaraCrawlMoveTolerance(item, coll, testData); return TestLaraCrawlMoveTolerance(item, coll, testSetup);
} }
bool TestLaraCrouchToCrawl(ITEM_INFO* item) bool TestLaraCrouchToCrawl(ITEM_INFO* item)
@ -1699,15 +1691,15 @@ bool TestLaraCrouchRoll(ITEM_INFO* item, COLL_INFO* coll)
return false; return false;
} }
bool TestLaraMonkeyMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MonkeyMoveTestData testData) bool TestLaraMonkeyMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MonkeyMoveTestSetup testSetup)
{ {
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, testSetup.Angle, OFFSET_RADIUS(coll->Setup.Radius));
if (probe.BottomBlock->Flags.Monkeyswing && // Is monkey sector. 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) <= testSetup.LowerBound && // Lower ceiling boundary.
(probe.Position.Ceiling - y) >= testData.UpperBound && // Lower ceiling boundary. TODO: Not working?? (probe.Position.Ceiling - y) >= testSetup.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)
@ -1720,94 +1712,94 @@ bool TestLaraMonkeyMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MonkeyMoveTes
bool TestLaraMonkeyForward(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraMonkeyForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
MonkeyMoveTestData testData MonkeyMoveTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
CLICK(1.25f), CLICK(1.25f),
-CLICK(1.25f) -CLICK(1.25f)
}; };
return TestLaraMonkeyMoveTolerance(item, coll, testData); return TestLaraMonkeyMoveTolerance(item, coll, testSetup);
} }
bool TestLaraMonkeyBack(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraMonkeyBack(ITEM_INFO* item, COLL_INFO* coll)
{ {
MonkeyMoveTestData testData MonkeyMoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f), item->pos.yRot + ANGLE(180.0f),
CLICK(1.25f), CLICK(1.25f),
-CLICK(1.25f) -CLICK(1.25f)
}; };
return TestLaraMonkeyMoveTolerance(item, coll, testData); return TestLaraMonkeyMoveTolerance(item, coll, testSetup);
} }
bool TestLaraMonkeyShimmyLeft(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraMonkeyShimmyLeft(ITEM_INFO* item, COLL_INFO* coll)
{ {
MonkeyMoveTestData testData MonkeyMoveTestSetup testSetup
{ {
item->pos.yRot - ANGLE(90.0f), item->pos.yRot - ANGLE(90.0f),
CLICK(0.5f), CLICK(0.5f),
-CLICK(0.5f) -CLICK(0.5f)
}; };
return TestLaraMonkeyMoveTolerance(item, coll, testData); return TestLaraMonkeyMoveTolerance(item, coll, testSetup);
} }
bool TestLaraMonkeyShimmyRight(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraMonkeyShimmyRight(ITEM_INFO* item, COLL_INFO* coll)
{ {
MonkeyMoveTestData testData MonkeyMoveTestSetup testSetup
{ {
item->pos.yRot + ANGLE(90.0f), item->pos.yRot + ANGLE(90.0f),
CLICK(0.5f), CLICK(0.5f),
-CLICK(0.5f) -CLICK(0.5f)
}; };
return TestLaraMonkeyMoveTolerance(item, coll, testData); return TestLaraMonkeyMoveTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, VaultTestData testData) VaultTestResult TestLaraVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, VaultTestSetup testSetup)
{ {
LaraInfo*& info = item->data; LaraInfo*& info = item->data;
int y = item->pos.yPos; int y = item->pos.yPos;
auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, coll->Setup.Radius * sqrt(2) + 4, -coll->Setup.Height); auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, OFFSET_RADIUS(coll->Setup.Radius), -coll->Setup.Height);
auto probeMiddle = GetCollisionResult(item); auto probeMiddle = GetCollisionResult(item);
bool swampTooDeep = testData.checkSwampDepth ? (TestEnvironment(ENV_FLAG_SWAMP, item) && info->waterSurfaceDist < -CLICK(3)) : TestEnvironment(ENV_FLAG_SWAMP, item); bool swampTooDeep = testSetup.CheckSwampDepth ? (TestEnvironment(ENV_FLAG_SWAMP, item) && info->waterSurfaceDist < -CLICK(3)) : TestEnvironment(ENV_FLAG_SWAMP, item);
// "Floor" ahead may be formed by ceiling; raise y position of probe point to find potential vault candidate location. // "Floor" ahead may be formed by ceiling; raise y position of probe point to find potential vault candidate location.
int yOffset = testData.lowerBound; int yOffset = testSetup.LowerBound;
while (((probeFront.Position.Ceiling - y) > -coll->Setup.Height || // Ceiling is below Lara's height. while (((probeFront.Position.Ceiling - y) > -coll->Setup.Height || // Ceiling is below Lara's height.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testData.clampMin || // Clamp is too small. abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMin || // Clamp is too small.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testData.clampMax) && // Clamp is too large. abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMax) && // Clamp is too large.
yOffset > (testData.upperBound - coll->Setup.Height)) // Offset is not too high. yOffset > (testSetup.UpperBound - coll->Setup.Height)) // Offset is not too high.
{ {
probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, coll->Setup.Radius * sqrt(2) + 4, yOffset); probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, OFFSET_RADIUS(coll->Setup.Radius), yOffset);
yOffset -= std::max((int)CLICK(0.5f), testData.clampMin); yOffset -= std::max((int)CLICK(0.5f), testSetup.ClampMin);
} }
// Assess vault candidate location. // Assess vault candidate location.
if ((probeFront.Position.Floor - y) < testData.lowerBound && // Lower floor bound. if ((probeFront.Position.Floor - y) < testSetup.LowerBound && // Lower floor bound.
(probeFront.Position.Floor - y) >= testData.upperBound && // Upper floor bound. (probeFront.Position.Floor - y) >= testSetup.UpperBound && // Upper floor bound.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testData.clampMin && // Lower clamp limit. abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMin && // Lower clamp limit.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testData.clampMax && // Upper clamp limit. abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMax && // Upper clamp limit.
abs(probeMiddle.Position.Ceiling - probeFront.Position.Floor) >= testData.gapMin && // Gap is optically permissive. abs(probeMiddle.Position.Ceiling - probeFront.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive.
!swampTooDeep && // Swamp depth is permissive. !swampTooDeep && // Swamp depth is permissive.
probeFront.Position.Floor != NO_HEIGHT) probeFront.Position.Floor != NO_HEIGHT)
{ {
return VaultTestResultData{ true, probeFront.Position.Floor }; return VaultTestResult { true, probeFront.Position.Floor };
} }
return VaultTestResultData{ false, NO_HEIGHT }; return VaultTestResult { false, NO_HEIGHT };
} }
VaultTestResultData TestLaraVault2Steps(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVault2Steps(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (-STEPUP_HEIGHT, -CLICK(2.5f)] // Floor range: (-STEPUP_HEIGHT, -CLICK(2.5f)]
// Clamp range: (-LARA_HEIGHT, MAX_HEIGHT] // Clamp range: (-LARA_HEIGHT, MAX_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
-STEPUP_HEIGHT, -STEPUP_HEIGHT,
-CLICK(2.5f), -CLICK(2.5f),
@ -1816,15 +1808,15 @@ VaultTestResultData TestLaraVault2Steps(ITEM_INFO* item, COLL_INFO* coll)
CLICK(1) CLICK(1)
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVault3Steps(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVault3Steps(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (-CLICK(2.5f), -CLICK(3.5f)] // Floor range: (-CLICK(2.5f), -CLICK(3.5f)]
// Clamp range: (-LARA_HEIGHT, MAX_HEIGHT] // Clamp range: (-LARA_HEIGHT, MAX_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
-CLICK(2.5f), -CLICK(2.5f),
-CLICK(3.5f), -CLICK(3.5f),
@ -1833,15 +1825,15 @@ VaultTestResultData TestLaraVault3Steps(ITEM_INFO* item, COLL_INFO* coll)
CLICK(1), CLICK(1),
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVaultAutoJump(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVaultAutoJump(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (-CLICK(3.5f), -CLICK(7.5f)] // Floor range: (-CLICK(3.5f), -CLICK(7.5f)]
// Clamp range: (-CLICK(0.1f), MAX_HEIGHT] // Clamp range: (-CLICK(0.1f), MAX_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
-CLICK(3.5f), -CLICK(3.5f),
-CLICK(7.5f), -CLICK(7.5f),
@ -1851,15 +1843,15 @@ VaultTestResultData TestLaraVaultAutoJump(ITEM_INFO* item, COLL_INFO* coll)
false false
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVault1StepToCrouch(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVault1StepToCrouch(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (0, -STEPUP_HEIGHT] // Floor range: (0, -STEPUP_HEIGHT]
// Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT] // Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
0, 0,
-STEPUP_HEIGHT, -STEPUP_HEIGHT,
@ -1868,15 +1860,15 @@ VaultTestResultData TestLaraVault1StepToCrouch(ITEM_INFO* item, COLL_INFO* coll)
CLICK(1), CLICK(1),
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVault2StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVault2StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (-STEPUP_HEIGHT, -CLICK(2.5f)] // Floor range: (-STEPUP_HEIGHT, -CLICK(2.5f)]
// Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT] // Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
-STEPUP_HEIGHT, -STEPUP_HEIGHT,
-CLICK(2.5f), -CLICK(2.5f),
@ -1885,15 +1877,15 @@ VaultTestResultData TestLaraVault2StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll
CLICK(1), CLICK(1),
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraVault3StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraVault3StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: (-CLICK(2.5f), -CLICK(3.5f)] // Floor range: (-CLICK(2.5f), -CLICK(3.5f)]
// Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT] // Clamp range: (-LARA_HEIGHT_CRAWL, -LARA_HEIGHT]
VaultTestData testData VaultTestSetup testSetup
{ {
-CLICK(2.5f), -CLICK(2.5f),
-CLICK(3.5f), -CLICK(3.5f),
@ -1902,15 +1894,15 @@ VaultTestResultData TestLaraVault3StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll
CLICK(1), CLICK(1),
}; };
return TestLaraVaultTolerance(item, coll, testData); return TestLaraVaultTolerance(item, coll, testSetup);
} }
VaultTestResultData TestLaraLadderAutoJump(ITEM_INFO* item, COLL_INFO* coll) VaultTestResult TestLaraLadderAutoJump(ITEM_INFO* item, COLL_INFO* coll)
{ {
LaraInfo*& info = item->data; LaraInfo*& info = item->data;
int y = item->pos.yPos; int y = item->pos.yPos;
auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, coll->Setup.Radius * sqrt(2) + 4, -coll->Setup.Height); auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, OFFSET_RADIUS(coll->Setup.Radius), -coll->Setup.Height);
auto probeMiddle = GetCollisionResult(item); auto probeMiddle = GetCollisionResult(item);
if (TestValidLedgeAngle(item, coll) && if (TestValidLedgeAngle(item, coll) &&
@ -1919,10 +1911,10 @@ VaultTestResultData TestLaraLadderAutoJump(ITEM_INFO* item, COLL_INFO* coll)
(probeMiddle.Position.Ceiling - y) <= -CLICK(6.5f) && // Lower middle ceiling bound. (Synced with TestLaraLadderMount()) (probeMiddle.Position.Ceiling - y) <= -CLICK(6.5f) && // Lower middle ceiling bound. (Synced with TestLaraLadderMount())
coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall. coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall.
{ {
return VaultTestResultData{ true, probeMiddle.Position.Ceiling }; return VaultTestResult{ true, probeMiddle.Position.Ceiling };
} }
return VaultTestResultData{ false, NO_HEIGHT }; return VaultTestResult{ false, NO_HEIGHT };
} }
bool TestLaraLadderMount(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraLadderMount(ITEM_INFO* item, COLL_INFO* coll)
@ -1930,8 +1922,8 @@ bool TestLaraLadderMount(ITEM_INFO* item, COLL_INFO* coll)
LaraInfo*& info = item->data; LaraInfo*& info = item->data;
int y = item->pos.yPos; int y = item->pos.yPos;
auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, coll->Setup.Radius * sqrt(2) + 4, -coll->Setup.Height);
auto probeMiddle = GetCollisionResult(item); auto probeMiddle = GetCollisionResult(item);
auto probeFront = GetCollisionResult(item, coll->NearestLedgeAngle, OFFSET_RADIUS(coll->Setup.Radius), -coll->Setup.Height);
if (TestValidLedgeAngle(item, coll) && if (TestValidLedgeAngle(item, coll) &&
info->climbStatus && // Ladder sector flag set. info->climbStatus && // Ladder sector flag set.
@ -1964,23 +1956,23 @@ bool TestLaraMonkeyAutoJump(ITEM_INFO* item, COLL_INFO* coll)
return false; return false;
} }
bool TestLaraCrawlVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, CrawlVaultTestData testData) bool TestLaraCrawlVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, CrawlVaultTestSetup testSetup)
{ {
int y = item->pos.yPos; int y = item->pos.yPos;
auto probeA = GetCollisionResult(item, item->pos.yRot, testData.crossDist, -LARA_HEIGHT_CRAWL); // Crossing. auto probeA = GetCollisionResult(item, item->pos.yRot, testSetup.CrossDist, -LARA_HEIGHT_CRAWL); // Crossing.
auto probeB = GetCollisionResult(item, item->pos.yRot, testData.destDist, -LARA_HEIGHT_CRAWL); // Approximate destination. auto probeB = GetCollisionResult(item, item->pos.yRot, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination.
auto probeMiddle = GetCollisionResult(item); auto probeMiddle = GetCollisionResult(item);
bool isSlope = testData.checkSlope ? probeB.Position.FloorSlope : false; bool isSlope = testSetup.CheckSlope ? probeB.Position.FloorSlope : false;
bool isDeath = testData.checkDeath ? probeB.Block->Flags.Death : false; bool isDeath = testSetup.CheckDeath ? probeB.Block->Flags.Death : false;
if ((probeA.Position.Floor - y) <= testData.lowerBound && // Lower floor bound. if ((probeA.Position.Floor - y) <= testSetup.LowerBound && // Lower floor bound.
(probeA.Position.Floor - y) >= testData.upperBound && // Upper floor bound. (probeA.Position.Floor - y) >= testSetup.UpperBound && // Upper floor bound.
abs(probeA.Position.Ceiling - probeA.Position.Floor) > testData.clampMin && // Crossing clamp limit. abs(probeA.Position.Ceiling - probeA.Position.Floor) > testSetup.ClampMin && // Crossing clamp limit.
abs(probeB.Position.Ceiling - probeB.Position.Floor) > testData.clampMin && // Destination clamp limit. abs(probeB.Position.Ceiling - probeB.Position.Floor) > testSetup.ClampMin && // Destination clamp limit.
abs(probeMiddle.Position.Ceiling - probeA.Position.Floor) >= testData.gapMin && // Gap is optically permissive (going up). abs(probeMiddle.Position.Ceiling - probeA.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going up).
abs(probeA.Position.Ceiling - probeMiddle.Position.Floor) >= testData.gapMin && // Gap is optically permissive (going down). abs(probeA.Position.Ceiling - probeMiddle.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going down).
abs(probeA.Position.Floor - probeB.Position.Floor) <= testData.probeDeltaMax && // Crossing and destination floor height difference suggests continuous crawl surface. abs(probeA.Position.Floor - probeB.Position.Floor) <= testSetup.ProbeHeightDifMax && // Crossing and destination floor height difference suggests continuous crawl surface.
(probeA.Position.Ceiling - y) < -testData.gapMin && // Ceiling height is permissive. (probeA.Position.Ceiling - y) < -testSetup.GapMin && // Ceiling height is permissive.
!isSlope && !isDeath && // No slope or death sector. !isSlope && !isDeath && // No slope or death sector.
probeA.Position.Floor != NO_HEIGHT && probeB.Position.Floor != NO_HEIGHT) probeA.Position.Floor != NO_HEIGHT && probeB.Position.Floor != NO_HEIGHT)
{ {
@ -1994,7 +1986,7 @@ bool TestLaraCrawlUpStep(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: [-CLICK(1), -STEPUP_HEIGHT] // Floor range: [-CLICK(1), -STEPUP_HEIGHT]
CrawlVaultTestData testData CrawlVaultTestSetup testSetup
{ {
-CLICK(1), -CLICK(1),
-STEPUP_HEIGHT, -STEPUP_HEIGHT,
@ -2005,14 +1997,14 @@ bool TestLaraCrawlUpStep(ITEM_INFO* item, COLL_INFO* coll)
CLICK(1) - 1 CLICK(1) - 1
}; };
return TestLaraCrawlVaultTolerance(item, coll, testData); return TestLaraCrawlVaultTolerance(item, coll, testSetup);
} }
bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: [STEPUP_HEIGHT, CLICK(1)] // Floor range: [STEPUP_HEIGHT, CLICK(1)]
CrawlVaultTestData testData CrawlVaultTestSetup testSetup
{ {
STEPUP_HEIGHT, STEPUP_HEIGHT,
CLICK(1), CLICK(1),
@ -2023,14 +2015,14 @@ bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll)
CLICK(1) - 1 CLICK(1) - 1
}; };
return TestLaraCrawlVaultTolerance(item, coll, testData); return TestLaraCrawlVaultTolerance(item, coll, testSetup);
} }
bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: [STEPUP_HEIGHT, CLICK(1)] // Floor range: [STEPUP_HEIGHT, CLICK(1)]
CrawlVaultTestData testData CrawlVaultTestSetup testSetup
{ {
STEPUP_HEIGHT, STEPUP_HEIGHT,
CLICK(1), CLICK(1),
@ -2042,14 +2034,14 @@ bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll)
false false
}; };
return TestLaraCrawlVaultTolerance(item, coll, testData); return TestLaraCrawlVaultTolerance(item, coll, testSetup);
} }
bool TestLaraCrawlExitJump(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraCrawlExitJump(ITEM_INFO* item, COLL_INFO* coll)
{ {
// Floor range: [-MAX_HEIGHT, STEPUP_HEIGHT) // Floor range: [-MAX_HEIGHT, STEPUP_HEIGHT)
CrawlVaultTestData testData CrawlVaultTestSetup testSetup
{ {
-MAX_HEIGHT, -MAX_HEIGHT,
STEPUP_HEIGHT + 1, STEPUP_HEIGHT + 1,
@ -2061,7 +2053,7 @@ bool TestLaraCrawlExitJump(ITEM_INFO* item, COLL_INFO* coll)
false false
}; };
return TestLaraCrawlVaultTolerance(item, coll, testData); return TestLaraCrawlVaultTolerance(item, coll, testSetup);
} }
bool TestLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll)
@ -2094,13 +2086,13 @@ bool TestLaraCrawlToHang(ITEM_INFO* item, COLL_INFO* coll)
return false; return false;
} }
bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestData testData) bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestSetup testSetup)
{ {
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, testSetup.Angle, testSetup.Dist, -coll->Setup.Height);
bool isWading = testData.CheckWadeStatus ? (info->waterStatus == LW_WADE) : false; bool isWading = testSetup.CheckWadeStatus ? (info->waterStatus == LW_WADE) : false;
if (((probe.Position.Floor - y) >= -STEPUP_HEIGHT || // Within highest floor bound... if (((probe.Position.Floor - y) >= -STEPUP_HEIGHT || // Within highest floor bound...
probe.Position.FloorSlope) && // OR surface is a slope. TODO: May fail when coming to a slope from the side. probe.Position.FloorSlope) && // OR surface is a slope. TODO: May fail when coming to a slope from the side.
@ -2109,7 +2101,7 @@ bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestData testDa
(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).
!TestEnvironment(ENV_FLAG_SWAMP, item) && // No swamp. !TestEnvironment(ENV_FLAG_SWAMP, item) && // No swamp.
!TestLaraFacingCorner(item, testData.Angle, testData.Dist) && // Avoid jumping through corners. !TestLaraFacingCorner(item, testSetup.Angle, testSetup.Dist) && // Avoid jumping through corners.
probe.Position.Floor != NO_HEIGHT) probe.Position.Floor != NO_HEIGHT)
{ {
return true; return true;
@ -2120,65 +2112,65 @@ bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestData testDa
bool TestLaraRunJumpForward(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraRunJumpForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
item->pos.yRot, item->pos.yRot,
CLICK(1.5f) CLICK(1.5f)
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraJumpForward(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraJumpForward(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
item->pos.yRot item->pos.yRot
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraJumpBack(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraJumpBack(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
item->pos.yRot + ANGLE(180.0f) item->pos.yRot + ANGLE(180.0f)
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraJumpLeft(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraJumpLeft(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
item->pos.yRot - ANGLE(90.0f) item->pos.yRot - ANGLE(90.0f)
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraJumpRight(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraJumpRight(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
item->pos.yRot + ANGLE(90.0f) item->pos.yRot + ANGLE(90.0f)
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraJumpUp(ITEM_INFO* item, COLL_INFO* coll) bool TestLaraJumpUp(ITEM_INFO* item, COLL_INFO* coll)
{ {
JumpTestData testData JumpTestSetup testSetup
{ {
0, 0,
0, 0,
false false
}; };
return TestLaraJumpTolerance(item, coll, testData); return TestLaraJumpTolerance(item, coll, testSetup);
} }
bool TestLaraPoleCollision(ITEM_INFO* item, COLL_INFO* coll, bool up, float offset) bool TestLaraPoleCollision(ITEM_INFO* item, COLL_INFO* coll, bool up, float offset)

View file

@ -59,7 +59,7 @@ bool TestLaraMonkeyStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepUp(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraStepUp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepDown(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraStepDown(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestData testData); bool TestLaraMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestSetup testSetup);
bool TestLaraRunForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraRunForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWalkForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraWalkForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWalkBack(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraWalkBack(ITEM_INFO* item, COLL_INFO* coll);
@ -71,31 +71,31 @@ bool TestLaraWalkBackSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestData testData); bool TestLaraCrawlMoveTolerance(ITEM_INFO* item, COLL_INFO* coll, MoveTestSetup testSetup);
bool TestLaraCrawlForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlBack(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlBack(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrouchToCrawl(ITEM_INFO* item); bool TestLaraCrouchToCrawl(ITEM_INFO* item);
bool TestLaraCrouchRoll(ITEM_INFO* item, COLL_INFO* coll); 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, MonkeyMoveTestSetup testSetup);
bool TestLaraMonkeyForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraMonkeyForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMonkeyBack(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraMonkeyBack(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMonkeyShimmyLeft(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraMonkeyShimmyLeft(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMonkeyShimmyRight(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraMonkeyShimmyRight(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, VaultTestData testData); VaultTestResult TestLaraVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, VaultTestSetup testSetup);
VaultTestResultData TestLaraVault2Steps(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVault2Steps(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVault3Steps(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVault3Steps(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVaultAutoJump(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVaultAutoJump(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVault1StepToCrouch(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVault1StepToCrouch(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVault2StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVault2StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraVault3StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraVault3StepsToCrouch(ITEM_INFO* item, COLL_INFO* coll);
VaultTestResultData TestLaraLadderAutoJump(ITEM_INFO* item, COLL_INFO* coll); VaultTestResult TestLaraLadderAutoJump(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraLadderMount(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraLadderMount(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMonkeyAutoJump(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraMonkeyAutoJump(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, CrawlVaultTestData testData); bool TestLaraCrawlVaultTolerance(ITEM_INFO* item, COLL_INFO* coll, CrawlVaultTestSetup testSetup);
bool TestLaraCrawlUpStep(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlUpStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll);
@ -103,7 +103,7 @@ bool TestLaraCrawlExitJump(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlToHang(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraCrawlToHang(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestData testData); bool TestLaraJumpTolerance(ITEM_INFO* item, COLL_INFO* coll, JumpTestSetup testSetup);
bool TestLaraRunJumpForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraRunJumpForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraJumpForward(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraJumpForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraJumpBack(ITEM_INFO* item, COLL_INFO* coll); bool TestLaraJumpBack(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -36,6 +36,7 @@ constexpr auto SQUARE = [](auto x) { return x * x; };
constexpr auto CLICK = [](auto x) { return STEP_SIZE * x; }; constexpr auto CLICK = [](auto x) { return STEP_SIZE * x; };
constexpr auto SECTOR = [](auto x) { return WALL_SIZE * x; }; constexpr auto SECTOR = [](auto x) { return WALL_SIZE * x; };
constexpr auto MESH_BITS = [](auto x) { return 1 << x; }; constexpr auto MESH_BITS = [](auto x) { return 1 << x; };
constexpr auto OFFSET_RADIUS = [](auto x) { return x * sqrt(2) + 4; };
short ANGLE(float angle); short ANGLE(float angle);
short FROM_DEGREES(float angle); short FROM_DEGREES(float angle);