TombEngine/TR5Main/Objects/TR4/Entity/tr4_sentrygun.cpp
2020-10-17 23:36:06 -05:00

230 lines
No EOL
5.2 KiB
C++

#include "framework.h"
#include "tr4_sentrygun.h"
#include "box.h"
#include "effect2.h"
#include "items.h"
#include "inventory.h"
#include "level.h"
#include "lot.h"
#include "tomb4fx.h"
#include "sphere.h"
#include "people.h"
#include "sound.h"
#include "trmath.h"
#include "objectslist.h"
extern Inventory g_Inventory;
BITE_INFO sentryGunBite = { 0, 0, 0, 8 };
static void SentryGunThrowFire(ITEM_INFO* item)
{
for (int i = 0; i < 3; i++)
{
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
spark->sR = (GetRandomControl() & 0x1F) + 48;
spark->sG = 48;
spark->sB = 255;
spark->dR = (GetRandomControl() & 0x3F) - 64;
spark->dG = (GetRandomControl() & 0x3F) + -128;
spark->dB = 32;
spark->colFadeSpeed = 12;
spark->fadeToBlack = 8;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 0x1F) + 16;
PHD_VECTOR pos1;
pos1.x = -140;
pos1.y = -30;
pos1.z = -4;
GetJointAbsPosition(item, &pos1, 7);
spark->x = (GetRandomControl() & 0x1F) + pos1.x - 16;
spark->y = (GetRandomControl() & 0x1F) + pos1.y - 16;
spark->z = (GetRandomControl() & 0x1F) + pos1.z - 16;
PHD_VECTOR pos2;
pos2.x = -280;
pos2.y = -30;
pos2.z = -4;
GetJointAbsPosition(item, &pos2, 7);
int v = (GetRandomControl() & 0x3F) + 192;
spark->xVel = v * (pos2.x - pos1.x) / 10;
spark->yVel = v * (pos2.y - pos1.y) / 10;
spark->zVel = v * (pos2.z - pos1.z) / 10;
spark->friction = 85;
spark->gravity = -16 - (GetRandomControl() & 0x1F);
spark->maxYvel = 0;
spark->flags = 538;
if ((GlobalCounter & 1) != 0)
{
v = 255;
spark->flags = 539;
}
spark->scalar = 3;
spark->dSize = (v * ((GetRandomControl() & 7) + 60)) / 256;
spark->sSize = spark->dSize / 8;
spark->size = spark->dSize / 8;
}
}
void InitialiseSentryGun(short itemNum)
{
ITEM_INFO* item = &g_Level.Items[itemNum];
ClearItem(itemNum);
item->itemFlags[0] = 0;
item->itemFlags[1] = 768;
item->itemFlags[2] = 0;
}
void SentryGunControl(short itemNum)
{
ITEM_INFO* item = &g_Level.Items[itemNum];
if (!CreatureActive(itemNum))
return;
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
AI_INFO info;
int c = 0;
if (creature)
{
// Flags set by the ID_MINE object?
if (item->meshBits & 0x40)
{
if (item->itemFlags[0])
{
PHD_VECTOR pos;
pos.x = sentryGunBite.x;
pos.y = sentryGunBite.y;
pos.z = sentryGunBite.z;
GetJointAbsPosition(item, &pos, sentryGunBite.meshNum);
TriggerDynamicLight(pos.x, pos.y, pos.z, 4 * item->itemFlags[0] + 12, 24, 16, 4);
item->itemFlags[0]--;
}
if (item->itemFlags[0] & 1)
item->meshBits |= 0x100;
else
item->meshBits &= ~0x100;
if (item->triggerFlags == 0)
{
item->pos.yPos -= 512;
CreatureAIInfo(item, &info);
item->pos.yPos += 512;
int deltaAngle = info.angle - creature->jointRotation[0];
info.ahead = true;
if (deltaAngle <= -ANGLE(90) || deltaAngle >= ANGLE(90))
info.ahead = false;
if (Targetable(item, &info))
{
if (info.distance < SQUARE(SECTOR(9)))
{
if (!g_Inventory.IsObjectPresentInInventory(ID_PUZZLE_ITEM5) && !item->itemFlags[0])
{
if (info.distance <= SQUARE(SECTOR(2)))
{
// Throw fire
SentryGunThrowFire(item);
c = phd_sin((GlobalCounter & 0x1F) * 2048) * 4096;
}
else
{
// Shot to Lara with bullets
c = 0;
item->itemFlags[0] = 2;
ShotLara(item, &info, &sentryGunBite, creature->jointRotation[0], 5);
SoundEffect(SFX_TR4_AUTOGUNS, &item->pos, 0);
item->itemFlags[2] += 256;
if (item->itemFlags[2] > 6144)
{
item->itemFlags[2] = 6144;
}
}
}
deltaAngle = c + info.angle - creature->jointRotation[0];
if (deltaAngle <= ANGLE(10))
{
if (deltaAngle < -ANGLE(10))
{
deltaAngle = -ANGLE(10);
}
}
else
{
deltaAngle = ANGLE(10);
}
creature->jointRotation[0] += deltaAngle;
CreatureJoint(item, 1, -info.xAngle);
}
}
item->itemFlags[2] -= 32;
if (item->itemFlags[2] < 0)
{
item->itemFlags[2] = 0;
}
creature->jointRotation[3] += item->itemFlags[2];
creature->jointRotation[2] += item->itemFlags[1];
if (creature->jointRotation[2] > ANGLE(90) ||
creature->jointRotation[2] < -ANGLE(90))
{
item->itemFlags[1] = -item->itemFlags[1];
}
}
else
{
// Stuck sentry gun
CreatureJoint(item, 0, (GetRandomControl() & 0x7FF) - 1024);
CreatureJoint(item, 1, ANGLE(45));
CreatureJoint(item, 2, (GetRandomControl() & 0x3FFF) - ANGLE(45));
}
}
else
{
ExplodingDeath(itemNum, -1, 257);
DisableBaddieAI(itemNum);
KillItem(itemNum);
item->flags |= 1u;
item->status = ITEM_DEACTIVATED;
RemoveAllItemsInRoom(item->roomNumber, ID_SMOKE_EMITTER_BLACK);
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos - 768, item->pos.zPos, 3, -2, 0, item->roomNumber);
for (int i = 0; i < 2; i++)
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos - 768, item->pos.zPos, 3, -1, 0, item->roomNumber);
SoundEffect(SFX_EXPLOSION1, &item->pos, 25165828);
SoundEffect(SFX_EXPLOSION2, &item->pos, 0);
}
}
}