the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "ParticleEngine.h"
3#include "Particle.h"
4#include "Textures.h"
5#include "TextureAtlas.h"
6#include "Tesselator.h"
7#include "TerrainParticle.h"
8#include "ResourceLocation.h"
9#include "Camera.h"
10#include "..\Minecraft.World\net.minecraft.world.entity.player.h"
11#include "..\Minecraft.World\net.minecraft.world.level.tile.h"
12#include "..\Minecraft.World\net.minecraft.world.level.h"
13#include "..\Minecraft.World\StringHelpers.h"
14#include "..\Minecraft.World\net.minecraft.world.level.dimension.h"
15
16ResourceLocation ParticleEngine::PARTICLES_LOCATION = ResourceLocation(TN_PARTICLES);
17
18ParticleEngine::ParticleEngine(Level *level, Textures *textures)
19{
20// if (level != NULL) // 4J - removed - we want level to be initialised to *something*
21 {
22 this->level = level;
23 }
24 this->textures = textures;
25
26 this->random = new Random();
27}
28
29ParticleEngine::~ParticleEngine()
30{
31 delete random;
32}
33
34void ParticleEngine::add(shared_ptr<Particle> p)
35{
36 int t = p->getParticleTexture();
37 int l = p->level->dimension->id == 0 ? 0 : ( p->level->dimension->id == -1 ? 1 : 2);
38 int maxParticles;
39 switch(p->GetType())
40 {
41 case eTYPE_DRAGONBREATHPARTICLE:
42 maxParticles = MAX_DRAGON_BREATH_PARTICLES;
43 break;
44 case eType_FIREWORKSSPARKPARTICLE:
45 maxParticles = MAX_FIREWORK_SPARK_PARTICLES;
46 break;
47 default:
48 maxParticles = MAX_PARTICLES_PER_LAYER;
49 break;
50 }
51 int list = p->getAlpha() != 1.0f ? TRANSLUCENT_LIST : OPAQUE_LIST; // 4J - Brought forward from Java 1.8
52
53 if( particles[l][t][list].size() >= maxParticles)
54 {
55 particles[l][t][list].pop_front();
56 }
57 particles[l][t][list].push_back(p);
58}
59
60void ParticleEngine::tick()
61{
62 for( int l = 0; l < 3; l++ )
63 {
64 for (int tt = 0; tt < TEXTURE_COUNT; tt++)
65 {
66 for( int list = 0; list < LIST_COUNT; list++ ) // 4J - Brought forward from Java 1.8
67 {
68 for (unsigned int i = 0; i < particles[l][tt][list].size(); i++)
69 {
70 shared_ptr<Particle> p = particles[l][tt][list][i];
71 p->tick();
72 if (p->removed)
73 {
74 particles[l][tt][list][i] = particles[l][tt][list].back();
75 particles[l][tt][list].pop_back();
76 i--;
77 }
78 }
79 }
80 }
81 }
82}
83
84void ParticleEngine::render(shared_ptr<Entity> player, float a, int list)
85{
86 // 4J - change brought forward from 1.2.3
87 float xa = Camera::xa;
88 float za = Camera::za;
89
90 float xa2 = Camera::xa2;
91 float za2 = Camera::za2;
92 float ya = Camera::ya;
93
94 Particle::xOff = (player->xOld + (player->x - player->xOld) * a);
95 Particle::yOff = (player->yOld + (player->y - player->yOld) * a);
96 Particle::zOff = (player->zOld + (player->z - player->zOld) * a);
97 int l = level->dimension->id == 0 ? 0 : ( level->dimension->id == -1 ? 1 : 2 );
98
99 glEnable(GL_BLEND);
100 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
101 glAlphaFunc(GL_GREATER, 1.0f / 255.0f);
102
103 for (int tt = 0; tt < TEXTURE_COUNT; tt++)
104 {
105 if(tt == ENTITY_PARTICLE_TEXTURE) continue;
106
107 if (!particles[l][tt][list].empty())
108 {
109 switch (list)
110 {
111 case TRANSLUCENT_LIST:
112 glDepthMask(false);
113 break;
114 case OPAQUE_LIST:
115 glDepthMask(true);
116 break;
117 }
118
119 MemSect(31);
120 if (tt == MISC_TEXTURE || tt == DRAGON_BREATH_TEXTURE) textures->bindTexture(&PARTICLES_LOCATION);
121 if (tt == TERRAIN_TEXTURE) textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS);
122 if (tt == ITEM_TEXTURE) textures->bindTexture(&TextureAtlas::LOCATION_ITEMS);
123 MemSect(0);
124 Tesselator *t = Tesselator::getInstance();
125 glColor4f(1.0f, 1.0f, 1.0f, 1);
126
127 t->begin();
128 for (unsigned int i = 0; i < particles[l][tt][list].size(); i++)
129 {
130 if(t->hasMaxVertices())
131 {
132 t->end();
133 t->begin();
134 }
135 shared_ptr<Particle> p = particles[l][tt][list][i];
136
137 if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought forward from 1.8.2
138 {
139 t->tex2(p->getLightColor(a));
140 }
141 p->render(t, a, xa, ya, za, xa2, za2);
142 }
143 t->end();
144 }
145 }
146
147 glDisable(GL_BLEND);
148 glDepthMask(true);
149 glAlphaFunc(GL_GREATER, .1f);
150}
151
152void ParticleEngine::renderLit(shared_ptr<Entity> player, float a, int list)
153{
154 // 4J - added. We call this before ParticleEngine::render in the general render per player, so if we
155 // don't set this here then the offsets will be from the previous player - a single frame lag for the
156 // java game, or totally incorrect placement of things for split screen.
157 Particle::xOff = (player->xOld + (player->x - player->xOld) * a);
158 Particle::yOff = (player->yOld + (player->y - player->yOld) * a);
159 Particle::zOff = (player->zOld + (player->z - player->zOld) * a);
160
161 float RAD = PI / 180;
162 float xa = (float) Mth::cos(player->yRot * RAD);
163 float za = (float) Mth::sin(player->yRot * RAD);
164
165 float xa2 = -za * (float) Mth::sin(player->xRot * RAD);
166 float za2 = xa * (float) Mth::sin(player->xRot * RAD);
167 float ya = (float) Mth::cos(player->xRot * RAD);
168
169 int l = level->dimension->id == 0 ? 0 : ( level->dimension->id == -1 ? 1 : 2 );
170 int tt = ENTITY_PARTICLE_TEXTURE;
171
172 if( !particles[l][tt][list].empty() )
173 {
174 Tesselator *t = Tesselator::getInstance();
175 for (unsigned int i = 0; i < particles[l][tt][list].size(); i++)
176 {
177 shared_ptr<Particle> p = particles[l][tt][list][i];
178
179 if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought forward from 1.8.2
180 {
181 t->tex2(p->getLightColor(a));
182 }
183 p->render(t, a, xa, ya, za, xa2, za2);
184 }
185 }
186}
187
188void ParticleEngine::setLevel(Level *level)
189{
190 this->level = level;
191 // 4J - we've now got a set of particle vectors for each dimension, and only clearing them when its game over & the level is set to NULL
192 if( level == NULL )
193 {
194 for( int l = 0; l < 3; l++ )
195 {
196 for (int tt = 0; tt < TEXTURE_COUNT; tt++)
197 {
198 for( int list = 0; list < LIST_COUNT; list++ )
199 {
200 particles[l][tt][list].clear();
201 }
202 }
203 }
204 }
205}
206
207void ParticleEngine::destroy(int x, int y, int z, int tid, int data)
208{
209 if (tid == 0) return;
210
211 Tile *tile = Tile::tiles[tid];
212 int SD = 4;
213 for (int xx = 0; xx < SD; xx++)
214 for (int yy = 0; yy < SD; yy++)
215 for (int zz = 0; zz < SD; zz++)
216 {
217 double xp = x + (xx + 0.5) / SD;
218 double yp = y + (yy + 0.5) / SD;
219 double zp = z + (zz + 0.5) / SD;
220 int face = random->nextInt(6);
221 add(( shared_ptr<TerrainParticle>(new TerrainParticle(level, xp, yp, zp, xp - x - 0.5f, yp - y - 0.5f, zp - z - 0.5f, tile, face, data, textures) ) )->init(x, y, z, data));
222 }
223}
224
225void ParticleEngine::crack(int x, int y, int z, int face)
226{
227 int tid = level->getTile(x, y, z);
228 if (tid == 0) return;
229 Tile *tile = Tile::tiles[tid];
230 float r = 0.10f;
231 double xp = x + random->nextDouble() * ((tile->getShapeX1() - tile->getShapeX0()) - r * 2) + r + tile->getShapeX0();
232 double yp = y + random->nextDouble() * ((tile->getShapeY1() - tile->getShapeY0()) - r * 2) + r + tile->getShapeY0();
233 double zp = z + random->nextDouble() * ((tile->getShapeZ1() - tile->getShapeZ0()) - r * 2) + r + tile->getShapeZ0();
234 if (face == 0) yp = y + tile->getShapeY0() - r;
235 if (face == 1) yp = y + tile->getShapeY1() + r;
236 if (face == 2) zp = z + tile->getShapeZ0() - r;
237 if (face == 3) zp = z + tile->getShapeZ1() + r;
238 if (face == 4) xp = x + tile->getShapeX0() - r;
239 if (face == 5) xp = x + tile->getShapeX1() + r;
240 add(( shared_ptr<TerrainParticle>(new TerrainParticle(level, xp, yp, zp, 0, 0, 0, tile, face, level->getData(x, y, z), textures) ) )->init(x, y, z, level->getData(x, y, z))->setPower(0.2f)->scale(0.6f));
241
242}
243
244void ParticleEngine::markTranslucent(shared_ptr<Particle> particle)
245{
246 moveParticleInList(particle, OPAQUE_LIST, TRANSLUCENT_LIST);
247}
248
249void ParticleEngine::markOpaque(shared_ptr<Particle> particle)
250{
251 moveParticleInList(particle, TRANSLUCENT_LIST, OPAQUE_LIST);
252}
253
254void ParticleEngine::moveParticleInList(shared_ptr<Particle> particle, int source, int destination)
255{
256 int l = particle->level->dimension->id == 0 ? 0 : ( particle->level->dimension->id == -1 ? 1 : 2);
257 for (int tt = 0; tt < TEXTURE_COUNT; tt++)
258 {
259 AUTO_VAR(it, find(particles[l][tt][source].begin(), particles[l][tt][source].end(), particle) );
260 if(it != particles[l][tt][source].end() )
261 {
262 (*it) = particles[l][tt][source].back();
263 particles[l][tt][source].pop_back();
264 particles[l][tt][destination].push_back(particle);
265 }
266 }
267}
268
269wstring ParticleEngine::countParticles()
270{
271 int l = level->dimension->id == 0 ? 0 : (level->dimension->id == -1 ? 1 : 2 );
272 int total = 0;
273 for( int tt = 0; tt < TEXTURE_COUNT; tt++ )
274 {
275 for( int list = 0; list < LIST_COUNT; list++ )
276 {
277 total += particles[l][tt][list].size();
278 }
279 }
280 return _toString<int>(total);
281}