TombEngine/TR5Main/Objects/Generic/puzzles_keys.cpp

337 lines
8.9 KiB
C++
Raw Normal View History

#include "framework.h"
2021-12-24 11:08:16 +03:00
#include "Objects/Generic/puzzles_keys.h"
#include "Game/animation.h"
#include "Game/camera.h"
2021-12-22 16:23:57 +03:00
#include "Game/collision/collide_item.h"
2021-12-24 11:08:16 +03:00
#include "Game/control/control.h"
2021-12-22 16:23:57 +03:00
#include "Game/gui.h"
2021-12-24 11:08:16 +03:00
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
2021-12-22 16:23:57 +03:00
#include "Game/pickup/pickup.h"
2021-12-24 03:32:19 +03:00
#include "Objects/Generic/Switches/generic_switch.h"
2021-12-24 11:08:16 +03:00
#include "Specific/input.h"
#include "Specific/level.h"
#include "Specific/setup.h"
2021-09-25 11:27:47 +02:00
2021-08-28 06:37:22 +02:00
using namespace TEN::Entities::Switches;
2022-02-24 14:22:30 +11:00
short puzzleItem;
enum PuzzleType
{
PUZZLETYPE_NORMAL,
PUZZLETYPE_SPECIFIC,
PUZZLETYPE_CUTSCENE,
PUZZLETYPE_ANIM_AFTER
};
OBJECT_COLLISION_BOUNDS PuzzleBounds =
2022-02-24 14:22:30 +11:00
{
0, 0,
-256, 256,
0, 0,
ANGLE(-10.0f), ANGLE(10.0f),
ANGLE(-30.0f), ANGLE(30.0f),
ANGLE(-10.0f), ANGLE(10.0f)
};
2021-10-27 19:00:30 +03:00
static PHD_VECTOR KeyHolePosition(0, 0, 312);
2021-10-27 19:00:30 +03:00
OBJECT_COLLISION_BOUNDS KeyHoleBounds =
2022-02-24 14:22:30 +11:00
{
-256, 256,
0, 0,
0, 412,
ANGLE(-10.0f), ANGLE(10.0f),
ANGLE(-30.0f), ANGLE(30.0f),
ANGLE(-10.0f), ANGLE(10.0f)
};
2022-02-24 14:22:30 +11:00
// Puzzles
void PuzzleHoleCollision(short itemNumber, ITEM_INFO* laraItem, CollisionInfo* coll)
{
2022-02-24 14:22:30 +11:00
auto* laraInfo = GetLaraInfo(laraItem);
auto* receptableItem = &g_Level.Items[itemNumber];
int flag = PUZZLETYPE_NORMAL;
2022-02-24 14:22:30 +11:00
if (receptableItem->TriggerFlags >= 0)
{
2022-02-24 14:22:30 +11:00
if (receptableItem->TriggerFlags <= 1024)
{
2022-02-24 14:22:30 +11:00
if (receptableItem->TriggerFlags &&
receptableItem->TriggerFlags != 999 &&
receptableItem->TriggerFlags != 998)
{
flag = PUZZLETYPE_ANIM_AFTER;
2022-02-24 14:22:30 +11:00
}
}
else
flag = PUZZLETYPE_CUTSCENE;
}
else
flag = PUZZLETYPE_SPECIFIC;
2022-02-24 14:22:30 +11:00
if (((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM) &&
!BinocularRange &&
laraItem->Animation.ActiveState == LS_IDLE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
2022-02-24 14:22:30 +11:00
laraInfo->Control.HandStatus == HandStatus::Free &&
GetKeyTrigger(&g_Level.Items[itemNumber])) ||
(laraInfo->Control.IsMoving &&
laraInfo->InteractedItem == itemNumber))
{
2022-02-24 14:22:30 +11:00
short oldYrot = receptableItem->Position.yRot;
2022-02-24 14:22:30 +11:00
auto* bounds = GetBoundsAccurate(receptableItem);
PuzzleBounds.boundingBox.X1 = bounds->X1 - 256;
PuzzleBounds.boundingBox.X2 = bounds->X2 + 256;
PuzzleBounds.boundingBox.Z1 = bounds->Z1 - 256;
PuzzleBounds.boundingBox.Z2 = bounds->Z2 + 256;
2022-02-24 14:22:30 +11:00
if (TestLaraPosition(&PuzzleBounds, receptableItem, laraItem))
{
2022-02-24 14:22:30 +11:00
if (!laraInfo->Control.IsMoving)
{
2021-11-16 15:51:50 +03:00
if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
{
2022-02-24 14:22:30 +11:00
if (g_Gui.IsObjectInInventory(receptableItem->ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1)))
g_Gui.SetEnterInventory(receptableItem->ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1));
2022-02-24 14:22:30 +11:00
receptableItem->Position.yRot = oldYrot;
return;
}
2022-02-24 14:22:30 +11:00
if (g_Gui.GetInventoryItemChosen() != receptableItem->ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1))
{
2022-02-24 14:22:30 +11:00
receptableItem->Position.yRot = oldYrot;
return;
}
}
2021-08-29 05:53:07 +02:00
if (flag != PUZZLETYPE_CUTSCENE)
{
2022-02-24 14:22:30 +11:00
PHD_VECTOR pos = { 0, 0, bounds->Z1 - 100 };
if (!MoveLaraPosition(&pos, receptableItem, laraItem))
{
laraInfo->InteractedItem = itemNumber;
2021-11-16 15:51:50 +03:00
g_Gui.SetInventoryItemChosen(NO_ITEM);
2022-02-24 14:22:30 +11:00
receptableItem->Position.yRot = oldYrot;
return;
}
}
2022-02-24 14:22:30 +11:00
RemoveObjectFromInventory(static_cast<GAME_OBJECT_ID>(receptableItem->ObjectNumber - (ID_PUZZLE_HOLE1 - ID_PUZZLE_ITEM1)), 1);
if (flag == PUZZLETYPE_SPECIFIC)
{
laraItem->Animation.ActiveState = LS_MISC_CONTROL;
laraItem->Animation.AnimNumber = -receptableItem->TriggerFlags;
2022-02-24 14:22:30 +11:00
if (laraItem->Animation.AnimNumber != LA_TRIDENT_SET)
2022-02-24 14:22:30 +11:00
PuzzleDone(receptableItem, itemNumber);
}
else
{
laraItem->Animation.AnimNumber = LA_USE_PUZZLE;
laraItem->Animation.ActiveState = LS_INSERT_PUZZLE;
2022-02-24 14:22:30 +11:00
receptableItem->ItemFlags[0] = 1;
}
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
2022-02-24 14:22:30 +11:00
laraInfo->Control.IsMoving = false;
ResetLaraFlex(laraItem);
laraInfo->Control.HandStatus = HandStatus::Busy;
receptableItem->Flags |= 0x20;
laraInfo->InteractedItem = itemNumber;
2021-11-16 15:51:50 +03:00
g_Gui.SetInventoryItemChosen(NO_ITEM);
2022-02-24 14:22:30 +11:00
receptableItem->Position.yRot = oldYrot;
return;
}
2022-02-24 14:22:30 +11:00
if (laraInfo->Control.IsMoving)
{
if (laraInfo->InteractedItem == itemNumber)
{
2022-02-24 14:22:30 +11:00
laraInfo->Control.IsMoving = false;
laraInfo->Control.HandStatus = HandStatus::Free;
}
}
2022-02-24 14:22:30 +11:00
receptableItem->Position.yRot = oldYrot;
}
else
{
if (!laraInfo->Control.IsMoving && laraInfo->InteractedItem == itemNumber || laraInfo->InteractedItem != itemNumber)
{
if (laraInfo->InteractedItem == itemNumber)
{
if (laraItem->Animation.ActiveState != LS_MISC_CONTROL)
{
if (flag != PUZZLETYPE_CUTSCENE)
2022-02-24 14:22:30 +11:00
ObjectCollision(itemNumber, laraItem, coll);
return;
}
}
2022-02-24 14:22:30 +11:00
if (laraItem->Animation.ActiveState == LS_MISC_CONTROL)
return;
2021-08-29 05:53:07 +02:00
if (flag != PUZZLETYPE_CUTSCENE)
2022-02-24 14:22:30 +11:00
ObjectCollision(itemNumber, laraItem, coll);
return;
}
}
}
void PuzzleDoneCollision(short itemNumber, ITEM_INFO* laraItem, CollisionInfo* coll)
{
2022-02-24 14:22:30 +11:00
if (g_Level.Items[itemNumber].TriggerFlags - 998 > 1)
ObjectCollision(itemNumber, laraItem, coll);
}
2022-02-24 14:22:30 +11:00
void PuzzleDone(ITEM_INFO* item, short itemNumber)
{
item->ObjectNumber += GAME_OBJECT_ID{ ID_PUZZLE_DONE1 - ID_PUZZLE_HOLE1 };
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.RequiredState = 0;
item->Animation.TargetState = g_Level.Anims[item->Animation.AnimNumber].ActiveState;
item->Animation.ActiveState = g_Level.Anims[item->Animation.AnimNumber].ActiveState;
2022-02-24 14:22:30 +11:00
AddActiveItem(itemNumber);
item->Flags |= IFLAG_ACTIVATION_MASK;
item->Status = ITEM_ACTIVE;
}
2021-11-03 03:49:57 +03:00
void DoPuzzle()
{
puzzleItem = Lara.InteractedItem;
2022-02-24 14:22:30 +11:00
auto* item = &g_Level.Items[puzzleItem];
int flag = 0;
if (item->TriggerFlags >= 0)
{
if (item->TriggerFlags <= 1024)
{
if (item->TriggerFlags && item->TriggerFlags != 999 && item->TriggerFlags != 998)
flag = 3;
}
else
flag = 2;
}
else
flag = 1;
if (LaraItem->Animation.ActiveState == LS_INSERT_PUZZLE)
{
if (item->ItemFlags[0])
{
if (flag == 3)
LaraItem->ItemFlags[0] = item->TriggerFlags;
else
{
LaraItem->ItemFlags[0] = 0;
PuzzleDone(item, puzzleItem);
item->ItemFlags[0] = 0;
}
}
if (LaraItem->Animation.AnimNumber == LA_TRIDENT_SET)
PuzzleDone(item, puzzleItem);
}
}
2022-02-24 14:22:30 +11:00
// Keys
void KeyHoleCollision(short itemNumber, ITEM_INFO* laraItem, CollisionInfo* coll)
{
2022-02-24 14:22:30 +11:00
auto* laraInfo = GetLaraInfo(laraItem);
auto* keyHoleItem = &g_Level.Items[itemNumber];
if (g_Level.Items[itemNumber].TriggerFlags == 1 &&
keyHoleItem->ObjectNumber == ID_KEY_HOLE8)
{
2022-02-24 14:22:30 +11:00
if (keyHoleItem->ItemFlags[3])
{
2022-02-24 14:22:30 +11:00
keyHoleItem->ItemFlags[3]--;
if (!keyHoleItem->ItemFlags[3])
keyHoleItem->MeshBits = 2;
}
}
2022-02-24 14:22:30 +11:00
if (!((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM) &&
!BinocularRange &&
laraItem->Animation.ActiveState == LS_IDLE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE) &&
2022-02-24 14:22:30 +11:00
laraInfo->Control.HandStatus == HandStatus::Free &&
(!laraInfo->Control.IsMoving || laraInfo->InteractedItem != itemNumber))
{
2022-02-24 14:22:30 +11:00
if (keyHoleItem->ObjectNumber < ID_KEY_HOLE6)
ObjectCollision(itemNumber, laraItem, coll);
}
else
{
2022-02-24 14:22:30 +11:00
if (TestLaraPosition(&KeyHoleBounds, keyHoleItem, laraItem))
{
2022-02-24 14:22:30 +11:00
if (!laraInfo->Control.IsMoving) //TROYE INVENTORY FIX ME
{
2022-02-24 14:22:30 +11:00
if (keyHoleItem->Status != ITEM_NOT_ACTIVE)
return;
2021-11-16 15:51:50 +03:00
if (g_Gui.GetInventoryItemChosen() == NO_ITEM)
{
2022-02-24 14:22:30 +11:00
if (g_Gui.IsObjectInInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1)))
g_Gui.SetEnterInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1));
2021-10-12 04:15:22 -05:00
return;
}
2022-02-24 14:22:30 +11:00
if (g_Gui.GetInventoryItemChosen() != keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1))
return;
}
2022-02-24 14:22:30 +11:00
if (MoveLaraPosition(&KeyHolePosition, keyHoleItem, laraItem))
{
2022-02-24 14:22:30 +11:00
if (keyHoleItem->ObjectNumber == ID_KEY_HOLE8)
laraItem->Animation.AnimNumber = LA_KEYCARD_USE;
else
{
2022-02-24 14:22:30 +11:00
RemoveObjectFromInventory(static_cast<GAME_OBJECT_ID>(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1)), 1);
laraItem->Animation.AnimNumber = LA_USE_KEY;
}
2022-02-24 14:22:30 +11:00
laraItem->Animation.ActiveState = LS_INSERT_KEY;
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
2022-02-24 14:22:30 +11:00
laraInfo->Control.IsMoving = false;
ResetLaraFlex(laraItem);
laraInfo->Control.HandStatus = HandStatus::Busy;
keyHoleItem->Flags |= 0x20;
keyHoleItem->Status = ITEM_ACTIVE;
if (keyHoleItem->TriggerFlags == 1 && keyHoleItem->ObjectNumber == ID_KEY_HOLE8)
{
2022-02-24 14:22:30 +11:00
keyHoleItem->ItemFlags[3] = 92;
2021-11-16 15:51:50 +03:00
g_Gui.SetInventoryItemChosen(NO_ITEM);
return;
}
}
else
laraInfo->InteractedItem = itemNumber;
2021-11-16 15:51:50 +03:00
g_Gui.SetInventoryItemChosen(NO_ITEM);
return;
}
if (laraInfo->Control.IsMoving && laraInfo->InteractedItem == itemNumber)
{
2022-02-24 14:22:30 +11:00
laraInfo->Control.IsMoving = false;
laraInfo->Control.HandStatus = HandStatus::Free;
}
}
return;
2022-02-24 14:22:30 +11:00
}