2020-08-25 18:14:18 -05:00
|
|
|
#include "framework.h"
|
|
|
|
#include "biggun.h"
|
|
|
|
#include "items.h"
|
|
|
|
#include "level.h"
|
|
|
|
#include "collide.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "lara.h"
|
2020-08-29 22:20:52 -03:00
|
|
|
#include "lara_flare.h"
|
2021-09-08 18:19:06 +03:00
|
|
|
#include "Sound\sound.h"
|
2020-08-25 18:14:18 -05:00
|
|
|
#include "sphere.h"
|
2021-09-08 18:07:48 +03:00
|
|
|
#include "effects\effects.h"
|
2020-08-25 18:14:18 -05:00
|
|
|
#include "lara_struct.h"
|
2021-09-08 18:07:48 +03:00
|
|
|
#include "effects\tomb4fx.h"
|
2020-08-25 22:55:23 -05:00
|
|
|
#include "draw.h"
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
static long GunRotYAdd = 0;
|
|
|
|
bool barrelRotating;
|
|
|
|
|
|
|
|
#define RECOIL_TIME 26
|
|
|
|
#define RECOIL_Z 25
|
|
|
|
|
|
|
|
//flags
|
|
|
|
#define FLAG_UPDOWN 1
|
|
|
|
#define FLAG_AUTOROT 2
|
|
|
|
#define FLAG_GETOFF 4
|
|
|
|
#define FLAG_FIRE 8
|
|
|
|
//frames
|
|
|
|
#define BGUN_UPDOWN_FRAMES 59
|
|
|
|
#define GETOFF_FRAME 30//the frame where Lara isn't looking either up or down in her "main" animation, aka when she can get off
|
|
|
|
|
|
|
|
enum {//states
|
|
|
|
BGUN_GETON,
|
|
|
|
BGUN_GETOFF,
|
|
|
|
BGUN_UPDOWN,
|
|
|
|
BGUN_RECOIL
|
|
|
|
};
|
|
|
|
enum {//anims
|
|
|
|
BGUN_GETON_A,
|
|
|
|
BGUN_GETOFF_A,
|
|
|
|
BGUN_UPDOWN_A,
|
|
|
|
BGUN_RECOIL_A
|
|
|
|
};
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
void FireBigGun(ITEM_INFO *obj)
|
|
|
|
{
|
2020-08-25 22:55:23 -05:00
|
|
|
short itemNumber = CreateItem();
|
|
|
|
if (itemNumber != NO_ITEM)
|
|
|
|
{
|
2020-09-11 12:54:30 -05:00
|
|
|
|
|
|
|
BIGGUNINFO *gun = (BIGGUNINFO*)obj->data;
|
|
|
|
|
2020-08-25 22:55:23 -05:00
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
|
|
|
item->objectNumber = ID_ROCKET;
|
|
|
|
item->roomNumber = LaraItem->roomNumber;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
|
2020-09-11 12:54:30 -05:00
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
2020-10-26 15:22:33 -05:00
|
|
|
pos.z = 256;//520;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-09-11 12:54:30 -05:00
|
|
|
GetJointAbsPosition(obj, &pos, 2);
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-09-11 12:54:30 -05:00
|
|
|
|
|
|
|
item->pos.xPos = pos.x;
|
|
|
|
item->pos.yPos = pos.y;
|
|
|
|
item->pos.zPos = pos.z;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-08-25 22:55:23 -05:00
|
|
|
InitialiseItem(itemNumber);
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
|
2020-09-11 12:54:30 -05:00
|
|
|
item->pos.xRot = -((gun->xRot - 32) * (ANGLE(1)));
|
|
|
|
item->pos.yRot = obj->pos.yRot;
|
|
|
|
item->pos.zRot = 0;
|
2020-10-06 10:36:30 -05:00
|
|
|
item->speed = 16;
|
2020-09-11 12:54:30 -05:00
|
|
|
item->itemFlags[0] = 1;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-08-25 22:55:23 -05:00
|
|
|
AddActiveItem(itemNumber);
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-09-11 12:54:30 -05:00
|
|
|
SmokeCountL = 32;
|
|
|
|
SmokeWeapon = WEAPON_ROCKET_LAUNCHER;
|
|
|
|
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
TriggerGunSmoke(pos.x, pos.y, pos.z, 0, 0, 0, 1, WEAPON_ROCKET_LAUNCHER, 32);
|
|
|
|
|
2021-05-26 06:04:32 +02:00
|
|
|
SoundEffect(SFX_TR4_EXPLOSION1, 0, 0);
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
2020-08-25 22:55:23 -05:00
|
|
|
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static int CanUseGun(ITEM_INFO *obj, ITEM_INFO *lara)
|
|
|
|
{
|
|
|
|
int dist;
|
2020-10-25 00:35:31 -05:00
|
|
|
long long x, z;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
if ((!(TrInput & IN_ACTION))
|
|
|
|
|| (Lara.gunStatus != LG_NO_ARMS)
|
|
|
|
|| (lara->gravityStatus))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
x = lara->pos.xPos - obj->pos.xPos;
|
|
|
|
z = lara->pos.zPos - obj->pos.zPos;
|
|
|
|
|
|
|
|
dist = SQUARE(x) + SQUARE(z);
|
|
|
|
|
|
|
|
if (dist > 30000)
|
|
|
|
return 0;
|
2020-10-25 00:35:31 -05:00
|
|
|
|
|
|
|
short ang = abs(lara->pos.yRot - obj->pos.yRot);
|
|
|
|
if (ang > ANGLE(35.0f) || ang < -ANGLE(35.0f))
|
|
|
|
return 0;
|
|
|
|
|
2020-08-25 18:14:18 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BigGunInitialise(short itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO *obj;
|
|
|
|
BIGGUNINFO *gun;
|
|
|
|
|
|
|
|
obj = &g_Level.Items[itemNum];
|
|
|
|
|
|
|
|
gun = (BIGGUNINFO*)malloc(sizeof(BIGGUNINFO));
|
|
|
|
obj->data = malloc(sizeof(BIGGUNINFO));
|
|
|
|
|
|
|
|
gun->flags = 0;
|
2020-10-25 00:35:31 -05:00
|
|
|
gun->fireCount = 0;
|
|
|
|
gun->xRot = GETOFF_FRAME;
|
2020-08-25 18:14:18 -05:00
|
|
|
gun->yRot = 0;
|
|
|
|
gun->startYRot = obj->pos.yRot;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BigGunCollision(short itemNum, ITEM_INFO* lara, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
ITEM_INFO* obj;
|
|
|
|
|
|
|
|
if (lara->hitPoints <= 0 || Lara.Vehicle != NO_ITEM)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obj = &g_Level.Items[itemNum];
|
|
|
|
|
|
|
|
if (CanUseGun(obj, lara))
|
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
BIGGUNINFO *gun;
|
2020-08-25 18:14:18 -05:00
|
|
|
Lara.Vehicle = itemNum;
|
|
|
|
|
|
|
|
if (Lara.gunType == WEAPON_FLARE)
|
|
|
|
{
|
|
|
|
CreateFlare(ID_FLARE_ITEM, 0);
|
|
|
|
undraw_flare_meshes();
|
|
|
|
Lara.flareControlLeft = false;
|
|
|
|
Lara.requestGunType = WEAPON_NONE;
|
|
|
|
Lara.gunType = WEAPON_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
|
2020-10-26 15:22:33 -05:00
|
|
|
obj->hitPoints = 1;
|
2020-08-25 18:14:18 -05:00
|
|
|
lara->pos.xPos = obj->pos.xPos;
|
|
|
|
lara->pos.xRot = obj->pos.xRot;
|
|
|
|
lara->pos.yPos = obj->pos.yPos;
|
|
|
|
lara->pos.yRot = obj->pos.yRot;
|
|
|
|
lara->pos.zPos = obj->pos.zPos;
|
|
|
|
lara->pos.zRot = obj->pos.zRot;
|
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
lara->animNumber = Objects[ID_BIGGUN_ANIMS].animIndex + BGUN_GETON_A;
|
|
|
|
lara->frameNumber = g_Level.Anims[Objects[ID_BIGGUN_ANIMS].animIndex + BGUN_GETON_A].frameBase;
|
|
|
|
lara->currentAnimState = BGUN_GETON;
|
|
|
|
lara->goalAnimState = BGUN_GETON;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
gun = (BIGGUNINFO*)obj->data;
|
|
|
|
gun->flags = 0;
|
2020-10-25 00:35:31 -05:00
|
|
|
gun->xRot = GETOFF_FRAME;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ObjectCollision(itemNum, lara, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
int BigGunControl(COLL_INFO *coll)
|
|
|
|
{
|
|
|
|
BIGGUNINFO *gun;
|
|
|
|
ITEM_INFO *obj;
|
|
|
|
ITEM_INFO *lara;
|
|
|
|
|
|
|
|
lara = LaraItem;
|
|
|
|
obj = &g_Level.Items[Lara.Vehicle];
|
|
|
|
gun = (BIGGUNINFO *)obj->data;
|
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
if (gun->flags & FLAG_UPDOWN)
|
2020-08-25 18:14:18 -05:00
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
if (barrelRotating)
|
|
|
|
gun->barrelZ--;
|
|
|
|
|
|
|
|
if (!gun->barrelZ)
|
|
|
|
barrelRotating = false;
|
|
|
|
|
2020-08-25 18:14:18 -05:00
|
|
|
if ((lara->hitPoints <= 0) || (TrInput & IN_ROLL))
|
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
gun->flags = FLAG_AUTOROT;
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
if ((TrInput & IN_ACTION) && gun->fireCount == 0)
|
|
|
|
{
|
|
|
|
FireBigGun(obj);
|
|
|
|
gun->fireCount = RECOIL_TIME;
|
|
|
|
gun->barrelZ = RECOIL_Z;
|
|
|
|
barrelRotating = true;
|
|
|
|
}
|
|
|
|
|
2020-08-25 18:14:18 -05:00
|
|
|
if (TrInput & IN_LEFT)
|
2020-10-25 00:35:31 -05:00
|
|
|
{
|
|
|
|
if (GunRotYAdd > 0)
|
|
|
|
GunRotYAdd /= 2;
|
|
|
|
|
|
|
|
GunRotYAdd -= 8;
|
|
|
|
|
|
|
|
if (GunRotYAdd < -64)
|
|
|
|
GunRotYAdd = -64;
|
|
|
|
}
|
|
|
|
else
|
2020-09-11 00:44:48 -05:00
|
|
|
if (TrInput & IN_RIGHT)
|
2020-10-25 00:35:31 -05:00
|
|
|
{
|
|
|
|
if (GunRotYAdd < 0)
|
|
|
|
GunRotYAdd /= 2;
|
2020-08-25 22:55:23 -05:00
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
GunRotYAdd += 8;
|
|
|
|
|
|
|
|
if (GunRotYAdd > 64)
|
|
|
|
GunRotYAdd = 64;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GunRotYAdd -= GunRotYAdd / 4;
|
|
|
|
if (abs(GunRotYAdd) < 8)
|
|
|
|
GunRotYAdd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gun->yRot += GunRotYAdd / 4;
|
|
|
|
|
|
|
|
if ((TrInput & IN_FORWARD) && (gun->xRot < BGUN_UPDOWN_FRAMES))
|
|
|
|
gun->xRot++;
|
|
|
|
else
|
|
|
|
if ((TrInput & IN_BACK) && (gun->xRot))
|
2020-08-25 18:14:18 -05:00
|
|
|
gun->xRot--;
|
|
|
|
}
|
|
|
|
}
|
2020-09-11 00:44:48 -05:00
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
if (gun->flags & FLAG_AUTOROT)
|
2020-08-25 18:14:18 -05:00
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
if (gun->xRot == GETOFF_FRAME)
|
2020-08-25 18:14:18 -05:00
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
lara->animNumber = Objects[ID_BIGGUN_ANIMS].animIndex + BGUN_GETOFF_A;
|
|
|
|
lara->frameNumber = g_Level.Anims[Objects[ID_BIGGUN].animIndex + BGUN_GETOFF_A].frameBase;
|
|
|
|
lara->currentAnimState = BGUN_GETOFF;
|
|
|
|
lara->goalAnimState = BGUN_GETOFF;
|
|
|
|
gun->flags = FLAG_GETOFF;
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
2020-10-25 00:35:31 -05:00
|
|
|
else if (gun->xRot > GETOFF_FRAME)
|
|
|
|
gun->xRot--;
|
|
|
|
else if (gun->xRot < GETOFF_FRAME)
|
|
|
|
gun->xRot++;
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (lara->currentAnimState)
|
|
|
|
{
|
2020-10-25 00:35:31 -05:00
|
|
|
case BGUN_GETON:
|
|
|
|
case BGUN_GETOFF:
|
2020-08-25 18:14:18 -05:00
|
|
|
AnimateItem(lara);
|
|
|
|
obj->animNumber = Objects[ID_BIGGUN].animIndex + (lara->animNumber - Objects[ID_BIGGUN_ANIMS].animIndex);
|
|
|
|
obj->frameNumber = g_Level.Anims[obj->animNumber].frameBase + (lara->frameNumber - g_Level.Anims[lara->animNumber].frameBase);
|
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
if ((gun->flags & FLAG_GETOFF) && lara->frameNumber == g_Level.Anims[lara->animNumber].frameEnd)
|
2020-08-25 18:14:18 -05:00
|
|
|
{
|
|
|
|
lara->animNumber = LA_STAND_SOLID;
|
|
|
|
lara->frameNumber = g_Level.Anims[lara->animNumber].frameBase;
|
|
|
|
lara->currentAnimState = LS_STOP;
|
|
|
|
lara->goalAnimState = LS_STOP;
|
|
|
|
Lara.Vehicle = NO_ITEM;
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
2020-10-26 15:22:33 -05:00
|
|
|
obj->hitPoints = 0;
|
2020-08-25 18:14:18 -05:00
|
|
|
}
|
|
|
|
break;
|
2020-10-25 00:35:31 -05:00
|
|
|
case BGUN_UPDOWN:
|
|
|
|
lara->animNumber = Objects[ID_BIGGUN_ANIMS].animIndex + BGUN_UPDOWN_A;
|
|
|
|
lara->frameNumber = g_Level.Anims[Objects[ID_BIGGUN].animIndex + BGUN_UPDOWN_A].frameBase + gun->xRot;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
obj->animNumber = Objects[ID_BIGGUN].animIndex + (lara->animNumber - Objects[ID_BIGGUN_ANIMS].animIndex);
|
|
|
|
obj->frameNumber = g_Level.Anims[obj->animNumber].frameBase + (lara->frameNumber - g_Level.Anims[lara->animNumber].frameBase);
|
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
if (gun->fireCount > 0)
|
|
|
|
gun->fireCount--;
|
|
|
|
else if (gun->fireCount <= 0)
|
|
|
|
gun->fireCount = 0;
|
2020-08-25 18:14:18 -05:00
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
gun->flags = FLAG_UPDOWN;
|
2020-08-25 18:14:18 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-10-25 00:35:31 -05:00
|
|
|
lara->pos.yRot = obj->pos.yRot = gun->startYRot + (gun->yRot * (ANGLE(1) / 4));
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
coll->enableSpaz = false;
|
|
|
|
coll->enableBaddiePush = false;
|
2021-09-02 11:20:41 +03:00
|
|
|
DoObjectCollision(lara, coll);
|
2020-08-25 18:14:18 -05:00
|
|
|
|
|
|
|
Camera.targetElevation = -ANGLE(15);
|
|
|
|
return 1;
|
|
|
|
}
|