mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-02 17:57:59 +03:00
1129 lines
No EOL
30 KiB
C++
1129 lines
No EOL
30 KiB
C++
#include "../newobjects.h"
|
|
#include "../../Game/items.h"
|
|
#include "../../Game/effect2.h"
|
|
#include "../../Game/lot.h"
|
|
#include "../../Game/Box.h"
|
|
#include "../../Game/sphere.h"
|
|
#include "../../Game/people.h"
|
|
#include "../../Game/draw.h"
|
|
#include "../../Game/effects.h"
|
|
#include "../../Game/misc.h"
|
|
|
|
#define MAX_TRIGGER_RANGE 0x4000
|
|
#define SMALL_FLASH 10
|
|
#define BIG_FLASH 16
|
|
#define BOLT_SPEED 384
|
|
|
|
enum { NOTHING, SUMMONING, KNOCKBACK };
|
|
enum { NORMAL_BOLT, LARGE_BOLT, SUMMON_BOLT };
|
|
enum { RIGHT_PRONG, ICONPOS, LEFT_PRONG };
|
|
enum { ATTACK_HEAD, ATTACK_HAND1, ATTACK_HAND2 };
|
|
|
|
enum londonboss_anims {
|
|
LONDONBOSS_EMPTY,
|
|
LONDONBOSS_STAND,
|
|
LONDONBOSS_WALK,
|
|
LONDONBOSS_RUN,
|
|
LONDONBOSS_SUMMON,
|
|
LONDONBOSS_BIGZAP,
|
|
LONDONBOSS_DEATH,
|
|
LONDONBOSS_LAUGH,
|
|
LONDONBOSS_LILZAP,
|
|
LONDONBOSS_VAULT2,
|
|
LONDONBOSS_VAULT3,
|
|
LONDONBOSS_VAULT4,
|
|
LONDONBOSS_GODOWN
|
|
};
|
|
|
|
#define LONDONBOSS_VAULT2_ANIM 9
|
|
#define LONDONBOSS_VAULT3_ANIM 18
|
|
#define LONDONBOSS_VAULT4_ANIM 15
|
|
#define LONDONBOSS_GODOWN_ANIM 21
|
|
#define LONDONBOSS_STND2SUM_ANIM 1
|
|
#define LONDONBOSS_SUMMON_ANIM 2
|
|
#define LONDONBOSS_GODOWN_ANIM 21
|
|
#define LONDONBOSS_VAULT_SHIFT 96
|
|
#define LONDONBOSS_AWARE_DISTANCE SQUARE(WALL_SIZE)
|
|
#define LONDONBOSS_WALK_TURN ANGLE(4)
|
|
#define LONDONBOSS_RUN_TURN ANGLE(7)
|
|
#define LONDONBOSS_WALK_RANGE SQUARE(WALL_SIZE)
|
|
#define LONDONBOSS_WALK_CHANCE 0x100
|
|
#define LONDONBOSS_LAUGH_CHANCE 0x100
|
|
#define LONDONBOSS_TURN ANGLE(2)
|
|
#define LONDONBOSS_DIE_ANIM 17
|
|
#define LONDONBOSS_FINAL_HEIGHT -11776
|
|
#define BIGZAP_TIMER 600
|
|
|
|
static long death_radii[5];
|
|
static long death_heights[5];
|
|
static long radii[5] = { 200,400,500,500,475 };
|
|
static long heights[5] = { -1536,-1280,-832,-384,0 };
|
|
static long dradii[5] = { 100 << 4,350 << 4,400 << 4,350 << 4,100 << 4 };
|
|
static long dheights1[5] = { -1536 - (768 << 3),-1152 - (384 << 3),-768,-384 + (384 << 3),0 + (768 << 3) };
|
|
static long dheights2[5] = { -1536,-1152,-768,-384,0 };
|
|
|
|
static BITE_INFO londonboss_points[3] = {
|
|
{16,56,356, 10}, // Right prong.
|
|
{-28,48,304, 10}, // Icon.
|
|
{-72,48,356, 10}, // Left prong.
|
|
};
|
|
|
|
static SHIELD_POINTS LondonBossShield[40];
|
|
static EXPLOSION_RING ExpRings[6];
|
|
static EXPLOSION_RING KBRings[3];
|
|
static BOSS_STRUCT bossdata;
|
|
|
|
static char links[20][4] = {
|
|
{ 0,0,1,2 },
|
|
{ 0,0,2,3, },
|
|
{ 0,0,3,4, },
|
|
{ 0,0,4,1, },
|
|
{ 1,2,5,6, },
|
|
{ 2,3,6,7, },
|
|
{ 3,4,7,8, },
|
|
{ 4,1,8,5, },
|
|
{ 1 + 4,2 + 4,5 + 4,6 + 4, },
|
|
{ 2 + 4,3 + 4,6 + 4,7 + 4, },
|
|
{ 3 + 4,4 + 4,7 + 4,8 + 4, },
|
|
{ 4 + 4,1 + 4,8 + 4,5 + 4, },
|
|
{ 1 + 8,2 + 8,5 + 8,6 + 8, },
|
|
{ 2 + 8,3 + 8,6 + 8,7 + 8, },
|
|
{ 3 + 8,4 + 8,7 + 8,8 + 8, },
|
|
{ 4 + 8,1 + 8,8 + 8,5 + 8, },
|
|
{ 1 + 12,2 + 12,5 + 12,5 + 12, },
|
|
{ 2 + 12,3 + 12,5 + 12,5 + 12, },
|
|
{ 3 + 12,4 + 12,5 + 12,5 + 12, },
|
|
{ 4 + 12,1 + 12,5 + 12,5 + 12, }
|
|
};
|
|
|
|
static char sumlinks[8][4] = {
|
|
{ 0,0,1,2 },
|
|
{ 0,0,2,3 },
|
|
{ 0,0,3,4 },
|
|
{ 0,0,4,1 },
|
|
{ 1,2,5,5 },
|
|
{ 2,3,5,5 },
|
|
{ 3,4,5,5 },
|
|
{ 4,1,5,5 }
|
|
};
|
|
|
|
static void DrawLondonBossShield(ITEM_INFO* item)
|
|
{
|
|
// PSX
|
|
}
|
|
|
|
static void DrawExplosionRings()
|
|
{
|
|
// PSX
|
|
}
|
|
|
|
static void DrawSummonRings()
|
|
{
|
|
// PSX
|
|
}
|
|
|
|
static void DrawKnockBackRings()
|
|
{
|
|
// PSX
|
|
}
|
|
|
|
static void TriggerLaserBolt(PHD_VECTOR* pos, ITEM_INFO* item, long type, short yang)
|
|
{
|
|
ITEM_INFO* bolt_item;
|
|
short item_number;
|
|
short angles[2];
|
|
|
|
/* Create a laser bolt and launch it on its way */
|
|
item_number = CreateItem();
|
|
if (item_number != NO_ITEM)
|
|
{
|
|
bolt_item = &Items[item_number];
|
|
|
|
bolt_item->objectNumber = ID_LASER_BOLT;
|
|
bolt_item->roomNumber = item->roomNumber;
|
|
bolt_item->pos.xPos = pos->x;
|
|
bolt_item->pos.yPos = pos->y;
|
|
bolt_item->pos.zPos = pos->z;
|
|
|
|
InitialiseItem(item_number);
|
|
|
|
if (type == SUMMON_BOLT)
|
|
{
|
|
bolt_item->pos.yPos += item->pos.yPos - 384;
|
|
bolt_item->pos.xRot = -pos->y << 5;
|
|
bolt_item->pos.yRot = GetRandomControl() << 1;
|
|
}
|
|
else
|
|
{
|
|
phd_GetVectorAngles(LaraItem->pos.xPos - pos->x, LaraItem->pos.yPos - STEP_SIZE - pos->y, LaraItem->pos.zPos - pos->z, angles);
|
|
bolt_item->pos.xRot = angles[1];
|
|
bolt_item->pos.yRot = yang;
|
|
bolt_item->pos.zRot = 0;
|
|
}
|
|
|
|
if (type != LARGE_BOLT)
|
|
{
|
|
bolt_item->speed = 16;
|
|
bolt_item->itemFlags[0] = -24;
|
|
bolt_item->itemFlags[1] = 4;
|
|
if (type == SUMMON_BOLT)
|
|
bolt_item->itemFlags[2] = 1; // Set the 'just draw front and back' flag.
|
|
}
|
|
else
|
|
{
|
|
bolt_item->speed = 24;
|
|
bolt_item->itemFlags[0] = 31;
|
|
bolt_item->itemFlags[1] = 16;
|
|
}
|
|
|
|
AddActiveItem(item_number);
|
|
}
|
|
}
|
|
|
|
static void TriggerPlasmaBallFlame(short fx_number, long type, long xv, long yv, long zv)
|
|
{
|
|
SPARKS* sptr;
|
|
long size;
|
|
long dx, dz;
|
|
|
|
dx = LaraItem->pos.xPos - Effects[fx_number].pos.xPos;
|
|
dz = LaraItem->pos.zPos - Effects[fx_number].pos.zPos;
|
|
|
|
if (dx < -MAX_TRIGGER_RANGE || dx > MAX_TRIGGER_RANGE || dz < -MAX_TRIGGER_RANGE || dz > MAX_TRIGGER_RANGE)
|
|
return;
|
|
|
|
sptr = &Sparks[GetFreeSpark()];
|
|
|
|
sptr->on = 1;
|
|
sptr->sG = 255;
|
|
sptr->sB = 48 + (GetRandomControl() & 31);
|
|
sptr->sR = 48;
|
|
|
|
sptr->dG = 192 + (GetRandomControl() & 63);
|
|
sptr->dB = 128 + (GetRandomControl() & 63);
|
|
sptr->dR = 32;
|
|
|
|
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
|
sptr->fadeToBlack = 8;
|
|
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
|
|
|
|
sptr->transType = 2;
|
|
|
|
sptr->extras = 0;
|
|
sptr->dynamic = -1;
|
|
|
|
sptr->x = ((GetRandomControl() & 15) - 8);
|
|
sptr->y = 0;
|
|
sptr->z = ((GetRandomControl() & 15) - 8);
|
|
|
|
sptr->xVel = xv + (GetRandomControl() & 255) - 128;
|
|
sptr->yVel = yv;
|
|
sptr->zVel = zv + (GetRandomControl() & 255) - 128;
|
|
sptr->friction = 5;
|
|
|
|
if (GetRandomControl() & 1)
|
|
{
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_FX;
|
|
sptr->rotAng = GetRandomControl() & 4095;
|
|
if (GetRandomControl() & 1)
|
|
sptr->rotAdd = -(GetRandomControl() & 15) - 16;
|
|
else
|
|
sptr->rotAdd = (GetRandomControl() & 15) + 16;
|
|
}
|
|
else
|
|
{
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX;
|
|
}
|
|
|
|
sptr->fxObj = fx_number;
|
|
sptr->scalar = 1;
|
|
size = (GetRandomControl() & 31) + 64;
|
|
sptr->size = sptr->sSize = size;
|
|
sptr->dSize = size >> 2;
|
|
sptr->gravity = sptr->maxYvel = 0;
|
|
}
|
|
|
|
static void TriggerPlasmaBall(ITEM_INFO* item, long type, PHD_VECTOR* pos1, short room_number, short angle)
|
|
{
|
|
FX_INFO* fx;
|
|
PHD_VECTOR pos;
|
|
short fx_number, angles[2];
|
|
long speed;
|
|
|
|
pos.x = pos1->x;
|
|
pos.y = pos1->y;
|
|
pos.z = pos1->z;
|
|
speed = (GetRandomControl() & 31) + 64;
|
|
angles[0] = angle + GetRandomControl() + 0x4000;
|
|
angles[1] = 0x2000;
|
|
|
|
fx_number = CreateNewEffect(room_number);
|
|
if (fx_number != NO_ITEM)
|
|
{
|
|
fx = &Effects[fx_number];
|
|
fx->pos.xPos = pos.x;
|
|
fx->pos.yPos = pos.y;
|
|
fx->pos.zPos = pos.z;
|
|
fx->pos.yRot = angles[0];
|
|
fx->pos.xRot = angles[1];
|
|
fx->objectNumber = ID_LASER_BOLT;
|
|
fx->speed = speed;
|
|
fx->fallspeed = 0;
|
|
fx->flag1 = 1;
|
|
if (type == 2)
|
|
fx->flag2 = 1;
|
|
else
|
|
fx->flag2 = 0;
|
|
}
|
|
}
|
|
|
|
static long KnockBackCollision(EXPLOSION_RING* erptr)
|
|
{
|
|
int radius, x, z, dist;
|
|
short angle, diff;
|
|
|
|
radius = erptr->radius;
|
|
x = LaraItem->pos.xPos - erptr->x;
|
|
z = LaraItem->pos.zPos - erptr->z;
|
|
if (x > 16000 || x < -16000 || z > 16000 || z < -16000)
|
|
dist = 0x7FFF;
|
|
else
|
|
dist = SQUARE(x) + SQUARE(z);
|
|
|
|
if (dist < SQUARE(radius))
|
|
{
|
|
/* Whump! Been hit by sphere - throw Lara through air */
|
|
LaraItem->hitPoints -= 200;
|
|
LaraItem->hitStatus = true;
|
|
angle = ATAN(z, x);
|
|
diff = LaraItem->pos.yRot - angle;
|
|
if (abs(diff) < 0x4000)
|
|
{
|
|
/* Facing away from blast */
|
|
LaraItem->speed = 75;
|
|
LaraItem->pos.yRot = angle;
|
|
}
|
|
else
|
|
{
|
|
/* Facing towards blast */
|
|
LaraItem->pos.yRot = short(angle - 0x8000);
|
|
LaraItem->speed = -75;
|
|
}
|
|
LaraItem->gravityStatus = true;
|
|
LaraItem->fallspeed = -50;
|
|
LaraItem->pos.xRot = LaraItem->pos.zRot = 0;
|
|
LaraItem->animNumber = 34;
|
|
LaraItem->frameNumber = GF(34, 0);
|
|
LaraItem->currentAnimState = 3;
|
|
LaraItem->goalAnimState = 3;
|
|
|
|
TriggerExplosionSparks(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, 3, -2, 2, LaraItem->roomNumber); // -2 = Set off a dynamic light controller.
|
|
for (x = 0; x < 3; x++)
|
|
TriggerPlasmaBall(LaraItem, 2, (PHD_VECTOR*)&LaraItem->pos, LaraItem->roomNumber, GetRandomControl() << 1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void ExplodeLondonBoss(ITEM_INFO* item)
|
|
{
|
|
SHIELD_POINTS* shptr;
|
|
long lp, lp1, angle, y, r, g, b;
|
|
|
|
if (bossdata.explode_count == 1 ||
|
|
bossdata.explode_count == 15 ||
|
|
bossdata.explode_count == 25 ||
|
|
bossdata.explode_count == 35 ||
|
|
bossdata.explode_count == 45 ||
|
|
bossdata.explode_count == 55) // Trigger explosion & ring ?
|
|
{
|
|
long x, y, z;
|
|
|
|
x = item->pos.xPos + ((GetRandomControl() & 1023) - 512);
|
|
y = item->pos.yPos - (GetRandomControl() & 1023) - 256;
|
|
z = item->pos.zPos + ((GetRandomControl() & 1023) - 512);
|
|
|
|
ExpRings[bossdata.ring_count].x = x;
|
|
ExpRings[bossdata.ring_count].y = y;
|
|
ExpRings[bossdata.ring_count].z = z;
|
|
ExpRings[bossdata.ring_count].on = true;
|
|
bossdata.ring_count++;
|
|
|
|
TriggerExplosionSparks(x, y, z, 3, -2, 2, 0); // -2 = Set off a dynamic light controller.
|
|
for (lp = 0; lp < 2; lp++)
|
|
TriggerExplosionSparks(x, y, z, 3, -1, 2, 0);
|
|
|
|
SoundEffect(SFX_TR3_BLAST_CIRCLE, &item->pos, PITCH_SHIFT | 0x800000);
|
|
}
|
|
|
|
// Adjust shield coordinates.
|
|
for (lp = 0; lp < 5; lp++)
|
|
{
|
|
if (bossdata.explode_count < 128) // Expand.
|
|
{
|
|
death_radii[lp] = (dradii[lp] >> 4) + (((dradii[lp]) * bossdata.explode_count) >> 7);
|
|
death_heights[lp] = dheights2[lp] + (((dheights1[lp] - dheights2[lp]) * bossdata.explode_count) >> 7);
|
|
}
|
|
}
|
|
|
|
// Setup shield coordinates.
|
|
shptr = &LondonBossShield[0]; // x,y,z,rgb.
|
|
|
|
for (lp = 0; lp < 5; lp++)
|
|
{
|
|
y = death_heights[lp];
|
|
angle = (Wibble << 3) & 511;
|
|
for (lp1 = 0; lp1 < 8; lp1++)
|
|
{
|
|
shptr->x = (rcossin_tbl[angle << 1] * death_radii[lp]) >> 11;
|
|
shptr->y = y;
|
|
shptr->z = (rcossin_tbl[(angle << 1) + 1] * death_radii[lp]) >> 11;
|
|
|
|
if (lp != 0 && lp != 4 && bossdata.explode_count < 64)
|
|
{
|
|
g = (GetRandomControl() & 31) + 224;
|
|
b = (g >> 2) + (GetRandomControl() & 63);
|
|
r = (GetRandomControl() & 63);
|
|
r = (r * (64 - bossdata.explode_count)) >> 6;
|
|
g = (g * (64 - bossdata.explode_count)) >> 6;
|
|
b = (b * (64 - bossdata.explode_count)) >> 6;
|
|
shptr->rgb = r | (g << 8) | (b << 16);
|
|
}
|
|
else
|
|
shptr->rgb = 0;
|
|
angle += 512;
|
|
angle &= 4095;
|
|
shptr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void LondonBossDie(short item_number)
|
|
{
|
|
ITEM_INFO* item;
|
|
item = &Items[item_number];
|
|
item->collidable = false;
|
|
item->hitPoints = -16384;
|
|
|
|
KillItem(item_number);
|
|
DisableBaddieAI(item_number);
|
|
|
|
item->flags |= ONESHOT; // Don't want bad guys triggered ever again
|
|
}
|
|
|
|
void ControlLaserBolts(short item_number)
|
|
{
|
|
FLOOR_INFO* floor;
|
|
ITEM_INFO* item;
|
|
PHD_VECTOR oldpos;
|
|
long g, b, rad;
|
|
short room_number, oldroom, hitlara;
|
|
int speed;
|
|
|
|
item = &Items[item_number];
|
|
|
|
oldpos.x = item->pos.xPos;
|
|
oldpos.y = item->pos.yPos;
|
|
oldpos.z = item->pos.zPos;
|
|
oldroom = item->roomNumber;
|
|
|
|
speed = (item->speed * COS(item->pos.xRot)) >> W2V_SHIFT;
|
|
item->pos.zPos += (speed * COS(item->pos.yRot)) >> W2V_SHIFT;
|
|
item->pos.xPos += (speed * SIN(item->pos.yRot)) >> W2V_SHIFT;
|
|
item->pos.yPos += -((item->speed * SIN(item->pos.xRot)) >> W2V_SHIFT);
|
|
if (item->speed < BOLT_SPEED)
|
|
item->speed += (item->speed >> 3) + 2;
|
|
|
|
if (item->itemFlags[2] && item->speed > (BOLT_SPEED >> 1))
|
|
{
|
|
item->itemFlags[3]++;
|
|
if (item->itemFlags[3] >= 16)
|
|
{
|
|
KillItem(item_number);
|
|
return;
|
|
}
|
|
}
|
|
|
|
room_number = item->roomNumber;
|
|
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &room_number);
|
|
|
|
if (item->roomNumber != room_number)
|
|
ItemNewRoom(item_number, room_number);
|
|
|
|
if (!item->itemFlags[2])
|
|
{
|
|
if (ItemNearLara(&item->pos, 400))
|
|
hitlara = 1;
|
|
else
|
|
hitlara = 0;
|
|
|
|
item->floor = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
if (hitlara || item->pos.yPos >= item->floor || item->pos.yPos <= GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos))
|
|
{
|
|
SoundEffect(SFX_EXPLOSION1, &item->pos, 0);
|
|
if (item->itemFlags[0] < 0)
|
|
rad = 2;
|
|
else
|
|
rad = 3;
|
|
TriggerExplosionSparks(oldpos.x, oldpos.y, oldpos.z, rad, -2, 2, item->roomNumber); // -2 = Set off a dynamic light controller.
|
|
for (g = 0; g < rad; g++)
|
|
TriggerExplosionSparks(oldpos.x, oldpos.y, oldpos.z, 2, -1, 2, item->roomNumber);
|
|
rad++;
|
|
for (g = 0; g < rad; g++)
|
|
TriggerPlasmaBall(item, 1, &oldpos, oldroom, item->pos.yRot);
|
|
|
|
if (hitlara)
|
|
{
|
|
LaraItem->hitPoints -= 30 + ((item->itemFlags[0] >= 0) << 9);
|
|
LaraItem->hitStatus = true;
|
|
}
|
|
else
|
|
{
|
|
long dx, dy, dz;
|
|
dx = SQUARE(LaraItem->pos.xPos - item->pos.xPos);
|
|
dy = SQUARE(LaraItem->pos.yPos - 256 - item->pos.yPos);
|
|
dz = SQUARE(LaraItem->pos.zPos - item->pos.zPos);
|
|
dx = SQRT_ASM(dx + dy + dz);
|
|
if (dx < 0x400)
|
|
{
|
|
LaraItem->hitPoints -= (0x400 - dx) >> (6 - ((item->itemFlags[0] >= 0) << 1));
|
|
LaraItem->hitStatus = true;
|
|
}
|
|
}
|
|
|
|
KillItem(item_number);
|
|
return;
|
|
}
|
|
}
|
|
g = 31 - (GetRandomControl() & 7);
|
|
b = g >> 1;
|
|
|
|
if (item->itemFlags[0] < 0) // Small bolt?
|
|
{
|
|
if (item->itemFlags[2])
|
|
{
|
|
g = (g * (16 - item->itemFlags[3])) >> 4;
|
|
b = (b * (16 - item->itemFlags[3])) >> 4;
|
|
}
|
|
|
|
rad = -item->itemFlags[0];
|
|
if (rad > SMALL_FLASH)
|
|
{
|
|
item->itemFlags[0]++;
|
|
item->itemFlags[1] += 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rad = item->itemFlags[0];
|
|
if (rad > BIG_FLASH)
|
|
{
|
|
item->itemFlags[0]--;
|
|
item->itemFlags[1] += 4;
|
|
}
|
|
}
|
|
|
|
TriggerDynamicLight(item->pos.xPos, item->pos.yPos, item->pos.zPos, rad, 0, g, b);
|
|
}
|
|
|
|
void ControlLondBossPlasmaBall(short fx_number)
|
|
{
|
|
FX_INFO* fx;
|
|
FLOOR_INFO* floor;
|
|
long speed;
|
|
long rnd, r, g, b, old_y;
|
|
byte radtab[2] = { 13,7 };
|
|
short room_number;
|
|
|
|
fx = &Effects[fx_number];
|
|
old_y = fx->pos.yPos;
|
|
|
|
fx->fallspeed++;
|
|
if (fx->speed > 8)
|
|
fx->speed -= 2;
|
|
if (fx->pos.xRot > -0x3c00)
|
|
fx->pos.xRot -= 0x100;
|
|
|
|
speed = (fx->speed * COS(fx->pos.xRot)) >> W2V_SHIFT;
|
|
fx->pos.zPos += (speed * COS(fx->pos.yRot)) >> W2V_SHIFT;
|
|
fx->pos.xPos += (speed * SIN(fx->pos.yRot)) >> W2V_SHIFT;
|
|
fx->pos.yPos += -((fx->speed * SIN(fx->pos.xRot)) >> W2V_SHIFT) + fx->fallspeed;
|
|
if ((Wibble & 15) == 0)
|
|
TriggerPlasmaBallFlame(fx_number, 0, 0, abs(old_y - fx->pos.yPos) << 3, 0);
|
|
|
|
room_number = fx->roomNumber;
|
|
floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &room_number);
|
|
if (fx->pos.yPos >= GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos) ||
|
|
fx->pos.yPos < GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos))
|
|
{
|
|
KillEffect(fx_number);
|
|
return;
|
|
}
|
|
|
|
if (Rooms[room_number].flags & ENV_FLAG_WATER)
|
|
{
|
|
KillEffect(fx_number);
|
|
return;
|
|
}
|
|
|
|
if (!fx->flag2 && ItemNearLara(&fx->pos, 200))
|
|
{
|
|
LaraItem->hitPoints -= 25;
|
|
LaraItem->hitStatus = true;
|
|
KillEffect(fx_number);
|
|
return;
|
|
}
|
|
|
|
if (room_number != fx->roomNumber)
|
|
EffectNewRoom(fx_number, LaraItem->roomNumber);
|
|
|
|
rnd = GetRandomControl();
|
|
g = 31 - ((rnd >> 4) & 3);
|
|
b = 24 - ((rnd >> 6) & 3);
|
|
r = rnd & 7;
|
|
TriggerDynamicLight(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, radtab[fx->flag1], r, g, b);
|
|
}
|
|
|
|
void InitialiseLondonBoss(short item_number)
|
|
{
|
|
SHIELD_POINTS* shptr;
|
|
long lp, lp1, angle, y;
|
|
|
|
bossdata.explode_count = 0;
|
|
bossdata.ring_count = 0;
|
|
bossdata.dead = 0;
|
|
bossdata.dropped_icon = 0;
|
|
|
|
shptr = &LondonBossShield[0];
|
|
|
|
for (lp = 0; lp < 5; lp++)
|
|
{
|
|
y = heights[lp];
|
|
angle = 0;
|
|
for (lp1 = 0; lp1 < 8; lp1++)
|
|
{
|
|
shptr->x = (rcossin_tbl[angle << 1] * radii[lp]) >> 11;
|
|
shptr->y = y;
|
|
shptr->z = (rcossin_tbl[(angle << 1) + 1] * radii[lp]) >> 11;
|
|
shptr->rgb = 0; // rgb.
|
|
angle += 512;
|
|
shptr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LondonBossControl(short item_number)
|
|
{
|
|
if (!CreatureActive(item_number))
|
|
return;
|
|
|
|
ITEM_INFO* item, *enemy;
|
|
CREATURE_INFO* londonboss;
|
|
short angle, head, tilt, lp, torso_y, torso_x;
|
|
int lara_dx, lara_dz, lara_dy;
|
|
AI_INFO info, lara_info;
|
|
PHD_VECTOR pos1, trident[3];
|
|
|
|
item = &Items[item_number];
|
|
londonboss = (CREATURE_INFO*)item->data;
|
|
head = angle = tilt = torso_x = torso_y = 0;
|
|
|
|
if (item->itemFlags[2])
|
|
{
|
|
if (item->itemFlags[2] == 1)
|
|
item->hitPoints = 0;
|
|
|
|
if (item->itemFlags[2] >= 12)
|
|
TriggerDynamicLight(item->pos.xPos, item->pos.yPos, item->pos.zPos, (GetRandomControl() & 3) + 8, 0, (GetRandomControl() & 7) + 8, (GetRandomControl() & 7) + 16);
|
|
else
|
|
TriggerDynamicLight(item->pos.xPos, item->pos.yPos, item->pos.zPos, 25 - (item->itemFlags[2] << 1) + (GetRandomControl() & 1), (16 - item->itemFlags[2]) + (GetRandomControl() & 7), 32 - item->itemFlags[2], 31);
|
|
}
|
|
|
|
for (lp = 0; lp < 3; lp++)
|
|
{
|
|
trident[lp].x = londonboss_points[lp].x;
|
|
trident[lp].y = londonboss_points[lp].y;
|
|
trident[lp].z = londonboss_points[lp].z;
|
|
GetJointAbsPosition(item, &trident[lp], londonboss_points[lp].meshNum);
|
|
}
|
|
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
if (item->currentAnimState != LONDONBOSS_DEATH)
|
|
{
|
|
item->animNumber = Objects[item->objectNumber].animIndex + LONDONBOSS_DIE_ANIM;
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LONDONBOSS_DEATH;
|
|
}
|
|
|
|
if (Anims[item->animNumber].frameEnd - item->frameNumber == 1)
|
|
{
|
|
item->frameNumber = Anims[item->animNumber].frameEnd - 1;
|
|
item->meshBits = 0; // Don't draw any of the boss while I'm killing it.
|
|
if (bossdata.explode_count == 0)
|
|
{
|
|
bossdata.ring_count = 0;
|
|
for (lp = 0; lp < 6; lp++)
|
|
{
|
|
ExpRings[lp].on = false;
|
|
ExpRings[lp].life = 32;
|
|
ExpRings[lp].radius = 512;
|
|
ExpRings[lp].speed = 128 + (lp << 5);
|
|
ExpRings[lp].xrot = ((GetRandomControl() & 511) - 256) << 4;
|
|
ExpRings[lp].zrot = ((GetRandomControl() & 511) - 256) << 4;
|
|
}
|
|
|
|
if (bossdata.dropped_icon == false)
|
|
{
|
|
//BossDropIcon(item_number);
|
|
bossdata.dropped_icon = true;
|
|
}
|
|
}
|
|
|
|
if (bossdata.explode_count < 256)
|
|
bossdata.explode_count++;
|
|
|
|
if (bossdata.explode_count > 128 && bossdata.ring_count == 6 && ExpRings[5].life == 0)
|
|
{
|
|
LondonBossDie(item_number);
|
|
bossdata.dead = true;
|
|
}
|
|
else
|
|
{
|
|
ExplodeLondonBoss(item);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (item->aiBits)
|
|
GetAITarget(londonboss);
|
|
|
|
CreatureAIInfo(item, &info);
|
|
|
|
if (londonboss->enemy == LaraItem)
|
|
{
|
|
lara_info.angle = info.angle;
|
|
lara_info.distance = info.distance;
|
|
lara_info.xAngle = info.xAngle;
|
|
}
|
|
else
|
|
{
|
|
lara_dz = LaraItem->pos.zPos - item->pos.zPos;
|
|
lara_dx = LaraItem->pos.xPos - item->pos.xPos;
|
|
lara_dy = item->pos.yPos - LaraItem->pos.yPos;
|
|
|
|
lara_info.angle = ATAN(lara_dz, lara_dx) - item->pos.yRot; //only need to fill out the bits of lara_info that will be needed by TargetVisible
|
|
lara_info.distance = lara_dz * lara_dz + lara_dx * lara_dx;
|
|
if (abs(lara_dx) > abs(lara_dz))
|
|
lara_info.xAngle = ATAN(abs(lara_dx) + (abs(lara_dz) >> 1), lara_dy);
|
|
else
|
|
lara_info.xAngle = ATAN(abs(lara_dz) + (abs(lara_dx) >> 1), lara_dy);
|
|
|
|
}
|
|
|
|
GetCreatureMood(item, &info, VIOLENT);
|
|
CreatureMood(item, &info, VIOLENT);
|
|
angle = CreatureTurn(item, londonboss->maximumTurn);
|
|
|
|
enemy = londonboss->enemy; //TargetVisible uses enemy, so need to fill this in as lara if we're doing other things
|
|
londonboss->enemy = LaraItem;
|
|
if (item->hitStatus || lara_info.distance < LONDONBOSS_AWARE_DISTANCE || TargetVisible(item, &lara_info) || LaraItem->pos.yPos < item->pos.yPos)
|
|
AlertAllGuards(item_number);
|
|
londonboss->enemy = enemy;
|
|
|
|
if (LaraItem->pos.yPos < item->pos.yPos)
|
|
londonboss->hurtByLara = true;
|
|
|
|
if (item->timer > 0)
|
|
item->timer--;
|
|
|
|
item->hitPoints = 300;
|
|
|
|
switch (item->currentAnimState)
|
|
{
|
|
case LONDONBOSS_LAUGH:
|
|
if (abs(lara_info.angle) < LONDONBOSS_WALK_TURN)
|
|
item->pos.yRot += lara_info.angle;
|
|
else if (lara_info.angle < 0)
|
|
item->pos.yRot -= LONDONBOSS_WALK_TURN;
|
|
else
|
|
item->pos.yRot += LONDONBOSS_WALK_TURN;
|
|
|
|
if (londonboss->alerted)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_STAND;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case LONDONBOSS_STAND:
|
|
londonboss->flags = 0;
|
|
londonboss->maximumTurn = 0;
|
|
|
|
if (londonboss->reachedGoal) //She's found this ambush point, so set up the next one
|
|
{
|
|
londonboss->reachedGoal = false;
|
|
item->aiBits |= AMBUSH;
|
|
item->itemFlags[3] += 0x2000;
|
|
}
|
|
|
|
head = lara_info.angle;
|
|
|
|
if (item->aiBits & GUARD)
|
|
{
|
|
if ((head < -0x3000 || head > 0x3000) && item->pos.yPos > LONDONBOSS_FINAL_HEIGHT)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
londonboss->maximumTurn = LONDONBOSS_WALK_TURN;
|
|
}
|
|
break;
|
|
|
|
head = AIGuard(londonboss);
|
|
if (!(GetRandomControl() & 0xF))
|
|
item->goalAnimState = LONDONBOSS_LAUGH;
|
|
break;
|
|
}
|
|
else if ((item->pos.yPos <= LONDONBOSS_FINAL_HEIGHT || item->pos.yPos < LaraItem->pos.yPos) && !(GetRandomControl() & 0xF) && !bossdata.charged && item->timer)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_LAUGH;
|
|
}
|
|
else if (londonboss->reachedGoal || LaraItem->pos.yPos > item->pos.yPos || item->pos.yPos <= LONDONBOSS_FINAL_HEIGHT)
|
|
{
|
|
if (bossdata.charged)
|
|
item->goalAnimState = LONDONBOSS_BIGZAP;
|
|
else if (!item->timer)
|
|
item->goalAnimState = LONDONBOSS_SUMMON;
|
|
else
|
|
item->goalAnimState = LONDONBOSS_LILZAP;
|
|
}
|
|
else if (item->aiBits & PATROL1)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
}
|
|
else if (londonboss->mood == ESCAPE_MOOD || item->pos.yPos > LaraItem->pos.yPos)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_RUN;
|
|
}
|
|
else if (londonboss->mood == BORED_MOOD || ((item->aiBits & FOLLOW) && (londonboss->reachedGoal || lara_info.distance > SQUARE(WALL_SIZE * 2))))
|
|
{
|
|
if (item->requiredAnimState)
|
|
item->goalAnimState = item->requiredAnimState;
|
|
else if (info.ahead)
|
|
item->goalAnimState = LONDONBOSS_STAND;
|
|
else
|
|
item->goalAnimState = LONDONBOSS_RUN;
|
|
}
|
|
else if (info.bite && info.distance < LONDONBOSS_WALK_RANGE)
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
else
|
|
item->goalAnimState = LONDONBOSS_RUN;
|
|
break;
|
|
|
|
case LONDONBOSS_WALK:
|
|
head = lara_info.angle;
|
|
londonboss->flags = 0;
|
|
londonboss->maximumTurn = LONDONBOSS_WALK_TURN;
|
|
|
|
if (item->aiBits & GUARD || (londonboss->reachedGoal && !(item->aiBits & FOLLOW)))
|
|
{
|
|
|
|
}
|
|
else if (item->aiBits & PATROL1)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
head = 0;
|
|
}
|
|
else if (londonboss->mood == ESCAPE_MOOD)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_RUN;
|
|
}
|
|
else if (londonboss->mood == BORED_MOOD)
|
|
{
|
|
if (GetRandomControl() < LONDONBOSS_LAUGH_CHANCE)
|
|
{
|
|
item->requiredAnimState = LONDONBOSS_LAUGH;
|
|
item->goalAnimState = LONDONBOSS_STAND;
|
|
}
|
|
}
|
|
else if (info.distance > LONDONBOSS_WALK_RANGE)
|
|
{
|
|
item->goalAnimState = LONDONBOSS_RUN;
|
|
}
|
|
break;
|
|
|
|
case LONDONBOSS_RUN:
|
|
if (info.ahead)
|
|
head = info.angle;
|
|
|
|
londonboss->maximumTurn = LONDONBOSS_RUN_TURN;
|
|
tilt = angle / 2;
|
|
|
|
if (item->aiBits & GUARD || (londonboss->reachedGoal && !(item->aiBits & FOLLOW)))
|
|
item->goalAnimState = LONDONBOSS_STAND;
|
|
else if (londonboss->mood == ESCAPE_MOOD)
|
|
break;
|
|
else if ((item->aiBits & FOLLOW) && (londonboss->reachedGoal || lara_info.distance > SQUARE(WALL_SIZE * 2)))
|
|
item->goalAnimState = LONDONBOSS_STAND;
|
|
else if (londonboss->mood == BORED_MOOD)
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
else if (info.ahead && info.distance < LONDONBOSS_WALK_RANGE)
|
|
item->goalAnimState = LONDONBOSS_WALK;
|
|
break;
|
|
|
|
case LONDONBOSS_SUMMON:
|
|
head = lara_info.angle;
|
|
|
|
if (londonboss->reachedGoal) //She's found this ambush point, so set up the next one
|
|
{
|
|
londonboss->reachedGoal = false;
|
|
item->aiBits = AMBUSH;
|
|
item->itemFlags[3] += 0x2000;
|
|
}
|
|
|
|
if (item->animNumber == Objects[item->objectNumber].animIndex + LONDONBOSS_STND2SUM_ANIM)
|
|
{
|
|
if (item->frameNumber == Anims[item->animNumber].frameBase)
|
|
{
|
|
bossdata.hp_counter = item->hitPoints;
|
|
item->timer = BIGZAP_TIMER;
|
|
}
|
|
else if (item->hitStatus && item->goalAnimState != LONDONBOSS_STAND) //if she takes *any* damage during the stand2summon anim, break off the summoning
|
|
{
|
|
StopSoundEffect(352);
|
|
SoundEffect(353, &item->pos, 0); // Take Hit
|
|
SoundEffect(355, &item->pos, 0); // Summon wind-down noise
|
|
|
|
item->goalAnimState = LONDONBOSS_STAND; //Put a condition in here so she can do more than one attack per waypoint?
|
|
}
|
|
}
|
|
else if (item->animNumber == Objects[item->objectNumber].animIndex + LONDONBOSS_SUMMON_ANIM && item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
bossdata.charged = true;
|
|
|
|
if (abs(lara_info.angle) < LONDONBOSS_WALK_TURN)
|
|
item->pos.yRot += lara_info.angle;
|
|
else if (lara_info.angle < 0)
|
|
item->pos.yRot -= LONDONBOSS_WALK_TURN;
|
|
else
|
|
item->pos.yRot += LONDONBOSS_WALK_TURN;
|
|
|
|
// Summon.
|
|
if ((Wibble & 7) == 0)
|
|
{
|
|
pos1.x = item->pos.xPos;
|
|
pos1.y = (GetRandomControl() & 511) - 256;
|
|
pos1.z = item->pos.zPos;
|
|
TriggerLaserBolt(&pos1, item, SUMMON_BOLT, 0);
|
|
|
|
for (lp = 0; lp < 6; lp++)
|
|
{
|
|
long rnd;
|
|
|
|
if (!ExpRings[lp].on)
|
|
{
|
|
ExpRings[lp].on = true;
|
|
ExpRings[lp].life = 64;
|
|
ExpRings[lp].speed = (GetRandomControl() & 15) + 16;
|
|
ExpRings[lp].x = item->pos.xPos;
|
|
ExpRings[lp].y = item->pos.yPos + 128 - (rnd = (GetRandomControl() & 1023));
|
|
ExpRings[lp].z = item->pos.zPos;
|
|
ExpRings[lp].xrot = ((GetRandomControl() & 511) - 256) << 4;
|
|
ExpRings[lp].zrot = ((GetRandomControl() & 511) - 256) << 4;
|
|
ExpRings[lp].radius = (1024 + (1024 - (abs(rnd - 512))));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
londonboss->maximumTurn = 0;
|
|
break;
|
|
|
|
case LONDONBOSS_BIGZAP:
|
|
if (londonboss->reachedGoal) //She's found this ambush point, so set up the next one
|
|
{
|
|
londonboss->reachedGoal = false;
|
|
item->aiBits = AMBUSH;
|
|
item->itemFlags[3] += 0x2000;
|
|
}
|
|
bossdata.charged = false;
|
|
if (abs(lara_info.angle) < LONDONBOSS_WALK_TURN)
|
|
item->pos.yRot += lara_info.angle;
|
|
else if (lara_info.angle < 0)
|
|
item->pos.yRot -= LONDONBOSS_WALK_TURN;
|
|
else
|
|
item->pos.yRot += LONDONBOSS_WALK_TURN;
|
|
|
|
torso_y = lara_info.angle;
|
|
torso_x = lara_info.xAngle;
|
|
|
|
londonboss->maximumTurn = 0;
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameBase + 36)
|
|
{
|
|
TriggerLaserBolt(&trident[RIGHT_PRONG], item, NORMAL_BOLT, item->pos.yRot + 0x200);
|
|
TriggerLaserBolt(&trident[ICONPOS], item, LARGE_BOLT, item->pos.yRot);
|
|
TriggerLaserBolt(&trident[LEFT_PRONG], item, NORMAL_BOLT, item->pos.yRot - 0x200);
|
|
}
|
|
|
|
break;
|
|
|
|
case LONDONBOSS_LILZAP:
|
|
if (londonboss->reachedGoal) //She's found this ambush point, so set up the next one
|
|
{
|
|
londonboss->reachedGoal = false;
|
|
item->aiBits = AMBUSH;
|
|
item->itemFlags[3] += 0x2000;
|
|
}
|
|
|
|
if (abs(lara_info.angle) < LONDONBOSS_WALK_TURN)
|
|
item->pos.yRot += lara_info.angle;
|
|
else if (lara_info.angle < 0)
|
|
item->pos.yRot -= LONDONBOSS_WALK_TURN;
|
|
else
|
|
item->pos.yRot += LONDONBOSS_WALK_TURN;
|
|
|
|
torso_y = lara_info.angle;
|
|
torso_x = lara_info.xAngle;
|
|
|
|
londonboss->maximumTurn = 0;
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameBase + 14)
|
|
{
|
|
TriggerLaserBolt(&trident[RIGHT_PRONG], item, NORMAL_BOLT, item->pos.yRot + 0x200);
|
|
TriggerLaserBolt(&trident[LEFT_PRONG], item, NORMAL_BOLT, item->pos.yRot - 0x200);
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
CreatureTilt(item, tilt);
|
|
CreatureJoint(item, 0, torso_y);
|
|
CreatureJoint(item, 1, torso_x);
|
|
CreatureJoint(item, 2, head);
|
|
|
|
if ((item->currentAnimState < LONDONBOSS_VAULT2 || item->currentAnimState > LONDONBOSS_GODOWN) && item->currentAnimState != LONDONBOSS_DEATH)
|
|
{
|
|
switch (CreatureVault(item_number, angle, 2, LONDONBOSS_VAULT_SHIFT))
|
|
{
|
|
case 2:
|
|
/* Half block jump */
|
|
londonboss->maximumTurn = 0;
|
|
item->animNumber = Objects[item->objectNumber].animIndex + LONDONBOSS_VAULT2_ANIM;
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LONDONBOSS_VAULT2;
|
|
break;
|
|
|
|
case 3:
|
|
/* 3/4 block jump */
|
|
londonboss->maximumTurn = 0;
|
|
item->animNumber = Objects[item->objectNumber].animIndex + LONDONBOSS_VAULT3_ANIM;
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LONDONBOSS_VAULT3;
|
|
break;
|
|
|
|
case 4:
|
|
/* Full block jump */
|
|
londonboss->maximumTurn = 0;
|
|
item->animNumber = Objects[item->objectNumber].animIndex + LONDONBOSS_VAULT4_ANIM;
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LONDONBOSS_VAULT4;
|
|
break;
|
|
case -4:
|
|
/* Full block fall */
|
|
londonboss->maximumTurn = 0;
|
|
item->animNumber = Objects[item->objectNumber].animIndex + LONDONBOSS_GODOWN_ANIM;
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LONDONBOSS_GODOWN;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
londonboss->maximumTurn = 0;
|
|
CreatureAnimation(item_number, angle, 0);
|
|
}
|
|
|
|
// Do light.
|
|
{
|
|
long g, b;
|
|
|
|
g = abs(rcossin_tbl[item->itemFlags[1] << 7] >> 7);
|
|
g += (GetRandomControl() & 7);
|
|
if (g > 31)
|
|
g = 31;
|
|
b = g >> 1;
|
|
TriggerDynamicLight(trident[ICONPOS].x, trident[ICONPOS].y, trident[ICONPOS].z, 10, 0, g >> 1, b >> 1);
|
|
item->itemFlags[1]++;
|
|
item->itemFlags[1] &= 63;
|
|
}
|
|
|
|
// Knockback.
|
|
if (item->hitPoints > 0 && item->itemFlags[0] != KNOCKBACK && LaraItem->hitPoints > 0)
|
|
{
|
|
long dx, dy, dz;
|
|
|
|
dx = LaraItem->pos.xPos - item->pos.xPos;
|
|
dy = LaraItem->pos.yPos - 256 - item->pos.yPos;
|
|
dz = LaraItem->pos.zPos - item->pos.zPos;
|
|
|
|
if (dx > 8000 || dx < -8000 || dy > 8000 || dy < -8000 || dz > 8000 || dz < -8000)
|
|
{
|
|
dx = 0xFFF;
|
|
}
|
|
else
|
|
{
|
|
dx = SQUARE(dx);
|
|
dy = SQUARE(dy);
|
|
dz = SQUARE(dz);
|
|
dx = SQRT_ASM(dx + dy + dz);
|
|
}
|
|
|
|
if (dx < 0xB00)
|
|
{
|
|
item->itemFlags[0] = KNOCKBACK;
|
|
for (lp = 0; lp < 3; lp++)
|
|
{
|
|
KBRings[lp].on = true;
|
|
KBRings[lp].life = 32;
|
|
KBRings[lp].speed = 64 + ((lp == 1) << 4);
|
|
KBRings[lp].x = item->pos.xPos;
|
|
KBRings[lp].y = item->pos.yPos - 384 - 128 + (lp << 7);
|
|
KBRings[lp].z = item->pos.zPos;
|
|
KBRings[lp].xrot = KBRings[lp].zrot = 0;
|
|
KBRings[lp].radius = 512 + ((lp == 1) << 8);
|
|
}
|
|
}
|
|
}
|
|
else if (KBRings[0].on == false && KBRings[1].on == false && KBRings[2].on == false)
|
|
{
|
|
item->itemFlags[0] = 0;
|
|
}
|
|
}
|
|
|
|
void S_DrawLondonBoss(ITEM_INFO* item)
|
|
{
|
|
DrawAnimatingItem(item);
|
|
|
|
if (bossdata.explode_count)
|
|
{
|
|
DrawLondonBossShield(item);
|
|
DrawExplosionRings();
|
|
}
|
|
else
|
|
{
|
|
DrawSummonRings();
|
|
DrawKnockBackRings();
|
|
}
|
|
|
|
if (item->hitPoints <= 0 && bossdata.explode_count == 0)
|
|
{
|
|
//UpdateElectricityPoints();
|
|
//LaraElectricDeath(0, item);
|
|
//LaraElectricDeath(1, item);
|
|
}
|
|
} |