Refactored energy bubbles function names; Removed LanguageScript.cpp from the project; Working on ID_CROCODILE_GOD;

This commit is contained in:
MontyTRC89 2021-08-20 06:00:34 +02:00
parent 2e1ac44c08
commit 4991da66f6
10 changed files with 720 additions and 704 deletions

View file

@ -38,14 +38,14 @@ enum ZoneType
ZONE_HUMAN_LONGJUMP_AND_MONKEY, ZONE_HUMAN_LONGJUMP_AND_MONKEY,
}; };
struct OBJECT_Bones struct OBJECT_BONES
{ {
short bone0; short bone0;
short bone1; short bone1;
short bone2; short bone2;
short bone3; short bone3;
OBJECT_Bones() OBJECT_BONES()
{ {
this->bone0 = 0; this->bone0 = 0;
this->bone1 = 0; this->bone1 = 0;
@ -53,7 +53,7 @@ struct OBJECT_Bones
this->bone3 = 0; this->bone3 = 0;
} }
OBJECT_Bones(short all) OBJECT_BONES(short all)
{ {
this->bone0 = all; this->bone0 = all;
this->bone1 = all; this->bone1 = all;
@ -61,7 +61,7 @@ struct OBJECT_Bones
this->bone3 = all; this->bone3 = all;
} }
OBJECT_Bones(short angleY, short angleX) OBJECT_BONES(short angleY, short angleX)
{ {
this->bone0 = angleY; this->bone0 = angleY;
this->bone1 = angleX; this->bone1 = angleX;
@ -69,7 +69,7 @@ struct OBJECT_Bones
this->bone3 = angleX; this->bone3 = angleX;
} }
OBJECT_Bones(short angleY, short angleX, bool total) OBJECT_BONES(short angleY, short angleX, bool total)
{ {
this->bone0 = angleY; this->bone0 = angleY;
this->bone1 = angleX; this->bone1 = angleX;

View file

@ -11,426 +11,429 @@
#include "lara.h" #include "lara.h"
#include "tr4_mutant.h" #include "tr4_mutant.h"
void BubblesEffect1(short fxNum, short xVel, short yVel, short zVel) namespace ten::entities::all
{ {
FX_INFO* fx = &EffectList[fxNum]; void TriggerSethMissileFlame(short fxNum, short xVel, short yVel, short zVel)
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{ {
SPARKS* spark = &Sparks[GetFreeSpark()]; FX_INFO* fx = &EffectList[fxNum];
spark->on = 1; int dx = LaraItem->pos.xPos - fx->pos.xPos;
spark->sR = 0; int dz = LaraItem->pos.zPos - fx->pos.zPos;
spark->dR = 0;
spark->sG = (GetRandomControl() & 0x7F) + 32; if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
spark->sB = spark->dG + 64;
spark->dB = (GetRandomControl() & 0x7F) + 32;
spark->dG = spark->dB + 64;
spark->fadeToBlack = 8;
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
spark->y = 0;
spark->x = (GetRandomControl() & 0xF) - 8;
spark->xVel = xVel;
spark->yVel = yVel;
spark->z = (GetRandomControl() & 0xF) - 8;
spark->zVel = zVel;
spark->friction = 68;
spark->flags = 602;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
{ {
spark->rotAdd = -32 - (GetRandomControl() & 0x1F); SPARKS* spark = &Sparks[GetFreeSpark()];
}
else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
if (fx->flag1 == 1)
{
spark->scalar = 3;
}
else
{
spark->scalar = 2;
}
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
}
}
void BubblesEffect2(short fxNum, short xVel, short yVel, short zVel) spark->on = 1;
{
FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
spark->sR = 0;
spark->sG = (GetRandomControl() & 0x7F) + 32;
spark->sB = spark->dG + 64;
spark->dB = 0;
spark->dG = spark->dR = (GetRandomControl() & 0x7F) + 32;
spark->fadeToBlack = 8;
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
spark->y = 0;
spark->x = (GetRandomControl() & 0xF) - 8;
spark->xVel = xVel;
spark->zVel = zVel;
spark->z = (GetRandomControl() & 0xF) - 8;
spark->yVel = yVel;
spark->friction = 68;
spark->flags = 602;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
{
spark->rotAdd = -32 - (GetRandomControl() & 0x1F);
}
else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
spark->scalar = 2;
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
}
}
void BubblesEffect4(short fxNum, short xVel, short yVel, short zVel)
{
FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
if (fx->flag1 == 3 || fx->flag1 == 4)
{
spark->sR = 0; spark->sR = 0;
spark->dR = 0; spark->dR = 0;
spark->sB = (GetRandomControl() & 0x7F) + 32; spark->sG = (GetRandomControl() & 0x7F) + 32;
spark->sG = spark->sB + 64; spark->sB = spark->dG + 64;
spark->dG = (GetRandomControl() & 0x7F) + 32; spark->dB = (GetRandomControl() & 0x7F) + 32;
spark->dB = spark->dG + 64; spark->dG = spark->dB + 64;
} spark->fadeToBlack = 8;
else spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
{ spark->transType = TransTypeEnum::COLADD;
spark->sR = (GetRandomControl() & 0x7F) + 32; spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
spark->sG = spark->sR - (GetRandomControl() & 0x1F); spark->y = 0;
spark->sB = 0; spark->x = (GetRandomControl() & 0xF) - 8;
spark->dR = (GetRandomControl() & 0x7F) + 32; spark->xVel = xVel;
spark->dB = 0; spark->yVel = yVel;
spark->dG = spark->dR - (GetRandomControl() & 0x1F); spark->z = (GetRandomControl() & 0xF) - 8;
} spark->zVel = zVel;
spark->fadeToBlack = 8; spark->friction = 68;
spark->colFadeSpeed = (GetRandomControl() & 3) + 4; spark->flags = 602;
spark->transType = COLADD; spark->rotAng = GetRandomControl() & 0xFFF;
spark->life = spark->sLife = (GetRandomControl() & 3) + 16; if (GetRandomControl() & 1)
spark->y = 0;
spark->x = (GetRandomControl() & 0xF) - 8;
spark->yVel = yVel;
spark->zVel = zVel;
spark->z = (GetRandomControl() & 0xF) - 8;
spark->xVel = xVel;
spark->friction = 68;
spark->flags = 602;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
{
spark->rotAdd = -32 - (GetRandomControl() & 0x1F);
}
else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
spark->scalar = 2;
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
}
}
void BubblesShatterFunction(FX_INFO* fx, int param1, int param2)
{
ShatterItem.yRot = fx->pos.yRot;
ShatterItem.meshp = &g_Level.Meshes[fx->frameNumber];
ShatterItem.sphere.x = fx->pos.xPos;
ShatterItem.sphere.y = fx->pos.yPos;
ShatterItem.sphere.z = fx->pos.zPos;
ShatterItem.bit = 0;
ShatterItem.flags = fx->flag2 & 0x400;
ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1);
}
void BubblesControl(short fxNum)
{
FX_INFO* fx = &EffectList[fxNum];
short angles[2];
phd_GetVectorAngles(
LaraItem->pos.xPos - fx->pos.xPos,
LaraItem->pos.yPos - fx->pos.yPos - STEP_SIZE,
LaraItem->pos.zPos - fx->pos.zPos,
angles);
int maxRotation = 0;
int maxSpeed = 0;
if (fx->flag1 == 1)
{
maxRotation = 512;
maxSpeed = 256;
}
else
{
if (fx->flag1 == 6)
{
if (fx->counter)
{ {
fx->counter--; spark->rotAdd = -32 - (GetRandomControl() & 0x1F);
} }
maxRotation = 256; else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
if (fx->flag1 == 1)
{
spark->scalar = 3;
}
else
{
spark->scalar = 2;
}
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
} }
else
{
maxRotation = 768;
}
maxSpeed = 192;
} }
if (fx->speed < maxSpeed) void TriggerHarpyFlameFlame(short fxNum, short xVel, short yVel, short zVel)
{ {
if (fx->flag1 == 6) FX_INFO* fx = &EffectList[fxNum];
int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{ {
fx->speed++; SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
spark->sR = 0;
spark->sG = (GetRandomControl() & 0x7F) + 32;
spark->sB = spark->dG + 64;
spark->dB = 0;
spark->dG = spark->dR = (GetRandomControl() & 0x7F) + 32;
spark->fadeToBlack = 8;
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
spark->y = 0;
spark->x = (GetRandomControl() & 0xF) - 8;
spark->xVel = xVel;
spark->zVel = zVel;
spark->z = (GetRandomControl() & 0xF) - 8;
spark->yVel = yVel;
spark->friction = 68;
spark->flags = 602;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
{
spark->rotAdd = -32 - (GetRandomControl() & 0x1F);
}
else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
spark->scalar = 2;
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
} }
else
{
fx->speed += 3;
}
int dy = angles[0] - fx->pos.yRot;
if (abs(dy) <= ANGLE(180.0f))
{
dy = -dy;
}
int dx = angles[1] - fx->pos.xRot;
if (abs(dx) <= ANGLE(180.0f))
dx = -dx;
dy /= 8;
dx /= 8;
if (dy < -maxRotation)
dy = -maxRotation;
else if (dy > maxRotation)
dy = maxRotation;
if (dx < -maxRotation)
dx = -maxRotation;
else if (dx > maxRotation)
dx = maxRotation;
if (fx->flag1 != 4 && (fx->flag1 != 6 || !fx->counter))
{
fx->pos.yRot += dy;
}
fx->pos.xRot += dx;
} }
fx->pos.zRot += 16 * fx->speed; void TriggerDemigodMissileFlame(short fxNum, short xVel, short yVel, short zVel)
if (fx->flag1 == 6)
fx->pos.zRot += 16 * fx->speed;
int oldX = fx->pos.xPos;
int oldY = fx->pos.yPos;
int oldZ = fx->pos.zPos;
int speed = (fx->speed * phd_cos(fx->pos.xRot));
fx->pos.zPos += (speed * phd_cos(fx->pos.yRot));
fx->pos.xPos += (speed * phd_sin(fx->pos.yRot));
fx->pos.yPos += -((fx->speed * phd_sin(fx->pos.xRot))) + fx->fallspeed;
short roomNumber = fx->roomNumber;
FLOOR_INFO* floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &roomNumber);
int floorHeight = GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos);
int ceilingHeight = GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos);
if (fx->pos.yPos >= floorHeight || fx->pos.yPos <= ceilingHeight)
{ {
fx->pos.xPos = oldX; FX_INFO* fx = &EffectList[fxNum];
fx->pos.yPos = oldY;
fx->pos.zPos = oldZ; int dx = LaraItem->pos.xPos - fx->pos.xPos;
int dz = LaraItem->pos.zPos - fx->pos.zPos;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{
SPARKS* spark = &Sparks[GetFreeSpark()];
spark->on = 1;
if (fx->flag1 == 3 || fx->flag1 == 4)
{
spark->sR = 0;
spark->dR = 0;
spark->sB = (GetRandomControl() & 0x7F) + 32;
spark->sG = spark->sB + 64;
spark->dG = (GetRandomControl() & 0x7F) + 32;
spark->dB = spark->dG + 64;
}
else
{
spark->sR = (GetRandomControl() & 0x7F) + 32;
spark->sG = spark->sR - (GetRandomControl() & 0x1F);
spark->sB = 0;
spark->dR = (GetRandomControl() & 0x7F) + 32;
spark->dB = 0;
spark->dG = spark->dR - (GetRandomControl() & 0x1F);
}
spark->fadeToBlack = 8;
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
spark->transType = COLADD;
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
spark->y = 0;
spark->x = (GetRandomControl() & 0xF) - 8;
spark->yVel = yVel;
spark->zVel = zVel;
spark->z = (GetRandomControl() & 0xF) - 8;
spark->xVel = xVel;
spark->friction = 68;
spark->flags = 602;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
{
spark->rotAdd = -32 - (GetRandomControl() & 0x1F);
}
else
{
spark->rotAdd = (GetRandomControl() & 0x1F) + 32;
}
spark->gravity = 0;
spark->maxYvel = 0;
spark->fxObj = fxNum;
spark->scalar = 2;
spark->sSize = spark->size = (GetRandomControl() & 7) + 64;
spark->dSize = spark->size / 32;
}
}
void BubblesShatterFunction(FX_INFO* fx, int param1, int param2)
{
ShatterItem.yRot = fx->pos.yRot;
ShatterItem.meshp = &g_Level.Meshes[fx->frameNumber];
ShatterItem.sphere.x = fx->pos.xPos;
ShatterItem.sphere.y = fx->pos.yPos;
ShatterItem.sphere.z = fx->pos.zPos;
ShatterItem.bit = 0;
ShatterItem.flags = fx->flag2 & 0x400;
ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1);
}
void ControlEnemyMissile(short fxNum)
{
FX_INFO* fx = &EffectList[fxNum];
short angles[2];
phd_GetVectorAngles(
LaraItem->pos.xPos - fx->pos.xPos,
LaraItem->pos.yPos - fx->pos.yPos - STEP_SIZE,
LaraItem->pos.zPos - fx->pos.zPos,
angles);
int maxRotation = 0;
int maxSpeed = 0;
if (fx->flag1 != 6)
BubblesShatterFunction(fx, 0, -32);
if (fx->flag1 == 1) if (fx->flag1 == 1)
{ {
TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); maxRotation = 512;
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber); maxSpeed = 256;
} }
else else
{ {
int shockwaveValue = 0; if (fx->flag1 == 6)
byte r, g, b, life;
if (fx->flag1)
{ {
if (fx->flag1 == 3 || fx->flag1 == 4) if (fx->counter)
{ {
shockwaveValue = 268451968; fx->counter--;
r = 128;
g = 64;
b = 0;
life = 16;
} }
else if (fx->flag1 == 5) maxRotation = 256;
}
else
{
maxRotation = 768;
}
maxSpeed = 192;
}
if (fx->speed < maxSpeed)
{
if (fx->flag1 == 6)
{
fx->speed++;
}
else
{
fx->speed += 3;
}
int dy = angles[0] - fx->pos.yRot;
if (abs(dy) <= ANGLE(180.0f))
{
dy = -dy;
}
int dx = angles[1] - fx->pos.xRot;
if (abs(dx) <= ANGLE(180.0f))
dx = -dx;
dy /= 8;
dx /= 8;
if (dy < -maxRotation)
dy = -maxRotation;
else if (dy > maxRotation)
dy = maxRotation;
if (dx < -maxRotation)
dx = -maxRotation;
else if (dx > maxRotation)
dx = maxRotation;
if (fx->flag1 != 4 && (fx->flag1 != 6 || !fx->counter))
{
fx->pos.yRot += dy;
}
fx->pos.xRot += dx;
}
fx->pos.zRot += 16 * fx->speed;
if (fx->flag1 == 6)
fx->pos.zRot += 16 * fx->speed;
int oldX = fx->pos.xPos;
int oldY = fx->pos.yPos;
int oldZ = fx->pos.zPos;
int speed = (fx->speed * phd_cos(fx->pos.xRot));
fx->pos.zPos += (speed * phd_cos(fx->pos.yRot));
fx->pos.xPos += (speed * phd_sin(fx->pos.yRot));
fx->pos.yPos += -((fx->speed * phd_sin(fx->pos.xRot))) + fx->fallspeed;
short roomNumber = fx->roomNumber;
FLOOR_INFO* floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &roomNumber);
int floorHeight = GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos);
int ceilingHeight = GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos);
if (fx->pos.yPos >= floorHeight || fx->pos.yPos <= ceilingHeight)
{
fx->pos.xPos = oldX;
fx->pos.yPos = oldY;
fx->pos.zPos = oldZ;
if (fx->flag1 != 6)
BubblesShatterFunction(fx, 0, -32);
if (fx->flag1 == 1)
{
TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 00, 24, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0);
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber);
}
else
{
int shockwaveValue = 0;
byte r, g, b, life;
if (fx->flag1)
{ {
shockwaveValue = 276848640; if (fx->flag1 == 3 || fx->flag1 == 4)
r = 0;
g = 96;
b = 128;
life = 16;
}
else
{
if (fx->flag1 != 2)
{ {
if (fx->flag1 == 6) shockwaveValue = 268451968;
{ r = 128;
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber); g = 64;
TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 2); b = 0;
fx->pos.yPos -= 128; life = 16;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2);
fx->pos.yPos += 256;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2);
}
} }
else else if (fx->flag1 == 5)
{ {
shockwaveValue = 276856832; shockwaveValue = 276848640;
r = 0; r = 0;
g = 128; g = 96;
b = 128; b = 128;
life = 16; life = 16;
} }
else
{
if (fx->flag1 != 2)
{
if (fx->flag1 == 6)
{
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber);
TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 2);
fx->pos.yPos -= 128;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2);
fx->pos.yPos += 256;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 2);
}
}
else
{
shockwaveValue = 276856832;
r = 0;
g = 128;
b = 128;
life = 16;
}
}
}
else
{
shockwaveValue = 268468288;
r = 64;
g = 128;
b = 0;
life = 16;
}
TriggerShockwave(&fx->pos, 32, 160, 64, r, g, b, life, 0, 0);
}
KillEffect(fxNum);
return;
}
if (ItemNearLara(&fx->pos, 200))
{
LaraItem->hitStatus = true;
if (fx->flag1 != 6)
{
BubblesShatterFunction(fx, 0, -32);
}
KillEffect(fxNum);
if (fx->flag1 == 1)
{
TriggerShockwave(&fx->pos, 48, 240, 64, 64, 128, 0, 24, 0, 0);
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber);
LaraBurn();
}
else if (fx->flag1)
{
switch (fx->flag1)
{
case 3:
case 4:
TriggerShockwave(&fx->pos, 32, 160, 64, 128, 64, 0, 16, 0, 1);
break;
case 5:
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 96, 128, 16, 0, 2);
break;
case 2:
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 128, 128, 16, 0, 2);
break;
case 6:
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber);
TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 0);
fx->pos.yPos -= 128;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0);
fx->pos.yPos += 256;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0);
LaraBurn();
break;
} }
} }
else else
{ {
shockwaveValue = 268468288; TriggerShockwave(&fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0);
r = 64;
g = 128;
b = 0;
life = 16;
}
TriggerShockwave(&fx->pos, 32, 160, 64, r, g, b, life, 0, 0);
}
KillEffect(fxNum);
return;
}
if (ItemNearLara(&fx->pos, 200))
{
LaraItem->hitStatus = true;
if (fx->flag1 != 6)
{
BubblesShatterFunction(fx, 0, -32);
}
KillEffect(fxNum);
if (fx->flag1 == 1)
{
TriggerShockwave(&fx->pos, 48, 240, 64, 64, 128, 0, 24, 0, 0);
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 2, fx->roomNumber);
LaraBurn();
}
else if (fx->flag1)
{
switch (fx->flag1)
{
case 3:
case 4:
TriggerShockwave(&fx->pos, 32, 160, 64, 128, 64, 0, 16, 0, 1);
break;
case 5:
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 96, 128, 16, 0, 2);
break;
case 2:
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 128, 128, 16, 0, 2);
break;
case 6:
TriggerExplosionSparks(oldX, oldY, oldZ, 3, -2, 0, fx->roomNumber);
TriggerShockwave(&fx->pos, 48, 240, 64, 0, 96, 128, 24, 0, 0);
fx->pos.yPos -= 128;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0);
fx->pos.yPos += 256;
TriggerShockwave(&fx->pos, 48, 240, 48, 0, 112, 128, 16, 0, 0);
LaraBurn();
break;
} }
} }
else else
{ {
TriggerShockwave( &fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0); if (roomNumber != fx->roomNumber)
} EffectNewRoom(fxNum, roomNumber);
}
else
{
if (roomNumber != fx->roomNumber)
EffectNewRoom(fxNum, roomNumber);
int dx = oldX - fx->pos.xPos; int dx = oldX - fx->pos.xPos;
int dy = oldY - fx->pos.yPos; int dy = oldY - fx->pos.yPos;
int dz = oldZ - fx->pos.zPos; int dz = oldZ - fx->pos.zPos;
if (Wibble & 4) if (Wibble & 4)
{
switch (fx->flag1)
{ {
switch (fx->flag1)
{
default: default:
case 1: case 1:
BubblesEffect1(fxNum, 32 * dx, 32 * dy, 32 * dz); TriggerSethMissileFlame(fxNum, 32 * dx, 32 * dy, 32 * dz);
break; break;
case 2: case 2:
BubblesEffect2(fxNum, 16 * dx, 16 * dy, 16 * dz); TriggerHarpyFlameFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
break; break;
case 3: case 3:
case 4: case 4:
case 5: case 5:
BubblesEffect4(fxNum, 16 * dx, 16 * dy, 16 * dz); TriggerDemigodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
break; break;
case 6: case 6:
TriggerMutantRocketEffects(fxNum, 16 * dx, 16 * dy, 16 * dz); ten::entities::tr4::TriggerCrocgodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
break; break;
}
} }
} }
} }

View file

@ -1,3 +1,6 @@
#pragma once #pragma once
void BubblesControl(short fxNum); namespace ten::entities::all
{
void ControlEnemyMissile(short fxNum);
}

View file

@ -104,7 +104,7 @@ void CrocodileControl(short itemNumber)
OBJECT_INFO* obj; OBJECT_INFO* obj;
CREATURE_INFO* crocodile; CREATURE_INFO* crocodile;
AI_INFO info; AI_INFO info;
OBJECT_Bones boneRot; OBJECT_BONES boneRot;
short angle; short angle;
short boneAngle; short boneAngle;

View file

@ -10,341 +10,324 @@
#include "objectslist.h" #include "objectslist.h"
#include "trmath.h" #include "trmath.h"
enum MUTANT_STATE namespace ten::entities::tr4
{ {
MUTANT_EMPTY, void TriggerCrocgodMissile(PHD_3DPOS* src, short roomNumber, short counter)
MUTANT_APPEAR,
MUTANT_IDLE,
MUTANT_SHOOT,
MUTANT_LOCUST1,
MUTANT_LOCUST2,
};
enum class MissileRotationType
{
M_FRONT,
M_LEFT,
M_RIGHT
};
constexpr auto MUTANT_ANIM_APPEAR = 0;
constexpr auto MUTANT_SHOOT_RANGE = SQUARE(SECTOR(10));
constexpr auto MUTANT_LOCUST1_RANGE = SQUARE(SECTOR(15));
constexpr auto MUTANT_LOCUST2_RANGE = SQUARE(SECTOR(30));
static void TriggerMutantRocket(PHD_3DPOS* src, short roomNumber, short counter)
{
FX_INFO* fx;
short fxNumber = NO_ITEM;
fxNumber = CreateNewEffect(roomNumber);
if (fxNumber != NO_ITEM)
{ {
FX_INFO* fx;
short fxNumber = NO_ITEM;
fxNumber = CreateNewEffect(roomNumber);
if (fxNumber != NO_ITEM)
{
fx = &EffectList[fxNumber];
fx->pos.xPos = src->xPos;
fx->pos.yPos = src->yPos - (GetRandomControl() & 0x3F) - 32;
fx->pos.zPos = src->zPos;
fx->pos.xRot = src->xRot;
fx->pos.yRot = src->yRot;
fx->pos.zRot = 0;
fx->roomNumber = roomNumber;
fx->counter = 16 * counter + 15;
fx->objectNumber = ID_ENERGY_BUBBLES;
fx->frameNumber = Objects[fx->objectNumber].meshIndex + 5 * 2;
fx->speed = (GetRandomControl() & 0x1F) + 96;
fx->flag1 = 6;
}
}
void TriggerCrocgodMissileFlame(short fxNumber, short xVel, short yVel, short zVel)
{
FX_INFO* fx;
SPARKS* sptr;
BYTE color, life, size;
//x = LaraItem->pos.xPos - Effects[m_fxNumber].pos.xPos;
//z = LaraItem->pos.zPos - Effects[m_fxNumber].pos.zPos;
//if (x >= -0x4000u && x <= 0x4000 && z >= -0x4000u && z <= 0x4000)
fx = &EffectList[fxNumber]; fx = &EffectList[fxNumber];
fx->pos.xPos = src->xPos; sptr = &Sparks[GetFreeSpark()];
fx->pos.yPos = src->yPos - (GetRandomControl() & 0x3F) - 32; sptr->on = true;
fx->pos.zPos = src->zPos; color = (GetRandomControl() & 0x3F) - 128;
fx->pos.xRot = src->xRot; sptr->sB = 0;
fx->pos.yRot = src->yRot; sptr->sR = color;
fx->pos.zRot = 0; sptr->sG = color / 2;
fx->roomNumber = roomNumber; color = (GetRandomControl() & 0x3F) - 128;
fx->counter = 16 * counter + 15; sptr->dB = 0;
fx->objectNumber = ID_ENERGY_BUBBLES; sptr->dR = color;
fx->frameNumber = Objects[fx->objectNumber].meshIndex + 5 * 2; sptr->dG = color / 2;
fx->speed = (GetRandomControl() & 0x1F) + 96; sptr->fadeToBlack = 8;
fx->flag1 = 6; sptr->colFadeSpeed = (GetRandomControl() & 3) + 8;
} sptr->transType = TransTypeEnum::COLADD;
} sptr->dynamic = -1;
life = (GetRandomControl() & 7) + 32;
void TriggerMutantRocketEffects(short fxNumber, short xVel, short yVel, short zVel) sptr->life = life;
{ sptr->sLife = life;
FX_INFO* fx; sptr->x = (GetRandomControl() & 0xF) - 8;
SPARKS* sptr; sptr->y = 0;
BYTE color, life, size; sptr->z = (GetRandomControl() & 0xF) - 8;
sptr->x += fx->pos.xPos;
//x = LaraItem->pos.xPos - Effects[m_fxNumber].pos.xPos; sptr->y += fx->pos.yPos;
//z = LaraItem->pos.zPos - Effects[m_fxNumber].pos.zPos; sptr->z += fx->pos.zPos;
//if (x >= -0x4000u && x <= 0x4000 && z >= -0x4000u && z <= 0x4000) sptr->xVel = xVel;
sptr->yVel = yVel;
fx = &EffectList[fxNumber]; sptr->zVel = zVel;
sptr = &Sparks[GetFreeSpark()]; sptr->friction = 34;
sptr->on = true; sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE;
color = (GetRandomControl() & 0x3F) - 128; sptr->rotAng = GetRandomControl() & 0xFFF;
sptr->sB = 0; if (GetRandomControl() & 1)
sptr->sR = color; sptr->rotAdd = (GetRandomControl() & 0x1F) - 32;
sptr->sG = color / 2; else
color = (GetRandomControl() & 0x3F) - 128; sptr->rotAdd = (GetRandomControl() & 0x1F) + 32;
sptr->dB = 0; sptr->gravity = 0;
sptr->dR = color; sptr->maxYvel = 0;
sptr->dG = color / 2; sptr->fxObj = byte(fxNumber);
sptr->fadeToBlack = 8; sptr->scalar = 2;
sptr->colFadeSpeed = (GetRandomControl() & 3) + 8; size = (GetRandomControl() & 0xF) + 128;
sptr->transType = COLADD; sptr->size = size;
sptr->dynamic = -1; sptr->sSize = size;
life = (GetRandomControl() & 7) + 32; sptr->dSize = size / 4;
sptr->life = life;
sptr->sLife = life;
sptr->x = (GetRandomControl() & 0xF) - 8;
sptr->y = 0;
sptr->z = (GetRandomControl() & 0xF) - 8;
sptr->x += fx->pos.xPos;
sptr->y += fx->pos.yPos;
sptr->z += fx->pos.zPos;
sptr->xVel = xVel;
sptr->yVel = yVel;
sptr->zVel = zVel;
sptr->friction = 34;
sptr->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE;
sptr->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
sptr->rotAdd = (GetRandomControl() & 0x1F) - 32;
else
sptr->rotAdd = (GetRandomControl() & 0x1F) + 32;
sptr->gravity = 0;
sptr->maxYvel = 0;
sptr->fxObj = byte(fxNumber);
sptr->scalar = 2;
size = (GetRandomControl() & 0xF) + 128;
sptr->size = size;
sptr->sSize = size;
sptr->dSize = size / 4;
}
static void ShootFireball(PHD_3DPOS* src, MissileRotationType rotation, short roomNumber, int timer)
{
switch (rotation)
{
case MissileRotationType::M_LEFT:
src->yRot -= GetRandomControl() % 0x2000;
break;
case MissileRotationType::M_RIGHT:
src->yRot += GetRandomControl() % 0x2000;
break;
} }
TriggerMutantRocket(src, roomNumber, timer); static void ShootFireball(PHD_3DPOS* src, MissileRotationType rotation, short roomNumber, int timer)
}
static bool ShootFrame(ITEM_INFO* item)
{
short frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
if (frameNumber == 45
//|| frameNumber == 50
//|| frameNumber == 55
|| frameNumber == 60
//|| frameNumber == 65
//|| frameNumber == 70
|| frameNumber == 75)
return true;
else
return false;
}
static void RotateHeadToTarget(ITEM_INFO* item, CREATURE_INFO* creature, int joint, short& headAngle)
{
if (creature->enemy == nullptr)
{ {
headAngle = item->pos.yRot; switch (rotation)
return;
}
ITEM_INFO* enemy = creature->enemy;
PHD_VECTOR pos;
int x, z;
pos.x = 0;
pos.y = 0;
pos.z = 0;
GetJointAbsPosition(item, &pos, joint);
x = enemy->pos.xPos - pos.x;
z = enemy->pos.zPos - pos.z;
headAngle = (short)(phd_atan(z, x) - item->pos.yRot) / 2;
}
static void GetTargetPosition(ITEM_INFO* item, PHD_3DPOS* target)
{
PHD_VECTOR start, end;
short angles[2];
start.x = 0;
start.y = -96;
start.z = 144;
GetJointAbsPosition(item, &start, 9);
end.x = 0;
end.y = -128;
end.z = 288;
GetJointAbsPosition(item, &end, 9);
phd_GetVectorAngles(end.x - start.x, end.y - start.y, end.z - start.z, angles);
target->xPos = end.x;
target->yPos = end.y;
target->zPos = end.z;
target->yRot = angles[0];
target->xRot = angles[1];
target->zRot = 0;
}
enum CARDINAL_POINT
{
C_NORTH = 0,
C_NORTH_EAST = 45,
C_EAST = 90,
C_EAST_SOUTH = 135,
C_SOUTH = 180,
C_SOUTH_WEST = 225,
C_WEST = 270,
C_WEST_NORTH = 315
};
static void MoveItemFront(ITEM_INFO* item, int distance)
{
short degree = short(TO_DEGREES(item->pos.yRot));
switch (degree)
{
case C_NORTH:
item->pos.zPos += distance;
break;
case C_EAST:
item->pos.xPos += distance;
break;
case C_SOUTH:
item->pos.zPos -= distance;
break;
case C_WEST:
item->pos.xPos -= distance;
break;
}
}
static void MoveItemBack(ITEM_INFO* item, int distance)
{
short degree = short(TO_DEGREES(item->pos.yRot));
switch (degree)
{
case C_NORTH:
item->pos.zPos -= distance;
break;
case C_EAST:
item->pos.xPos -= distance;
break;
case C_SOUTH:
item->pos.zPos += distance;
break;
case C_WEST:
item->pos.xPos += distance;
break;
}
}
static void MutantAIFix(ITEM_INFO* item, AI_INFO* info)
{
MoveItemFront(item, SECTOR(2));
item->pos.yPos -= CLICK(3);
CreatureAIInfo(item, info);
item->pos.yPos += CLICK(3);
MoveItemBack(item, SECTOR(2));
}
void InitialiseMutant(short itemNumber)
{
ITEM_INFO* item;
InitialiseCreature(itemNumber);
item = &g_Level.Items[itemNumber];
item->animNumber = Objects[item->objectNumber].animIndex + MUTANT_ANIM_APPEAR;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = MUTANT_APPEAR;
item->goalAnimState = MUTANT_APPEAR;
}
void MutantControl(short itemNumber)
{
if (!CreatureActive(itemNumber))
return;
ITEM_INFO* item;
CREATURE_INFO* mutant;
AI_INFO info;
OBJECT_Bones mutant_joint;
short frameNumber;
short headY;
short angle;
item = &g_Level.Items[itemNumber];
mutant = GetCreatureInfo(item);
angle = 0;
headY = 0;
if (item->aiBits & ALL_AIOBJ)
GetAITarget(mutant);
else if (mutant->hurtByLara)
mutant->enemy = LaraItem;
else
TargetNearestEntity(item, mutant);
MutantAIFix(item, &info);
RotateHeadToTarget(item, mutant, 9, headY);
GetCreatureMood(item, &info, VIOLENT);
CreatureMood(item, &info, VIOLENT);
mutant->maximumTurn = 0;
angle = CreatureTurn(item, 0);
switch (item->currentAnimState)
{
case MUTANT_IDLE:
if (info.ahead)
{ {
int random = GetRandomControl() & 31; case MissileRotationType::M_LEFT:
if ((random > 0 && random < 10) && info.distance <= MUTANT_SHOOT_RANGE) src->yRot -= GetRandomControl() % 0x2000;
item->goalAnimState = MUTANT_SHOOT; break;
else if ((random > 10 && random < 20) && info.distance <= MUTANT_LOCUST1_RANGE) case MissileRotationType::M_RIGHT:
item->goalAnimState = MUTANT_LOCUST1; src->yRot += GetRandomControl() % 0x2000;
else if ((random > 20 && random < 30) && info.distance <= MUTANT_LOCUST2_RANGE) break;
item->goalAnimState = MUTANT_LOCUST2;
} }
break;
case MUTANT_SHOOT: TriggerCrocgodMissile(src, roomNumber, timer);
frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
if (frameNumber >= 94 && frameNumber <= 96)
{
PHD_3DPOS src;
GetTargetPosition(item, &src);
if (frameNumber == 94)
{
ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 0);
}
else if (frameNumber == 95)
{
ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1);
//ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1);
}
else if (frameNumber == 96)
{
ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1);
//ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1);
}
}
break;
case MUTANT_LOCUST1:
frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
if (frameNumber >= 60 && frameNumber <= 120)
ten::entities::tr4::SpawnLocust(item);
break;
case MUTANT_LOCUST2:
if (ShootFrame(item))
{
PHD_3DPOS src;
GetTargetPosition(item, &src);
ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 1);
}
break;
} }
if (item->currentAnimState != MUTANT_LOCUST1) static bool ShootFrame(ITEM_INFO* item)
mutant_joint = OBJECT_Bones(headY, info.xAngle, true); {
else short frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
mutant_joint = OBJECT_Bones(0); if (frameNumber == 45
//|| frameNumber == 50
//|| frameNumber == 55
|| frameNumber == 60
//|| frameNumber == 65
//|| frameNumber == 70
|| frameNumber == 75)
return true;
else
return false;
}
CreatureJoint(item, 0, mutant_joint.bone0); static void RotateHeadToTarget(ITEM_INFO* item, CREATURE_INFO* creature, int joint, short& headAngle)
CreatureJoint(item, 1, mutant_joint.bone1); {
CreatureJoint(item, 2, mutant_joint.bone2); if (creature->enemy == nullptr)
CreatureJoint(item, 3, mutant_joint.bone3); {
CreatureAnimation(itemNumber, angle, 0); headAngle = item->pos.yRot;
} return;
}
ITEM_INFO* enemy = creature->enemy;
PHD_VECTOR pos;
int x, z;
pos.x = 0;
pos.y = 0;
pos.z = 0;
GetJointAbsPosition(item, &pos, joint);
x = enemy->pos.xPos - pos.x;
z = enemy->pos.zPos - pos.z;
headAngle = (short)(phd_atan(z, x) - item->pos.yRot) / 2;
}
static void GetTargetPosition(ITEM_INFO* item, PHD_3DPOS* target)
{
PHD_VECTOR start, end;
short angles[2];
start.x = 0;
start.y = -96;
start.z = 144;
GetJointAbsPosition(item, &start, 9);
end.x = 0;
end.y = -128;
end.z = 288;
GetJointAbsPosition(item, &end, 9);
phd_GetVectorAngles(end.x - start.x, end.y - start.y, end.z - start.z, angles);
target->xPos = end.x;
target->yPos = end.y;
target->zPos = end.z;
target->yRot = angles[0];
target->xRot = angles[1];
target->zRot = 0;
}
enum CARDINAL_POINT
{
C_NORTH = 0,
C_NORTH_EAST = 45,
C_EAST = 90,
C_EAST_SOUTH = 135,
C_SOUTH = 180,
C_SOUTH_WEST = 225,
C_WEST = 270,
C_WEST_NORTH = 315
};
static void MoveItemFront(ITEM_INFO* item, int distance)
{
short degree = short(TO_DEGREES(item->pos.yRot));
switch (degree)
{
case C_NORTH:
item->pos.zPos += distance;
break;
case C_EAST:
item->pos.xPos += distance;
break;
case C_SOUTH:
item->pos.zPos -= distance;
break;
case C_WEST:
item->pos.xPos -= distance;
break;
}
}
static void MoveItemBack(ITEM_INFO* item, int distance)
{
short degree = short(TO_DEGREES(item->pos.yRot));
switch (degree)
{
case C_NORTH:
item->pos.zPos -= distance;
break;
case C_EAST:
item->pos.xPos -= distance;
break;
case C_SOUTH:
item->pos.zPos += distance;
break;
case C_WEST:
item->pos.xPos += distance;
break;
}
}
static void MutantAIFix(ITEM_INFO* item, AI_INFO* info)
{
MoveItemFront(item, SECTOR(2));
item->pos.yPos -= CLICK(3);
CreatureAIInfo(item, info);
item->pos.yPos += CLICK(3);
MoveItemBack(item, SECTOR(2));
}
void InitialiseCrocgod(short itemNumber)
{
ITEM_INFO* item;
InitialiseCreature(itemNumber);
item = &g_Level.Items[itemNumber];
item->animNumber = Objects[item->objectNumber].animIndex + MUTANT_ANIM_APPEAR;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_MUTANT_APPEAR;
item->goalAnimState = STATE_MUTANT_APPEAR;
}
void CrocgodControl(short itemNumber)
{
if (!CreatureActive(itemNumber))
return;
ITEM_INFO* item;
CREATURE_INFO* mutant;
AI_INFO info;
OBJECT_BONES mutant_joint;
short frameNumber;
short headY;
short angle;
item = &g_Level.Items[itemNumber];
mutant = GetCreatureInfo(item);
angle = 0;
headY = 0;
if (item->aiBits & ALL_AIOBJ)
GetAITarget(mutant);
else if (mutant->hurtByLara)
mutant->enemy = LaraItem;
else
TargetNearestEntity(item, mutant);
MutantAIFix(item, &info);
RotateHeadToTarget(item, mutant, 9, headY);
GetCreatureMood(item, &info, VIOLENT);
CreatureMood(item, &info, VIOLENT);
mutant->maximumTurn = 0;
angle = CreatureTurn(item, 0);
switch (item->currentAnimState)
{
case STATE_MUTANT_IDLE:
if (info.ahead)
{
int random = GetRandomControl() & 31;
if ((random > 0 && random < 10) && info.distance <= MUTANT_SHOOT_RANGE)
item->goalAnimState = STATE_MUTANT_SHOOT;
else if ((random > 10 && random < 20) && info.distance <= MUTANT_LOCUST1_RANGE)
item->goalAnimState = STATE_MUTANT_LOCUST1;
else if ((random > 20 && random < 30) && info.distance <= MUTANT_LOCUST2_RANGE)
item->goalAnimState = STATE_MUTANT_LOCUST2;
}
break;
case STATE_MUTANT_SHOOT:
frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
if (frameNumber >= 94 && frameNumber <= 96)
{
PHD_3DPOS src;
GetTargetPosition(item, &src);
if (frameNumber == 94)
{
ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 0);
}
else if (frameNumber == 95)
{
ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1);
//ShootFireball(&src, MissileRotationType::M_LEFT, item->roomNumber, 1);
}
else if (frameNumber == 96)
{
ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1);
//ShootFireball(&src, MissileRotationType::M_RIGHT, item->roomNumber, 1);
}
}
break;
case STATE_MUTANT_LOCUST1:
frameNumber = (item->frameNumber - g_Level.Anims[item->objectNumber].frameBase);
if (frameNumber >= 60 && frameNumber <= 120)
ten::entities::tr4::SpawnLocust(item);
break;
case STATE_MUTANT_LOCUST2:
if (ShootFrame(item))
{
PHD_3DPOS src;
GetTargetPosition(item, &src);
ShootFireball(&src, MissileRotationType::M_FRONT, item->roomNumber, 1);
}
break;
}
if (item->currentAnimState != STATE_MUTANT_LOCUST1)
mutant_joint = OBJECT_BONES(headY, info.xAngle, true);
else
mutant_joint = OBJECT_BONES(0);
CreatureJoint(item, 0, mutant_joint.bone0);
CreatureJoint(item, 1, mutant_joint.bone1);
CreatureJoint(item, 2, mutant_joint.bone2);
CreatureJoint(item, 3, mutant_joint.bone3);
CreatureAnimation(itemNumber, angle, 0);
}
}

View file

@ -1,5 +1,33 @@
#pragma once #pragma once
void InitialiseMutant(short itemNumber); #include "framework.h"
void MutantControl(short itemNumber); #include "trmath.h"
void TriggerMutantRocketEffects(short fxNumber, short xVel, short yVel, short zVel);
namespace ten::entities::tr4
{
enum MUTANT_STATE
{
STATE_MUTANT_EMPTY,
STATE_MUTANT_APPEAR,
STATE_MUTANT_IDLE,
STATE_MUTANT_SHOOT,
STATE_MUTANT_LOCUST1,
STATE_MUTANT_LOCUST2,
};
enum class MissileRotationType
{
M_FRONT,
M_LEFT,
M_RIGHT
};
constexpr auto MUTANT_ANIM_APPEAR = 0;
constexpr auto MUTANT_SHOOT_RANGE = SQUARE(SECTOR(10));
constexpr auto MUTANT_LOCUST1_RANGE = SQUARE(SECTOR(15));
constexpr auto MUTANT_LOCUST2_RANGE = SQUARE(SECTOR(30));
void InitialiseCrocgod(short itemNumber);
void CrocgodControl(short itemNumber);
void TriggerCrocgodMissileFlame(short fxNumber, short xVel, short yVel, short zVel);
}

View file

@ -664,8 +664,8 @@ static void StartBaddy(OBJECT_INFO* obj)
obj = &Objects[ID_CROCODILE_GOD]; obj = &Objects[ID_CROCODILE_GOD];
if (obj->loaded) if (obj->loaded)
{ {
obj->initialise = InitialiseMutant; obj->initialise = ten::entities::tr4::InitialiseCrocgod;
obj->control = MutantControl; obj->control = ten::entities::tr4::CrocgodControl;
obj->collision = CreatureCollision; obj->collision = CreatureCollision;
obj->shadowSize = UNIT_SHADOW / 2; obj->shadowSize = UNIT_SHADOW / 2;
obj->hitPoints = NOT_TARGETABLE; obj->hitPoints = NOT_TARGETABLE;

View file

@ -1241,7 +1241,7 @@ static void StartShatter(OBJECT_INFO *obj)
static void StartProjectiles(OBJECT_INFO *obj) static void StartProjectiles(OBJECT_INFO *obj)
{ {
InitProjectile(obj, BubblesControl, ID_ENERGY_BUBBLES, true); InitProjectile(obj, ten::entities::all::ControlEnemyMissile, ID_ENERGY_BUBBLES, true);
InitProjectile(obj, MissileControl, ID_BUBBLES, true); InitProjectile(obj, MissileControl, ID_BUBBLES, true);
InitProjectile(obj, MissileControl, ID_IMP_ROCK, true); InitProjectile(obj, MissileControl, ID_IMP_ROCK, true);
InitProjectile(obj, TorpedoControl, ID_TORPEDO); InitProjectile(obj, TorpedoControl, ID_TORPEDO);

View file

@ -110,7 +110,7 @@ enum GAME_OBJECT_ID : short
ID_DOBERMAN, ID_DOBERMAN,
ID_HAMMERHEAD, // TR4 - OK ID_HAMMERHEAD, // TR4 - OK
ID_CROCODILE_GOD, // TR4 Citadel Gate Mutant ID_CROCODILE_GOD, // TR4 Citadel Gate Mutant
ID_LOCUSTS_EMITTER, ID_LOCUSTS_EMITTER, // TR4 - OK
/* Humans */ /* Humans */
ID_SCUBA_HARPOON = 150, ID_SCUBA_HARPOON = 150,

View file

@ -711,7 +711,6 @@ xcopy /Y "$(ProjectDir)Shaders\HUD\*.hlsl" "$(TargetDir)\Shaders\HUD\"</Command>
<ClCompile Include="Scripting\GameScriptSinkInfo.cpp" /> <ClCompile Include="Scripting\GameScriptSinkInfo.cpp" />
<ClCompile Include="Scripting\GameScriptSkyLayer.cpp" /> <ClCompile Include="Scripting\GameScriptSkyLayer.cpp" />
<ClCompile Include="Scripting\GameScriptSoundSourceInfo.cpp" /> <ClCompile Include="Scripting\GameScriptSoundSourceInfo.cpp" />
<ClCompile Include="Scripting\LanguageScript.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_demigod.cpp" /> <ClCompile Include="Objects\TR4\Entity\tr4_demigod.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_guide.cpp" /> <ClCompile Include="Objects\TR4\Entity\tr4_guide.cpp" />
<ClCompile Include="Objects\TR4\Entity\tr4_jeanyves.cpp" /> <ClCompile Include="Objects\TR4\Entity\tr4_jeanyves.cpp" />