* Initial commit.

:)
This commit is contained in:
iProgramInCpp
2023-07-30 22:22:02 +03:00
commit 9642818a88
613 changed files with 151754 additions and 0 deletions

View 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();
}

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

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

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

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

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

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

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

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

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

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