mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-23 20:09:46 +03:00
* Initial commit.
:)
This commit is contained in:
33
source/World/Particle/BubbleParticle.cpp
Normal file
33
source/World/Particle/BubbleParticle.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "Particle.hpp"
|
||||
#include "Level.hpp"
|
||||
|
||||
BubbleParticle::BubbleParticle(Level* level, float x, float y, float z, float vx, float vy, float vz) :
|
||||
Particle(level, x, y, z, vx, vy, vz)
|
||||
{
|
||||
field_F8 = field_FC = field_100 = 1.0f;
|
||||
field_DC = PTI_BUBBLE;
|
||||
setSize(0.02f, 0.02f);
|
||||
|
||||
field_F0 *= 0.2f + 0.6f * sharedRandom.nextFloat();
|
||||
m_vel.x = vx * 0.2f + 0.02f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.y = vy * 0.2f + 0.02f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.z = vz * 0.2f + 0.02f * (2.0f * Mth::random() - 1.0f);
|
||||
field_EC = int(8.0f / (Mth::random() * 0.8f + 0.2f));
|
||||
}
|
||||
|
||||
void BubbleParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
m_vel.y += 0.002f;
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
m_vel *= 0.85f;
|
||||
|
||||
if (m_pLevel->getMaterial(Mth::floor(m_pos.x), Mth::floor(m_pos.y), Mth::floor(m_pos.z)) != Material::water)
|
||||
remove();
|
||||
|
||||
field_EC--;
|
||||
if (field_EC <= 0)
|
||||
remove();
|
||||
}
|
||||
35
source/World/Particle/ExplodeParticle.cpp
Normal file
35
source/World/Particle/ExplodeParticle.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "Particle.hpp"
|
||||
|
||||
ExplodeParticle::ExplodeParticle(Level* level, float x, float y, float z, float vx, float vy, float vz) :
|
||||
Particle(level, x, y, z, vx, vy, vz)
|
||||
{
|
||||
m_vel.x = vx + 0.05f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.y = vy + 0.05f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.z = vz + 0.05f * (2.0f * Mth::random() - 1.0f);
|
||||
|
||||
field_F8 = field_FC = field_100 = 0.7f + 0.3f * sharedRandom.nextFloat();
|
||||
field_F0 = 1.0f + 6.0f * sharedRandom.nextFloat() * sharedRandom.nextFloat();
|
||||
field_EC = int(16.0f / (0.2f + 0.8f * sharedRandom.nextFloat())) + 2;
|
||||
}
|
||||
|
||||
void ExplodeParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
field_E8++;
|
||||
if (field_E8 > field_EC)
|
||||
remove();
|
||||
|
||||
m_vel.y += 0.004f;
|
||||
field_DC = -8 * field_E8 / field_EC + 7;
|
||||
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
m_vel *= 0.9f;
|
||||
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
53
source/World/Particle/FlameParticle.cpp
Normal file
53
source/World/Particle/FlameParticle.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#include "Particle.hpp"
|
||||
|
||||
FlameParticle::FlameParticle(Level* level, float x, float y, float z, float vx, float vy, float vz) :
|
||||
Particle(level, x, y, z, vx, vy, vz)
|
||||
{
|
||||
m_vel.x = m_vel.x * 0.01f + vx;
|
||||
m_vel.y = m_vel.y * 0.01f + vy;
|
||||
m_vel.z = m_vel.z * 0.01f + vz;
|
||||
|
||||
// @NOTE: Useless genrand_int32 calls. Will keep them in to keep consistent
|
||||
sharedRandom.genrand_int32();
|
||||
sharedRandom.genrand_int32();
|
||||
sharedRandom.genrand_int32();
|
||||
sharedRandom.genrand_int32();
|
||||
sharedRandom.genrand_int32();
|
||||
sharedRandom.genrand_int32();
|
||||
|
||||
field_104 = field_F0;
|
||||
field_F8 = field_FC = field_100 = 1.0f;
|
||||
field_EC = int(8.0f / (0.2f + 0.8f * Mth::random())) + 4;
|
||||
field_DC = PTI_FLAME;
|
||||
}
|
||||
|
||||
float FlameParticle::getBrightness(float unused)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void FlameParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
field_E8++;
|
||||
if (field_E8 > field_EC)
|
||||
remove();
|
||||
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
m_vel *= 0.96f;
|
||||
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
|
||||
void FlameParticle::render(Tesselator& t, float f, float a, float b, float c, float d, float e)
|
||||
{
|
||||
float mult = float(field_E8 + f) / float(field_EC);
|
||||
field_F0 = field_104 * (1.0f - 0.5f * mult * mult);
|
||||
Particle::render(t, f, a, b, c, d, e);
|
||||
}
|
||||
51
source/World/Particle/LavaParticle.cpp
Normal file
51
source/World/Particle/LavaParticle.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "Particle.hpp"
|
||||
#include "Level.hpp"
|
||||
|
||||
LavaParticle::LavaParticle(Level* level, float x, float y, float z) :
|
||||
Particle(level, x, y, z, 0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
m_vel *= 0.8f;
|
||||
m_vel.y = sharedRandom.nextFloat() * 0.4f + 0.05f;
|
||||
field_F8 = field_FC = field_100 = 1.0f;
|
||||
field_104 = field_F0 = field_F0 * (0.2f + 2 * sharedRandom.nextFloat());
|
||||
field_DC = PTI_LAVA;
|
||||
field_EC = int(16.0f / (0.2f + 0.8f * Mth::random()));
|
||||
}
|
||||
|
||||
float LavaParticle::getBrightness(float unused)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void LavaParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
field_E8++;
|
||||
if (field_E8 > field_EC)
|
||||
remove();
|
||||
|
||||
float a = float(field_E8) / float(field_EC);
|
||||
float b = sharedRandom.nextFloat();
|
||||
if (a < b)
|
||||
{
|
||||
m_pLevel->addParticle("smoke", m_pos.x, m_pos.y, m_pos.z, m_vel.x, m_vel.y, m_vel.z);
|
||||
}
|
||||
|
||||
m_vel.y -= 0.03f;
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
m_vel *= 0.999f;
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
|
||||
void LavaParticle::render(Tesselator& t, float f, float a, float b, float c, float d, float e)
|
||||
{
|
||||
float mult = float(field_E8 + f) / float(field_EC);
|
||||
field_F0 = field_104 * (1.0f - mult * mult);
|
||||
Particle::render(t, f, a, b, c, d, e);
|
||||
}
|
||||
95
source/World/Particle/Particle.cpp
Normal file
95
source/World/Particle/Particle.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "Particle.hpp"
|
||||
|
||||
float Particle::xOff, Particle::yOff, Particle::zOff;
|
||||
|
||||
Particle::Particle(Level* level, float x, float y, float z, float vx, float vy, float vz) : Entity(level)
|
||||
{
|
||||
setSize(0.2f, 0.2f);
|
||||
field_84 = 0.5f * field_8C;
|
||||
|
||||
setPos(x, y, z);
|
||||
m_vel.x = vx + 0.4f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.y = vy + 0.4f * (2.0f * Mth::random() - 1.0f);
|
||||
m_vel.z = vz + 0.4f * (2.0f * Mth::random() - 1.0f);
|
||||
|
||||
float mult = 0.4f * 0.15f * (Mth::random() + Mth::random() + 1.0f) / Mth::sqrt(m_vel.x * m_vel.x + m_vel.y * m_vel.y + m_vel.z * m_vel.z);
|
||||
m_vel.x *= mult;
|
||||
m_vel.y = m_vel.y * mult + 0.1f;
|
||||
m_vel.z *= mult;
|
||||
|
||||
field_E0 = 3.0f * sharedRandom.nextFloat();
|
||||
field_E4 = 3.0f * sharedRandom.nextFloat();
|
||||
field_F0 = 2.0f * (0.5f + 0.5f * sharedRandom.nextFloat());
|
||||
field_EC = int(4.0f / (0.1f + 0.9f * sharedRandom.nextFloat()));
|
||||
}
|
||||
|
||||
int Particle::getParticleTexture()
|
||||
{
|
||||
return PT_PARTICLES;
|
||||
}
|
||||
|
||||
Particle* Particle::scale(float f)
|
||||
{
|
||||
setSize(0.2f * f, 0.2f * f);
|
||||
field_F0 *= f;
|
||||
return this;
|
||||
}
|
||||
|
||||
Particle* Particle::setPower(float f)
|
||||
{
|
||||
m_vel.x *= f;
|
||||
m_vel.y = (m_vel.y - 0.1f) * f + 0.1f;
|
||||
m_vel.z *= f;
|
||||
return this;
|
||||
}
|
||||
|
||||
void Particle::render(Tesselator& t, float f, float a4, float a5, float a6, float a7, float a8)
|
||||
{
|
||||
constexpr float C_MAGIC_1 = 0.062438f; // @BUG: Slightly bigger than 1/16.0f
|
||||
|
||||
int texture = field_DC;
|
||||
int texX = texture % 16;
|
||||
if (texture < 0)
|
||||
texture += 15;
|
||||
|
||||
float texU_1 = float(texX) / 16.0f;
|
||||
float texV_1 = float(texture >> 4) / 16.0f;
|
||||
|
||||
float posX = Lerp(field_3C.x, m_pos.x, f) - xOff;
|
||||
float posY = Lerp(field_3C.y, m_pos.y, f) - yOff;
|
||||
float posZ = Lerp(field_3C.z, m_pos.z, f) - zOff;
|
||||
float fBright = getBrightness(f);
|
||||
|
||||
float sizeX = a4 * field_F0 * 0.1f;
|
||||
float sizeY = a5 * field_F0 * 0.1f;
|
||||
float sizeZ = a6 * field_F0 * 0.1f;
|
||||
float siz2X = a7 * field_F0 * 0.1f;
|
||||
float siz2Z = a8 * field_F0 * 0.1f;
|
||||
|
||||
t.color(field_F8 * fBright, field_FC * fBright, field_100 * fBright);
|
||||
t.vertexUV(posX - sizeX - siz2X, posY - sizeY, posZ - sizeZ - siz2Z, texU_1 + C_MAGIC_1, texV_1 + C_MAGIC_1);
|
||||
t.vertexUV(posX - sizeX + siz2X, posY + sizeY, posZ - sizeZ + siz2Z, texU_1 + C_MAGIC_1, texV_1);
|
||||
t.vertexUV(posX + sizeX + siz2X, posY + sizeY, posZ + sizeZ + siz2Z, texU_1, texV_1);
|
||||
t.vertexUV(posX + sizeX - siz2X, posY - sizeY, posZ + sizeZ - siz2Z, texU_1, texV_1 + C_MAGIC_1);
|
||||
}
|
||||
|
||||
void Particle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
field_E8++;
|
||||
if (field_E8 >= field_EC)
|
||||
remove();
|
||||
|
||||
m_vel.y -= field_F4 * 0.04f;
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
m_vel.x *= 0.98f;
|
||||
m_vel.y *= 0.98f;
|
||||
m_vel.z *= 0.98f;
|
||||
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
127
source/World/Particle/Particle.hpp
Normal file
127
source/World/Particle/Particle.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include "Entity.hpp"
|
||||
#include "Tesselator.hpp"
|
||||
|
||||
enum eParticleTexture
|
||||
{
|
||||
PT_PARTICLES,
|
||||
PT_TERRAIN,
|
||||
PT_PARTICLES2,
|
||||
PT_PARTICLES3,
|
||||
};
|
||||
|
||||
enum eParticleTextureIndex
|
||||
{
|
||||
PTI_BUBBLE = 32,
|
||||
PTI_FLAME = 48,
|
||||
PTI_LAVA,
|
||||
};
|
||||
|
||||
class Particle : public Entity
|
||||
{
|
||||
public:
|
||||
Particle(Level*, float y, float x, float z, float vx, float vy, float vz);
|
||||
|
||||
virtual void render(Tesselator&, float, float, float, float, float, float);
|
||||
virtual int getParticleTexture();
|
||||
//TODO: addAdditonalSaveData
|
||||
//TODO: readAdditionalSaveData
|
||||
//TODO: defineSynchedData
|
||||
|
||||
void tick() override;
|
||||
|
||||
Particle* scale(float);
|
||||
Particle* setPower(float);
|
||||
|
||||
public:
|
||||
int field_DC = 0;
|
||||
float field_E0 = 0.0f;
|
||||
float field_E4 = 0.0f;
|
||||
int field_E8 = 0;
|
||||
int field_EC = 0;
|
||||
float field_F0 = 0.0f;
|
||||
float field_F4 = 0.0f;
|
||||
float field_F8 = 1.0f;
|
||||
float field_FC = 1.0f;
|
||||
float field_100 = 1.0f;
|
||||
|
||||
static float xOff, yOff, zOff;
|
||||
};
|
||||
|
||||
class TerrainParticle : public Particle
|
||||
{
|
||||
public:
|
||||
TerrainParticle(Level*, float x, float y, float z, Tile*);
|
||||
TerrainParticle(Level*, float x, float y, float z, float vx, float vy, float vz, Tile*);
|
||||
|
||||
void render(Tesselator&, float, float, float, float, float, float) override;
|
||||
int getParticleTexture() override;
|
||||
TerrainParticle* init(int x, int y, int z);
|
||||
|
||||
public:
|
||||
Tile* m_pTile;
|
||||
};
|
||||
|
||||
class BubbleParticle : public Particle
|
||||
{
|
||||
public:
|
||||
BubbleParticle(Level*, float x, float y, float z, float vx, float vy, float vz);
|
||||
void tick() override;
|
||||
};
|
||||
|
||||
class SmokeParticle : public Particle
|
||||
{
|
||||
public:
|
||||
SmokeParticle(Level*, float x, float y, float z, float vx, float vy, float vz, float a9);
|
||||
void tick() override;
|
||||
void render(Tesselator&, float, float, float, float, float, float) override;
|
||||
|
||||
public:
|
||||
float field_104 = 0.0f;
|
||||
};
|
||||
|
||||
class RedDustParticle : public Particle
|
||||
{
|
||||
public:
|
||||
RedDustParticle(Level*, float x, float y, float z, float vx, float vy, float vz);
|
||||
void tick() override;
|
||||
void render(Tesselator&, float, float, float, float, float, float) override;
|
||||
|
||||
public:
|
||||
float field_104 = 0.0f;
|
||||
};
|
||||
|
||||
class ExplodeParticle : public Particle
|
||||
{
|
||||
public:
|
||||
ExplodeParticle(Level*, float x, float y, float z, float vx, float vy, float vz);
|
||||
void tick() override;
|
||||
|
||||
public:
|
||||
float field_104 = 0.0f;
|
||||
};
|
||||
|
||||
class FlameParticle : public Particle
|
||||
{
|
||||
public:
|
||||
FlameParticle(Level*, float x, float y, float z, float vx, float vy, float vz);
|
||||
void tick() override;
|
||||
void render(Tesselator&, float, float, float, float, float, float) override;
|
||||
float getBrightness(float f) override;
|
||||
|
||||
public:
|
||||
float field_104 = 0.0f;
|
||||
};
|
||||
|
||||
class LavaParticle : public Particle
|
||||
{
|
||||
public:
|
||||
LavaParticle(Level*, float x, float y, float z);
|
||||
void tick() override;
|
||||
void render(Tesselator&, float, float, float, float, float, float) override;
|
||||
float getBrightness(float f) override;
|
||||
|
||||
public:
|
||||
float field_104 = 0.0f;
|
||||
};
|
||||
191
source/World/Particle/ParticleEngine.cpp
Normal file
191
source/World/Particle/ParticleEngine.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#include <sstream>
|
||||
#include "ParticleEngine.hpp"
|
||||
|
||||
ParticleEngine::ParticleEngine(Level* level, Textures* textures)
|
||||
{
|
||||
m_pLevel = level;
|
||||
m_pTextures = textures;
|
||||
m_pTextures->loadTexture("particles.png", true);
|
||||
}
|
||||
|
||||
void ParticleEngine::setLevel(Level* level)
|
||||
{
|
||||
#ifdef ORIGINAL_CODE
|
||||
m_pLevel = level;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
#ifndef ORIGINAL_CODE
|
||||
for (auto pParticle : m_particles[i])
|
||||
delete pParticle;
|
||||
#endif
|
||||
// @BUG: memory leak?
|
||||
m_particles[i].clear();
|
||||
}
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
m_pLevel = level;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ParticleEngine::add(Particle* particle)
|
||||
{
|
||||
m_particles[particle->getParticleTexture()].push_back(particle);
|
||||
}
|
||||
|
||||
std::string ParticleEngine::countParticles()
|
||||
{
|
||||
// @NOTE: For whatever reason this returns a string??
|
||||
std::stringstream ss;
|
||||
ss << (m_particles[0].size() + m_particles[1].size() + m_particles[2].size() + m_particles[3].size());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void ParticleEngine::crack(int x, int y, int z, int dir)
|
||||
{
|
||||
TileID tileID = m_pLevel->getTile(x, y, z);
|
||||
if (!tileID) return;
|
||||
|
||||
Tile* pTile = Tile::tiles[tileID];
|
||||
|
||||
float posX, posY, posZ;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case DIR_YNEG:
|
||||
posX = float(x) + Lerp(pTile->m_aabb.min.x, pTile->m_aabb.max.x - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + Lerp(pTile->m_aabb.min.z, pTile->m_aabb.max.z - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posY = float(y) + pTile->m_aabb.min.y - 0.1f;
|
||||
break;
|
||||
case DIR_YPOS:
|
||||
posX = float(x) + Lerp(pTile->m_aabb.min.x, pTile->m_aabb.max.x - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + Lerp(pTile->m_aabb.min.z, pTile->m_aabb.max.z - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posY = float(y) + pTile->m_aabb.max.y + 0.1f;
|
||||
break;
|
||||
case DIR_ZNEG:
|
||||
posX = float(x) + Lerp(pTile->m_aabb.min.x, pTile->m_aabb.max.x - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posY = float(y) + Lerp(pTile->m_aabb.min.y, pTile->m_aabb.max.y - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + pTile->m_aabb.min.z - 0.1f;
|
||||
break;
|
||||
case DIR_ZPOS:
|
||||
posX = float(x) + Lerp(pTile->m_aabb.min.x, pTile->m_aabb.max.x - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posY = float(y) + Lerp(pTile->m_aabb.min.y, pTile->m_aabb.max.y - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + pTile->m_aabb.max.z + 0.1f;
|
||||
break;
|
||||
case DIR_XNEG:
|
||||
posY = float(y) + Lerp(pTile->m_aabb.min.y, pTile->m_aabb.max.y - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + Lerp(pTile->m_aabb.min.z, pTile->m_aabb.max.z - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posX = float(x) + pTile->m_aabb.min.x - 0.1f;
|
||||
break;
|
||||
case DIR_XPOS:
|
||||
posY = float(y) + Lerp(pTile->m_aabb.min.y, pTile->m_aabb.max.y - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posZ = float(z) + Lerp(pTile->m_aabb.min.z, pTile->m_aabb.max.z - 0.2f, m_random.nextFloat()) + 0.1f;
|
||||
posX = float(x) + pTile->m_aabb.max.x + 0.1f;
|
||||
break;
|
||||
default:
|
||||
// @TODO: dont know what they do for the undefined case
|
||||
posX = float(x), posY = float(y), posZ = float(z);
|
||||
break;
|
||||
}
|
||||
|
||||
add((new TerrainParticle(m_pLevel, posX, posY, posZ, pTile))->setPower(0.2f)->scale(0.6f));
|
||||
}
|
||||
|
||||
void ParticleEngine::destroy(int x, int y, int z)
|
||||
{
|
||||
TileID tileID = m_pLevel->getTile(x, y, z);
|
||||
if (!tileID) return;
|
||||
|
||||
float timeS = getTimeS();
|
||||
|
||||
Tile* pTile = Tile::tiles[tileID];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
float posX = float(x) + (float(i) + 0.5f) / 3.0f;
|
||||
float posY = float(y) + (float(j) + 0.5f) / 3.0f;
|
||||
float posZ = float(z) + (float(k) + 0.5f) / 3.0f;
|
||||
|
||||
add((new TerrainParticle(m_pLevel, posX, posY, posZ, posX - float(x) - 0.5f, posY - float(y) - 0.5f, posZ - float(z) - 0.5f, pTile))->init(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeS != -1.0)
|
||||
getTimeS();
|
||||
|
||||
// @NOTE: Useless string creation
|
||||
#ifdef ORIGINAL_CODE
|
||||
std::string("gen destroy particles: ");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENH_CAMERA_NO_PARTICLES
|
||||
bool g_bDisableParticles;
|
||||
#endif
|
||||
|
||||
void ParticleEngine::render(Entity* ent, float f)
|
||||
{
|
||||
#ifdef ENH_CAMERA_NO_PARTICLES
|
||||
if (g_bDisableParticles)
|
||||
return;
|
||||
#endif
|
||||
|
||||
float x1 = Mth::cos(float(M_PI) * ent->m_yaw / 180.0f);
|
||||
float x3 = Mth::sin(float(M_PI) * ent->m_yaw / 180.0f);
|
||||
float x4 = -(x3 * Mth::sin(float(M_PI) * ent->m_pitch / 180.0f));
|
||||
float x5 = x1 * Mth::sin(float(M_PI) * ent->m_pitch / 180.0f);
|
||||
float x2 = Mth::cos(float(M_PI) * ent->m_pitch / 180.0f);
|
||||
|
||||
Particle::xOff = Lerp(ent->field_98.x, ent->m_pos.x, f);
|
||||
Particle::yOff = Lerp(ent->field_98.y, ent->m_pos.y, f);
|
||||
Particle::zOff = Lerp(ent->field_98.z, ent->m_pos.z, f);
|
||||
|
||||
// @BUG: Ignoring the last particle array. Invisible?
|
||||
Tesselator& t = Tesselator::instance;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (i == PT_TERRAIN)
|
||||
m_pTextures->loadAndBindTexture(C_TERRAIN_NAME);
|
||||
else
|
||||
m_pTextures->loadAndBindTexture("particles.png");
|
||||
|
||||
t.begin();
|
||||
|
||||
for (auto pParticle : m_particles[i])
|
||||
pParticle->render(t, f, x1, x2, x3, x4, x5);
|
||||
|
||||
t.draw();
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEngine::renderLit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ParticleEngine::tick()
|
||||
{
|
||||
for (int p = 0; p < 4; p++)
|
||||
{
|
||||
for (size_t i = 0; i < m_particles[p].size(); i++)
|
||||
{
|
||||
Particle* particle = m_particles[p][i];
|
||||
particle->tick();
|
||||
|
||||
if (particle->m_bRemoved)
|
||||
{
|
||||
// remove it
|
||||
m_particles[p].erase(m_particles[p].begin() + i);
|
||||
i--;
|
||||
delete particle;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
source/World/Particle/ParticleEngine.hpp
Normal file
28
source/World/Particle/ParticleEngine.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "Level.hpp"
|
||||
#include "Textures.hpp"
|
||||
#include "Particle.hpp"
|
||||
|
||||
class ParticleEngine
|
||||
{
|
||||
public:
|
||||
ParticleEngine(Level*, Textures*);
|
||||
|
||||
void add(Particle*);
|
||||
std::string countParticles();
|
||||
void crack(int x, int y, int z, int dir);
|
||||
void destroy(int x, int y, int z);
|
||||
void render(Entity*, float f);
|
||||
void renderLit();
|
||||
void tick();
|
||||
void setLevel(Level*);
|
||||
|
||||
public:
|
||||
Level* m_pLevel;
|
||||
// todo
|
||||
std::vector<Particle*> m_particles[4];
|
||||
Textures* m_pTextures;
|
||||
Random m_random;
|
||||
};
|
||||
|
||||
62
source/World/Particle/RedDustParticle.cpp
Normal file
62
source/World/Particle/RedDustParticle.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "Particle.hpp"
|
||||
|
||||
RedDustParticle::RedDustParticle(Level* level, float x, float y, float z, float vx, float vy, float vz) :
|
||||
Particle(level, x, y, z, 0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
m_vel.x = vx + m_vel.x * 0.1f;
|
||||
m_vel.y = vy + m_vel.y * 0.1f;
|
||||
m_vel.z = vz + m_vel.z * 0.1f;
|
||||
|
||||
if (vx == 0.0f)
|
||||
vx = 1.0f;
|
||||
|
||||
float f = Mth::random() * 0.4f + 0.6f;
|
||||
field_F8 = f * vx * (Mth::random() * 0.2f + 0.8f);
|
||||
field_FC = f * vy * (Mth::random() * 0.2f + 0.8f);
|
||||
field_100 = f * vz * (Mth::random() * 0.2f + 0.8f);
|
||||
|
||||
field_104 = field_F0 = field_F0 * 0.75f;
|
||||
|
||||
m_bNoCollision = false;
|
||||
field_EC = int(8.0f / (0.2f + 0.8f * Mth::random()));
|
||||
}
|
||||
|
||||
void RedDustParticle::render(Tesselator& t, float f, float a, float b, float c, float d, float e)
|
||||
{
|
||||
float mult = 32.0f * (float(field_E8 + f) / float(field_EC));
|
||||
if (mult < 0.0f)
|
||||
mult = 0.0f;
|
||||
if (mult > 1.0f)
|
||||
mult = 1.0f;
|
||||
|
||||
field_F0 = field_104 * mult;
|
||||
Particle::render(t, f, a, b, c, d, e);
|
||||
}
|
||||
|
||||
void RedDustParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
field_E8++;
|
||||
if (field_E8 > field_EC)
|
||||
remove();
|
||||
|
||||
m_vel.y += 0.004f;
|
||||
field_DC = -8 * field_E8 / field_EC + 7;
|
||||
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
if (m_pos.y == field_3C.y)
|
||||
{
|
||||
m_vel.x *= 1.1f;
|
||||
m_vel.z *= 1.1f;
|
||||
}
|
||||
|
||||
m_vel *= 0.96f;
|
||||
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
56
source/World/Particle/SmokeParticle.cpp
Normal file
56
source/World/Particle/SmokeParticle.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "Particle.hpp"
|
||||
|
||||
SmokeParticle::SmokeParticle(Level* level, float x, float y, float z, float vx, float vy, float vz, float a9) :
|
||||
Particle(level, x, y, z, 0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
m_vel.x = vx + m_vel.x * 0.1f;
|
||||
m_vel.y = vy + m_vel.y * 0.1f;
|
||||
m_vel.z = vz + m_vel.z * 0.1f;
|
||||
|
||||
field_100 = field_FC = field_F8 = Mth::random() * 0.5f;
|
||||
|
||||
field_104 = field_F0 = field_F0 * 0.75f * a9;
|
||||
|
||||
m_bNoCollision = false;
|
||||
field_EC = int((a9 * 8.0f) / (0.2f + 0.8f * Mth::random()));
|
||||
}
|
||||
|
||||
void SmokeParticle::render(Tesselator& t, float f, float a, float b, float c, float d, float e)
|
||||
{
|
||||
float mult = 32.0f * (float(field_E8 + f) / float(field_EC));
|
||||
if (mult < 0.0f)
|
||||
mult = 0.0f;
|
||||
if (mult > 1.0f)
|
||||
mult = 1.0f;
|
||||
|
||||
field_F0 = field_104 * mult;
|
||||
Particle::render(t, f, a, b, c, d, e);
|
||||
}
|
||||
|
||||
void SmokeParticle::tick()
|
||||
{
|
||||
field_3C = m_pos;
|
||||
|
||||
field_E8++;
|
||||
if (field_E8 > field_EC)
|
||||
remove();
|
||||
|
||||
m_vel.y += 0.004f;
|
||||
field_DC = -8 * field_E8 / field_EC + 7;
|
||||
|
||||
move(m_vel.x, m_vel.y, m_vel.z);
|
||||
|
||||
if (m_pos.y == field_3C.y)
|
||||
{
|
||||
m_vel.x *= 1.1f;
|
||||
m_vel.z *= 1.1f;
|
||||
}
|
||||
|
||||
m_vel *= 0.96f;
|
||||
|
||||
if (field_7C)
|
||||
{
|
||||
m_vel.x *= 0.7f;
|
||||
m_vel.z *= 0.7f;
|
||||
}
|
||||
}
|
||||
67
source/World/Particle/TerrainParticle.cpp
Normal file
67
source/World/Particle/TerrainParticle.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "Particle.hpp"
|
||||
#include "Level.hpp"
|
||||
|
||||
TerrainParticle::TerrainParticle(Level* level, float x, float y, float z, Tile* tile) :
|
||||
TerrainParticle(level, x, y, z, 0.0f, 0.0f, 0.0f, tile)
|
||||
{
|
||||
}
|
||||
|
||||
TerrainParticle::TerrainParticle(Level* level, float x, float y, float z, float vx, float vy, float vz, Tile* tile) :
|
||||
Particle(level, x, y, z, vx, vy, vz)
|
||||
{
|
||||
m_pTile = tile;
|
||||
field_DC = tile->m_TextureFrame;
|
||||
field_F4 = tile->field_28;
|
||||
field_100 = 0.6f;
|
||||
field_FC = 0.6f;
|
||||
field_F8 = 0.6f;
|
||||
field_F0 *= 0.5f;
|
||||
}
|
||||
|
||||
TerrainParticle* TerrainParticle::init(int x, int y, int z)
|
||||
{
|
||||
if (m_pTile == Tile::grass)
|
||||
return this;
|
||||
|
||||
int color = m_pTile->getColor(m_pLevel, x, y, z);
|
||||
field_F8 *= float(GET_RED(color)) / 255.0f;
|
||||
field_FC *= float(GET_GREEN(color)) / 255.0f;
|
||||
field_100 *= float(GET_BLUE(color)) / 255.0f;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
int TerrainParticle::getParticleTexture()
|
||||
{
|
||||
return PT_TERRAIN;
|
||||
}
|
||||
|
||||
void TerrainParticle::render(Tesselator& t, float f, float a4, float a5, float a6, float a7, float a8)
|
||||
{
|
||||
constexpr float C_MAGIC_1 = 0.015609f; // @BUG: Slightly bigger than 1/64.0f
|
||||
|
||||
int texture = field_DC;
|
||||
int texX = texture % 16;
|
||||
if (texture < 0)
|
||||
texture += 15;
|
||||
|
||||
float texU_1 = (float(texX) + 0.25f * field_E0) / 16.0f;
|
||||
float texV_1 = (float(texture >> 4) + 0.25f * field_E4) / 16.0f;
|
||||
|
||||
float posX = Lerp(field_3C.x, m_pos.x, f) - xOff;
|
||||
float posY = Lerp(field_3C.y, m_pos.y, f) - yOff;
|
||||
float posZ = Lerp(field_3C.z, m_pos.z, f) - zOff;
|
||||
float fBright = getBrightness(f);
|
||||
|
||||
float sizeX = a4 * field_F0 * 0.1f;
|
||||
float sizeY = a5 * field_F0 * 0.1f;
|
||||
float sizeZ = a6 * field_F0 * 0.1f;
|
||||
float siz2X = a7 * field_F0 * 0.1f;
|
||||
float siz2Z = a8 * field_F0 * 0.1f;
|
||||
|
||||
t.color(field_F8 * fBright, field_FC * fBright, field_100 * fBright);
|
||||
t.vertexUV(posX - sizeX - siz2X, posY - sizeY, posZ - sizeZ - siz2Z, texU_1 + C_MAGIC_1, texV_1 + C_MAGIC_1);
|
||||
t.vertexUV(posX - sizeX + siz2X, posY + sizeY, posZ - sizeZ + siz2Z, texU_1 + C_MAGIC_1, texV_1);
|
||||
t.vertexUV(posX + sizeX + siz2X, posY + sizeY, posZ + sizeZ + siz2Z, texU_1, texV_1);
|
||||
t.vertexUV(posX + sizeX - siz2X, posY - sizeY, posZ + sizeZ - siz2Z, texU_1, texV_1 + C_MAGIC_1);
|
||||
}
|
||||
Reference in New Issue
Block a user