mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-08 03:28:03 +03:00
420 lines
No EOL
10 KiB
C++
420 lines
No EOL
10 KiB
C++
#include "framework.h"
|
|
#include "tr4_bubbles.h"
|
|
#include "effect2.h"
|
|
#include "debris.h"
|
|
#include "items.h"
|
|
#include "traps.h"
|
|
#include "draw.h"
|
|
#include "tomb4fx.h"
|
|
#include "effect.h"
|
|
#include "level.h"
|
|
#include "lara.h"
|
|
#include "tr4_mutant.h"
|
|
|
|
namespace ten::entities::all
|
|
{
|
|
void TriggerSethMissileFlame(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;
|
|
spark->sR = 0;
|
|
spark->dR = 0;
|
|
spark->sG = (GetRandomControl() & 0x7F) + 32;
|
|
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 = TransTypeEnum::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);
|
|
}
|
|
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 TriggerHarpyFlameFlame(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;
|
|
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 TriggerDemigodMissileFlame(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->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 == 1)
|
|
{
|
|
maxRotation = 512;
|
|
maxSpeed = 256;
|
|
}
|
|
else
|
|
{
|
|
if (fx->flag1 == 6)
|
|
{
|
|
if (fx->counter)
|
|
{
|
|
fx->counter--;
|
|
}
|
|
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
|
|
{
|
|
if (fx->flag1)
|
|
{
|
|
if (fx->flag1 == 3 || fx->flag1 == 4)
|
|
{
|
|
TriggerShockwave(&fx->pos, 32, 160, 64, 128, 64, 0, 16, 0, 0);
|
|
}
|
|
else if (fx->flag1 == 5)
|
|
{
|
|
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 96, 128, 16, 0, 0);
|
|
}
|
|
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
|
|
{
|
|
TriggerShockwave(&fx->pos, 32, 160, 64, 0, 128, 128, 16, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TriggerShockwave(&fx->pos, 32, 160, 64, 64, 128, 0, 16, 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
|
|
{
|
|
TriggerShockwave(&fx->pos, 24, 88, 48, 64, 128, 0, 16, (((~g_Level.Rooms[fx->roomNumber].flags) / 16) & 2) * 65536, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (roomNumber != fx->roomNumber)
|
|
EffectNewRoom(fxNum, roomNumber);
|
|
|
|
int dx = oldX - fx->pos.xPos;
|
|
int dy = oldY - fx->pos.yPos;
|
|
int dz = oldZ - fx->pos.zPos;
|
|
|
|
if (Wibble & 4)
|
|
{
|
|
switch (fx->flag1)
|
|
{
|
|
default:
|
|
case 1:
|
|
TriggerSethMissileFlame(fxNum, 32 * dx, 32 * dy, 32 * dz);
|
|
break;
|
|
case 2:
|
|
TriggerHarpyFlameFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
TriggerDemigodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
|
|
break;
|
|
case 6:
|
|
TEN::Entities::TR4::TriggerCrocgodMissileFlame(fxNum, 16 * dx, 16 * dy, 16 * dz);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |