Move various functions out of lara_swim.cpp

This commit is contained in:
Sezz 2021-11-10 01:32:54 +11:00
parent 1fccd6af22
commit a653767d71
10 changed files with 261 additions and 262 deletions

View file

@ -10,6 +10,7 @@
#include "lara_tests.h"
#include "items.h"
#include "setup.h"
#include "GameScriptLevel.h"
/*this file has all the generic **collision** test functions called in lara's state code*/
@ -351,3 +352,150 @@ void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)
Lara.waterStatus = LW_UNDERWATER;
}
}
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)
{
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
short oldXrot = item->pos.xRot;
short oldYrot = item->pos.yRot;
short oldZrot = item->pos.zRot;
if (item->pos.xRot < -ANGLE(90.0f) ||
item->pos.xRot > ANGLE(90.0f))
{
Lara.moveAngle = item->pos.yRot + ANGLE(180.0f);
coll->Setup.ForwardAngle = item->pos.yRot - ANGLE(180.0f);
}
else
{
Lara.moveAngle = item->pos.yRot;
coll->Setup.ForwardAngle = item->pos.yRot;
}
int height = LARA_HEIGHT * phd_sin(item->pos.xRot);
height = abs(height);
if (height < ((LaraDrawType == LARA_TYPE::DIVESUIT) << 6) + 200)
height = ((LaraDrawType == LARA_TYPE::DIVESUIT) << 6) + 200;
coll->Setup.BadHeightUp = -(STEP_SIZE / 4);
coll->Setup.Height = height;
GetCollisionInfo(coll, item, PHD_VECTOR(0, height / 2, 0));
auto c1 = *coll;
c1.Setup.ForwardAngle += ANGLE(45.0f);
GetCollisionInfo(&c1, item, PHD_VECTOR(0, height / 2, 0));
auto c2 = *coll;
c2.Setup.ForwardAngle -= ANGLE(45.0f);
GetCollisionInfo(&c2, item, PHD_VECTOR(0, height / 2, 0));
ShiftItem(item, coll);
int flag = 0;
switch (coll->CollisionType)
{
case CT_FRONT:
if (item->pos.xRot <= ANGLE(25.0f))
{
if (item->pos.xRot >= -ANGLE(25.0f))
{
if (item->pos.xRot > ANGLE(5.0f))
item->pos.xRot += ANGLE(0.5f);
else if (item->pos.xRot < -ANGLE(5.0f))
item->pos.xRot -= ANGLE(0.5f);
else if (item->pos.xRot > 0)
item->pos.xRot += 45;
else if (item->pos.xRot < 0)
item->pos.xRot -= 45;
else
{
item->fallspeed = 0;
flag = 1;
}
}
else
{
item->pos.xRot -= ANGLE(1.0f);
flag = 1;
}
}
else
{
item->pos.xRot += ANGLE(1.0f);
flag = 1;
}
if (c1.CollisionType == CT_LEFT)
item->pos.yRot += ANGLE(2.0f);
else if (c1.CollisionType == CT_RIGHT)
item->pos.yRot -= ANGLE(2.0f);
else if (c2.CollisionType == CT_LEFT)
item->pos.yRot += ANGLE(2.0f);
else if (c2.CollisionType == CT_RIGHT)
item->pos.yRot -= ANGLE(2.0f);
break;
case CT_TOP:
if (item->pos.xRot >= -8190)
{
flag = 1;
item->pos.xRot -= ANGLE(1.0f);
}
break;
case CT_TOP_FRONT:
item->fallspeed = 0;
flag = 1;
break;
case CT_LEFT:
item->pos.yRot += ANGLE(2.0f);
flag = 1;
break;
case CT_RIGHT:
item->pos.yRot -= ANGLE(2.0f);
flag = 1;
break;
case CT_CLAMP:
flag = 2;
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
item->fallspeed = 0;
break;
}
if (coll->Middle.Floor < 0 && coll->Middle.Floor != NO_HEIGHT)
{
flag = 1;
item->pos.xRot += ANGLE(1.0f);
item->pos.yPos += coll->Middle.Floor;
}
if (oldX == item->pos.xPos &&
oldY == item->pos.yPos &&
oldZ == item->pos.zPos &&
oldXrot == item->pos.xRot &&
oldYrot == item->pos.yRot ||
flag != 1)
{
if (flag == 2)
return;
}
if (Lara.waterStatus != LW_FLYCHEAT && Lara.ExtraAnim == NO_ITEM)
TestLaraWaterDepth(item, coll);
}

View file

@ -17,3 +17,4 @@ short GetDirOctant(int rot);
void GetLaraDeadlyBounds();
void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll);
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -8,6 +8,7 @@
#include "Lara.h"
#include "level.h"
#include "input.h"
#include "lara_collide.h"
void lara_col_surftread(ITEM_INFO* item, COLL_INFO* coll)
{

View file

@ -13,8 +13,4 @@ void _cdecl lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll);
bool _cdecl TestLaraWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll);
bool _cdecl TestLaraWaterStepOut(ITEM_INFO* item, COLL_INFO* coll);
bool _cdecl TestLaraLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll); // NEW function for water to ladder move
void lara_as_waterout(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -9,6 +9,7 @@
#include "input.h"
#include "Sound/sound.h"
#include "GameFlowScript.h"
#include "lara_collide.h"
struct SUBSUIT_INFO
{
@ -96,81 +97,6 @@ void LaraWaterCurrent(COLL_INFO* coll)
coll->Setup.OldPosition.z = LaraItem->pos.zPos;
}
int GetWaterDepth(int x, int y, int z, short roomNumber)
{
FLOOR_INFO* floor;
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
short roomIndex = NO_ROOM;
do
{
int zFloor = (z - r->z) / SECTOR(1);
int xFloor = (x - r->x) / SECTOR(1);
if (zFloor <= 0)
{
zFloor = 0;
if (xFloor < 1)
xFloor = 1;
else if (xFloor > r->xSize - 2)
xFloor = r->xSize - 2;
}
else if (zFloor >= r->zSize - 1)
{
zFloor = r->zSize - 1;
if (xFloor < 1)
xFloor = 1;
else if (xFloor > r->xSize - 2)
xFloor = r->xSize - 2;
}
else if (xFloor < 0)
xFloor = 0;
else if (xFloor >= r->xSize)
xFloor = r->xSize - 1;
floor = &r->floor[zFloor + xFloor * r->zSize];
roomIndex = floor->WallPortal;
if (roomIndex != NO_ROOM)
{
roomNumber = roomIndex;
r = &g_Level.Rooms[roomIndex];
}
} while (roomIndex != NO_ROOM);
if (r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
{
while (floor->RoomAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
r = &g_Level.Rooms[floor->RoomAbove(x, y, z).value_or(floor->Room)];
if (!(r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP)))
{
int wh = floor->CeilingHeight(x, z);
floor = GetFloor(x, y, z, &roomNumber);
return (GetFloorHeight(floor, x, y, z) - wh);
}
floor = GetSector(r, x - r->x, z - r->z);
}
return DEEP_WATER;
}
else
{
while (floor->RoomBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
r = &g_Level.Rooms[floor->RoomBelow(x, y, z).value_or(floor->Room)];
if (r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
{
int wh = floor->FloorHeight(x, z);
floor = GetFloor(x, y, z, &roomNumber);
return (GetFloorHeight(floor, x, y, z) - wh);
}
floor = GetSector(r, x - r->x, z - r->z);
}
return NO_HEIGHT;
}
}
void lara_col_waterroll(ITEM_INFO* item, COLL_INFO* coll)
{
LaraSwimCollision(item, coll);
@ -474,183 +400,3 @@ void SwimTurn(ITEM_INFO* item)
item->pos.zRot += LARA_LEAN_RATE * 2;
}
}
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)
{
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
short oldXrot = item->pos.xRot;
short oldYrot = item->pos.yRot;
short oldZrot = item->pos.zRot;
if (item->pos.xRot < -ANGLE(90.0f) ||
item->pos.xRot > ANGLE(90.0f))
{
Lara.moveAngle = item->pos.yRot + ANGLE(180.0f);
coll->Setup.ForwardAngle = item->pos.yRot - ANGLE(180.0f);
}
else
{
Lara.moveAngle = item->pos.yRot;
coll->Setup.ForwardAngle = item->pos.yRot;
}
int height = LARA_HEIGHT * phd_sin(item->pos.xRot);
height = abs(height);
if (height < ((LaraDrawType == LARA_TYPE::DIVESUIT) << 6) + 200)
height = ((LaraDrawType == LARA_TYPE::DIVESUIT) << 6) + 200;
coll->Setup.BadHeightUp = -(STEP_SIZE / 4);
coll->Setup.Height = height;
GetCollisionInfo(coll, item, PHD_VECTOR(0, height / 2, 0));
auto c1 = *coll;
c1.Setup.ForwardAngle += ANGLE(45.0f);
GetCollisionInfo(&c1, item, PHD_VECTOR(0, height / 2, 0));
auto c2 = *coll;
c2.Setup.ForwardAngle -= ANGLE(45.0f);
GetCollisionInfo(&c2, item, PHD_VECTOR(0, height / 2, 0));
ShiftItem(item, coll);
int flag = 0;
switch (coll->CollisionType)
{
case CT_FRONT:
if (item->pos.xRot <= ANGLE(25.0f))
{
if (item->pos.xRot >= -ANGLE(25.0f))
{
if (item->pos.xRot > ANGLE(5.0f))
item->pos.xRot += ANGLE(0.5f);
else if (item->pos.xRot < -ANGLE(5.0f))
item->pos.xRot -= ANGLE(0.5f);
else if (item->pos.xRot > 0)
item->pos.xRot += 45;
else if (item->pos.xRot < 0)
item->pos.xRot -= 45;
else
{
item->fallspeed = 0;
flag = 1;
}
}
else
{
item->pos.xRot -= ANGLE(1.0f);
flag = 1;
}
}
else
{
item->pos.xRot += ANGLE(1.0f);
flag = 1;
}
if (c1.CollisionType == CT_LEFT)
item->pos.yRot += ANGLE(2.0f);
else if (c1.CollisionType == CT_RIGHT)
item->pos.yRot -= ANGLE(2.0f);
else if (c2.CollisionType == CT_LEFT)
item->pos.yRot += ANGLE(2.0f);
else if (c2.CollisionType == CT_RIGHT)
item->pos.yRot -= ANGLE(2.0f);
break;
case CT_TOP:
if (item->pos.xRot >= -8190)
{
flag = 1;
item->pos.xRot -= ANGLE(1.0f);
}
break;
case CT_TOP_FRONT:
item->fallspeed = 0;
flag = 1;
break;
case CT_LEFT:
item->pos.yRot += ANGLE(2.0f);
flag = 1;
break;
case CT_RIGHT:
item->pos.yRot -= ANGLE(2.0f);
flag = 1;
break;
case CT_CLAMP:
flag = 2;
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
item->fallspeed = 0;
break;
}
if (coll->Middle.Floor < 0 && coll->Middle.Floor != NO_HEIGHT)
{
flag = 1;
item->pos.xRot += ANGLE(1.0f);
item->pos.yPos += coll->Middle.Floor;
}
if (oldX == item->pos.xPos &&
oldY == item->pos.yPos &&
oldZ == item->pos.zPos &&
oldXrot == item->pos.xRot &&
oldYrot == item->pos.yRot ||
flag != 1)
{
if (flag == 2)
return;
}
if (Lara.waterStatus != LW_FLYCHEAT && Lara.ExtraAnim == NO_ITEM)
TestLaraWaterDepth(item, coll);
}
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll)
{
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
int waterDepth = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, roomNumber);
if (waterDepth == NO_HEIGHT)
{
item->fallspeed = 0;
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
}
// Height check was at STEP_SIZE * 2 before but changed to this
// because now Lara surfaces on a head level, not mid-body level.
if (waterDepth <= LARA_HEIGHT - LARA_HEADROOM / 2)
{
item->animNumber = LA_UNDERWATER_TO_STAND;
item->frameNumber = GF(LA_UNDERWATER_TO_STAND, 0);
item->currentAnimState = LS_ONWATER_EXIT;
item->goalAnimState = LS_STOP;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
Lara.waterStatus = LW_WADE;
item->pos.yPos = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
}
}

View file

@ -2,7 +2,6 @@
#include "collide.h"
void LaraWaterCurrent(COLL_INFO* coll);
int GetWaterDepth(int x, int y, int z, short roomNumber);
void lara_col_waterroll(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_uwdeath(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_dive(ITEM_INFO* item, COLL_INFO* coll);
@ -18,5 +17,3 @@ void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll);
void UpdateSubsuitAngles();
void SwimTurnSubsuit(ITEM_INFO* item);
void SwimTurn(ITEM_INFO* item);
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll);
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -1549,6 +1549,39 @@ bool TestLaraLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll) // NEW function fo
return true;
}
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll)
{
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
int waterDepth = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, roomNumber);
if (waterDepth == NO_HEIGHT)
{
item->fallspeed = 0;
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
}
// Height check was at STEP_SIZE * 2 before but changed to this
// because now Lara surfaces on a head level, not mid-body level.
if (waterDepth <= LARA_HEIGHT - LARA_HEADROOM / 2)
{
item->animNumber = LA_UNDERWATER_TO_STAND;
item->frameNumber = GF(LA_UNDERWATER_TO_STAND, 0);
item->currentAnimState = LS_ONWATER_EXIT;
item->goalAnimState = LS_STOP;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
Lara.waterStatus = LW_WADE;
item->pos.yPos = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
}
}
#ifndef NEW_TIGHTROPE
void GetTighRopeFallOff(int regularity) {
if(LaraItem->hitPoints <= 0 || LaraItem->hitStatus)

View file

@ -42,6 +42,7 @@ void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip);
bool TestLaraWaterStepOut(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll);
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll);
#ifndef NEW_TIGHTROPE
void GetTighRopeFallOff(int Regularity);

View file

@ -935,6 +935,81 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
return NO_HEIGHT;
}
int GetWaterDepth(int x, int y, int z, short roomNumber)
{
FLOOR_INFO* floor;
ROOM_INFO* r = &g_Level.Rooms[roomNumber];
short roomIndex = NO_ROOM;
do
{
int zFloor = (z - r->z) / SECTOR(1);
int xFloor = (x - r->x) / SECTOR(1);
if (zFloor <= 0)
{
zFloor = 0;
if (xFloor < 1)
xFloor = 1;
else if (xFloor > r->xSize - 2)
xFloor = r->xSize - 2;
}
else if (zFloor >= r->zSize - 1)
{
zFloor = r->zSize - 1;
if (xFloor < 1)
xFloor = 1;
else if (xFloor > r->xSize - 2)
xFloor = r->xSize - 2;
}
else if (xFloor < 0)
xFloor = 0;
else if (xFloor >= r->xSize)
xFloor = r->xSize - 1;
floor = &r->floor[zFloor + xFloor * r->zSize];
roomIndex = floor->WallPortal;
if (roomIndex != NO_ROOM)
{
roomNumber = roomIndex;
r = &g_Level.Rooms[roomIndex];
}
} while (roomIndex != NO_ROOM);
if (r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
{
while (floor->RoomAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
r = &g_Level.Rooms[floor->RoomAbove(x, y, z).value_or(floor->Room)];
if (!(r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP)))
{
int wh = floor->CeilingHeight(x, z);
floor = GetFloor(x, y, z, &roomNumber);
return (GetFloorHeight(floor, x, y, z) - wh);
}
floor = GetSector(r, x - r->x, z - r->z);
}
return DEEP_WATER;
}
else
{
while (floor->RoomBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
r = &g_Level.Rooms[floor->RoomBelow(x, y, z).value_or(floor->Room)];
if (r->flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP))
{
int wh = floor->FloorHeight(x, z);
floor = GetFloor(x, y, z, &roomNumber);
return (GetFloorHeight(floor, x, y, z) - wh);
}
floor = GetSector(r, x - r->x, z - r->z);
}
return NO_HEIGHT;
}
}
int GetDistanceToFloor(int itemNumber, bool precise)
{
auto item = &g_Level.Items[itemNumber];

View file

@ -89,6 +89,7 @@ FLOOR_INFO* GetFloor(int x, int y, int z, short* roomNumber);
int GetCeiling(FLOOR_INFO* floor, int x, int y, int z);
int GetWaterSurface(int x, int y, int z, short roomNumber);
int GetWaterHeight(int x, int y, int z, short roomNumber);
int GetWaterDepth(int x, int y, int z, short roomNumber);
int GetDistanceToFloor(int itemNumber, bool precise = true);
unsigned CALLBACK GameMain(void*);