TombEngine/TR5Main/Objects/Generic/Object/generic_trapdoor.cpp

207 lines
5.9 KiB
C++
Raw Normal View History

2020-12-21 13:16:29 -03:00
#include "framework.h"
2021-12-24 11:08:16 +03:00
#include "Objects/Generic/Object/generic_trapdoor.h"
2021-12-22 16:23:57 +03:00
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
2021-12-22 16:23:57 +03:00
#include "Game/collision/floordata.h"
#include "Specific/input.h"
#include "Game/camera.h"
#include "Game/control/control.h"
#include "Specific/level.h"
#include "Game/animation.h"
#include "Game/items.h"
#include "Renderer/Renderer11.h"
#include "Game/collision/collide_item.h"
2021-09-29 03:41:36 +03:00
using namespace TEN::Renderer;
using namespace TEN::Floordata;
2021-09-25 11:27:47 +02:00
OBJECT_COLLISION_BOUNDS CeilingTrapDoorBounds = {-256, 256, 0, 900, -768, -256, -1820, 1820, -5460, 5460, -1820, 1820};
static PHD_VECTOR CeilingTrapDoorPos = {0, 1056, -480};
OBJECT_COLLISION_BOUNDS FloorTrapDoorBounds = {-256, 256, 0, 0, -1024, -256, -1820, 1820, -5460, 5460, -1820, 1820};
static PHD_VECTOR FloorTrapDoorPos = {0, 0, -655};
void InitialiseTrapDoor(short itemNumber)
{
ITEM_INFO* item;
item = &g_Level.Items[itemNumber];
2021-09-29 03:41:36 +03:00
TEN::Floordata::UpdateBridgeItem(itemNumber);
2021-06-12 16:39:13 -04:00
CloseTrapDoor(itemNumber);
}
void TrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item;
item = &g_Level.Items[itemNumber];
if (item->ActiveState == 1 && item->FrameNumber == g_Level.Anims[item->AnimNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
void CeilingTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
2021-09-20 03:02:54 +03:00
auto item = &g_Level.Items[itemNumber];
bool itemIsAbove = item->Position.yPos <= l->Position.yPos - LARA_HEIGHT + LARA_HEADROOM;
2021-09-20 03:02:54 +03:00
bool result = TestLaraPosition(&CeilingTrapDoorBounds, item, l);
l->Position.yRot += ANGLE(180);
2021-09-20 03:02:54 +03:00
bool result2 = TestLaraPosition(&CeilingTrapDoorBounds, item, l);
l->Position.yRot += ANGLE(180);
2021-09-20 03:02:54 +03:00
if (TrInput & IN_ACTION && item->Status != ITEM_ACTIVE && l->ActiveState == LS_JUMP_UP && l->Airborne && Lara.Control.HandStatus == HandStatus::Free && itemIsAbove && (result || result2))
{
AlignLaraPosition(&CeilingTrapDoorPos, item, l);
if (result2)
l->Position.yRot += ANGLE(180);
ResetLaraFlex(l);
Lara.Control.HandStatus = HandStatus::Busy;
l->Airborne = false;
l->VerticalVelocity = 0;
l->AnimNumber = LA_TRAPDOOR_CEILING_OPEN;
l->FrameNumber = g_Level.Anims[l->AnimNumber].frameBase;
l->ActiveState = LS_FREEFALL_BIS;
AddActiveItem(itemNumber);
item->Status = ITEM_ACTIVE;
item->TargetState = 1;
UseForcedFixedCamera = 1;
ForcedFixedCamera.x = item->Position.xPos - phd_sin(item->Position.yRot) * 1024;
ForcedFixedCamera.y = item->Position.yPos + 1024;
ForcedFixedCamera.z = item->Position.zPos - phd_cos(item->Position.yRot) * 1024;
ForcedFixedCamera.roomNumber = item->RoomNumber;
}
else
{
if (item->ActiveState == 1)
UseForcedFixedCamera = 0;
}
if (item->ActiveState == 1 && item->FrameNumber == g_Level.Anims[item->AnimNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
void FloorTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
ITEM_INFO* item;
item = &g_Level.Items[itemNumber];
if (TrInput & IN_ACTION && item->Status != ITEM_ACTIVE && l->ActiveState == LS_IDLE && l->AnimNumber == LA_STAND_IDLE && Lara.Control.HandStatus == HandStatus::Free
|| Lara.Control.IsMoving && Lara.interactedItem == itemNumber)
{
if (TestLaraPosition(&FloorTrapDoorBounds, item, l))
{
if (MoveLaraPosition(&FloorTrapDoorPos, item, l))
{
l->AnimNumber = LA_TRAPDOOR_FLOOR_OPEN;
l->FrameNumber = g_Level.Anims[l->AnimNumber].frameBase;
l->ActiveState = LS_TRAPDOOR_FLOOR_OPEN;
Lara.Control.IsMoving = false;
ResetLaraFlex(l);
Lara.Control.HandStatus = HandStatus::Busy;
AddActiveItem(itemNumber);
item->Status = ITEM_ACTIVE;
item->TargetState = 1;
UseForcedFixedCamera = 1;
ForcedFixedCamera.x = item->Position.xPos - phd_sin(item->Position.yRot) * 2048;
ForcedFixedCamera.y = item->Position.yPos - 2048;
if (ForcedFixedCamera.y < g_Level.Rooms[item->RoomNumber].maxceiling)
ForcedFixedCamera.y = g_Level.Rooms[item->RoomNumber].maxceiling;
ForcedFixedCamera.z = item->Position.zPos - phd_cos(item->Position.yRot) * 2048;
ForcedFixedCamera.roomNumber = item->RoomNumber;
}
else
{
Lara.interactedItem =itemNumber;
}
}
}
else
{
if (item->ActiveState == 1)
UseForcedFixedCamera = 0;
}
if (item->ActiveState == 1 && item->FrameNumber == g_Level.Anims[item->AnimNumber].frameEnd)
ObjectCollision(itemNumber, l, coll);
}
void TrapDoorControl(short itemNumber)
{
ITEM_INFO* item;
item = &g_Level.Items[itemNumber];
if (TriggerActive(item))
{
if (!item->ActiveState && item->TriggerFlags >= 0)
{
item->TargetState = 1;
}
else if (item->FrameNumber == g_Level.Anims[item->AnimNumber].frameEnd && CurrentLevel == 14 && item->ObjectNumber == ID_TRAPDOOR1)
{
item->Status = ITEM_INVISIBLE;
}
}
else
{
item->Status = ITEM_ACTIVE;
if (item->ActiveState == 1)
{
item->TargetState = 0;
}
}
AnimateItem(item);
if (item->ActiveState == 1 && (item->ItemFlags[2] || JustLoaded))
{
2021-06-12 16:39:13 -04:00
OpenTrapDoor(itemNumber);
}
else if (!item->ActiveState && !item->ItemFlags[2])
{
2021-06-12 16:39:13 -04:00
CloseTrapDoor(itemNumber);
}
}
2021-06-12 16:39:13 -04:00
void CloseTrapDoor(short itemNumber)
{
2021-06-12 16:39:13 -04:00
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->ItemFlags[2] = 1;
}
2021-06-12 16:39:13 -04:00
void OpenTrapDoor(short itemNumber)
{
2021-06-12 16:39:13 -04:00
ITEM_INFO* item = &g_Level.Items[itemNumber];
item->ItemFlags[2] = 0;
}
2021-06-11 12:07:09 -04:00
int TrapDoorFloorBorder(short itemNumber)
{
2021-09-29 03:41:36 +03:00
return GetBridgeBorder(itemNumber, false);
2021-06-11 12:07:09 -04:00
}
int TrapDoorCeilingBorder(short itemNumber)
{
2021-09-29 03:41:36 +03:00
return GetBridgeBorder(itemNumber, true);
2021-06-11 12:07:09 -04:00
}
std::optional<int> TrapDoorFloor(short itemNumber, int x, int y, int z)
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!item->MeshBits || item->ItemFlags[2] == 0)
2021-06-11 12:07:09 -04:00
return std::nullopt;
2021-09-29 03:41:36 +03:00
return GetBridgeItemIntersect(itemNumber, x, y, z, false);
2021-06-11 12:07:09 -04:00
}
std::optional<int> TrapDoorCeiling(short itemNumber, int x, int y, int z)
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
if (!item->MeshBits || item->ItemFlags[2] == 0)
2021-06-11 12:07:09 -04:00
return std::nullopt;
2021-09-29 03:41:36 +03:00
return GetBridgeItemIntersect(itemNumber, x, y, z, true);
2021-06-11 12:07:09 -04:00
}