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 "net.minecraft.world.level.h"
3#include "net.minecraft.world.level.dimension.h"
4#include "net.minecraft.world.h"
5#include "net.minecraft.world.level.tile.h"
6#include "FireTile.h"
7#include "SoundTypes.h"
8#include "..\Minecraft.Client\MinecraftServer.h"
9#include "..\Minecraft.Client\PlayerList.h"
10
11// AP - added for Vita to set Alpha Cut out
12#include "IntBuffer.h"
13#include "..\Minecraft.Client\Tesselator.h"
14
15
16const wstring FireTile::TEXTURE_FIRST = L"fire_0";
17const wstring FireTile::TEXTURE_SECOND = L"fire_1";
18
19FireTile::FireTile(int id) : Tile(id, Material::fire,isSolidRender())
20{
21 flameOdds = new int[256];
22 memset( flameOdds,0,sizeof(int)*256);
23
24 burnOdds = new int[256];
25 memset( burnOdds,0,sizeof(int)*256);
26
27 icons = NULL;
28
29 setTicking(true);
30}
31
32FireTile::~FireTile()
33{
34 delete [] flameOdds;
35 delete [] burnOdds;
36}
37
38void FireTile::init()
39{
40 setFlammable(Tile::wood_Id, FLAME_HARD, BURN_MEDIUM);
41 setFlammable(Tile::woodSlab_Id, FLAME_HARD, BURN_MEDIUM);
42 setFlammable(Tile::woodSlabHalf_Id, FLAME_HARD, BURN_MEDIUM);
43 setFlammable(Tile::fence_Id, FLAME_HARD, BURN_MEDIUM);
44 setFlammable(Tile::stairs_wood_Id, FLAME_HARD, BURN_MEDIUM);
45 setFlammable(Tile::stairs_birchwood_Id, FLAME_HARD, BURN_MEDIUM);
46 setFlammable(Tile::stairs_sprucewood_Id, FLAME_HARD, BURN_MEDIUM);
47 setFlammable(Tile::stairs_junglewood_Id, FLAME_HARD, BURN_MEDIUM);
48 setFlammable(Tile::treeTrunk_Id, FLAME_HARD, BURN_HARD);
49 setFlammable(Tile::leaves_Id, FLAME_EASY, BURN_EASY);
50 setFlammable(Tile::bookshelf_Id, FLAME_EASY, BURN_MEDIUM);
51 setFlammable(Tile::tnt_Id, FLAME_MEDIUM, BURN_INSTANT);
52 setFlammable(Tile::tallgrass_Id, FLAME_INSTANT, BURN_INSTANT);
53 setFlammable(Tile::wool_Id, FLAME_EASY, BURN_EASY);
54 setFlammable(Tile::vine_Id, FLAME_MEDIUM, BURN_INSTANT);
55 setFlammable(Tile::coalBlock_Id, FLAME_HARD, BURN_HARD);
56 setFlammable(Tile::hayBlock_Id, FLAME_INSTANT, BURN_MEDIUM);
57}
58
59void FireTile::setFlammable(int id, int flame, int burn)
60{
61 flameOdds[id] = flame;
62 burnOdds[id] = burn;
63}
64
65AABB *FireTile::getAABB(Level *level, int x, int y, int z)
66{
67 return NULL;
68}
69
70bool FireTile::blocksLight()
71{
72 return false;
73}
74
75bool FireTile::isSolidRender(bool isServerLevel)
76{
77 return false;
78}
79
80bool FireTile::isCubeShaped()
81{
82 return false;
83}
84
85int FireTile::getRenderShape()
86{
87 return Tile::SHAPE_FIRE;
88}
89
90int FireTile::getResourceCount(Random *random)
91{
92 return 0;
93}
94
95int FireTile::getTickDelay(Level *level)
96{
97 return 30;
98}
99
100void FireTile::tick(Level *level, int x, int y, int z, Random *random)
101{
102 if (!level->getGameRules()->getBoolean(GameRules::RULE_DOFIRETICK))
103 {
104 return;
105 }
106
107 // 4J added - we don't want fire to do anything that might create new fire, or destroy this fire, if we aren't actually tracking (for network) the chunk this is in in the player
108 // chunk map. If we did change something in that case, then the change wouldn't get sent to any player that had already received that full chunk, and so we'd just become desynchronised.
109 // Seems safest just to do an addToTickNextTick here instead with a decent delay, to make sure that we will get ticked again in the future, when we might again be in a chunk
110 // that is being tracked.
111 if( !level->isClientSide ) // Note - should only be being ticked on the server
112 {
113 if( !MinecraftServer::getInstance()->getPlayers()->isTrackingTile(x, y, z, level->dimension->id) )
114 {
115 level->addToTickNextTick(x, y, z, id, getTickDelay(level) * 5);
116 return;
117 }
118 }
119
120
121 bool infiniBurn = level->getTile(x, y - 1, z) == Tile::netherRack_Id;
122 if (level->dimension->id == 1) // 4J - was == instanceof TheEndDimension
123 {
124 if (level->getTile(x, y - 1, z) == Tile::unbreakable_Id) infiniBurn = true;
125 }
126
127 if (!mayPlace(level, x, y, z))
128 {
129 level->removeTile(x, y, z);
130 }
131
132 if (!infiniBurn && level->isRaining())
133 {
134 if (level->isRainingAt(x, y, z) || level->isRainingAt(x - 1, y, z) || level->isRainingAt(x + 1, y, z) || level->isRainingAt(x, y, z - 1) || level->isRainingAt(x, y, z + 1)) {
135
136 level->removeTile(x, y, z);
137 return;
138 }
139 }
140
141 int age = level->getData(x, y, z);
142 if (age < 15)
143 {
144 level->setData(x, y, z, age + random->nextInt(3) / 2, Tile::UPDATE_NONE);
145 }
146 level->addToTickNextTick(x, y, z, id, getTickDelay(level) + random->nextInt(10));
147
148 if (!infiniBurn && !isValidFireLocation(level, x, y, z))
149 {
150 if (!level->isTopSolidBlocking(x, y - 1, z) || age > 3) level->removeTile(x, y, z);
151 return;
152 }
153
154 if (!infiniBurn && !canBurn(level, x, y - 1, z))
155 {
156 if (age == 15 && random->nextInt(4) == 0)
157 {
158 level->removeTile(x, y, z);
159 return;
160 }
161 }
162
163 bool isHumid = level->isHumidAt(x, y, z);
164 int extra = 0;
165 if (isHumid)
166 {
167 extra = -50;
168 }
169 checkBurnOut(level, x + 1, y, z, 300 + extra, random, age);
170 checkBurnOut(level, x - 1, y, z, 300 + extra, random, age);
171 checkBurnOut(level, x, y - 1, z, 250 + extra, random, age);
172 checkBurnOut(level, x, y + 1, z, 250 + extra, random, age);
173 checkBurnOut(level, x, y, z - 1, 300 + extra, random, age);
174 checkBurnOut(level, x, y, z + 1, 300 + extra, random, age);
175 if( app.GetGameHostOption(eGameHostOption_FireSpreads) )
176 {
177 for (int xx = x - 1; xx <= x + 1; xx++)
178 {
179 for (int zz = z - 1; zz <= z + 1; zz++)
180 {
181 for (int yy = y - 1; yy <= y + 4; yy++)
182 {
183 if (xx == x && yy == y && zz == z) continue;
184
185 int rate = 100;
186 if (yy > y + 1)
187 {
188 rate += ((yy - (y + 1)) * 100);
189 }
190
191 int fodds = getFireOdds(level, xx, yy, zz);
192 if (fodds > 0) {
193 int odds = (fodds + 40 + (level->difficulty * 7)) / (age + 30);
194 if (isHumid)
195 {
196 odds /= 2;
197 }
198 if (odds > 0 && random->nextInt(rate) <= odds)
199 {
200 if (!(level->isRaining() && level->isRainingAt(xx, yy, zz) || level->isRainingAt(xx - 1, yy, z) || level->isRainingAt(xx + 1, yy, zz) || level->isRainingAt(xx, yy, zz - 1) || level->isRainingAt(xx, yy, zz + 1)))
201 {
202 int tAge = age + random->nextInt(5) / 4;
203 if (tAge > 15) tAge = 15;
204 level->setTileAndData(xx, yy, zz, id, tAge, Tile::UPDATE_ALL);
205 }
206 }
207 }
208 }
209 }
210 }
211 }
212}
213
214bool FireTile::canInstantlyTick()
215{
216 return false;
217}
218
219void FireTile::checkBurnOut(Level *level, int x, int y, int z, int chance, Random *random, int age)
220{
221 int odds = burnOdds[level->getTile(x, y, z)];
222 if (random->nextInt(chance) < odds)
223 {
224 bool wasTnt = level->getTile(x, y, z) == Tile::tnt_Id;
225 if (random->nextInt(age + 10) < 5 && !level->isRainingAt(x, y, z) && app.GetGameHostOption(eGameHostOption_FireSpreads))
226 {
227 int tAge = age + random->nextInt(5) / 4;
228 if (tAge > 15) tAge = 15;
229 level->setTileAndData(x, y, z, id, tAge, Tile::UPDATE_ALL);
230 } else
231 {
232 level->removeTile(x, y, z);
233 }
234 if (wasTnt)
235 {
236 Tile::tnt->destroy(level, x, y, z, TntTile::EXPLODE_BIT);
237 }
238 }
239}
240
241bool FireTile::isValidFireLocation(Level *level, int x, int y, int z)
242{
243 if (canBurn(level, x + 1, y, z)) return true;
244 if (canBurn(level, x - 1, y, z)) return true;
245 if (canBurn(level, x, y - 1, z)) return true;
246 if (canBurn(level, x, y + 1, z)) return true;
247 if (canBurn(level, x, y, z - 1)) return true;
248 if (canBurn(level, x, y, z + 1)) return true;
249
250 return false;
251}
252
253int FireTile::getFireOdds(Level *level, int x, int y, int z)
254{
255 int odds = 0;
256 if (!level->isEmptyTile(x, y, z)) return 0;
257
258 odds = getFlammability(level, x + 1, y, z, odds);
259 odds = getFlammability(level, x - 1, y, z, odds);
260 odds = getFlammability(level, x, y - 1, z, odds);
261 odds = getFlammability(level, x, y + 1, z, odds);
262 odds = getFlammability(level, x, y, z - 1, odds);
263 odds = getFlammability(level, x, y, z + 1, odds);
264
265 return odds;
266}
267
268bool FireTile::mayPick()
269{
270 return false;
271}
272
273bool FireTile::canBurn(LevelSource *level, int x, int y, int z)
274{
275 return flameOdds[level->getTile(x, y, z)] > 0;
276}
277
278int FireTile::getFlammability(Level *level, int x, int y, int z, int odds)
279{
280 int f = flameOdds[level->getTile(x, y, z)];
281 if (f > odds) return f;
282 return odds;
283}
284
285bool FireTile::mayPlace(Level *level, int x, int y, int z)
286{
287 return level->isTopSolidBlocking(x, y - 1, z) || isValidFireLocation(level, x, y, z);
288}
289
290void FireTile::neighborChanged(Level *level, int x, int y, int z, int type)
291{
292 if (!level->isTopSolidBlocking(x, y - 1, z) && !isValidFireLocation(level, x, y, z))
293 {
294 level->removeTile(x, y, z);
295 return;
296 }
297}
298
299void FireTile::onPlace(Level *level, int x, int y, int z)
300{
301 if (level->dimension->id <= 0 && level->getTile(x, y - 1, z) == Tile::obsidian_Id)
302 {
303 if (Tile::portalTile->trySpawnPortal(level, x, y, z, true))
304 {
305 return;
306 }
307 }
308 if (!level->isTopSolidBlocking(x, y - 1, z) && !isValidFireLocation(level, x, y, z))
309 {
310 level->removeTile(x, y, z);
311 return;
312 }
313 level->addToTickNextTick(x, y, z, id, getTickDelay(level) + level->random->nextInt(10));
314}
315
316bool FireTile::isFlammable(int tile)
317{
318 return flameOdds[tile] > 0;
319}
320
321void FireTile::animateTick(Level *level, int x, int y, int z, Random *random)
322{
323 if (random->nextInt(24) == 0)
324 {
325 level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f,eSoundType_FIRE_FIRE, 1 + random->nextFloat(), random->nextFloat() * 0.7f + 0.3f, false);
326 }
327
328 if (level->isTopSolidBlocking(x, y - 1, z) || Tile::fire->canBurn(level, x, y - 1, z))
329 {
330 for (int i = 0; i < 3; i++)
331 {
332 float xx = x + random->nextFloat();
333 float yy = y + random->nextFloat() * 0.5f + 0.5f;
334 float zz = z + random->nextFloat();
335 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
336 }
337 }
338 else
339 {
340 if (Tile::fire->canBurn(level, x - 1, y, z))
341 {
342 for (int i = 0; i < 2; i++)
343 {
344 float xx = x + random->nextFloat() * 0.1f;
345 float yy = y + random->nextFloat();
346 float zz = z + random->nextFloat();
347 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
348 }
349 }
350 if (Tile::fire->canBurn(level, x + 1, y, z))
351 {
352 for (int i = 0; i < 2; i++)
353 {
354 float xx = x + 1 - random->nextFloat() * 0.1f;
355 float yy = y + random->nextFloat();
356 float zz = z + random->nextFloat();
357 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
358 }
359 }
360 if (Tile::fire->canBurn(level, x, y, z - 1))
361 {
362 for (int i = 0; i < 2; i++)
363 {
364 float xx = x + random->nextFloat();
365 float yy = y + random->nextFloat();
366 float zz = z + random->nextFloat() * 0.1f;
367 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
368 }
369 }
370 if (Tile::fire->canBurn(level, x, y, z + 1))
371 {
372 for (int i = 0; i < 2; i++)
373 {
374 float xx = x + random->nextFloat();
375 float yy = y + random->nextFloat();
376 float zz = z + 1 - random->nextFloat() * 0.1f;
377 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
378 }
379 }
380 if (Tile::fire->canBurn(level, x, y + 1, z))
381 {
382 for (int i = 0; i < 2; i++)
383 {
384 float xx = x + random->nextFloat();
385 float yy = y + 1 - random->nextFloat() * 0.1f;
386 float zz = z + random->nextFloat();
387 level->addParticle(eParticleType_largesmoke, xx, yy, zz, 0, 0, 0);
388 }
389 }
390 }
391}
392
393void FireTile::registerIcons(IconRegister *iconRegister)
394{
395 icons = new Icon*[2];
396 icons[0] = iconRegister->registerIcon(TEXTURE_FIRST);
397 icons[1] = iconRegister->registerIcon(TEXTURE_SECOND);
398}
399
400Icon *FireTile::getTextureLayer(int layer)
401{
402#ifdef __PSVITA__
403 // AP - alpha cut out is expensive on vita. Set the Alpha Cut out flag
404 Tesselator* t = Tesselator::getInstance();
405 t->setAlphaCutOut( true );
406#endif
407
408 return icons[layer];
409}
410
411Icon *FireTile::getTexture(int face, int data)
412{
413 return icons[0];
414}