2020-06-15 19:59:08 +02:00
|
|
|
#include "framework.h"
|
|
|
|
#include "explosion.h"
|
2021-09-08 18:31:35 +03:00
|
|
|
#include "Specific\trmath.h"
|
2020-06-15 19:59:08 +02:00
|
|
|
#include "spark.h"
|
2021-09-08 18:07:48 +03:00
|
|
|
#include "effects\tomb4fx.h"
|
2020-06-15 19:59:08 +02:00
|
|
|
#include "setup.h"
|
2021-09-08 18:07:48 +03:00
|
|
|
#include "effects\effects.h"
|
2021-09-08 18:31:35 +03:00
|
|
|
#include "Specific\prng.h"
|
2021-08-30 18:03:21 +03:00
|
|
|
using namespace TEN::Math::Random;
|
|
|
|
namespace TEN {
|
2020-06-15 19:59:08 +02:00
|
|
|
namespace Effects {
|
|
|
|
namespace Explosion {
|
|
|
|
using namespace DirectX::SimpleMath;
|
2021-08-30 18:03:21 +03:00
|
|
|
using namespace TEN::Effects::Spark;
|
2020-06-15 19:59:08 +02:00
|
|
|
std::array<ExplosionParticle, 64> explosionParticles;
|
|
|
|
constexpr float PARTICLE_DISTANCE = 512;
|
2021-07-23 21:50:29 +01:00
|
|
|
void TriggerExplosion(Vector3 const& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room)
|
2020-06-15 19:59:08 +02:00
|
|
|
{
|
|
|
|
SpawnExplosionParticle(pos);
|
|
|
|
for (int i = 0; i < 3; i++) {
|
2021-09-17 16:07:53 +03:00
|
|
|
Vector3 particlePos = pos + Vector3(GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2));
|
2020-06-15 19:59:08 +02:00
|
|
|
SpawnExplosionParticle(particlePos);
|
|
|
|
}
|
|
|
|
if (triggerSparks) {
|
|
|
|
PHD_VECTOR sparkPos;
|
|
|
|
sparkPos.x = pos.x;
|
|
|
|
sparkPos.y = pos.y;
|
|
|
|
sparkPos.z = pos.z;
|
|
|
|
//TriggerExplosionSparks(&sparkPos, room); @TODO
|
|
|
|
}
|
|
|
|
if (triggerShockwave) {
|
|
|
|
PHD_3DPOS shockPos;
|
|
|
|
shockPos.xPos = pos.x;
|
|
|
|
shockPos.yPos = pos.y;
|
|
|
|
shockPos.zPos = pos.z;
|
|
|
|
TriggerShockwave(&shockPos, 0, size, 64, 32, 32, 32, 30, rand() & 0xFFFF, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void UpdateExplosionParticles()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < explosionParticles.size(); i++) {
|
|
|
|
ExplosionParticle& e = explosionParticles[i];
|
|
|
|
if (!e.active) continue;
|
|
|
|
e.age++;
|
|
|
|
if (e.age > e.life) {
|
|
|
|
e.active = false;
|
|
|
|
continue;
|
|
|
|
};
|
|
|
|
e.vel *= 0.98f;
|
|
|
|
e.pos += e.vel;
|
|
|
|
e.angularVel *= 0.98f;
|
|
|
|
e.rotation += e.angularVel;
|
|
|
|
int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1;
|
|
|
|
float normalizedAge = e.age / e.life;
|
|
|
|
e.sprite = lerp(0, numSprites, normalizedAge);
|
|
|
|
e.tint = Vector4::Lerp(Vector4(2, 2, 2, 1), Vector4(0, 0, 0, 0), normalizedAge);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ExplosionParticle& getFreeExplosionParticle()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < explosionParticles.size(); i++)
|
|
|
|
{
|
|
|
|
if (!explosionParticles[i].active) {
|
|
|
|
return explosionParticles[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return explosionParticles[0];
|
|
|
|
}
|
2021-07-23 21:50:29 +01:00
|
|
|
void SpawnExplosionParticle(Vector3 const & pos)
|
2020-06-15 19:59:08 +02:00
|
|
|
{
|
|
|
|
ExplosionParticle& e = getFreeExplosionParticle();
|
|
|
|
e = {};
|
|
|
|
e.pos = pos;
|
|
|
|
const float maxVel = 10;
|
2021-09-17 16:07:53 +03:00
|
|
|
e.vel = Vector3(GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2));
|
2020-06-15 19:59:08 +02:00
|
|
|
e.active = true;
|
|
|
|
e.tint = Vector4(1, 1, 1, 1);
|
2021-09-17 16:07:53 +03:00
|
|
|
e.life = GenerateFloat(60, 90);
|
|
|
|
e.size = GenerateFloat(512, 768);
|
|
|
|
e.angularVel = GenerateFloat(-RADIAN, RADIAN);
|
|
|
|
e.rotation = GenerateFloat(-0.05, 0.05);
|
2020-06-15 19:59:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|