2020-05-27 09:21:20 +02:00
|
|
|
#include "framework.h"
|
2019-11-01 08:35:01 +01:00
|
|
|
#include "objects.h"
|
|
|
|
#include "items.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "effect.h"
|
2019-11-01 08:35:01 +01:00
|
|
|
#include "effect2.h"
|
|
|
|
#include "draw.h"
|
2019-11-21 07:43:34 +01:00
|
|
|
#include "Lara.h"
|
2019-11-01 08:35:01 +01:00
|
|
|
#include "sphere.h"
|
|
|
|
#include "debris.h"
|
|
|
|
#include "control.h"
|
2019-11-09 09:55:56 +01:00
|
|
|
#include "switch.h"
|
2020-01-16 19:14:35 +01:00
|
|
|
#include "box.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "setup.h"
|
2020-04-17 07:00:47 +02:00
|
|
|
#include "tomb4fx.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "level.h"
|
|
|
|
#include "input.h"
|
2020-04-24 19:15:05 +02:00
|
|
|
#include "sound.h"
|
2019-11-01 08:35:01 +01:00
|
|
|
|
2020-04-24 19:15:05 +02:00
|
|
|
OBJECT_TEXTURE* WaterfallTextures[6];
|
|
|
|
float WaterfallY[6];
|
2019-11-27 15:12:35 +01:00
|
|
|
int lastWaterfallY = 0;
|
2020-07-25 18:02:35 +02:00
|
|
|
OBJECT_COLLISION_BOUNDS TightRopeBounds =
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0xFF00, 0x0100, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
PHD_VECTOR TightRopePos = { 0, 0, 0 };
|
|
|
|
|
2020-07-25 18:02:35 +02:00
|
|
|
OBJECT_COLLISION_BOUNDS ParallelBarsBounds =
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
0xFD80, 0x0280, 0x02C0, 0x0340, 0xFFA0, 0x0060, 0xF8E4, 0x071C, 0xEAAC, 0x1554, 0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
|
|
|
|
PHD_VECTOR PolePos = { 0, 0, -208 };
|
|
|
|
PHD_VECTOR PolePosR = { 0, 0, 0 };
|
2020-07-25 18:02:35 +02:00
|
|
|
OBJECT_COLLISION_BOUNDS PoleBounds = // offset 0xA1250
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
0xFF00, 0x0100, 0x0000, 0x0000, 0xFE00, 0x0200, 0xF8E4, 0x071C, 0xEAAC, 0x1554,
|
|
|
|
0xF8E4, 0x071C
|
|
|
|
};
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void ControlAnimatingSlots(short itemNumber)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
// TODO: TR5 has here a series of hardcoded OCB codes, this function actually is just a placeholder
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void PoleCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2019-11-01 08:35:01 +01:00
|
|
|
|
2020-08-04 20:32:07 +10:00
|
|
|
if ((TrInput & IN_ACTION) && !Lara.gunStatus && l->currentAnimState == LS_STOP &&
|
|
|
|
l->animNumber == LA_STAND_IDLE
|
2019-11-01 08:35:01 +01:00
|
|
|
|| Lara.isMoving && Lara.generalPtr == (void*)itemNumber)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short rot = item->pos.yRot;
|
2019-11-01 08:35:01 +01:00
|
|
|
item->pos.yRot = l->pos.yRot;
|
2020-07-25 18:02:35 +02:00
|
|
|
if (TestLaraPosition(&PoleBounds, item, l))
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&PolePos, item, l))
|
|
|
|
{
|
2020-08-04 20:32:07 +10:00
|
|
|
l->animNumber = LA_STAND_TO_POLE;
|
|
|
|
l->currentAnimState = LS_POLE_IDLE;
|
2020-07-21 09:56:47 +02:00
|
|
|
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
|
2019-11-01 08:35:01 +01:00
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNumber;
|
|
|
|
}
|
|
|
|
item->pos.yRot = rot;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNumber)
|
|
|
|
{
|
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
item->pos.yRot = rot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_ACTION
|
|
|
|
&& !Lara.gunStatus
|
|
|
|
&& l->gravityStatus
|
|
|
|
&& l->fallspeed > Lara.gunStatus
|
2020-08-04 20:32:07 +10:00
|
|
|
&& (l->currentAnimState == LS_REACH || l->currentAnimState == LS_JUMP_UP))
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
if (TestBoundsCollide(item, l, 100))
|
|
|
|
{
|
|
|
|
if (TestCollision(item, l))
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short rot = item->pos.yRot;
|
2019-12-22 17:06:25 -03:00
|
|
|
item->pos.yRot = l->pos.yRot;
|
2020-08-04 20:32:07 +10:00
|
|
|
if (l->currentAnimState == LS_REACH)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
PolePosR.y = l->pos.yPos - item->pos.yPos + 10;
|
|
|
|
AlignLaraPosition(&PolePosR, item, l);
|
2020-08-04 20:32:07 +10:00
|
|
|
l->animNumber = LA_REACH_TO_POLE;
|
2020-07-21 09:56:47 +02:00
|
|
|
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
|
2019-11-01 08:35:01 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PolePosR.y = l->pos.yPos - item->pos.yPos + 66;
|
|
|
|
AlignLaraPosition(&PolePosR, item, l);
|
2020-08-04 20:32:07 +10:00
|
|
|
l->animNumber = LA_JUMP_UP_TO_POLE;
|
2020-07-21 09:56:47 +02:00
|
|
|
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
|
2019-11-01 08:35:01 +01:00
|
|
|
}
|
|
|
|
l->gravityStatus = false;
|
|
|
|
l->fallspeed = false;
|
2020-08-04 20:32:07 +10:00
|
|
|
l->currentAnimState = LS_POLE_IDLE;
|
2019-11-01 08:35:01 +01:00
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
item->pos.yRot = rot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-04 20:32:07 +10:00
|
|
|
if ((l->currentAnimState < LS_POLE_IDLE || l->currentAnimState > LS_POLE_TURN_COUNTER_CLOCKWISE) &&
|
|
|
|
l->currentAnimState != LS_JUMP_BACK)
|
2019-11-01 08:35:01 +01:00
|
|
|
ObjectCollision(itemNumber, l, coll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void ControlTriggerTriggerer(short itemNumber)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2019-11-01 08:35:01 +01:00
|
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
|
2019-11-27 15:12:35 +01:00
|
|
|
int height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
if (TriggerIndex)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short* trigger = TriggerIndex;
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
if ((*trigger & 0x1F) == 5)
|
|
|
|
{
|
|
|
|
if ((*trigger & 0x8000) != 0)
|
|
|
|
return;
|
|
|
|
trigger++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*trigger & 0x1F) == 6)
|
|
|
|
{
|
|
|
|
if ((*trigger & 0x8000) != 0)
|
|
|
|
return;
|
|
|
|
trigger++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*trigger & 0x1F) == 19)
|
|
|
|
{
|
|
|
|
if ((*trigger & 0x8000) != 0)
|
|
|
|
return;
|
|
|
|
trigger++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*trigger & 0x1F) == 20)
|
|
|
|
{
|
|
|
|
if (TriggerActive(item))
|
|
|
|
*trigger |= 0x20u;
|
|
|
|
else
|
|
|
|
*trigger &= 0xDFu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void AnimateWaterfalls()
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
lastWaterfallY = (lastWaterfallY - 7) & 0x3F;
|
|
|
|
float y = lastWaterfallY * 0.00390625f;
|
|
|
|
float theY;
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
for (int i = 0; i < 6; i++)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
if (Objects[ID_WATERFALL1 + i].loaded)
|
|
|
|
{
|
|
|
|
OBJECT_TEXTURE* texture = WaterfallTextures[i];
|
|
|
|
|
|
|
|
texture->vertices[0].y = y + WaterfallY[i];
|
|
|
|
texture->vertices[1].y = y + WaterfallY[i];
|
|
|
|
texture->vertices[2].y = y + WaterfallY[i] + 0.24609375f;
|
|
|
|
texture->vertices[3].y = y + WaterfallY[i] + 0.24609375f;
|
|
|
|
|
|
|
|
if (i < 5)
|
|
|
|
{
|
|
|
|
texture++;
|
|
|
|
|
|
|
|
texture->vertices[0].y = y + WaterfallY[i];
|
|
|
|
texture->vertices[1].y = y + WaterfallY[i];
|
|
|
|
texture->vertices[2].y = y + WaterfallY[i] + 0.24609375f;
|
|
|
|
texture->vertices[3].y = y + WaterfallY[i] + 0.24609375f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void ControlWaterfall(short itemNumber)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2019-11-01 08:35:01 +01:00
|
|
|
TriggerActive(item);
|
|
|
|
|
|
|
|
if (itemNumber != 0)
|
|
|
|
{
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
|
|
|
|
if (item->triggerFlags == 0x29C)
|
|
|
|
{
|
|
|
|
SoundEffect(SFX_D_METAL_KICKOPEN, &item->pos, 0);
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags == 0x309)
|
|
|
|
{
|
|
|
|
SoundEffect(SFX_WATERFALL_LOOP, &item->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->triggerFlags == 2 || item->triggerFlags == 0x29C)
|
|
|
|
{
|
|
|
|
item->status = ITEM_INVISIBLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void TightRopeCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNum];
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
if (((TrInput & IN_ACTION) == 0
|
2020-08-04 20:32:07 +10:00
|
|
|
|| l->currentAnimState != LS_STOP
|
|
|
|
|| l->animNumber != LA_STAND_IDLE
|
2019-11-03 08:05:48 +01:00
|
|
|
|| l->status == ITEM_INVISIBLE
|
2019-11-01 08:35:01 +01:00
|
|
|
|| Lara.gunStatus)
|
|
|
|
&& (!Lara.isMoving || Lara.generalPtr != (void*)itemNum))
|
|
|
|
{
|
2020-08-04 20:32:07 +10:00
|
|
|
if (l->currentAnimState == LS_TIGHTROPE_FORWARD &&
|
|
|
|
l->goalAnimState != LS_TIGHTROPE_EXIT &&
|
2019-11-01 08:35:01 +01:00
|
|
|
!Lara.tightRopeOff)
|
|
|
|
{
|
|
|
|
if (item->pos.yRot == l->pos.yRot)
|
|
|
|
{
|
|
|
|
if (abs(item->pos.xPos - l->pos.xPos) + abs(item->pos.zPos - l->pos.zPos) < 640)
|
|
|
|
Lara.tightRopeOff = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
2020-07-25 18:02:35 +02:00
|
|
|
if (TestLaraPosition(&TightRopeBounds, item, l))
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
if (MoveLaraPosition(&TightRopePos, item, l))
|
|
|
|
{
|
2020-08-04 20:32:07 +10:00
|
|
|
l->currentAnimState = LS_TIGHTROPE_ENTER;
|
|
|
|
l->animNumber = LA_TIGHTROPE_START;
|
2020-07-21 09:56:47 +02:00
|
|
|
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
|
2019-11-01 08:35:01 +01:00
|
|
|
Lara.isMoving = false;
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
Lara.tightRopeOnCount = 60;
|
|
|
|
Lara.tightRopeOff = 0;
|
|
|
|
Lara.tightRopeFall = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.generalPtr = (void*)itemNum;
|
|
|
|
}
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Lara.isMoving && Lara.generalPtr == (void*)itemNum)
|
|
|
|
Lara.isMoving = false;
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void ParallelBarsCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2020-08-04 20:32:07 +10:00
|
|
|
if (TrInput & IN_ACTION && l->currentAnimState == LS_REACH && l->animNumber == LA_REACH)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
2020-07-25 18:02:35 +02:00
|
|
|
int test1 = TestLaraPosition(&ParallelBarsBounds, item, l);
|
2019-11-27 15:12:35 +01:00
|
|
|
int test2 = 0;
|
2019-11-01 08:35:01 +01:00
|
|
|
if (!test1)
|
|
|
|
{
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
2020-07-25 18:02:35 +02:00
|
|
|
test2 = TestLaraPosition(&ParallelBarsBounds, item, l);
|
2019-11-01 08:35:01 +01:00
|
|
|
item->pos.yRot += -ANGLE(180);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (test1 || test2)
|
|
|
|
{
|
2020-08-04 20:32:07 +10:00
|
|
|
l->currentAnimState = LS_MISC_CONTROL;
|
|
|
|
l->animNumber = LA_SWINGBAR_GRAB;
|
2020-07-21 09:56:47 +02:00
|
|
|
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
|
2019-11-01 08:35:01 +01:00
|
|
|
l->fallspeed = false;
|
|
|
|
l->gravityStatus = false;
|
|
|
|
|
|
|
|
Lara.headYrot = 0;
|
|
|
|
Lara.headXrot = 0;
|
|
|
|
Lara.torsoYrot = 0;
|
|
|
|
Lara.torsoXrot = 0;
|
|
|
|
|
|
|
|
if (test1)
|
|
|
|
l->pos.yRot = item->pos.yRot;
|
|
|
|
else
|
|
|
|
l->pos.yRot = item->pos.yRot + -ANGLE(180);
|
|
|
|
|
|
|
|
PHD_VECTOR pos1;
|
|
|
|
pos1.x = 0;
|
|
|
|
pos1.y = -128;
|
|
|
|
pos1.z = 512;
|
|
|
|
|
|
|
|
PHD_VECTOR pos2;
|
|
|
|
pos2.x = 0;
|
|
|
|
pos2.y = -128;
|
|
|
|
pos2.z = 512;
|
|
|
|
|
2020-04-29 06:43:53 +02:00
|
|
|
GetLaraJointPosition(&pos1, LM_LHAND);
|
|
|
|
GetLaraJointPosition(&pos2, LM_RHAND);
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
if (l->pos.yRot & 0x4000)
|
2020-10-06 12:44:14 -05:00
|
|
|
l->pos.xPos += item->pos.xPos - ((pos1.x + pos2.x) / 2);
|
2019-11-01 08:35:01 +01:00
|
|
|
else
|
2020-10-06 12:44:14 -05:00
|
|
|
l->pos.zPos += item->pos.zPos - ((pos1.z + pos2.z) / 2);
|
|
|
|
l->pos.yPos += item->pos.yPos - ((pos1.y + pos2.y) / 2);
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
Lara.generalPtr = item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ObjectCollision(itemNumber, l, coll);
|
|
|
|
}
|
|
|
|
}
|
2020-08-04 20:32:07 +10:00
|
|
|
else if (l->currentAnimState != LS_BARS_SWING)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
ObjectCollision(itemNumber, l, coll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void CutsceneRopeControl(short itemNumber)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
PHD_VECTOR pos1;
|
|
|
|
PHD_VECTOR pos2;
|
2019-11-27 15:12:35 +01:00
|
|
|
int dx;
|
|
|
|
int dy;
|
|
|
|
int dz;
|
2019-11-01 08:35:01 +01:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNumber];
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
pos1.x = -128;
|
|
|
|
pos1.y = -72;
|
|
|
|
pos1.z = -16;
|
2020-07-21 09:56:47 +02:00
|
|
|
GetJointAbsPosition(&g_Level.Items[item->itemFlags[2]], &pos1, 0);
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
pos2.x = 830;
|
|
|
|
pos2.z = -12;
|
|
|
|
pos2.y = 0;
|
2020-07-21 09:56:47 +02:00
|
|
|
GetJointAbsPosition(&g_Level.Items[item->itemFlags[3]], &pos2, 0);
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
item->pos.xPos = pos2.x;
|
|
|
|
item->pos.yPos = pos2.y;
|
|
|
|
item->pos.zPos = pos2.z;
|
|
|
|
|
|
|
|
dx = (pos2.x - pos1.x) * (pos2.x - pos1.x);
|
|
|
|
dy = (pos2.y - pos1.y) * (pos2.y - pos1.y);
|
|
|
|
dz = (pos2.z - pos1.z) * (pos2.z - pos1.z);
|
|
|
|
|
2020-04-20 14:17:01 +02:00
|
|
|
item->itemFlags[1] = ((sqrt(dx + dy + dz) * 2) + sqrt(dx + dy + dz)) * 2;
|
2019-11-01 08:35:01 +01:00
|
|
|
item->pos.xRot = -4869;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void HybridCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNum];
|
2019-11-01 08:35:01 +01:00
|
|
|
|
|
|
|
/*if (gfCurrentLevel == LVL5_SINKING_SUBMARINE)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
if (item->frameNumber < g_Level.Anims[item->animNumber].frame_end)
|
2019-11-01 08:35:01 +01:00
|
|
|
{
|
|
|
|
ObjectCollision(itemNum, laraitem, coll);
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
2019-12-23 23:10:24 +01:00
|
|
|
void InitialiseTightRope(short itemNumber)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2019-12-23 23:10:24 +01:00
|
|
|
|
|
|
|
if (item->pos.yRot > 0)
|
|
|
|
{
|
|
|
|
if (item->pos.yRot == ANGLE(90))
|
|
|
|
item->pos.xPos -= 256;
|
|
|
|
}
|
|
|
|
else if (item->pos.yRot)
|
|
|
|
{
|
|
|
|
if (item->pos.yRot == -ANGLE(180))
|
|
|
|
{
|
|
|
|
item->pos.zPos += 256;
|
|
|
|
}
|
|
|
|
else if (item->pos.yRot == -ANGLE(90))
|
|
|
|
{
|
|
|
|
item->pos.xPos += 256;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.zPos -= 256;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-15 18:30:34 +02:00
|
|
|
void InitialiseAnimating(short itemNumber)
|
|
|
|
{
|
2020-08-04 07:10:31 +02:00
|
|
|
/*ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2020-04-15 18:30:34 +02:00
|
|
|
item->currentAnimState = 0;
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex;
|
2020-08-04 07:10:31 +02:00
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;*/
|
2020-04-15 18:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void AnimatingControl(short itemNumber)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2020-04-15 18:30:34 +02:00
|
|
|
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
return;
|
|
|
|
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AnimateItem(item);
|
|
|
|
|
2020-08-04 07:10:31 +02:00
|
|
|
// TODO: ID_SHOOT_SWITCH2 probably the bell in Trajan Markets, use LUA for that
|
|
|
|
/*if (item->frameNumber >= g_Level.Anims[item->animNumber].frameEnd)
|
2020-04-15 18:30:34 +02:00
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
2020-04-15 18:30:34 +02:00
|
|
|
RemoveActiveItem(itemNumber);
|
|
|
|
item->aiBits = 0;
|
2020-05-30 15:55:23 +02:00
|
|
|
item->status = ITEM_NOT_ACTIVE;
|
2020-08-04 07:10:31 +02:00
|
|
|
}*/
|
2020-04-15 18:30:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void HighObject2Control(short itemNumber)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
2020-04-15 18:30:34 +02:00
|
|
|
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (!item->itemFlags[2])
|
|
|
|
{
|
2020-10-06 12:44:14 -05:00
|
|
|
int div = (item->triggerFlags % 10) * 1024;
|
|
|
|
int mod = (item->triggerFlags / 10) * 1024;
|
2020-04-15 18:30:34 +02:00
|
|
|
item->itemFlags[0] = GetRandomControl() % div;
|
|
|
|
item->itemFlags[1] = GetRandomControl() % mod;
|
|
|
|
item->itemFlags[2] = (GetRandomControl() & 0xF) + 15;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (--item->itemFlags[2] < 15)
|
|
|
|
{
|
|
|
|
SPARKS* spark = &Sparks[GetFreeSpark()];
|
|
|
|
spark->on = 1;
|
|
|
|
spark->sR = -1;
|
|
|
|
spark->sB = 16;
|
|
|
|
spark->sG = (GetRandomControl() & 0x1F) + 48;
|
|
|
|
spark->dR = (GetRandomControl() & 0x3F) - 64;
|
|
|
|
spark->dB = 0;
|
|
|
|
spark->dG = (GetRandomControl() & 0x3F) + -128;
|
|
|
|
spark->fadeToBlack = 4;
|
|
|
|
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
|
|
|
|
spark->transType = COLADD;
|
|
|
|
spark->life = spark->sLife = (GetRandomControl() & 3) + 24;
|
|
|
|
spark->x = item->itemFlags[1] + (GetRandomControl() & 0x3F) + item->pos.xPos - 544;
|
|
|
|
spark->y = item->pos.yPos;
|
|
|
|
spark->z = item->itemFlags[0] + (GetRandomControl() & 0x3F) + item->pos.zPos - 544;
|
|
|
|
spark->xVel = (GetRandomControl() & 0x1FF) - 256;
|
|
|
|
spark->friction = 6;
|
|
|
|
spark->zVel = (GetRandomControl() & 0x1FF) - 256;
|
|
|
|
spark->rotAng = GetRandomControl() & 0xFFF;
|
|
|
|
spark->rotAdd = (GetRandomControl() & 0x3F) - 32;
|
|
|
|
spark->maxYvel = 0;
|
|
|
|
spark->yVel = -512 - (GetRandomControl() & 0x3FF);
|
|
|
|
spark->sSize = spark->size = (GetRandomControl() & 0xF) + 32;
|
2020-09-12 13:49:09 +02:00
|
|
|
spark->dSize = spark->size / 4;
|
2020-04-15 18:30:34 +02:00
|
|
|
|
|
|
|
if (GetRandomControl() & 3)
|
|
|
|
{
|
|
|
|
spark->flags = SP_ROTATE | SP_DEF | SP_SCALE | SP_EXPDEF;
|
|
|
|
spark->scalar = 3;
|
|
|
|
spark->gravity = (GetRandomControl() & 0x3F) + 32;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
spark->flags = SP_ROTATE | SP_DEF | SP_SCALE;
|
|
|
|
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST;
|
|
|
|
spark->scalar = 1;
|
|
|
|
spark->gravity = (GetRandomControl() & 0xF) + 64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|