TombEngine/TR5Main/Objects/Generic/Traps/traps.cpp

299 lines
8.6 KiB
C++
Raw Normal View History

#include "framework.h"
2019-12-01 08:13:19 +01:00
#include "traps.h"
2021-12-22 16:23:57 +03:00
#include "Game/items.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/weather.h"
#include "Game/Lara/lara.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/sphere.h"
#include "Game/camera.h"
#include "tr5_light.h"
2021-12-22 16:23:57 +03:00
#include "Game/animation.h"
#include "Specific/level.h"
#include "Specific/input.h"
#include "Game/room.h"
2021-09-15 17:40:00 +03:00
#include "Sound/sound.h"
using namespace TEN::Effects::Environment;
static short WreckingBallData[2] = {0, 0};
2020-04-24 19:15:05 +02:00
void InitialiseWreckingBall(short itemNumber)
{
ITEM_INFO* item;
short room;
item = &g_Level.Items[itemNumber];
item->ItemFlags[3] = FindAllItems(ID_ANIMATING16)[0];
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
item->Pose.Position.y = GetCeiling(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z) + 1644;
GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room);
if (room != item->RoomNumber)
ItemNewRoom(itemNumber, room);
}
void WreckingBallCollision(short itemNumber, ITEM_INFO* l, CollisionInfo* coll)
{
ITEM_INFO* item;
int x, y, z, test;
short damage;
item = &g_Level.Items[itemNumber];
2021-09-10 00:20:59 +03:00
if (TestBoundsCollide(item, l, coll->Setup.Radius))
{
2022-03-31 23:55:54 +11:00
x = l->Pose.Position.x;
y = l->Pose.Position.y;
z = l->Pose.Position.z;
test = (x & 1023) > 256 && (x & 1023) < 768 && (z & 1023) > 256 && (z & 1023) < 768;
damage = item->Animation.VerticalVelocity > 0 ? 96 : 0;
if (ItemPushItem(item, l, coll, coll->Setup.EnableSpasm, 1))
{
if (test)
l->HitPoints = 0;
else
l->HitPoints -= damage;
2022-03-31 23:55:54 +11:00
x -= l->Pose.Position.x;
y -= l->Pose.Position.y;
z -= l->Pose.Position.z;
if (damage)
{
for (int i = 14 + (GetRandomControl() & 3); i > 0; --i)
{
2022-03-31 23:55:54 +11:00
TriggerBlood(l->Pose.Position.x + (GetRandomControl() & 63) - 32, l->Pose.Position.y - (GetRandomControl() & 511) - 256,
l->Pose.Position.z + (GetRandomControl() & 63) - 32, -1, 1);
}
}
2021-09-10 00:20:59 +03:00
if (!coll->Setup.EnableObjectPush || test)
{
2022-03-31 23:55:54 +11:00
l->Pose.Position.x += x;
l->Pose.Position.y += y;
l->Pose.Position.z += z;
}
}
}
}
void WreckingBallControl(short itemNumber)
{
ITEM_INFO* item, *item2;
int test, x, z, oldX, oldZ, wx, wz, flagX, flagZ, height, dx, dz, ceilingX, ceilingZ, adx, adz;
short room;
item = &g_Level.Items[itemNumber];
test = 1;
item2 = &g_Level.Items[item->ItemFlags[3]];
2022-03-31 23:55:54 +11:00
if (LaraItem->Pose.Position.x >= 45056 && LaraItem->Pose.Position.x <= 57344 && LaraItem->Pose.Position.z >= 26624 && LaraItem->Pose.Position.z <= 43008
|| item->ItemFlags[2] < 900)
{
if (item->ItemFlags[2] < 900)
{
if (!item->ItemFlags[2] || !(GlobalCounter & 0x3F))
{
WreckingBallData[0] = GetRandomControl() % 7 - 3;
WreckingBallData[1] = GetRandomControl() % 7 - 3;
}
x = (WreckingBallData[0] << 10) + 51712;
z = (WreckingBallData[1] << 10) + 34304;
test = 0;
}
else
{
2022-03-31 23:55:54 +11:00
x = LaraItem->Pose.Position.x;
z = LaraItem->Pose.Position.z;
}
}
else
{
x = 51200;
z = 33792;
test = 0;
}
if (item->ItemFlags[2] < 900)
++item->ItemFlags[2];
if (item->ItemFlags[1] <= 0)
{
2022-03-31 23:55:54 +11:00
oldX = item->Pose.Position.x;
oldZ = item->Pose.Position.z;
x = x & 0xFFFFFE00 | 0x200;
z = z & 0xFFFFFE00 | 0x200;
2022-03-31 23:55:54 +11:00
dx = x - item->Pose.Position.x;
dz = z - item->Pose.Position.z;
wx = 0;
if (dx < 0)
wx = -1024;
else if (dx > 0)
wx = 1024;
wz = 0;
if (dz < 0)
wz = -1024;
else if (dz > 0)
wz = 1024;
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
ceilingX = GetCeiling(GetFloor(item->Pose.Position.x + wx, item2->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x + wx, item2->Pose.Position.y, item->Pose.Position.z);
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
ceilingZ = GetCeiling(GetFloor(item->Pose.Position.x, item2->Pose.Position.y, item->Pose.Position.z + wz, &room), item->Pose.Position.x, item2->Pose.Position.y, item->Pose.Position.z + wz);
if (ceilingX <= item2->Pose.Position.y && ceilingX != NO_HEIGHT)
flagX = 1;
else
flagX = 0;
2022-03-31 23:55:54 +11:00
if (ceilingZ <= item2->Pose.Position.y && ceilingZ != NO_HEIGHT)
flagZ = 1;
else
flagZ = 0;
if (!item->ItemFlags[0])
{
if (flagX && dx && (abs(dx) > abs(dz) || !flagZ || GetRandomControl() & 1))
{
item->ItemFlags[0] = 1;
}
else if (flagZ && dz)
{
item->ItemFlags[0] = 2;
}
}
if (item->ItemFlags[0] == 1)
{
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Pose, 0);
adx = abs(dx);
if (adx >= 32)
adx = 32;
if (dx > 0)
{
2022-03-31 23:55:54 +11:00
item->Pose.Position.x += adx;
}
else if (dx < 0)
{
2022-03-31 23:55:54 +11:00
item->Pose.Position.x -= adx;
}
else
{
item->ItemFlags[0] = 0;
}
}
if (item->ItemFlags[0] == 2)
{
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Pose, 0);
adz = abs(dz);
if (adz >= 32)
adz = 32;
if (dz > 0)
{
2022-03-31 23:55:54 +11:00
item->Pose.Position.z += adz;
}
else if (dz < 0)
{
2022-03-31 23:55:54 +11:00
item->Pose.Position.z -= adz;
}
else
{
item->ItemFlags[0] = 0;
}
}
2022-03-31 23:55:54 +11:00
if (item->ItemFlags[1] == -1 && (oldX != item->Pose.Position.x || oldZ != item->Pose.Position.z))
{
item->ItemFlags[1] = 0;
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_A, &item->Pose, 0);
}
2022-03-31 23:55:54 +11:00
if ((item->Pose.Position.x & 0x3FF) == 512 && (item->Pose.Position.z & 0x3FF) == 512)
item->ItemFlags[0] = 0;
2022-03-31 23:55:54 +11:00
if (x == item->Pose.Position.x && z == item->Pose.Position.z && test)
{
if (item->ItemFlags[1] != -1)
{
StopSoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP);
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_C, &item->Pose, 0);
}
item->ItemFlags[1] = 1;
item->TriggerFlags = 30;
}
}
else if (item->ItemFlags[1] == 1)
{
if (!item->TriggerFlags)
{
--item->TriggerFlags;
}
else if (!item->Animation.ActiveState)
{
item->Animation.TargetState = 1;
}
else if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd)
{
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_DROP, &item->Pose, 0);
++item->ItemFlags[1];
item->Animation.VerticalVelocity = 6;
2022-03-31 23:55:54 +11:00
item->Pose.Position.y += item->Animation.VerticalVelocity;
}
}
else if (item->ItemFlags[1] == 2)
{
item->Animation.VerticalVelocity += 24;
2022-03-31 23:55:54 +11:00
item->Pose.Position.y += item->Animation.VerticalVelocity;
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
height = GetFloorHeight(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
if (height < item->Pose.Position.y)
{
2022-03-31 23:55:54 +11:00
item->Pose.Position.y = height;
if (item->Animation.VerticalVelocity > 48)
{
BounceCamera(item, 64, 8192);
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
}
else
{
++item->ItemFlags[1];
item->Animation.VerticalVelocity = 0;
}
}
2022-03-31 23:55:54 +11:00
else if (height - item->Pose.Position.y < 1536 && item->Animation.ActiveState)
{
item->Animation.TargetState = 0;
}
}
else if (item->ItemFlags[1] == 3)
{
item->Animation.VerticalVelocity -= 3;
2022-03-31 23:55:54 +11:00
item->Pose.Position.y += item->Animation.VerticalVelocity;
if (item->Pose.Position.y < item2->Pose.Position.y + 1644)
{
2022-03-31 00:24:22 +11:00
StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP);
item->ItemFlags[0] = 1;
2022-03-31 23:55:54 +11:00
item->Pose.Position.y = item2->Pose.Position.y + 1644;
if (item->Animation.VerticalVelocity < -32)
{
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_TOP_IMPACT, &item->Pose, 4104);
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
BounceCamera(item, 16, 8192);
}
else
{
item->ItemFlags[1] = -1;
item->Animation.VerticalVelocity = 0;
item->ItemFlags[0] = 0;
}
}
else if (!item->ItemFlags[0])
{
2022-03-31 23:55:54 +11:00
SoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP, &item->Pose, 0);
}
}
2022-03-31 23:55:54 +11:00
item2->Pose.Position.x = item->Pose.Position.x;
item2->Pose.Position.z = item->Pose.Position.z;
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
item2->Pose.Position.y = GetCeiling(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
GetFloor(item2->Pose.Position.x, item2->Pose.Position.y, item2->Pose.Position.z, &room);
if (room != item2->RoomNumber)
ItemNewRoom(item->ItemFlags[3], room);
2022-03-31 23:55:54 +11:00
TriggerAlertLight(item2->Pose.Position.x, item2->Pose.Position.y + 64, item2->Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter & 0x3F), item2->RoomNumber, 24);
TriggerAlertLight(item2->Pose.Position.x, item2->Pose.Position.y + 64, item2->Pose.Position.z, 255, 64, 0, 64 * (GlobalCounter - 32) & 0xFFF, item2->RoomNumber, 24);
room = item->RoomNumber;
2022-03-31 23:55:54 +11:00
GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room);
if (room != item->RoomNumber)
ItemNewRoom(itemNumber, room);
AnimateItem(item);
}