2020-05-27 09:21:20 +02:00
|
|
|
#include "framework.h"
|
2020-04-13 13:36:23 +02:00
|
|
|
#include "bubble.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "level.h"
|
2020-04-24 19:15:05 +02:00
|
|
|
#include "control.h"
|
2020-05-30 15:55:23 +02:00
|
|
|
#include "trmath.h"
|
|
|
|
#include "objectslist.h"
|
2020-06-20 23:39:08 +02:00
|
|
|
using std::vector;
|
2020-04-13 13:36:23 +02:00
|
|
|
extern vector<BUBBLE_STRUCT> Bubbles = vector<BUBBLE_STRUCT>(MAX_BUBBLES);
|
|
|
|
|
|
|
|
void UpdateBubbles()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < MAX_BUBBLES; i++)
|
|
|
|
{
|
|
|
|
BUBBLE_STRUCT* bubble = &Bubbles[i];
|
|
|
|
if (!bubble->active) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
bubble->age++;
|
2020-04-13 15:57:28 +02:00
|
|
|
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);
|
2020-07-21 09:56:47 +02:00
|
|
|
int ceilingHeight = g_Level.Rooms[bubble->roomNumber].maxceiling;
|
2020-04-13 13:36:23 +02:00
|
|
|
short roomNumber = bubble->roomNumber;
|
|
|
|
|
|
|
|
|
|
|
|
FLOOR_INFO* floor = GetFloor(bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z, &roomNumber);
|
|
|
|
int height = GetFloorHeight(floor, bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z);
|
|
|
|
|
|
|
|
if (bubble->worldPosition.y > height || !floor)
|
|
|
|
{
|
|
|
|
bubble->active = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
if (!(g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER))
|
2020-04-13 13:36:23 +02:00
|
|
|
{
|
2020-07-21 09:56:47 +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);
|
2020-04-13 13:36:23 +02:00
|
|
|
bubble->active = false;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ceiling = GetCeiling(floor, bubble->worldPosition.x, bubble->worldPosition.y, bubble->worldPosition.z);
|
|
|
|
if (ceiling == NO_HEIGHT || bubble->worldPosition.y <= ceiling)
|
|
|
|
{
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetFreeBubble() //8BEAC(<), 8DEF0(<) (F)
|
|
|
|
{
|
|
|
|
int oldestAgeIndex = 0;
|
|
|
|
int oldestAge = 0;
|
2020-05-30 15:55:23 +02:00
|
|
|
for (int i = 0; i < MAX_BUBBLES; i++)
|
|
|
|
{
|
2020-04-13 13:36:23 +02:00
|
|
|
BUBBLE_STRUCT* bub = &Bubbles[i];
|
2020-05-30 15:55:23 +02:00
|
|
|
if (!bub->active)
|
2020-04-13 13:36:23 +02:00
|
|
|
return i;
|
2020-05-30 15:55:23 +02:00
|
|
|
|
|
|
|
if (oldestAge < bub->age)
|
|
|
|
{
|
2020-04-13 13:36:23 +02:00
|
|
|
oldestAge = bub->age;
|
|
|
|
oldestAgeIndex = i;
|
|
|
|
}
|
|
|
|
}
|
2020-05-30 15:55:23 +02:00
|
|
|
|
2020-04-13 13:36:23 +02:00
|
|
|
//incase we dont find any non-active bubble, take the one with the oldest age
|
|
|
|
return oldestAgeIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreateBubble(PHD_VECTOR* pos, short roomNum, int unk1, int unk2, int flags, int xv, int yv, int zv) //8BF14(<), 8DF58(<) (F)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
if (g_Level.Rooms[roomNum].flags & ENV_FLAG_WATER)
|
2020-04-13 13:36:23 +02:00
|
|
|
{
|
|
|
|
BUBBLE_STRUCT* bubble = &Bubbles[GetFreeBubble()];
|
|
|
|
bubble->active = true;
|
|
|
|
bubble->size = 0;
|
|
|
|
bubble->age = 0;
|
2020-05-23 14:26:06 +02:00
|
|
|
bubble->speed = flags & BUBBLE_FLAG_CLUMP ? frandMinMax(8, 16) : frandMinMax(8, 12);
|
2020-04-13 13:36:23 +02:00
|
|
|
bubble->sourceColor = Vector4(0, 0, 0, 1);
|
|
|
|
float shade = frandMinMax(0.3, 0.8);
|
|
|
|
bubble->destinationColor = Vector4(shade, shade, shade, 1);
|
|
|
|
bubble->color = bubble->sourceColor;
|
2020-06-18 14:24:52 +02:00
|
|
|
bubble->destinationSize = flags & BUBBLE_FLAG_BIG_SIZE ? frandMinMax(256, 512) : frandMinMax(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;
|
|
|
|
bubble->amplitude = Vector3(frandMinMax(-maxAmplitude, maxAmplitude), frandMinMax(-maxAmplitude, maxAmplitude), frandMinMax(-maxAmplitude, maxAmplitude));
|
|
|
|
bubble->worldPositionCenter = bubble->worldPosition;
|
|
|
|
bubble->wavePeriod = Vector3::Zero;
|
|
|
|
bubble->waveSpeed = Vector3(1 / frandMinMax(8, 16), 1 / frandMinMax(8, 16), 1 / frandMinMax(8, 16));
|
|
|
|
bubble->roomNumber = roomNum;
|
|
|
|
}
|
|
|
|
}
|