the whole game

This commit is contained in:
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__BreakingItemParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__BreakingItemParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
#include "../renderer/Tesselator.h"
#include "../../world/item/Item.h"
#include "../../world/level/Level.h"
#include "../../world/level/tile/Tile.h"
class BreakingItemParticle: public Particle
{
typedef Particle super;
public:
BreakingItemParticle(Level* level, float x, float y, float z, Item* item)
: super(level, x, y, z, 0, 0, 0)
{
_init(item);
}
BreakingItemParticle(Level* level, float x, float y, float z, float xa, float ya, float za, Item* item)
: super(level, x, y, z, 0, 0, 0)
{
_init(item);
xd *= 0.1f;
yd *= 0.1f;
zd *= 0.1f;
xd += xa;
yd += ya;
zd += za;
}
void _init(Item* item) {
tex = item->getIcon(0);
rCol = gCol = bCol = 1.0f;
gravity = Tile::snow->gravity;
size /= 2;
}
int getParticleTexture() {
return ParticleEngine::ITEM_TEXTURE;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float u0 = (tex % 16 + uo / 4.0f) / 16.0f;
float u1 = u0 + 0.999f / 16.0f / 4;
float v0 = (tex / 16 + vo / 4.0f) / 16.0f;
float v1 = v0 + 0.999f / 16.0f / 4;
float r = 0.1f * size;
float x = (float) (xo + (this->x - xo) * a - xOff);
float y = (float) (yo + (this->y - yo) * a - yOff);
float z = (float) (zo + (this->z - zo) * a - zOff);
float br = getBrightness(a);
t.color(br * rCol, br * gCol, br * bCol);
t.vertexUV(x - xa * r - xa2 * r, y - ya * r, z - za * r - za2 * r, u0, v1);
t.vertexUV(x - xa * r + xa2 * r, y + ya * r, z - za * r + za2 * r, u0, v0);
t.vertexUV(x + xa * r + xa2 * r, y + ya * r, z + za * r + za2 * r, u1, v0);
t.vertexUV(x + xa * r - xa2 * r, y - ya * r, z + za * r - za2 * r, u1, v1);
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__BreakingItemParticle_H__*/

View File

@@ -0,0 +1,51 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__BubbleParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__BubbleParticle_H__
//package net.minecraft.client.particle;
#include "../../util/Mth.h"
#include "../../world/level/Level.h"
#include "../../world/level/material/Material.h"
#include "Particle.h"
class BubbleParticle: public Particle
{
typedef Particle super;
public:
BubbleParticle(Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z, xa, ya, za)
{
rCol = 1.0f;
gCol = 1.0f;
bCol = 1.0f;
tex = 32;
this->setSize(0.02f, 0.02f);
size = size*(sharedRandom.nextFloat()*0.6f+0.2f);
xd = xa*0.2f+(float)(Mth::random()*2-1)*0.02f;
yd = ya*0.2f+(float)(Mth::random()*2-1)*0.02f;
zd = za*0.2f+(float)(Mth::random()*2-1)*0.02f;
lifetime = (int) (8 / (Mth::random() * 0.8 + 0.2));
}
void tick() {
xo = x;
yo = y;
zo = z;
yd += 0.002f;
move(xd, yd, zd);
xd *= 0.85f;
yd *= 0.85f;
zd *= 0.85f;
if (level->getMaterial(Mth::floor(x), Mth::floor(y), Mth::floor(z)) != Material::water) remove();
if (lifetime-- <= 0) remove();
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__BubbleParticle_H__*/

View File

@@ -0,0 +1,74 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__CritParticle2_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__CritParticle2_H__
//package net.minecraft.client.particle;
#include "Particle.h"
#include "../../util/Mth.h"
#include "../../world/level/Level.h"
#include "../../world/level/material/Material.h"
class CritParticle2: public Particle
{
typedef Particle super;
public:
CritParticle2(Level* level, float x, float y, float z, float xa, float ya, float za, float scale = 1.0f)
: super(level, x, y, z, 0, 0, 0),
visible(true)
{
xd *= 0.1f;
yd *= 0.1f;
zd *= 0.1f;
xd += xa * 0.4f;
yd += ya * 0.4f;
zd += za * 0.4f;
rCol = gCol = bCol = (float) (Mth::random() * 0.3f + 0.6f);
size *= 0.75f;
size *= scale;
oSize = size;
lifetime = (int)(6 / (Mth::random() * 0.8f + 0.6f) * scale);
noPhysics = false;
tex = 16 * 4 + 1;
tick();
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
if (!visible) return;
float l = ((age + a) / lifetime) * 32;
if (l < 0) l = 0;
if (l > 1) l = 1;
size = oSize * l;
super::render(t, a, xa, ya, za, xa2, za2);
}
void tick() {
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
move(xd, yd, zd);
gCol *= 0.96f;
bCol *= 0.9f;
xd *= 0.70f;
yd *= 0.70f;
zd *= 0.70f;
yd -= 0.02f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
protected:
bool visible;
float oSize;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__CritParticle2_H__*/

View File

@@ -0,0 +1,51 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__ExplodeParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__ExplodeParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
#include "../renderer/Tesselator.h"
#include "../../world/level/Level.h"
class ExplodeParticle: public Particle
{
typedef Particle super;
public:
ExplodeParticle(Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z, xa, ya, za)
{
xd = xa + (Mth::random()*2.0f-1.0f) * 0.05f;
yd = ya + (Mth::random()*2.0f-1.0f) * 0.05f;
zd = za + (Mth::random()*2.0f-1.0f) * 0.05f;
rCol = gCol = bCol = sharedRandom.nextFloat() * 0.3f + 0.7f;
size = sharedRandom.nextFloat() * sharedRandom.nextFloat() * 6.0f + 1.0f;
lifetime = (int)(16.0f/(sharedRandom.nextFloat() * 0.8f + 0.2f)) + 2;
// noPhysics = true;
}
void tick()
{
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
tex = 7 - age * 8 / lifetime;
yd += 0.004f;
move(xd, yd, zd);
xd *= 0.90f;
yd *= 0.90f;
zd *= 0.90f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__ExplodeParticle_H__*/

View File

@@ -0,0 +1,73 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__FlameParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__FlameParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
#include "../renderer/Tesselator.h"
#include "../../world/level/Level.h"
class FlameParticle: public Particle
{
typedef Particle super;
float oSize;
public:
FlameParticle(Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z, xa, ya, za)
{
xd = xd * 0.01f + xa;
yd = yd * 0.01f + ya;
zd = zd * 0.01f + za;
x += (sharedRandom.nextFloat()-sharedRandom.nextFloat()) * 0.05f;
y += (sharedRandom.nextFloat()-sharedRandom.nextFloat()) * 0.05f;
z += (sharedRandom.nextFloat()-sharedRandom.nextFloat()) * 0.05f;
//printf("xd, yd, zd: %f, %f, %f\n", xd, yd, zd);
oSize = size;
rCol = gCol = bCol = 1.0f;
lifetime = (int)(8.0f/(Mth::random()*0.8f+0.2f))+4;
noPhysics = true;
tex = 48;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float s = (age + a) / (float) lifetime;
size = oSize * (1 - s*s*0.5f);
super::render(t, a, xa, ya, za, xa2, za2);
}
float getBrightness(float a) {
return 1.0f;
/*
float l = (age+a)/lifetime;
if (l<0) l = 0;
if (l>1) l = 1;
float br = super::getBrightness(a);
return br*l+(1-l);
*/
}
void tick()
{
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
move(xd, yd, zd);
xd *= 0.96f;
yd *= 0.96f;
zd *= 0.96f;
if (onGround)
{
xd *= 0.7f;
zd *= 0.7f;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__FlameParticle_H__*/

View File

@@ -0,0 +1,72 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionParticle_H__
//package net.minecraft.client.particle;
#include "../renderer/Tesselator.h"
#include "../renderer/Textures.h"
#include "../../world/level/Level.h"
class HugeExplosionParticle: public Particle
{
typedef Particle super;
public:
HugeExplosionParticle(Textures* textures, Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z, 0, 0, 0),
life(0),
lifeTime(6 + sharedRandom.nextInt(4)),
textures(textures),
size(1 - xa * 0.5f)
{
rCol = gCol = bCol = sharedRandom.nextFloat() * 0.6f + 0.4f;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
int tex = (int) ((life + a) * 15 / lifeTime);
if (tex > 15) return;
textures->loadAndBindTexture("misc/explosion.png");
float u0 = (tex % 4) / 4.0f;
float u1 = u0 + 0.999f / 4.0f;
float v0 = (tex / 4) / 4.0f;
float v1 = v0 + 0.999f / 4.0f;
// xa2 = 0;
// za2 = 1;
float r = size + size;
float x = xo + (this->x - xo) * a - xOff;
float y = yo + (this->y - yo) * a - yOff;
float z = zo + (this->z - zo) * a - zOff;
const float xar = xa * r, yar = ya * r, zar = za * r;
const float xa2r = xa2 * r, za2r = za2 * r;
t.begin();
t.color(rCol, gCol, bCol, 1.0f);
t.vertexUV(x - xar - xa2r, y - yar, z - zar - za2r, u1, v1);
t.vertexUV(x - xar + xa2r, y + yar, z - zar + za2r, u1, v0);
t.vertexUV(x + xar + xa2r, y + yar, z + zar + za2r, u0, v0);
t.vertexUV(x + xar - xa2r, y - yar, z + zar - za2r, u0, v1);
t.draw();
//glPolygonOffset(0, 0.0f);
}
void tick() {
xo = x;
yo = y;
zo = z;
life++;
if (life == lifeTime) remove();
}
int getParticleTexture() {
return ParticleEngine::ENTITY_PARTICLE_TEXTURE;
}
private:
int life;
int lifeTime;
float size;
Textures* textures;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionParticle_H__*/

View File

@@ -0,0 +1,40 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionSeedParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionSeedParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
class HugeExplosionSeedParticle: public Particle
{
typedef Particle super;
public:
HugeExplosionSeedParticle(Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z, 0, 0, 0),
life(0),
lifeTime(8)
{
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {}
void tick() {
for (int i = 0; i < 6; i++) {
float xx = x + (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 4;
float yy = y + (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 4;
float zz = z + (sharedRandom.nextFloat() - sharedRandom.nextFloat()) * 4;
level->addParticle(PARTICLETYPE(largeexplode), xx, yy, zz, life / (float) lifeTime, 0, 0);
}
life++;
if (life == lifeTime) remove();
}
int getParticleTexture() {
return ParticleEngine::TERRAIN_TEXTURE;
}
private:
int life;
int lifeTime;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__HugeExplosionSeedParticle_H__*/

View File

@@ -0,0 +1,63 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__LavaParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__LavaParticle_H__
//package net.minecraft.client.particle;
#include "../renderer/Tesselator.h"
#include "../../world/level/Level.h"
class LavaParticle: public Particle
{
typedef Particle super;
float oSize;
public:
LavaParticle(Level* level, float x, float y, float z)
: super(level, x, y, z, 0, 0, 0)
{
xd *= 0.8f;
yd *= 0.8f;
zd *= 0.8f;
yd = sharedRandom.nextFloat() * 0.4f + 0.05f;
rCol = gCol = bCol = 1;
size *= (sharedRandom.nextFloat() * 2 + 0.2f);
oSize = size;
lifetime = (int) (16 / (Mth::random() * 0.8 + 0.2));
noPhysics = false;
tex = 49;
}
float getBrightness(float a) {
return 1;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float s = (age + a) / (float) lifetime;
size = oSize * (1 - s*s);
super::render(t, a, xa, ya, za, xa2, za2);
}
void tick() {
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
float odds = age / (float) lifetime;
if (sharedRandom.nextFloat() > odds) level->addParticle(PARTICLETYPE(smoke), x, y, z, xd, yd, zd);
yd -= 0.03f;
move(xd, yd, zd);
xd *= 0.999f;
yd *= 0.999f;
zd *= 0.999f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__LavaParticle_H__*/

View File

@@ -0,0 +1,99 @@
#include "Particle.h"
float
Particle::xOff = 0,
Particle::yOff = 0,
Particle::zOff = 0;
Particle::Particle( Level* level, float x, float y, float z, float xa, float ya, float za )
: super(level),
age(0),
gravity(0),
rCol(1), gCol(1), bCol(1),
tex(0)
{
setSize(0.2f, 0.2f);
heightOffset = bbHeight / 2.0f;
setPos(x, y, z);
xd = xa + (float) (Mth::random() * 2 - 1) * 0.4f;
yd = ya + (float) (Mth::random() * 2 - 1) * 0.4f;
zd = za + (float) (Mth::random() * 2 - 1) * 0.4f;
float speed = (float) (Mth::random() + Mth::random() + 1) * 0.15f;
float dd = (float) (Mth::sqrt(xd * xd + yd * yd + zd * zd));
const float mul = 0.4f * speed / dd;
xd = xd * mul;
yd = yd * mul + 0.1f;
zd = zd * mul;
uo = sharedRandom.nextFloat() * 3;
vo = sharedRandom.nextFloat() * 3;
size = (sharedRandom.nextFloat() * 0.5f + 0.5f) * 2;
lifetime = (int) (4.0f / (sharedRandom.nextFloat() * 0.9f + 0.1f));
makeStepSound = false;
}
Particle* Particle::setPower( float power )
{
xd *= power;
yd = (yd - 0.1f) * power + 0.1f;
zd *= power;
return this;
}
Particle* Particle::scale( float scale )
{
setSize(0.2f * scale, 0.2f * scale);
size *= scale;
return this;
}
void Particle::tick()
{
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
yd -= 0.04f * gravity;
move(xd, yd, zd);
xd *= 0.98f;
yd *= 0.98f;
zd *= 0.98f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
void Particle::render( Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2 )
{
float u0 = (tex % 16) / 16.0f;
float u1 = u0 + 0.999f / 16.0f;
float v0 = (tex / 16) / 16.0f;
float v1 = v0 + 0.999f / 16.0f;
float r = 0.1f * size;
float x = (float) (xo + (this->x - xo) * a - xOff);
float y = (float) (yo + (this->y - yo) * a - yOff);
float z = (float) (zo + (this->z - zo) * a - zOff);
float br = getBrightness(a);
t.color(rCol * br, gCol * br, bCol * br);
t.vertexUV(x - xa * r - xa2 * r, y - ya * r, z - za * r - za2 * r, u1, v1);
t.vertexUV(x - xa * r + xa2 * r, y + ya * r, z - za * r + za2 * r, u1, v0);
t.vertexUV(x + xa * r + xa2 * r, y + ya * r, z + za * r + za2 * r, u0, v0);
t.vertexUV(x + xa * r - xa2 * r, y - ya * r, z + za * r - za2 * r, u0, v1);
//printf("uv: %f, %f, %f, %f\n", u0, v0, u1, v1);
}
int Particle::getParticleTexture()
{
return ParticleEngine::MISC_TEXTURE;
}

46
src/client/particle/Particle.h Executable file
View File

@@ -0,0 +1,46 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__Particle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__Particle_H__
//package net.minecraft.client.particle;
#include "../renderer/Tesselator.h"
#include "../../world/entity/Entity.h"
#include "../../world/level/Level.h"
#include "ParticleEngine.h"
class CompoundTag;
class Particle: public Entity {
typedef Entity super;
public:
static float xOff, yOff, zOff;
Particle(Level* level, float x, float y, float z, float xa, float ya, float za);
virtual ~Particle() {}
Particle* setPower(float power);
Particle* scale(float scale);
virtual void tick();
virtual void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2);
virtual int getParticleTexture();
virtual void addAdditonalSaveData(CompoundTag* entityTag) {}
virtual void readAdditionalSaveData(CompoundTag* tag) {}
virtual int getEntityTypeId() const { return 0; }
protected:
int tex;
float uo, vo;
int age;
int lifetime;
float size;
float gravity;
float rCol, gCol, bCol;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__Particle_H__*/

View File

@@ -0,0 +1,157 @@
#include "ParticleEngine.h"
#include "Particle.h"
#include "TerrainParticle.h"
#include "../renderer/Textures.h"
#include "../../world/level/Level.h"
#include "../../NinecraftApp.h"
ParticleEngine::ParticleEngine(Level* level, Textures* textures)
: level(level),
textures(textures)
{
textures->loadTexture("particles.png");
}
ParticleEngine::~ParticleEngine() {
clear();
}
void ParticleEngine::add(Particle* p) {
int t = p->getParticleTexture();
particles[t].push_back(p);
}
void ParticleEngine::tick() {
for (int tt = 0; tt < TEXTURE_COUNT; tt++) {
ParticleList& list = particles[tt];
unsigned int size = list.size();
for (unsigned int i = 0; i < size; ++i) {
Particle* p = list[i];
p->tick();
if (p->removed) {
list.erase(list.begin() + (i--));
--size;
delete p;
}
}
}
}
void ParticleEngine::render(Entity* player, float a) {
float xa = (float) Mth::cos(player->yRot * Mth::PI / 180);
float za = (float) Mth::sin(player->yRot * Mth::PI / 180);
float xa2 = -za * (float) Mth::sin(player->xRot * Mth::PI / 180);
float za2 = xa * (float) Mth::sin(player->xRot * Mth::PI / 180);
float ya = (float) Mth::cos(player->xRot * Mth::PI / 180);
Particle::xOff = (player->xOld+(player->x-player->xOld)*a);
Particle::yOff = (player->yOld+(player->y-player->yOld)*a);
Particle::zOff = (player->zOld+(player->z-player->zOld)*a);
for (int tt = 0; tt < 3; tt++) {
if (particles[tt].size() == 0) continue;
if (tt == MISC_TEXTURE)
textures->loadAndBindTexture("particles.png");
else if (tt == TERRAIN_TEXTURE)
textures->loadAndBindTexture("terrain.png");
else if (tt == ITEM_TEXTURE)
textures->loadAndBindTexture("gui/items.png");
Tesselator& t = Tesselator::instance;
t.begin();
for (unsigned int i = 0; i < particles[tt].size(); i++) {
Particle* p = particles[tt][i];
p->render(t, a, xa, ya, za, xa2, za2);
}
t.draw();
}
renderLit(player, a);
}
void ParticleEngine::renderLit(Entity* player, float a) {
int tt = ENTITY_PARTICLE_TEXTURE;
ParticleList& pl = particles[tt];
const int size = pl.size();
if (size == 0) return;
float xa = Mth::cos(player->yRot * Mth::DEGRAD);
float za = Mth::sin(player->yRot * Mth::DEGRAD);
float xs = Mth::sin(player->xRot * Mth::DEGRAD);
float xa2 = -za * xs;
float za2 = xa * xs;
float ya = Mth::cos(player->xRot * Mth::DEGRAD);
Tesselator& t = Tesselator::instance;
for (int i = 0; i < size; i++) {
Particle* p = pl[i];
p->render(t, a, xa, ya, za, xa2, za2);
}
}
void ParticleEngine::setLevel(Level* level) {
this->level = level;
clear();
}
void ParticleEngine::destroy(int x, int y, int z) {
int tid = level->getTile(x, y, z);
if (tid == 0) return;
int data = level->getData(x, y, z);
//static Stopwatch sw;
//sw.start();
Tile* tile = Tile::tiles[tid];
const int SD = 3;
for (int xx = 0; xx < SD; xx++)
for (int yy = 1; yy < SD; yy++)
for (int zz = 0; zz < SD; zz++) {
float xp = x + (xx + 0.5f) / SD;
float yp = y + (yy + 0.5f) / SD;
float zp = z + (zz + 0.5f) / SD;
add((new TerrainParticle(level, xp, yp, zp, 2*(xp - x - 0.5f), 2*(yp - y - 0.5f), 2*(zp - z - 0.5f), tile, data))->init(x, y, z));
}
//sw.stop();
//sw.print("gen destroy particles: ");
}
void ParticleEngine::crack(int x, int y, int z, int face) {
int tid = level->getTile(x, y, z);
if (tid == 0) return;
int data = level->getData(x, y, z);
Tile* tile = Tile::tiles[tid];
float r = 0.10f;
float xp = x + random.nextFloat() * ((tile->xx1 - tile->xx0) - r * 2) + r + tile->xx0;
float yp = y + random.nextFloat() * ((tile->yy1 - tile->yy0) - r * 2) + r + tile->yy0;
float zp = z + random.nextFloat() * ((tile->zz1 - tile->zz0) - r * 2) + r + tile->zz0;
switch (face) {
case 0: yp = y + tile->yy0 - r; break;
case 1: yp = y + tile->yy1 + r; break;
case 2: zp = z + tile->zz0 - r; break;
case 3: zp = z + tile->zz1 + r; break;
case 4: xp = x + tile->xx0 - r; break;
case 5: xp = x + tile->xx1 + r; break;
}
add((new TerrainParticle(level, xp, yp, zp, 0, 0, 0, tile, data))->init(x, y, z)->setPower(0.2f)->scale(0.6f));
}
std::string ParticleEngine::countParticles() {
std::stringstream ss;
int count = 0;
for (int i = 0; i < TEXTURE_COUNT; ++i)
count += particles[i].size();
ss << count;
return ss.str();
}
void ParticleEngine::clear()
{
for (int tt = 0; tt < TEXTURE_COUNT; tt++) {
for (unsigned int i = 0; i < particles[tt].size(); i++)
delete particles[tt][i];
particles[tt].clear();
}
}

View File

@@ -0,0 +1,54 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__ParticleEngine_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__ParticleEngine_H__
//package net.minecraft.client.particle;
#include <vector>
#include "../../world/entity/Entity.h"
#include "../../world/level/tile/Tile.h"
#include "../renderer/gles.h"
class Textures;
class Level;
class Particle;
typedef std::vector<Particle*> ParticleList;
class ParticleEngine
{
public:
static const int MISC_TEXTURE = 0;
static const int TERRAIN_TEXTURE = 1;
static const int ITEM_TEXTURE = 2;
static const int ENTITY_PARTICLE_TEXTURE = 3;
static const int TEXTURE_COUNT = 4;
ParticleEngine(Level* level, Textures* textures);
~ParticleEngine();
void add(Particle* p);
void destroy(int x, int y, int z);
void tick();
void render(Entity* player, float a);
void renderLit(Entity* player, float a);
void setLevel(Level* level);
void crack(int x, int y, int z, int face);
std::string countParticles();
protected:
void clear();
Level* level;
GLuint textureIds[4];
private:
ParticleList particles[4];
Textures* textures;
Random random;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__ParticleEngine_H__*/

View File

@@ -0,0 +1,17 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__ParticleInclude_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__ParticleInclude_H__
#include "Particle.h"
#include "BubbleParticle.h"
#include "CritParticle2.h"
#include "ExplodeParticle.h"
#include "FlameParticle.h"
#include "LavaParticle.h"
#include "RedDustParticle.h"
#include "SmokeParticle.h"
#include "TerrainParticle.h"
#include "HugeExplosionSeedParticle.h"
#include "HugeExplosionParticle.h"
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__ParticleInclude_H__*/

View File

@@ -0,0 +1,73 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__RedDustParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__RedDustParticle_H__
//package net.minecraft.client.particle;
#include "../renderer/Tesselator.h"
#include "../../world/level/Level.h"
class RedDustParticle: public Particle
{
typedef Particle super;
public:
float oSize;
RedDustParticle(Level* level, float x, float y, float z, float rCol, float gCol, float bCol, float scale = 1.0f)
: super(level, x, y, z, 0, 0, 0)
{
xd *= 0.1f;
yd *= 0.1f;
zd *= 0.1f;
if (rCol == 0) {
rCol = 1;
}
float brr = (float) Mth::random() * 0.4f + 0.6f;
this->rCol = ((float) (Mth::random() * 0.2f) + 0.8f) * rCol * brr;
this->gCol = ((float) (Mth::random() * 0.2f) + 0.8f) * gCol * brr;
this->bCol = ((float) (Mth::random() * 0.2f) + 0.8f) * bCol * brr;
size *= 0.75f;
size *= scale;
oSize = size;
lifetime = (int) (8 / (Mth::random() * 0.8 + 0.2));
lifetime = (int)(lifetime * scale);
noPhysics = false;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float l = ((age + a) / lifetime) * 32;
if (l < 0) l = 0;
if (l > 1) l = 1;
size = oSize * l;
super::render(t, a, xa, ya, za, xa2, za2);
}
void tick() {
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
tex = 7 - age * 8 / lifetime;
move(xd, yd, zd);
if (y == yo) {
xd *= 1.1f;
zd *= 1.1f;
}
xd *= 0.96f;
yd *= 0.96f;
zd *= 0.96f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__RedDustParticle_H__*/

View File

@@ -0,0 +1,69 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__SmokeParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__SmokeParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
class SmokeParticle: public Particle
{
typedef Particle super;
public:
float oSize;
SmokeParticle(Level* level, float x, float y, float z, float xa, float ya, float za, float scale = 1.0f)
: super(level, x, y, z, 0, 0, 0)
{
xd *= 0.1f;
yd *= 0.1f;
zd *= 0.1f;
xd += xa;
yd += ya;
zd += za;
rCol = gCol = bCol = (float) (Mth::random() * 0.5f);
size *= 0.75f;
size *= scale;
oSize = size;
lifetime = (int) (scale * 8.0f / (Mth::random() * 0.8f + 0.2f));
noPhysics = false;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float l = ((age + a) / lifetime) * 32;
if (l < 0) l = 0;
if (l > 1) l = 1;
size = oSize * l;
super::render(t, a, xa, ya, za, xa2, za2);
}
void tick() {
xo = x;
yo = y;
zo = z;
if (age++ >= lifetime) remove();
tex = 7 - age * 8 / lifetime;
yd += 0.004f;
move(xd, yd, zd);
if (y == yo) {
xd *= 1.1f;
zd *= 1.1f;
}
xd *= 0.96f;
yd *= 0.96f;
zd *= 0.96f;
if (onGround) {
xd *= 0.7f;
zd *= 0.7f;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__SmokeParticle_H__*/

View File

@@ -0,0 +1,26 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__SplashParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__SplashParticle_H__
//package net.minecraft.client.particle;
#include "WaterDropParticle.h"
#include "../../world/level/Level.h"
class SplashParticle: public WaterDropParticle
{
typedef WaterDropParticle super;
public:
SplashParticle(Level* level, float x, float y, float z, float xa, float ya, float za)
: super(level, x, y, z)
{
gravity = 0.04f;
tex += 1;
if (ya == 0 && (xa != 0 || za != 0)) {
xd = xa;
yd = ya + 0.1;
zd = za;
}
}
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__SplashParticle_H__*/

View File

@@ -0,0 +1,82 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__TakeAnimationParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__TakeAnimationParticle_H__
//package net.minecraft.client.particle;
#include "Particle.h"
#include "../renderer/entity/EntityRenderDispatcher.h"
#include "../renderer/Tesselator.h"
#include "../../world/entity/Entity.h"
#include "../../world/level/Level.h"
#include "../../util/Mth.h"
#include "../../world/entity/item/ItemEntity.h"
class TakeAnimationParticle: public Particle
{
typedef Particle super;
public:
//@todo:itementity
TakeAnimationParticle(Level* level, ItemEntity* item, Entity* target, float yOffs)
: super(level, item->x, item->y, item->z, item->xd, item->yd, item->zd),
e(level, item->x, item->y, item->z, item->item),
//bx(item->x), by(item->y), bz(item->z),
target(target),
yOffs(yOffs),
life(0),
lifeTime(3)
{
e.item.count = 1;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float time = (life + a) / lifeTime;
time = time*time;
float xo = e.x;
float yo = e.y;
float zo = e.z;
float xt = target->xOld + (target->x - target->xOld) * a;
float yt = target->yOld + (target->y - target->yOld) * a+yOffs;
float zt = target->zOld + (target->z - target->zOld) * a;
float xx = xo + (xt - xo) * time;
float yy = yo + (yt - yo) * time;
float zz = zo + (zt - zo) * time;
int xTile = Mth::floor(xx);
int yTile = Mth::floor(yy + heightOffset * 0.5f);
int zTile = Mth::floor(zz);
float br = level->getBrightness(xTile, yTile, zTile);
glColor4f2(br, br, br, 1);
xx -= xOff;
yy -= yOff;
zz -= zOff;
EntityRenderDispatcher::getInstance()->render(&e, xx, yy, zz, e.yRot, a);
}
void tick() {
life++;
if (life == lifeTime) remove();
}
int getParticleTexture() {
return ParticleEngine::ENTITY_PARTICLE_TEXTURE;
}
private:
//Entity* item;
ItemEntity e;
Entity* target;
//float bx, by, bz;
int life;
int lifeTime;
float yOffs;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__TakeAnimationParticle_H__*/

View File

@@ -0,0 +1,63 @@
#ifndef NET_MINECRAFT_CLIENT_PARTICLE__TerrainParticle_H__
#define NET_MINECRAFT_CLIENT_PARTICLE__TerrainParticle_H__
//package net.minecraft.client.particle;
#include "../renderer/Tesselator.h"
#include "../../world/level/Level.h"
#include "../../world/level/tile/Tile.h"
#include "../../world/level/tile/GrassTile.h"
class TerrainParticle: public Particle
{
typedef Particle super;
public:
TerrainParticle(Level* level, float x, float y, float z, float xa, float ya, float za, Tile* tile, int data)
: super(level, x, y, z, xa, ya, za),
tile(tile)
{
tex = tile->getTexture(2, data);
gravity = tile->gravity;
rCol = gCol = bCol = 0.6f;
size /= 2;
//noPhysics = true;
}
TerrainParticle* init(int x, int y, int z) {
if (tile == Tile::grass) return this;
int col = tile->getColor(level, x, y, z);
rCol *= ((col >> 16) & 0xff) / 255.0f;
gCol *= ((col >> 8) & 0xff) / 255.0f;
bCol *= ((col) & 0xff) / 255.0f;
return this;
}
int getParticleTexture() {
return ParticleEngine::TERRAIN_TEXTURE;
}
void render(Tesselator& t, float a, float xa, float ya, float za, float xa2, float za2) {
float u0 = ((tex & 15) + uo / 4.0f) / 16.0f;
float u1 = u0 + 0.999f / 16.0f / 4;
float v0 = ((tex >> 4) + vo / 4.0f) / 16.0f;
float v1 = v0 + 0.999f / 16.0f / 4;
float r = 0.1f * size;
float x = (float) (xo + (this->x - xo) * a - xOff);
float y = (float) (yo + (this->y - yo) * a - yOff);
float z = (float) (zo + (this->z - zo) * a - zOff);
float br = getBrightness(a);
t.color(br * rCol, br * gCol, br * bCol);
t.vertexUV(x - xa * r - xa2 * r, y - ya * r, z - za * r - za2 * r, u0, v1);
t.vertexUV(x - xa * r + xa2 * r, y + ya * r, z - za * r + za2 * r, u0, v0);
t.vertexUV(x + xa * r + xa2 * r, y + ya * r, z + za * r + za2 * r, u1, v0);
t.vertexUV(x + xa * r - xa2 * r, y - ya * r, z + za * r - za2 * r, u1, v1);
}
private:
Tile* tile;
};
#endif /*NET_MINECRAFT_CLIENT_PARTICLE__TerrainParticle_H__*/