Fixed and Implemented TonyBoss

This commit is contained in:
TokyoSU 2020-05-14 18:39:17 +02:00
parent 71bdf876b0
commit 6d4cfeef98
13 changed files with 421 additions and 1323 deletions

View file

@ -3105,7 +3105,7 @@ int ExplodeItemNode(ITEM_INFO* item, int Node, int NoXZVel, int bits)
ShatterItem.sphere.x = CreatureSpheres[Node].x; ShatterItem.sphere.x = CreatureSpheres[Node].x;
ShatterItem.sphere.y = CreatureSpheres[Node].y; ShatterItem.sphere.y = CreatureSpheres[Node].y;
ShatterItem.sphere.z = CreatureSpheres[Node].z; ShatterItem.sphere.z = CreatureSpheres[Node].z;
ShatterItem.il = (ITEM_LIGHT *) &item->legacyLightData; ShatterItem.il = (ITEM_LIGHT *) &item->legacyLightData; // TODO: remove it or at last change it with the new renderer light...
ShatterItem.flags = item->objectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0; ShatterItem.flags = item->objectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
ShatterImpactData.impactDirection = Vector3(0, -1, 0); ShatterImpactData.impactDirection = Vector3(0, -1, 0);
ShatterImpactData.impactLocation = { (float)ShatterItem.sphere.x,(float)ShatterItem.sphere.y,(float)ShatterItem.sphere.z }; ShatterImpactData.impactLocation = { (float)ShatterItem.sphere.x,(float)ShatterItem.sphere.y,(float)ShatterItem.sphere.z };

View file

@ -33,53 +33,75 @@ int SmokeCountR;
//int SmokeWindZ; //int SmokeWindZ;
int SplashCount = 0; int SplashCount = 0;
SPARKS Sparks[MAX_SPARKS]; SPARKS Sparks[MAX_SPARKS];
PHD_VECTOR NodeVectors[16]; PHD_VECTOR NodeVectors[MAX_NODE];
NODEOFFSET_INFO NodeOffsets[16] = { NODEOFFSET_INFO NodeOffsets[MAX_NODE] = {
{ -0x10, 0x28, 0xA0, -0xE, 0 }, { -16, 40, 160, -14, false }, // TR5 offset 0
{ -0x10, -8, 0xA0, 0, 0 }, { -16, -8, 160, 0, false }, // TR5 offset 1
{ 0, 0, 0x100, 8, 0 }, { 0, 0, 256, 8, false }, // TR5 offset 2
{ 0, 0, 0x100, 0x11, 0 }, { 0, 0, 256, 17, false }, // TR5 offset 3
{ 0, 0, 0x100, 0x1A, 0 }, { 0, 0, 256, 26, false }, // TR5 offset 4
{ 0, 0x90, 0x28, 0xA, 0 }, { 0, 144, 40, 10, false }, // TR5 offset 5
{ -0x28, 0x40, 0x168, 0xE, 0 }, { -40, 64, 360, 14, false }, // TR5 offset 6
{ 0, -0x258, -0x28, 0, 0 }, { 0, -600, -40, 0, false }, // TR5 offset 7
{ 0, 0x20, 0x10, 9, 0 }, { 0, 32, 16, 9, false }, // TR5 offset 8
{ 0 }, { 0, 340, 0, 7, false }, // TR3 offset 0
{ 0 }, { 0, 0, -96, 10, false }, // TR3 offset 1
{ 0 }, { 13, 48, 320, 13, false }, // TR3 offset 2
{ 0 }, { 0, -256, 0, 5, false }, // TR3 offset 3
{ 0 }, { 0, 64, 0, 10, false }, // TR3 offset 4 // tony left
{ 0 }, { 0, 64, 0, 13, false }, // TR3 offset 5 // tony right
{ 0 } { -32, -16, -192, 13, false }, // TR3 offset 6
{ -64, 410, 0, 20, false }, // TR3 offset 7
{ 64, 410, 0, 23, false }, // TR3 offset 8
{ -160, -8, 16, 5, false }, // TR3 offset 9
{ -160, -8, 16, 9, false }, // TR3 offset 10
{ -160, -8, 16, 13, false }, // TR3 offset 11
{ 0, 0, 0, 0, false }, // TR3 offset 12
{ 0, 0, 0, 0, false }, // Empty
}; };
extern GameFlow* g_GameFlow; extern GameFlow* g_GameFlow;
void DetatchSpark(int num, int type)//32D8C, 3328C (F) void DetatchSpark(int num, int type)// (F) (D)
{ {
FX_INFO* fx = &Effects[num]; FX_INFO* fx;
ITEM_INFO* item = &Items[num]; ITEM_INFO* item;
SPARKS* sptr = &Sparks[0]; SPARKS* sptr;
sptr = &Sparks[0];
for (int lp = 0; lp < MAX_SPARKS; lp++, sptr++) for (int lp = 0; lp < MAX_SPARKS; lp++, sptr++)
{ {
if (sptr->on && sptr->flags & type && sptr->fxObj == num) if (sptr->on && (sptr->flags & type) && sptr->fxObj == num)
{ {
if (type == 64) if (type == SP_FX)
{ {
sptr->x += fx->pos.xPos; if (sptr->flags & SP_USEFXOBJPOS)
sptr->y += fx->pos.yPos; {
sptr->z += fx->pos.zPos; sptr->on = FALSE;
}
sptr->flags &= 0xBF; else
{
fx = &Effects[num];
sptr->x += fx->pos.xPos;
sptr->y += fx->pos.yPos;
sptr->z += fx->pos.zPos;
sptr->flags &= ~SP_FX;
}
} }
else if (type == 128) else if (type == SP_ITEM)
{ {
sptr->x += item->pos.xPos; if (sptr->flags & SP_USEFXOBJPOS)
sptr->y += item->pos.yPos; {
sptr->z += item->pos.zPos; sptr->on = FALSE;
}
sptr->flags &= 0x7F; else
{
item = &Items[num];
sptr->x += item->pos.xPos;
sptr->y += item->pos.yPos;
sptr->z += item->pos.zPos;
sptr->flags &= ~SP_ITEM;
}
} }
} }
} }

View file

@ -2,6 +2,7 @@
#include <d3d11.h> #include <d3d11.h>
#include "..\Global\global.h" #include "..\Global\global.h"
#define MAX_NODE 23
#define RIPPLE_FLAG_BLOOD 0x80 #define RIPPLE_FLAG_BLOOD 0x80
#define RIPPLE_FLAG_RAND_POS 0x40 #define RIPPLE_FLAG_RAND_POS 0x40
#define RIPPLE_FLAG_RAND_ROT 0x20 #define RIPPLE_FLAG_RAND_ROT 0x20
@ -40,8 +41,8 @@ extern SPLASH_SETUP SplashSetup;
extern int SmokeWeapon; extern int SmokeWeapon;
extern int SmokeCountL; extern int SmokeCountL;
extern int SmokeCountR; extern int SmokeCountR;
extern PHD_VECTOR NodeVectors[16]; extern PHD_VECTOR NodeVectors[MAX_NODE];
extern NODEOFFSET_INFO NodeOffsets[16]; extern NODEOFFSET_INFO NodeOffsets[MAX_NODE];
void DetatchSpark(int num, int type); void DetatchSpark(int num, int type);
int GetFreeSpark(); int GetFreeSpark();

View file

@ -60,9 +60,9 @@
#define MAX_DRAW_STATICS 16384 #define MAX_DRAW_STATICS 16384
#define MAX_BONES 32 #define MAX_BONES 32
#define MAX_SPRITES 16384 #define MAX_SPRITES 16384
#define MAX_SPARKS 1024 // 128 normally #define MAX_SPARKS 1024
#define MAX_SPARKS_FIRE 20 #define MAX_SPARKS_FIRE 20
#define MAX_FIRE_LIST 32 // FIRE_SPARKS list #define MAX_FIRE_LIST 32
#define MAX_SPARKS_SMOKE 32 #define MAX_SPARKS_SMOKE 32
#define MAX_SPARKS_BLOOD 32 #define MAX_SPARKS_BLOOD 32
#define MAX_ENERGY_ARCS 256 #define MAX_ENERGY_ARCS 256
@ -111,7 +111,7 @@ constexpr auto MAX_SPLASH = 8;
#define SP_EXPDEF 512 #define SP_EXPDEF 512
#define SP_USEFXOBJPOS 1024 #define SP_USEFXOBJPOS 1024
#define SP_UNDERWEXP 2048 #define SP_UNDERWEXP 2048
#define SP_NODEATTATCH 4096 #define SP_NODEATTACH 4096
#define SP_PLASMAEXP 8192 #define SP_PLASMAEXP 8192
#define SD_EXPLOSION 1 #define SD_EXPLOSION 1

View file

@ -794,7 +794,8 @@ typedef enum GAME_OBJECT_ID
ID_CIVVY, ID_CIVVY,
ID_MUTANT2, ID_MUTANT2,
ID_LIZARD, // TR3 - 35 ID_LIZARD, // TR3 - 35
ID_TONY_BOSS, ID_TONY_BOSS, // TR3 - Not Finished
ID_TONY_BOSS_FLAME, // TR3 Tony Flame Controller
ID_PUNA_BOSS, // TR3 - 36 ID_PUNA_BOSS, // TR3 - 36
ID_SOPHIA_LEE_BOSS, // TR3 - 57 ID_SOPHIA_LEE_BOSS, // TR3 - 57
ID_LASER_BOLT, ID_LASER_BOLT,
@ -817,7 +818,7 @@ typedef enum GAME_OBJECT_ID
ID_WRAITH4, ID_WRAITH4,
ID_LARA_DOUBLE, // TR4 - OK - Needs testing ID_LARA_DOUBLE, // TR4 - OK - Needs testing
ID_COMPY, ID_COMPY,
ID_HYDRA = 274, ID_HYDRA,
ID_GUARDIAN, ID_GUARDIAN,
ID_SCIENTIST, ID_SCIENTIST,
ID_MERCENARY, ID_MERCENARY,
@ -833,6 +834,9 @@ typedef enum GAME_OBJECT_ID
ID_ROMAN_GOD1, ID_ROMAN_GOD1,
ID_ROMAN_GOD2, ID_ROMAN_GOD2,
ID_LAGOON_WITCH, ID_LAGOON_WITCH,
ID_BOSS_SHIELD,
ID_BOSS_EXPLOSION_SHOCKWAVE,
ID_BOSS_EXPLOSION_RING,
/* Traps / Doors */ /* Traps / Doors */
ID_SPRINGBOARD = 320, ID_SPRINGBOARD = 320,

View file

@ -506,7 +506,7 @@ void TriggerPilotFlame(int itemnum)
spark->yVel = -(GetRandomControl() & 3); spark->yVel = -(GetRandomControl() & 3);
spark->zVel = (GetRandomControl() & 31) - 16; spark->zVel = (GetRandomControl() & 31) - 16;
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTATCH; spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
spark->fxObj = itemnum; spark->fxObj = itemnum;
spark->nodeNumber = 0; spark->nodeNumber = 0;
spark->friction = 4; spark->friction = 4;

File diff suppressed because it is too large Load diff

View file

@ -9,19 +9,30 @@
#include "..\..\Specific\level.h" #include "..\..\Specific\level.h"
#include "../../Specific/setup.h" #include "../../Specific/setup.h"
#include "../../Game/lara.h" #include "../../Game/lara.h"
#include "../../Game/traps.h"
#include "../../Game/sound.h"
// TODO: custom render for DrawExplosionRings() and DrawTonyBossShield() enum TonyFlameType
// TODO: add flame effect for tony, check TriggerXX() function.
enum TONY_EFFECT
{ {
ROCKZAPPL = 0, // To ceiling from left hand T_NOFLAME = 0,
ROCKZAPPR, // To ceiling from right hand T_ROCKZAPPL = 0, // To ceiling from left hand
ZAPP, // From right hand. T_ROCKZAPPR, // To ceiling from right hand
DROPPER, // From ceiling. T_ZAPP, // From right hand.
ROCKZAPPDEBRIS, // Small bits from ceiling explosions. T_DROPPER, // From ceiling.
ZAPPDEBRIS, // Small bits from hand flame explosions. T_ROCKZAPPDEBRIS, // Small bits from ceiling explosions.
DROPPERDEBRIS, // Small bits from droppers explosions. T_ZAPPDEBRIS, // Small bits from hand flame explosions.
T_DROPPERDEBRIS // Small bits from droppers explosions.
};
struct TONY_FLAME
{
bool on;
PHD_VECTOR pos;
int fallspeed;
int speed;
short y_rot;
short room_number;
TonyFlameType type;
}; };
enum TONY_STATE enum TONY_STATE
@ -35,62 +46,72 @@ enum TONY_STATE
TONYBOSS_DEATH TONYBOSS_DEATH
}; };
static long death_radii[5]; static BOSS_STRUCT BossData; // exclusive for tony unlike TR3
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 SHIELD_POINTS TonyBossShield[40]; // x,y,z,rgb. #define TONYBOSS_TURN ANGLE(2.0f)
static EXPLOSION_RING ExpRings[7]; #define TONYBOSS_HITS 100
static BOSS_STRUCT bossdata; // exclusive for tony unlike TR3 #define MAX_TONY_TRIGGER_RANGE 0x4000
#define TONYBOSS_TURN (ONE_DEGREE * 2) static void TriggerTonyEffect(const TONY_FLAME flame)
#define TONYBOSS_HITS 100 {
#define MAX_TONY_TRIGGER_RANGE 0x4000 short fx_number = CreateNewEffect(flame.room_number);
#define SPN_TONYHANDLFLAME 4 // {0, 64, 0, 10} if (fx_number != -1)
#define SPN_TONYHANDRFLAME 5 // {0, 64, 0, 13} {
FX_INFO* fx = &Effects[fx_number];
fx->pos.xPos = flame.pos.x;
fx->pos.yPos = flame.pos.y;
fx->pos.zPos = flame.pos.z;
fx->fallspeed = flame.fallspeed;
fx->pos.xRot = 0;
fx->pos.yRot = flame.y_rot;
fx->pos.zRot = 0;
fx->objectNumber = ID_TONY_BOSS_FLAME;
fx->speed = flame.speed;
fx->shade = 0;
fx->flag1 = flame.type;
fx->flag2 = (GetRandomControl() & 3) + 1;
void TriggerTonyFlame(short itemNum, long hand) switch (flame.type)
{
case T_ZAPPDEBRIS:
fx->flag2 <<= 1;
break;
case T_ZAPP:
fx->flag2 = 0;
break;
}
}
}
void TriggerTonyFlame(short itemNum, int hand)
{ {
ITEM_INFO* item; ITEM_INFO* item;
long size;
SPARKS* sptr; SPARKS* sptr;
long dx, dz; int dx, dz;
item = &Items[itemNum]; item = &Items[itemNum];
dx = LaraItem->pos.xPos - item->pos.xPos; dx = LaraItem->pos.xPos - item->pos.xPos;
dz = LaraItem->pos.zPos - item->pos.zPos; dz = LaraItem->pos.zPos - item->pos.zPos;
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE) if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
return; return;
sptr = &Sparks[GetFreeSpark()]; sptr = &Sparks[GetFreeSpark()];
sptr->on = TRUE;
sptr->on = 1;
sptr->sR = 255; sptr->sR = 255;
sptr->sG = 48 + (GetRandomControl() & 31); sptr->sG = 48 + (GetRandomControl() & 31);
sptr->sB = 48; sptr->sB = 48;
sptr->dR = 192 + (GetRandomControl() & 63); sptr->dR = 192 + (GetRandomControl() & 63);
sptr->dG = 128 + (GetRandomControl() & 63); sptr->dG = 128 + (GetRandomControl() & 63);
sptr->dB = 32; sptr->dB = 32;
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3); sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
sptr->fadeToBlack = 8; sptr->fadeToBlack = 8;
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24; sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
sptr->transType = COLADD;
sptr->transType = 2; sptr->extras = NULL;
sptr->extras = 0;
sptr->dynamic = -1; sptr->dynamic = -1;
sptr->x = ((GetRandomControl() & 15) - 8); sptr->x = ((GetRandomControl() & 15) - 8);
sptr->y = 0; sptr->y = 0;
sptr->z = ((GetRandomControl() & 15) - 8); sptr->z = ((GetRandomControl() & 15) - 8);
sptr->xVel = ((GetRandomControl() & 255) - 128); sptr->xVel = ((GetRandomControl() & 255) - 128);
sptr->yVel = -(GetRandomControl() & 15) - 16; sptr->yVel = -(GetRandomControl() & 15) - 16;
sptr->zVel = ((GetRandomControl() & 255) - 128); sptr->zVel = ((GetRandomControl() & 255) - 128);
@ -98,7 +119,7 @@ void TriggerTonyFlame(short itemNum, long hand)
if (GetRandomControl() & 1) if (GetRandomControl() & 1)
{ {
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_ITEM | SP_NODEATTATCH; sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
sptr->rotAng = GetRandomControl() & 4095; sptr->rotAng = GetRandomControl() & 4095;
if (GetRandomControl() & 1) if (GetRandomControl() & 1)
sptr->rotAdd = -(GetRandomControl() & 15) - 16; sptr->rotAdd = -(GetRandomControl() & 15) - 16;
@ -106,16 +127,17 @@ void TriggerTonyFlame(short itemNum, long hand)
sptr->rotAdd = (GetRandomControl() & 15) + 16; sptr->rotAdd = (GetRandomControl() & 15) + 16;
} }
else else
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTATCH; {
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
}
sptr->gravity = -(GetRandomControl() & 31) - 16; sptr->gravity = -(GetRandomControl() & 31) - 16;
sptr->maxYvel = -(GetRandomControl() & 7) - 16; sptr->maxYvel = -(GetRandomControl() & 7) - 16;
sptr->fxObj = itemNum; sptr->fxObj = itemNum;
sptr->nodeNumber = 0; sptr->nodeNumber = hand;
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
//sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
sptr->scalar = 1; sptr->scalar = 1;
size = (GetRandomControl() & 31) + 64; unsigned char size = (GetRandomControl() & 31) + 32;
sptr->size = size; sptr->size = size;
sptr->sSize = size; sptr->sSize = size;
sptr->dSize = size >> 2; sptr->dSize = size >> 2;
@ -124,39 +146,30 @@ void TriggerTonyFlame(short itemNum, long hand)
void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, long zv) void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, long zv)
{ {
SPARKS* sptr; SPARKS* sptr;
long size; int dx, dz;
long dx, dz;
dx = LaraItem->pos.xPos - Effects[fxNumber].pos.xPos; dx = LaraItem->pos.xPos - Effects[fxNumber].pos.xPos;
dz = LaraItem->pos.zPos - Effects[fxNumber].pos.zPos; dz = LaraItem->pos.zPos - Effects[fxNumber].pos.zPos;
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE) if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
return; return;
sptr = &Sparks[GetFreeSpark()]; sptr = &Sparks[GetFreeSpark()];
sptr->on = TRUE;
sptr->on = 1;
sptr->sR = 255; sptr->sR = 255;
sptr->sG = 48 + (GetRandomControl() & 31); sptr->sG = 48 + (GetRandomControl() & 31);
sptr->sB = 48; sptr->sB = 48;
sptr->dR = 192 + (GetRandomControl() & 63); sptr->dR = 192 + (GetRandomControl() & 63);
sptr->dG = 128 + (GetRandomControl() & 63); sptr->dG = 128 + (GetRandomControl() & 63);
sptr->dB = 32; sptr->dB = 32;
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3); sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
sptr->fadeToBlack = 8; sptr->fadeToBlack = 8;
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24; sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
sptr->transType = COLADD;
sptr->transType = 2;
sptr->extras = 0; sptr->extras = 0;
sptr->dynamic = -1; sptr->dynamic = -1;
sptr->x = ((GetRandomControl() & 15) - 8); sptr->x = ((GetRandomControl() & 15) - 8);
sptr->y = 0; sptr->y = 0;
sptr->z = ((GetRandomControl() & 15) - 8); sptr->z = ((GetRandomControl() & 15) - 8);
sptr->xVel = xv + ((GetRandomControl() & 255) - 128); sptr->xVel = xv + ((GetRandomControl() & 255) - 128);
sptr->yVel = yv; sptr->yVel = yv;
sptr->zVel = zv + ((GetRandomControl() & 255) - 128); sptr->zVel = zv + ((GetRandomControl() & 255) - 128);
@ -176,159 +189,168 @@ void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, long zv)
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX; sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX;
} }
sptr->fxObj = fxNumber; sptr->fxObj = (unsigned char)fxNumber;
sptr->def = (unsigned char)Objects[ID_DEFAULT_SPRITES].meshIndex;
//sptr->def = objects[EXPLOSION1].mesh_index;
sptr->scalar = 1; sptr->scalar = 1;
size = (GetRandomControl() & 31) + 64; unsigned char size = (GetRandomControl() & 31) + 64;
sptr->size = sptr->sSize = size; sptr->size = size;
sptr->sSize = size;
sptr->dSize = size >> 2; sptr->dSize = size >> 2;
if (type == ROCKZAPPL || type == ROCKZAPPR) if (type == T_ROCKZAPPL || type == T_ROCKZAPPR)
{ {
sptr->gravity = (GetRandomControl() & 31) + 16; sptr->gravity = (GetRandomControl() & 31) + 16;
sptr->maxYvel = (GetRandomControl() & 15) + 48; sptr->maxYvel = (GetRandomControl() & 15) + 48;
sptr->yVel = -sptr->yVel << 4; sptr->yVel = -sptr->yVel << 4;
sptr->scalar = 2; sptr->scalar = 2;
} }
else if (type == ROCKZAPPDEBRIS || type == ZAPPDEBRIS || type == DROPPERDEBRIS) else if (type == T_ROCKZAPPDEBRIS || type == T_ZAPPDEBRIS || type == T_DROPPERDEBRIS)
{ {
sptr->gravity = sptr->maxYvel = 0; sptr->gravity = 0;
sptr->maxYvel = 0;
} }
else if (type == DROPPER) else if (type == T_DROPPER)
{ {
sptr->gravity = -(GetRandomControl() & 31) - 16; sptr->gravity = -(GetRandomControl() & 31) - 16;
sptr->maxYvel = -(GetRandomControl() & 31) - 64; sptr->maxYvel = -(GetRandomControl() & 31) - 64;
sptr->yVel = sptr->yVel << 4; sptr->yVel = sptr->yVel << 4;
sptr->scalar = 2; sptr->scalar = 2;
} }
else if (type == ZAPP) else if (type == T_ZAPP)
{ {
sptr->gravity = sptr->maxYvel = 0; sptr->gravity = sptr->maxYvel = 0;
sptr->scalar = 2; sptr->scalar = 2;
} }
} }
void TriggerFireBall(ITEM_INFO* item, long type, PHD_VECTOR* pos1, short roomNumber, short angle, long zdspeed) void TriggerFireBall(ITEM_INFO* item, TonyFlameType type, PHD_VECTOR* lara_pos, short roomNumber, short angle, int zdspeed)
{ {
FX_INFO* fx; TONY_FLAME flame;
PHD_VECTOR pos; memset(&flame, 0, sizeof(TONY_FLAME));
short fxNumber;
long speed, fallspeed;
if (type == ROCKZAPPL) switch (type)
{ {
pos.x = pos.y = pos.z = 0; case T_ROCKZAPPL:
GetJointAbsPosition(item, &pos, 10); flame.on = true;
angle = item->pos.yRot; flame.pos.x = 0;
speed = 0; flame.pos.y = 0;
fallspeed = -16; flame.pos.z = 0;
} GetJointAbsPosition(item, &flame.pos, 10);
else if (type == ROCKZAPPR) flame.fallspeed = -16;
{ flame.speed = 0;
pos.x = pos.y = pos.z = 0; flame.y_rot = item->pos.yRot;
GetJointAbsPosition(item, &pos, 13); flame.room_number = roomNumber;
angle = item->pos.yRot; flame.type = T_ROCKZAPPL;
speed = 0; break;
fallspeed = -16; case T_ROCKZAPPR:
} flame.on = true;
else if (type == ZAPP) flame.pos.x = 0;
{ flame.pos.y = 0;
pos.x = pos.y = pos.z = 0; flame.pos.z = 0;
GetJointAbsPosition(item, &pos, 13); GetJointAbsPosition(item, &flame.pos, 13);
speed = 160; flame.fallspeed = -16;
fallspeed = -(GetRandomControl() & 7) - 32; flame.speed = 0;
} flame.y_rot = item->pos.yRot;
else if (type == ROCKZAPPDEBRIS) flame.room_number = roomNumber;
{ flame.type = T_ROCKZAPPR;
pos.x = pos1->x; break;
pos.y = pos1->y; case T_ZAPP:
pos.z = pos1->z; flame.on = true;
speed = zdspeed + (GetRandomControl() & 3); flame.pos.x = 0;
angle = GetRandomControl() << 1; flame.pos.y = 0;
fallspeed = (GetRandomControl() & 3) - 2; flame.pos.z = 0;
} GetJointAbsPosition(item, &flame.pos, 13);
else if (type == ZAPPDEBRIS) flame.fallspeed = (GetRandomControl() & 7) + 10;
{ flame.speed = 160;
pos.x = pos1->x; flame.y_rot = item->pos.yRot;
pos.y = pos1->y; flame.room_number = roomNumber;
pos.z = pos1->z; flame.type = T_ZAPP;
speed = (GetRandomControl() & 7) + 48; break;
case T_DROPPER:
flame.on = true;
flame.pos.x = lara_pos->x;
flame.pos.y = lara_pos->y + 64; // avoid some ceiling problem (only for TR3 thought)...
flame.pos.z = lara_pos->z;
flame.fallspeed = (GetRandomControl() & 3) + 4;
flame.speed = 0;
flame.y_rot = angle;
flame.room_number = roomNumber;
flame.type = T_DROPPER;
break;
case T_ROCKZAPPDEBRIS:
flame.on = true;
flame.pos.x = lara_pos->x;
flame.pos.y = lara_pos->y;
flame.pos.z = lara_pos->z;
flame.fallspeed = (GetRandomControl() & 3) - 2;
flame.speed = zdspeed + (GetRandomControl() & 3);
flame.y_rot = GetRandomControl() << 1;
flame.room_number = roomNumber;
flame.type = T_ROCKZAPPDEBRIS;
break;
case T_ZAPPDEBRIS:
flame.on = true;
flame.pos.x = lara_pos->x;
flame.pos.y = lara_pos->y;
flame.pos.z = lara_pos->z;
flame.fallspeed = -(GetRandomControl() & 15) - 16;
flame.speed = (GetRandomControl() & 7) + 48;
angle += (GetRandomControl() & 0x1fff) - 0x9000; angle += (GetRandomControl() & 0x1fff) - 0x9000;
fallspeed = -(GetRandomControl() & 15) - 16; flame.y_rot = angle;
} flame.room_number = roomNumber;
else if (type == DROPPER) flame.type = T_ZAPPDEBRIS;
{ break;
pos.x = pos1->x; case T_DROPPERDEBRIS:
pos.y = pos1->y; flame.on = true;
pos.z = pos1->z; flame.pos.x = lara_pos->x;
speed = 0; flame.pos.y = lara_pos->y;
fallspeed = (GetRandomControl() & 3) + 4; flame.pos.z = lara_pos->z;
} flame.fallspeed = -(GetRandomControl() & 31) - 32;
else// if (type == DROPPERDEBRIS) flame.speed = (GetRandomControl() & 31) + 32;
{ flame.y_rot = GetRandomControl() << 1;
pos.x = pos1->x; flame.room_number = roomNumber;
pos.y = pos1->y; flame.type = T_DROPPERDEBRIS;
pos.z = pos1->z; break;
speed = (GetRandomControl() & 31) + 32;
angle = GetRandomControl() << 1;
fallspeed = -(GetRandomControl() & 31) - 32;
} }
fxNumber = CreateNewEffect(roomNumber); if (flame.on)
if (fxNumber != NO_ITEM) TriggerTonyEffect(flame);
{
fx = &Effects[fxNumber];
fx->pos.xPos = pos.x;
fx->pos.yPos = pos.y;
fx->pos.zPos = pos.z;
fx->pos.yRot = angle;
fx->objectNumber = ID_GUARD1; // TONYFIREBALL
fx->speed = speed;
fx->fallspeed = fallspeed;
fx->flag1 = type;
fx->flag2 = (GetRandomControl() & 3) + 1;
if (type == ZAPPDEBRIS)
fx->flag2 <<= 1;
else if (type == ZAPP)
fx->flag2 = 0;
}
} }
void TonyFireBallControl(short fxNumber) void ControlTonyFireBall(short fxNumber)
{ {
FX_INFO* fx; FX_INFO* fx;
FLOOR_INFO* floor; FLOOR_INFO* floor;
long old_x, old_y, old_z, x; long old_x, old_y, old_z, x;
long rnd, r, g, b; long rnd, j;
unsigned char radtab[7] = { 16,0,14,9,7,7,7 }; unsigned char radtab[7] = { 16,0,14,9,7,7,7 };
short roomNumber; TonyFlameType type;
short room_number;
fx = &Effects[fxNumber]; fx = &Effects[fxNumber];
old_x = fx->pos.xPos; old_x = fx->pos.xPos;
old_y = fx->pos.yPos; old_y = fx->pos.yPos;
old_z = fx->pos.zPos; old_z = fx->pos.zPos;
if (fx->flag1 == ROCKZAPPL || fx->flag1 == ROCKZAPPR) if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
{ {
fx->fallspeed += (fx->fallspeed >> 3) + 1; fx->fallspeed += (fx->fallspeed >> 3) + 1;
if (fx->fallspeed < -4096) if (fx->fallspeed < -4096)
fx->fallspeed = -4096; fx->fallspeed = -4096;
fx->pos.yPos += fx->fallspeed; fx->pos.yPos += fx->fallspeed;
if (Wibble & 4) if (Wibble & 4)
TriggerFireBallFlame(fxNumber, fx->flag1, 0, 0, 0); TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, 0, 0, 0);
} }
else if (fx->flag1 == DROPPER) else if (fx->flag1 == T_DROPPER)
{ {
fx->fallspeed += 2; fx->fallspeed += 2;
fx->pos.yPos += fx->fallspeed; fx->pos.yPos += fx->fallspeed;
if (Wibble & 4) if (Wibble & 4)
TriggerFireBallFlame(fxNumber, fx->flag1, 0, 0, 0); TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, 0, 0, 0);
} }
else else
{ {
if (fx->flag1 != ZAPP) if (fx->flag1 != T_ZAPP)
{ {
if (fx->speed > 48) if (fx->speed > 48)
fx->speed--; fx->speed--;
@ -340,19 +362,20 @@ void TonyFireBallControl(short fxNumber)
fx->pos.zPos += (fx->speed * phd_cos(fx->pos.yRot) >> W2V_SHIFT); fx->pos.zPos += (fx->speed * phd_cos(fx->pos.yRot) >> W2V_SHIFT);
fx->pos.xPos += (fx->speed * phd_sin(fx->pos.yRot) >> W2V_SHIFT); fx->pos.xPos += (fx->speed * phd_sin(fx->pos.yRot) >> W2V_SHIFT);
if (Wibble & 4) if (Wibble & 4)
TriggerFireBallFlame(fxNumber, fx->flag1, (old_x - fx->pos.xPos) << 3, (old_y - fx->pos.yPos) << 3, (old_z - fx->pos.zPos) << 3); TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, (short)((old_x - fx->pos.xPos) << 3), (short)((old_y - fx->pos.yPos) << 3), (short)((old_z - fx->pos.zPos) << 3));
} }
roomNumber = fx->roomNumber; room_number = fx->roomNumber;
floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &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)) 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))
{ {
if (fx->flag1 == ROCKZAPPL || fx->flag1 == ROCKZAPPR || fx->flag1 == ZAPP || fx->flag1 == DROPPER) if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR || fx->flag1 == T_ZAPP || fx->flag1 == T_DROPPER)
{ {
PHD_VECTOR pos; PHD_VECTOR pos;
TriggerExplosionSparks(old_x, old_y, old_z, 3, -2, 0, fx->roomNumber); // -2 = Set off a dynamic light controller. TriggerExplosionSparks(old_x, old_y, old_z, 3, -2, 0, fx->roomNumber); // -2 = Set off a dynamic light controller.
if (fx->flag1 == ROCKZAPPL || fx->flag1 == ROCKZAPPR) if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
{ {
for (x = 0; x < 2; x++) for (x = 0; x < 2; x++)
TriggerExplosionSparks(old_x, old_y, old_z, 3, -1, 0, fx->roomNumber); TriggerExplosionSparks(old_x, old_y, old_z, 3, -1, 0, fx->roomNumber);
@ -360,36 +383,36 @@ void TonyFireBallControl(short fxNumber)
pos.x = old_x; pos.x = old_x;
pos.y = old_y; pos.y = old_y;
pos.z = old_z; pos.z = old_z;
if (fx->flag1 == ZAPP) if (fx->flag1 == T_ZAPP)
r = 7; j = 7;
else else
r = 3; j = 3;
if (fx->flag1 == ZAPP) if (fx->flag1 == T_ZAPP)
g = ZAPPDEBRIS; type = T_ZAPPDEBRIS;
else if (fx->flag1 == DROPPER) else if (fx->flag1 == T_DROPPER)
g = DROPPERDEBRIS; type = T_DROPPERDEBRIS;
else else
g = ROCKZAPPDEBRIS; type = T_ROCKZAPPDEBRIS;
for (x = 0; x < r; x++) for (x = 0; x < j; x++)
TriggerFireBall((ITEM_INFO*)NULL, g, &pos, fx->roomNumber, fx->pos.yRot, 32 + (x << 2)); TriggerFireBall(NULL, type, &pos, fx->roomNumber, fx->pos.yRot, 32 + (x << 2));
if (fx->flag1 == ROCKZAPPL || fx->flag1 == ROCKZAPPR) if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
{ {
roomNumber = LaraItem->roomNumber; room_number = LaraItem->roomNumber;
floor = GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &roomNumber); floor = GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &room_number);
pos.y = GetCeiling(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos) + 256; pos.y = GetCeiling(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos) + 256;
pos.x = LaraItem->pos.xPos + (GetRandomControl() & 1023) - 512; pos.x = LaraItem->pos.xPos + (GetRandomControl() & 1023) - 512;
pos.z = LaraItem->pos.zPos + (GetRandomControl() & 1023) - 512; pos.z = LaraItem->pos.zPos + (GetRandomControl() & 1023) - 512;
TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, roomNumber); // -2 = Set off a dynamic light controller. TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, room_number); // -2 = Set off a dynamic light controller.
TriggerFireBall((ITEM_INFO*)NULL, DROPPER, &pos, roomNumber, 0, 0); TriggerFireBall(NULL, T_DROPPER, &pos, room_number, 0, 0);
} }
} }
KillEffect(fxNumber); KillEffect(fxNumber);
return; return;
} }
if (Rooms[roomNumber].flags & ENV_FLAG_WATER) if (Rooms[room_number].flags & LW_UNDERWATER)
{ {
KillEffect(fxNumber); KillEffect(fxNumber);
return; return;
@ -399,32 +422,33 @@ void TonyFireBallControl(short fxNumber)
{ {
if (ItemNearLara(&fx->pos, 200)) if (ItemNearLara(&fx->pos, 200))
{ {
LaraItem->hitStatus = true; LaraItem->hitStatus = TRUE;
KillEffect(fxNumber); KillEffect(fxNumber);
LaraItem->hitPoints -= 200;
LaraBurn();
return; return;
} }
} }
if (roomNumber != fx->roomNumber) if (room_number != fx->roomNumber)
EffectNewRoom(fxNumber, LaraItem->roomNumber); EffectNewRoom(fxNumber, LaraItem->roomNumber);
if (radtab[fx->flag1]) if (radtab[fx->flag1])
{ {
rnd = GetRandomControl(); rnd = GetRandomControl();
r = 31 - ((rnd >> 4) & 3); BYTE r3 = 31 - ((rnd >> 4) & 3);
g = 24 - ((rnd >> 6) & 3); BYTE g3 = 24 - ((rnd >> 6) & 3);
b = rnd & 7; BYTE b3 = rnd & 7;
//TriggerDynamic(fx->pos.x_pos, fx->pos.y_pos, fx->pos.z_pos, radtab[fx->flag1], r, g, b); TriggerDynamicLight(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, radtab[fx->flag1], r3, g3, b3);
} }
} }
void TonyDie(short itemNum) void TonyBossDie(short itemNum)
{ {
ITEM_INFO* item; ITEM_INFO* item;
item = &Items[itemNum]; item = &Items[itemNum];
item->collidable = false; item->collidable = FALSE;
item->hitPoints = -16384; // NOT_TARGETABLE item->hitPoints = -16384;
KillItem(itemNum); KillItem(itemNum);
DisableBaddieAI(itemNum); DisableBaddieAI(itemNum);
@ -434,33 +458,48 @@ void TonyDie(short itemNum)
void InitialiseTony(short itemNum) void InitialiseTony(short itemNum)
{ {
SHIELD_POINTS* shptr;
ITEM_INFO* item; ITEM_INFO* item;
int lp, lp1, y;
short angle;
item = &Items[itemNum]; item = &Items[itemNum];
item->itemFlags[3] = 0; item->itemFlags[3] = 0;
bossdata.explode_count = 0; BossData.ExplodeCount = 0;
bossdata.ring_count = 0; BossData.RingCount = 0;
bossdata.dropped_icon = false; BossData.DroppedIcon = false;
bossdata.dead = false; BossData.DrawExplode = false; // not draw it when triggered !
BossData.Dead = false;
}
// initialise shield coordinate: static bool TonyIsDying()
shptr = &TonyBossShield[0]; {
for (lp = 0; lp < 5; lp++) return BossData.ExplodeCount == 01 ||
BossData.ExplodeCount == 15 ||
BossData.ExplodeCount == 25 ||
BossData.ExplodeCount == 35 ||
BossData.ExplodeCount == 45 ||
BossData.ExplodeCount == 55;
}
static void ExplodeTonyBoss(ITEM_INFO* item)
{
if (item->hitPoints <= 0 && TonyIsDying())
{ {
y = heights[lp]; int x, y, z;
angle = 0; x = item->pos.xPos + (GetRandomDraw() & 0x3FF) - 512;
for (lp1 = 0; lp1 < 8; lp1++) y = item->pos.yPos - (GetRandomDraw() & 0x3FF) - 256;
{ z = item->pos.zPos + (GetRandomDraw() & 0x3FF) - 512;
shptr->x = (rcossin_tbl[angle << 1] * radii[lp]) >> 11; BossData.DrawExplode = true;
shptr->y = y; // TODO: AddExplosionRings(x, y, z); // random position for rings
shptr->z = (rcossin_tbl[(angle << 1) + 1] * radii[lp]) >> 11;
shptr->rgb = 0; TriggerExplosionSparks(x, y, z, 3, -2, 0, item->roomNumber);
angle += 512; for (int i = 0; i < 2; i++)
shptr++; TriggerExplosionSparks(x, y, z, 3, -1, 0, item->roomNumber);
}
SoundEffect(SFX_TR3_BLAST_CIRCLE, &item->pos, PITCH_SHIFT | 0x800000);
}
if (BossData.DrawExplode)
{
// TODO: AddExplosionGeometry(item->pos.xPos, item->pos.yPos - 512, item->pos.zPos, BossData.ExplodeCount); // int x, int y, int z, int size
BossData.DrawExplode = false;
} }
} }
@ -488,6 +527,26 @@ void TonyControl(short itemNum)
item->frameNumber = Anims[item->animNumber].frameBase; item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = 6; item->currentAnimState = 6;
} }
if ((item->frameNumber - Anims[item->animNumber].frameBase) > 110)
{
item->meshBits = 0;
if (!BossData.DroppedIcon)
BossData.DroppedIcon = true;
}
if (BossData.ExplodeCount < 256)
BossData.ExplodeCount++;
if (BossData.ExplodeCount <= 128 || BossData.RingCount != 6)
{
ExplodeTonyBoss(item);
}
else
{
TonyBossDie(itemNum);
BossData.Dead = true;
}
} }
else else
{ {
@ -498,7 +557,7 @@ void TonyControl(short itemNum)
if (!item->itemFlags[3]) // Is she close enough yet ? if (!item->itemFlags[3]) // Is she close enough yet ?
{ {
long dx, dz; int dx, dz;
dx = item->pos.xPos - LaraItem->pos.xPos; dx = item->pos.xPos - LaraItem->pos.xPos;
dz = item->pos.zPos - LaraItem->pos.zPos; dz = item->pos.zPos - LaraItem->pos.zPos;
if ((SQUARE(dx) + SQUARE(dz)) < SQUARE(5120)) if ((SQUARE(dx) + SQUARE(dz)) < SQUARE(5120))
@ -517,15 +576,14 @@ void TonyControl(short itemNum)
switch (item->currentAnimState) switch (item->currentAnimState)
{ {
case TONYBOSS_WAIT: // Waiting. case TONYBOSS_WAIT: // Waiting.
tonyboss->maximumTurn = 0; tonyboss->maximumTurn = 0;
if (item->goalAnimState != TONYBOSS_RISE && item->itemFlags[3]) if (item->goalAnimState != TONYBOSS_RISE && item->itemFlags[3])
item->goalAnimState = TONYBOSS_RISE; item->goalAnimState = TONYBOSS_RISE;
break; break;
case TONYBOSS_RISE: // Rising. case TONYBOSS_RISE: // Rising.
if (item->frameNumber - Anims[item->animNumber].frameBase > 16) if ((item->frameNumber - Anims[item->animNumber].frameBase) > 16)
tonyboss->maximumTurn = TONYBOSS_TURN; tonyboss->maximumTurn = TONYBOSS_TURN;
else else
tonyboss->maximumTurn = 0; tonyboss->maximumTurn = 0;
@ -534,10 +592,9 @@ void TonyControl(short itemNum)
case TONYBOSS_FLOAT: // Rising. case TONYBOSS_FLOAT: // Rising.
torso_y = info.angle; torso_y = info.angle;
torso_x = info.xAngle; torso_x = info.xAngle;
tonyboss->maximumTurn = TONYBOSS_TURN; tonyboss->maximumTurn = TONYBOSS_TURN;
if (!bossdata.explode_count) if (!BossData.ExplodeCount)
{ {
if (item->goalAnimState != TONYBOSS_BIGBOOM && item->itemFlags[3] != 2) if (item->goalAnimState != TONYBOSS_BIGBOOM && item->itemFlags[3] != 2)
{ {
@ -563,38 +620,35 @@ void TonyControl(short itemNum)
} }
} }
} }
break; break;
case TONYBOSS_ROCKZAPP: // Shooting at ceiling. case TONYBOSS_ROCKZAPP: // Shooting at ceiling.
torso_y = info.angle; torso_y = info.angle;
torso_x = info.xAngle; torso_x = info.xAngle;
tonyboss->maximumTurn = 0; tonyboss->maximumTurn = 0;
if (item->frameNumber - Anims[item->animNumber].frameBase == 40) if (item->frameNumber - Anims[item->animNumber].frameBase == 40)
{ {
//TriggerFireBall(item, ROCKZAPPL, (PHD_VECTOR*)NULL, item->roomNumber, 0, 0); TriggerFireBall(item, T_ROCKZAPPL, NULL, item->roomNumber, 0, 0);
//TriggerFireBall(item, ROCKZAPPR, (PHD_VECTOR*)NULL, item->roomNumber, 0, 0); TriggerFireBall(item, T_ROCKZAPPR, NULL, item->roomNumber, 0, 0);
} }
break; break;
case TONYBOSS_ZAPP: // Shooting at ceiling. case TONYBOSS_ZAPP: // Shooting at ceiling.
torso_y = info.angle; torso_y = info.angle;
torso_x = info.xAngle; torso_x = info.xAngle;
tonyboss->maximumTurn = TONYBOSS_TURN >> 1; tonyboss->maximumTurn = TONYBOSS_TURN >> 1;
//if (item->frameNumber - Anims[item->animNumber].frameBase == 28) if ((item->frameNumber - Anims[item->animNumber].frameBase) == 28)
// TriggerFireBall(item, ZAPP, (PHD_VECTOR*)NULL, item->roomNumber, item->pos.yRot, 0); TriggerFireBall(item, T_ZAPP, NULL, item->roomNumber, item->pos.yRot, 0);
break; break;
case TONYBOSS_BIGBOOM: // Changing room. case TONYBOSS_BIGBOOM: // Changing room.
tonyboss->maximumTurn = 0; tonyboss->maximumTurn = 0;
if (item->frameNumber - Anims[item->animNumber].frameBase == 56) if ((item->frameNumber - Anims[item->animNumber].frameBase) == 56)
{ {
item->itemFlags[3] = 2; item->itemFlags[3] = 2;
bossdata.explode_count = 1; BossData.DrawExplode = true; // EXPLOOOOOOOOOOSION (if you have the ref (O.~))
} }
break; break;
@ -605,7 +659,8 @@ void TonyControl(short itemNum)
if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_ZAPP || item->currentAnimState == TONYBOSS_BIGBOOM) if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_ZAPP || item->currentAnimState == TONYBOSS_BIGBOOM)
{ {
long bright, r, g, b; byte r, g, b;
int bright;
bright = item->frameNumber - Anims[item->animNumber].frameBase; bright = item->frameNumber - Anims[item->animNumber].frameBase;
if (bright > 16) if (bright > 16)
@ -625,26 +680,30 @@ void TonyControl(short itemNum)
pos1.x = pos1.y = pos1.z = 0; pos1.x = pos1.y = pos1.z = 0;
GetJointAbsPosition(item, &pos1, 10); GetJointAbsPosition(item, &pos1, 10);
//TriggerDynamic(pos1.x, pos1.y, pos1.z, 12, r, g, b); TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, r, g, b);
//TriggerTonyFlame(itemNum, SPN_TONYHANDRFLAME); TriggerTonyFlame(itemNum, 14);
if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_BIGBOOM) if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_BIGBOOM)
{ {
pos1.x = pos1.y = pos1.z = 0; pos1.x = pos1.y = pos1.z = 0;
GetJointAbsPosition(item, &pos1, 13); GetJointAbsPosition(item, &pos1, 13);
//TriggerDynamic(pos1.x, pos1.y, pos1.z, 12, r, g, b); TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, r, g, b);
//TriggerTonyFlame(itemNum, SPN_TONYHANDLFLAME); TriggerTonyFlame(itemNum, 13);
} }
} }
if (bossdata.explode_count && item->hitPoints > 0) if (BossData.ExplodeCount && item->hitPoints > 0)
{ {
//ExplodeTonyBoss(item); ExplodeTonyBoss(item);
bossdata.explode_count++; BossData.ExplodeCount++;
//if (bossdata.explode_count == 32) //if (bossdata.explode_count == 32)
// FlipMap[]; // DoFlipMap(1);
if (bossdata.explode_count > 64) if (BossData.ExplodeCount > 64)
bossdata.explode_count = bossdata.ring_count = 0; {
BossData.ExplodeCount = 0;
BossData.RingCount = 0;
}
} }
/* Actually do animation allowing for collisions */ /* Actually do animation allowing for collisions */
@ -654,9 +713,9 @@ void TonyControl(short itemNum)
CreatureAnimation(itemNum, angle, 0); CreatureAnimation(itemNum, angle, 0);
} }
void DrawTony(ITEM_INFO* item) void S_DrawTonyBoss(ITEM_INFO* item)
{ {
//DrawAnimatingItem(item); DrawAnimatingItem(item);
// TODO: psx draw (need to be rewrited !) // TODO: psx draw (need to be rewrited !)
//if (bossdata.explode_count && item->hitPoints <= 0) //if (bossdata.explode_count && item->hitPoints <= 0)

View file

@ -891,7 +891,7 @@ void TriggerRomanStatueAttackEffect1(short itemNum, int factor)
spark->xVel = (byte)GetRandomControl() - 128; spark->xVel = (byte)GetRandomControl() - 128;
spark->friction = 4; spark->friction = 4;
spark->zVel = (byte)GetRandomControl() - 128; spark->zVel = (byte)GetRandomControl() - 128;
spark->flags = SP_NODEATTATCH | SP_EXPDEF | SP_ITEM | SP_ROTATE | SP_DEF | SP_SCALE; // 4762; spark->flags = SP_NODEATTACH | SP_EXPDEF | SP_ITEM | SP_ROTATE | SP_DEF | SP_SCALE; // 4762;
spark->fxObj = itemNum; spark->fxObj = itemNum;
spark->nodeNumber = 6; spark->nodeNumber = 6;
spark->rotAng = GetRandomControl() & 0xFFF; spark->rotAng = GetRandomControl() & 0xFFF;

View file

@ -392,7 +392,7 @@ void TriggerElectricityWiresSparks(int x, int z, char objNum, char node, int fla
spark->fxObj = objNum; spark->fxObj = objNum;
spark->transType = 2; spark->transType = 2;
spark->flags = SP_ITEM | SP_NODEATTATCH | SP_SCALE | SP_DEF; spark->flags = SP_ITEM | SP_NODEATTACH | SP_SCALE | SP_DEF;
spark->nodeNumber = node; spark->nodeNumber = node;
spark->x = x; spark->x = x;
spark->z = z; spark->z = z;

View file

@ -124,19 +124,21 @@ typedef struct KAYAK_INFO {
typedef struct BOSS_STRUCT typedef struct BOSS_STRUCT
{ {
short attack_count; PHD_VECTOR BeamTarget;
short death_count; bool DroppedIcon;
byte attack_flag; bool IsInvincible;
byte attack_type; bool DrawExplode; // allow explosion geometry
byte attack_head_count; bool Charged;
byte ring_count; bool Dead;
short explode_count; short AttackCount;
short lizman_item, lizman_room; short DeathCount;
short hp_counter; short AttackFlag;
short dropped_icon; short AttackType;
byte charged; short AttackHeadCount;
byte dead; short RingCount;
PHD_VECTOR BeamTarget; short ExplodeCount;
short LizmanItem, LizmanRoom;
short HpCounter;
}; };
typedef struct SHIELD_POINTS typedef struct SHIELD_POINTS
@ -261,8 +263,8 @@ void ControlFish(short itemNumber);
bool FishNearLara(PHD_3DPOS* pos, int distance, ITEM_INFO* item); bool FishNearLara(PHD_3DPOS* pos, int distance, ITEM_INFO* item);
void InitialiseTony(short itemNum); void InitialiseTony(short itemNum);
void TonyControl(short itemNum); void TonyControl(short itemNum);
void DrawTony(ITEM_INFO* item); void S_DrawTonyBoss(ITEM_INFO* item);
void TonyFireBallControl(short fxNumber); void ControlTonyFireBall(short fxNumber);
void InitialiseShiva(short itemNum); void InitialiseShiva(short itemNum);
void ShivaControl(short itemNum); void ShivaControl(short itemNum);
void ControlLaserBolts(short item_number); void ControlLaserBolts(short item_number);

View file

@ -221,10 +221,8 @@ void Renderer11::drawSparks()
{ {
PHD_VECTOR nodePos; PHD_VECTOR nodePos;
for (int i = 0; i < 16; i++) for (int i = 0; i < MAX_NODE; i++)
{
NodeOffsets[i].gotIt = false; NodeOffsets[i].gotIt = false;
}
for (int i = 0; i < MAX_SPARKS; i++) for (int i = 0; i < MAX_SPARKS; i++)
{ {
@ -261,7 +259,7 @@ void Renderer11::drawSparks()
{ {
ITEM_INFO* item = &Items[spark->fxObj]; ITEM_INFO* item = &Items[spark->fxObj];
if (spark->flags & SP_NODEATTATCH) if (spark->flags & SP_NODEATTACH)
{ {
if (NodeOffsets[spark->nodeNumber].gotIt) if (NodeOffsets[spark->nodeNumber].gotIt)
{ {
@ -282,7 +280,7 @@ void Renderer11::drawSparks()
GetLaraJointPosition(&nodePos, -meshNum); GetLaraJointPosition(&nodePos, -meshNum);
NodeOffsets[spark->nodeNumber].gotIt = true; NodeOffsets[spark->nodeNumber].gotIt = true;
NodeVectors[spark->nodeNumber].x = nodePos.x; NodeVectors[spark->nodeNumber].x = nodePos.x;
NodeVectors[spark->nodeNumber].y = nodePos.y; NodeVectors[spark->nodeNumber].y = nodePos.y;
NodeVectors[spark->nodeNumber].z = nodePos.z; NodeVectors[spark->nodeNumber].z = nodePos.z;

View file

@ -3259,7 +3259,7 @@ void CustomObjects()
obj->initialise = InitialiseTony; obj->initialise = InitialiseTony;
obj->collision = CreatureCollision; obj->collision = CreatureCollision;
obj->control = TonyControl; obj->control = TonyControl;
obj->drawRoutine = DrawTony; obj->drawRoutine = S_DrawTonyBoss;
obj->shadowSize = UNIT_SHADOW / 2; obj->shadowSize = UNIT_SHADOW / 2;
obj->hitPoints = 100; obj->hitPoints = 100;
obj->pivotLength = 50; obj->pivotLength = 50;
@ -3274,6 +3274,10 @@ void CustomObjects()
Bones[obj->boneIndex + 13 * 4] |= ROT_Y; Bones[obj->boneIndex + 13 * 4] |= ROT_Y;
} }
obj = &Objects[ID_TONY_BOSS_FLAME];
obj->control = ControlTonyFireBall;
obj->drawRoutine = NULL;
obj = &Objects[ID_BIRDMONSTER]; obj = &Objects[ID_BIRDMONSTER];
if (obj->loaded) if (obj->loaded)
{ {
@ -3333,9 +3337,7 @@ void CustomObjects()
obj = &Objects[ID_KNIFETHROWER_KNIFE]; obj = &Objects[ID_KNIFETHROWER_KNIFE];
if (obj->loaded) if (obj->loaded)
{
obj->control = KnifeControl; obj->control = KnifeControl;
}
obj = &Objects[ID_MERCENARY_UZI]; obj = &Objects[ID_MERCENARY_UZI];
if (obj->loaded) if (obj->loaded)