TombEngine/TR5Main/Game/laraflar.cpp

485 lines
9.5 KiB
C++
Raw Normal View History

#include "laraflar.h"
2019-12-01 08:13:19 +01:00
#include "..\Global\global.h"
2019-12-01 08:13:19 +01:00
#include "draw.h"
#include "items.h"
#include "sphere.h"
#include "larafire.h"
#include "Lara.h"
#include "collide.h"
#include "effect2.h"
2019-12-01 08:13:19 +01:00
extern LaraExtraInfo g_LaraExtra;
2019-12-02 09:11:21 +01:00
void FlareControl(short itemNumber)//4A418, 4A87C
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
ITEM_INFO* item = &Items[itemNumber];
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
KillItem(itemNumber);
return;
}
2019-12-01 08:13:19 +01:00
if (item->fallspeed)
{
item->pos.xRot += ANGLE(3);
item->pos.zRot += ANGLE(5);
}
else
{
item->pos.xRot = 0;
item->pos.zRot = 0;
}
2019-12-02 09:11:21 +01:00
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
2019-12-01 08:13:19 +01:00
2019-12-02 09:11:21 +01:00
int xv = 0;
int zv = 0;
2019-12-01 08:13:19 +01:00
item->pos.xPos += (xv = (item->speed * SIN(item->pos.yRot) >> W2V_SHIFT));
item->pos.zPos += (zv = (item->speed * COS(item->pos.yRot) >> W2V_SHIFT));
if (Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->fallspeed += (5 - item->fallspeed) / 2;
item->speed += (5 - item->speed) / 2;
}
else
item->fallspeed += 6;
item->pos.yPos += item->fallspeed;
DoProperDetection(itemNumber, oldX, oldY, oldZ, xv, zv);
2019-12-02 09:11:21 +01:00
short age = (short)(item->data) & 0x7FFF;
2019-12-01 08:13:19 +01:00
if (age >= 900)
{
if (!item->fallspeed && !item->speed)
KillItem(itemNumber);
}
else
{
age++;
}
if (DoFlareLight((PHD_VECTOR*)&item->pos, age))
{
/*if (gfLevelFlags & 0x2000 && item->roomNumber == gfMirrorRoom)
{
item->pos.zPos = 2 * gfMirrorZPlane - item->pos.zPos;
sub_401807(&item->pos, v9);
v10 = 2 * gfMirrorZPlane - item->pos.zPos;
item->pos.zPos = v10;
}*/
age |= 0x8000;
}
item->data = (void*)age;
2019-11-21 07:43:34 +01:00
}
void ready_flare()//4A3E4(<), 4A848(<) (F)
{
2019-12-01 08:13:19 +01:00
Lara.gunStatus = LG_NO_ARMS;
Lara.leftArm.zRot = 0;
Lara.leftArm.yRot = 0;
Lara.leftArm.xRot = 0;
Lara.rightArm.zRot = 0;
Lara.rightArm.yRot = 0;
Lara.rightArm.xRot = 0;
Lara.rightArm.lock = 0;
Lara.leftArm.lock = 0;
2019-11-21 07:43:34 +01:00
Lara.target = NULL;
}
2019-12-01 08:13:19 +01:00
void undraw_flare_meshes()
2019-11-21 07:43:34 +01:00
{
2019-12-15 16:19:01 +01:00
LARA_MESHES(ID_LARA, LM_LHAND);
2019-11-21 07:43:34 +01:00
}
2019-12-15 16:19:01 +01:00
2019-11-21 07:43:34 +01:00
void draw_flare_meshes()//4A394(<), 4A7F8(<) (F)
{
2019-12-15 16:19:01 +01:00
LARA_MESHES(ID_FLARE_ANIM, LM_LHAND);
2019-11-21 07:43:34 +01:00
}
void undraw_flare()//4A108, 4A56C
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
Lara.flareControlLeft = true;
2019-12-02 09:11:21 +01:00
short frame1 = Lara.flareFrame;
short frame2 = Lara.leftArm.frameNumber;
2019-12-01 08:13:19 +01:00
if (LaraItem->goalAnimState == STATE_LARA_STOP &&
g_LaraExtra.Vehicle == NO_ITEM)
{
if (LaraItem->animNumber == ANIMATION_LARA_STAY_IDLE)
{
LaraItem->animNumber = ANIMATION_LARA_FLARE_THROW;
frame1 = frame2 + Anims[LaraItem->animNumber].frameBase;
2019-12-26 23:35:16 -03:00
Lara.flareFrame = frame1;
LaraItem->frameNumber = frame1;
2019-12-01 08:13:19 +01:00
}
if (LaraItem->animNumber == ANIMATION_LARA_FLARE_THROW)
{
Lara.flareControlLeft = false;
if (frame1 >= Anims[LaraItem->animNumber].frameBase + 31)
{
Lara.requestGunType = Lara.lastGunType;
Lara.gunType = Lara.lastGunType;
Lara.gunStatus = LG_NO_ARMS;
InitialiseNewWeapon();
Lara.target = NULL;
Lara.rightArm.lock = 0;
Lara.leftArm.lock = 0;
LaraItem->animNumber = ANIMATION_LARA_STAY_SOLID;
Lara.flareFrame = Anims[LaraItem->animNumber].frameBase;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
LaraItem->currentAnimState = STATE_LARA_STOP;
LaraItem->goalAnimState = STATE_LARA_STOP;
return;
}
Lara.flareFrame++;
}
}
else if (LaraItem->currentAnimState == STATE_LARA_STOP)
{
LaraItem->animNumber = ANIMATION_LARA_STAY_SOLID;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
}
2019-12-26 23:35:16 -03:00
if (frame2 >= 33 && frame2 < 72)
{
frame2 = 2;
DoFlareInHand(Lara.flareAge);
}
else if (!frame2)
2019-12-01 08:13:19 +01:00
{
frame2 = 1;
DoFlareInHand(Lara.flareAge);
}
else if (frame2 >= 72 && frame2 < 95)
{
frame2++;
if (frame2 == 94)
{
frame2 = 1;
2019-12-26 23:35:16 -03:00
DoFlareInHand(Lara.flareAge);
2019-12-01 08:13:19 +01:00
}
}
2019-12-26 23:35:16 -03:00
else if (frame2 >= 1 && frame2 < 33)
2019-12-01 08:13:19 +01:00
{
frame2++;
if (frame2 == 21)
{
CreateFlare(ID_FLARE_ITEM, 1);
undraw_flare_meshes();
Lara.flareAge = 0;
}
else if (frame2 == 33)
{
frame2 = 0;
Lara.requestGunType = Lara.lastGunType;
Lara.gunType = Lara.lastGunType;
Lara.gunStatus = LG_NO_ARMS;
InitialiseNewWeapon();
Lara.flareControlLeft = false;
Lara.target = NULL;
Lara.rightArm.lock = 0;
Lara.leftArm.lock = 0;
Lara.flareFrame = 0;
}
2019-12-26 23:35:16 -03:00
else if (frame2 < 21)
{
DoFlareInHand(Lara.flareAge);
}
2019-12-01 08:13:19 +01:00
}
2019-12-26 23:35:16 -03:00
else if (frame2 >= 95 && frame2 < 110)
2019-12-01 08:13:19 +01:00
{
frame2++;
if (frame2 == 110)
2019-12-26 23:35:16 -03:00
{
2019-12-01 08:13:19 +01:00
frame2 = 1;
2019-12-26 23:35:16 -03:00
DoFlareInHand(Lara.flareAge);
}
2019-12-01 08:13:19 +01:00
}
Lara.leftArm.frameNumber = frame2;
set_flare_arm(Lara.leftArm.frameNumber);
2019-11-21 07:43:34 +01:00
}
void draw_flare()//49F74, 4A3D8 (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short frame;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
if (LaraItem->currentAnimState == STATE_LARA_FLARE_PICKUP ||
LaraItem->currentAnimState == STATE_LARA_PICKUP)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
DoFlareInHand(Lara.flareAge);
Lara.flareControlLeft = false;
2019-12-26 23:35:16 -03:00
Lara.leftArm.frameNumber = 93;
2019-12-01 08:13:19 +01:00
set_flare_arm(93);
2019-11-21 07:43:34 +01:00
}
else
{
2019-12-01 08:13:19 +01:00
frame = Lara.leftArm.frameNumber + 1;
Lara.flareControlLeft = true;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
if (frame < 33 || frame > 94)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
frame = 33;
2019-11-21 07:43:34 +01:00
}
2019-12-01 08:13:19 +01:00
else if (frame == 46)
2019-11-21 07:43:34 +01:00
{
draw_flare_meshes();
}
2019-12-01 08:13:19 +01:00
else if (frame >= 72 && frame <= 93)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
if (frame == 72)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
SoundEffect(SFX_RAVESTICK, &LaraItem->pos, Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER);
Lara.flareAge = 1;
2019-11-21 07:43:34 +01:00
}
2019-12-01 08:13:19 +01:00
DoFlareInHand(Lara.flareAge);
2019-11-21 07:43:34 +01:00
}
else
{
2019-12-01 08:13:19 +01:00
if (frame == 94)
2019-11-21 07:43:34 +01:00
{
ready_flare();
2019-12-01 08:13:19 +01:00
frame = 0;
DoFlareInHand(Lara.flareAge);
2019-11-21 07:43:34 +01:00
}
}
2019-12-01 08:13:19 +01:00
Lara.leftArm.frameNumber = frame;
set_flare_arm(frame);
}
2019-11-21 07:43:34 +01:00
}
void set_flare_arm(int frame)//49ED4, 4A338 (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short anim = Objects[ID_FLARE_ANIM].animIndex;
2019-11-21 07:43:34 +01:00
if (frame >= 95)
{
2019-12-01 08:13:19 +01:00
anim += 4;
2019-11-21 07:43:34 +01:00
}
else if (frame >= 72)
{
2019-12-01 08:13:19 +01:00
anim += 3;
2019-11-21 07:43:34 +01:00
}
else if (frame >= 33)
{
2019-12-01 08:13:19 +01:00
anim += 2;
2019-11-21 07:43:34 +01:00
}
else if (frame >= 1)
{
2019-12-01 08:13:19 +01:00
anim += 1;
2019-11-21 07:43:34 +01:00
}
2019-12-01 08:13:19 +01:00
Lara.leftArm.animNumber = anim;
Lara.leftArm.frameBase = Anims[anim].framePtr;
2019-11-21 07:43:34 +01:00
}
void CreateFlare(short objectNum, int thrown)//49BBC, 4A020
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short itemNum = CreateItem();
2019-12-01 08:13:19 +01:00
if (itemNum != NO_ITEM)
{
bool flag = false;
ITEM_INFO* item = &Items[itemNum];
item->objectNumber = objectNum;
item->roomNumber = LaraItem->roomNumber;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
PHD_VECTOR pos;
pos.x = -16;
pos.y = 32;
pos.z = 42;
GetLaraJointPosition(&pos, LJ_LHAND);
item->pos.xPos = pos.x;
item->pos.yPos = pos.y;
item->pos.zPos = pos.z;
ITEM_INFO* tmp1[128];
MESH_INFO* tmp2[128];
2019-12-02 09:11:21 +01:00
short roomNumber = LaraItem->roomNumber;
2019-12-01 08:13:19 +01:00
FLOOR_INFO* floor = GetFloor(pos.x, pos.y, pos.z, &roomNumber);
2019-12-02 09:11:21 +01:00
int collided = GetCollidedObjects(item, 0, 1, &tmp1[0], &tmp2[0], 0);
2019-12-01 08:13:19 +01:00
if (collided || GetFloorHeight(floor, pos.x, pos.y, pos.z) < pos.y)
{
flag = true;
item->pos.yRot = LaraItem->pos.yRot - ANGLE(180);
item->pos.xPos = LaraItem->pos.xPos + 80 * SIN(item->pos.yRot) >> W2V_SHIFT;
item->pos.zPos = LaraItem->pos.zPos + 80 * COS(item->pos.yRot) >> W2V_SHIFT;
item->roomNumber = LaraItem->roomNumber;
}
else
{
if (thrown)
item->pos.yRot = LaraItem->pos.yRot;
else
item->pos.yRot = LaraItem->pos.yRot - ANGLE(45);
item->roomNumber = roomNumber;
}
InitialiseItem(itemNum);
item->pos.zRot = 0;
item->pos.xRot = 0;
item->shade = -1;
if (thrown)
{
item->speed = LaraItem->speed + 50;
item->fallspeed = LaraItem->fallspeed - 50;
}
else
{
item->speed = LaraItem->speed + 10;
item->fallspeed = LaraItem->fallspeed + 50;
}
if (flag)
item->speed >>= 1;
if (objectNum == ID_FLARE_ITEM)
{
if (DoFlareLight((PHD_VECTOR*)&item->pos, Lara.flareAge))
item->data = (void*)(Lara.flareAge | 0x8000);
else
item->data = (void*)(Lara.flareAge & 0x7FFF);
}
else
{
item->itemFlags[3] = (Lara.currentZvel >> W2V_SHIFT) & 1;
}
AddActiveItem(itemNum);
item->status = ITEM_ACTIVE;
}
2019-11-21 07:43:34 +01:00
}
void DoFlareInHand(int flare_age)//49984, 49DE8
{
2019-12-01 08:13:19 +01:00
PHD_VECTOR pos;
2019-11-21 07:43:34 +01:00
pos.x = 11;
pos.y = 32;
pos.z = 41;
2019-12-01 08:13:19 +01:00
GetLaraJointPosition(&pos, LJ_LHAND);
2019-11-21 07:43:34 +01:00
DoFlareLight(&pos, flare_age);
2019-12-01 08:13:19 +01:00
/*if (gfLevelFlags & GF_LVOP_MIRROR_USED && LaraItem->room_number == gfMirrorRoom)
2019-11-21 07:43:34 +01:00
{
pos.z = 2 * gfMirrorZPlane - pos.z;
DoFlareLight(&pos, flare_age);
2019-12-01 08:13:19 +01:00
}*/
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
if (Lara.flareAge >= 900)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
if (Lara.gunStatus == LG_NO_ARMS)
Lara.gunStatus = LG_UNDRAW_GUNS;
2019-11-21 07:43:34 +01:00
}
2019-12-01 08:13:19 +01:00
else if (Lara.flareAge != 0)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
Lara.flareAge++;
2019-11-21 07:43:34 +01:00
}
}
2019-12-02 09:11:21 +01:00
int DoFlareLight(PHD_VECTOR* pos, int age)//49708, 49B6C (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
int x, y, z;
int r, g, b;
int random;
int falloff;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
if (age >= 900 || age == 0)
2019-11-21 07:43:34 +01:00
return 0;
random = GetRandomControl();
x = pos->x + (random << 3 & 120);
y = pos->y + (random >> 1 & 120) - 256;
z = pos->z + (random >> 5 & 120);
2019-12-01 08:13:19 +01:00
if (age < 4)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
falloff = (random & 3) + 4 * (age + 1);
if (falloff > 16)
falloff -= (random >> 12) & 3;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
r = (random >> 4 & 0x1F) + 8 * (age + 4);
g = (random & 0x1F) + 16 * (age + 10);
b = (random >> 8 & 0x1F) + 16 * age;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
TriggerDynamicLight(x, y, z, falloff, r, g, b);
2019-11-21 07:43:34 +01:00
return 1;
}
2019-12-01 08:13:19 +01:00
else if (age < 16)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
falloff = (random & 1) + age + 2;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
r = (random >> 4 & 0x1F) + 4 * age + 64;
g = (random & 0x3F) + 4 * age + 128;
b = (random >> 8 & 0x1F) + 4 * age + 16;
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
TriggerDynamicLight(x, y, z, falloff, r, g, b);
2019-11-21 07:43:34 +01:00
return 1;
}
2019-12-01 08:13:19 +01:00
else if (age < 810 || random & 0x2000)
2019-11-21 07:43:34 +01:00
{
falloff = 16;
r = (random >> 4 & 0x1F) + 128;
g = (random & 0x3F) + 192;
b = (random >> 8 & 0x20) + (random >> 8 & 0x3F);
2019-12-01 08:13:19 +01:00
TriggerDynamicLight(x, y, z, falloff, r, g, b);
2019-11-21 07:43:34 +01:00
return 1;
}
2019-12-01 08:13:19 +01:00
else if (age >= 876)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
falloff = 16 - ((age - 876) >> 1);
2019-11-21 07:43:34 +01:00
r = (GetRandomControl() & 0x3F) + 64;
g = (GetRandomControl() & 0x3F) + 192;
b = GetRandomControl() & 0x1F;
2019-12-01 08:13:19 +01:00
TriggerDynamicLight(x, y, z, falloff, r, g, b);
2019-11-21 07:43:34 +01:00
return random & 1;
}
else
{
falloff = (GetRandomControl() & 6) + 8;
r = (GetRandomControl() & 0x3F) + 64;
g = (GetRandomControl() & 0x3F) + 192;
b = GetRandomControl() & 0x7F;
2019-12-01 08:13:19 +01:00
TriggerDynamicLight(x, y, z, falloff, r, g, b);
2019-11-21 07:43:34 +01:00
return 0;
}
}
void Inject_LaraFlar()
{
2019-12-01 08:13:19 +01:00
2019-11-15 07:40:22 +01:00
}