mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-04-05 15:03:31 +00:00
310 lines
10 KiB
C++
Executable File
310 lines
10 KiB
C++
Executable File
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__FireTile_H__
|
|
#define NET_MINECRAFT_WORLD_LEVEL_TILE__FireTile_H__
|
|
|
|
//package net.minecraft.world.level.tile;
|
|
|
|
#include "../../../util/Random.h"
|
|
#include "../material/Material.h"
|
|
#include "../Level.h"
|
|
|
|
#include "Tile.h"
|
|
|
|
class FireTile: public Tile
|
|
{
|
|
int flameOdds[256];
|
|
int burnOdds[256];
|
|
public:
|
|
static const int FLAME_INSTANT = 60;
|
|
static const int FLAME_EASY = 30;
|
|
static const int FLAME_MEDIUM = 15;
|
|
static const int FLAME_HARD = 5;
|
|
|
|
static const int BURN_INSTANT = 100;
|
|
static const int BURN_EASY = 60;
|
|
static const int BURN_MEDIUM = 20;
|
|
static const int BURN_HARD = 5;
|
|
static const int BURN_NEVER = 0;
|
|
|
|
FireTile(int id, int tex)
|
|
: Tile(id, tex, Material::fire)
|
|
{
|
|
for (int i = 0; i < 256; ++i)
|
|
flameOdds[i] = burnOdds[i] = 0;
|
|
|
|
setFlammable(Tile::wood->id, FLAME_HARD, BURN_MEDIUM);
|
|
setFlammable(Tile::treeTrunk->id, FLAME_HARD, BURN_HARD);
|
|
setFlammable(((Tile*)Tile::leaves)->id, FLAME_EASY, BURN_EASY);
|
|
setFlammable(Tile::bookshelf->id, FLAME_EASY, BURN_MEDIUM);
|
|
setFlammable(Tile::tnt->id, FLAME_MEDIUM, BURN_INSTANT);
|
|
setFlammable(Tile::cloth->id, FLAME_EASY, BURN_EASY);
|
|
|
|
//setTicking(true); //@fire
|
|
}
|
|
|
|
AABB* getAABB(Level* level, int x, int y, int z) {
|
|
return NULL;
|
|
}
|
|
|
|
bool blocksLight() {
|
|
return false;
|
|
}
|
|
|
|
bool isSolidRender() {
|
|
return false;
|
|
}
|
|
|
|
bool isCubeShaped() {
|
|
return false;
|
|
}
|
|
|
|
int getRenderShape() {
|
|
return Tile::SHAPE_FIRE;
|
|
}
|
|
|
|
int getResourceCount(Random* random) {
|
|
return 0;
|
|
}
|
|
|
|
int getTickDelay() {
|
|
return 10;
|
|
}
|
|
|
|
void tick(Level* level, int x, int y, int z, Random* random) {
|
|
return; //@fire
|
|
|
|
bool infiniBurn = false;//level->getTile(x, y - 1, z) == Tile::hellRock->id;
|
|
|
|
int age = level->getData(x, y, z);
|
|
if (age < 15) {
|
|
level->setData(x, y, z, age + 1);
|
|
level->addToTickNextTick(x, y, z, id, getTickDelay());
|
|
}
|
|
if (!infiniBurn && !isValidFireLocation(level, x, y, z)) {
|
|
if (!level->isSolidBlockingTile(x, y - 1, z) || age > 3) level->setTile(x, y, z, 0);
|
|
return;
|
|
}
|
|
|
|
if (!infiniBurn && !canBurn(level, x, y - 1, z)) {
|
|
if (age == 15 && random->nextInt(4) == 0) {
|
|
level->setTile(x, y, z, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (age % 2 == 0 && age > 2) {
|
|
checkBurn(level, x + 1, y, z, 300, random);
|
|
checkBurn(level, x - 1, y, z, 300, random);
|
|
checkBurn(level, x, y - 1, z, 250, random);
|
|
checkBurn(level, x, y + 1, z, 250, random);
|
|
checkBurn(level, x, y, z - 1, 300, random);
|
|
checkBurn(level, x, y, z + 1, 300, random);
|
|
|
|
for (int xx = x - 1; xx <= x + 1; xx++) {
|
|
for (int zz = z - 1; zz <= z + 1; zz++) {
|
|
for (int yy = y - 1; yy <= y + 4; yy++) {
|
|
if (xx == x && yy == y && zz == z) continue;
|
|
|
|
int rate = 100;
|
|
if (yy > y + 1) {
|
|
rate += ((yy - (y + 1)) * 100);
|
|
}
|
|
|
|
int odds = getFireOdds(level, xx, yy, zz);
|
|
if (odds > 0 && random->nextInt(rate) <= odds) {
|
|
level->setTile(xx, yy, zz, this->id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (age == 15) {
|
|
checkBurn(level, x + 1, y, z, 1, random);
|
|
checkBurn(level, x - 1, y, z, 1, random);
|
|
checkBurn(level, x, y - 1, z, 1, random);
|
|
checkBurn(level, x, y + 1, z, 1, random);
|
|
checkBurn(level, x, y, z - 1, 1, random);
|
|
checkBurn(level, x, y, z + 1, 1, random);
|
|
}
|
|
}
|
|
|
|
bool mayPick() {
|
|
return false;
|
|
}
|
|
|
|
bool canBurn(LevelSource* level, int x, int y, int z) {
|
|
return flameOdds[level->getTile(x, y, z)] > 0;
|
|
}
|
|
|
|
int getFlammability(Level* level, int x, int y, int z, int odds) {
|
|
|
|
int f = flameOdds[level->getTile(x, y, z)];
|
|
if (f > odds) return f;
|
|
return odds;
|
|
}
|
|
|
|
|
|
bool mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
|
return level->isSolidBlockingTile(x, y - 1, z) || isValidFireLocation(level, x, y, z);
|
|
}
|
|
|
|
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
|
return; //@fire
|
|
if (!level->isSolidBlockingTile(x, y - 1, z) && !isValidFireLocation(level, x, y, z)) {
|
|
level->setTile(x, y, z, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void onPlace(Level* level, int x, int y, int z) {
|
|
return; //@fire
|
|
if (!level->isSolidBlockingTile(x, y - 1, z) && !isValidFireLocation(level, x, y, z)) {
|
|
level->setTile(x, y, z, 0);
|
|
return;
|
|
}
|
|
level->addToTickNextTick(x, y, z, id, getTickDelay());
|
|
}
|
|
|
|
bool isFlammable(int tile) {
|
|
return flameOdds[tile] > 0;
|
|
}
|
|
|
|
void ignite(Level* level, int x, int y, int z) {
|
|
return; //@fire
|
|
|
|
bool lit = false;
|
|
if (!lit) lit = tryIgnite(level, x, y + 1, z);
|
|
if (!lit) lit = tryIgnite(level, x - 1, y, z);
|
|
if (!lit) lit = tryIgnite(level, x + 1, y, z);
|
|
if (!lit) lit = tryIgnite(level, x, y, z - 1);
|
|
if (!lit) lit = tryIgnite(level, x, y, z + 1);
|
|
if (!lit) lit = tryIgnite(level, x, y - 1, z);
|
|
if (!lit) {
|
|
level->setTile(x, y, z, Tile::fire->id);
|
|
}
|
|
}
|
|
|
|
void animateTick(Level* level, int x, int y, int z, Random* random) {
|
|
return; //@fire
|
|
|
|
//if (random.nextInt(24) == 0) {
|
|
// level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, "fire.fire", 1 + random.nextFloat(), random.nextFloat() * 0.7f + 0.3f);
|
|
//}
|
|
|
|
if (level->isSolidBlockingTile(x, y - 1, z) || Tile::fire->canBurn(level, x, y - 1, z)) {
|
|
for (int i = 0; i < 3; i++) {
|
|
float xx = x + random->nextFloat();
|
|
float yy = y + random->nextFloat() * 0.5f + 0.5f;
|
|
float zz = z + random->nextFloat();
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
} else {
|
|
if (Tile::fire->canBurn(level, x - 1, y, z)) {
|
|
for (int i = 0; i < 2; i++) {
|
|
float xx = x + random->nextFloat() * 0.1f;
|
|
float yy = y + random->nextFloat();
|
|
float zz = z + random->nextFloat();
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
}
|
|
if (Tile::fire->canBurn(level, x + 1, y, z)) {
|
|
for (int i = 0; i < 2; i++) {
|
|
float xx = x + 1 - random->nextFloat() * 0.1f;
|
|
float yy = y + random->nextFloat();
|
|
float zz = z + random->nextFloat();
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
}
|
|
if (Tile::fire->canBurn(level, x, y, z - 1)) {
|
|
for (int i = 0; i < 2; i++) {
|
|
float xx = x + random->nextFloat();
|
|
float yy = y + random->nextFloat();
|
|
float zz = z + random->nextFloat() * 0.1f;
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
}
|
|
if (Tile::fire->canBurn(level, x, y, z + 1)) {
|
|
for (int i = 0; i < 2; i++) {
|
|
float xx = x + random->nextFloat();
|
|
float yy = y + random->nextFloat();
|
|
float zz = z + 1 - random->nextFloat() * 0.1f;
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
}
|
|
if (Tile::fire->canBurn(level, x, y + 1, z)) {
|
|
for (int i = 0; i < 2; i++) {
|
|
float xx = x + random->nextFloat();
|
|
float yy = y + 1 - random->nextFloat() * 0.1f;
|
|
float zz = z + random->nextFloat();
|
|
level->addParticle(PARTICLETYPE(largesmoke), xx, yy, zz, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
void setFlammable(int id, int flame, int burn) {
|
|
flameOdds[id] = flame;
|
|
burnOdds[id] = burn;
|
|
}
|
|
|
|
void checkBurn(Level* level, int x, int y, int z, int chance, Random* random) {
|
|
return; //@fire
|
|
|
|
int odds = burnOdds[level->getTile(x, y, z)];
|
|
if (random->nextInt(chance) < odds) {
|
|
bool wasTnt = level->getTile(x, y, z) == Tile::tnt->id;
|
|
if (random->nextInt(2) == 0) {
|
|
level->setTile(x, y, z, this->id);
|
|
} else {
|
|
level->setTile(x, y, z, 0);
|
|
}
|
|
if (wasTnt) {
|
|
Tile::tnt->destroy(level, x, y, z, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool isValidFireLocation(Level* level, int x, int y, int z) {
|
|
return false; //@fire
|
|
|
|
if (canBurn(level, x + 1, y, z)) return true;
|
|
if (canBurn(level, x - 1, y, z)) return true;
|
|
if (canBurn(level, x, y - 1, z)) return true;
|
|
if (canBurn(level, x, y + 1, z)) return true;
|
|
if (canBurn(level, x, y, z - 1)) return true;
|
|
if (canBurn(level, x, y, z + 1)) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
int getFireOdds(Level* level, int x, int y, int z) {
|
|
return 0; //@fire
|
|
|
|
int odds = 0;
|
|
if (!level->isEmptyTile(x, y, z)) return 0;
|
|
|
|
odds = getFlammability(level, x + 1, y, z, odds);
|
|
odds = getFlammability(level, x - 1, y, z, odds);
|
|
odds = getFlammability(level, x, y - 1, z, odds);
|
|
odds = getFlammability(level, x, y + 1, z, odds);
|
|
odds = getFlammability(level, x, y, z - 1, odds);
|
|
odds = getFlammability(level, x, y, z + 1, odds);
|
|
|
|
return odds;
|
|
}
|
|
|
|
bool tryIgnite(Level* level, int x, int y, int z) {
|
|
return false; //@fire
|
|
|
|
int t = level->getTile(x, y, z);
|
|
if (t == Tile::fire->id) return true;
|
|
if (t == 0) {
|
|
level->setTile(x, y, z, Tile::fire->id);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__FireTile_H__*/
|