2021-08-30 17:50:32 +03:00
|
|
|
#include "framework.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Game/control/trigger.h"
|
|
|
|
|
|
|
|
#include "Game/camera.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/collision/floordata.h"
|
|
|
|
#include "Game/control/flipeffect.h"
|
|
|
|
#include "Game/control/box.h"
|
|
|
|
#include "Game/control/lot.h"
|
2023-01-03 15:37:12 +02:00
|
|
|
#include "Game/control/volume.h"
|
2022-11-22 19:16:35 +02:00
|
|
|
#include "Game/effects/item_fx.h"
|
2023-02-04 11:44:13 +01:00
|
|
|
#include "Game/items.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/Lara/lara.h"
|
|
|
|
#include "Game/Lara/lara_climb.h"
|
2022-06-23 16:08:43 +03:00
|
|
|
#include "Game/Lara/lara_helpers.h"
|
2022-02-02 23:11:57 +11:00
|
|
|
#include "Game/Lara/lara_tests.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Game/room.h"
|
2022-05-24 04:43:36 +03:00
|
|
|
#include "Game/savegame.h"
|
2023-02-04 11:44:13 +01:00
|
|
|
#include "Game/spotcam.h"
|
2021-09-25 16:00:30 +03:00
|
|
|
#include "Objects/Generic/Switches/generic_switch.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Objects/objectslist.h"
|
2023-02-04 11:44:13 +01:00
|
|
|
#include "Objects/TR3/Vehicles/kayak.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Sound/sound.h"
|
2022-12-12 20:08:28 +11:00
|
|
|
#include "Specific/clock.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Specific/setup.h"
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-11-22 19:16:35 +02:00
|
|
|
using namespace TEN::Effects::Items;
|
2021-08-30 17:50:32 +03:00
|
|
|
using namespace TEN::Entities::Switches;
|
|
|
|
|
2021-09-15 21:09:09 +03:00
|
|
|
int TriggerTimer;
|
2021-09-15 17:40:00 +03:00
|
|
|
int KeyTriggerActive;
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
int TriggerActive(ItemInfo* item)
|
2021-08-30 17:52:38 +03:00
|
|
|
{
|
2022-12-13 14:00:36 +11:00
|
|
|
int flag = (~item->Flags & IFLAG_REVERSE) >> 14;
|
2022-02-09 16:55:46 +11:00
|
|
|
if ((item->Flags & IFLAG_ACTIVATION_MASK) != IFLAG_ACTIVATION_MASK)
|
2022-12-13 14:00:36 +11:00
|
|
|
{
|
2021-08-30 17:52:38 +03:00
|
|
|
flag = !flag;
|
2022-12-13 14:00:36 +11:00
|
|
|
}
|
2021-08-30 17:52:38 +03:00
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->Timer)
|
2021-08-30 17:52:38 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->Timer > 0)
|
2021-08-30 17:52:38 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
--item->Timer;
|
|
|
|
if (!item->Timer)
|
|
|
|
item->Timer = -1;
|
2021-08-30 17:52:38 +03:00
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (item->Timer < -1)
|
2021-08-30 17:52:38 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
++item->Timer;
|
|
|
|
if (item->Timer == -1)
|
|
|
|
item->Timer = 0;
|
2021-08-30 17:52:38 +03:00
|
|
|
}
|
2022-03-05 15:20:20 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->Timer <= -1)
|
2021-08-30 17:52:38 +03:00
|
|
|
flag = !flag;
|
|
|
|
}
|
|
|
|
}
|
2022-09-06 20:05:06 +10:00
|
|
|
|
2021-08-30 17:52:38 +03:00
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
bool GetKeyTrigger(ItemInfo* item)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
|
|
|
auto triggerIndex = GetTriggerIndex(item);
|
|
|
|
|
2021-09-15 10:12:42 +03:00
|
|
|
if (triggerIndex == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
short* trigger = triggerIndex;
|
|
|
|
|
|
|
|
if (*trigger & END_BIT)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (short* j = &trigger[2]; (*j >> 8) & 0x3C || item != &g_Level.Items[*j & VALUE_BITS]; j++)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2021-09-15 10:12:42 +03:00
|
|
|
if (*j & END_BIT)
|
|
|
|
return false;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2021-09-15 10:12:42 +03:00
|
|
|
return true;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
int GetSwitchTrigger(ItemInfo* item, short* itemNos, int attatchedToSwitch)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
|
|
|
auto triggerIndex = GetTriggerIndex(item);
|
|
|
|
|
2021-09-15 10:12:42 +03:00
|
|
|
if (triggerIndex == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
short* trigger = triggerIndex;
|
|
|
|
|
|
|
|
if (*trigger & END_BIT)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
trigger += 2;
|
|
|
|
short* current = itemNos;
|
|
|
|
int k = 0;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2021-09-15 10:12:42 +03:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (TRIG_BITS(*trigger) == TO_OBJECT && item != &g_Level.Items[*trigger & VALUE_BITS])
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2021-09-15 10:12:42 +03:00
|
|
|
current[k] = *trigger & VALUE_BITS;
|
|
|
|
++k;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
2021-09-15 10:12:42 +03:00
|
|
|
|
|
|
|
if (*trigger & END_BIT)
|
|
|
|
break;
|
|
|
|
|
|
|
|
++trigger;
|
|
|
|
|
|
|
|
} while (true);
|
|
|
|
|
|
|
|
return k;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-03-05 15:20:20 +11:00
|
|
|
int SwitchTrigger(short itemNumber, short timer)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2023-02-04 11:44:13 +01:00
|
|
|
auto& item = g_Level.Items[itemNumber];
|
2022-03-05 15:20:20 +11:00
|
|
|
|
2023-02-04 11:44:13 +01:00
|
|
|
if (item.Status == ITEM_DEACTIVATED)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2023-02-04 11:44:13 +01:00
|
|
|
if ((!item.Animation.ActiveState && item.ObjectNumber != ID_JUMP_SWITCH || item.Animation.ActiveState == 1 && item.ObjectNumber == ID_JUMP_SWITCH) &&
|
|
|
|
timer > 0)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2023-02-04 11:44:13 +01:00
|
|
|
item.Timer = timer;
|
|
|
|
item.Status = ITEM_ACTIVE;
|
|
|
|
|
2021-08-30 17:50:32 +03:00
|
|
|
if (timer != 1)
|
2023-02-04 11:44:13 +01:00
|
|
|
item.Timer = FPS * timer;
|
|
|
|
|
2021-08-30 17:50:32 +03:00
|
|
|
return 1;
|
|
|
|
}
|
2023-02-04 11:44:13 +01:00
|
|
|
|
2023-02-04 11:49:05 +01:00
|
|
|
if (item.TriggerFlags >= 0 || item.Animation.ActiveState)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-03-05 15:20:20 +11:00
|
|
|
RemoveActiveItem(itemNumber);
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2023-02-04 11:49:05 +01:00
|
|
|
item.Status = ITEM_NOT_ACTIVE;
|
|
|
|
if (!item.ItemFlags[0] == 0)
|
|
|
|
item.Flags |= ONESHOT;
|
2023-02-04 11:34:10 +01:00
|
|
|
return 1;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-02-04 11:44:13 +01:00
|
|
|
item.Status = ITEM_ACTIVE;
|
2021-08-30 17:50:32 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2023-02-04 11:44:13 +01:00
|
|
|
else if (item.Status)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2023-02-04 11:44:13 +01:00
|
|
|
if (item.ObjectNumber == ID_AIRLOCK_SWITCH &&
|
2023-04-13 15:09:31 +10:00
|
|
|
item.Animation.AnimNumber == GetAnimIndex(item, 2) &&
|
|
|
|
item.Animation.FrameNumber == GetFrameIndex(&item, 0))
|
2023-02-04 11:44:13 +01:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ((item.Flags & ONESHOT) >> 8);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-15 17:20:42 +03:00
|
|
|
int KeyTrigger(short itemNum)
|
|
|
|
{
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* item = &g_Level.Items[itemNum];
|
2021-09-15 17:20:42 +03:00
|
|
|
int oldkey;
|
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if ((item->Status != ITEM_ACTIVE || Lara.Control.HandStatus == HandStatus::Busy) && (!KeyTriggerActive || Lara.Control.HandStatus != HandStatus::Busy))
|
2021-09-15 17:20:42 +03:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
oldkey = KeyTriggerActive;
|
|
|
|
|
|
|
|
if (!oldkey)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Status = ITEM_DEACTIVATED;
|
2021-09-15 17:20:42 +03:00
|
|
|
|
|
|
|
KeyTriggerActive = false;
|
|
|
|
|
|
|
|
return oldkey;
|
|
|
|
}
|
|
|
|
|
2022-11-20 05:29:08 +02:00
|
|
|
bool PickupTrigger(short itemNum)
|
2021-09-15 17:20:42 +03:00
|
|
|
{
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* item = &g_Level.Items[itemNum];
|
2021-09-15 17:20:42 +03:00
|
|
|
|
2022-11-20 05:29:08 +02:00
|
|
|
if (((item->Flags & IFLAG_CLEAR_BODY) && (item->Flags & IFLAG_KILLED)) ||
|
|
|
|
item->Status != ITEM_INVISIBLE ||
|
|
|
|
item->ItemFlags[3] != 1 ||
|
|
|
|
item->TriggerFlags & 0x80)
|
2021-09-15 17:20:42 +03:00
|
|
|
{
|
2022-11-20 05:29:08 +02:00
|
|
|
return false;
|
2021-09-15 17:20:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
KillItem(itemNum);
|
2022-11-20 05:29:08 +02:00
|
|
|
item->Flags |= IFLAG_CLEAR_BODY;
|
2021-09-15 17:20:42 +03:00
|
|
|
|
2022-11-20 05:29:08 +02:00
|
|
|
return true;
|
2021-09-15 17:20:42 +03:00
|
|
|
}
|
|
|
|
|
2021-10-04 03:14:05 +03:00
|
|
|
void RefreshCamera(short type, short* data)
|
|
|
|
{
|
|
|
|
short trigger, value, targetOk;
|
|
|
|
|
|
|
|
targetOk = 2;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
trigger = *(data++);
|
|
|
|
value = trigger & VALUE_BITS;
|
|
|
|
|
|
|
|
switch (TRIG_BITS(trigger))
|
|
|
|
{
|
|
|
|
case TO_CAMERA:
|
|
|
|
data++;
|
|
|
|
|
|
|
|
if (value == Camera.last)
|
|
|
|
{
|
|
|
|
Camera.number = value;
|
|
|
|
|
2022-02-16 18:13:07 +11:00
|
|
|
if ((Camera.timer < 0) || (Camera.type == CameraType::Look) || (Camera.type == CameraType::Combat))
|
2021-10-04 03:14:05 +03:00
|
|
|
{
|
|
|
|
Camera.timer = -1;
|
|
|
|
targetOk = 0;
|
|
|
|
break;
|
|
|
|
}
|
2022-02-16 18:13:07 +11:00
|
|
|
Camera.type = CameraType::Fixed;
|
2021-10-04 03:14:05 +03:00
|
|
|
targetOk = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
targetOk = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_TARGET:
|
2022-02-16 18:13:07 +11:00
|
|
|
if (Camera.type == CameraType::Look || Camera.type == CameraType::Combat)
|
2021-10-04 03:14:05 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
Camera.item = &g_Level.Items[value];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (!(trigger & END_BIT));
|
|
|
|
|
|
|
|
if (Camera.item)
|
2022-02-09 16:55:46 +11:00
|
|
|
if (!targetOk || (targetOk == 2 && Camera.item->LookedAt && Camera.item != Camera.lastItem))
|
2021-10-04 03:14:05 +03:00
|
|
|
Camera.item = NULL;
|
|
|
|
|
|
|
|
if (Camera.number == -1 && Camera.timer > 0)
|
|
|
|
Camera.timer = -1;
|
|
|
|
}
|
|
|
|
|
2022-05-05 07:12:26 +02:00
|
|
|
short* GetTriggerIndex(FloorInfo* floor, int x, int y, int z)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-03-14 01:20:51 +11:00
|
|
|
auto bottomBlock = GetCollision(x, y, z, floor->Room).BottomBlock;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2021-09-17 15:32:55 +03:00
|
|
|
if (bottomBlock->TriggerIndex == -1)
|
|
|
|
return nullptr;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2021-09-17 15:32:55 +03:00
|
|
|
return &g_Level.FloorData[bottomBlock->TriggerIndex];
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
short* GetTriggerIndex(ItemInfo* item)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
auto roomNumber = item->RoomNumber;
|
2022-03-31 23:55:54 +11:00
|
|
|
auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
|
|
|
|
return GetTriggerIndex(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2022-12-30 15:58:52 +00:00
|
|
|
void Antitrigger(short const value, short const flags)
|
|
|
|
{
|
|
|
|
ItemInfo* item = &g_Level.Items[value];
|
|
|
|
if (item->ObjectNumber == ID_EARTHQUAKE)
|
|
|
|
{
|
|
|
|
item->ItemFlags[0] = 0;
|
|
|
|
item->ItemFlags[1] = 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->Flags &= ~(CODE_BITS | REVERSE);
|
|
|
|
|
|
|
|
if (flags & ONESHOT)
|
|
|
|
item->Flags |= ATONESHOT;
|
|
|
|
|
|
|
|
if (item->Active && Objects[item->ObjectNumber].intelligent)
|
|
|
|
{
|
|
|
|
DisableEntityAI(value);
|
2023-01-02 19:24:37 +00:00
|
|
|
RemoveActiveItem(value, false);
|
2022-12-30 15:58:52 +00:00
|
|
|
item->Active = false;
|
|
|
|
item->Status = ITEM_INVISIBLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Trigger(short const value, short const flags)
|
|
|
|
{
|
|
|
|
ItemInfo* item = &g_Level.Items[value];
|
|
|
|
item->Flags |= TRIGGERED;
|
|
|
|
|
|
|
|
if (flags & ONESHOT)
|
|
|
|
item->Flags |= ONESHOT;
|
|
|
|
|
|
|
|
if (!(item->Active) && !(item->Flags & IFLAG_KILLED))
|
|
|
|
{
|
|
|
|
if (Objects[item->ObjectNumber].intelligent)
|
|
|
|
{
|
|
|
|
if (item->Status != ITEM_NOT_ACTIVE)
|
|
|
|
{
|
|
|
|
if (item->Status == ITEM_INVISIBLE)
|
|
|
|
{
|
|
|
|
item->TouchBits = NO_JOINT_BITS;
|
2023-01-12 19:26:07 +02:00
|
|
|
if (EnableEntityAI(value, false))
|
2022-12-30 15:58:52 +00:00
|
|
|
{
|
|
|
|
item->Status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->Status = ITEM_INVISIBLE;
|
|
|
|
AddActiveItem(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->TouchBits = NO_JOINT_BITS;
|
|
|
|
item->Status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(value);
|
2023-01-12 19:26:07 +02:00
|
|
|
EnableEntityAI(value, true);
|
2022-12-30 15:58:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->TouchBits = NO_JOINT_BITS;
|
|
|
|
AddActiveItem(value);
|
|
|
|
item->Status = ITEM_ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-28 02:23:25 +02:00
|
|
|
void TestTriggers(int x, int y, int z, FloorInfo* floor, VolumeActivator activator, bool heavy, int heavyFlags)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
|
|
|
int flip = -1;
|
|
|
|
int flipAvailable = 0;
|
|
|
|
int newEffect = -1;
|
|
|
|
int switchOff = 0;
|
2023-02-04 11:34:10 +01:00
|
|
|
//int switchFlag = 0;
|
2021-08-30 17:50:32 +03:00
|
|
|
short objectNumber = 0;
|
|
|
|
int keyResult = 0;
|
|
|
|
short cameraFlags = 0;
|
|
|
|
short cameraTimer = 0;
|
|
|
|
int spotCamIndex = 0;
|
|
|
|
|
2021-10-01 18:31:06 +03:00
|
|
|
auto data = GetTriggerIndex(floor, x, y, z);
|
|
|
|
|
2021-08-30 17:50:32 +03:00
|
|
|
if (!data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
short triggerType = (*(data++) >> 8) & 0x3F;
|
|
|
|
short flags = *(data++);
|
2023-01-03 15:37:12 +02:00
|
|
|
short timer = flags & TIMER_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-02-16 18:13:07 +11:00
|
|
|
if (Camera.type != CameraType::Heavy)
|
2021-08-30 17:50:32 +03:00
|
|
|
RefreshCamera(triggerType, data);
|
|
|
|
|
|
|
|
short value = 0;
|
|
|
|
|
|
|
|
if (heavy)
|
|
|
|
{
|
|
|
|
switch (triggerType)
|
|
|
|
{
|
|
|
|
case TRIGGER_TYPES::HEAVY:
|
|
|
|
case TRIGGER_TYPES::HEAVYANTITRIGGER:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::HEAVYSWITCH:
|
|
|
|
if (!heavyFlags)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (heavyFlags >= 0)
|
|
|
|
{
|
|
|
|
flags &= CODE_BITS;
|
|
|
|
if (flags != heavyFlags)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
flags |= CODE_BITS;
|
|
|
|
flags += heavyFlags;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Enemies can only activate heavy triggers
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (triggerType)
|
|
|
|
{
|
|
|
|
case TRIGGER_TYPES::SWITCH:
|
2023-01-03 15:37:12 +02:00
|
|
|
value = *(data++) & VALUE_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
if (flags & ONESHOT)
|
2022-02-09 16:55:46 +11:00
|
|
|
g_Level.Items[value].ItemFlags[0] = 1;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
if (!SwitchTrigger(value, timer))
|
|
|
|
return;
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
objectNumber = g_Level.Items[value].ObjectNumber;
|
2023-02-04 11:34:10 +01:00
|
|
|
//This disables the antitrigger of the Valve switch (ocb 5). I don't know the purpose of this in TR4.
|
|
|
|
//if (objectNumber >= ID_SWITCH_TYPE1 && objectNumber <= ID_SWITCH_TYPE6 && g_Level.Items[value].TriggerFlags == 5)
|
|
|
|
//switchFlag = 1;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-03-13 02:04:24 +11:00
|
|
|
switchOff = (g_Level.Items[value].Animation.ActiveState == 1);
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::MONKEY:
|
2022-03-13 02:04:24 +11:00
|
|
|
if (LaraItem->Animation.ActiveState >= LS_MONKEY_IDLE &&
|
|
|
|
(LaraItem->Animation.ActiveState <= LS_MONKEY_TURN_180 ||
|
2023-01-03 15:37:12 +02:00
|
|
|
LaraItem->Animation.ActiveState == LS_MONKEY_TURN_LEFT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_MONKEY_TURN_RIGHT))
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::TIGHTROPE_T:
|
2022-03-13 02:04:24 +11:00
|
|
|
if (LaraItem->Animation.ActiveState >= LS_TIGHTROPE_IDLE &&
|
|
|
|
LaraItem->Animation.ActiveState <= LS_TIGHTROPE_RECOVER_BALANCE &&
|
|
|
|
LaraItem->Animation.ActiveState != LS_DOVE_SWITCH)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::CRAWLDUCK_T:
|
2022-03-13 02:04:24 +11:00
|
|
|
if (LaraItem->Animation.ActiveState == LS_DOVE_SWITCH ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CRAWL_IDLE ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CRAWL_TURN_LEFT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CRAWL_TURN_RIGHT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CRAWL_BACK ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CROUCH_IDLE ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CROUCH_ROLL ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CROUCH_TURN_LEFT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_CROUCH_TURN_RIGHT)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::CLIMB_T:
|
2022-11-04 13:10:13 +01:00
|
|
|
if (LaraItem->Animation.ActiveState == LS_HANG ||
|
2022-03-13 02:04:24 +11:00
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_IDLE ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_UP ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_LEFT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_STOP ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_RIGHT ||
|
|
|
|
LaraItem->Animation.ActiveState == LS_LADDER_DOWN)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::PAD:
|
|
|
|
case TRIGGER_TYPES::ANTIPAD:
|
2022-03-14 01:20:51 +11:00
|
|
|
if (GetCollision(floor, x, y, z).Position.Floor == y)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::KEY:
|
2023-01-03 15:37:12 +02:00
|
|
|
value = *(data++) & VALUE_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
keyResult = KeyTrigger(value);
|
|
|
|
if (keyResult != -1)
|
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::PICKUP:
|
2023-01-03 15:37:12 +02:00
|
|
|
value = *(data++) & VALUE_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
if (!PickupTrigger(value))
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::COMBAT:
|
2022-02-11 01:31:54 +11:00
|
|
|
if (Lara.Control.HandStatus == HandStatus::WeaponReady)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case TRIGGER_TYPES::HEAVY:
|
|
|
|
case TRIGGER_TYPES::DUMMY:
|
|
|
|
case TRIGGER_TYPES::HEAVYSWITCH:
|
|
|
|
case TRIGGER_TYPES::HEAVYANTITRIGGER:
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
short targetType = 0;
|
|
|
|
short trigger = 0;
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
ItemInfo* item = NULL;
|
|
|
|
ItemInfo* cameraItem = NULL;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
trigger = *(data++);
|
|
|
|
value = trigger & VALUE_BITS;
|
2023-01-03 15:37:12 +02:00
|
|
|
targetType = (trigger >> 10) & FUNCTION_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
switch (targetType)
|
|
|
|
{
|
|
|
|
case TO_OBJECT:
|
|
|
|
item = &g_Level.Items[value];
|
|
|
|
|
|
|
|
if (keyResult >= 2 ||
|
|
|
|
(triggerType == TRIGGER_TYPES::ANTIPAD ||
|
|
|
|
triggerType == TRIGGER_TYPES::ANTITRIGGER ||
|
|
|
|
triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER) &&
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Flags & ATONESHOT)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (triggerType == TRIGGER_TYPES::SWITCH && item->Flags & SWONESHOT)
|
2021-09-24 05:48:27 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType != TRIGGER_TYPES::SWITCH
|
|
|
|
&& triggerType != TRIGGER_TYPES::ANTIPAD
|
|
|
|
&& triggerType != TRIGGER_TYPES::ANTITRIGGER
|
|
|
|
&& triggerType != TRIGGER_TYPES::HEAVYANTITRIGGER
|
2022-02-09 16:55:46 +11:00
|
|
|
&& (item->Flags & ONESHOT))
|
2021-09-24 05:48:27 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType != TRIGGER_TYPES::ANTIPAD
|
|
|
|
&& triggerType != TRIGGER_TYPES::ANTITRIGGER
|
|
|
|
&& triggerType != TRIGGER_TYPES::HEAVYANTITRIGGER)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ObjectNumber == ID_DART_EMITTER && item->Active)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Timer = timer;
|
2021-08-30 17:50:32 +03:00
|
|
|
if (timer != 1)
|
2022-06-05 03:56:08 +03:00
|
|
|
item->Timer = FPS * timer;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
if (triggerType == TRIGGER_TYPES::SWITCH ||
|
|
|
|
triggerType == TRIGGER_TYPES::HEAVYSWITCH)
|
|
|
|
{
|
|
|
|
if (heavyFlags >= 0)
|
|
|
|
{
|
2023-02-04 11:34:10 +01:00
|
|
|
//if (switchFlag)
|
|
|
|
//item->Flags |= (flags & CODE_BITS);
|
|
|
|
//else
|
|
|
|
|
|
|
|
item->Flags ^= (flags & CODE_BITS);
|
2021-08-30 17:50:32 +03:00
|
|
|
|
|
|
|
if (flags & ONESHOT)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Flags |= SWONESHOT;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (((flags ^ item->Flags) & CODE_BITS) == CODE_BITS)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Flags ^= (flags & CODE_BITS);
|
2021-08-30 17:50:32 +03:00
|
|
|
if (flags & ONESHOT)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Flags |= SWONESHOT;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (triggerType == TRIGGER_TYPES::ANTIPAD ||
|
2023-01-03 15:37:12 +02:00
|
|
|
triggerType == TRIGGER_TYPES::ANTITRIGGER ||
|
|
|
|
triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-12-30 15:58:52 +00:00
|
|
|
Antitrigger(value, flags);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
else if (flags & CODE_BITS)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Flags |= flags & CODE_BITS;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if ((item->Flags & CODE_BITS) == CODE_BITS)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-12-30 15:58:52 +00:00
|
|
|
Trigger(value, flags);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_CAMERA:
|
|
|
|
trigger = *(data++);
|
|
|
|
|
|
|
|
if (keyResult == 1)
|
|
|
|
break;
|
|
|
|
|
2022-10-01 18:58:36 +10:00
|
|
|
if (g_Level.Cameras[value].Flags & ONESHOT)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
Camera.number = value;
|
|
|
|
|
2022-10-01 18:58:36 +10:00
|
|
|
if (Camera.type == CameraType::Look || Camera.type == CameraType::Combat && !(g_Level.Cameras[value].Flags & 3))
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType == TRIGGER_TYPES::COMBAT)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType == TRIGGER_TYPES::SWITCH && timer && switchOff)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (Camera.number != Camera.last || triggerType == TRIGGER_TYPES::SWITCH)
|
|
|
|
{
|
2023-01-03 15:37:12 +02:00
|
|
|
Camera.timer = (trigger & TIMER_BITS) * FPS;
|
2022-02-16 18:13:07 +11:00
|
|
|
Camera.type = heavy ? CameraType::Heavy : CameraType::Fixed;
|
2021-08-30 17:50:32 +03:00
|
|
|
if (trigger & ONESHOT)
|
2022-10-01 18:58:36 +10:00
|
|
|
g_Level.Cameras[Camera.number].Flags |= ONESHOT;
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FLYBY:
|
|
|
|
trigger = *(data++);
|
|
|
|
|
|
|
|
if (keyResult == 1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType == TRIGGER_TYPES::ANTIPAD ||
|
|
|
|
triggerType == TRIGGER_TYPES::ANTITRIGGER ||
|
|
|
|
triggerType == TRIGGER_TYPES::HEAVYANTITRIGGER)
|
|
|
|
UseSpotCam = false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
spotCamIndex = 0;
|
|
|
|
if (SpotCamRemap[value] != 0)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < SpotCamRemap[value]; i++)
|
|
|
|
{
|
|
|
|
spotCamIndex += CameraCnt[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(SpotCam[spotCamIndex].flags & SCF_CAMERA_ONE_SHOT))
|
|
|
|
{
|
|
|
|
if (trigger & ONESHOT)
|
|
|
|
SpotCam[spotCamIndex].flags |= SCF_CAMERA_ONE_SHOT;
|
|
|
|
|
|
|
|
if (!UseSpotCam || CurrentLevel == 0)
|
|
|
|
{
|
|
|
|
UseSpotCam = true;
|
2022-01-11 15:16:24 +03:00
|
|
|
if (LastSpotCamSequence != value)
|
2021-08-30 17:50:32 +03:00
|
|
|
TrackCameraInit = false;
|
|
|
|
InitialiseSpotCam(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_TARGET:
|
|
|
|
cameraItem = &g_Level.Items[value];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_SINK:
|
2023-04-12 23:44:13 +10:00
|
|
|
Lara.Context.WaterCurrentActive = value + 1;
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FLIPMAP:
|
|
|
|
flipAvailable = true;
|
|
|
|
|
2021-09-13 03:07:58 +03:00
|
|
|
if (FlipMap[value] & ONESHOT)
|
2021-08-30 17:50:32 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (triggerType == TRIGGER_TYPES::SWITCH)
|
|
|
|
FlipMap[value] ^= (flags & CODE_BITS);
|
|
|
|
else if (flags & CODE_BITS)
|
|
|
|
FlipMap[value] |= (flags & CODE_BITS);
|
|
|
|
|
|
|
|
if ((FlipMap[value] & CODE_BITS) == CODE_BITS)
|
|
|
|
{
|
2021-09-13 03:07:58 +03:00
|
|
|
if (flags & ONESHOT)
|
|
|
|
FlipMap[value] |= ONESHOT;
|
2021-08-30 17:50:32 +03:00
|
|
|
if (!FlipStats[value])
|
|
|
|
flip = value;
|
|
|
|
}
|
|
|
|
else if (FlipStats[value])
|
|
|
|
flip = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FLIPON:
|
|
|
|
flipAvailable = true;
|
2023-01-03 15:37:12 +02:00
|
|
|
if ((FlipMap[value] & CODE_BITS) == CODE_BITS && !FlipStats[value])
|
2021-08-30 17:50:32 +03:00
|
|
|
flip = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FLIPOFF:
|
|
|
|
flipAvailable = true;
|
2023-01-03 15:37:12 +02:00
|
|
|
if ((FlipMap[value] & CODE_BITS) == CODE_BITS && FlipStats[value])
|
2021-08-30 17:50:32 +03:00
|
|
|
flip = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FLIPEFFECT:
|
|
|
|
TriggerTimer = timer;
|
|
|
|
newEffect = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_FINISH:
|
|
|
|
RequiredStartPos = false;
|
|
|
|
LevelComplete = CurrentLevel + 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_CD:
|
|
|
|
PlaySoundTrack(value, flags);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TO_CUTSCENE:
|
|
|
|
// TODO: not used for now
|
|
|
|
break;
|
|
|
|
|
2022-05-15 05:53:01 +02:00
|
|
|
case TO_SECRET:
|
|
|
|
if (!(Statistics.Level.Secrets & (1 << value)))
|
|
|
|
{
|
|
|
|
PlaySecretTrack();
|
|
|
|
Statistics.Level.Secrets |= (1 << value);
|
|
|
|
Statistics.Game.Secrets++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2023-01-03 15:37:12 +02:00
|
|
|
case TO_LUAEVENT:
|
|
|
|
trigger = *(data++);
|
|
|
|
|
|
|
|
if (g_Level.EventSets.size() > value)
|
|
|
|
{
|
|
|
|
auto& set = g_Level.EventSets[value];
|
|
|
|
|
|
|
|
auto activatorType = heavy ? (int)VolumeActivatorFlags::Flyby |
|
|
|
|
(int)VolumeActivatorFlags::Moveable |
|
|
|
|
(int)VolumeActivatorFlags::NPC : (int)VolumeActivatorFlags::Player;
|
|
|
|
|
|
|
|
switch (trigger & TIMER_BITS)
|
|
|
|
{
|
|
|
|
case 0:
|
2023-01-28 02:23:25 +02:00
|
|
|
HandleEvent(set.OnEnter, activator);
|
2023-01-03 15:37:12 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2023-01-28 02:23:25 +02:00
|
|
|
HandleEvent(set.OnInside, activator);
|
2023-01-03 15:37:12 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2023-01-28 02:23:25 +02:00
|
|
|
HandleEvent(set.OnLeave, activator);
|
2023-01-03 15:37:12 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2021-08-30 17:50:32 +03:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
} while (!(trigger & END_BIT));
|
|
|
|
|
2022-02-16 18:13:07 +11:00
|
|
|
if (cameraItem && (Camera.type == CameraType::Fixed || Camera.type == CameraType::Heavy))
|
2021-08-30 17:50:32 +03:00
|
|
|
Camera.item = cameraItem;
|
|
|
|
|
|
|
|
if (flip != -1)
|
|
|
|
DoFlipMap(flip);
|
|
|
|
|
|
|
|
if (newEffect != -1 && (flip || !flipAvailable))
|
|
|
|
FlipEffect = newEffect;
|
|
|
|
}
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
void TestTriggers(ItemInfo* item, bool heavy, int heavyFlags)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2023-01-28 02:23:25 +02:00
|
|
|
auto roomNum = item->RoomNumber;
|
|
|
|
auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNum);
|
|
|
|
|
|
|
|
TestTriggers(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, floor, item->Index, heavy, heavyFlags);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TestTriggers(int x, int y, int z, short roomNumber, bool heavy, int heavyFlags)
|
|
|
|
{
|
|
|
|
auto roomNum = roomNumber;
|
|
|
|
auto floor = GetFloor(x, y, z, &roomNum);
|
|
|
|
|
|
|
|
// Don't process legacy triggers if trigger triggerer wasn't used
|
|
|
|
if (floor->Flags.MarkTriggerer && !floor->Flags.MarkTriggererActive)
|
|
|
|
return;
|
|
|
|
|
2023-01-28 02:23:25 +02:00
|
|
|
TestTriggers(x, y, z, floor, nullptr, heavy, heavyFlags);
|
2021-08-30 17:50:32 +03:00
|
|
|
}
|
|
|
|
|
2022-05-05 07:08:14 +02:00
|
|
|
void ProcessSectorFlags(ItemInfo* item)
|
2021-08-30 17:50:32 +03:00
|
|
|
{
|
2022-06-23 16:08:43 +03:00
|
|
|
auto block = GetCollision(item).BottomBlock;
|
|
|
|
bool isLara = item->IsLara();
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-06-23 16:08:43 +03:00
|
|
|
// Monkeyswing and climb (only for Lara)
|
|
|
|
if (isLara)
|
|
|
|
{
|
|
|
|
auto* lara = GetLaraInfo(item);
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-06-23 16:08:43 +03:00
|
|
|
// Set climb status
|
|
|
|
if (TestLaraNearClimbableWall(item, block))
|
|
|
|
lara->Control.CanClimbLadder = true;
|
|
|
|
else
|
|
|
|
lara->Control.CanClimbLadder = false;
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-06-23 16:08:43 +03:00
|
|
|
// Set monkeyswing status
|
|
|
|
lara->Control.CanMonkeySwing = block->Flags.Monkeyswing;
|
2022-02-11 01:31:54 +11:00
|
|
|
}
|
2021-08-30 17:50:32 +03:00
|
|
|
|
2022-06-23 16:08:43 +03:00
|
|
|
// Burn or drown item
|
|
|
|
if (block->Flags.Death && item->Pose.Position.y == item->Floor)
|
|
|
|
{
|
|
|
|
if (isLara)
|
|
|
|
{
|
|
|
|
if (!IsJumpState((LaraState)item->Animation.ActiveState) ||
|
|
|
|
GetLaraInfo(item)->Control.WaterStatus != WaterStatus::Dry)
|
|
|
|
{
|
|
|
|
// To allow both lava and rapids in same level, also check floor material flag.
|
2023-03-12 10:36:12 +11:00
|
|
|
if (block->Material == MaterialType::Water && Objects[ID_KAYAK_LARA_ANIMS].loaded)
|
2022-06-23 16:08:43 +03:00
|
|
|
KayakLaraRapidsDrown(item);
|
|
|
|
else
|
|
|
|
LavaBurn(item);
|
|
|
|
}
|
|
|
|
}
|
2022-06-23 16:11:37 +03:00
|
|
|
else if (Objects[item->ObjectNumber].intelligent && item->HitPoints != NOT_TARGETABLE)
|
2022-11-22 19:16:35 +02:00
|
|
|
{
|
2023-03-12 10:36:12 +11:00
|
|
|
if (block->Material == MaterialType::Water)
|
2022-11-22 19:16:35 +02:00
|
|
|
DoDamage(item, INT_MAX); // TODO: Implement correct rapids behaviour for other objects!
|
|
|
|
else
|
|
|
|
ItemBurn(item);
|
|
|
|
}
|
2022-06-23 16:08:43 +03:00
|
|
|
}
|
2022-01-19 22:45:38 +11:00
|
|
|
}
|