2020-05-27 09:21:20 +02:00
|
|
|
#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"
|
2020-09-30 12:37:06 -03:00
|
|
|
#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"
|
2019-12-20 23:02:35 -03:00
|
|
|
|
2021-09-15 12:58:07 +03:00
|
|
|
using namespace TEN::Effects::Environment;
|
|
|
|
|
2019-12-23 19:38:47 -03:00
|
|
|
static short WreckingBallData[2] = {0, 0};
|
2020-04-24 19:15:05 +02:00
|
|
|
|
2019-12-23 19:38:47 -03:00
|
|
|
void InitialiseWreckingBall(short itemNumber)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
short room;
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNumber];
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[3] = FindAllItems(ID_ANIMATING16)[0];
|
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos = GetCeiling(GetFloor(item->Position.xPos, item->Position.yPos, item->Position.zPos, &room), item->Position.xPos, item->Position.yPos, item->Position.zPos) + 1644;
|
|
|
|
GetFloor(item->Position.xPos, item->Position.yPos, item->Position.zPos, &room);
|
2022-02-09 16:55:46 +11:00
|
|
|
if (room != item->RoomNumber)
|
2019-12-23 19:38:47 -03:00
|
|
|
ItemNewRoom(itemNumber, room);
|
|
|
|
}
|
|
|
|
|
2022-03-14 01:20:51 +11:00
|
|
|
void WreckingBallCollision(short itemNumber, ITEM_INFO* l, CollisionInfo* coll)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
int x, y, z, test;
|
|
|
|
short damage;
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNumber];
|
2021-09-10 00:20:59 +03:00
|
|
|
if (TestBoundsCollide(item, l, coll->Setup.Radius))
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
x = l->Position.xPos;
|
|
|
|
y = l->Position.yPos;
|
|
|
|
z = l->Position.zPos;
|
2019-12-23 19:38:47 -03:00
|
|
|
test = (x & 1023) > 256 && (x & 1023) < 768 && (z & 1023) > 256 && (z & 1023) < 768;
|
2022-03-13 02:04:24 +11:00
|
|
|
damage = item->Animation.VerticalVelocity > 0 ? 96 : 0;
|
2022-01-30 14:43:33 +11:00
|
|
|
if (ItemPushItem(item, l, coll, coll->Setup.EnableSpasm, 1))
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
|
|
|
if (test)
|
2022-02-09 16:55:46 +11:00
|
|
|
l->HitPoints = 0;
|
2019-12-23 19:38:47 -03:00
|
|
|
else
|
2022-02-09 16:55:46 +11:00
|
|
|
l->HitPoints -= damage;
|
2022-03-31 21:17:06 +11:00
|
|
|
x -= l->Position.xPos;
|
|
|
|
y -= l->Position.yPos;
|
|
|
|
z -= l->Position.zPos;
|
2019-12-23 19:38:47 -03:00
|
|
|
if (damage)
|
|
|
|
{
|
|
|
|
for (int i = 14 + (GetRandomControl() & 3); i > 0; --i)
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
TriggerBlood(l->Position.xPos + (GetRandomControl() & 63) - 32, l->Position.yPos - (GetRandomControl() & 511) - 256,
|
|
|
|
l->Position.zPos + (GetRandomControl() & 63) - 32, -1, 1);
|
2019-12-23 19:38:47 -03:00
|
|
|
}
|
|
|
|
}
|
2021-09-10 00:20:59 +03:00
|
|
|
if (!coll->Setup.EnableObjectPush || test)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
l->Position.xPos += x;
|
|
|
|
l->Position.yPos += y;
|
|
|
|
l->Position.zPos += z;
|
2019-12-23 19:38:47 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-09 11:17:26 -03:00
|
|
|
void WreckingBallControl(short itemNumber)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2020-04-09 11:17:26 -03:00
|
|
|
ITEM_INFO* item, *item2;
|
|
|
|
int test, x, z, oldX, oldZ, wx, wz, flagX, flagZ, height, dx, dz, ceilingX, ceilingZ, adx, adz;
|
|
|
|
short room;
|
2019-12-23 19:38:47 -03:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNumber];
|
2020-04-09 11:17:26 -03:00
|
|
|
test = 1;
|
2022-02-09 16:55:46 +11:00
|
|
|
item2 = &g_Level.Items[item->ItemFlags[3]];
|
2022-03-31 21:17:06 +11:00
|
|
|
if (LaraItem->Position.xPos >= 45056 && LaraItem->Position.xPos <= 57344 && LaraItem->Position.zPos >= 26624 && LaraItem->Position.zPos <= 43008
|
2022-02-09 16:55:46 +11:00
|
|
|
|| item->ItemFlags[2] < 900)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[2] < 900)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (!item->ItemFlags[2] || !(GlobalCounter & 0x3F))
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
|
|
|
WreckingBallData[0] = GetRandomControl() % 7 - 3;
|
|
|
|
WreckingBallData[1] = GetRandomControl() % 7 - 3;
|
|
|
|
}
|
2021-08-30 15:13:18 -05:00
|
|
|
x = (WreckingBallData[0] << 10) + 51712;
|
|
|
|
z = (WreckingBallData[1] << 10) + 34304;
|
2019-12-23 19:38:47 -03:00
|
|
|
test = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
x = LaraItem->Position.xPos;
|
|
|
|
z = LaraItem->Position.zPos;
|
2019-12-23 19:38:47 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x = 51200;
|
|
|
|
z = 33792;
|
|
|
|
test = 0;
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[2] < 900)
|
|
|
|
++item->ItemFlags[2];
|
2021-08-29 23:53:58 +03:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[1] <= 0)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
oldX = item->Position.xPos;
|
|
|
|
oldZ = item->Position.zPos;
|
2020-04-09 11:17:26 -03:00
|
|
|
x = x & 0xFFFFFE00 | 0x200;
|
|
|
|
z = z & 0xFFFFFE00 | 0x200;
|
2022-03-31 21:17:06 +11:00
|
|
|
dx = x - item->Position.xPos;
|
|
|
|
dz = z - item->Position.zPos;
|
2020-04-09 11:17:26 -03:00
|
|
|
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;
|
2022-02-09 16:55:46 +11:00
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
ceilingX = GetCeiling(GetFloor(item->Position.xPos + wx, item2->Position.yPos, item->Position.zPos, &room), item->Position.xPos + wx, item2->Position.yPos, item->Position.zPos);
|
2022-02-09 16:55:46 +11:00
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
ceilingZ = GetCeiling(GetFloor(item->Position.xPos, item2->Position.yPos, item->Position.zPos + wz, &room), item->Position.xPos, item2->Position.yPos, item->Position.zPos + wz);
|
|
|
|
if (ceilingX <= item2->Position.yPos && ceilingX != NO_HEIGHT)
|
2020-04-09 11:17:26 -03:00
|
|
|
flagX = 1;
|
|
|
|
else
|
|
|
|
flagX = 0;
|
2022-03-31 21:17:06 +11:00
|
|
|
if (ceilingZ <= item2->Position.yPos && ceilingZ != NO_HEIGHT)
|
2020-04-09 11:17:26 -03:00
|
|
|
flagZ = 1;
|
|
|
|
else
|
|
|
|
flagZ = 0;
|
2022-02-09 16:55:46 +11:00
|
|
|
if (!item->ItemFlags[0])
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
|
|
|
if (flagX && dx && (abs(dx) > abs(dz) || !flagZ || GetRandomControl() & 1))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 1;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else if (flagZ && dz)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 2;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[0] == 1)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Position, 0);
|
2020-04-09 11:17:26 -03:00
|
|
|
adx = abs(dx);
|
|
|
|
if (adx >= 32)
|
|
|
|
adx = 32;
|
|
|
|
if (dx > 0)
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.xPos += adx;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else if (dx < 0)
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.xPos -= adx;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 0;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[0] == 2)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP, &item->Position, 0);
|
2020-04-09 11:17:26 -03:00
|
|
|
adz = abs(dz);
|
|
|
|
if (adz >= 32)
|
|
|
|
adz = 32;
|
|
|
|
if (dz > 0)
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.zPos += adz;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else if (dz < 0)
|
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.zPos -= adz;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 0;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-03-31 21:17:06 +11:00
|
|
|
if (item->ItemFlags[1] == -1 && (oldX != item->Position.xPos || oldZ != item->Position.zPos))
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[1] = 0;
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_A, &item->Position, 0);
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
2022-03-31 21:17:06 +11:00
|
|
|
if ((item->Position.xPos & 0x3FF) == 512 && (item->Position.zPos & 0x3FF) == 512)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 0;
|
2022-03-31 21:17:06 +11:00
|
|
|
if (x == item->Position.xPos && z == item->Position.zPos && test)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ItemFlags[1] != -1)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-02 00:17:02 +00:00
|
|
|
StopSoundEffect(SFX_TR5_BASE_CLAW_MOTOR_B_LOOP);
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_MOTOR_C, &item->Position, 0);
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[1] = 1;
|
|
|
|
item->TriggerFlags = 30;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (item->ItemFlags[1] == 1)
|
2019-12-23 19:38:47 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (!item->TriggerFlags)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
--item->TriggerFlags;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
2022-03-13 02:04:24 +11:00
|
|
|
else if (!item->Animation.ActiveState)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.TargetState = 1;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
2022-03-13 02:04:24 +11:00
|
|
|
else if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_DROP, &item->Position, 0);
|
2022-02-09 16:55:46 +11:00
|
|
|
++item->ItemFlags[1];
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity = 6;
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos += item->Animation.VerticalVelocity;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (item->ItemFlags[1] == 2)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity += 24;
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos += item->Animation.VerticalVelocity;
|
2022-02-09 16:55:46 +11:00
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
height = GetFloorHeight(GetFloor(item->Position.xPos, item->Position.yPos, item->Position.zPos, &room), item->Position.xPos, item->Position.yPos, item->Position.zPos);
|
|
|
|
if (height < item->Position.yPos)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos = height;
|
2022-03-13 02:04:24 +11:00
|
|
|
if (item->Animation.VerticalVelocity > 48)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
|
|
|
BounceCamera(item, 64, 8192);
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
++item->ItemFlags[1];
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity = 0;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-03-31 21:17:06 +11:00
|
|
|
else if (height - item->Position.yPos < 1536 && item->Animation.ActiveState)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.TargetState = 0;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
2019-12-23 19:38:47 -03:00
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (item->ItemFlags[1] == 3)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity -= 3;
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos += item->Animation.VerticalVelocity;
|
|
|
|
if (item->Position.yPos < item2->Position.yPos + 1644)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 00:24:22 +11:00
|
|
|
StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP);
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 1;
|
2022-03-31 21:17:06 +11:00
|
|
|
item->Position.yPos = item2->Position.yPos + 1644;
|
2022-03-13 02:04:24 +11:00
|
|
|
if (item->Animation.VerticalVelocity < -32)
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_TOP_IMPACT, &item->Position, 4104);
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
|
2020-04-09 11:17:26 -03:00
|
|
|
BounceCamera(item, 16, 8192);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[1] = -1;
|
2022-03-13 02:04:24 +11:00
|
|
|
item->Animation.VerticalVelocity = 0;
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ItemFlags[0] = 0;
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (!item->ItemFlags[0])
|
2020-04-09 11:17:26 -03:00
|
|
|
{
|
2022-03-31 21:17:06 +11:00
|
|
|
SoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP, &item->Position, 0);
|
2020-04-09 11:17:26 -03:00
|
|
|
}
|
|
|
|
}
|
2022-03-31 21:17:06 +11:00
|
|
|
item2->Position.xPos = item->Position.xPos;
|
|
|
|
item2->Position.zPos = item->Position.zPos;
|
2022-02-09 16:55:46 +11:00
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
item2->Position.yPos = GetCeiling(GetFloor(item->Position.xPos, item->Position.yPos, item->Position.zPos, &room), item->Position.xPos, item->Position.yPos, item->Position.zPos);
|
|
|
|
GetFloor(item2->Position.xPos, item2->Position.yPos, item2->Position.zPos, &room);
|
2022-02-09 16:55:46 +11:00
|
|
|
if (room != item2->RoomNumber)
|
|
|
|
ItemNewRoom(item->ItemFlags[3], room);
|
2022-03-31 21:17:06 +11:00
|
|
|
TriggerAlertLight(item2->Position.xPos, item2->Position.yPos + 64, item2->Position.zPos, 255, 64, 0, 64 * (GlobalCounter & 0x3F), item2->RoomNumber, 24);
|
|
|
|
TriggerAlertLight(item2->Position.xPos, item2->Position.yPos + 64, item2->Position.zPos, 255, 64, 0, 64 * (GlobalCounter - 32) & 0xFFF, item2->RoomNumber, 24);
|
2022-02-09 16:55:46 +11:00
|
|
|
room = item->RoomNumber;
|
2022-03-31 21:17:06 +11:00
|
|
|
GetFloor(item->Position.xPos, item->Position.yPos, item->Position.zPos, &room);
|
2022-02-09 16:55:46 +11:00
|
|
|
if (room != item->RoomNumber)
|
2020-04-09 11:17:26 -03:00
|
|
|
ItemNewRoom(itemNumber, room);
|
|
|
|
AnimateItem(item);
|
2019-12-23 19:38:47 -03:00
|
|
|
}
|
Decompiled ID_DARTS, ID_DART_EMITTER, ID_FALLING_CEILING, ID_PROPELLER_H, ID_PROPELLER_V, KillAllTriggersControl, InitialiseFlameEmitter, FlameEmitterCollision, InitialiseFlameEmitter2 , GenSlot1Control, InitialiseGenSlot3, InitialiseGenSlot4;
2020-01-28 07:30:58 +01:00
|
|
|
|