Files
minecraft-pe-0.6.1/src/world/level/tile/LeafTile.h

219 lines
7.9 KiB
C++
Executable File

#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LeafTile_H__
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LeafTile_H__
//package net.minecraft.world.level.tile;
#include "TransparentTile.h"
#include "../Level.h"
#include "../material/Material.h"
#include "../../item/Item.h"
#include "../../item/ItemInstance.h"
#include "../FoliageColor.h"
#include "../LevelSource.h"
#include "../biome/BiomeSource.h"
class Entity;
class LeafTile: public TransparentTile
{
typedef TransparentTile super;
public:
static const int LEAF_TYPE_MASK = 3;
static const int REQUIRED_WOOD_RANGE = 4;
//@attn @note: PERSISTENT_LEAF_BIT and UPDATE_LEAF_BIT are reversed
// here, compared to desktop version
static const int PERSISTENT_LEAF_BIT = 8; // player-placed
static const int UPDATE_LEAF_BIT = 4;
static const int NORMAL_LEAF = 0;
static const int EVERGREEN_LEAF = 1;
static const int BIRCH_LEAF = 2;
LeafTile(int id, int tex)
: super(id, tex, Material::leaves, false),
oTex(tex),
checkBuffer(NULL)
{
setTicking(true);
}
~LeafTile() {
if (checkBuffer != NULL)
delete[] checkBuffer;
}
int getRenderLayer() {
return isSolidRender()? Tile::RENDERLAYER_OPAQUE : Tile::RENDERLAYER_ALPHATEST;
}
int getColor(LevelSource* level, int x, int y, int z) {
int data = (level->getData(x, y, z) & LEAF_TYPE_MASK);
if (data == EVERGREEN_LEAF) {
return FoliageColor::getEvergreenColor();
}
if (data == BIRCH_LEAF) {
return FoliageColor::getBirchColor();
}
if (!FoliageColor::useTint){
return FoliageColor::getDefaultColor();
}
// return FoliageColor::getDefaultColor(); we need to hook this up with OPTION_FOLIAGE_TINT
level->getBiomeSource()->getBiomeBlock(x, z, 1, 1);
float temperature = level->getBiomeSource()->temperatures[0];
float rainfall = level->getBiomeSource()->downfalls[0];
return FoliageColor::get(temperature, rainfall);
}
void onRemove(Level* level, int x, int y, int z) {
int r = 1;
int r2 = r + 1;
if (level->hasChunksAt(x - r2, y - r2, z - r2, x + r2, y + r2, z + r2)) {
for (int xo = -r; xo <= r; xo++)
for (int yo = -r; yo <= r; yo++)
for (int zo = -r; zo <= r; zo++) {
int t = level->getTile(x + xo, y + yo, z + zo);
if (t == Tile::leaves->id) {
int currentData = level->getData(x + xo, y + yo, z + zo);
level->setDataNoUpdate(x + xo, y + yo, z + zo, currentData | UPDATE_LEAF_BIT);
}
}
}
}
int* checkBuffer; //@todo Rewrite this?
void tick(Level* level, int x, int y, int z, Random* random) {
if (level->isClientSide) return;
int currentData = level->getData(x, y, z);
if ((currentData & UPDATE_LEAF_BIT) != 0 && (currentData & PERSISTENT_LEAF_BIT) == 0) {
const int r = LeafTile::REQUIRED_WOOD_RANGE;
int r2 = r + 1;
const int W = 32;
const int WW = W * W;
const int WO = W / 2;
if (!checkBuffer) {
checkBuffer = new int[W * W * W];
}
if (level->hasChunksAt(x - r2, y - r2, z - r2, x + r2, y + r2, z + r2)) {
for (int xo = -r; xo <= r; xo++)
for (int yo = -r; yo <= r; yo++)
for (int zo = -r; zo <= r; zo++) {
int t = level->getTile(x + xo, y + yo, z + zo);
if (t == Tile::treeTrunk->id) {
checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO)] = 0;
} else if (t == Tile::leaves->id) {
checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO)] = -2;
} else {
checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO)] = -1;
}
}
for (int i = 1; i <= LeafTile::REQUIRED_WOOD_RANGE; i++) {
for (int xo = -r; xo <= r; xo++)
for (int yo = -r; yo <= r; yo++)
for (int zo = -r; zo <= r; zo++) {
if (checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO)] == i - 1) {
if (checkBuffer[(xo + WO - 1) * WW + (yo + WO) * W + (zo + WO)] == -2) {
checkBuffer[(xo + WO - 1) * WW + (yo + WO) * W + (zo + WO)] = i;
}
if (checkBuffer[(xo + WO + 1) * WW + (yo + WO) * W + (zo + WO)] == -2) {
checkBuffer[(xo + WO + 1) * WW + (yo + WO) * W + (zo + WO)] = i;
}
if (checkBuffer[(xo + WO) * WW + (yo + WO - 1) * W + (zo + WO)] == -2) {
checkBuffer[(xo + WO) * WW + (yo + WO - 1) * W + (zo + WO)] = i;
}
if (checkBuffer[(xo + WO) * WW + (yo + WO + 1) * W + (zo + WO)] == -2) {
checkBuffer[(xo + WO) * WW + (yo + WO + 1) * W + (zo + WO)] = i;
}
if (checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO - 1)] == -2) {
checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO - 1)] = i;
}
if (checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO + 1)] == -2) {
checkBuffer[(xo + WO) * WW + (yo + WO) * W + (zo + WO + 1)] = i;
}
}
}
}
}
int mid = checkBuffer[(WO) * WW + (WO) * W + (WO)];
if (mid >= 0) {
level->setDataNoUpdate(x, y, z, currentData & ~UPDATE_LEAF_BIT);
} else {
die(level, x, y, z);
}
}
}
void playerDestroy(Level* level, Player* player, int x, int y, int z, int data) {
if (!level->isClientSide) {
ItemInstance* item = player->inventory->getSelected();
if (item && item->id == ((Item*)Item::shears)->id) {
// drop leaf block instead of sapling
popResource(level, x, y, z, ItemInstance(Tile::leaves->id, 1, data & LEAF_TYPE_MASK));
return;
}
}
super::playerDestroy(level, player, x, y, z, data);
}
int getResourceCount(Random* random) {
return random->nextInt(20) == 0 ? 1 : 0;
}
int getResource(int data, Random* random) {
return Tile::sapling->id;
}
void spawnResources(Level* level, int x, int y, int z, int data, float odds) {
if (!level->isClientSide) {
int chance = 20;
if (level->random.nextInt(chance) == 0) {
int type = getResource(data, &level->random);
popResource(level, x, y, z, ItemInstance(type, 1, getSpawnResourcesAuxValue(data)));
}
if ((data & LEAF_TYPE_MASK) == NORMAL_LEAF && level->random.nextInt(200) == 0) {
popResource(level, x, y, z, ItemInstance(Item::apple, 1, 0));
}
}
}
bool isSolidRender() {
return !allowSame;
}
int getTexture(int face, int data) {
if ((data & LEAF_TYPE_MASK) == EVERGREEN_LEAF) {
return (this == Tile::leaves)? tex + 5 * 16
: tex - 16;
}
return tex;
}
void setFancy(bool fancyGraphics) {
allowSame = fancyGraphics;
tex = oTex + (fancyGraphics ? 0 : 1);
}
protected:
int getSpawnResourcesAuxValue(int data) {
return data & LEAF_TYPE_MASK;
}
private:
void die(Level* level, int x, int y, int z) {
spawnResources(level, x, y, z, level->getData(x, y, z) & LEAF_TYPE_MASK, 0);
level->setTile(x, y, z, 0);
}
int oTex;
};
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LeafTile_H__*/