box.cpp cleanup; allow fall damage in swan dive state

This commit is contained in:
Sezz 2022-03-05 15:20:20 +11:00
parent a4c74cd588
commit bae68adc4c
8 changed files with 449 additions and 537 deletions

View file

@ -52,9 +52,9 @@ constexpr auto LARA_RAD_DEATH = 400;
constexpr auto LARA_VELOCITY = 12;
constexpr auto LARA_FREEFALL_VELOCITY = 131;
constexpr auto LARA_FREEFALL_DAMAGE_VELOCITY = 141;
constexpr auto LARA_FREEFALL_DEATH_VELOCITY = 155;
constexpr auto LARA_FREEFALL_DIVE_DEATH_VELOCITY = 133;
constexpr auto LARA_DAMAGE_VELOCITY = 141;
constexpr auto LARA_DEATH_VELOCITY = 155;
constexpr auto LARA_DIVE_DEATH_VELOCITY = 133;
constexpr auto LARA_RUN_JUMP_TIME = 22; // Frames to count before a running jump is possible.
constexpr auto LARA_POSE_TIME = 30 * 30; // 30 frames * 30 = 30 seconds to AFK pose.

View file

@ -152,13 +152,13 @@ void DoLaraCrawlFlex(ITEM_INFO* item, COLL_INFO* coll, short maxAngle, short rat
void DoLaraFallDamage(ITEM_INFO* item)
{
if (item->VerticalVelocity >= LARA_FREEFALL_DAMAGE_VELOCITY)
if (item->VerticalVelocity >= LARA_DAMAGE_VELOCITY)
{
if (item->VerticalVelocity >= LARA_FREEFALL_DEATH_VELOCITY)
if (item->VerticalVelocity >= LARA_DEATH_VELOCITY)
item->HitPoints = 0;
else [[likely]]
{
int base = item->VerticalVelocity - (LARA_FREEFALL_DAMAGE_VELOCITY - 1);
int base = item->VerticalVelocity - (LARA_DAMAGE_VELOCITY - 1);
item->HitPoints -= LARA_HEALTH_MAX * (pow(base, 2) / 196);
}
}
@ -228,17 +228,15 @@ void DoLaraTightropeBalanceRegen(ITEM_INFO* item)
LaraInfo*& GetLaraInfo(ITEM_INFO* item)
{
if (item->ObjectNumber != ID_LARA)
{
if (item->ObjectNumber == ID_LARA)
return (LaraInfo*&)item->Data;
TENLog(std::string("Attempted to fetch LaraInfo data from entity with object ID ") + std::to_string(item->ObjectNumber), LogLevel::Warning);
auto* firstLaraItem = FindItem(ID_LARA);
return (LaraInfo*&)firstLaraItem->Data;
}
return (LaraInfo*&)item->Data;
}
short GetLaraSlideDirection(ITEM_INFO* item, COLL_INFO* coll)
{
short direction = item->Position.yRot;

View file

@ -138,7 +138,7 @@ void lara_as_freefall(ITEM_INFO* item, COLL_INFO* coll)
{
item->Velocity = item->Velocity * 0.95f;
if (item->VerticalVelocity == LARA_FREEFALL_DEATH_VELOCITY &&
if (item->VerticalVelocity == LARA_DEATH_VELOCITY &&
item->HitPoints > 0)
{
SoundEffect(SFX_TR4_LARA_FALL, &item->Position, 0);
@ -785,6 +785,8 @@ void lara_as_swan_dive(ITEM_INFO* item, COLL_INFO* coll)
if (TestLaraLand(item, coll))
{
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->TargetState = LS_DEATH;
else if (TestLaraSlide(item, coll))
@ -851,7 +853,7 @@ void lara_as_freefall_dive(ITEM_INFO* item, COLL_INFO* coll)
if (TestLaraLand(item, coll))
{
if (item->VerticalVelocity >= LARA_FREEFALL_DIVE_DEATH_VELOCITY ||
if (item->VerticalVelocity >= LARA_DIVE_DEATH_VELOCITY ||
item->HitPoints <= 0)
{
item->TargetState = LS_DEATH;

View file

@ -111,6 +111,7 @@ bool TestLaraKeepLow(ITEM_INFO* item, COLL_INFO* coll)
auto probeBack = GetCollisionResult(item, item->Position.yRot + ANGLE(180.0f), radius, -coll->Setup.Height);
auto probeMiddle = GetCollisionResult(item);
// TODO: Assess clamp instead?
// TODO: Cannot use as a failsafe in standing states; bugged with slanted ceilings reaching the ground.
// In common setups, Lara may embed on such ceilings, resulting in inappropriate crouch state dispatches. @Sezz 2021.10.15
if ((probeFront.Position.Ceiling - y) >= -LARA_HEIGHT || // Front is not a clamp.

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,7 @@ struct OBJECT_BONES
{
this->bone0 = angleY;
this->bone1 = angleX;
if (total)
{
this->bone2 = angleY;
@ -183,27 +184,27 @@ constexpr auto CLIP_BOTTOM = 0x8;
constexpr auto SECONDARY_CLIP = 0x10;
constexpr auto ALL_CLIP = (CLIP_LEFT | CLIP_RIGHT | CLIP_TOP | CLIP_BOTTOM);
void GetCreatureMood(ITEM_INFO* item, AI_INFO* info, int violent);
void CreatureMood(ITEM_INFO* item, AI_INFO* info, int violent);
void GetCreatureMood(ITEM_INFO* item, AI_INFO* AI, int violent);
void CreatureMood(ITEM_INFO* item, AI_INFO* AI, int violent);
void FindAITargetObject(CREATURE_INFO* creature, short objectNumber);
void GetAITarget(CREATURE_INFO* creature);
int CreatureVault(short itemNum, short angle, int vault, int shift);
int CreatureVault(short itemNumber, short angle, int vault, int shift);
void DropBaddyPickups(ITEM_INFO* item);
int MoveCreature3DPos(PHD_3DPOS* srcpos, PHD_3DPOS* destpos, int velocity, short angdif, int angadd);
void CreatureYRot2(PHD_3DPOS* srcpos, short angle, short angadd);
int MoveCreature3DPos(PHD_3DPOS* srcPos, PHD_3DPOS* destPos, int velocity, short angleDif, int angleAdd);
void CreatureYRot2(PHD_3DPOS* srcPos, short angle, short angadd);
bool SameZone(CREATURE_INFO* creature, ITEM_INFO* target);
void FindAITargetObject(CREATURE_INFO* creature, short objNum);
short AIGuard(CREATURE_INFO* creature);
void AlertNearbyGuards(ITEM_INFO* item);
void AlertAllGuards(short itemNumber);
void CreatureKill(ITEM_INFO* item, int killAnim, int killState, short laraAnim);
void CreatureKill(ITEM_INFO* item, int killAnim, int killState, int laraKillState);
short CreatureEffect2(ITEM_INFO* item, BITE_INFO* bite, short damage, short angle, std::function<CreatureEffectFunction> func);
short CreatureEffect(ITEM_INFO* item, BITE_INFO* bite, std::function<CreatureEffectFunction> func);
void CreatureUnderwater(ITEM_INFO* item, int depth);
void CreatureFloat(short itemNumber);
void CreatureJoint(ITEM_INFO* item, short joint, short required);
void CreatureTilt(ITEM_INFO* item, short angle);
short CreatureTurn(ITEM_INFO* item, short maximumTurn);
short CreatureTurn(ITEM_INFO* item, short maxTurn);
void CreatureDie(short itemNumber, int explode);
int BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOT_INFO* LOT);
int CreatureCreature(short itemNumber);
@ -215,8 +216,8 @@ int SearchLOT(LOT_INFO* LOT, int expansion);
int CreatureActive(short itemNumber);
void InitialiseCreature(short itemNumber);
int StalkBox(ITEM_INFO* item, ITEM_INFO* enemy, int boxNumber);
void CreatureAIInfo(ITEM_INFO* item, AI_INFO* info);
void CreatureAIInfo(ITEM_INFO* item, AI_INFO* AI);
TARGET_TYPE CalculateTarget(PHD_VECTOR* target, ITEM_INFO* item, LOT_INFO* LOT);
int CreatureAnimation(short itemNumber, short angle, short tilt);
void AdjustStopperFlag(ITEM_INFO* item, int dir, bool set);
void AdjustStopperFlag(ITEM_INFO* item, int direction, bool set);
void InitialiseItemBoxData();

View file

@ -31,9 +31,7 @@ int TriggerActive(ITEM_INFO* item)
flag = (~item->Flags & IFLAG_REVERSE) >> 14;
if ((item->Flags & IFLAG_ACTIVATION_MASK) != IFLAG_ACTIVATION_MASK)
{
flag = !flag;
}
else
{
if (item->Timer)
@ -50,6 +48,7 @@ int TriggerActive(ITEM_INFO* item)
if (item->Timer == -1)
item->Timer = 0;
}
if (item->Timer <= -1)
flag = !flag;
}
@ -114,9 +113,10 @@ int GetSwitchTrigger(ITEM_INFO* item, short* itemNos, int attatchedToSwitch)
return 0;
}
int SwitchTrigger(short itemNum, short timer)
int SwitchTrigger(short itemNumber, short timer)
{
ITEM_INFO* item = &g_Level.Items[itemNum];
auto* item = &g_Level.Items[itemNumber];
if (item->Status == ITEM_DEACTIVATED)
{
if ((!item->ActiveState && item->ObjectNumber != ID_JUMP_SWITCH || item->ActiveState == 1 && item->ObjectNumber == ID_JUMP_SWITCH) && timer > 0)
@ -129,7 +129,7 @@ int SwitchTrigger(short itemNum, short timer)
}
if (item->TriggerFlags != 6 || item->ActiveState)
{
RemoveActiveItem(itemNum);
RemoveActiveItem(itemNumber);
item->Status = ITEM_NOT_ACTIVE;
if (!item->ItemFlags[0] == 0)

View file

@ -62,7 +62,7 @@ extern int KeyTriggerActive;
bool GetKeyTrigger(ITEM_INFO* item);
int GetSwitchTrigger(ITEM_INFO* item, short* itemNos, int attatchedToSwitch);
int SwitchTrigger(short itemNum, short timer);
int SwitchTrigger(short itemNumber, short timer);
int KeyTrigger(short itemNum);
int PickupTrigger(short itemNum);
void RefreshCamera(short type, short* data);