TombEngine/TR5Main/Game/effects/bubble.cpp

125 lines
3.7 KiB
C++
Raw Normal View History

#include "framework.h"
2021-12-22 16:23:57 +03:00
#include "Game/effects/bubble.h"
2021-12-24 03:32:19 +03:00
#include "Game/collision/collide_room.h"
2021-12-22 16:23:57 +03:00
#include "Game/control/control.h"
#include "Objects/objectslist.h"
2021-12-24 03:32:19 +03:00
#include "Specific/level.h"
2021-12-22 16:23:57 +03:00
#include "Specific/setup.h"
#include "Specific/prng.h"
2021-12-24 03:32:19 +03:00
#include "Specific/trmath.h"
2021-12-22 16:23:57 +03:00
using std::vector;
2021-08-30 18:03:21 +03:00
using namespace TEN::Math::Random;
2021-12-22 16:23:57 +03:00
2020-04-13 13:36:23 +02:00
extern vector<BUBBLE_STRUCT> Bubbles = vector<BUBBLE_STRUCT>(MAX_BUBBLES);
void DisableBubbles()
{
for (int i = 0; i < MAX_BUBBLES; i++)
{
auto* bubble = &Bubbles[i];
bubble->active = false;
}
}
2020-04-13 13:36:23 +02:00
void UpdateBubbles()
{
for (int i = 0; i < MAX_BUBBLES; i++)
{
auto* bubble = &Bubbles[i];
if (!bubble->active)
2020-04-13 13:36:23 +02:00
continue;
2020-04-13 13:36:23 +02:00
bubble->age++;
float alpha = bubble->age / 15.0f;
2020-04-13 13:36:23 +02:00
alpha = fmin(alpha, 1.0f);
bubble->size = lerp(0, bubble->destinationSize, alpha);
bubble->color = Vector4::Lerp(bubble->sourceColor, bubble->destinationColor, alpha);
int ceilingHeight = g_Level.Rooms[bubble->roomNumber].maxceiling;
2020-04-13 13:36:23 +02:00
short roomNumber = bubble->roomNumber;
auto probe = GetCollision(bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z, bubble->roomNumber);
2020-04-13 13:36:23 +02:00
FLOOR_INFO* floor = GetFloor(bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z, &roomNumber);
if (bubble->worldPosition.y > probe.Position.Floor || !floor)
2020-04-13 13:36:23 +02:00
{
bubble->active = 0;
continue;
}
if (!TestEnvironment(ENV_FLAG_WATER, probe.RoomNumber))
2020-04-13 13:36:23 +02:00
{
SetupRipple(bubble->worldPosition.x, g_Level.Rooms[bubble->roomNumber].maxceiling, bubble->worldPosition.z, (GetRandomControl() & 0xF) + 48, RIPPLE_FLAG_SHORT_LIFE + RIPPLE_FLAG_RAND_ROT, Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_RIPPLES);
2020-04-13 13:36:23 +02:00
bubble->active = false;
continue;
}
if (probe.Position.Ceiling == NO_HEIGHT || bubble->worldPosition.y <= probe.Position.Ceiling)
2020-04-13 13:36:23 +02:00
{
bubble->active = false;
continue;
}
bubble->wavePeriod += bubble->waveSpeed;
bubble->worldPositionCenter.y -= bubble->speed;
bubble->worldPosition = bubble->worldPositionCenter + bubble->amplitude * Vector3(sin(bubble->wavePeriod.x), sin(bubble->wavePeriod.y), sin(bubble->wavePeriod.z));
}
}
2021-02-03 01:50:59 -03:00
int GetFreeBubble()
2020-04-13 13:36:23 +02:00
{
int oldestLifeIndex = 0;
2020-04-13 13:36:23 +02:00
int oldestAge = 0;
for (int i = 0; i < MAX_BUBBLES; i++)
{
auto* bubble = &Bubbles[i];
if (!bubble->active)
2020-04-13 13:36:23 +02:00
return i;
if (oldestAge < bubble->age)
{
oldestAge = bubble->age;
oldestLifeIndex = i;
2020-04-13 13:36:23 +02:00
}
}
// In case we don't find any inactive bubble, take the oldest one.
return oldestLifeIndex;
2020-04-13 13:36:23 +02:00
}
2021-02-03 01:50:59 -03:00
void CreateBubble(PHD_VECTOR* pos, short roomNum, int unk1, int unk2, int flags, int xv, int yv, int zv)
2020-04-13 13:36:23 +02:00
{
if (g_Level.Rooms[roomNum].flags & ENV_FLAG_WATER)
2020-04-13 13:36:23 +02:00
{
auto* bubble = &Bubbles[GetFreeBubble()];
2020-04-13 13:36:23 +02:00
bubble->active = true;
bubble->size = 0;
bubble->age = 0;
2021-09-17 16:07:53 +03:00
bubble->speed = flags & BUBBLE_FLAG_CLUMP ? GenerateFloat(8, 16) : GenerateFloat(8, 12);
2020-04-13 13:36:23 +02:00
bubble->sourceColor = Vector4(0, 0, 0, 1);
2021-09-17 16:07:53 +03:00
float shade = GenerateFloat(0.3, 0.8);
2020-04-13 13:36:23 +02:00
bubble->destinationColor = Vector4(shade, shade, shade, 1);
bubble->color = bubble->sourceColor;
2021-09-17 16:07:53 +03:00
bubble->destinationSize = flags & BUBBLE_FLAG_BIG_SIZE ? GenerateFloat(256, 512) : GenerateFloat(32, 128);
2020-04-13 13:36:23 +02:00
bubble->spriteNum = flags & BUBBLE_FLAG_CLUMP ? SPR_UNKNOWN1 : SPR_BUBBLES;
2020-05-23 14:26:06 +02:00
bubble->rotation = 0;
2020-04-13 13:36:23 +02:00
bubble->worldPosition = Vector3(pos->x, pos->y, pos->z);
float maxAmplitude = (flags & BUBBLE_FLAG_HIGH_AMPLITUDE) ? 256 : 32;
2021-09-17 16:07:53 +03:00
bubble->amplitude = Vector3(GenerateFloat(-maxAmplitude, maxAmplitude), GenerateFloat(-maxAmplitude, maxAmplitude), GenerateFloat(-maxAmplitude, maxAmplitude));
2020-04-13 13:36:23 +02:00
bubble->worldPositionCenter = bubble->worldPosition;
bubble->wavePeriod = Vector3::Zero;
2021-09-17 16:07:53 +03:00
bubble->waveSpeed = Vector3(1 / GenerateFloat(8, 16), 1 / GenerateFloat(8, 16), 1 / GenerateFloat(8, 16));
2020-04-13 13:36:23 +02:00
bubble->roomNumber = roomNum;
}
}