TombEngine/TR5Main/Objects/Effects/tr4_bubbles.cpp
2021-08-28 06:37:22 +02:00

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;
}
}
}
}
}