the whole game
This commit is contained in:
213
src/world/level/tile/BedTile.cpp
Executable file
213
src/world/level/tile/BedTile.cpp
Executable file
@@ -0,0 +1,213 @@
|
||||
#include "BedTile.h"
|
||||
#include "../Level.h"
|
||||
#include "../dimension/Dimension.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../../Direction.h"
|
||||
|
||||
const int BedTile::HEAD_DIRECTION_OFFSETS[4][2] = {
|
||||
{ 0, 1 },
|
||||
{ -1, 0 },
|
||||
{ 0, -1 },
|
||||
{ 1, 0 }
|
||||
};
|
||||
|
||||
BedTile::BedTile( int id ) : super(id, 6 + 8 * 16, Material::cloth) {
|
||||
setShape();
|
||||
}
|
||||
|
||||
bool BedTile::use(Level* level, int x, int y, int z, Player* player) {
|
||||
if(player->isSleeping()) {
|
||||
int dimensionsMatch = player->bedPosition.x == x ? 1 : 0;
|
||||
dimensionsMatch += player->bedPosition.y == y ? 1 : 0;
|
||||
dimensionsMatch += player->bedPosition.z == z ? 1 : 0;
|
||||
int maxDistance = Mth::abs(player->bedPosition.x - x);
|
||||
maxDistance = Mth::Max(maxDistance, Mth::abs(player->bedPosition.y - y));
|
||||
maxDistance = Mth::Max(maxDistance, Mth::abs(player->bedPosition.z - z));
|
||||
if(dimensionsMatch >= 2 && maxDistance < 3) {
|
||||
player->stopSleepInBed(false, true, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(level->isClientSide) return true;
|
||||
int data = level->getData(x, y, z);
|
||||
|
||||
if(!isHeadPiece(data)) {
|
||||
int direction = DirectionalTile::getDirection(data);
|
||||
x += HEAD_DIRECTION_OFFSETS[direction][0];
|
||||
z += HEAD_DIRECTION_OFFSETS[direction][1];
|
||||
if(level->getTile(x, y, z) != id) {
|
||||
return true;
|
||||
}
|
||||
data = level->getData(x, y, z);
|
||||
}
|
||||
if(!level->dimension->mayRespawn()) {
|
||||
float xc = x + 0.5f;
|
||||
float yc = y + 0.5f;
|
||||
float zc = z + 0.5f;
|
||||
level->setTile(x, y, z, 0);
|
||||
int direction = DirectionalTile::getDirection(data);
|
||||
x += HEAD_DIRECTION_OFFSETS[direction][0];
|
||||
y += HEAD_DIRECTION_OFFSETS[direction][1];
|
||||
if(level->getTile(x, y, z) == id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
xc = (xc + x + 0.5f) / 2;
|
||||
yc = (yc + y + 0.5f) / 2;
|
||||
zc = (zc + z + 0.5f) / 2;
|
||||
}
|
||||
level->explode(NULL, x + 0.5f, y + 0.5f, z + 0.5f, 5, true);
|
||||
return true;
|
||||
}
|
||||
if(isOccupied(data)) {
|
||||
Player* sleepingPlayer = NULL;
|
||||
for(PlayerList::iterator i = level->players.begin(); i != level->players.end(); ++i) {
|
||||
if((*i)->isSleeping()) {
|
||||
Pos pos = (*i)->bedPosition;
|
||||
if(pos.x == x && pos.y == y && pos.z == z) {
|
||||
sleepingPlayer = (*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(sleepingPlayer == NULL) {
|
||||
BedTile::setOccupied(level, x, y, z, false);
|
||||
}
|
||||
else {
|
||||
sleepingPlayer->displayClientMessage("This bed is occupied"/*"tile.bed.occupied"*/);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int result = player->startSleepInBed(x, y, z);
|
||||
if(result == BedSleepingResult::OK) {
|
||||
BedTile::setOccupied(level, x, y, z, true);
|
||||
return true;
|
||||
}
|
||||
if(result == BedSleepingResult::NOT_POSSIBLE_NOW) {
|
||||
player->displayClientMessage("You can only sleep at night" /*tile.bed.noSleep"*/);
|
||||
} else if(result == BedSleepingResult::NOT_SAFE) {
|
||||
player->displayClientMessage("You may not rest now, there are monsters nearby"/*"tile.bed.notSafe"*/);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BedTile::setOccupied( Level* level, int x, int y, int z, bool occupied ) {
|
||||
int data = level->getData(x, y, z);
|
||||
if(occupied) {
|
||||
data |= OCCUPIED_DATA;
|
||||
} else {
|
||||
data &= ~OCCUPIED_DATA;
|
||||
}
|
||||
level->setData(x, y, z, data);
|
||||
}
|
||||
|
||||
int BedTile::getTexture( int face, int data ) {
|
||||
if(face == Facing::DOWN) {
|
||||
return Tile::wood->tex;
|
||||
}
|
||||
int direction = getDirection(data);
|
||||
int tileFacing = Direction::RELATIVE_DIRECTION_FACING[direction][face];
|
||||
if (isHeadPiece(data)) {
|
||||
if (tileFacing == Facing::NORTH) {
|
||||
return tex + 2 + 16;
|
||||
}
|
||||
if (tileFacing == Facing::EAST || tileFacing == Facing::WEST) {
|
||||
return tex + 1 + 16;
|
||||
}
|
||||
return tex + 1;
|
||||
} else {
|
||||
if (tileFacing == Facing::SOUTH) {
|
||||
return tex - 1 + 16;
|
||||
}
|
||||
if (tileFacing == Facing::EAST || tileFacing == Facing::WEST) {
|
||||
return tex + 16;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
int BedTile::getRenderShape() {
|
||||
return Tile::SHAPE_BED;
|
||||
}
|
||||
|
||||
bool BedTile::isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BedTile::isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void BedTile::neighborChanged( Level* level, int x, int y, int z, int type ) {
|
||||
int data = level->getData(x, y, z);
|
||||
int direction = getDirection(data);
|
||||
if(isHeadPiece(data)) {
|
||||
if(level->getTile(x - HEAD_DIRECTION_OFFSETS[direction][0], y, z - HEAD_DIRECTION_OFFSETS[direction][1]) != id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
} else {
|
||||
if(level->getTile(x + HEAD_DIRECTION_OFFSETS[direction][0], y, z + HEAD_DIRECTION_OFFSETS[direction][1]) != id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
if(!level->isClientSide) {
|
||||
//spawnResources(level, x, y, z, data, 1);
|
||||
popResource(level, x, y, z, ItemInstance(Item::bed));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BedTile::getResource( int data, Random* random ) {
|
||||
if(isHeadPiece(data)) {
|
||||
return 0;
|
||||
}
|
||||
return Item::bed->id;
|
||||
}
|
||||
|
||||
bool BedTile::findStandUpPosition( Level* level, int x, int y, int z, int skipCount, Pos& position) {
|
||||
int data = level->getData(x, y, z);
|
||||
int direction = DirectionalTile::getDirection(data);
|
||||
for(int step = 0; step <= 1; ++step) {
|
||||
int startX = x - BedTile::HEAD_DIRECTION_OFFSETS[direction][0] * step - 1;
|
||||
int startZ = z - BedTile::HEAD_DIRECTION_OFFSETS[direction][1] * step - 1;
|
||||
int endX = startX + 2;
|
||||
int endZ = startZ + 2;
|
||||
for(int standX = startX; standX <= endX; ++standX) {
|
||||
for (int standZ = startZ; standZ <= endZ; ++standZ) {
|
||||
if (level->isSolidBlockingTile(standX, y - 1, standZ) && level->isEmptyTile(standX, y, standZ) && level->isEmptyTile(standX, y + 1, standZ)) {
|
||||
if (skipCount > 0) {
|
||||
skipCount--;
|
||||
continue;
|
||||
}
|
||||
position = Pos(standX, y, standZ);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BedTile::spawnResources( Level* level, int x, int y, int z, int data, float odds ) {
|
||||
if(!isHeadPiece(data)) {
|
||||
//super::spawnResources(level, x, y, z, data, odds);
|
||||
popResource(level, x, y, z, ItemInstance(Item::bed));
|
||||
}
|
||||
}
|
||||
|
||||
void BedTile::updateShape( LevelSource* level, int x, int y, int z ) {
|
||||
setShape();
|
||||
}
|
||||
|
||||
int BedTile::getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
void BedTile::setShape() {
|
||||
super::setShape(0, 0, 0, 1, 9.0f / 16.0f, 1);
|
||||
}
|
||||
|
||||
bool BedTile::isHeadPiece( int data ) {
|
||||
return (data & HEAD_PIECE_DATA) != 0;
|
||||
}
|
||||
|
||||
bool BedTile::isOccupied( int data ) {
|
||||
return (data & OCCUPIED_DATA) != 0;
|
||||
}
|
||||
40
src/world/level/tile/BedTile.h
Executable file
40
src/world/level/tile/BedTile.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__BedTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__BedTile_H__
|
||||
|
||||
#include "DirectionalTile.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class Pos;
|
||||
class BedTile : public DirectionalTile
|
||||
{
|
||||
typedef DirectionalTile super;
|
||||
public:
|
||||
static const int HEAD_PIECE_DATA = 0x8;
|
||||
static const int OCCUPIED_DATA = 0x4;
|
||||
static const int HEAD_DIRECTION_OFFSETS[4][2];
|
||||
|
||||
BedTile(int id);
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
|
||||
int getTexture(int face, int data);
|
||||
int getRenderShape();
|
||||
int getRenderLayer();
|
||||
bool isCubeShaped();
|
||||
bool isSolidRender();
|
||||
|
||||
void updateShape(LevelSource* level, int x, int y, int z);
|
||||
void setShape();
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type);
|
||||
|
||||
int getResource(int data, Random* random);
|
||||
void spawnResources(Level* level, int x, int y, int z, int data, float odds);
|
||||
|
||||
static bool isHeadPiece( int data );
|
||||
static bool isOccupied(int data);
|
||||
static void setOccupied( Level* level, int x, int y, int z, bool occupied );
|
||||
static bool findStandUpPosition( Level* level, int x, int y, int z, int skipCount, Pos& position);
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__BedTile_H__ */
|
||||
33
src/world/level/tile/BookshelfTile.h
Executable file
33
src/world/level/tile/BookshelfTile.h
Executable file
@@ -0,0 +1,33 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__BookshelfTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__BookshelfTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../item/Item.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class BookshelfTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
BookshelfTile(int id, int tex)
|
||||
: super(id, tex, Material::wood)
|
||||
{
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face <= 1) return 4;
|
||||
return tex;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
//@Override
|
||||
int getResource(int data, Random* random/*, int playerBonusLevel*/) {
|
||||
return Item::book->id;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__BookshelfTile_H__*/
|
||||
82
src/world/level/tile/Bush.h
Executable file
82
src/world/level/tile/Bush.h
Executable file
@@ -0,0 +1,82 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__Bush_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__Bush_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../Level.h"
|
||||
#include "Tile.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class Bush: public Tile
|
||||
{
|
||||
public:
|
||||
Bush(int id, int tex)
|
||||
: Tile(id, Material::plant)
|
||||
{
|
||||
this->tex = tex;
|
||||
setTicking(true);
|
||||
float ss = 0.2f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 3, 0.5f + ss);
|
||||
}
|
||||
Bush(int id, int tex, const Material* material) : Tile(id, material) {
|
||||
this->tex = tex;
|
||||
setTicking(true);
|
||||
float ss = 0.2f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 3, 0.5f + ss);
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
||||
return mayPlaceOn(level->getTile(x, y - 1, z));
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
Tile::neighborChanged(level, x, y, z, type);
|
||||
checkAlive(level, x, y, z);
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
checkAlive(level, x, y, z);
|
||||
}
|
||||
|
||||
bool canSurvive(Level* level, int x, int y, int z) {
|
||||
return (level->getRawBrightness(x, y, z)>=8 || level->canSeeSky(x, y, z)) && mayPlaceOn(level->getTile(x, y - 1, z));
|
||||
}
|
||||
|
||||
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_CROSS_TEXTURE;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool mayPlaceOn(int tile) {
|
||||
return tile == ((Tile*)Tile::grass)->id || tile == Tile::dirt->id || tile == Tile::farmland->id;
|
||||
}
|
||||
|
||||
const void checkAlive(Level* level, int x, int y, int z) {
|
||||
if (!canSurvive(level, x, y, z)) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, 0);
|
||||
//printf("died! @ %d,%d,%d\n", x, y, z);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__Bush_H__*/
|
||||
111
src/world/level/tile/CactusTile.h
Executable file
111
src/world/level/tile/CactusTile.h
Executable file
@@ -0,0 +1,111 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__CactusTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__CactusTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
//#include "world/damagesource/DamageSource.h"
|
||||
#include "Tile.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/Entity.h"
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class Random;
|
||||
|
||||
class CactusTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
|
||||
public:
|
||||
CactusTile(int id, int tex)
|
||||
: super(id, tex, Material::cactus)
|
||||
{
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->isEmptyTile(x, y + 1, z)) {
|
||||
int height = 1;
|
||||
while (level->getTile(x, y - height, z) == id) {
|
||||
height++;
|
||||
}
|
||||
if (height < 3) {
|
||||
int age = level->getData(x, y, z);
|
||||
// It takes way to long on pocket edition becuase of fewer ticks
|
||||
if (age >= /*15*/10) {
|
||||
level->setTile(x, y + 1, z, id);
|
||||
level->setData(x, y, z, 0);
|
||||
} else {
|
||||
level->setData(x, y, z, age + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
float r = 1 / 16.0f;
|
||||
tmpBB.x0 = x + r;
|
||||
tmpBB.y0 = (float)y;
|
||||
tmpBB.z0 = z + r;
|
||||
tmpBB.x1 = x + 1 - r;
|
||||
tmpBB.y1 = y + 1 - r;
|
||||
tmpBB.z1 = z + 1 - r;
|
||||
return &tmpBB;
|
||||
}
|
||||
|
||||
AABB getTileAABB(Level* level, int x, int y, int z) {
|
||||
float r = 1 / 16.0f;
|
||||
return AABB((float)x + r, (float)y, (float)z + r, (float)x + 1 - r, (float)y + 1, (float)z + 1 - r);
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face == 1) return tex - 1;
|
||||
if (face == 0) return tex + 1;
|
||||
else return tex;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_CACTUS;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
if (!super::mayPlace(level, x, y, z)) return false;
|
||||
|
||||
return canSurvive(level, x, y, z);
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
if (!canSurvive(level, x, y, z)) {
|
||||
// Should always spawn a cactus when this happens
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z), 1);
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool canSurvive(Level* level, int x, int y, int z) {
|
||||
if (level->getMaterial(x - 1, y, z)->isSolid()) return false;
|
||||
if (level->getMaterial(x + 1, y, z)->isSolid()) return false;
|
||||
if (level->getMaterial(x, y, z - 1)->isSolid()) return false;
|
||||
if (level->getMaterial(x, y, z + 1)->isSolid()) return false;
|
||||
int below = level->getTile(x, y - 1, z);
|
||||
return below == Tile::cactus->id || below == Tile::sand->id;
|
||||
}
|
||||
|
||||
void entityInside(Level* level, int x, int y, int z, Entity* entity) {
|
||||
entity->hurt(NULL/*DamageSource.cactus*/, 1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__CactusTile_H__*/
|
||||
40
src/world/level/tile/CarriedTile.h
Executable file
40
src/world/level/tile/CarriedTile.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__CarriedTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__CarriedTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class CarriedTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
CarriedTile(int id, int texDefault, int texTop = -1)
|
||||
: super(id, tex, Material::dirt),
|
||||
texDefault(texDefault),
|
||||
texTop(texTop >= 0? texTop : texDefault)
|
||||
{
|
||||
}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (face == 1) return texTop;
|
||||
return texDefault;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int texDefault;
|
||||
int texTop;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__CarriedTile_H__*/
|
||||
321
src/world/level/tile/ChestTile.cpp
Executable file
321
src/world/level/tile/ChestTile.cpp
Executable file
@@ -0,0 +1,321 @@
|
||||
#include "ChestTile.h"
|
||||
#include "entity/ChestTileEntity.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
|
||||
ChestTile::ChestTile( int id )
|
||||
: super(id, Material::wood)
|
||||
{
|
||||
tex = 10 + 16;
|
||||
const float m = 0.025f;
|
||||
setShape(m, 0, m, 1-m, 1-m-m, 1-m);
|
||||
}
|
||||
|
||||
bool ChestTile::isSolidRender()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChestTile::isCubeShaped()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int ChestTile::getRenderShape()
|
||||
{
|
||||
return super::getRenderShape();
|
||||
//return Tile::SHAPE_ENTITYTILE_ANIMATED;
|
||||
}
|
||||
|
||||
void ChestTile::onPlace( Level* level, int x, int y, int z )
|
||||
{
|
||||
super::onPlace(level, x, y, z);
|
||||
recalcLockDir(level, x, y, z);
|
||||
|
||||
//@fullchest
|
||||
//int n = level->getTile(x, y, z - 1); // face = 2
|
||||
//int s = level->getTile(x, y, z + 1); // face = 3
|
||||
//int w = level->getTile(x - 1, y, z); // face = 4
|
||||
//int e = level->getTile(x + 1, y, z); // face = 5
|
||||
//if (n == id) recalcLockDir(level, x, y, z - 1);
|
||||
//if (s == id) recalcLockDir(level, x, y, z + 1);
|
||||
//if (w == id) recalcLockDir(level, x - 1, y, z);
|
||||
//if (e == id) recalcLockDir(level, x + 1, y, z);
|
||||
}
|
||||
|
||||
void ChestTile::setPlacedBy( Level* level, int x, int y, int z, Mob* by )
|
||||
{
|
||||
int n = level->getTile(x, y, z - 1); // face = 2
|
||||
int s = level->getTile(x, y, z + 1); // face = 3
|
||||
int w = level->getTile(x - 1, y, z); // face = 4
|
||||
int e = level->getTile(x + 1, y, z); // face = 5
|
||||
|
||||
int facing = 0;
|
||||
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3;
|
||||
|
||||
if (dir == 0) facing = Facing::NORTH;
|
||||
if (dir == 1) facing = Facing::EAST;
|
||||
if (dir == 2) facing = Facing::SOUTH;
|
||||
if (dir == 3) facing = Facing::WEST;
|
||||
|
||||
if (n != id && s != id && w != id && e != id) {
|
||||
level->setData(x, y, z, facing);
|
||||
} else {
|
||||
if ((n == id || s == id) && (facing == Facing::WEST || facing == Facing::EAST)) {
|
||||
if (n == id) level->setData(x, y, z - 1, facing);
|
||||
else level->setData(x, y, z + 1, facing);
|
||||
level->setData(x, y, z, facing);
|
||||
}
|
||||
if ((w == id || e == id) && (facing == Facing::NORTH || facing == Facing::SOUTH)) {
|
||||
if (w == id) level->setData(x - 1, y, z, facing);
|
||||
else level->setData(x + 1, y, z, facing);
|
||||
level->setData(x, y, z, facing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChestTile::recalcLockDir( Level* level, int x, int y, int z )
|
||||
{
|
||||
if (level->isClientSide)
|
||||
return;
|
||||
|
||||
int n = level->getTile(x, y, z - 1); // face = 2
|
||||
int s = level->getTile(x, y, z + 1); // face = 3
|
||||
int w = level->getTile(x - 1, y, z); // face = 4
|
||||
int e = level->getTile(x + 1, y, z); // face = 5
|
||||
|
||||
// Long!
|
||||
//@fullchest
|
||||
int lockDir = 4;
|
||||
/*
|
||||
if (n == id || s == id) {
|
||||
int w2 = level->getTile(x - 1, y, n == id ? z - 1 : z + 1);
|
||||
int e2 = level->getTile(x + 1, y, n == id ? z - 1 : z + 1);
|
||||
|
||||
lockDir = 5;
|
||||
|
||||
int otherDir = -1;
|
||||
if (n == id) otherDir = level->getData(x, y, z - 1);
|
||||
else otherDir = level->getData(x, y, z + 1);
|
||||
if (otherDir == 4) lockDir = 4;
|
||||
|
||||
if ((Tile::solid[w] || Tile::solid[w2]) && !Tile::solid[e] && !Tile::solid[e2]) lockDir = 5;
|
||||
if ((Tile::solid[e] || Tile::solid[e2]) && !Tile::solid[w] && !Tile::solid[w2]) lockDir = 4;
|
||||
} else if (w == id || e == id) {
|
||||
int n2 = level->getTile(w == id ? x - 1 : x + 1, y, z - 1);
|
||||
int s2 = level->getTile(w == id ? x - 1 : x + 1, y, z + 1);
|
||||
|
||||
lockDir = 3;
|
||||
int otherDir = -1;
|
||||
if (w == id) otherDir = level->getData(x - 1, y, z);
|
||||
else otherDir = level->getData(x + 1, y, z);
|
||||
if (otherDir == 2) lockDir = 2;
|
||||
|
||||
if ((Tile::solid[n] || Tile::solid[n2]) && !Tile::solid[s] && !Tile::solid[s2]) lockDir = 3;
|
||||
if ((Tile::solid[s] || Tile::solid[s2]) && !Tile::solid[n] && !Tile::solid[n2]) lockDir = 2;
|
||||
} else */ {
|
||||
lockDir = level->getData(x, y, z);
|
||||
if ((lockDir == Facing::NORTH && Tile::solid[n])
|
||||
|| (lockDir == Facing::SOUTH && Tile::solid[s])
|
||||
|| (lockDir == Facing::WEST && Tile::solid[w])
|
||||
|| (lockDir == Facing::EAST && Tile::solid[e])) {
|
||||
if (Tile::solid[n] && !Tile::solid[s]) lockDir = Facing::SOUTH;
|
||||
if (Tile::solid[s] && !Tile::solid[n]) lockDir = Facing::NORTH;
|
||||
if (Tile::solid[w] && !Tile::solid[e]) lockDir = Facing::EAST;
|
||||
if (Tile::solid[e] && !Tile::solid[w]) lockDir = Facing::WEST;
|
||||
}
|
||||
}
|
||||
|
||||
level->setData(x, y, z, lockDir);
|
||||
}
|
||||
|
||||
int ChestTile::getTexture( LevelSource* level, int x, int y, int z, int face )
|
||||
{
|
||||
if (face == 1) return tex - 1;
|
||||
if (face == 0) return tex - 1;
|
||||
|
||||
/*
|
||||
int n = level->getTile(x, y, z - 1); // face = 2
|
||||
int s = level->getTile(x, y, z + 1); // face = 3
|
||||
int w = level->getTile(x - 1, y, z); // face = 4
|
||||
int e = level->getTile(x + 1, y, z); // face = 5
|
||||
*/
|
||||
|
||||
// Long!
|
||||
//@fullchest
|
||||
/*
|
||||
if (n == id || s == id) {
|
||||
if (face == 2 || face == 3) return tex;
|
||||
int offs = 0;
|
||||
if (n == id) {
|
||||
offs = -1;
|
||||
}
|
||||
|
||||
int w2 = level->getTile(x - 1, y, n == id ? z - 1 : z + 1);
|
||||
int e2 = level->getTile(x + 1, y, n == id ? z - 1 : z + 1);
|
||||
|
||||
if (face == 4) offs = -1 - offs;
|
||||
|
||||
int lockDir = 5;
|
||||
if ((Tile::solid[w] || Tile::solid[w2]) && !Tile::solid[e] && !Tile::solid[e2]) lockDir = 5;
|
||||
if ((Tile::solid[e] || Tile::solid[e2]) && !Tile::solid[w] && !Tile::solid[w2]) lockDir = 4;
|
||||
return (face == lockDir ? tex + 16 : tex + 32) + offs;
|
||||
} else if (w == id || e == id) {
|
||||
if (face == 4 || face == 5) return tex;
|
||||
int offs = 0;
|
||||
if (w == id) {
|
||||
offs = -1;
|
||||
}
|
||||
|
||||
int n2 = level->getTile(w == id ? x - 1 : x + 1, y, z - 1);
|
||||
int s2 = level->getTile(w == id ? x - 1 : x + 1, y, z + 1);
|
||||
|
||||
if (face == 3) offs = -1 - offs;
|
||||
int lockDir = 3;
|
||||
if ((Tile::solid[n] || Tile::solid[n2]) && !Tile::solid[s] && !Tile::solid[s2]) lockDir = 3;
|
||||
if ((Tile::solid[s] || Tile::solid[s2]) && !Tile::solid[n] && !Tile::solid[n2]) lockDir = 2;
|
||||
|
||||
return (face == lockDir ? tex + 16 : tex + 32) + offs;
|
||||
} else { */
|
||||
//int lockDir = 3;
|
||||
int lockDir = level->getData(x, y, z);
|
||||
|
||||
/*
|
||||
if ((lockDir == Facing::NORTH && Tile::solid[n])
|
||||
|| (lockDir == Facing::SOUTH && Tile::solid[s])
|
||||
|| (lockDir == Facing::WEST && Tile::solid[w])
|
||||
|| (lockDir == Facing::EAST && Tile::solid[e])) {
|
||||
if (Tile::solid[n] && !Tile::solid[s]) lockDir = 3;
|
||||
if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2;
|
||||
if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5;
|
||||
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
if (Tile::solid[n] && !Tile::solid[s]) lockDir = 3;
|
||||
if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2;
|
||||
if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5;
|
||||
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
|
||||
*/
|
||||
return (face == lockDir)? tex + 1 : tex;
|
||||
}
|
||||
|
||||
int ChestTile::getTexture( int face )
|
||||
{
|
||||
if (face == 1) return tex - 1;
|
||||
if (face == 0) return tex - 1;
|
||||
if (face == 3) return tex + 1;
|
||||
return tex;
|
||||
}
|
||||
|
||||
bool ChestTile::mayPlace( Level* level, int x, int y, int z, unsigned char face )
|
||||
{
|
||||
int chestCount = 0;
|
||||
|
||||
if (level->getTile(x - 1, y, z) == id) chestCount++;
|
||||
if (level->getTile(x + 1, y, z) == id) chestCount++;
|
||||
if (level->getTile(x, y, z - 1) == id) chestCount++;
|
||||
if (level->getTile(x, y, z + 1) == id) chestCount++;
|
||||
|
||||
//@fullchest
|
||||
if (chestCount > 0) return false;
|
||||
|
||||
//if (isFullChest(level, x - 1, y, z)) return false;
|
||||
//if (isFullChest(level, x + 1, y, z)) return false;
|
||||
//if (isFullChest(level, x, y, z - 1)) return false;
|
||||
//if (isFullChest(level, x, y, z + 1)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChestTile::neighborChanged( Level* level, int x, int y, int z, int type )
|
||||
{
|
||||
super::neighborChanged(level, x, y, z, type);
|
||||
recalcLockDir(level, x, y, z);
|
||||
TileEntity* te = level->getTileEntity(x, y, z);
|
||||
if (te != NULL) te->clearCache();
|
||||
}
|
||||
|
||||
void ChestTile::onRemove( Level* level, int x, int y, int z )
|
||||
{
|
||||
if (!level->isClientSide) {
|
||||
TileEntity* te = level->getTileEntity(x, y, z);
|
||||
if (te != NULL && te->type == TileEntityType::Chest) {
|
||||
Container* container = (ChestTileEntity*) te;
|
||||
for (int i = 0; i < container->getContainerSize(); i++) {
|
||||
ItemInstance* item = container->getItem(i);
|
||||
if (item != NULL) {
|
||||
float xo = random.nextFloat() * 0.8f + 0.1f;
|
||||
float yo = random.nextFloat() * 0.8f + 0.1f;
|
||||
float zo = random.nextFloat() * 0.8f + 0.1f;
|
||||
|
||||
while (item->count > 0) {
|
||||
int count = random.nextInt(21) + 10;
|
||||
if (count > item->count) count = item->count;
|
||||
item->count -= count;
|
||||
ItemEntity* itemEntity = new ItemEntity(level, x + xo, y + yo, z + zo, ItemInstance(item->id, count, item->getAuxValue()));
|
||||
float pow = 0.05f;
|
||||
itemEntity->xd = (float) random.nextGaussian() * pow;
|
||||
itemEntity->yd = (float) random.nextGaussian() * pow + 0.2f;
|
||||
itemEntity->zd = (float) random.nextGaussian() * pow;
|
||||
//if (item->hasTag()) {
|
||||
// itemEntity->item->setTag((CompoundTag*) item->getTag()->copy());
|
||||
//}
|
||||
level->addEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super::onRemove(level, x, y, z);
|
||||
}
|
||||
|
||||
bool ChestTile::use( Level* level, int x, int y, int z, Player* player )
|
||||
{
|
||||
TileEntity* te = level->getTileEntity(x, y, z);
|
||||
if (!TileEntity::isType(te, TileEntityType::Chest))
|
||||
return true;
|
||||
|
||||
ChestTileEntity* chest = (ChestTileEntity*) te;
|
||||
|
||||
if (level->isSolidBlockingTile(x, y + 1, z)) return true;
|
||||
|
||||
// @fullchest
|
||||
//if (level->getTile(x - 1, y, z) == id && (level->isSolidBlockingTile(x - 1, y + 1, z))) return true;
|
||||
//if (level->getTile(x + 1, y, z) == id && (level->isSolidBlockingTile(x + 1, y + 1, z))) return true;
|
||||
//if (level->getTile(x, y, z - 1) == id && (level->isSolidBlockingTile(x, y + 1, z - 1))) return true;
|
||||
//if (level->getTile(x, y, z + 1) == id && (level->isSolidBlockingTile(x, y + 1, z + 1))) return true;
|
||||
|
||||
//if (level->getTile(x - 1, y, z) == id) container = /*new*/ CompoundContainer("Large chest", (ChestTileEntity) level->getTileEntity(x - 1, y, z), container);
|
||||
//if (level->getTile(x + 1, y, z) == id) container = /*new*/ CompoundContainer("Large chest", container, (ChestTileEntity) level->getTileEntity(x + 1, y, z));
|
||||
//if (level->getTile(x, y, z - 1) == id) container = /*new*/ CompoundContainer("Large chest", (ChestTileEntity) level->getTileEntity(x, y, z - 1), container);
|
||||
//if (level->getTile(x, y, z + 1) == id) container = /*new*/ CompoundContainer("Large chest", container, (ChestTileEntity) level->getTileEntity(x, y, z + 1));
|
||||
|
||||
if (level->isClientSide) {
|
||||
return true;
|
||||
}
|
||||
|
||||
player->openContainer(chest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntity* ChestTile::newTileEntity()
|
||||
{
|
||||
return TileEntityFactory::createTileEntity(TileEntityType::Chest);
|
||||
}
|
||||
|
||||
bool ChestTile::isFullChest( Level* level, int x, int y, int z )
|
||||
{
|
||||
return false; //@fullchest
|
||||
/*
|
||||
if (level->getTile(x, y, z) != id) return false;
|
||||
if (level->getTile(x - 1, y, z) == id) return true;
|
||||
if (level->getTile(x + 1, y, z) == id) return true;
|
||||
if (level->getTile(x, y, z - 1) == id) return true;
|
||||
if (level->getTile(x, y, z + 1) == id) return true;
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
51
src/world/level/tile/ChestTile.h
Executable file
51
src/world/level/tile/ChestTile.h
Executable file
@@ -0,0 +1,51 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ChestTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ChestTile_H__
|
||||
|
||||
#include "EntityTile.h"
|
||||
class Level;
|
||||
class LevelSource;
|
||||
class Mob;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
class ChestTile: public EntityTile
|
||||
{
|
||||
typedef EntityTile super;
|
||||
public:
|
||||
static const int EVENT_SET_OPEN_COUNT = 1;
|
||||
|
||||
ChestTile(int id);
|
||||
|
||||
bool isSolidRender();
|
||||
|
||||
/*@Override*/
|
||||
bool isCubeShaped();
|
||||
|
||||
int getRenderShape();
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face);
|
||||
void setPlacedBy(Level* level, int x, int y, int z, Mob* by);
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z);
|
||||
void onRemove(Level* level, int x, int y, int z);
|
||||
|
||||
void recalcLockDir(Level* level, int x, int y, int z);
|
||||
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
int getTexture(int face);
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type);
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
|
||||
TileEntity* newTileEntity();
|
||||
|
||||
private:
|
||||
bool isFullChest(Level* level, int x, int y, int z);
|
||||
|
||||
Random random;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ChestTile_H__*/
|
||||
26
src/world/level/tile/ClayTile.h
Executable file
26
src/world/level/tile/ClayTile.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ClayTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ClayTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class ClayTile: public Tile {
|
||||
public:
|
||||
ClayTile(int id, int tex)
|
||||
: Tile(id, tex, Material::clay)
|
||||
{}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Item::clay->id;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ClayTile_H__*/
|
||||
45
src/world/level/tile/ClothTile.h
Executable file
45
src/world/level/tile/ClothTile.h
Executable file
@@ -0,0 +1,45 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ClothTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ClothTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../material/Material.h"
|
||||
|
||||
class ClothTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
static const int COLOR_TEX_POS = 7 * 16 + 1;
|
||||
public:
|
||||
ClothTile(int id)
|
||||
: super(id, 4 * 16, Material::cloth)
|
||||
{
|
||||
}
|
||||
ClothTile(int id, int data)
|
||||
: super(id, 4 * 16, Material::cloth)
|
||||
{
|
||||
}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (data == 0) {
|
||||
// un-colored cloth
|
||||
return tex;
|
||||
}
|
||||
|
||||
// invert bits (so 1111 becomes black)
|
||||
data = ~(data & 0xf);
|
||||
return COLOR_TEX_POS + ((data & 8) >> 3) + ((data & 7) * 16);
|
||||
}
|
||||
|
||||
static int getTileDataForItemAuxValue(int auxValue) {
|
||||
return (~auxValue & 0xf);
|
||||
}
|
||||
protected:
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
return data;
|
||||
}
|
||||
static int getItemAuxValueForTileData(int data) {
|
||||
return (~data & 0xf);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ClothTile_H__*/
|
||||
113
src/world/level/tile/CropTile.cpp
Executable file
113
src/world/level/tile/CropTile.cpp
Executable file
@@ -0,0 +1,113 @@
|
||||
#include "CropTile.h"
|
||||
#include "Tile.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
|
||||
CropTile::CropTile( int id, int tex ) : super(id, tex) {
|
||||
this->tex = tex;
|
||||
setTicking(true);
|
||||
float ss = 0.5f;
|
||||
setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss);
|
||||
}
|
||||
|
||||
void CropTile::tick( Level* level, int x, int y, int z, Random* random ) {
|
||||
super::tick(level, x, y, z, random);
|
||||
if(level->getRawBrightness(x, y, z) >= Level::MAX_BRIGHTNESS - 6) {
|
||||
int age = level->getData(x, y, z);
|
||||
if(age < 7) {
|
||||
float growthSpeed = getGrowthSpeed(level, x, y, z);
|
||||
if(random->nextInt(int(25 / growthSpeed)) == 0) {
|
||||
age++;
|
||||
level->setData(x, y, z, age);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CropTile::growCropsToMax( Level* level, int x, int y, int z ) {
|
||||
level->setData(x, y, z, 7);
|
||||
}
|
||||
|
||||
float CropTile::getGrowthSpeed( Level* level, int x, int y, int z ) {
|
||||
float speed = 1;
|
||||
|
||||
int n = level->getTile(x, y, z - 1);
|
||||
int s = level->getTile(x, y, z + 1);
|
||||
int w = level->getTile(x - 1, y, z);
|
||||
int e = level->getTile(x + 1, y, z);
|
||||
|
||||
int d0 = level->getTile(x - 1, y, z - 1);
|
||||
int d1 = level->getTile(x + 1, y, z - 1);
|
||||
int d2 = level->getTile(x + 1, y, z + 1);
|
||||
int d3 = level->getTile(x - 1, y, z + 1);
|
||||
|
||||
bool horizontal = w == this->id || e == this->id;
|
||||
bool vertical = n == this->id || s == this->id;
|
||||
bool diagonal = d0 == this->id || d1 == this->id || d2 == this->id || d3 == this->id;
|
||||
|
||||
for (int xx = x - 1; xx <= x + 1; xx++) {
|
||||
for (int zz = z - 1; zz <= z + 1; zz++) {
|
||||
int t = level->getTile(xx, y - 1, zz);
|
||||
|
||||
float tileSpeed = 0;
|
||||
if (t == Tile::farmland->id) {
|
||||
tileSpeed = 1;
|
||||
if (level->getData(xx, y - 1, zz) > 0) tileSpeed = 3;
|
||||
}
|
||||
|
||||
if (xx != x || zz != z) tileSpeed /= 4;
|
||||
|
||||
speed += tileSpeed;
|
||||
}
|
||||
}
|
||||
if (diagonal || (horizontal && vertical)) speed /= 2;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
int CropTile::getTexture( LevelSource* level, int x, int y, int z, int face ) {
|
||||
int data = level->getData(x, y, z);
|
||||
if (data < 0) data = 7;
|
||||
return tex + data;
|
||||
}
|
||||
|
||||
int CropTile::getTexture( int face, int data ) {
|
||||
if (data < 0) data = 7;
|
||||
return tex + data;
|
||||
}
|
||||
|
||||
int CropTile::getRenderShape() {
|
||||
return Tile::SHAPE_ROWS;
|
||||
}
|
||||
void CropTile::spawnResources( Level* level, int x, int y, int z, int data, float odds ) {
|
||||
super::spawnResources(level, x, y, z, data, odds);
|
||||
|
||||
if (level->isClientSide) {
|
||||
return;
|
||||
}
|
||||
int count = 3;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (level->random.nextInt(5 * 3) > data) continue;
|
||||
float s = 0.7f;
|
||||
float xo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float yo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float zo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
ItemEntity* item = new ItemEntity(level, float(x) + xo, float(y) + yo, float(z) + zo, ItemInstance(Item::seeds_wheat));
|
||||
item->throwTime = 10;
|
||||
level->addEntity(item);
|
||||
}
|
||||
}
|
||||
|
||||
int CropTile::getResource( int data, Random* random ) {
|
||||
if (data == 7) {
|
||||
return Item::wheat->id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CropTile::getResourceCount( Random* random ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CropTile::mayPlaceOn( int tile ) {
|
||||
return tile == Tile::farmland->id;
|
||||
}
|
||||
29
src/world/level/tile/CropTile.h
Executable file
29
src/world/level/tile/CropTile.h
Executable file
@@ -0,0 +1,29 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__CropTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__CropTile_H__
|
||||
|
||||
#include "Bush.h"
|
||||
|
||||
class CropTile : public Bush
|
||||
{
|
||||
typedef Bush super;
|
||||
public:
|
||||
CropTile(int id, int tex);
|
||||
bool mayPlaceOn(int tile);
|
||||
void tick(Level* level, int x, int y, int z, Random* random);
|
||||
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
int getTexture( int face, int data );
|
||||
|
||||
int getRenderShape();
|
||||
|
||||
void spawnResources(Level* level, int x, int y, int z, int data, float odds);
|
||||
int getResource(int data, Random* random);
|
||||
int getResourceCount(Random* random);
|
||||
|
||||
void growCropsToMax(Level* level, int x, int y, int z);
|
||||
private:
|
||||
float getGrowthSpeed(Level* level, int x, int y, int z);
|
||||
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__CropTile_H__ */
|
||||
17
src/world/level/tile/DirectionalTile.h
Executable file
17
src/world/level/tile/DirectionalTile.h
Executable file
@@ -0,0 +1,17 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__DirectionalTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__DirectionalTile_H__
|
||||
#include "Tile.h"
|
||||
class Material;
|
||||
class DirectionalTile : public Tile {
|
||||
public:
|
||||
static const int DIRECTION_MASK = 0x3;
|
||||
static const int DIRECTION_INV_MASK = 0xc;
|
||||
static int getDirection(int data) {
|
||||
return data & DIRECTION_MASK;
|
||||
}
|
||||
protected:
|
||||
DirectionalTile(int id, int tex, const Material* material) : Tile(id, tex, material) {}
|
||||
DirectionalTile(int id, const Material* material) : Tile(id, material) {}
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__DirectionalTile_H__ */
|
||||
20
src/world/level/tile/DirtTile.h
Executable file
20
src/world/level/tile/DirtTile.h
Executable file
@@ -0,0 +1,20 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__DirtTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__DirtTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class DirtTile: public Tile
|
||||
{
|
||||
public:
|
||||
/*protected*/
|
||||
DirtTile(int id, int tex)
|
||||
: Tile(id, tex, Material::dirt)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__DirtTile_H__*/
|
||||
230
src/world/level/tile/DoorTile.cpp
Executable file
230
src/world/level/tile/DoorTile.cpp
Executable file
@@ -0,0 +1,230 @@
|
||||
#include "DoorTile.h"
|
||||
#include "LevelEvent.h"
|
||||
#include "../Level.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
|
||||
DoorTile::DoorTile(int id, const Material* material)
|
||||
: super(id, material)
|
||||
{
|
||||
tex = 1 + 6 * 16;
|
||||
if (material == Material::metal) tex++;
|
||||
|
||||
float r = 0.5f;
|
||||
float h = 1.0f;
|
||||
super::setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r);
|
||||
}
|
||||
|
||||
int DoorTile::getTexture(LevelSource* level, int x, int y, int z, int face) {
|
||||
if (face == 0 || face == 1) return tex;
|
||||
|
||||
int compositeData = getCompositeData(level, x, y, z);
|
||||
int texture = tex;
|
||||
if ((compositeData & C_IS_UPPER_MASK) != 0) texture -= 16;
|
||||
|
||||
int dir = compositeData & C_DIR_MASK;
|
||||
bool isOpen = (compositeData & C_OPEN_MASK) != 0;
|
||||
if (isOpen) {
|
||||
if (dir == 0 && face == 2) texture = -texture;
|
||||
else if (dir == 1 && face == 5) texture = -texture;
|
||||
else if (dir == 2 && face == 3) texture = -texture;
|
||||
else if (dir == 3 && face == 4) texture = -texture;
|
||||
} else {
|
||||
if (dir == 0 && face == 5) texture = -texture;
|
||||
else if (dir == 1 && face == 3) texture = -texture;
|
||||
else if (dir == 2 && face == 4) texture = -texture;
|
||||
else if (dir == 3 && face == 2) texture = -texture;
|
||||
if ((compositeData & C_RIGHT_HINGE_MASK) != 0) texture = -texture;
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
bool DoorTile::blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DoorTile::isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DoorTile::isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int DoorTile::getRenderShape() {
|
||||
return Tile::SHAPE_DOOR;
|
||||
}
|
||||
|
||||
int DoorTile::getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
AABB DoorTile::getTileAABB(Level* level, int x, int y, int z) {
|
||||
updateShape(level, x, y, z);
|
||||
return super::getTileAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
AABB* DoorTile::getAABB(Level* level, int x, int y, int z) {
|
||||
updateShape(level, x, y, z);
|
||||
return super::getAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
void DoorTile::updateShape(LevelSource* level, int x, int y, int z) {
|
||||
setShape(getCompositeData(level, x, y, z));
|
||||
}
|
||||
|
||||
void DoorTile::setShape(int compositeData) {
|
||||
float r = 3 / 16.0f;
|
||||
super::setShape(0, 0, 0, 1, 2, 1);
|
||||
int dir = compositeData & C_DIR_MASK;
|
||||
bool open = (compositeData & C_OPEN_MASK) != 0;
|
||||
bool hasRightHinge = (compositeData & C_RIGHT_HINGE_MASK) != 0;
|
||||
if (dir == 0) {
|
||||
if (open) {
|
||||
if (!hasRightHinge) super::setShape(0, 0, 0, 1, 1, r);
|
||||
else super::setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
} else super::setShape(0, 0, 0, r, 1, 1);
|
||||
} else if (dir == 1) {
|
||||
if (open) {
|
||||
if (!hasRightHinge) super::setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
else super::setShape(0, 0, 0, r, 1, 1);
|
||||
} else super::setShape(0, 0, 0, 1, 1, r);
|
||||
} else if (dir == 2) {
|
||||
if (open) {
|
||||
if (!hasRightHinge) super::setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
else super::setShape(0, 0, 0, 1, 1, r);
|
||||
} else super::setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
} else if (dir == 3) {
|
||||
if (open) {
|
||||
if (!hasRightHinge) super::setShape(0, 0, 0, r, 1, 1);
|
||||
else super::setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
} else super::setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void DoorTile::attack(Level* level, int x, int y, int z, Player* player) {
|
||||
use(level, x, y, z, player);
|
||||
}
|
||||
|
||||
bool DoorTile::use(Level* level, int x, int y, int z, Player* player) {
|
||||
if (material == Material::metal) return true;
|
||||
|
||||
int compositeData = getCompositeData(level, x, y, z);
|
||||
int lowerData = compositeData & C_LOWER_DATA_MASK;
|
||||
lowerData ^= 4;
|
||||
if ((compositeData & C_IS_UPPER_MASK) == 0) {
|
||||
level->setData(x, y, z, lowerData);
|
||||
level->setTilesDirty(x, y, z, x, y, z);
|
||||
} else {
|
||||
level->setData(x, y - 1, z, lowerData);
|
||||
level->setTilesDirty(x, y - 1, z, x, y, z);
|
||||
}
|
||||
|
||||
level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DoorTile::isOpen( LevelSource* level, int x, int y, int z )
|
||||
{
|
||||
return (getCompositeData(level, x, y, z) & C_OPEN_MASK) != 0;
|
||||
}
|
||||
|
||||
void DoorTile::setOpen(Level* level, int x, int y, int z, bool shouldOpen) {
|
||||
int compositeData = getCompositeData(level, x, y, z);
|
||||
bool isOpen = (compositeData & C_OPEN_MASK) != 0;
|
||||
if (isOpen == shouldOpen) return;
|
||||
|
||||
int lowerData = compositeData & C_LOWER_DATA_MASK;
|
||||
lowerData ^= 4;
|
||||
if ((compositeData & C_IS_UPPER_MASK) == 0) {
|
||||
level->setData(x, y, z, lowerData);
|
||||
level->setTilesDirty(x, y, z, x, y, z);
|
||||
} else {
|
||||
level->setData(x, y - 1, z, lowerData);
|
||||
level->setTilesDirty(x, y - 1, z, x, y, z);
|
||||
}
|
||||
|
||||
level->levelEvent(NULL, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
|
||||
}
|
||||
|
||||
void DoorTile::neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
int data = level->getData(x, y, z);
|
||||
if ((data & UPPER_BIT) == 0) {
|
||||
bool spawn = false;
|
||||
if (level->getTile(x, y + 1, z) != id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
spawn = true;
|
||||
}
|
||||
if (!level->isSolidBlockingTile(x, y - 1, z)) {
|
||||
level->setTile(x, y, z, 0);
|
||||
spawn = true;
|
||||
if (level->getTile(x, y + 1, z) == id) {
|
||||
level->setTile(x, y + 1, z, 0);
|
||||
}
|
||||
}
|
||||
if (spawn) {
|
||||
if (!level->isClientSide) {
|
||||
spawnResources(level, x, y, z, data, 0);
|
||||
}
|
||||
} else {
|
||||
bool signal = level->hasNeighborSignal(x, y, z) || level->hasNeighborSignal(x, y + 1, z);
|
||||
if ((signal || ((type > 0 && Tile::tiles[type]->isSignalSource()) || type == 0)) && type != id) {
|
||||
setOpen(level, x, y, z, signal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (level->getTile(x, y - 1, z) != id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
if(material == Material::metal) {
|
||||
popResource(level, x, y, z, ItemInstance(Item::door_iron));
|
||||
} else {
|
||||
popResource(level, x, y, z, ItemInstance(Item::door_wood));
|
||||
}
|
||||
}
|
||||
if (type > 0 && type != id) {
|
||||
neighborChanged(level, x, y - 1, z, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DoorTile::getResource(int data, Random* random) {
|
||||
if ((data & 8) != 0) return 0;
|
||||
if (material == Material::metal) return Item::door_iron->id;
|
||||
return Item::door_wood->id;
|
||||
}
|
||||
|
||||
HitResult DoorTile::clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b) {
|
||||
updateShape(level, xt, yt, zt);
|
||||
return super::clip(level, xt, yt, zt, a, b);
|
||||
}
|
||||
|
||||
int DoorTile::getDir(LevelSource* level, int x, int y, int z) {
|
||||
return getCompositeData(level, x, y, z) & C_DIR_MASK;
|
||||
}
|
||||
|
||||
bool DoorTile::mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
||||
if (y >= Level::DEPTH - 1) return false;
|
||||
|
||||
return (level->isSolidBlockingTile(x, y - 1, z)
|
||||
&& super::mayPlace(level, x, y, z)
|
||||
&& super::mayPlace(level, x, y + 1, z));
|
||||
}
|
||||
|
||||
int DoorTile::getCompositeData( LevelSource* level, int x, int y, int z ) {
|
||||
int data = level->getData(x, y, z);
|
||||
bool isUpper = (data & UPPER_BIT) != 0;
|
||||
int lowerData;
|
||||
int upperData;
|
||||
if (isUpper) {
|
||||
lowerData = level->getData(x, y - 1, z);
|
||||
upperData = data;
|
||||
} else {
|
||||
lowerData = data;
|
||||
upperData = level->getData(x, y + 1, z);
|
||||
}
|
||||
|
||||
// bits: dir, dir, open/closed, isUpper, isRightHinge
|
||||
bool isRightHinge = (upperData & 1) != 0;
|
||||
return lowerData & C_LOWER_DATA_MASK | (isUpper ? 8 : 0) | (isRightHinge ? 16 : 0);
|
||||
}
|
||||
61
src/world/level/tile/DoorTile.h
Executable file
61
src/world/level/tile/DoorTile.h
Executable file
@@ -0,0 +1,61 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__DoorTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__DoorTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class Item;
|
||||
class Level;
|
||||
class LevelSource;
|
||||
class Player;
|
||||
|
||||
|
||||
class DoorTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
static const int UPPER_BIT = 8;
|
||||
static const int C_DIR_MASK = 3;
|
||||
static const int C_OPEN_MASK = 4;
|
||||
static const int C_LOWER_DATA_MASK = 7;
|
||||
static const int C_IS_UPPER_MASK = 8;
|
||||
static const int C_RIGHT_HINGE_MASK = 16;
|
||||
|
||||
DoorTile(int id, const Material* material);
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
|
||||
bool blocksLight();
|
||||
bool isSolidRender();
|
||||
bool isCubeShaped();
|
||||
int getRenderShape();
|
||||
int getRenderLayer();
|
||||
|
||||
AABB getTileAABB(Level* level, int x, int y, int z);
|
||||
AABB* getAABB(Level* level, int x, int y, int z);
|
||||
|
||||
void updateShape(LevelSource* level, int x, int y, int z);
|
||||
void setShape(int compositeData);
|
||||
|
||||
void attack(Level* level, int x, int y, int z, Player* player);
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
|
||||
void setOpen(Level* level, int x, int y, int z, bool shouldOpen);
|
||||
static bool isOpen(LevelSource* level, int x, int y, int z);
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type);
|
||||
|
||||
int getResource(int data, Random* random);
|
||||
|
||||
HitResult clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b);
|
||||
|
||||
int getDir(LevelSource* level, int x, int y, int z);
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face);
|
||||
|
||||
static int getCompositeData(LevelSource* level, int x, int y, int z);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__DoorTile_H__*/
|
||||
38
src/world/level/tile/EntityTile.cpp
Executable file
38
src/world/level/tile/EntityTile.cpp
Executable file
@@ -0,0 +1,38 @@
|
||||
#include "EntityTile.h"
|
||||
#include "entity/TileEntity.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
void EntityTile::onPlace( Level* level, int x, int y, int z )
|
||||
{
|
||||
super::onPlace(level, x, y, z);
|
||||
level->setTileEntity(x, y, z, newTileEntity());
|
||||
}
|
||||
|
||||
void EntityTile::onRemove( Level* level, int x, int y, int z )
|
||||
{
|
||||
super::onRemove(level, x, y, z);
|
||||
level->removeTileEntity(x, y, z);
|
||||
}
|
||||
|
||||
void EntityTile::triggerEvent( Level* level, int x, int y, int z, int b0, int b1 )
|
||||
{
|
||||
super::triggerEvent(level, x, y, z, b0, b1);
|
||||
TileEntity* te = level->getTileEntity(x, y, z);
|
||||
if (te != NULL) {
|
||||
te->triggerEvent(b0, b1);
|
||||
}
|
||||
}
|
||||
|
||||
EntityTile::EntityTile( int id, const Material* material )
|
||||
: super(id, material)
|
||||
{
|
||||
isEntityTile[this->id] = true;
|
||||
}
|
||||
|
||||
EntityTile::EntityTile( int id, int tex, const Material* material )
|
||||
: super(id, tex, material)
|
||||
{
|
||||
isEntityTile[this->id] = true;
|
||||
}
|
||||
|
||||
28
src/world/level/tile/EntityTile.h
Executable file
28
src/world/level/tile/EntityTile.h
Executable file
@@ -0,0 +1,28 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__EntityTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__EntityTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class Level;
|
||||
class TileEntity;
|
||||
class Material;
|
||||
|
||||
/*abstract*/
|
||||
class EntityTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
virtual TileEntity* newTileEntity() = 0;
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z);
|
||||
void onRemove(Level* level, int x, int y, int z);
|
||||
|
||||
void triggerEvent(Level* level, int x, int y, int z, int b0, int b1);
|
||||
protected:
|
||||
EntityTile(int id, const Material* material);
|
||||
EntityTile(int id, int tex, const Material* material);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__EntityTile_H__*/
|
||||
110
src/world/level/tile/FarmTile.h
Executable file
110
src/world/level/tile/FarmTile.h
Executable file
@@ -0,0 +1,110 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__FarmTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__FarmTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class FarmTile: public Tile {
|
||||
public:
|
||||
FarmTile(int id)
|
||||
: Tile(id, Material::dirt)
|
||||
{
|
||||
tex = 7 + 5 * 16;
|
||||
setTicking(true);
|
||||
setShape(0, 0, 0, 1, 15 / 16.0f, 1);
|
||||
setLightBlock(255);
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
tmpBB.x0 = (float)x;
|
||||
tmpBB.y0 = (float)y;
|
||||
tmpBB.z0 = (float)z;
|
||||
tmpBB.x1 = (float)(x + 1);
|
||||
tmpBB.y1 = (float)(y + 1);
|
||||
tmpBB.z1 = (float)(z + 1);
|
||||
return &tmpBB;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (face == 1 && data > 0) return tex - 1;
|
||||
if (face == 1) return tex;
|
||||
return 2;
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (isNearWater(level, x, y, z)) {
|
||||
level->setData(x, y, z, 7);
|
||||
} else {
|
||||
int moisture = level->getData(x, y, z);
|
||||
if (moisture > 0) {
|
||||
level->setData(x, y, z, moisture - 1);
|
||||
} else {
|
||||
if (!isUnderCrops(level, x, y, z)) {
|
||||
level->setTile(x, y, z, Tile::dirt->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fallOn(Level* level, int x, int y, int z, Entity* entity, float fallDistance) {
|
||||
if (!level->isClientSide && level->random.nextFloat() < (fallDistance - .5f)) {
|
||||
level->setTile(x, y, z, Tile::dirt->id);
|
||||
}
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
Tile::neighborChanged(level, x, y, z, type);
|
||||
const Material* above = level->getMaterial(x, y + 1, z);
|
||||
if (above->isSolid()) {
|
||||
level->setTile(x, y, z, Tile::dirt->id);
|
||||
}
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Tile::dirt->getResource(0, random);
|
||||
}
|
||||
|
||||
private:
|
||||
bool isUnderCrops(Level* level, int x, int y, int z) {
|
||||
int r = 0;
|
||||
for (int xx = x - r; xx <= x + r; xx++)
|
||||
for (int zz = z - r; zz <= z + r; zz++) {
|
||||
if (level->getTile(xx, y + 1, zz) == Tile::crops->id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNearWater(Level* level, int x, int y, int z) {
|
||||
for (int xx = x - 4; xx <= x + 4; xx++) {
|
||||
for (int yy = y; yy <= y + 1; yy++) {
|
||||
for (int zz = z - 4; zz <= z + 4; zz++) {
|
||||
if (level->getMaterial(xx, yy, zz) == Material::water) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__FarmTile_H__*/
|
||||
98
src/world/level/tile/FenceGateTile.h
Executable file
98
src/world/level/tile/FenceGateTile.h
Executable file
@@ -0,0 +1,98 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__FenceGateTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__FenceGateTile_H__
|
||||
|
||||
#include "Tile.h"
|
||||
#include "LevelEvent.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../Direction.h"
|
||||
#include "../../entity/Mob.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../../phys/AABB.h"
|
||||
#include "../../../util/Mth.h"
|
||||
|
||||
class FenceGateTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
|
||||
static const int DIRECTION_MASK = 3;
|
||||
static const int OPEN_BIT = 4;
|
||||
public:
|
||||
FenceGateTile(int id, int tex)
|
||||
: super(id, tex, Material::wood)
|
||||
{
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
if (!level->getMaterial(x, y - 1, z)->isSolid()) return false;
|
||||
return super::mayPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
int data = level->getData(x, y, z);
|
||||
if (isOpen(data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const float xx = (float)x;
|
||||
const float yy = (float)y;
|
||||
const float zz = (float)z;
|
||||
if (data == Direction::NORTH || data == Direction::SOUTH) {
|
||||
tmpBB.set(xx, yy, zz + 6.0f / 16.0f, xx + 1, yy + 1.5f, zz + 10.0f / 16.0f);
|
||||
} else {
|
||||
tmpBB.set(xx + 6.0f / 16.0f, yy, zz, xx + 10.0f / 16.0f, yy + 1.5f, zz + 1);
|
||||
}
|
||||
return &tmpBB;
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_FENCE_GATE;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void setPlacedBy(Level* level, int x, int y, int z, Mob* by) {
|
||||
int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3)) % 4;
|
||||
level->setData(x, y, z, dir);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
int data = level->getData(x, y, z);
|
||||
if (isOpen(data)) {
|
||||
level->setData(x, y, z, data & ~OPEN_BIT);
|
||||
} else {
|
||||
// open the door from the player
|
||||
int dir = (((Mth::floor(player->yRot * 4 / (360) + 0.5f)) & 3)) % 4;
|
||||
int current = getDirection(data);
|
||||
if (current == ((dir + 2) % 4)) {
|
||||
data = dir;
|
||||
}
|
||||
level->setData(x, y, z, data | OPEN_BIT);
|
||||
}
|
||||
level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isOpen(int data) {
|
||||
return (data & OPEN_BIT) != 0;
|
||||
}
|
||||
|
||||
static int getDirection(int data) {
|
||||
return (data & DIRECTION_MASK);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__FenceGateTile_H__*/
|
||||
117
src/world/level/tile/FenceTile.h
Executable file
117
src/world/level/tile/FenceTile.h
Executable file
@@ -0,0 +1,117 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__FenceTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__FenceTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Tile.h"
|
||||
/* import net.minecraft.world.level->* */
|
||||
#include "../material/Material.h"
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class FenceTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
FenceTile(int id, int tex)
|
||||
: super(id, tex, Material::wood)
|
||||
{
|
||||
}
|
||||
|
||||
FenceTile(int id, int tex, const Material* material)
|
||||
: super(id, tex, material)
|
||||
{
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
return super::mayPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
bool n = connectsTo(level, x, y, z - 1);
|
||||
bool s = connectsTo(level, x, y, z + 1);
|
||||
bool w = connectsTo(level, x - 1, y, z);
|
||||
bool e = connectsTo(level, x + 1, y, z);
|
||||
|
||||
float west = 6.0f / 16.0f;
|
||||
float east = 10.0f / 16.0f;
|
||||
float north = 6.0f / 16.0f;
|
||||
float south = 10.0f / 16.0f;
|
||||
|
||||
if (n) {
|
||||
north = 0;
|
||||
}
|
||||
if (s) {
|
||||
south = 1;
|
||||
}
|
||||
if (w) {
|
||||
west = 0;
|
||||
}
|
||||
if (e) {
|
||||
east = 1;
|
||||
}
|
||||
|
||||
tmpBB.set((float)x + west, (float)y, (float)z + north, (float)x + east, (float)y + 1.5f, (float)z + south);
|
||||
return &tmpBB;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void updateShape(LevelSource* level, int x, int y, int z) {
|
||||
bool n = connectsTo(level, x, y, z - 1);
|
||||
bool s = connectsTo(level, x, y, z + 1);
|
||||
bool w = connectsTo(level, x - 1, y, z);
|
||||
bool e = connectsTo(level, x + 1, y, z);
|
||||
|
||||
float west = 6.0f / 16.0f;
|
||||
float east = 10.0f / 16.0f;
|
||||
float north = 6.0f / 16.0f;
|
||||
float south = 10.0f / 16.0f;
|
||||
|
||||
if (n) {
|
||||
north = 0;
|
||||
}
|
||||
if (s) {
|
||||
south = 1;
|
||||
}
|
||||
if (w) {
|
||||
west = 0;
|
||||
}
|
||||
if (e) {
|
||||
east = 1;
|
||||
}
|
||||
|
||||
setShape(west, 0, north, east, 1.0f, south);
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_FENCE;
|
||||
}
|
||||
|
||||
bool connectsTo(LevelSource* level, int x, int y, int z) {
|
||||
int tile = level->getTile(x, y, z);
|
||||
if (tile == id || tile == Tile::fenceGate->id) {
|
||||
return true;
|
||||
}
|
||||
Tile* tileInstance = Tile::tiles[tile];
|
||||
if (tileInstance != NULL) {
|
||||
if (tileInstance->material->isSolidBlocking() && tileInstance->isCubeShaped()) {
|
||||
return tileInstance->material != Material::vegetable;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL->TILE__FenceTile_H__*/
|
||||
309
src/world/level/tile/FireTile.h
Executable file
309
src/world/level/tile/FireTile.h
Executable file
@@ -0,0 +1,309 @@
|
||||
#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__*/
|
||||
175
src/world/level/tile/FurnaceTile.cpp
Executable file
175
src/world/level/tile/FurnaceTile.cpp
Executable file
@@ -0,0 +1,175 @@
|
||||
#include "FurnaceTile.h"
|
||||
#include "entity/FurnaceTileEntity.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../../entity/Mob.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../../item/ItemInstance.h"
|
||||
#include "../../../util/Mth.h"
|
||||
#include "../LevelSource.h"
|
||||
#include "../Level.h"
|
||||
|
||||
bool FurnaceTile::noDrop = false;
|
||||
|
||||
FurnaceTile::FurnaceTile( int id, bool lit )
|
||||
: super(id, Material::stone),
|
||||
lit(lit)
|
||||
{
|
||||
tex = 13 + 16 * 2;
|
||||
}
|
||||
|
||||
int FurnaceTile::getResource( int data, Random* random/*, int playerBonusLevel*/ )
|
||||
{
|
||||
return Tile::furnace->id;
|
||||
}
|
||||
|
||||
void FurnaceTile::onPlace( Level* level, int x, int y, int z )
|
||||
{
|
||||
super::onPlace(level, x, y, z);
|
||||
recalcLockDir(level, x, y, z);
|
||||
}
|
||||
|
||||
int FurnaceTile::getTexture( LevelSource* level, int x, int y, int z, int face )
|
||||
{
|
||||
if (face == 1) return tex + 17;
|
||||
if (face == 0) return tex + 17;
|
||||
|
||||
int lockDir = level->getData(x, y, z);
|
||||
|
||||
if (face != lockDir) return tex;
|
||||
if (lit) return tex + 16;
|
||||
else return tex - 1;
|
||||
}
|
||||
|
||||
int FurnaceTile::getTexture( int face )
|
||||
{
|
||||
if (face == 1) return tex + 17;
|
||||
if (face == 0) return tex + 17;
|
||||
if (face == 3) return tex - 1;
|
||||
return tex;
|
||||
}
|
||||
|
||||
void FurnaceTile::animateTick( Level* level, int xt, int yt, int zt, Random* random )
|
||||
{
|
||||
if (!lit) return;
|
||||
|
||||
int dir = level->getData(xt, yt, zt);
|
||||
|
||||
float x = xt + 0.5f;
|
||||
float y = yt + 0.0f + random->nextFloat() * 6 / 16.0f;
|
||||
float z = zt + 0.5f;
|
||||
float r = 0.52f;
|
||||
float ss = random->nextFloat() * 0.6f - 0.3f;
|
||||
|
||||
if (dir == 4) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x - r, y, z + ss, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x - r, y, z + ss, 0, 0, 0);
|
||||
} else if (dir == 5) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x + r, y, z + ss, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x + r, y, z + ss, 0, 0, 0);
|
||||
} else if (dir == 2) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x + ss, y, z - r, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x + ss, y, z - r, 0, 0, 0);
|
||||
} else if (dir == 3) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x + ss, y, z + r, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x + ss, y, z + r, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceTile::use( Level* level, int x, int y, int z, Player* player )
|
||||
{
|
||||
if (level->isClientSide)
|
||||
return true;
|
||||
|
||||
FurnaceTileEntity* furnace = static_cast<FurnaceTileEntity*>(level->getTileEntity(x, y, z));
|
||||
if (furnace != NULL) player->openFurnace(furnace);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void FurnaceTile::setLit( bool lit, Level* level, int x, int y, int z )
|
||||
{
|
||||
int data = level->getData(x, y, z);
|
||||
TileEntity* te = level->getTileEntity(x, y, z);
|
||||
|
||||
noDrop = true;
|
||||
if (lit) level->setTile(x, y, z, Tile::furnace_lit->id);
|
||||
else level->setTile(x, y, z, Tile::furnace->id);
|
||||
noDrop = false;
|
||||
|
||||
level->setData(x, y, z, data);
|
||||
|
||||
LOGI("lit? %d @ %d, %d, %d\n", lit, x, y, z);
|
||||
|
||||
if (te != NULL) {
|
||||
te->clearRemoved();
|
||||
level->setTileEntity(x, y, z, te);
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity* FurnaceTile::newTileEntity()
|
||||
{
|
||||
return TileEntityFactory::createTileEntity(TileEntityType::Furnace);
|
||||
}
|
||||
|
||||
void FurnaceTile::setPlacedBy( Level* level, int x, int y, int z, Mob* by )
|
||||
{
|
||||
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3;
|
||||
|
||||
if (dir == 0) level->setData(x, y, z, Facing::NORTH);
|
||||
if (dir == 1) level->setData(x, y, z, Facing::EAST);
|
||||
if (dir == 2) level->setData(x, y, z, Facing::SOUTH);
|
||||
if (dir == 3) level->setData(x, y, z, Facing::WEST);
|
||||
}
|
||||
|
||||
void FurnaceTile::onRemove( Level* level, int x, int y, int z )
|
||||
{
|
||||
if (!noDrop && !level->isClientSide) {
|
||||
FurnaceTileEntity* container = (FurnaceTileEntity*) level->getTileEntity(x, y, z);
|
||||
if (container != NULL) {
|
||||
for (int i = 0; i < container->getContainerSize(); i++) {
|
||||
ItemInstance* item = container->getItem(i);
|
||||
if (item) {
|
||||
float xo = random.nextFloat() * 0.8f + 0.1f;
|
||||
float yo = random.nextFloat() * 0.8f + 0.1f;
|
||||
float zo = random.nextFloat() * 0.8f + 0.1f;
|
||||
|
||||
while (item->count > 0) {
|
||||
int count = random.nextInt(21) + 10;
|
||||
if (count > item->count) count = item->count;
|
||||
item->count -= count;
|
||||
|
||||
ItemEntity* itemEntity = new ItemEntity(level, x + xo, y + yo, z + zo, ItemInstance(item->id, count, item->getAuxValue()));
|
||||
float pow = 0.05f;
|
||||
itemEntity->xd = random.nextGaussian() * pow;
|
||||
itemEntity->yd = random.nextGaussian() * pow + 0.2f;
|
||||
itemEntity->zd = random.nextGaussian() * pow;
|
||||
level->addEntity(itemEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super::onRemove(level, x, y, z);
|
||||
}
|
||||
|
||||
void FurnaceTile::recalcLockDir( Level* level, int x, int y, int z )
|
||||
{
|
||||
if (level->isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
int n = level->getTile(x, y, z - 1); // face = 2
|
||||
int s = level->getTile(x, y, z + 1); // face = 3
|
||||
int w = level->getTile(x - 1, y, z); // face = 4
|
||||
int e = level->getTile(x + 1, y, z); // face = 5
|
||||
|
||||
int lockDir = 3;
|
||||
if (Tile::solid[e] && !Tile::solid[w]) lockDir = 4;
|
||||
else if (Tile::solid[w] && !Tile::solid[e]) lockDir = 5;
|
||||
else if (Tile::solid[s] && !Tile::solid[n]) lockDir = 2;
|
||||
else if (Tile::solid[n] && !Tile::solid[s]) lockDir = 3;
|
||||
|
||||
level->setData(x, y, z, lockDir);
|
||||
}
|
||||
44
src/world/level/tile/FurnaceTile.h
Executable file
44
src/world/level/tile/FurnaceTile.h
Executable file
@@ -0,0 +1,44 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__FurnaceTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__FurnaceTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "EntityTile.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class Level;
|
||||
class Mob;
|
||||
class Player;
|
||||
class LevelSource;
|
||||
|
||||
class FurnaceTile: public EntityTile
|
||||
{
|
||||
typedef EntityTile super;
|
||||
public:
|
||||
FurnaceTile(int id, bool lit);
|
||||
|
||||
int getTexture(int face);
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
|
||||
void animateTick(Level* level, int xt, int yt, int zt, Random* random);
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
int getResource(int data, Random* random/*, int playerBonusLevel*/);
|
||||
|
||||
static void setLit(bool lit, Level* level, int x, int y, int z);
|
||||
|
||||
TileEntity* newTileEntity();
|
||||
|
||||
void setPlacedBy(Level* level, int x, int y, int z, Mob* by);
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z);
|
||||
void onRemove(Level* level, int x, int y, int z);
|
||||
private:
|
||||
void recalcLockDir(Level* level, int x, int y, int z);
|
||||
|
||||
Random random;
|
||||
const bool lit;
|
||||
static bool noDrop;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__FurnaceTile_H__*/
|
||||
27
src/world/level/tile/GlassTile.h
Executable file
27
src/world/level/tile/GlassTile.h
Executable file
@@ -0,0 +1,27 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__GlassTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__GlassTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "HalfTransparentTile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class GlassTile: public HalfTransparentTile
|
||||
{
|
||||
typedef HalfTransparentTile super;
|
||||
public:
|
||||
GlassTile(int id, int tex, const Material* material, bool allowSame)
|
||||
: super(id, tex, material, allowSame)
|
||||
{}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__GlassTile_H__*/
|
||||
54
src/world/level/tile/GrassTile.cpp
Executable file
54
src/world/level/tile/GrassTile.cpp
Executable file
@@ -0,0 +1,54 @@
|
||||
#include "GrassTile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
|
||||
GrassTile::GrassTile(int id)
|
||||
: super(id, Material::dirt)
|
||||
{
|
||||
tex = 3;
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
int GrassTile::getTexture( LevelSource* level, int x, int y, int z, int face ) {
|
||||
if (face == 1) return 0;
|
||||
if (face == 0) return 2;
|
||||
const Material* above = level->getMaterial(x, y + 1, z);
|
||||
if (above == Material::topSnow || above == Material::snow) return 4 * 16 + 4;
|
||||
else return 3;
|
||||
}
|
||||
|
||||
int GrassTile::getTexture( int face, int data ) {
|
||||
if (face == 1) return 0;
|
||||
if (face == 0) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
int GrassTile::getColor( LevelSource* level, int x, int y, int z ) {
|
||||
//level.getBiomeSource().getBiomeBlock(x, z, 1, 1);
|
||||
//float temp = level.getBiomeSource().temperatures[0];
|
||||
//float rain = level.getBiomeSource().downfalls[0];
|
||||
|
||||
return 0x339933;//GrassColor.get(temp, rain);
|
||||
}
|
||||
|
||||
void GrassTile::tick( Level* level, int x, int y, int z, Random* random ) {
|
||||
if (level->isClientSide) return;
|
||||
|
||||
if (level->getRawBrightness(x, y + 1, z) < MIN_BRIGHTNESS && level->getMaterial(x, y + 1, z)->blocksLight()) {
|
||||
if (random->nextInt(4) != 0) return;
|
||||
level->setTile(x, y, z, Tile::dirt->id);
|
||||
} else {
|
||||
if (level->getRawBrightness(x, y + 1, z) >= level->MAX_BRIGHTNESS - 6) {
|
||||
int xt = x + random->nextInt(3) - 1;
|
||||
int yt = y + random->nextInt(5) - 3;
|
||||
int zt = z + random->nextInt(3) - 1;
|
||||
if (level->getTile(xt, yt, zt) == Tile::dirt->id && level->getRawBrightness(xt, yt + 1, zt) >= MIN_BRIGHTNESS && !level->getMaterial(xt, yt + 1, zt)->blocksLight()) {
|
||||
level->setTile(xt, yt, zt, Tile::grass->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GrassTile::getResource( int data, Random* random ) {
|
||||
return Tile::dirt->getResource(0, random);
|
||||
}
|
||||
29
src/world/level/tile/GrassTile.h
Executable file
29
src/world/level/tile/GrassTile.h
Executable file
@@ -0,0 +1,29 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__GrassTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__GrassTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
#include "../LevelSource.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class GrassTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
static const int MIN_BRIGHTNESS = 4;
|
||||
|
||||
GrassTile(int id);
|
||||
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
int getTexture(int face, int data);
|
||||
int getColor(LevelSource* level, int x, int y, int z);
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random);
|
||||
int getResource(int data, Random* random);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__GrassTile_H__*/
|
||||
26
src/world/level/tile/GravelTile.h
Executable file
26
src/world/level/tile/GravelTile.h
Executable file
@@ -0,0 +1,26 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__GravelTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__GravelTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "HeavyTile.h"
|
||||
|
||||
class GravelTile: public HeavyTile
|
||||
{
|
||||
typedef HeavyTile super;
|
||||
public:
|
||||
GravelTile(int type, int tex)
|
||||
: super(type, tex)
|
||||
{
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
if (random->nextInt(10) == 0) return Item::flint->id;
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__GravelTile_H__*/
|
||||
39
src/world/level/tile/HalfTransparentTile.h
Executable file
39
src/world/level/tile/HalfTransparentTile.h
Executable file
@@ -0,0 +1,39 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__HalfTransparentTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__HalfTransparentTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../LevelSource.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class HalfTransparentTile: public Tile {
|
||||
bool allowSame;
|
||||
|
||||
public:
|
||||
/*protected*/
|
||||
HalfTransparentTile(int id, int tex, const Material* material, bool allowSame)
|
||||
: Tile(id, tex, material)
|
||||
{
|
||||
this->allowSame = allowSame;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_BLEND;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
int id = level->getTile(x, y, z);
|
||||
if (!allowSame && id == this->id) return false;
|
||||
return Tile::shouldRenderFace(level, x, y, z, face);
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__HalfTransparentTile_H__*/
|
||||
72
src/world/level/tile/HeavyTile.cpp
Executable file
72
src/world/level/tile/HeavyTile.cpp
Executable file
@@ -0,0 +1,72 @@
|
||||
#include "HeavyTile.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/item/FallingTile.h"
|
||||
|
||||
bool HeavyTile::instaFall = false;
|
||||
|
||||
HeavyTile::HeavyTile( int id, int tex )
|
||||
: super(id, tex, Material::sand)
|
||||
{
|
||||
}
|
||||
|
||||
HeavyTile::HeavyTile( int id, int tex, const Material* material )
|
||||
: super(id, tex, material)
|
||||
{
|
||||
}
|
||||
|
||||
void HeavyTile::onPlace( Level* level, int x, int y, int z ) {
|
||||
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
|
||||
}
|
||||
|
||||
void HeavyTile::neighborChanged( Level* level, int x, int y, int z, int type ) {
|
||||
level->addToTickNextTick(x, y, z, id, getTickDelay(level));
|
||||
}
|
||||
|
||||
void HeavyTile::tick( Level* level, int x, int y, int z, Random* random ) {
|
||||
if (!level->isClientSide) {
|
||||
checkSlide(level, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
int HeavyTile::getTickDelay( Level* level ) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool HeavyTile::isFree( Level* level, int x, int y, int z ) {
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t == 0) return true;
|
||||
if (t == ((Tile*)Tile::fire)->id) return true;
|
||||
const Material* material = Tile::tiles[t]->material;
|
||||
if (material == Material::water) return true;
|
||||
if (material == Material::lava) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HeavyTile::checkSlide( Level* level, int x, int y, int z ) {
|
||||
int x2 = x;
|
||||
int y2 = y;
|
||||
int z2 = z;
|
||||
if (isFree(level, x2, y2 - 1, z2) && y2 >= 0) {
|
||||
int r = 32;
|
||||
if (instaFall || !level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) {
|
||||
level->setTile(x, y, z, 0);
|
||||
while (isFree(level, x, y - 1, z) && y > 0)
|
||||
y--;
|
||||
if (y > 0) {
|
||||
level->setTile(x, y, z, id);
|
||||
//level->setTileAndUpdate(x, y, z, id);
|
||||
}
|
||||
} else if (!level->isClientSide) {
|
||||
FallingTile* e = new FallingTile(level, x + 0.5f, y + 0.5f, z + 0.5f, id, level->getData(x, y, z));
|
||||
falling(e);
|
||||
level->addEntity(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HeavyTile::falling( FallingTile* entity ) {
|
||||
}
|
||||
|
||||
void HeavyTile::onLand( Level* level, int xt, int yt, int zt, int data ) {
|
||||
}
|
||||
32
src/world/level/tile/HeavyTile.h
Executable file
32
src/world/level/tile/HeavyTile.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__HeavyTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__HeavyTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class FallingTile;
|
||||
|
||||
class HeavyTile: public Tile {
|
||||
typedef Tile super;
|
||||
public:
|
||||
static bool instaFall;
|
||||
|
||||
HeavyTile(int id, int tex);
|
||||
HeavyTile(int id, int tex, const Material* material);
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z);
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type);
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random);
|
||||
int getTickDelay(Level* level);
|
||||
|
||||
static bool isFree(Level* level, int x, int y, int z);
|
||||
|
||||
virtual void falling(FallingTile* entity);
|
||||
virtual void onLand(Level* level, int xt, int yt, int zt, int data);
|
||||
private:
|
||||
void checkSlide(Level* level, int x, int y, int z);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__HeavyTile_H__*/
|
||||
41
src/world/level/tile/IceTile.h
Executable file
41
src/world/level/tile/IceTile.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__IceTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__IceTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../LightLayer.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class IceTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
IceTile(int id, int tex)
|
||||
: super(id, tex, Material::ice)
|
||||
{
|
||||
friction = 0.98f;
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
void playerDestroy(Level* level, Player* player, int x, int y, int z, int data) {
|
||||
const Material* below = level->getMaterial(x, y - 1, z);
|
||||
if (below->blocksMotion() || below->isLiquid()) {
|
||||
level->setTile(x, y, z, Tile::water->id);
|
||||
}
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->getBrightness(LightLayer::Block, x, y, z) > 11 - Tile::lightBlock[id]) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, Tile::calmWater->id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__IceTile_H__*/
|
||||
21
src/world/level/tile/InvisibleTile.h
Executable file
21
src/world/level/tile/InvisibleTile.h
Executable file
@@ -0,0 +1,21 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__InvisibleTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__InvisibleTile_H__
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class InvisibleTile : public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
InvisibleTile(int id, int tex, const Material* material)
|
||||
: super(id, tex, material)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int getRenderShape()
|
||||
{
|
||||
return SHAPE_INVISIBLE;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__InvisibleTile_H__*/
|
||||
112
src/world/level/tile/LadderTile.h
Executable file
112
src/world/level/tile/LadderTile.h
Executable file
@@ -0,0 +1,112 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LadderTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LadderTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class LadderTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
|
||||
public:
|
||||
LadderTile(int id, int tex)
|
||||
: super(id, tex, Material::decoration)
|
||||
{
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
int dir = level->getData(x, y, z);
|
||||
float r = 2 / 16.0f;
|
||||
|
||||
if (dir == 2) this->setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
if (dir == 3) this->setShape(0, 0, 0, 1, 1, r);
|
||||
if (dir == 4) this->setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
if (dir == 5) this->setShape(0, 0, 0, r, 1, 1);
|
||||
|
||||
return super::getAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
AABB getTileAABB(Level* level, int x, int y, int z) {
|
||||
int dir = level->getData(x, y, z);
|
||||
float r = 2 / 16.0f;
|
||||
|
||||
if (dir == 2) this->setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
if (dir == 3) this->setShape(0, 0, 0, 1, 1, r);
|
||||
if (dir == 4) this->setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
if (dir == 5) this->setShape(0, 0, 0, r, 1, 1);
|
||||
|
||||
return super::getTileAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_LADDER;
|
||||
}
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
||||
if (level->isSolidBlockingTile(x - 1, y, z)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x + 1, y, z)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x, y, z - 1)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x, y, z + 1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue)
|
||||
{
|
||||
int dir = itemValue;
|
||||
|
||||
if ((dir == 0 || face == 2) && level->isSolidBlockingTile(x, y, z + 1)) dir = 2;
|
||||
if ((dir == 0 || face == 3) && level->isSolidBlockingTile(x, y, z - 1)) dir = 3;
|
||||
if ((dir == 0 || face == 4) && level->isSolidBlockingTile(x + 1, y, z)) dir = 4;
|
||||
if ((dir == 0 || face == 5) && level->isSolidBlockingTile(x - 1, y, z)) dir = 5;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
int face = level->getData(x, y, z);
|
||||
bool ok = false;
|
||||
|
||||
if (face == 2 && level->isSolidBlockingTile(x, y, z + 1)) ok = true;
|
||||
if (face == 3 && level->isSolidBlockingTile(x, y, z - 1)) ok = true;
|
||||
if (face == 4 && level->isSolidBlockingTile(x + 1, y, z)) ok = true;
|
||||
if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) ok = true;
|
||||
if (!ok) {
|
||||
//spawnResources(level, x, y, z, face); //@crafting
|
||||
popResource(level, x, y, z, ItemInstance(Tile::ladder));
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
|
||||
super::neighborChanged(level, x, y, z, type);
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LadderTile_H__*/
|
||||
208
src/world/level/tile/LeafTile.h
Executable file
208
src/world/level/tile/LeafTile.h
Executable file
@@ -0,0 +1,208 @@
|
||||
#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"
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
return FoliageColor::getDefaultColor();
|
||||
}
|
||||
|
||||
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__*/
|
||||
27
src/world/level/tile/LevelEvent.h
Executable file
27
src/world/level/tile/LevelEvent.h
Executable file
@@ -0,0 +1,27 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LevelEvent_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LevelEvent_H__
|
||||
|
||||
class LevelEvent
|
||||
{
|
||||
public:
|
||||
static const int SOUND_CLICK = 1000;
|
||||
static const int SOUND_CLICK_FAIL = 1001;
|
||||
static const int SOUND_LAUNCH = 1002;
|
||||
static const int SOUND_OPEN_DOOR = 1003;
|
||||
static const int SOUND_FIZZ = 1004;
|
||||
static const int SOUND_PLAY_RECORDING = 1005;
|
||||
|
||||
static const int SOUND_GHAST_WARNING = 1007;
|
||||
static const int SOUND_GHAST_FIREBALL = 1008;
|
||||
static const int SOUND_BLAZE_FIREBALL = 1009;
|
||||
|
||||
static const int PARTICLES_SHOOT = 2000;
|
||||
static const int PARTICLES_DESTROY_BLOCK = 2001;
|
||||
static const int PARTICLES_POTION_SPLASH = 2002;
|
||||
static const int PARTICLES_EYE_OF_ENDER_DEATH = 2003;
|
||||
static const int PARTICLES_MOBTILE_SPAWN = 2004;
|
||||
|
||||
static const int ALL_PLAYERS_SLEEPING = 9800;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LevelEvent_H__*/
|
||||
15
src/world/level/tile/LightGemTile.cpp
Executable file
15
src/world/level/tile/LightGemTile.cpp
Executable file
@@ -0,0 +1,15 @@
|
||||
#include "LightGemTile.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../item/Item.h"
|
||||
LightGemTile::LightGemTile( int id, int tex, const Material* material )
|
||||
: super(id, tex, material)
|
||||
{ }
|
||||
|
||||
int LightGemTile::getResourceCount( Random* random ) {
|
||||
return 2 + random->nextInt(3);
|
||||
}
|
||||
|
||||
int LightGemTile::getResource( int data, Random* random ) {
|
||||
return Item::yellowDust->id;
|
||||
}
|
||||
|
||||
12
src/world/level/tile/LightGemTile.h
Executable file
12
src/world/level/tile/LightGemTile.h
Executable file
@@ -0,0 +1,12 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LightGemTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LightGemTile_H__
|
||||
#include "Tile.h"
|
||||
class LightGemTile : public Tile {
|
||||
typedef Tile super;
|
||||
public:
|
||||
LightGemTile(int id, int tex, const Material* material);
|
||||
int getResourceCount(Random* random);
|
||||
int getResource(int data, Random* random);
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__LightGemTile_H__ */
|
||||
232
src/world/level/tile/LiquidTile.h
Executable file
232
src/world/level/tile/LiquidTile.h
Executable file
@@ -0,0 +1,232 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "../Level.h"
|
||||
#include "Tile.h"
|
||||
|
||||
/*abstract*/
|
||||
class LiquidTile: public Tile
|
||||
{
|
||||
public:
|
||||
static float getHeight(int d) {
|
||||
// if (d == 0) d++; // NM
|
||||
if (d >= 8) d = 0;
|
||||
float h = (d + 1) / 9.0f;
|
||||
return h;
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face == 0 || face == 1) {
|
||||
return tex;
|
||||
} else {
|
||||
return tex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mayPick(int data, bool liquid) {
|
||||
return liquid && data == 0;
|
||||
}
|
||||
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
const Material* m = level->getMaterial(x, y, z);
|
||||
if (m == this->material) return false;
|
||||
if (m == Material::ice) return false;
|
||||
if (face == 1) return true;
|
||||
return Tile::shouldRenderFace(level, x, y, z, face);
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_WATER;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getColor(LevelSource* level, int x, int y, int z) {
|
||||
return 0x999999ff;
|
||||
}
|
||||
|
||||
void handleEntityInside(Level* level, int x, int y, int z, Entity* e, Vec3& current) {
|
||||
Vec3 flow = getFlow(level, x, y, z);
|
||||
current.x += flow.x * .5f;
|
||||
current.y += flow.y * .5f;
|
||||
current.z += flow.z * .5f;
|
||||
}
|
||||
|
||||
int getTickDelay() {
|
||||
if (material == Material::water) return 5;
|
||||
if (material == Material::lava) return 30;
|
||||
return 0;
|
||||
}
|
||||
|
||||
float getBrightness(LevelSource* level, int x, int y, int z) {
|
||||
float a = level->getBrightness(x, y, z);
|
||||
float b = level->getBrightness(x, y + 1, z);
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
virtual void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
Tile::tick(level, x, y, z, random);
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return (material == Material::water)? Tile::RENDERLAYER_BLEND : Tile::RENDERLAYER_OPAQUE;
|
||||
}
|
||||
|
||||
void animateTick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (material == Material::water && random->nextInt(64) == 0) {
|
||||
int d = level->getData(x, y, z);
|
||||
if (d > 0 && d < 8) {
|
||||
//level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, "liquid.water", random.nextFloat() * 0.25f + 0.75f, random.nextFloat() * 1.0f + 0.5f);
|
||||
}
|
||||
}
|
||||
if (material == Material::lava) {
|
||||
if (level->getMaterial(x, y + 1, z) == Material::air && !level->isSolidRenderTile(x, y + 1, z)) {
|
||||
if (random->nextInt(100) == 0) {
|
||||
float xx = x + random->nextFloat();
|
||||
float yy = y + yy1;
|
||||
float zz = z + random->nextFloat();
|
||||
level->addParticle(PARTICLETYPE(lava), xx, yy, zz, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float getSlopeAngle(LevelSource* level, int x, int y, int z, const Material* m) {
|
||||
Vec3 flow;
|
||||
if (m == Material::water) flow = ((LiquidTile*) Tile::water)->getFlow(level, x, y, z);
|
||||
if (m == Material::lava) flow = ((LiquidTile*) Tile::lava)->getFlow(level, x, y, z);
|
||||
if (flow.x == 0 && flow.z == 0) return -1000;
|
||||
return atan2(flow.z, flow.x) - Mth::PI * 0.5f;
|
||||
}
|
||||
|
||||
virtual void onPlace(Level* level, int x, int y, int z) {
|
||||
updateLiquid(level, x, y, z);
|
||||
}
|
||||
|
||||
virtual void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
updateLiquid(level, x, y, z);
|
||||
}
|
||||
|
||||
protected:
|
||||
LiquidTile(int id, const Material* material)
|
||||
: Tile(id, (material == Material::lava ? 14 : 12) * 16 + 13, material)
|
||||
{
|
||||
float yo = 0;
|
||||
float e = 0;
|
||||
|
||||
setShape(0 + e, 0 + yo, 0 + e, 1 + e, 1 + yo, 1 + e);
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
void fizz(Level* level, int x, int y, int z) {
|
||||
//level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, "random.fizz", 0.5f, 2.6f + (level->random.nextFloat() - level->random.nextFloat()) * 0.8f);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
level->addParticle(PARTICLETYPE(largesmoke), (float)x + Mth::random(), (float)y + 1.2f, (float)z + Mth::random(), 0, 0, 0);
|
||||
}
|
||||
}
|
||||
int getDepth(Level* level, int x, int y, int z) {
|
||||
if (level->getMaterial(x, y, z) != material) return -1;
|
||||
else return level->getData(x, y, z);
|
||||
}
|
||||
|
||||
int getRenderedDepth(LevelSource* level, int x, int y, int z) {
|
||||
if (level->getMaterial(x, y, z) != material) return -1;
|
||||
int d = level->getData(x, y, z);
|
||||
if (d >= 8) d = 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
private:
|
||||
void updateLiquid(Level* level, int x, int y, int z) {
|
||||
if (level->getTile(x, y, z) != id) return;
|
||||
if (material == Material::lava) {
|
||||
bool water = false;
|
||||
if (water || level->getMaterial(x, y, z - 1) == Material::water) water = true;
|
||||
if (water || level->getMaterial(x, y, z + 1) == Material::water) water = true;
|
||||
if (water || level->getMaterial(x - 1, y, z) == Material::water) water = true;
|
||||
if (water || level->getMaterial(x + 1, y, z) == Material::water) water = true;
|
||||
// if (water || level->getMaterial(x, y - 1, z) == Material::water) water = true; // NM
|
||||
if (water || level->getMaterial(x, y + 1, z) == Material::water) water = true;
|
||||
if (water) {
|
||||
int data = level->getData(x, y, z);
|
||||
if (data == 0) {
|
||||
level->setTile(x, y, z, Tile::obsidian->id);
|
||||
} else if (data <= 4) {
|
||||
level->setTile(x, y, z, Tile::stoneBrick->id);
|
||||
}
|
||||
fizz(level, x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 getFlow(LevelSource* level, int x, int y, int z) {
|
||||
Vec3 flow(0,0,0);
|
||||
int mid = getRenderedDepth(level, x, y, z);
|
||||
for (int d = 0; d < 4; d++) {
|
||||
|
||||
int xt = x;
|
||||
int yt = y;
|
||||
int zt = z;
|
||||
|
||||
if (d == 0) xt--;
|
||||
if (d == 1) zt--;
|
||||
if (d == 2) xt++;
|
||||
if (d == 3) zt++;
|
||||
|
||||
int t = getRenderedDepth(level, xt, yt, zt);
|
||||
if (t < 0) {
|
||||
if (!level->getMaterial(xt, yt, zt)->blocksMotion()) {
|
||||
t = getRenderedDepth(level, xt, yt - 1, zt);
|
||||
if (t >= 0) {
|
||||
int dir = t - (mid - 8);
|
||||
flow = flow.add((float)((xt - x) * dir), (float)((yt - y) * dir), (float)((zt - z) * dir));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (t >= 0) {
|
||||
int dir = t - mid;
|
||||
flow = flow.add((float)((xt - x) * dir), (float)((yt - y) * dir), (float)((zt - z) * dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (level->getData(x, y, z) >= 8) {
|
||||
bool ok = false;
|
||||
if (ok || shouldRenderFace(level, x, y, z - 1, 2)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x, y, z + 1, 3)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x - 1, y, z, 4)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x + 1, y, z, 5)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x, y + 1, z - 1, 2)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x, y + 1, z + 1, 3)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x - 1, y + 1, z, 4)) ok = true;
|
||||
if (ok || shouldRenderFace(level, x + 1, y + 1, z, 5)) ok = true;
|
||||
if (ok) flow = flow.normalized().add(0, -6, 0);
|
||||
}
|
||||
flow = flow.normalized();
|
||||
return flow;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTile_H__*/
|
||||
230
src/world/level/tile/LiquidTileDynamic.h
Executable file
230
src/world/level/tile/LiquidTileDynamic.h
Executable file
@@ -0,0 +1,230 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileDynamic_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileDynamic_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "LiquidTile.h"
|
||||
#include "../Level.h"
|
||||
|
||||
class LiquidTileDynamic: public LiquidTile
|
||||
{
|
||||
typedef LiquidTile super;
|
||||
public:
|
||||
LiquidTileDynamic(int id, const Material* material)
|
||||
: super(id, material),
|
||||
maxCount(0)
|
||||
{}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
//printf("liquid-tick\n");
|
||||
int depth = getDepth(level, x, y, z);
|
||||
|
||||
int dropOff = 1;
|
||||
if (material == Material::lava && !level->dimension->ultraWarm) dropOff = 2;
|
||||
|
||||
bool becomeStatic = true;
|
||||
if (depth > 0) {
|
||||
int highest = -100;
|
||||
maxCount = 0;
|
||||
highest = getHighest(level, x - 1, y, z, highest);
|
||||
highest = getHighest(level, x + 1, y, z, highest);
|
||||
highest = getHighest(level, x, y, z - 1, highest);
|
||||
highest = getHighest(level, x, y, z + 1, highest);
|
||||
|
||||
int newDepth = highest + dropOff;
|
||||
if (newDepth >= 8 || highest < 0) {
|
||||
newDepth = -1;
|
||||
}
|
||||
if (getDepth(level, x, y + 1, z) >= 0) {
|
||||
int above = getDepth(level, x, y + 1, z);
|
||||
if (above >= 8) newDepth = above;
|
||||
else newDepth = above + 8;
|
||||
}
|
||||
if (maxCount >= 2 && material == Material::water) {
|
||||
// Only spread spring if it's on top of an existing spring, or on top of solid ground.
|
||||
if (level->isSolidBlockingTile(x, y - 1, z)) {
|
||||
newDepth = 0;
|
||||
} else if (level->getMaterial(x, y - 1, z) == material && level->getData(x, y, z) == 0) {
|
||||
newDepth = 0;
|
||||
}
|
||||
}
|
||||
if (material == Material::lava) {
|
||||
if (depth < 8 && newDepth < 8) {
|
||||
if (newDepth > depth) {
|
||||
if (random->nextInt(4) != 0) {
|
||||
newDepth = depth;
|
||||
becomeStatic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newDepth != depth) {
|
||||
depth = newDepth;
|
||||
if (depth < 0) {
|
||||
level->setTile(x, y, z, 0);
|
||||
} else {
|
||||
level->setData(x, y, z, depth);
|
||||
level->addToTickNextTick(x, y, z, id, getTickDelay());
|
||||
level->updateNeighborsAt(x, y, z, id);
|
||||
}
|
||||
} else {
|
||||
if (becomeStatic) setStatic(level, x, y, z);
|
||||
}
|
||||
} else {
|
||||
setStatic(level, x, y, z);
|
||||
}
|
||||
if (canSpreadTo(level, x, y - 1, z)) {
|
||||
if (depth >= 8) level->setTileAndData(x, y - 1, z, id, depth);
|
||||
else level->setTileAndData(x, y - 1, z, id, depth + 8);
|
||||
} else if (depth >= 0 && (depth == 0 || isWaterBlocking(level, x, y - 1, z))) {
|
||||
bool* spreads = getSpread(level, x, y, z);
|
||||
int neighbor = depth + dropOff;
|
||||
if (depth >= 8) {
|
||||
neighbor = 1;
|
||||
}
|
||||
if (neighbor >= 8) return;
|
||||
if (spreads[0]) trySpreadTo(level, x - 1, y, z, neighbor);
|
||||
if (spreads[1]) trySpreadTo(level, x + 1, y, z, neighbor);
|
||||
if (spreads[2]) trySpreadTo(level, x, y, z - 1, neighbor);
|
||||
if (spreads[3]) trySpreadTo(level, x, y, z + 1, neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
/*protected*/
|
||||
int getHighest(Level* level, int x, int y, int z, int current) {
|
||||
int d = getDepth(level, x, y, z);
|
||||
if (d < 0) return current;
|
||||
if (d == 0) maxCount++;
|
||||
if (d >= 8) {
|
||||
d = 0;
|
||||
}
|
||||
return current < 0 || d < current ? d : current;
|
||||
}
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z) {
|
||||
super::onPlace(level, x, y, z);
|
||||
if (level->getTile(x, y, z) == id) {
|
||||
level->addToTickNextTick(x, y, z, id, getTickDelay());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void setStatic(Level* level, int x, int y, int z) {
|
||||
int d = level->getData(x, y, z);
|
||||
level->setTileAndDataNoUpdate(x, y, z, id + 1, d);
|
||||
level->setTilesDirty(x, y, z, x, y, z);
|
||||
level->sendTileUpdated(x, y, z);
|
||||
}
|
||||
|
||||
bool canSpreadTo(Level* level, int x, int y, int z) {
|
||||
const Material* target = level->getMaterial(x, y, z);
|
||||
if (target == material) return false;
|
||||
if (target == Material::lava) return false;
|
||||
return !isWaterBlocking(level, x, y, z);
|
||||
}
|
||||
|
||||
bool isWaterBlocking(Level* level, int x, int y, int z) {
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t == 0) return false;
|
||||
if (t == Tile::door_wood->id /*|| t == Tile::door_iron->id */ || t == Tile::sign->id || t == Tile::ladder->id || t == Tile::reeds->id) {
|
||||
return true;
|
||||
}
|
||||
const Material* m = Tile::tiles[t]->material;
|
||||
if (m->blocksMotion()) return true;
|
||||
if (m->isSolid()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool* getSpread(Level* level, int x, int y, int z) {
|
||||
for (int d = 0; d < 4; d++) {
|
||||
dist[d] = 1000;
|
||||
int xx = x;
|
||||
int yy = y;
|
||||
int zz = z;
|
||||
|
||||
if (d == 0) xx--;
|
||||
if (d == 1) xx++;
|
||||
if (d == 2) zz--;
|
||||
if (d == 3) zz++;
|
||||
if (isWaterBlocking(level, xx, yy, zz)) {
|
||||
continue;
|
||||
} else if (level->getMaterial(xx, yy, zz) == material && level->getData(xx, yy, zz) == 0) {
|
||||
continue;
|
||||
} else {
|
||||
if (!isWaterBlocking(level, xx, yy - 1, zz)) {
|
||||
dist[d] = 0;
|
||||
} else {
|
||||
dist[d] = getSlopeDistance(level, xx, yy, zz, 1, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int lowest = dist[0];
|
||||
for (int d = 1; d < 4; d++) {
|
||||
if (dist[d] < lowest) lowest = dist[d];
|
||||
}
|
||||
|
||||
for (int d = 0; d < 4; d++) {
|
||||
result[d] = dist[d] == lowest;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void trySpreadTo(Level* level, int x, int y, int z, int neighbor) {
|
||||
if (canSpreadTo(level, x, y, z)) {
|
||||
int old = level->getTile(x, y, z);
|
||||
if (old > 0) {
|
||||
if (material == Material::lava) {
|
||||
fizz(level, x, y, z);
|
||||
} else {
|
||||
Tile::tiles[old]->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
}
|
||||
}
|
||||
level->setTileAndData(x, y, z, id, neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
int getSlopeDistance(Level* level, int x, int y, int z, int pass, int from) {
|
||||
int lowest = 1000;
|
||||
for (int d = 0; d < 4; d++) {
|
||||
if (d == 0 && from == 1) continue;
|
||||
if (d == 1 && from == 0) continue;
|
||||
if (d == 2 && from == 3) continue;
|
||||
if (d == 3 && from == 2) continue;
|
||||
|
||||
int xx = x;
|
||||
int yy = y;
|
||||
int zz = z;
|
||||
|
||||
if (d == 0) xx--;
|
||||
if (d == 1) xx++;
|
||||
if (d == 2) zz--;
|
||||
if (d == 3) zz++;
|
||||
|
||||
if (isWaterBlocking(level, xx, yy, zz)) {
|
||||
continue;
|
||||
} else if (level->getMaterial(xx, yy, zz) == material && level->getData(xx, yy, zz) == 0) {
|
||||
continue;
|
||||
} else {
|
||||
if (!isWaterBlocking(level, xx, yy - 1, zz)) {
|
||||
return pass;
|
||||
} else {
|
||||
if (pass < 4) {
|
||||
int v = getSlopeDistance(level, xx, yy, zz, pass + 1, d);
|
||||
if (v < lowest) lowest = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
int maxCount;
|
||||
|
||||
static const int NumDirections = 4;
|
||||
|
||||
bool result[NumDirections];
|
||||
int dist[NumDirections];
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileDynamic_H__*/
|
||||
66
src/world/level/tile/LiquidTileStatic.h
Executable file
66
src/world/level/tile/LiquidTileStatic.h
Executable file
@@ -0,0 +1,66 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileStatic_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileStatic_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "LiquidTile.h"
|
||||
#include "../Level.h"
|
||||
#include "FireTile.h"
|
||||
|
||||
class LiquidTileStatic: public LiquidTile
|
||||
{
|
||||
typedef LiquidTile super;
|
||||
public:
|
||||
LiquidTileStatic(int id, const Material* material)
|
||||
: super(id, material)
|
||||
{
|
||||
setTicking(false);
|
||||
if (material == Material::lava) setTicking(true);
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
super::neighborChanged(level, x, y, z, type);
|
||||
if (level->getTile(x, y, z) == id) {
|
||||
setDynamic(level, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
//@fire
|
||||
return;
|
||||
|
||||
if (material == Material::lava) {
|
||||
int h = random->nextInt(3);
|
||||
for (int i = 0; i < h; i++) {
|
||||
x += random->nextInt(3) - 1;
|
||||
y++;
|
||||
z += random->nextInt(3) - 1;
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t == 0) {
|
||||
if (isFlammable(level, x - 1, y, z) || isFlammable(level, x + 1, y, z) || isFlammable(level, x, y, z - 1) || isFlammable(level, x, y, z + 1) || isFlammable(level, x, y - 1, z) || isFlammable(level, x, y + 1, z)) {
|
||||
level->setTile(x, y, z, Tile::fire->id);
|
||||
return;
|
||||
}
|
||||
} else if (Tile::tiles[t]->material->blocksMotion()) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool isFlammable(Level* level, int x, int y, int z) {
|
||||
return level->getMaterial(x, y, z)->isFlammable();
|
||||
}
|
||||
|
||||
void setDynamic(Level* level, int x, int y, int z) {
|
||||
int d = level->getData(x, y, z);
|
||||
level->noNeighborUpdate = true;
|
||||
level->setTileAndDataNoUpdate(x, y, z, id - 1, d);
|
||||
level->setTilesDirty(x, y, z, x, y, z);
|
||||
level->addToTickNextTick(x, y, z, id - 1, getTickDelay());
|
||||
level->noNeighborUpdate = false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__LiquidTileStatic_H__*/
|
||||
27
src/world/level/tile/MelonTile.cpp
Executable file
27
src/world/level/tile/MelonTile.cpp
Executable file
@@ -0,0 +1,27 @@
|
||||
#include "MelonTile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../../item/Item.h"
|
||||
MelonTile::MelonTile( int id )
|
||||
:super(id, Material::vegetable){
|
||||
tex = TEX;
|
||||
}
|
||||
|
||||
int MelonTile::getTexture( LevelSource* level, int x, int y, int z, int face ) {
|
||||
return getTexture(face);
|
||||
}
|
||||
|
||||
int MelonTile::getTexture( int face ) {
|
||||
if(face == Facing::UP || face == Facing::DOWN) return TEX_TOP;
|
||||
return TEX;
|
||||
}
|
||||
|
||||
int MelonTile::getResource( int data, Random* random ) {
|
||||
return Item::melon->id;
|
||||
}
|
||||
|
||||
int MelonTile::getResourceCount( Random* random ) {
|
||||
return 3 + random->nextInt(5);
|
||||
}
|
||||
|
||||
17
src/world/level/tile/MelonTile.h
Executable file
17
src/world/level/tile/MelonTile.h
Executable file
@@ -0,0 +1,17 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__MelonTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__MelonTile_H__
|
||||
#include "Tile.h"
|
||||
class MelonTile : public Tile {
|
||||
typedef Tile super;
|
||||
public:
|
||||
MelonTile(int id);
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
int getTexture(int face);
|
||||
int getResource(int data, Random* random);
|
||||
int getResourceCount(Random* random);
|
||||
private:
|
||||
static const int TEX = 8 + 8 * 16;
|
||||
static const int TEX_TOP = 9 + 8 * 16;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__MelonTile_H__ */
|
||||
23
src/world/level/tile/MetalTile.h
Executable file
23
src/world/level/tile/MetalTile.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__MetalTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__MetalTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class MetalTile: public Tile
|
||||
{
|
||||
public:
|
||||
MetalTile(int id, int tex)
|
||||
: Tile(id, Material::metal)
|
||||
{
|
||||
this->tex = tex;
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
return tex;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__MetalTile_H__*/
|
||||
42
src/world/level/tile/MultiTextureTile.h
Executable file
42
src/world/level/tile/MultiTextureTile.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__MultiTextureTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__MultiTextureTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../material/Material.h"
|
||||
|
||||
class MultiTextureTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
MultiTextureTile(int id, const int* textures, int texCount, const Material* material)
|
||||
: super(id, textures[0], material),
|
||||
_textures(textures),
|
||||
_textureCount(texCount)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int getTexture(int face, int data) {
|
||||
if (data >= 0 && data < _textureCount)
|
||||
{
|
||||
return _textures[data];
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
static int getTileDataForItemAuxValue(int auxValue) {
|
||||
return (auxValue & 0xf);
|
||||
}
|
||||
protected:
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
return data;
|
||||
}
|
||||
static int getItemAuxValueForTileData(int data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const int* _textures;
|
||||
int _textureCount;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ClothTile_H__*/
|
||||
56
src/world/level/tile/Mushroom.cpp
Executable file
56
src/world/level/tile/Mushroom.cpp
Executable file
@@ -0,0 +1,56 @@
|
||||
#include "Mushroom.h"
|
||||
|
||||
Mushroom::Mushroom(int id, int tex)
|
||||
: super(id, tex)
|
||||
{
|
||||
float ss = 0.2f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 2, 0.5f + ss);
|
||||
this->setTicking(true);
|
||||
}
|
||||
|
||||
void Mushroom::tick( Level* level, int x, int y, int z, Random* random ) {
|
||||
if(random->nextInt(25) == 0) {
|
||||
int r = 4;
|
||||
int max = 5;
|
||||
for (int xx = x - r; xx <= x + r; xx++)
|
||||
for (int zz = z - r; zz <= z + r; zz++)
|
||||
for (int yy = y - 1; yy <= y + 1; yy++) {
|
||||
if (level->getTile(xx, yy, zz) == id && --max <= 0) return;
|
||||
}
|
||||
|
||||
int x2 = x + random->nextInt(3) - 1;
|
||||
int y2 = y + random->nextInt(2) - random->nextInt(2);
|
||||
int z2 = z + random->nextInt(3) - 1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (level->isEmptyTile(x2, y2, z2) && canSurvive(level, x2, y2, z2)) {
|
||||
x = x2;
|
||||
y = y2;
|
||||
z = z2;
|
||||
}
|
||||
x2 = x + random->nextInt(3) - 1;
|
||||
y2 = y + random->nextInt(2) - random->nextInt(2);
|
||||
z2 = z + random->nextInt(3) - 1;
|
||||
}
|
||||
|
||||
if (level->isEmptyTile(x2, y2, z2) && canSurvive(level, x2, y2, z2)) {
|
||||
level->setTile(x2, y2, z2, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Mushroom::mayPlace( Level* level, int x, int y, int z, unsigned char face ) {
|
||||
return super::mayPlace(level, x, y, z, face) && canSurvive(level, x, y, z);
|
||||
}
|
||||
|
||||
bool Mushroom::mayPlaceOn( int tile ) {
|
||||
return Tile::solid[tile];
|
||||
}
|
||||
|
||||
bool Mushroom::canSurvive( Level* level, int x, int y, int z ) {
|
||||
if (y < 0 || y >= LEVEL_HEIGHT/*Level::maxBuildHeight*/)
|
||||
return false;
|
||||
|
||||
int below = level->getTile(x, y - 1, z);
|
||||
return (level->getRawBrightness(x, y, z) < 13 && mayPlaceOn(below));
|
||||
}
|
||||
|
||||
20
src/world/level/tile/Mushroom.h
Executable file
20
src/world/level/tile/Mushroom.h
Executable file
@@ -0,0 +1,20 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__Mushroom_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__Mushroom_H__
|
||||
|
||||
#include "Bush.h"
|
||||
|
||||
class Mushroom : public Bush
|
||||
{
|
||||
typedef Bush super;
|
||||
public:
|
||||
Mushroom(int id, int tex);
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random);
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face);
|
||||
bool mayPlaceOn(int tile);
|
||||
|
||||
bool canSurvive(Level* level, int x, int y, int z);
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__Mushroom_H__ */
|
||||
74
src/world/level/tile/NetherReactor.cpp
Executable file
74
src/world/level/tile/NetherReactor.cpp
Executable file
@@ -0,0 +1,74 @@
|
||||
#include "NetherReactor.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../Level.h"
|
||||
#include "entity/NetherReactorTileEntity.h"
|
||||
#include "NetherReactorPattern.h"
|
||||
NetherReactor::NetherReactor( int id, int tex, const Material* material ) : super(id, tex, material) { }
|
||||
|
||||
bool NetherReactor::use( Level* level, int x, int y, int z, Player* player ) {
|
||||
if(level->getLevelData()->getGameType() != GameType::Survival)
|
||||
return false;
|
||||
|
||||
// Level, X, Z
|
||||
NetherReactorPattern pattern;
|
||||
for(int checkLevel = 0; checkLevel <= 2; ++checkLevel) {
|
||||
for(int checkX = -1; checkX <= 1; ++checkX) {
|
||||
for(int checkZ = -1; checkZ <= 1; ++checkZ) {
|
||||
if(level->getTile(x + checkX, y + checkLevel - 1, z + checkZ) != pattern.getTileAt(checkLevel, checkX + 1, checkZ + 1)) {
|
||||
player->displayClientMessage("Not the correct pattern!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!canSpawnStartNetherReactor(level, x, y, z, player)) return false;
|
||||
player->displayClientMessage("Active!");
|
||||
NetherReactorTileEntity* reactor = static_cast<NetherReactorTileEntity*>(level->getTileEntity(x, y, z));
|
||||
if (reactor != NULL) {
|
||||
reactor->lightItUp(x, y, z);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntity* NetherReactor::newTileEntity() {
|
||||
return TileEntityFactory::createTileEntity(TileEntityType::NetherReactor);
|
||||
}
|
||||
|
||||
void NetherReactor::setPhase(Level* level, int x, int y, int z, int phase) {
|
||||
int curPhase = level->getData(x, y, z);
|
||||
if(curPhase != phase) {
|
||||
level->setData(x, y, z, phase);
|
||||
}
|
||||
}
|
||||
|
||||
int NetherReactor::getTexture( int face, int data ) {
|
||||
switch(data) {
|
||||
case 1: return tex-1;
|
||||
case 2: return tex-2;
|
||||
default: return tex;
|
||||
}
|
||||
}
|
||||
|
||||
bool NetherReactor::canSpawnStartNetherReactor( Level* level, int x, int y, int z, Player* player ) {
|
||||
if(!allPlayersCloseToReactor(level, x, y, z)) {
|
||||
player->displayClientMessage("All players need to be close to the reactor.");
|
||||
return false;
|
||||
} else if(y > LEVEL_HEIGHT - 28) {
|
||||
player->displayClientMessage("The nether reactor needs to be built lower down.");
|
||||
return false;
|
||||
} else if(y < 2) {
|
||||
player->displayClientMessage("The nether reactor needs to be built higher up.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetherReactor::allPlayersCloseToReactor( Level* level, int x, int y, int z ) {
|
||||
for(PlayerList::const_iterator i = level->players.begin(); i != level->players.end(); ++i) {
|
||||
Player* currentPlayer = (*i);
|
||||
if(!(currentPlayer->x >= x - 5 && currentPlayer->x <= x + 5)) return false;
|
||||
if(!(currentPlayer->y - currentPlayer->heightOffset >= y -1 && currentPlayer->y - currentPlayer->heightOffset <= y + 1)) return false;
|
||||
if(!(currentPlayer->z >= z - 5 && currentPlayer->z <= z + 5)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
19
src/world/level/tile/NetherReactor.h
Executable file
19
src/world/level/tile/NetherReactor.h
Executable file
@@ -0,0 +1,19 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactor_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactor_H__
|
||||
|
||||
#include "EntityTile.h"
|
||||
|
||||
class Material;
|
||||
class NetherReactor : public EntityTile {
|
||||
typedef EntityTile super;
|
||||
public:
|
||||
int getTexture(int face, int data);
|
||||
NetherReactor(int id, int tex, const Material* material);
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
static void setPhase(Level* level, int x, int y, int z, int phase);
|
||||
TileEntity* newTileEntity();
|
||||
bool canSpawnStartNetherReactor( Level* level, int x, int y, int z, Player* player );
|
||||
bool allPlayersCloseToReactor( Level* level, int x, int y, int z );
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactor_H__ */
|
||||
43
src/world/level/tile/NetherReactorPattern.cpp
Executable file
43
src/world/level/tile/NetherReactorPattern.cpp
Executable file
@@ -0,0 +1,43 @@
|
||||
#include "NetherReactorPattern.h"
|
||||
#include "Tile.h"
|
||||
NetherReactorPattern::NetherReactorPattern( ) {
|
||||
const int goldId = Tile::goldBlock->id;
|
||||
const int stoneId = Tile::stoneBrick->id;
|
||||
const int netherCoreId = Tile::netherReactor->id;
|
||||
const unsigned int types[3][3][3] =
|
||||
{
|
||||
// Level 0
|
||||
{
|
||||
{goldId, stoneId, goldId},
|
||||
{stoneId, stoneId, stoneId},
|
||||
{goldId, stoneId, goldId}
|
||||
},
|
||||
// Level 1
|
||||
{
|
||||
{stoneId, 0, stoneId},
|
||||
{0, netherCoreId, 0},
|
||||
{stoneId, 0, stoneId}
|
||||
},
|
||||
// Level 2
|
||||
{
|
||||
{0, stoneId, 0},
|
||||
{stoneId, stoneId, stoneId},
|
||||
{0, stoneId, 0}
|
||||
}
|
||||
};
|
||||
for(int setLevel = 0; setLevel <= 2; ++setLevel) {
|
||||
for(int setX = 0; setX <= 2; ++setX) {
|
||||
for(int setZ = 0; setZ <= 2; ++setZ) {
|
||||
setTileAt(setLevel, setX, setZ, types[setLevel][setX][setZ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorPattern::setTileAt( int level, int x, int z, int tile) {
|
||||
pattern[level][x][z] = tile;
|
||||
}
|
||||
|
||||
unsigned int NetherReactorPattern::getTileAt( int level, int x, int z ) {
|
||||
return pattern[level][x][z];
|
||||
}
|
||||
14
src/world/level/tile/NetherReactorPattern.h
Executable file
14
src/world/level/tile/NetherReactorPattern.h
Executable file
@@ -0,0 +1,14 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactorPattern_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactorPattern_H__
|
||||
|
||||
class NetherReactorPattern {
|
||||
public:
|
||||
NetherReactorPattern();
|
||||
unsigned int getTileAt(int level, int x, int z);
|
||||
private:
|
||||
void setTileAt(int level, int x, int z, int tile);
|
||||
private:
|
||||
unsigned int pattern[3][3][3];
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__NetherReactorPattern_H__ */
|
||||
60
src/world/level/tile/ObsidianTile.h
Executable file
60
src/world/level/tile/ObsidianTile.h
Executable file
@@ -0,0 +1,60 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ObsidianTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ObsidianTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "StoneTile.h"
|
||||
class
|
||||
|
||||
ObsidianTile: public StoneTile
|
||||
{
|
||||
public:
|
||||
ObsidianTile(int id, int tex, bool isGlowing)
|
||||
: StoneTile(id, tex), isGlowing(isGlowing)
|
||||
{
|
||||
}
|
||||
int getResourceCount(Random* random) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Tile::obsidian->id;
|
||||
}
|
||||
void animateTick(Level* level, int x, int y, int z, Random* random) {
|
||||
if(isGlowing) {
|
||||
poofParticles(level, x, y, z);
|
||||
}
|
||||
}
|
||||
void poofParticles(Level* level, int x, int y, int z) {
|
||||
Random& random = level->random;
|
||||
float r = 1 / 16.0f;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float xx = x + random.nextFloat();
|
||||
float yy = y + random.nextFloat();
|
||||
float zz = z + random.nextFloat();
|
||||
if (i == 0 && !level->isSolidBlockingTile(x, y + 1, z)) yy = y + 1 + r;
|
||||
if (i == 1 && !level->isSolidBlockingTile(x, y - 1, z)) yy = y + 0 - r;
|
||||
if (i == 2 && !level->isSolidBlockingTile(x, y, z + 1)) zz = z + 1 + r;
|
||||
if (i == 3 && !level->isSolidBlockingTile(x, y, z - 1)) zz = z + 0 - r;
|
||||
if (i == 4 && !level->isSolidBlockingTile(x + 1, y, z)) xx = x + 1 + r;
|
||||
if (i == 5 && !level->isSolidBlockingTile(x - 1, y, z)) xx = x + 0 - r;
|
||||
if (xx < x || xx > x + 1 || yy < 0 || yy > y + 1 || zz < z || zz > z + 1) {
|
||||
level->addParticle(PARTICLETYPE(reddust), xx, yy, zz, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool isGlowing;
|
||||
/* void wasExploded(Level* level, int x, int y, int z) {
|
||||
float s = 0.7f;
|
||||
float xo = level->random.nextFloat() * s + (1 - s) * 0.5;
|
||||
float yo = level->random.nextFloat() * s + (1 - s) * 0.5;
|
||||
float zo = level->random.nextFloat() * s + (1 - s) * 0.5;
|
||||
ItemEntity* item = new ItemEntity(level, x + xo, y + yo, z + zo, new ItemInstance(id));
|
||||
item->throwTime = 10;
|
||||
level->addEntity(item);
|
||||
}*/
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ObsidianTile_H__*/
|
||||
41
src/world/level/tile/OreTile.h
Executable file
41
src/world/level/tile/OreTile.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__OreTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__OreTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../../item/DyePowderItem.h"
|
||||
|
||||
class OreTile: public Tile
|
||||
{
|
||||
public:
|
||||
OreTile(int id, int tex)
|
||||
: Tile(id, tex, Material::stone)
|
||||
{
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
if (id == Tile::coalOre->id) return Item::coal->id;
|
||||
if (id == Tile::emeraldOre->id) return Item::emerald->id;
|
||||
if (id == Tile::lapisOre->id) return Item::dye_powder->id;
|
||||
return id;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
if (id == Tile::lapisOre->id) return 4 + random->nextInt(5);
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
//@Override
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
// lapis spawns blue dye
|
||||
if (id == Tile::lapisOre->id) return DyePowderItem::BLUE;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__OreTile_H__*/
|
||||
64
src/world/level/tile/QuartzBlockTile.h
Executable file
64
src/world/level/tile/QuartzBlockTile.h
Executable file
@@ -0,0 +1,64 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__QuartzBlockTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__QuartzBlockTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class QuartzBlockTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
|
||||
static const int TYPE_DEFAULT = 0;
|
||||
static const int TYPE_CHISELED = 1;
|
||||
static const int TYPE_LINES = 2;
|
||||
|
||||
QuartzBlockTile(int id)
|
||||
: super(id, 4 + 13 * 16, Material::stone)
|
||||
{}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (face == Facing::UP || face == Facing::DOWN) {
|
||||
if (data == TYPE_CHISELED)
|
||||
{
|
||||
return 6 + 12 * 16;
|
||||
}
|
||||
if (data == TYPE_LINES)
|
||||
{
|
||||
return 5 + 12 * 16;
|
||||
}
|
||||
if (face == Facing::DOWN) {
|
||||
return 3 + 13 * 16;
|
||||
}
|
||||
return 4 + 12 * 16;
|
||||
}
|
||||
if (data == TYPE_CHISELED)
|
||||
{
|
||||
return 6 + 13 * 16;
|
||||
}
|
||||
if (data == TYPE_LINES)
|
||||
{
|
||||
return 5 + 13 * 16;
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
static int getTileDataForItemAuxValue(int auxValue) {
|
||||
return (auxValue & 0xf);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__QuartzBlockTile_H__*/
|
||||
93
src/world/level/tile/RedStoneOreTile.h
Executable file
93
src/world/level/tile/RedStoneOreTile.h
Executable file
@@ -0,0 +1,93 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__RedStoneOreTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__RedStoneOreTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
class Player;
|
||||
|
||||
class RedStoneOreTile: public Tile
|
||||
{
|
||||
bool lit;
|
||||
|
||||
public:
|
||||
RedStoneOreTile(int id, int tex, bool lit)
|
||||
: Tile(id, tex, Material::stone)
|
||||
{
|
||||
if (lit) {
|
||||
this->setTicking(true);
|
||||
}
|
||||
this->lit = lit;
|
||||
}
|
||||
|
||||
int getTickDelay() {
|
||||
return 30;
|
||||
}
|
||||
|
||||
void attack(Level* level, int x, int y, int z, Player* player) {
|
||||
interact(level, x, y, z);
|
||||
Tile::attack(level, x, y, z, player);
|
||||
}
|
||||
|
||||
void stepOn(Level* level, int x, int y, int z, Entity* entity) {
|
||||
interact(level, x, y, z);
|
||||
Tile::stepOn(level, x, y, z, entity);
|
||||
}
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
interact(level, x, y, z);
|
||||
return Tile::use(level, x, y, z, player);
|
||||
}
|
||||
|
||||
/*private*/ void interact(Level* level, int x, int y, int z) {
|
||||
poofParticles(level, x, y, z);
|
||||
if (id == Tile::redStoneOre->id) {
|
||||
level->setTile(x, y, z, Tile::redStoneOre_lit->id);
|
||||
}
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (id == Tile::redStoneOre_lit->id) {
|
||||
level->setTile(x, y, z, Tile::redStoneOre->id);
|
||||
}
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
//return Item.redStone.id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 4 + random->nextInt(2);
|
||||
}
|
||||
|
||||
void animateTick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (lit) {
|
||||
poofParticles(level, x, y, z);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void poofParticles(Level* level, int x, int y, int z) {
|
||||
Random& random = level->random;
|
||||
float r = 1 / 16.0f;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float xx = x + random.nextFloat();
|
||||
float yy = y + random.nextFloat();
|
||||
float zz = z + random.nextFloat();
|
||||
if (i == 0 && !level->isSolidBlockingTile(x, y + 1, z)) yy = y + 1 + r;
|
||||
if (i == 1 && !level->isSolidBlockingTile(x, y - 1, z)) yy = y + 0 - r;
|
||||
if (i == 2 && !level->isSolidBlockingTile(x, y, z + 1)) zz = z + 1 + r;
|
||||
if (i == 3 && !level->isSolidBlockingTile(x, y, z - 1)) zz = z + 0 - r;
|
||||
if (i == 4 && !level->isSolidBlockingTile(x + 1, y, z)) xx = x + 1 + r;
|
||||
if (i == 5 && !level->isSolidBlockingTile(x - 1, y, z)) xx = x + 0 - r;
|
||||
if (xx < x || xx > x + 1 || yy < 0 || yy > y + 1 || zz < z || zz > z + 1) {
|
||||
level->addParticle(PARTICLETYPE(reddust), xx, yy, zz, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__RedStoneOreTile_H__*/
|
||||
98
src/world/level/tile/ReedTile.h
Executable file
98
src/world/level/tile/ReedTile.h
Executable file
@@ -0,0 +1,98 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ReedTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ReedTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class ReedTile: public Tile
|
||||
{
|
||||
public:
|
||||
ReedTile(int id, int tex)
|
||||
: Tile(id, Material::plant)
|
||||
{
|
||||
this->tex = tex;
|
||||
float ss = 6 / 16.0f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 1, 0.5f + ss);
|
||||
this->setTicking(true);
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->isEmptyTile(x, y + 1, z)) {
|
||||
int height = 1;
|
||||
while (level->getTile(x, y - height, z) == id) {
|
||||
height++;
|
||||
}
|
||||
if (height < 3) {
|
||||
int age = level->getData(x, y, z);
|
||||
if (age == 15) {
|
||||
level->setTile(x, y + 1, z, id);
|
||||
level->setData(x, y, z, 0);
|
||||
} else {
|
||||
level->setData(x, y, z, age + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
int below = level->getTile(x, y - 1, z);
|
||||
if (below == id) return true;
|
||||
if (below != ((Tile*)Tile::grass)->id && below != Tile::dirt->id && below != Tile::sand->id) return false;
|
||||
if (level->getMaterial(x - 1, y - 1, z) == Material::water) return true;
|
||||
if (level->getMaterial(x + 1, y - 1, z) == Material::water) return true;
|
||||
if (level->getMaterial(x, y - 1, z - 1) == Material::water) return true;
|
||||
if (level->getMaterial(x, y - 1, z + 1) == Material::water) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
checkAlive(level, x, y, z);
|
||||
}
|
||||
|
||||
bool canSurvive(Level* level, int x, int y, int z) {
|
||||
return mayPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Item::reeds->id;
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_CROSS_TEXTURE;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
protected:
|
||||
const void checkAlive(Level* level, int x, int y, int z) {
|
||||
if (!canSurvive(level, x, y, z)) {
|
||||
popResource(level, x, y, z, ItemInstance(Item::reeds));
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ReedTile_H__*/
|
||||
37
src/world/level/tile/SandStoneTile.h
Executable file
37
src/world/level/tile/SandStoneTile.h
Executable file
@@ -0,0 +1,37 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__SandStoneTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__SandStoneTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../Facing.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
#include "MultiTextureTile.h"
|
||||
|
||||
class SandStoneTile: public MultiTextureTile
|
||||
{
|
||||
typedef MultiTextureTile super;
|
||||
public:
|
||||
SandStoneTile(int id, const int* textures, int texCount)
|
||||
: super(id, textures, texCount, Material::stone)
|
||||
{}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (face == Facing::UP || (face == Facing::DOWN && data > 0)) {
|
||||
return 11 * 16;//tex - 16;
|
||||
}
|
||||
if (face == Facing::DOWN) {
|
||||
return 13 * 16;//tex + 16;
|
||||
}
|
||||
return super::getTexture(face, data);
|
||||
}
|
||||
|
||||
static const int TYPE_DEFAULT = 0;
|
||||
static const int TYPE_HEIROGLYPHS = 1;
|
||||
static const int TYPE_SMOOTHSIDE = 2;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__SandStoneTile_H__*/
|
||||
26
src/world/level/tile/SandTile.cpp
Executable file
26
src/world/level/tile/SandTile.cpp
Executable file
@@ -0,0 +1,26 @@
|
||||
#include "SandTile.h"
|
||||
#include "../../entity/item/FallingTile.h"
|
||||
|
||||
bool SandTile::instaFall = false;
|
||||
|
||||
/*private*/
|
||||
void SandTile::checkSlide(Level* level, int x, int y, int z)
|
||||
{
|
||||
int x2 = x;
|
||||
int y2 = y;
|
||||
int z2 = z;
|
||||
if (isFree(level, x2, y2 - 1, z2) && y2 >= 0) {
|
||||
int r = 32;
|
||||
if (instaFall || !level->hasChunksAt(x - r, y - r, z - r, x + r, y + r, z + r)) {
|
||||
level->setTile(x, y, z, 0);
|
||||
while (isFree(level, x, y - 1, z) && y > 0)
|
||||
y--;
|
||||
if (y > 0) {
|
||||
level->setTile(x, y, z, id);
|
||||
}
|
||||
} else {
|
||||
FallingTile* e = new FallingTile(level, x + 0.5f, y + 0.5f, z + 0.5f, id);
|
||||
level->addEntity(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/world/level/tile/SandTile.h
Executable file
57
src/world/level/tile/SandTile.h
Executable file
@@ -0,0 +1,57 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__SandTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__SandTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class Level;
|
||||
|
||||
class SandTile: public Tile
|
||||
{
|
||||
public:
|
||||
static bool instaFall;
|
||||
|
||||
SandTile(int type, int tex)
|
||||
: Tile(type, tex, Material::sand)
|
||||
{
|
||||
}
|
||||
|
||||
// id == 0 -> not possible to create via serialization (yet)
|
||||
int getEntityTypeId() const { return 0; } // @todo
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z) {
|
||||
//level->addToTickNextTick(x, y, z, id, getTickDelay());
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
//level->addToTickNextTick(x, y, z, id, getTickDelay());
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
checkSlide(level, x, y, z);
|
||||
}
|
||||
|
||||
int getTickDelay() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static bool isFree(Level* level, int x, int y, int z) {
|
||||
int t = level->getTile(x, y, z);
|
||||
if (t == 0) return true;
|
||||
if (t == ((Tile*)Tile::fire)->id) return true;
|
||||
const Material* material = Tile::tiles[t]->material;
|
||||
if (material == Material::water) return true;
|
||||
if (material == Material::lava) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void checkSlide(Level* level, int x, int y, int z);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__SandTile_H__*/
|
||||
132
src/world/level/tile/Sapling.h
Executable file
132
src/world/level/tile/Sapling.h
Executable file
@@ -0,0 +1,132 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__Sapling_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__Sapling_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Bush.h"
|
||||
#include "../Level.h"
|
||||
#include "../levelgen/feature/SpruceFeature.h"
|
||||
#include "../levelgen/feature/BirchFeature.h"
|
||||
#include "../levelgen/feature/TreeFeature.h"
|
||||
|
||||
class Sapling: public Bush
|
||||
{
|
||||
typedef Bush super;
|
||||
|
||||
static const int TYPE_MASK = 3;
|
||||
static const int AGE_BIT = 8;
|
||||
public:
|
||||
Sapling(int id, int tex)
|
||||
: super(id, tex)
|
||||
{
|
||||
float ss = 0.4f;
|
||||
setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, ss * 2, 0.5f + ss);
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->isClientSide) return;
|
||||
|
||||
super::tick(level, x, y, z, random);
|
||||
|
||||
if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) {
|
||||
if (random->nextInt(7) == 0) {
|
||||
int data = level->getData(x, y, z);
|
||||
if ((data & AGE_BIT) == 0) {
|
||||
//@attn @fix : was setData, but it only works if using sendTileUpdate
|
||||
level->setDataNoUpdate(x, y, z, data | AGE_BIT);
|
||||
} else {
|
||||
growTree(level, x, y, z, random);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getTexture(int face, int data) {
|
||||
data = data & LeafTile::LEAF_TYPE_MASK;
|
||||
if (data == LeafTile::EVERGREEN_LEAF) {
|
||||
return 15 + 16 * 3;
|
||||
} else if (data == LeafTile::BIRCH_LEAF) {
|
||||
return 15 + 16 * 4;
|
||||
//} else if (data == TYPE_JUNGLE) {
|
||||
// return 14 + 16;
|
||||
} else {
|
||||
return super::getTexture(face, data);
|
||||
}
|
||||
}
|
||||
|
||||
void growTree(Level* level, int x, int y, int z, Random* random) {
|
||||
int data = level->getData(x, y, z) & TYPE_MASK;
|
||||
|
||||
Feature* f = NULL;
|
||||
|
||||
int ox = 0, oz = 0;
|
||||
bool multiblock = false;
|
||||
|
||||
if (data == LeafTile::EVERGREEN_LEAF) {
|
||||
f = new SpruceFeature(true);
|
||||
} else if (data == LeafTile::BIRCH_LEAF) {
|
||||
f = new BirchFeature(true);
|
||||
// } else if (data == TYPE_JUNGLE) {
|
||||
//
|
||||
// // check for mega tree
|
||||
// for (ox = 0; ox >= -1; ox--) {
|
||||
// for (oz = 0; oz >= -1; oz--) {
|
||||
// if (isSapling(level, x + ox, y, z + oz, TYPE_JUNGLE) &&
|
||||
// isSapling(level, x + ox + 1, y, z + oz, TYPE_JUNGLE) &&
|
||||
// isSapling(level, x + ox, y, z + oz + 1, TYPE_JUNGLE) &&
|
||||
// isSapling(level, x + ox + 1, y, z + oz + 1, TYPE_JUNGLE)) {
|
||||
// f = /*new*/ MegaTreeFeature(true, 10 + random.nextInt(20), TreeTile::JUNGLE_TRUNK, LeafTile::JUNGLE_LEAF);
|
||||
// multiblock = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (f) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (!f) {
|
||||
// ox = oz = 0;
|
||||
// f = new TreeFeature(true, 4 + random.nextInt(7), TreeTile::JUNGLE_TRUNK, LeafTile::JUNGLE_LEAF, false);
|
||||
// }
|
||||
} else {
|
||||
//if (random->nextInt(10) == 0) {
|
||||
// f = new BasicTree(true);
|
||||
//} else
|
||||
f = new TreeFeature(true);
|
||||
}
|
||||
|
||||
if (multiblock) {
|
||||
level->setTileNoUpdate(x + ox, y, z + oz, 0);
|
||||
level->setTileNoUpdate(x + ox + 1, y, z + oz, 0);
|
||||
level->setTileNoUpdate(x + ox, y, z + oz + 1, 0);
|
||||
level->setTileNoUpdate(x + ox + 1, y, z + oz + 1, 0);
|
||||
} else {
|
||||
level->setTileNoUpdate(x, y, z, 0);
|
||||
}
|
||||
|
||||
if (!f->place(level, random, x + ox, y, z + oz)) {
|
||||
if (multiblock) {
|
||||
level->setTileAndDataNoUpdate(x + ox, y, z + oz, this->id, data);
|
||||
level->setTileAndDataNoUpdate(x + ox + 1, y, z + oz, this->id, data);
|
||||
level->setTileAndDataNoUpdate(x + ox, y, z + oz + 1, this->id, data);
|
||||
level->setTileAndDataNoUpdate(x + ox + 1, y, z + oz + 1, this->id, data);
|
||||
} else {
|
||||
level->setTileAndDataNoUpdate(x, y, z, this->id, data);
|
||||
}
|
||||
}
|
||||
|
||||
if (f) delete f;
|
||||
}
|
||||
|
||||
bool isSapling(Level* level, int x, int y, int z, int type) {
|
||||
return (level->getTile(x, y, z) == id) && ((level->getData(x, y, z) & TYPE_MASK) == type);
|
||||
}
|
||||
|
||||
protected:
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
return data & TYPE_MASK;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__Sapling_H__*/
|
||||
113
src/world/level/tile/SignTile.h
Executable file
113
src/world/level/tile/SignTile.h
Executable file
@@ -0,0 +1,113 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__SignTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__SignTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "EntityTile.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../material/Material.h"
|
||||
#include "entity/TileEntity.h"
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class SignTile: public EntityTile
|
||||
{
|
||||
typedef EntityTile super;
|
||||
public:
|
||||
SignTile(int id, int tileEntityClassId, bool onGround)
|
||||
: super(id, Material::wood),
|
||||
tileEntityClassId(tileEntityClassId),
|
||||
onGround(onGround)
|
||||
{
|
||||
tex = 4;
|
||||
float r = 4 / 16.0f;
|
||||
float h = 16 / 16.0f;
|
||||
this->setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
AABB getTileAABB(Level* level, int x, int y, int z) {
|
||||
updateShape(level, x, y, z);
|
||||
return super::getTileAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void updateShape(LevelSource* level, int x, int y, int z) {
|
||||
if (onGround) return;
|
||||
|
||||
int face = level->getData(x, y, z);
|
||||
|
||||
float h0 = (4 + 0.5f) / 16.0f;
|
||||
float h1 = (12 + 0.5f) / 16.0f;
|
||||
float w0 = 0 / 16.0f;
|
||||
float w1 = 16 / 16.0f;
|
||||
|
||||
float d0 = 2 / 16.0f;
|
||||
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
if (face == 2) setShape(w0, h0, 1 - d0, w1, h1, 1);
|
||||
if (face == 3) setShape(w0, h0, 0, w1, h1, d0);
|
||||
if (face == 4) setShape(1 - d0, h0, w0, 1, h1, w1);
|
||||
if (face == 5) setShape(0, h0, w0, d0, h1, w1);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_INVISIBLE;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isPathfindable(LevelSource* level, int x, int y, int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
TileEntity* newTileEntity() {
|
||||
return TileEntityFactory::createTileEntity(tileEntityClassId);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getResource(int data, Random* random/*, int playerBonusLevel*/) {
|
||||
return Item::sign->id;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
bool remove = false;
|
||||
|
||||
if (onGround) {
|
||||
if (!level->getMaterial(x, y - 1, z)->isSolid()) remove = true;
|
||||
} else {
|
||||
int face = level->getData(x, y, z);
|
||||
remove = true;
|
||||
if (face == 2 && level->getMaterial(x, y, z + 1)->isSolid()) remove = false;
|
||||
if (face == 3 && level->getMaterial(x, y, z - 1)->isSolid()) remove = false;
|
||||
if (face == 4 && level->getMaterial(x + 1, y, z)->isSolid()) remove = false;
|
||||
if (face == 5 && level->getMaterial(x - 1, y, z)->isSolid()) remove = false;
|
||||
}
|
||||
if (remove) {
|
||||
spawnResources(level, x, y, z, level->getData(x, y, z), 0);
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
super::neighborChanged(level, x, y, z, type);
|
||||
}
|
||||
private:
|
||||
bool onGround;
|
||||
int tileEntityClassId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__SignTile_H__*/
|
||||
38
src/world/level/tile/SnowTile.h
Executable file
38
src/world/level/tile/SnowTile.h
Executable file
@@ -0,0 +1,38 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__SnowTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__SnowTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
#include "../material/Material.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class SnowTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
SnowTile(int id, int tex)
|
||||
: super(id, tex, Material::snow)
|
||||
{
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Item::snowBall->id;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->getBrightness(LightLayer::Block, x, y, z) > 11) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__SnowTile_H__*/
|
||||
237
src/world/level/tile/StairTile.cpp
Executable file
237
src/world/level/tile/StairTile.cpp
Executable file
@@ -0,0 +1,237 @@
|
||||
#include "../Level.h"
|
||||
#include "../../phys/HitResult.h"
|
||||
#include "../../phys/Vec3.h"
|
||||
#include "../../Facing.h"
|
||||
#include "StairTile.h"
|
||||
|
||||
const int StairTile::DEAD_SPACES[8][2] = {
|
||||
{2, 6}, {3, 7}, {2, 3}, {6, 7},
|
||||
{0, 4}, {1, 5}, {0, 1}, {4, 5}
|
||||
};
|
||||
|
||||
int StairTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue) {
|
||||
if (face == Facing::DOWN || (face != Facing::UP && clickY > 0.5)) {
|
||||
return itemValue | UPSIDEDOWN_BIT;
|
||||
}
|
||||
return itemValue;
|
||||
}
|
||||
|
||||
|
||||
bool StairTile::setStepShape(LevelSource* level, int x, int y, int z) {
|
||||
int data = level->getData(x, y, z);
|
||||
int dir = data & 0x3;
|
||||
|
||||
float bottom = 0.5f;
|
||||
float top = 1.0f;
|
||||
|
||||
if ((data & UPSIDEDOWN_BIT) != 0) {
|
||||
bottom = 0;
|
||||
top = .5f;
|
||||
}
|
||||
|
||||
float west = 0;
|
||||
float east = 1;
|
||||
float north = 0;
|
||||
float south = .5f;
|
||||
|
||||
bool checkInnerPiece = true;
|
||||
|
||||
if (dir == DIR_EAST) {
|
||||
west = .5f;
|
||||
south = 1;
|
||||
|
||||
int backTile = level->getTile(x + 1, y, z);
|
||||
int backData = level->getData(x + 1, y, z);
|
||||
if (isStairs(backTile) && ((data & UPSIDEDOWN_BIT) == (backData & UPSIDEDOWN_BIT))) {
|
||||
int backDir = backData & 0x3;
|
||||
if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) {
|
||||
south = .5f;
|
||||
checkInnerPiece = false;
|
||||
} else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) {
|
||||
north = .5f;
|
||||
checkInnerPiece = false;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_WEST) {
|
||||
east = .5f;
|
||||
south = 1;
|
||||
|
||||
int backTile = level->getTile(x - 1, y, z);
|
||||
int backData = level->getData(x - 1, y, z);
|
||||
if (isStairs(backTile) && ((data & UPSIDEDOWN_BIT) == (backData & UPSIDEDOWN_BIT))) {
|
||||
int backDir = backData & 0x3;
|
||||
if (backDir == DIR_NORTH && !isLockAttached(level, x, y, z + 1, data)) {
|
||||
south = .5f;
|
||||
checkInnerPiece = false;
|
||||
} else if (backDir == DIR_SOUTH && !isLockAttached(level, x, y, z - 1, data)) {
|
||||
north = .5f;
|
||||
checkInnerPiece = false;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_SOUTH) {
|
||||
north = .5f;
|
||||
south = 1;
|
||||
|
||||
int backTile = level->getTile(x, y, z + 1);
|
||||
int backData = level->getData(x, y, z + 1);
|
||||
if (isStairs(backTile) && ((data & UPSIDEDOWN_BIT) == (backData & UPSIDEDOWN_BIT))) {
|
||||
int backDir = backData & 0x3;
|
||||
if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) {
|
||||
east = .5f;
|
||||
checkInnerPiece = false;
|
||||
} else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) {
|
||||
west = .5f;
|
||||
checkInnerPiece = false;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_NORTH) {
|
||||
int backTile = level->getTile(x, y, z - 1);
|
||||
int backData = level->getData(x, y, z - 1);
|
||||
if (isStairs(backTile) && ((data & UPSIDEDOWN_BIT) == (backData & UPSIDEDOWN_BIT))) {
|
||||
int backDir = backData & 0x3;
|
||||
if (backDir == DIR_WEST && !isLockAttached(level, x + 1, y, z, data)) {
|
||||
east = .5f;
|
||||
checkInnerPiece = false;
|
||||
} else if (backDir == DIR_EAST && !isLockAttached(level, x - 1, y, z, data)) {
|
||||
west = .5f;
|
||||
checkInnerPiece = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setShape(west, bottom, north, east, top, south);
|
||||
return checkInnerPiece;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method adds an extra 1/8 block if the stairs can attach as an
|
||||
* "inner corner."
|
||||
*/
|
||||
bool StairTile::setInnerPieceShape(LevelSource* level, int x, int y, int z) {
|
||||
int data = level->getData(x, y, z);
|
||||
int dir = data & 0x3;
|
||||
|
||||
float bottom = 0.5f;
|
||||
float top = 1.0f;
|
||||
|
||||
if ((data & UPSIDEDOWN_BIT) != 0) {
|
||||
bottom = 0;
|
||||
top = .5f;
|
||||
}
|
||||
|
||||
float west = 0;
|
||||
float east = .5f;
|
||||
float north = .5f;
|
||||
float south = 1.0f;
|
||||
|
||||
bool hasInnerPiece = false;
|
||||
|
||||
if (dir == DIR_EAST) {
|
||||
int frontTile = level->getTile(x - 1, y, z);
|
||||
int frontData = level->getData(x - 1, y, z);
|
||||
if (isStairs(frontTile) && ((data & UPSIDEDOWN_BIT) == (frontData & UPSIDEDOWN_BIT))) {
|
||||
int frontDir = frontData & 0x3;
|
||||
if (frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) {
|
||||
north = 0;
|
||||
south = .5f;
|
||||
hasInnerPiece = true;
|
||||
} else if (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data)) {
|
||||
north = .5f;
|
||||
south = 1;
|
||||
hasInnerPiece = true;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_WEST) {
|
||||
int frontTile = level->getTile(x + 1, y, z);
|
||||
int frontData = level->getData(x + 1, y, z);
|
||||
if (isStairs(frontTile) && ((data & UPSIDEDOWN_BIT) == (frontData & UPSIDEDOWN_BIT))) {
|
||||
west = .5f;
|
||||
east = 1.0f;
|
||||
int frontDir = frontData & 0x3;
|
||||
if (frontDir == DIR_NORTH && !isLockAttached(level, x, y, z - 1, data)) {
|
||||
north = 0;
|
||||
south = .5f;
|
||||
hasInnerPiece = true;
|
||||
} else if (frontDir == DIR_SOUTH && !isLockAttached(level, x, y, z + 1, data)) {
|
||||
north = .5f;
|
||||
south = 1;
|
||||
hasInnerPiece = true;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_SOUTH) {
|
||||
int frontTile = level->getTile(x, y, z - 1);
|
||||
int frontData = level->getData(x, y, z - 1);
|
||||
if (isStairs(frontTile) && ((data & UPSIDEDOWN_BIT) == (frontData & UPSIDEDOWN_BIT))) {
|
||||
north = 0;
|
||||
south = .5f;
|
||||
|
||||
int frontDir = frontData & 0x3;
|
||||
if (frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) {
|
||||
hasInnerPiece = true;
|
||||
} else if (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data)) {
|
||||
west = .5f;
|
||||
east = 1.0f;
|
||||
hasInnerPiece = true;
|
||||
}
|
||||
}
|
||||
} else if (dir == DIR_NORTH) {
|
||||
int frontTile = level->getTile(x, y, z + 1);
|
||||
int frontData = level->getData(x, y, z + 1);
|
||||
if (isStairs(frontTile) && ((data & UPSIDEDOWN_BIT) == (frontData & UPSIDEDOWN_BIT))) {
|
||||
int frontDir = frontData & 0x3;
|
||||
if (frontDir == DIR_WEST && !isLockAttached(level, x - 1, y, z, data)) {
|
||||
hasInnerPiece = true;
|
||||
} else if (frontDir == DIR_EAST && !isLockAttached(level, x + 1, y, z, data)) {
|
||||
west = .5f;
|
||||
east = 1.0f;
|
||||
hasInnerPiece = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasInnerPiece) {
|
||||
setShape(west, bottom, north, east, top, south);
|
||||
}
|
||||
return hasInnerPiece;
|
||||
}
|
||||
|
||||
HitResult StairTile::clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b)
|
||||
{
|
||||
HitResult results[8];
|
||||
|
||||
int data = level->getData(xt, yt, zt);
|
||||
int dir = data & 0x3;
|
||||
bool upsideDown = (data & UPSIDEDOWN_BIT) == UPSIDEDOWN_BIT;
|
||||
const int* deadSpaces = (const int*)&DEAD_SPACES[dir + (upsideDown ? 4 : 0)];
|
||||
|
||||
isClipping = true;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
clipStep = i;
|
||||
results[i] = super::clip(level, xt, yt, zt, a, b);
|
||||
}
|
||||
isClipping = false;
|
||||
|
||||
results[deadSpaces[0]] = HitResult();
|
||||
results[deadSpaces[1]] = HitResult();
|
||||
|
||||
HitResult* closest = NULL;
|
||||
double closestDist = 0;
|
||||
|
||||
for (int r = 0; r < 8; r++) {
|
||||
HitResult& result = results[r];
|
||||
if (result.isHit()) {
|
||||
double dist = result.pos.distanceToSqr(b);
|
||||
|
||||
if (dist > closestDist) {
|
||||
closest = &result;
|
||||
closestDist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closest == NULL)
|
||||
{
|
||||
return HitResult();
|
||||
}
|
||||
|
||||
return *closest;
|
||||
}
|
||||
243
src/world/level/tile/StairTile.h
Executable file
243
src/world/level/tile/StairTile.h
Executable file
@@ -0,0 +1,243 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__StairTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__StairTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../../../util/Mth.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../entity/Mob.h"
|
||||
|
||||
class StairTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
Tile* base;
|
||||
|
||||
bool isClipping;
|
||||
int clipStep;
|
||||
int baseData;
|
||||
|
||||
public:
|
||||
|
||||
static const int UPSIDEDOWN_BIT = 4;
|
||||
|
||||
// the direction is the way going up (for normal non-upsidedown stairs)
|
||||
static const int DIR_EAST = 0;
|
||||
static const int DIR_WEST = 1;
|
||||
static const int DIR_SOUTH = 2;
|
||||
static const int DIR_NORTH = 3;
|
||||
|
||||
static const int DEAD_SPACES[8][2];
|
||||
|
||||
StairTile(int id, Tile* base)
|
||||
: super(id, base->tex, base->material),
|
||||
base(base),
|
||||
isClipping(false),
|
||||
clipStep(0),
|
||||
baseData(0) // when needed in the future, set this to necessary texture data
|
||||
{
|
||||
setDestroyTime(base->destroySpeed);
|
||||
setExplodeable(base->explosionResistance / 3);
|
||||
setSoundType(*base->soundType);
|
||||
setLightBlock(255);
|
||||
}
|
||||
|
||||
HitResult clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b);
|
||||
|
||||
void updateShape(LevelSource* level, int x, int y, int z) {
|
||||
if (isClipping) {
|
||||
setShape(0.5f * (clipStep % 2), 0.5f * (clipStep / 2 % 2), 0.5f * (clipStep / 4 % 2), 0.5f + 0.5f * (clipStep % 2), 0.5f + 0.5f * (clipStep / 2 % 2), 0.5f + 0.5f * (clipStep / 4 % 2));
|
||||
} else {
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void setBaseShape(LevelSource* level, int x, int y, int z) {
|
||||
int data = level->getData(x, y, z);
|
||||
|
||||
if ((data & UPSIDEDOWN_BIT) != 0) {
|
||||
setShape(0, .5f, 0, 1, 1, 1);
|
||||
} else {
|
||||
setShape(0, 0, 0, 1, .5f, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isStairs(int id) {
|
||||
return id > 0 && Tile::tiles[id]->getRenderShape() == Tile::SHAPE_STAIRS;
|
||||
}
|
||||
|
||||
bool isLockAttached(LevelSource* level, int x, int y, int z, int data) {
|
||||
int lockTile = level->getTile(x, y, z);
|
||||
if (isStairs(lockTile) && level->getData(x, y, z) == data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool setStepShape(LevelSource* level, int x, int y, int z);
|
||||
bool setInnerPieceShape(LevelSource* level, int x, int y, int z);
|
||||
|
||||
// AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
// return super::getAABB(level, x, y, z);
|
||||
//// return AABB.newTemp(x, y, z, x + 1, y + 1, z + 1);
|
||||
// }
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_STAIRS;
|
||||
}
|
||||
|
||||
//bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
// return super::shouldRenderFace(level, x, y, z, face);
|
||||
//}
|
||||
|
||||
void addAABBs(Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes) {
|
||||
setBaseShape(level, x, y, z);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
|
||||
bool checkInnerPiece = setStepShape(level, x, y, z);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
|
||||
if (checkInnerPiece) {
|
||||
if (setInnerPieceShape(level, x, y, z)) {
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
}
|
||||
}
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* void neighborChanged(Level level, int x, int y, int z, int type) {
|
||||
* if (level.isOnline) return; if (level.getMaterial(x, y + 1, z).isSolid())
|
||||
* { level.setTile(x, y, z, base.id); } else { checkStairs(level, x, y, z);
|
||||
* checkStairs(level, x + 1, y - 1, z); checkStairs(level, x - 1, y - 1, z);
|
||||
* checkStairs(level, x, y - 1, z - 1); checkStairs(level, x, y - 1, z + 1);
|
||||
* checkStairs(level, x + 1, y + 1, z); checkStairs(level, x - 1, y + 1, z);
|
||||
* checkStairs(level, x, y + 1, z - 1); checkStairs(level, x, y + 1, z + 1);
|
||||
* } base.neighborChanged(level, x, y, z, type); }
|
||||
*/
|
||||
|
||||
/** DELEGATES: **/
|
||||
|
||||
void addLights(Level* level, int x, int y, int z) {
|
||||
base->addLights(level, x, y, z);
|
||||
}
|
||||
|
||||
void animateTick(Level* level, int x, int y, int z, Random* random) {
|
||||
base->animateTick(level, x, y, z, random);
|
||||
}
|
||||
|
||||
void attack(Level* level, int x, int y, int z, Player* player) {
|
||||
base->attack(level, x, y, z, player);
|
||||
}
|
||||
|
||||
void destroy(Level* level, int x, int y, int z, int data) {
|
||||
base->destroy(level, x, y, z, data);
|
||||
}
|
||||
|
||||
float getBrightness(LevelSource* level, int x, int y, int z) {
|
||||
return base->getBrightness(level, x, y, z);
|
||||
}
|
||||
|
||||
float getExplosionResistance(Entity* source) {
|
||||
return base->getExplosionResistance(source);
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return base->getRenderLayer();
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return base->getResourceCount(random);
|
||||
}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
return base->getTexture(face, baseData);
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
return base->getTexture(face, baseData);
|
||||
}
|
||||
|
||||
int getTexture(LevelSource* level, int x, int y, int z, int face) {
|
||||
return base->getTexture(face, baseData);
|
||||
}
|
||||
|
||||
int getTickDelay() {
|
||||
return base->getTickDelay();
|
||||
}
|
||||
|
||||
AABB getTileAABB(Level* level, int x, int y, int z) {
|
||||
return base->getTileAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
void handleEntityInside(Level* level, int x, int y, int z, Entity* e, Vec3& current) {
|
||||
base->handleEntityInside(level, x, y, z, e, current);
|
||||
}
|
||||
|
||||
bool mayPick() {
|
||||
return base->mayPick();
|
||||
}
|
||||
|
||||
bool mayPick(int data, bool liquid) {
|
||||
return base->mayPick(data, liquid);
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
||||
return base->mayPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z) {
|
||||
neighborChanged(level, x, y, z, 0);
|
||||
base->onPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
void onRemove(Level* level, int x, int y, int z) {
|
||||
base->onRemove(level, x, y, z);
|
||||
}
|
||||
|
||||
void prepareRender(Level* level, int x, int y, int z) {
|
||||
base->prepareRender(level, x, y, z);
|
||||
}
|
||||
|
||||
void stepOn(Level* level, int x, int y, int z, Entity* entity) {
|
||||
base->stepOn(level, x, y, z, entity);
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
base->tick(level, x, y, z, random);
|
||||
}
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
return base->use(level, x, y, z, player);
|
||||
}
|
||||
|
||||
void wasExploded(Level* level, int x, int y, int z) {
|
||||
base->wasExploded(level, x, y, z);
|
||||
}
|
||||
|
||||
void setPlacedBy(Level* level, int x, int y, int z, Mob* by) {
|
||||
int dir = (Mth::floor(by->yRot * 4 / (360) + 0.5f)) & 3;
|
||||
int usd = level->getData(x, y, z) & UPSIDEDOWN_BIT;
|
||||
|
||||
if (dir == 0) level->setData(x, y, z, 2 | usd);
|
||||
if (dir == 1) level->setData(x, y, z, 1 | usd);
|
||||
if (dir == 2) level->setData(x, y, z, 3 | usd);
|
||||
if (dir == 3) level->setData(x, y, z, 0 | usd);
|
||||
}
|
||||
|
||||
int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue);
|
||||
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__StairTile_H__*/
|
||||
153
src/world/level/tile/StemTile.cpp
Executable file
153
src/world/level/tile/StemTile.cpp
Executable file
@@ -0,0 +1,153 @@
|
||||
#include "StemTile.h"
|
||||
StemTile::StemTile( int id, Tile* fruit )
|
||||
: super(id, 15 + 6 * 16),
|
||||
fruit(fruit) {
|
||||
setTicking(true);
|
||||
float ss = 0.125f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss);
|
||||
}
|
||||
|
||||
bool StemTile::mayPlaceOn( int tile ) {
|
||||
return tile == Tile::farmland->id;
|
||||
}
|
||||
|
||||
void StemTile::tick( Level* level, int x, int y, int z, Random* random ) {
|
||||
super::tick(level, x, y, z, random);
|
||||
if (level->getRawBrightness(x, y + 1, z) >= Level::MAX_BRIGHTNESS - 6) {
|
||||
|
||||
float growthSpeed = getGrowthSpeed(level, x, y, z);
|
||||
|
||||
if (random->nextInt((int) (25 / growthSpeed) + 1) == 0) {
|
||||
int age = level->getData(x, y, z);
|
||||
if (age < 7) {
|
||||
age++;
|
||||
level->setData(x, y, z, age);
|
||||
} else {
|
||||
if (level->getTile(x - 1, y, z) == fruit->id) return;
|
||||
if (level->getTile(x + 1, y, z) == fruit->id) return;
|
||||
if (level->getTile(x, y, z - 1) == fruit->id) return;
|
||||
if (level->getTile(x, y, z + 1) == fruit->id) return;
|
||||
for(int a = 0; a < 4; ++a) {
|
||||
int dir = a; //random->nextInt(4);
|
||||
int xx = x;
|
||||
int zz = z;
|
||||
if (dir == 0) xx--;
|
||||
if (dir == 1) xx++;
|
||||
if (dir == 2) zz--;
|
||||
if (dir == 3) zz++;
|
||||
int below = level->getTile(xx, y - 1, zz);
|
||||
if (level->getTile(xx, y, zz) == 0 && (below == Tile::farmland->id || below == Tile::dirt->id || below == Tile::grass->id)) {
|
||||
level->setTile(xx, y, zz, fruit->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StemTile::growCropsToMax( Level* level, int x, int y, int z ) {
|
||||
level->setData(x, y, z, 7);
|
||||
}
|
||||
|
||||
float StemTile::getGrowthSpeed( Level* level, int x, int y, int z ) {
|
||||
float speed = 1;
|
||||
|
||||
int n = level->getTile(x, y, z - 1);
|
||||
int s = level->getTile(x, y, z + 1);
|
||||
int w = level->getTile(x - 1, y, z);
|
||||
int e = level->getTile(x + 1, y, z);
|
||||
|
||||
int d0 = level->getTile(x - 1, y, z - 1);
|
||||
int d1 = level->getTile(x + 1, y, z - 1);
|
||||
int d2 = level->getTile(x + 1, y, z + 1);
|
||||
int d3 = level->getTile(x - 1, y, z + 1);
|
||||
|
||||
bool horizontal = w == this->id || e == this->id;
|
||||
bool vertical = n == this->id || s == this->id;
|
||||
bool diagonal = d0 == this->id || d1 == this->id || d2 == this->id || d3 == this->id;
|
||||
|
||||
for (int xx = x - 1; xx <= x + 1; xx++)
|
||||
for (int zz = z - 1; zz <= z + 1; zz++) {
|
||||
int t = level->getTile(xx, y - 1, zz);
|
||||
|
||||
float tileSpeed = 0;
|
||||
if (t == Tile::farmland->id) {
|
||||
tileSpeed = 1;
|
||||
if (level->getData(xx, y - 1, zz) > 0) tileSpeed = 3;
|
||||
}
|
||||
|
||||
if (xx != x || zz != z) tileSpeed /= 4;
|
||||
|
||||
speed += tileSpeed;
|
||||
}
|
||||
|
||||
if (diagonal || (horizontal && vertical)) speed /= 2;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
int StemTile::getColor( int data ) {
|
||||
int r = data * 32;
|
||||
int g = 255 - data * 8;
|
||||
int b = data * 4;
|
||||
return r << 16 | g << 8 | b;
|
||||
}
|
||||
|
||||
int StemTile::getColor( LevelSource* level, int x, int y, int z ) {
|
||||
return getColor(level->getData(x, y, z));
|
||||
}
|
||||
|
||||
int StemTile::getTexture( int face, int data ) {
|
||||
return tex;
|
||||
}
|
||||
|
||||
void StemTile::updateDefaultShape() {
|
||||
float ss = 0.125f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.25f, 0.5f + ss);
|
||||
}
|
||||
|
||||
void StemTile::updateShape( LevelSource* level, int x, int y, int z ) {
|
||||
yy1 = (level->getData(x, y, z) * 2 + 2) / 16.0f;
|
||||
float ss = 0.125f;
|
||||
this->setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, (float) yy1, 0.5f + ss);
|
||||
}
|
||||
|
||||
int StemTile::getRenderShape() {
|
||||
return Tile::SHAPE_STEM;
|
||||
}
|
||||
|
||||
int StemTile::getConnectDir( LevelSource* level, int x, int y, int z ) {
|
||||
int d = level->getData(x, y, z);
|
||||
if (d < 7) return -1;
|
||||
if (level->getTile(x - 1, y, z) == fruit->id) return 0;
|
||||
if (level->getTile(x + 1, y, z) == fruit->id) return 1;
|
||||
if (level->getTile(x, y, z - 1) == fruit->id) return 2;
|
||||
if (level->getTile(x, y, z + 1) == fruit->id) return 3;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StemTile::spawnResources( Level* level, int x, int y, int z, int data, float odds ) {
|
||||
super::spawnResources(level, x, y, z, data, odds);
|
||||
|
||||
if (level->isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
Item* seed = NULL;
|
||||
//if (fruit == Tile::pumpkin) seed = Item::seeds_pumpkin;
|
||||
if (fruit == Tile::melon) seed = Item::seeds_melon;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (level->random.nextInt(5 * 3) > data) continue;
|
||||
popResource(level, x, y, z, ItemInstance(seed));
|
||||
}
|
||||
}
|
||||
|
||||
int StemTile::getResource( int data, Random* random ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StemTile::getResourceCount( Random* random ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
28
src/world/level/tile/StemTile.h
Executable file
28
src/world/level/tile/StemTile.h
Executable file
@@ -0,0 +1,28 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__StemTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__StemTile_H__
|
||||
#include "Bush.h"
|
||||
class StemTile : public Bush {
|
||||
typedef Bush super;
|
||||
public:
|
||||
StemTile(int id, Tile* fruit);
|
||||
bool mayPlaceOn(int tile);
|
||||
void tick(Level* level, int x, int y, int z, Random* random);
|
||||
void growCropsToMax(Level* level, int x, int y, int z);
|
||||
int getColor(int data);
|
||||
int getColor(LevelSource* level, int x, int y, int z);
|
||||
int getTexture(int face, int data);
|
||||
void updateDefaultShape();
|
||||
void updateShape(LevelSource* level, int x, int y, int z);
|
||||
int getRenderShape();
|
||||
int getConnectDir(LevelSource* level, int x, int y, int z);
|
||||
void spawnResources(Level* level, int x, int y, int z, int data, float odds);
|
||||
int getResource(int data, Random* random);
|
||||
int getResourceCount(Random* random);
|
||||
private:
|
||||
float getGrowthSpeed(Level* level, int x, int y, int z);
|
||||
|
||||
private:
|
||||
Tile* fruit;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__StemTile_H__ */
|
||||
155
src/world/level/tile/StoneSlabTile.cpp
Executable file
155
src/world/level/tile/StoneSlabTile.cpp
Executable file
@@ -0,0 +1,155 @@
|
||||
#include "StoneSlabTile.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
#include "../../Facing.h"
|
||||
|
||||
const std::string StoneSlabTile::SLAB_NAMES[] = {
|
||||
"stone", "sand", "wood", "cobble", "brick", "smoothStoneBrick"
|
||||
};
|
||||
const int StoneSlabTile::SLAB_NAMES_COUNT = sizeof(SLAB_NAMES) / sizeof(std::string);
|
||||
|
||||
StoneSlabTile::StoneSlabTile(int id, bool fullSize)
|
||||
: Tile(id, 6, Material::stone)
|
||||
{
|
||||
this->fullSize = fullSize;
|
||||
|
||||
if (!fullSize) {
|
||||
setShape(0, 0, 0, 1, 0.5f, 1);
|
||||
}
|
||||
setLightBlock(255);
|
||||
}
|
||||
|
||||
void StoneSlabTile::updateShape(LevelSource* level, int x, int y, int z)
|
||||
{
|
||||
if (fullSize) {
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
} else {
|
||||
bool upper = (level->getData(x, y, z) & TOP_SLOT_BIT) != 0;
|
||||
if (upper) {
|
||||
setShape(0, 0.5f, 0, 1, 1, 1);
|
||||
} else {
|
||||
setShape(0, 0, 0, 1, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StoneSlabTile::updateDefaultShape()
|
||||
{
|
||||
if (fullSize) {
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
} else {
|
||||
setShape(0, 0, 0, 1, 0.5f, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int StoneSlabTile::getTexture(int face, int data) {
|
||||
data = data & TYPE_MASK;
|
||||
if (data == STONE_SLAB) {
|
||||
if (face <= 1) return 6;
|
||||
return 5;
|
||||
} else if (data == SAND_SLAB) {
|
||||
if (face == Facing::DOWN) return 13 * 16;
|
||||
if (face == Facing::UP) return 11 * 16;
|
||||
return 12 * 16;
|
||||
} else if (data == WOOD_SLAB) {
|
||||
return 4;
|
||||
} else if (data == COBBLESTONE_SLAB) {
|
||||
return 16;
|
||||
} else if (data == BRICK_SLAB) {
|
||||
return Tile::redBrick->tex;
|
||||
} else if (data == SMOOTHBRICK_SLAB) {
|
||||
return Tile::stoneBrickSmooth->tex;
|
||||
}
|
||||
return 6;
|
||||
}
|
||||
|
||||
int StoneSlabTile::getTexture(int face) {
|
||||
return getTexture(face, 0);
|
||||
}
|
||||
|
||||
bool StoneSlabTile::isSolidRender() {
|
||||
return fullSize;
|
||||
}
|
||||
|
||||
int StoneSlabTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue)
|
||||
{
|
||||
if (fullSize) return itemValue;
|
||||
|
||||
if (face == Facing::DOWN || (face != Facing::UP && clickY > 0.5)) {
|
||||
return itemValue | TOP_SLOT_BIT;
|
||||
}
|
||||
return itemValue;
|
||||
}
|
||||
|
||||
/*
|
||||
void StoneSlabTile::onPlace(Level* level, int x, int y, int z) {
|
||||
if (this != Tile::stoneSlabHalf) Tile::onPlace(level, x, y, z);
|
||||
int below = level->getTile(x, y - 1, z);
|
||||
|
||||
int myData = level->getData(x, y, z);
|
||||
int belowData = level->getData(x, y - 1, z);
|
||||
|
||||
if (myData != belowData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (below == Tile::stoneSlabHalf->id) {
|
||||
level->setTile(x, y, z, 0);
|
||||
level->setTileAndData(x, y - 1, z, Tile::stoneSlab->id, myData);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int StoneSlabTile::getResource(int data, Random* random) {
|
||||
return Tile::stoneSlabHalf->id;
|
||||
}
|
||||
|
||||
int StoneSlabTile::getResourceCount(Random* random) {
|
||||
if (fullSize) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool StoneSlabTile::isCubeShaped() {
|
||||
return fullSize;
|
||||
}
|
||||
|
||||
void StoneSlabTile::addAABBs( Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes ) {
|
||||
updateShape(level, x, y, z);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
}
|
||||
|
||||
static bool isHalfSlab(int tileId) {
|
||||
return tileId == Tile::stoneSlabHalf->id;// || tileId == Tile::woodSlabHalf->id;
|
||||
}
|
||||
|
||||
bool StoneSlabTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
|
||||
if (fullSize) return super::shouldRenderFace(level, x, y, z, face);
|
||||
|
||||
if (face != Facing::UP && face != Facing::DOWN && !super::shouldRenderFace(level, x, y, z, face)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ox = x, oy = y, oz = z;
|
||||
ox += Facing::STEP_X[Facing::OPPOSITE_FACING[face]];
|
||||
oy += Facing::STEP_Y[Facing::OPPOSITE_FACING[face]];
|
||||
oz += Facing::STEP_Z[Facing::OPPOSITE_FACING[face]];
|
||||
|
||||
bool isUpper = (level->getData(ox, oy, oz) & TOP_SLOT_BIT) != 0;
|
||||
if (isUpper) {
|
||||
if (face == Facing::DOWN) return true;
|
||||
if (face == Facing::UP && super::shouldRenderFace(level, x, y, z, face)) return true;
|
||||
return !(isHalfSlab(level->getTile(x, y, z)) && (level->getData(x, y, z) & TOP_SLOT_BIT) != 0);
|
||||
} else {
|
||||
if (face == Facing::UP) return true;
|
||||
if (face == Facing::DOWN && super::shouldRenderFace(level, x, y, z, face)) return true;
|
||||
return !(isHalfSlab(level->getTile(x, y, z)) && (level->getData(x, y, z) & TOP_SLOT_BIT) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
int StoneSlabTile::getSpawnResourcesAuxValue(int data) {
|
||||
return data & TYPE_MASK;
|
||||
}
|
||||
56
src/world/level/tile/StoneSlabTile.h
Executable file
56
src/world/level/tile/StoneSlabTile.h
Executable file
@@ -0,0 +1,56 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__StoneSlabTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__StoneSlabTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class Level;
|
||||
class LevelSource;
|
||||
|
||||
class StoneSlabTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
static const int STONE_SLAB = 0;
|
||||
static const int SAND_SLAB = 1;
|
||||
static const int WOOD_SLAB = 2;
|
||||
static const int COBBLESTONE_SLAB = 3;
|
||||
static const int BRICK_SLAB = 4;
|
||||
static const int SMOOTHBRICK_SLAB = 5;
|
||||
|
||||
static const int TYPE_MASK = 7;
|
||||
static const int TOP_SLOT_BIT = 8;
|
||||
|
||||
|
||||
static const std::string SLAB_NAMES[];
|
||||
static const int SLAB_NAMES_COUNT;
|
||||
|
||||
StoneSlabTile(int id, bool fullSize);
|
||||
|
||||
int getTexture(int face, int data);
|
||||
int getTexture(int face);
|
||||
|
||||
bool isSolidRender();
|
||||
bool isCubeShaped();
|
||||
|
||||
void updateShape(LevelSource* level, int x, int y, int z);
|
||||
void updateDefaultShape();
|
||||
|
||||
void addAABBs( Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes );
|
||||
|
||||
//void onPlace(Level* level, int x, int y, int z);
|
||||
int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue);
|
||||
|
||||
int getResource(int data, Random* random);
|
||||
int getResourceCount(Random* random);
|
||||
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face);
|
||||
|
||||
protected:
|
||||
int getSpawnResourcesAuxValue(int data);
|
||||
private:
|
||||
bool fullSize;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__StoneSlabTile_H__*/
|
||||
24
src/world/level/tile/StoneTile.h
Executable file
24
src/world/level/tile/StoneTile.h
Executable file
@@ -0,0 +1,24 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__StoneTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__StoneTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class StoneTile: public Tile
|
||||
{
|
||||
public:
|
||||
StoneTile(int id, int tex)
|
||||
: Tile(id, tex, Material::stone)
|
||||
{
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Tile::stoneBrick->id;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__StoneTile_H__*/
|
||||
32
src/world/level/tile/StonecutterTile.h
Executable file
32
src/world/level/tile/StonecutterTile.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__StonecutterTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__StonecutterTile_H__
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
|
||||
class StonecutterTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
StonecutterTile(int id)
|
||||
: super(id, Material::stone)
|
||||
{
|
||||
tex = 13 + 16 * 2;
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face == Facing::UP) return 9 + 10 * 16;
|
||||
if (face == Facing::DOWN) return 14 + 3 * 16;
|
||||
if (face == Facing::NORTH || face == Facing::SOUTH) return 8 + 10 * 16;
|
||||
return tex;
|
||||
}
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
player->startStonecutting(x, y, z);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__StonecutterTile_H__*/
|
||||
55
src/world/level/tile/TallGrass.cpp
Executable file
55
src/world/level/tile/TallGrass.cpp
Executable file
@@ -0,0 +1,55 @@
|
||||
#include "TallGrass.h"
|
||||
#include "../FoliageColor.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../../item/ShearsItem.h"
|
||||
|
||||
TallGrass::TallGrass( int id, int tex ) : super(id, tex, Material::replaceable_plant) {
|
||||
float ss = 0.4f;
|
||||
setShape(0.5f - ss, 0, 0.5f - ss, 0.5f + ss, 0.8f, 0.5f + ss);
|
||||
}
|
||||
|
||||
int TallGrass::getTexture( int face, int data ) {
|
||||
if(data == TALL_GRASS) return tex;
|
||||
if(data == FERN) return tex + 16 + 1;
|
||||
if(data == DEAD_SHRUB) return tex + 16;
|
||||
return tex;
|
||||
}
|
||||
|
||||
int TallGrass::getColor() {
|
||||
/*double temp = 0.5;
|
||||
double rain = 1.0;
|
||||
return GrassColor.get(temp, rain);*/
|
||||
return 0x339933;
|
||||
}
|
||||
|
||||
int TallGrass::getColor( int auxData ) {
|
||||
if(auxData == DEAD_SHRUB) return 0xffffffff;
|
||||
return FoliageColor::getDefaultColor();
|
||||
}
|
||||
|
||||
int TallGrass::getColor( LevelSource* level, int x, int y, int z ) {
|
||||
int d = level->getData(x, y, z);
|
||||
if (d == DEAD_SHRUB) return 0xffffff;
|
||||
|
||||
return 0x339933;//level->getBiome(x, z)->getGrassColor();
|
||||
}
|
||||
|
||||
int TallGrass::getResource( int data, Random* random ) {
|
||||
if (random->nextInt(8) == 0) {
|
||||
return Item::seeds_wheat->id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TallGrass::playerDestroy( Level* level, Player* player, int x, int y, int z, int data ) {
|
||||
if (!level->isClientSide && player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::shears->id) {
|
||||
//player->awardStat(Stats.blockMined[id], 1);
|
||||
|
||||
// drop leaf block instead of sapling
|
||||
ItemInstance itemInstance(Tile::tallgrass, 1, data);
|
||||
popResource(level, x, y, z, itemInstance);
|
||||
} else {
|
||||
super::playerDestroy(level, player, x, y, z, data);
|
||||
}
|
||||
}
|
||||
24
src/world/level/tile/TallGrass.h
Executable file
24
src/world/level/tile/TallGrass.h
Executable file
@@ -0,0 +1,24 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TallGrass_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TallGrass_H__
|
||||
#include "Bush.h"
|
||||
class Pos;
|
||||
class TallGrass : public Bush {
|
||||
public:
|
||||
typedef Bush super;
|
||||
|
||||
public:
|
||||
static const int DEAD_SHRUB = 0;
|
||||
static const int TALL_GRASS = 1;
|
||||
static const int FERN = 3;
|
||||
|
||||
|
||||
TallGrass(int id, int tex);
|
||||
int getTexture(int face, int data);
|
||||
int getColor();
|
||||
int getColor(int auxData);
|
||||
int getColor(LevelSource* level, int x, int y, int z);
|
||||
int getResource(int data, Random* random);
|
||||
void playerDestroy(Level* level, Player* player, int x, int y, int z, int data);
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__TallGrass_H__ */
|
||||
133
src/world/level/tile/ThinFenceTile.h
Executable file
133
src/world/level/tile/ThinFenceTile.h
Executable file
@@ -0,0 +1,133 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__ThinFenceTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__ThinFenceTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class ThinFenceTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
ThinFenceTile(int id, int tex, int edgeTex, const Material* material, bool dropsResources)
|
||||
: super(id, tex, material),
|
||||
edgeTexture(edgeTex),
|
||||
dropsResources(dropsResources)
|
||||
{
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getResource(int data, Random* random/*, int playerBonusLevel*/) {
|
||||
if (!dropsResources) {
|
||||
return 0;
|
||||
}
|
||||
return super::getResource(data, random/*, playerBonusLevel*/);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_IRON_FENCE;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
int id = level->getTile(x, y, z);
|
||||
if (id == this->id) return false;
|
||||
return super::shouldRenderFace(level, x, y, z, face);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void addAABBs(Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes ) {
|
||||
bool n = attachsTo(level->getTile(x, y, z - 1));
|
||||
bool s = attachsTo(level->getTile(x, y, z + 1));
|
||||
bool w = attachsTo(level->getTile(x - 1, y, z));
|
||||
bool e = attachsTo(level->getTile(x + 1, y, z));
|
||||
|
||||
if ((w && e) || (!w && !e && !n && !s)) {
|
||||
setShape(0, 0, 7.0f / 16.0f, 1, 1, 9.0f / 16.0f);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
} else if (w && !e) {
|
||||
setShape(0, 0, 7.0f / 16.0f, .5f, 1, 9.0f / 16.0f);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
} else if (!w && e) {
|
||||
setShape(.5f, 0, 7.0f / 16.0f, 1, 1, 9.0f / 16.0f);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
}
|
||||
if ((n && s) || (!w && !e && !n && !s)) {
|
||||
setShape(7.0f / 16.0f, 0, 0, 9.0f / 16.0f, 1, 1);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
} else if (n && !s) {
|
||||
setShape(7.0f / 16.0f, 0, 0, 9.0f / 16.0f, 1, .5f);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
} else if (!n && s) {
|
||||
setShape(7.0f / 16.0f, 0, .5f, 9.0f / 16.0f, 1, 1);
|
||||
super::addAABBs(level, x, y, z, box, boxes);
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void updateDefaultShape() {
|
||||
setShape(0, 0, 0, 1, 1, 1);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void updateShape(LevelSource* level, int x, int y, int z) {
|
||||
float minX = 7.0f / 16.0f;
|
||||
float maxX = 9.0f / 16.0f;
|
||||
float minZ = 7.0f / 16.0f;
|
||||
float maxZ = 9.0f / 16.0f;
|
||||
|
||||
bool n = attachsTo(level->getTile(x, y, z - 1));
|
||||
bool s = attachsTo(level->getTile(x, y, z + 1));
|
||||
bool w = attachsTo(level->getTile(x - 1, y, z));
|
||||
bool e = attachsTo(level->getTile(x + 1, y, z));
|
||||
|
||||
if ((w && e) || (!w && !e && !n && !s)) {
|
||||
minX = 0;
|
||||
maxX = 1;
|
||||
} else if (w && !e) {
|
||||
minX = 0;
|
||||
} else if (!w && e) {
|
||||
maxX = 1;
|
||||
}
|
||||
if ((n && s) || (!w && !e && !n && !s)) {
|
||||
minZ = 0;
|
||||
maxZ = 1;
|
||||
} else if (n && !s) {
|
||||
minZ = 0;
|
||||
} else if (!n && s) {
|
||||
maxZ = 1;
|
||||
}
|
||||
|
||||
setShape(minX, 0, minZ, maxX, 1, maxZ);
|
||||
}
|
||||
|
||||
int getEdgeTexture() {
|
||||
return edgeTexture;
|
||||
}
|
||||
|
||||
const bool attachsTo(int tile) {
|
||||
return Tile::solid[tile] || tile == id || tile == Tile::glass->id;
|
||||
}
|
||||
private:
|
||||
int edgeTexture;
|
||||
const bool dropsResources;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__ThinFenceTile_H__*/
|
||||
747
src/world/level/tile/Tile.cpp
Executable file
747
src/world/level/tile/Tile.cpp
Executable file
@@ -0,0 +1,747 @@
|
||||
#include "TileInclude.h"
|
||||
#include "../Level.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../../item/TileItem.h"
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
//#include "locale/Descriptive.h"
|
||||
//#include "stats/Stats.h"
|
||||
#include "../../entity/Entity.h"
|
||||
#include "../LevelSource.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../phys/AABB.h"
|
||||
#include "../../phys/HitResult.h"
|
||||
#include "../../phys/Vec3.h"
|
||||
#include "../../../locale/I18n.h"
|
||||
#include "../../item/ClothTileItem.h"
|
||||
|
||||
#include "../../item/AuxDataTileItem.h"
|
||||
#include "../../item/LeafTileItem.h"
|
||||
#include "../../item/StoneSlabTileItem.h"
|
||||
#include "../../item/SaplingTileItem.h"
|
||||
#include "../../item/ItemCategory.h"
|
||||
|
||||
const int Tile::RENDERLAYER_OPAQUE = 0;
|
||||
const int Tile::RENDERLAYER_ALPHATEST = 1;
|
||||
const int Tile::RENDERLAYER_BLEND = 2;
|
||||
|
||||
const std::string Tile::TILE_DESCRIPTION_PREFIX("tile.");
|
||||
|
||||
const Tile::SoundType Tile::SOUND_NORMAL("stone", 1, 1);
|
||||
const Tile::SoundType Tile::SOUND_WOOD("wood", 1, 1);
|
||||
const Tile::SoundType Tile::SOUND_GRAVEL("gravel", 1, 1);
|
||||
const Tile::SoundType Tile::SOUND_GRASS("grass", 0.5f, 1);
|
||||
const Tile::SoundType Tile::SOUND_STONE("stone", 1, 1);
|
||||
const Tile::SoundType Tile::SOUND_METAL("stone", 1, 1.5f);
|
||||
const Tile::SoundType Tile::SOUND_GLASS("stone", "random.glass", 1, 1);
|
||||
const Tile::SoundType Tile::SOUND_CLOTH("cloth", 1, 1);
|
||||
|
||||
#ifdef PRE_ANDROID23
|
||||
const Tile::SoundType Tile::SOUND_SAND("sand", 0.45f, 1);
|
||||
#else
|
||||
const Tile::SoundType Tile::SOUND_SAND("sand", "step.gravel", 1, 1);
|
||||
#endif
|
||||
|
||||
const Tile::SoundType Tile::SOUND_SILENT("", 0, 0);
|
||||
|
||||
Tile* Tile::tiles[] = {NULL};
|
||||
int Tile::lightBlock[] = {0};
|
||||
int Tile::lightEmission[] = {0};
|
||||
bool Tile::solid[] = {false};
|
||||
bool Tile::isEntityTile[] = {false};
|
||||
bool Tile::translucent[] = {true, false}; // @trans: translucent, @trans "asbMax", some more like "*conditon"
|
||||
bool Tile::shouldTick[] = {false};
|
||||
bool Tile::sendTileData[] = {false};
|
||||
|
||||
Tile* Tile::sand = NULL;
|
||||
Tile* Tile::sandStone = NULL;
|
||||
const int SANDSTONE_TEXTURES[] = { 0 + 16 * 12, 5 + 16 * 14, 6 + 16 * 14 };
|
||||
const int SANDSTONE_TEXTURE_COUNT = 3;
|
||||
|
||||
Tile* Tile::stoneBrick = NULL;
|
||||
Tile* Tile::redBrick = NULL;
|
||||
Tile* Tile::wood = NULL;
|
||||
Tile* Tile::sapling = NULL;
|
||||
Tile* Tile::glass = NULL;
|
||||
Tile* Tile::web = NULL;
|
||||
Tile* Tile::thinGlass = NULL;
|
||||
Tile* Tile::calmWater = NULL;
|
||||
Tile* Tile::calmLava = NULL;
|
||||
Tile* Tile::gravel = NULL;
|
||||
Tile* Tile::rock = NULL;
|
||||
Tile* Tile::unbreakable = NULL;
|
||||
Tile* Tile::dirt = NULL;
|
||||
Tile* Tile::grass = NULL;
|
||||
Tile* Tile::ice = NULL;
|
||||
Tile* Tile::clay = NULL;
|
||||
Tile* Tile::farmland = NULL;
|
||||
Tile* Tile::stoneSlab = NULL;
|
||||
Tile* Tile::stoneSlabHalf=NULL;
|
||||
Tile* Tile::cloth = NULL;
|
||||
Tile* Tile::flower = NULL;
|
||||
Tile* Tile::rose = NULL;
|
||||
Tile* Tile::mushroom1 = NULL;
|
||||
Tile* Tile::mushroom2 = NULL;
|
||||
Tile* Tile::topSnow = NULL;
|
||||
Tile* Tile::treeTrunk = NULL;
|
||||
Tile* Tile::snow = NULL;
|
||||
LeafTile* Tile::leaves = NULL;
|
||||
Tile* Tile::emeraldOre = NULL;
|
||||
Tile* Tile::redStoneOre = NULL;
|
||||
Tile* Tile::redStoneOre_lit = NULL;
|
||||
Tile* Tile::goldOre = NULL;
|
||||
Tile* Tile::ironOre = NULL;
|
||||
Tile* Tile::coalOre = NULL;
|
||||
Tile* Tile::lapisOre = NULL;
|
||||
Tile* Tile::lapisBlock = NULL;
|
||||
Tile* Tile::reeds = NULL;
|
||||
Tile* Tile::ladder = NULL;
|
||||
Tile* Tile::obsidian = NULL;
|
||||
Tile* Tile::tnt = NULL;
|
||||
Tile* Tile::bookshelf = NULL;
|
||||
Tile* Tile::sign = NULL;
|
||||
Tile* Tile::wallSign = NULL;
|
||||
Tile* Tile::mossStone = NULL;
|
||||
Tile* Tile::torch = NULL;
|
||||
Tile* Tile::water = NULL;
|
||||
Tile* Tile::lava = NULL;
|
||||
FireTile* Tile::fire = NULL;
|
||||
Tile* Tile::invisible_bedrock = NULL;
|
||||
Tile* Tile::goldBlock = NULL;
|
||||
Tile* Tile::ironBlock = NULL;
|
||||
Tile* Tile::emeraldBlock= NULL;
|
||||
Tile* Tile::workBench = NULL;
|
||||
Tile* Tile::stonecutterBench = NULL;
|
||||
Tile* Tile::crops = NULL;
|
||||
Tile* Tile::furnace = NULL;
|
||||
Tile* Tile::furnace_lit = NULL;
|
||||
Tile* Tile::chest = NULL;
|
||||
Tile* Tile::lightGem = NULL;
|
||||
Tile* Tile::stairs_wood = NULL;
|
||||
Tile* Tile::stairs_stone= NULL;
|
||||
Tile* Tile::stairs_brick= NULL;
|
||||
Tile* Tile::door_wood = NULL;
|
||||
Tile* Tile::door_iron = NULL;
|
||||
Tile* Tile::cactus = NULL;
|
||||
|
||||
Tile* Tile::melon = NULL;
|
||||
Tile* Tile::melonStem = NULL;
|
||||
|
||||
Tile* Tile::bed = NULL;
|
||||
Tile* Tile::tallgrass = NULL;
|
||||
Tile* Tile::trapdoor = NULL;
|
||||
Tile* Tile::stoneBrickSmooth = NULL;
|
||||
const int STONE_BRICK_TEXTURES[] = { 6 + 16 * 3, 4 + 16 * 6, 5 + 16 * 6 };
|
||||
const int STONE_BRICK_TEXTURE_COUNT = 3;
|
||||
|
||||
Tile* Tile::fence = NULL;
|
||||
Tile* Tile::fenceGate = NULL;
|
||||
|
||||
Tile* Tile::info_updateGame1 = NULL;
|
||||
Tile* Tile::info_updateGame2 = NULL;
|
||||
Tile* Tile::info_reserved6 = NULL;
|
||||
Tile* Tile::grass_carried = NULL;
|
||||
LeafTile* Tile::leaves_carried = NULL;
|
||||
|
||||
Tile* Tile::netherReactor = NULL;
|
||||
Tile* Tile::glowingObsidian = NULL;
|
||||
|
||||
Tile* Tile::stairs_stoneBrickSmooth = NULL;
|
||||
Tile* Tile::netherBrick = NULL;
|
||||
Tile* Tile::netherrack = NULL;
|
||||
Tile* Tile::stairs_netherBricks = NULL;
|
||||
Tile* Tile::stairs_sandStone = NULL;
|
||||
Tile* Tile::quartzBlock = NULL;
|
||||
Tile* Tile::stairs_quartz = NULL;
|
||||
|
||||
/*static*/
|
||||
void Tile::initTiles() {
|
||||
rock = (new StoneTile(1, 1))->init()->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stone");
|
||||
grass = (GrassTile*) (new GrassTile(2))->init()->setDestroyTime(0.6f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("grass");
|
||||
dirt = (new DirtTile(3, 2))->init()->setDestroyTime(0.5f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("dirt");
|
||||
stoneBrick = (new Tile(4, 16, Material::stone))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stonebrick");
|
||||
wood = (new Tile(5, 4, Material::wood))->init()->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("wood");
|
||||
sapling = (new Sapling(6, 15))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("sapling");//->sendTileData();
|
||||
unbreakable = (new Tile(7, 17, Material::stone))->init()->setDestroyTime(-1)->setExplodeable(6000000)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("bedrock");
|
||||
water = (new LiquidTileDynamic(8, Material::water))->init()->setDestroyTime(100.0f)->setLightBlock(3)->setCategory(ItemCategory::Structures)->setDescriptionId("water");
|
||||
calmWater = (new LiquidTileStatic(9, Material::water))->init()->setDestroyTime(100.0f)->setLightBlock(3)->setCategory(ItemCategory::Structures)->setDescriptionId("water");
|
||||
lava = (new LiquidTileDynamic(10, Material::lava))->init()->setDestroyTime(00.0f)->setLightEmission(1.0f)->setLightBlock(255)->setCategory(ItemCategory::Structures)->setDescriptionId("lava"); // 00.0?
|
||||
calmLava = (new LiquidTileStatic(11, Material::lava))->init()->setDestroyTime(100.0f)->setLightEmission(1.0f)->setLightBlock(255)->setCategory(ItemCategory::Structures)->setDescriptionId("lava");
|
||||
sand = (new HeavyTile(12, 18))->init()->setDestroyTime(0.5f)->setSoundType(SOUND_SAND)->setCategory(ItemCategory::Structures)->setDescriptionId("sand");
|
||||
gravel = (new GravelTile(13, 19))->init()->setDestroyTime(0.6f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("gravel");
|
||||
goldOre = (new OreTile(14, 32))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Decorations)->setDescriptionId("oreGold");
|
||||
ironOre = (new OreTile(15, 33))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Decorations)->setDescriptionId("oreIron");
|
||||
coalOre = (new OreTile(16, 34))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("oreCoal");
|
||||
treeTrunk = (new TreeTile(17))->init()->setDestroyTime(2.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("log");
|
||||
leaves = (LeafTile*) (new LeafTile(18, 4 + 3 * 16))->init()->setDestroyTime(0.2f)->setLightBlock(1)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("leaves");
|
||||
|
||||
glass = (new GlassTile(20, 49, Material::glass, false))->init()->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setCategory(ItemCategory::Structures)->setDescriptionId("glass");
|
||||
lapisOre = (new OreTile(21, 10 * 16))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("oreLapis");
|
||||
lapisBlock = (new Tile(22, 9 * 16, Material::stone))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Decorations)->setDescriptionId("blockLapis");
|
||||
sandStone = (new SandStoneTile(24, (const int*)&SANDSTONE_TEXTURES, SANDSTONE_TEXTURE_COUNT))->init()->setSoundType(SOUND_STONE)->setDestroyTime(0.8f)->setCategory(ItemCategory::Structures)->setDescriptionId("sandStone");
|
||||
bed = (new BedTile(26))->init()->setDestroyTime(0.2f)->setCategory(ItemCategory::Structures)->setDescriptionId("bed");
|
||||
web = (new WebTile(30, 11))->init()->setLightBlock(1)->setDestroyTime(4.0f)->setCategory(ItemCategory::Decorations)->setDescriptionId("web");
|
||||
tallgrass = (new TallGrass(31, 2 * 16 + 7))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Decorations)->setDescriptionId("tallgrass");
|
||||
cloth = (new ClothTile(35))->init()->setDestroyTime(0.8f)->setSoundType(SOUND_CLOTH)->setCategory(ItemCategory::Structures)->setDescriptionId("cloth");
|
||||
|
||||
flower = (new Bush(37, 13))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Decorations)->setDescriptionId("flower");
|
||||
rose = (new Bush(38, 12))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Decorations)->setDescriptionId("rose");
|
||||
mushroom1 = (new Mushroom(39, 13 + 16))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setLightEmission(2 / 16.0f)->setCategory(ItemCategory::Decorations)->setDescriptionId("mushroom");
|
||||
mushroom2 = (new Mushroom(40, 12 + 16))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Decorations)->setDescriptionId("mushroom");
|
||||
goldBlock = (new MetalTile(41, 39 - 16))->init()->setDestroyTime(3.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setCategory(ItemCategory::Decorations)->setDescriptionId("blockGold");
|
||||
ironBlock = (new MetalTile(42, 38 - 16))->init()->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setCategory(ItemCategory::Decorations)->setDescriptionId("blockIron");
|
||||
stoneSlab = (new StoneSlabTile(43, true))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stoneSlab");
|
||||
stoneSlabHalf=(new StoneSlabTile(44, false))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stoneSlab");
|
||||
redBrick = (new Tile(45, 7, Material::stone))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("brick");
|
||||
tnt = (new TntTile(46, 8))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Tools)->setDescriptionId("tnt");
|
||||
bookshelf = (new BookshelfTile(47, 35))->init()->setDestroyTime(1.5f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Decorations)->setDescriptionId("bookshelf");
|
||||
mossStone = (new Tile(48, 36, Material::stone))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stoneMoss");
|
||||
obsidian = (new ObsidianTile(49, 37, false))->init()->setDestroyTime(10.0f)->setExplodeable(2000)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("obsidian");
|
||||
torch = (new TorchTile(50, 5 * 16))->init()->setDestroyTime(0.0f)->setLightEmission(15 / 16.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Tools)->setDescriptionId("torch");
|
||||
|
||||
stairs_wood = (new StairTile(53, wood))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsWood");
|
||||
chest = (new ChestTile(54))->init()->setCategory(ItemCategory::Structures)->setDestroyTime(2.5f)->setSoundType(SOUND_WOOD)->setDescriptionId("chest");//->sendTileData();
|
||||
|
||||
emeraldOre = (new OreTile(56, 16 * 3 + 2))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Decorations)->setDescriptionId("oreDiamond");
|
||||
emeraldBlock= (new MetalTile(57, 40 - 16))->init()->setDestroyTime(5.0f)->setExplodeable(10)->setSoundType(SOUND_METAL)->setCategory(ItemCategory::Decorations)->setDescriptionId("blockDiamond");
|
||||
workBench = (new WorkbenchTile(58))->init()->setDestroyTime(2.5f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("workbench");
|
||||
crops = (new CropTile(59, 8 + 5 * 16))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("crops");//->sendTileData();
|
||||
farmland = (new FarmTile(60))->init()->setDestroyTime(0.6f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("farmland");
|
||||
furnace = (new FurnaceTile(61, false))->init()->setDestroyTime(3.5f)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("furnace");//.sendTileData();
|
||||
furnace_lit = (new FurnaceTile(62, true))->init()->setDestroyTime(3.5f)->setSoundType(SOUND_STONE)->setLightEmission(14 / 16.0f)->setCategory(ItemCategory::Structures)->setDescriptionId("furnace");//.sendTileData();
|
||||
sign = (new SignTile(63, TileEntityType::Sign, true))->init()->setDestroyTime(1.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Decorations)->setDescriptionId("sign");//->sendTileData();
|
||||
door_wood = (new DoorTile(64, Material::wood))->init()->setDestroyTime(3.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("doorWood");
|
||||
ladder = (new LadderTile(65, 3 + 5 * 16))->init()->setDestroyTime(0.4f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("ladder");
|
||||
|
||||
stairs_stone= (new StairTile(67, stoneBrick))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsStone");
|
||||
wallSign = (new SignTile(68, TileEntityType::Sign, false))->init()->setDestroyTime(1.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Decorations)->setDescriptionId("sign");//->sendTileData();
|
||||
|
||||
door_iron = (new DoorTile(71, Material::metal))->init()->setDestroyTime(5.0f)->setSoundType(SOUND_METAL)->setCategory(ItemCategory::Structures)->setDescriptionId("doorIron");
|
||||
|
||||
redStoneOre = (new RedStoneOreTile(73, 16 * 3 + 3, false))->init()->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("oreRedstone");
|
||||
redStoneOre_lit = (new RedStoneOreTile(74, 16 * 3 + 3, true))->init()->setDestroyTime(3.0f)->setLightEmission(10 / 16.0f)->setExplodeable(5)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("oreRedstone");
|
||||
|
||||
topSnow = (new TopSnowTile(78, 16 * 4 + 2))->init()->setDestroyTime(0.1f)->setSoundType(SOUND_CLOTH)->setCategory(ItemCategory::Structures)->setDescriptionId("snow");
|
||||
ice = (new IceTile(79, 16 * 4 + 3))->init()->setDestroyTime(0.5f)->setLightBlock(3)->setSoundType(SOUND_GLASS)->setCategory(ItemCategory::Structures)->setDescriptionId("ice");
|
||||
snow = (new SnowTile(80, 16 * 4 + 2))->init()->setDestroyTime(0.2f)->setSoundType(SOUND_CLOTH)->setCategory(ItemCategory::Structures)->setDescriptionId("snow");
|
||||
cactus = (new CactusTile(81, 16 * 4 + 6))->init()->setDestroyTime(0.4f)->setSoundType(SOUND_CLOTH)->setCategory(ItemCategory::Structures)->setDescriptionId("cactus");
|
||||
clay = (new ClayTile(82, 16 * 4 + 8))->init()->setDestroyTime(0.6f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("clay");
|
||||
reeds = (new ReedTile(83, 16 * 4 + 9))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("reeds");
|
||||
|
||||
fence = (new FenceTile(85, 4))->init()->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("fence");
|
||||
|
||||
netherrack = (new Tile(87, 7 + 6 * 16, Material::stone))->init()->setDestroyTime(0.4f)->setSoundType(SOUND_STONE)->setDescriptionId("hellrock");
|
||||
//hellSand = (new HellSandTile(88, 8 + 6 * 16, Material::sand))->init()->setDestroyTime(0.5f)->setSoundType(SOUND_SAND)->setDescriptionId("hellsand");
|
||||
|
||||
lightGem = (new LightGemTile(89, 9 + 16 * 6, Material::glass))->init()->setDestroyTime(0.3f)->setCategory(ItemCategory::Structures)->setSoundType(SOUND_GLASS)->setLightEmission(1.0f)->setDescriptionId("lightgem");
|
||||
invisible_bedrock = (new InvisibleTile(95, 0, Material::stone))->init()->setDestroyTime(-1)->setExplodeable(6000000);//->setSoundType(SOUND_SILENT);
|
||||
trapdoor = (new TrapDoorTile(96, Material::wood))->init()->setDestroyTime(3.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("trapdoor");//->sendTileData();
|
||||
|
||||
stoneBrickSmooth = (new MultiTextureTile(98, (const int*)&STONE_BRICK_TEXTURES, STONE_BRICK_TEXTURE_COUNT, Material::stone))->init()->setDestroyTime(1.5f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stonebricksmooth");
|
||||
|
||||
thinGlass = (new ThinFenceTile(102, 1 + 3 * 16, 4 + 9 * 16, Material::glass, false))->init()->setDestroyTime(0.3f)->setSoundType(SOUND_GLASS)->setCategory(ItemCategory::Structures)->setDescriptionId("thinGlass");
|
||||
melon = (new MelonTile(103))->init()->setDestroyTime(1.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("melon");
|
||||
melonStem = (new StemTile(105, Tile::melon))->init()->setDestroyTime(0.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("pumpkinStem");//->sendTileData();
|
||||
fenceGate = (new FenceGateTile(107, 4))->init()->setDestroyTime(2.0f)->setExplodeable(5)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("fenceGate");//->sendTileData();
|
||||
stairs_brick = (new StairTile(108, Tile::redBrick))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsBrick");//->sendTileData();
|
||||
|
||||
stairs_stoneBrickSmooth = (new StairTile(109, Tile::stoneBrickSmooth))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsStoneBrickSmooth");//->sendTileData();
|
||||
netherBrick = (new Tile(112, 0 + 14 * 16, Material::stone))->init()->setDestroyTime(2.0f)->setExplodeable(10)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("netherBrick");
|
||||
stairs_netherBricks = (new StairTile(114, Tile::netherBrick))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsNetherBrick");//->sendTileData();
|
||||
stairs_sandStone = (new StairTile(128, Tile::sandStone))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsSandStone");//->sendTileData();
|
||||
|
||||
quartzBlock = (new QuartzBlockTile(155))->init()->setSoundType(SOUND_STONE)->setDestroyTime(0.8f)->setCategory(ItemCategory::Structures)->setDescriptionId("quartzBlock");
|
||||
stairs_quartz = (new StairTile(156, Tile::quartzBlock))->init()->setCategory(ItemCategory::Structures)->setDescriptionId("stairsQuartz");//->sendTileData();
|
||||
|
||||
//
|
||||
// Special tiles for Pocket Edition is placed at high IDs
|
||||
//
|
||||
stonecutterBench= (new StonecutterTile(245))->init()->setDestroyTime(2.5f)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("stonecutter");
|
||||
glowingObsidian = (new ObsidianTile(246, 10 + 16 * 13, true))->init()->setDestroyTime(10.0f)->setLightEmission(14 / 16.0f)->setExplodeable(2000)->setSoundType(SOUND_STONE)->setCategory(ItemCategory::Structures)->setDescriptionId("glowingobsidian");
|
||||
netherReactor = (new NetherReactor(247, 10 + 14 * 16, Material::metal))->init()->setDestroyTime(3.0f)->setSoundType(SOUND_METAL)->setCategory(ItemCategory::Structures)->setDescriptionId("netherreactor");
|
||||
info_updateGame1= (new Tile(248, 252, Material::dirt))->init()->setDestroyTime(1.0f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("info_update");
|
||||
info_updateGame2= (new Tile(249, 253, Material::dirt))->init()->setDestroyTime(1.0f)->setSoundType(SOUND_GRAVEL)->setCategory(ItemCategory::Structures)->setDescriptionId("info_update");
|
||||
grass_carried = (new CarriedTile(253, 3, 12*16 + 12))->init()->setDescriptionId("grass");
|
||||
leaves_carried = (LeafTile*) (new LeafTile(254, 11 + 14 * 16))->init()->setDestroyTime(0.2f)->setLightBlock(1)->setSoundType(SOUND_GRASS)->setCategory(ItemCategory::Structures)->setDescriptionId("leaves");
|
||||
info_reserved6 = (new Tile(255, Material::dirt))->init();
|
||||
|
||||
//
|
||||
// Stuff that need to be inited in a specific order (i.e. after the other tiles have been created)
|
||||
//
|
||||
fire = (FireTile*) (new FireTile(51, 1 * 16 + 15))->init()->setDestroyTime(0.0f)->setLightEmission(1.0f)->setSoundType(SOUND_WOOD)->setCategory(ItemCategory::Structures)->setDescriptionId("fire");
|
||||
|
||||
//
|
||||
// Special case for certain items since they can have different icons
|
||||
// @note: Make sure those different items are handled in ItemInHandRenderer::renderItem
|
||||
//
|
||||
Item::items[cloth->id] = (new ClothTileItem(cloth->id - 256))->setCategory(ItemCategory::Structures)->setDescriptionId("cloth");
|
||||
Item::items[treeTrunk->id] = (new AuxDataTileItem(treeTrunk->id - 256, treeTrunk))->setCategory(ItemCategory::Structures)->setDescriptionId("log");
|
||||
Item::items[stoneBrickSmooth->id] = (new AuxDataTileItem(stoneBrickSmooth->id - 256, stoneBrickSmooth))->setCategory(ItemCategory::Structures)->setDescriptionId("stonebricksmooth");
|
||||
Item::items[stoneSlabHalf->id] = (new StoneSlabTileItem(stoneSlabHalf->id - 256))->setCategory(ItemCategory::Structures)->setDescriptionId("stoneSlab");
|
||||
Item::items[sapling->id] = (new SaplingTileItem(sapling->id - 256))->setCategory(ItemCategory::Structures)->setDescriptionId("sapling");
|
||||
Item::items[leaves->id] = (new LeafTileItem(leaves->id - 256))->setCategory(ItemCategory::Decorations)->setDescriptionId("leaves");
|
||||
Item::items[sandStone->id] = (new AuxDataTileItem(sandStone->id - 256, sandStone))->setCategory(ItemCategory::Structures)->setDescriptionId("sandStone");
|
||||
|
||||
Item::items[quartzBlock->id] = (new AuxDataTileItem(quartzBlock->id - 256, quartzBlock))->setCategory(ItemCategory::Structures)->setDescriptionId("quartzBlock");
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (Tile::tiles[i] != NULL) {
|
||||
if (Item::items[i] == NULL) {
|
||||
Item::items[i] = new TileItem(i - 256);
|
||||
Item::items[i]->category = Tile::tiles[i]->category;
|
||||
}
|
||||
// Check for missing category
|
||||
if (Item::items[i]->category == -1)
|
||||
LOGE("Error: Missing category for tile %d: %s\n", tiles[i]->id, tiles[i]->getDescriptionId().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void Tile::teardownTiles() {
|
||||
for (int i = 0; i < 256; ++i)
|
||||
if (Tile::tiles[i]) {
|
||||
delete Tile::tiles[i];
|
||||
Tile::tiles[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Tile::transformToValidBlockId( int blockId ) {
|
||||
return transformToValidBlockId(blockId, 0, 0, 0);
|
||||
}
|
||||
|
||||
int Tile::transformToValidBlockId( int blockId, int x, int y, int z ) {
|
||||
if (blockId != 0 && Tile::tiles[blockId] == NULL)
|
||||
return (((x + y + z)&1) == 1)? Tile::info_updateGame1->id : Tile::info_updateGame2->id;
|
||||
return blockId;
|
||||
}
|
||||
|
||||
|
||||
Tile::Tile(int id, const Material* material)
|
||||
: id(id),
|
||||
material(material),
|
||||
tex(1),
|
||||
category(-1),
|
||||
gravity(1.0f),
|
||||
friction(0.6f),
|
||||
soundType(&Tile::SOUND_NORMAL),
|
||||
tmpBB(0,0,0,1,1,1),
|
||||
xx0(0),yy0(0),zz0(0),
|
||||
xx1(1),yy1(1),zz1(1)
|
||||
{
|
||||
if (Tile::tiles[id]) {
|
||||
printf("Slot %d is already occupied by %p when adding %p\n", id, &Tile::tiles[id], this);
|
||||
}
|
||||
}
|
||||
|
||||
Tile::Tile( int id, int tex, const Material* material )
|
||||
: id(id),
|
||||
tex(tex),
|
||||
material(material),
|
||||
category(-1),
|
||||
gravity(1.0f),
|
||||
friction(0.6f),
|
||||
soundType(&Tile::SOUND_NORMAL),
|
||||
tmpBB(0,0,0,1,1,1),
|
||||
xx0(0),yy0(0),zz0(0),
|
||||
xx1(1),yy1(1),zz1(1)
|
||||
{
|
||||
if (Tile::tiles[id]) {
|
||||
printf("Slot %d is already occupied by %p when adding %p\n", id, &Tile::tiles[id], this);
|
||||
}
|
||||
}
|
||||
|
||||
//Tile* sendTileData() {
|
||||
// Tile::sendTileData[id] = true;
|
||||
// return this;
|
||||
//}
|
||||
|
||||
/*protected*/
|
||||
Tile* Tile::setLightEmission(float f) {
|
||||
Tile::lightEmission[id] = (int) (Level::MAX_BRIGHTNESS * f);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*public static*/
|
||||
bool Tile::isFaceVisible(Level* level, int x, int y, int z, int f) {
|
||||
switch (f) {
|
||||
case Facing::DOWN : y--; break;
|
||||
case Facing::UP : y++; break;
|
||||
case Facing::NORTH: z--; break;
|
||||
case Facing::SOUTH: z++; break;
|
||||
case Facing::WEST : x--; break;
|
||||
case Facing::EAST : x++; break;
|
||||
}
|
||||
return !level->isSolidRenderTile(x, y, z);
|
||||
}
|
||||
|
||||
/* private */
|
||||
Tile* Tile::init() {
|
||||
Tile::tiles[id] = this;
|
||||
setShape(xx0, yy0, zz0, xx1, yy1, zz1); // @attn
|
||||
solid[id] = isSolidRender();
|
||||
lightBlock[id] = isSolidRender() ? 255 : 0;
|
||||
translucent[id] = !material->blocksLight();
|
||||
return this;
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
float Tile::getDestroyProgress(Player* player) {
|
||||
if (destroySpeed < 0) return 0;
|
||||
if (!player->canDestroy(this)) return 1 / destroySpeed / 100.0f;
|
||||
return (player->getDestroySpeed(this) / destroySpeed) / 30.0f;
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
HitResult Tile::clip(Level* level, int xt, int yt, int zt, const Vec3& A, const Vec3& B) {
|
||||
updateShape(level, xt, yt, zt);
|
||||
|
||||
//Stopwatch sw;
|
||||
//sw.start();
|
||||
|
||||
Vec3 sub((float)xt, (float)yt, (float)zt);
|
||||
Vec3 a = A - sub;//a.add((float)-xt, (float)-yt, (float)-zt);
|
||||
Vec3 b = B - sub;//b.add((float)-xt, (float)-yt, (float)-zt);
|
||||
|
||||
Vec3 xh0, xh1, yh0, yh1, zh0, zh1;
|
||||
|
||||
bool bxh0 = a.clipX(b, xx0, xh0);
|
||||
bool bxh1 = a.clipX(b, xx1, xh1);
|
||||
|
||||
bool byh0 = a.clipY(b, yy0, yh0);
|
||||
bool byh1 = a.clipY(b, yy1, yh1);
|
||||
|
||||
bool bzh0 = a.clipZ(b, zz0, zh0);
|
||||
bool bzh1 = a.clipZ(b, zz1, zh1);
|
||||
|
||||
//if (!containsX(xh0)) xh0 = NULL;
|
||||
if (!bxh0 || !containsX(xh0)) bxh0 = false;
|
||||
if (!bxh1 || !containsX(xh1)) bxh1 = false;
|
||||
if (!byh0 || !containsY(yh0)) byh0 = false;
|
||||
if (!byh1 || !containsY(yh1)) byh1 = false;
|
||||
if (!bzh0 || !containsZ(zh0)) bzh0 = false;
|
||||
if (!bzh1 || !containsZ(zh1)) bzh1 = false;
|
||||
Vec3* closest = NULL;
|
||||
|
||||
//if (xh0 != NULL && (closest == NULL || a.distanceToSqr(xh0) < a.distanceToSqr(closest))) closest = xh0;
|
||||
if (bxh0 && (closest == NULL || a.distanceToSqr(xh0) < a.distanceToSqr(*closest))) closest = &xh0;
|
||||
if (bxh1 && (closest == NULL || a.distanceToSqr(xh1) < a.distanceToSqr(*closest))) closest = &xh1;
|
||||
if (byh0 && (closest == NULL || a.distanceToSqr(yh0) < a.distanceToSqr(*closest))) closest = &yh0;
|
||||
if (byh1 && (closest == NULL || a.distanceToSqr(yh1) < a.distanceToSqr(*closest))) closest = &yh1;
|
||||
if (bzh0 && (closest == NULL || a.distanceToSqr(zh0) < a.distanceToSqr(*closest))) closest = &zh0;
|
||||
if (bzh1 && (closest == NULL || a.distanceToSqr(zh1) < a.distanceToSqr(*closest))) closest = &zh1;
|
||||
|
||||
if (closest == NULL)
|
||||
return HitResult();
|
||||
|
||||
int face = -1;
|
||||
|
||||
if (closest == &xh0) face = 4;
|
||||
if (closest == &xh1) face = 5;
|
||||
if (closest == &yh0) face = 0;
|
||||
if (closest == &yh1) face = 1;
|
||||
if (closest == &zh0) face = 2;
|
||||
if (closest == &zh1) face = 3;
|
||||
|
||||
//sw.stop();
|
||||
//sw.printEvery(5, ">>> ");
|
||||
|
||||
return HitResult(xt, yt, zt, face, closest->add((float)xt, (float)yt, (float)zt));
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void Tile::spawnResources(Level* level, int x, int y, int z, int data, float odds) {
|
||||
if (level->isClientSide) return;
|
||||
|
||||
int count = getResourceCount(&level->random);
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (level->random.nextFloat() > odds) continue;
|
||||
int type = getResource(data, &level->random);
|
||||
if (type <= 0) continue;
|
||||
const float s = 0.7f;
|
||||
float xo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float yo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float zo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
ItemEntity* item = new ItemEntity(level, x + xo, y + yo, z + zo, ItemInstance(type, 1, getSpawnResourcesAuxValue(data)));
|
||||
item->throwTime = 10;
|
||||
level->addEntity(item);
|
||||
}
|
||||
}
|
||||
|
||||
void Tile::spawnResources( Level* level, int x, int y, int z, int data )
|
||||
{
|
||||
spawnResources(level, x, y, z, data, 1);
|
||||
}
|
||||
|
||||
void Tile::popResource(Level* level, int x, int y, int z, const ItemInstance& itemInstance) {
|
||||
if (level->isClientSide || level->getLevelData()->getGameType() == GameType::Creative) return;
|
||||
|
||||
float s = 0.7f;
|
||||
float xo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float yo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float zo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
|
||||
ItemEntity* item = new ItemEntity(level, x + xo, y + yo, z + zo, itemInstance);
|
||||
item->throwTime = 10;
|
||||
level->addEntity(item);
|
||||
}
|
||||
|
||||
|
||||
void Tile::destroy( Level* level, int x, int y, int z, int data )
|
||||
{
|
||||
}
|
||||
|
||||
bool Tile::isCubeShaped()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Tile::getRenderShape()
|
||||
{
|
||||
return SHAPE_BLOCK;
|
||||
}
|
||||
|
||||
float Tile::getBrightness( LevelSource* level, int x, int y, int z )
|
||||
{
|
||||
return level->getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
bool Tile::shouldRenderFace( LevelSource* level, int x, int y, int z, int face )
|
||||
{
|
||||
if (face == 0 && y == -1) return false;
|
||||
// For fixed size worlds //@todo: external constants rather than magic numbers
|
||||
if (face == 2 && z == -1) return false;
|
||||
if (face == 3 && z == 256) return false;
|
||||
if (face == 4 && x == -1) return false;
|
||||
if (face == 5 && x == 256) return false;
|
||||
// Common
|
||||
if (face == 0 && yy0 > 0) return true;
|
||||
if (face == 1 && yy1 < 1) return true;
|
||||
if (face == 2 && zz0 > 0) return true;
|
||||
if (face == 3 && zz1 < 1) return true;
|
||||
if (face == 4 && xx0 > 0) return true;
|
||||
if (face == 5 && xx1 < 1) return true;
|
||||
Tile* t = Tile::tiles[level->getTile(x, y, z)];
|
||||
if (!t) return true;
|
||||
if (face == 1 && t->id == topSnow->id) return false;
|
||||
return !t->isSolidRender();
|
||||
//return (!level->isSolidRenderTile(x, y, z));
|
||||
}
|
||||
|
||||
int Tile::getTexture( LevelSource* level, int x, int y, int z, int face )
|
||||
{
|
||||
return getTexture(face, level->getData(x, y, z));
|
||||
}
|
||||
|
||||
int Tile::getTexture( int face, int data )
|
||||
{
|
||||
return getTexture(face);
|
||||
}
|
||||
|
||||
int Tile::getTexture( int face )
|
||||
{
|
||||
return tex;
|
||||
}
|
||||
|
||||
void Tile::addAABBs( Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes )
|
||||
{
|
||||
AABB* aabb = getAABB(level, x, y, z);
|
||||
if (aabb != NULL && box->intersects(*aabb)) {
|
||||
boxes.push_back(*aabb);
|
||||
}
|
||||
}
|
||||
|
||||
AABB* Tile::getAABB( Level* level, int x, int y, int z )
|
||||
{
|
||||
tmpBB.x0 = x + xx0;
|
||||
tmpBB.y0 = y + yy0;
|
||||
tmpBB.z0 = z + zz0;
|
||||
tmpBB.x1 = x + xx1;
|
||||
tmpBB.y1 = y + yy1;
|
||||
tmpBB.z1 = z + zz1;
|
||||
return &tmpBB;
|
||||
}
|
||||
|
||||
bool Tile::isSolidRender()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tile::mayPick( int data, bool liquid )
|
||||
{
|
||||
return mayPick();
|
||||
}
|
||||
|
||||
bool Tile::mayPick()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int Tile::getTickDelay()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
int Tile::getResourceCount( Random* random )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Tile::getResource( int data, Random* random )
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
float Tile::getExplosionResistance( Entity* source )
|
||||
{
|
||||
return explosionResistance / 5.0f;
|
||||
}
|
||||
|
||||
int Tile::getRenderLayer()
|
||||
{
|
||||
return Tile::RENDERLAYER_OPAQUE;
|
||||
}
|
||||
|
||||
bool Tile::use( Level* level, int x, int y, int z, Player* player )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::spawnBurnResources( Level* level, float x, float y, float z )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Tile::getColor( LevelSource* level, int x, int y, int z )
|
||||
{
|
||||
return 0xffffff;
|
||||
}
|
||||
|
||||
bool Tile::getSignal( LevelSource* level, int x, int y, int z )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::getSignal( LevelSource* level, int x, int y, int z, int dir )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::isSignalSource()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tile::getDirectSignal( Level* level, int x, int y, int z, int dir )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Tile::playerDestroy( Level* level, Player* player, int x, int y, int z, int data )
|
||||
{
|
||||
//player.awardStat(Stats.blockMined[id], 1);
|
||||
spawnResources(level, x, y, z, data);
|
||||
}
|
||||
|
||||
bool Tile::canSurvive( Level* level, int x, int y, int z )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Tile* Tile::setDescriptionId( const std::string& id )
|
||||
{
|
||||
descriptionId = TILE_DESCRIPTION_PREFIX + id;
|
||||
return this;
|
||||
}
|
||||
|
||||
std::string Tile::getName() const
|
||||
{
|
||||
return I18n::get(getDescriptionId() + ".name");
|
||||
}
|
||||
|
||||
std::string Tile::getDescriptionId() const
|
||||
{
|
||||
return descriptionId;
|
||||
}
|
||||
|
||||
Tile* Tile::setSoundType( const SoundType& soundType )
|
||||
{
|
||||
this->soundType = &soundType;
|
||||
return this;
|
||||
}
|
||||
|
||||
Tile* Tile::setLightBlock( int i )
|
||||
{
|
||||
lightBlock[id] = i;
|
||||
return this;
|
||||
}
|
||||
|
||||
Tile* Tile::setExplodeable( float explosionResistance )
|
||||
{
|
||||
this->explosionResistance = explosionResistance * 3;
|
||||
return this;
|
||||
}
|
||||
|
||||
Tile* Tile::setDestroyTime( float destroySpeed )
|
||||
{
|
||||
this->destroySpeed = destroySpeed;
|
||||
if (explosionResistance < destroySpeed * 5) explosionResistance = destroySpeed * 5;
|
||||
return this;
|
||||
}
|
||||
|
||||
void Tile::setTicking( bool tick )
|
||||
{
|
||||
shouldTick[id] = tick;
|
||||
}
|
||||
|
||||
int Tile::getSpawnResourcesAuxValue( int data )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Tile::containsX( const Vec3& v )
|
||||
{
|
||||
return v.y >= yy0 && v.y <= yy1 && v.z >= zz0 && v.z <= zz1;
|
||||
}
|
||||
|
||||
bool Tile::containsY( const Vec3& v )
|
||||
{
|
||||
return v.x >= xx0 && v.x <= xx1 && v.z >= zz0 && v.z <= zz1;
|
||||
}
|
||||
|
||||
bool Tile::containsZ( const Vec3& v )
|
||||
{
|
||||
return v.x >= xx0 && v.x <= xx1 && v.y >= yy0 && v.y <= yy1;
|
||||
}
|
||||
|
||||
/*public*/
|
||||
AABB Tile::getTileAABB(Level* level, int x, int y, int z) {
|
||||
return AABB(x + xx0, y + yy0, z + zz0, x + xx1, y + yy1, z + zz1);
|
||||
}
|
||||
|
||||
/*public*/
|
||||
void Tile::setShape(float x0, float y0, float z0, float x1, float y1, float z1) {
|
||||
this->xx0 = x0;
|
||||
this->yy0 = y0;
|
||||
this->zz0 = z0;
|
||||
this->xx1 = x1;
|
||||
this->yy1 = y1;
|
||||
this->zz1 = z1;
|
||||
}
|
||||
|
||||
/*public*/
|
||||
bool Tile::mayPlace(Level* level, int x, int y, int z, unsigned char face) {
|
||||
return mayPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
bool Tile::mayPlace( Level* level, int x, int y, int z ) {
|
||||
int t = level->getTile(x, y, z);
|
||||
return t == 0 || Tile::tiles[t]->material->isReplaceable();
|
||||
}
|
||||
|
||||
Tile* Tile::setCategory(int category) {
|
||||
this->category = category;
|
||||
return this;
|
||||
}
|
||||
389
src/world/level/tile/Tile.h
Executable file
389
src/world/level/tile/Tile.h
Executable file
@@ -0,0 +1,389 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__Tile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__Tile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include <string>
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class Entity;
|
||||
class Mob;
|
||||
class Player;
|
||||
class Level;
|
||||
class LevelSource;
|
||||
class Material;
|
||||
class Random;
|
||||
class ItemInstance;
|
||||
|
||||
class Bush;
|
||||
class GrassTile;
|
||||
class LeafTile;
|
||||
class FireTile;
|
||||
|
||||
// @Note: Got a memory leak in initTiles? You probably didn't call
|
||||
// Tile::init after constructing the tile!
|
||||
class Tile
|
||||
{
|
||||
static const std::string TILE_DESCRIPTION_PREFIX;
|
||||
|
||||
public:
|
||||
class SoundType
|
||||
{
|
||||
public:
|
||||
//const std::string name;
|
||||
const float volume;
|
||||
const float pitch;
|
||||
const std::string breakSound;
|
||||
const std::string stepSound;
|
||||
|
||||
SoundType(const std::string& name, float volume, float pitch)
|
||||
: volume(volume),
|
||||
pitch(pitch),
|
||||
breakSound("step." + name),
|
||||
stepSound("step." + name)
|
||||
{}
|
||||
SoundType(const std::string& name, const std::string& breakSound, float volume, float pitch)
|
||||
: volume(volume),
|
||||
pitch(pitch),
|
||||
stepSound("step." + name),
|
||||
breakSound(breakSound)
|
||||
{}
|
||||
|
||||
float getVolume() const {
|
||||
return volume;
|
||||
}
|
||||
|
||||
float getPitch() const {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
const std::string& getBreakSound() const {
|
||||
return breakSound;
|
||||
}
|
||||
|
||||
const std::string& getStepSound() const {
|
||||
return stepSound;
|
||||
}
|
||||
};
|
||||
|
||||
static const SoundType SOUND_NORMAL;
|
||||
static const SoundType SOUND_WOOD;
|
||||
static const SoundType SOUND_GRAVEL;
|
||||
static const SoundType SOUND_GRASS;
|
||||
static const SoundType SOUND_STONE;
|
||||
static const SoundType SOUND_METAL;
|
||||
static const SoundType SOUND_GLASS;
|
||||
static const SoundType SOUND_CLOTH;
|
||||
static const SoundType SOUND_SAND;
|
||||
static const SoundType SOUND_SILENT;
|
||||
|
||||
static const int SHAPE_INVISIBLE = -1;
|
||||
static const int SHAPE_BLOCK = 0;
|
||||
static const int SHAPE_CROSS_TEXTURE = 1;
|
||||
static const int SHAPE_TORCH = 2;
|
||||
static const int SHAPE_FIRE = 3;
|
||||
static const int SHAPE_WATER = 4;
|
||||
static const int SHAPE_RED_DUST = 5;
|
||||
static const int SHAPE_ROWS = 6;
|
||||
static const int SHAPE_DOOR = 7;
|
||||
static const int SHAPE_LADDER = 8;
|
||||
static const int SHAPE_RAIL = 9;
|
||||
static const int SHAPE_STAIRS = 10;
|
||||
static const int SHAPE_FENCE = 11;
|
||||
static const int SHAPE_LEVER = 12;
|
||||
static const int SHAPE_CACTUS = 13;
|
||||
static const int SHAPE_BED = 14;
|
||||
static const int SHAPE_DIODE = 15;
|
||||
static const int SHAPE_IRON_FENCE = 18;
|
||||
static const int SHAPE_STEM = 19;
|
||||
static const int SHAPE_FENCE_GATE = 21;
|
||||
static const int SHAPE_ENTITYTILE_ANIMATED = 22;
|
||||
|
||||
|
||||
static const int NUM_BLOCK_TYPES = 256;
|
||||
|
||||
static Tile* tiles[NUM_BLOCK_TYPES];
|
||||
|
||||
static bool sendTileData[NUM_BLOCK_TYPES];
|
||||
static bool shouldTick[NUM_BLOCK_TYPES];
|
||||
static bool solid[NUM_BLOCK_TYPES];
|
||||
static bool isEntityTile[NUM_BLOCK_TYPES];
|
||||
static int lightBlock[NUM_BLOCK_TYPES];
|
||||
static bool translucent[NUM_BLOCK_TYPES];
|
||||
static int lightEmission[NUM_BLOCK_TYPES];
|
||||
|
||||
static Tile* rock;
|
||||
static Tile* grass;
|
||||
static Tile* dirt;
|
||||
static Tile* stoneBrick;
|
||||
static Tile* wood;
|
||||
static Tile* sapling;
|
||||
static Tile* unbreakable;
|
||||
static Tile* water;
|
||||
static Tile* calmWater;
|
||||
static Tile* lava;
|
||||
static Tile* calmLava;
|
||||
static Tile* sand;
|
||||
static Tile* gravel;
|
||||
static Tile* goldOre;
|
||||
static Tile* ironOre;
|
||||
static Tile* coalOre;
|
||||
static Tile* treeTrunk;
|
||||
static LeafTile* leaves;
|
||||
static Tile* sponge;
|
||||
static Tile* web;
|
||||
static Tile* glass;
|
||||
static Tile* thinGlass;
|
||||
static Tile* lapisOre;
|
||||
static Tile* lapisBlock;
|
||||
static Tile* dispenser;
|
||||
static Tile* sandStone;
|
||||
static Tile* musicBlock;
|
||||
static Tile* bed;
|
||||
static Tile* unused_27;
|
||||
static Tile* unused_28;
|
||||
static Tile* unused_29;
|
||||
static Tile* unused_30;
|
||||
static Tile* tallgrass;
|
||||
static Tile* unused_32;
|
||||
static Tile* unused_33;
|
||||
static Tile* unused_34;
|
||||
static Tile* unused_36;
|
||||
|
||||
static Tile* cloth;
|
||||
static Tile* flower;
|
||||
static Tile* rose;
|
||||
static Tile* mushroom1;
|
||||
static Tile* mushroom2;
|
||||
static Tile* goldBlock;
|
||||
static Tile* ironBlock;
|
||||
static Tile* stoneSlab;
|
||||
static Tile* stoneSlabHalf;
|
||||
static Tile* redBrick;
|
||||
static Tile* tnt;
|
||||
static Tile* bookshelf;
|
||||
static Tile* mossStone;
|
||||
static Tile* obsidian;
|
||||
static Tile* torch;
|
||||
static FireTile* fire;
|
||||
static Tile* mobSpawner;
|
||||
static Tile* stairs_wood;
|
||||
static Tile* chest;
|
||||
static Tile* redStoneDust;
|
||||
static Tile* emeraldOre;
|
||||
static Tile* emeraldBlock;
|
||||
static Tile* workBench;
|
||||
static Tile* stonecutterBench;
|
||||
static Tile* crops;
|
||||
static Tile* farmland;
|
||||
static Tile* furnace;
|
||||
static Tile* furnace_lit;
|
||||
static Tile* sign;
|
||||
static Tile* door_wood;
|
||||
static Tile* ladder;
|
||||
static Tile* rail;
|
||||
static Tile* stairs_stone;
|
||||
static Tile* wallSign;
|
||||
static Tile* lever;
|
||||
static Tile* pressurePlate_stone;
|
||||
static Tile* door_iron;
|
||||
static Tile* pressurePlate_wood;
|
||||
static Tile* redStoneOre;
|
||||
static Tile* redStoneOre_lit;
|
||||
static Tile* notGate_off;
|
||||
static Tile* notGate_on;
|
||||
static Tile* button;
|
||||
static Tile* topSnow;
|
||||
static Tile* ice;
|
||||
static Tile* snow;
|
||||
static Tile* cactus;
|
||||
static Tile* clay;
|
||||
static Tile* reeds;
|
||||
static Tile* recordPlayer;
|
||||
static Tile* fence;
|
||||
static Tile* stairs_brick;
|
||||
static Tile* fenceGate;
|
||||
static Tile* pumpkin;
|
||||
static Tile* hellRock;
|
||||
static Tile* hellSand;
|
||||
static Tile* lightGem;
|
||||
static Tile* portalTile;
|
||||
static Tile* litPumpkin;
|
||||
static Tile* cake;
|
||||
static Tile* diode_off;
|
||||
static Tile* diode_on;
|
||||
static Tile* trapdoor;
|
||||
static Tile* stoneBrickSmooth;
|
||||
static Tile* grass_carried;
|
||||
static LeafTile* leaves_carried;
|
||||
static Tile* melon;
|
||||
static Tile* melonStem;
|
||||
static Tile* netherReactor;
|
||||
static Tile* glowingObsidian;
|
||||
|
||||
static Tile* stairs_stoneBrickSmooth;
|
||||
static Tile* netherBrick;
|
||||
static Tile* netherrack;
|
||||
static Tile* stairs_netherBricks;
|
||||
static Tile* stairs_sandStone;
|
||||
static Tile* quartzBlock;
|
||||
static Tile* stairs_quartz;
|
||||
|
||||
// invisible bedrock is used to block off empty chunks (i.e. prevent player movement)
|
||||
static Tile* invisible_bedrock;
|
||||
static Tile* info_updateGame1;
|
||||
static Tile* info_updateGame2;
|
||||
static Tile* info_reserved6;
|
||||
|
||||
static void initTiles();
|
||||
static void teardownTiles();
|
||||
|
||||
static int transformToValidBlockId(int blockId);
|
||||
static int transformToValidBlockId(int blockId, int x, int y, int z);
|
||||
|
||||
Tile(int id, const Material* material);
|
||||
Tile(int id, int tex, const Material* material);
|
||||
virtual ~Tile() {}
|
||||
|
||||
virtual bool isCubeShaped();
|
||||
virtual int getRenderShape();
|
||||
virtual void setShape(float x0, float y0, float z0, float x1, float y1, float z1);
|
||||
virtual void updateShape(LevelSource* level, int x, int y, int z) {}
|
||||
virtual void updateDefaultShape() {}
|
||||
|
||||
virtual void addLights(Level* level, int x, int y, int z) {}
|
||||
|
||||
virtual float getBrightness(LevelSource* level, int x, int y, int z);
|
||||
|
||||
static bool isFaceVisible(Level* level, int x, int y, int z, int f);
|
||||
virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face);
|
||||
|
||||
virtual int getTexture(int face);
|
||||
virtual int getTexture(int face, int data);
|
||||
virtual int getTexture(LevelSource* level, int x, int y, int z, int face);
|
||||
|
||||
// @attn Not threadsafe (ADDON: nor safe to _save_ this returned AABB*.
|
||||
// Make a copy if you need to save this AABB (rather then using as a temp)
|
||||
virtual AABB* getAABB(Level* level, int x, int y, int z);
|
||||
virtual void addAABBs(Level* level, int x, int y, int z, const AABB* box, std::vector<AABB>& boxes);
|
||||
virtual AABB getTileAABB(Level* level, int x, int y, int z);
|
||||
|
||||
virtual bool isSolidRender();
|
||||
|
||||
virtual bool mayPick();
|
||||
virtual bool mayPick(int data, bool liquid);
|
||||
virtual bool mayPlace(Level* level, int x, int y, int z, unsigned char face);
|
||||
virtual bool mayPlace(Level* level, int x, int y, int z);
|
||||
|
||||
virtual int getTickDelay();
|
||||
virtual void tick(Level* level, int x, int y, int z, Random* random) {}
|
||||
virtual void animateTick(Level* level, int x, int y, int z, Random* random) {}
|
||||
|
||||
virtual void destroy(Level* level, int x, int y, int z, int data);
|
||||
|
||||
virtual void neighborChanged(Level* level, int x, int y, int z, int type) {}
|
||||
|
||||
virtual void onPlace(Level* level, int x, int y, int z) {}
|
||||
virtual void onRemove(Level* level, int x, int y, int z) {}
|
||||
|
||||
virtual int getResource(int data, Random* random);
|
||||
virtual int getResourceCount(Random* random);
|
||||
|
||||
virtual float getDestroyProgress(Player* player);
|
||||
|
||||
virtual void spawnResources(Level* level, int x, int y, int z, int data);
|
||||
virtual void spawnResources(Level* level, int x, int y, int z, int data, float odds);
|
||||
virtual bool spawnBurnResources(Level* level, float x, float y, float z);
|
||||
void popResource(Level* level, int x, int y, int z, const ItemInstance& itemInstance);
|
||||
|
||||
virtual float getExplosionResistance(Entity* source);
|
||||
|
||||
virtual HitResult clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b);
|
||||
|
||||
virtual void wasExploded(Level* level, int x, int y, int z) {}
|
||||
|
||||
virtual int getRenderLayer();
|
||||
|
||||
virtual bool use(Level* level, int x, int y, int z, Player* player);
|
||||
|
||||
virtual void stepOn(Level* level, int x, int y, int z, Entity* entity) {}
|
||||
|
||||
virtual void fallOn( Level* level, int x, int y, int z, Entity* entity, float fallDistance ) {}
|
||||
|
||||
virtual int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue) { return itemValue; }
|
||||
virtual void setPlacedBy(Level* level, int x, int y, int z, Mob* by) {}
|
||||
|
||||
virtual void prepareRender(Level* level, int x, int y, int z) {}
|
||||
|
||||
virtual void attack(Level* level, int x, int y, int z, Player* player) {}
|
||||
|
||||
virtual void handleEntityInside(Level* level, int x, int y, int z, Entity* e, Vec3& current) {}
|
||||
|
||||
virtual int getColor(LevelSource* level, int x, int y, int z);
|
||||
|
||||
virtual bool isSignalSource();
|
||||
virtual bool getSignal(LevelSource* level, int x, int y, int z);
|
||||
virtual bool getSignal(LevelSource* level, int x, int y, int z, int dir);
|
||||
virtual bool getDirectSignal(Level* level, int x, int y, int z, int dir);
|
||||
|
||||
virtual void entityInside(Level* level, int x, int y, int z, Entity* entity) {}
|
||||
|
||||
virtual void playerDestroy(Level* level, Player* player, int x, int y, int z, int data);
|
||||
|
||||
virtual bool canSurvive(Level* level, int x, int y, int z);
|
||||
|
||||
|
||||
virtual std::string getName() const;
|
||||
virtual std::string getDescriptionId() const;
|
||||
virtual Tile* setDescriptionId(const std::string& id);
|
||||
|
||||
virtual void triggerEvent(Level* level, int x, int y, int z, int b0, int b1) {}
|
||||
|
||||
protected:
|
||||
virtual Tile* setSoundType(const SoundType& soundType);
|
||||
|
||||
virtual Tile* setLightBlock(int i);
|
||||
virtual Tile* setLightEmission(float f);
|
||||
|
||||
virtual Tile* setExplodeable(float explosionResistance);
|
||||
virtual Tile* setDestroyTime(float destroySpeed);
|
||||
|
||||
virtual void setTicking(bool tick);
|
||||
|
||||
/*** Returns the item instance's auxValue when a TileItem is spawned from this Tile. */
|
||||
virtual int getSpawnResourcesAuxValue(int data);
|
||||
|
||||
private:
|
||||
Tile* init();
|
||||
Tile* setCategory(int category);
|
||||
|
||||
bool containsX(const Vec3& v);
|
||||
bool containsY(const Vec3& v);
|
||||
bool containsZ(const Vec3& v);
|
||||
public:
|
||||
int tex;
|
||||
const int id;
|
||||
|
||||
float xx0, yy0, zz0, xx1, yy1, zz1;
|
||||
const SoundType* soundType;
|
||||
|
||||
float gravity;
|
||||
const Material* const material;
|
||||
float friction;
|
||||
|
||||
//protected:
|
||||
float destroySpeed;
|
||||
float explosionResistance;
|
||||
|
||||
int category;
|
||||
protected:
|
||||
AABB tmpBB;
|
||||
|
||||
static const int RENDERLAYER_OPAQUE;
|
||||
static const int RENDERLAYER_ALPHATEST;
|
||||
static const int RENDERLAYER_BLEND;
|
||||
private:
|
||||
std::string descriptionId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__Tile_H__*/
|
||||
62
src/world/level/tile/TileInclude.h
Executable file
62
src/world/level/tile/TileInclude.h
Executable file
@@ -0,0 +1,62 @@
|
||||
#ifndef TILE_INCLUDE_H__
|
||||
#define TILE_INCLUDE_H__
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
#include "BedTile.h"
|
||||
#include "BookshelfTile.h"
|
||||
#include "Bush.h"
|
||||
#include "CactusTile.h"
|
||||
#include "CarriedTile.h"
|
||||
#include "ClayTile.h"
|
||||
#include "ChestTile.h"
|
||||
#include "ClothTile.h"
|
||||
#include "CropTile.h"
|
||||
#include "DirtTile.h"
|
||||
#include "DoorTile.h"
|
||||
#include "FarmTile.h"
|
||||
#include "FenceTile.h"
|
||||
#include "FenceGateTile.h"
|
||||
#include "FireTile.h"
|
||||
#include "FurnaceTile.h"
|
||||
#include "GlassTile.h"
|
||||
#include "GrassTile.h"
|
||||
#include "GravelTile.h"
|
||||
#include "HeavyTile.h"
|
||||
#include "IceTile.h"
|
||||
#include "InvisibleTile.h"
|
||||
#include "LadderTile.h"
|
||||
#include "LeafTile.h"
|
||||
#include "LightGemTile.h"
|
||||
#include "LiquidTileDynamic.h"
|
||||
#include "LiquidTileStatic.h"
|
||||
#include "MelonTile.h"
|
||||
#include "MultiTextureTile.h"
|
||||
#include "Mushroom.h"
|
||||
#include "ObsidianTile.h"
|
||||
#include "OreTile.h"
|
||||
#include "MetalTile.h"
|
||||
#include "NetherReactor.h"
|
||||
#include "QuartzBlockTile.h"
|
||||
#include "RedStoneOreTile.h"
|
||||
#include "ReedTile.h"
|
||||
#include "SandStoneTile.h"
|
||||
#include "Sapling.h"
|
||||
#include "SignTile.h"
|
||||
#include "SnowTile.h"
|
||||
#include "StairTile.h"
|
||||
#include "StemTile.h"
|
||||
#include "StonecutterTile.h"
|
||||
#include "StoneTile.h"
|
||||
#include "StoneSlabTile.h"
|
||||
#include "TallGrass.h"
|
||||
#include "ThinFenceTile.h"
|
||||
#include "TopSnowTile.h"
|
||||
#include "TorchTile.h"
|
||||
#include "TrapDoorTile.h"
|
||||
#include "TreeTile.h"
|
||||
#include "TntTile.h"
|
||||
#include "WebTile.h"
|
||||
#include "WorkbenchTile.h"
|
||||
|
||||
#endif /* TILE_INCLUDE_H__ */
|
||||
69
src/world/level/tile/TntTile.h
Executable file
69
src/world/level/tile/TntTile.h
Executable file
@@ -0,0 +1,69 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TntTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TntTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
#include "../../entity/item/PrimedTnt.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
|
||||
class TntTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
static const int EXPLODE_BIT = 1;
|
||||
public:
|
||||
TntTile(int id, int tex)
|
||||
: super(id, tex, Material::explosive)
|
||||
{
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face == 0) return tex + 2;
|
||||
if (face == 1) return tex + 1;
|
||||
return tex;
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
if (type > 0 && Tile::tiles[type]->isSignalSource()) {
|
||||
if (level->hasNeighborSignal(x, y, z)) {
|
||||
destroy(level, x, y, z, EXPLODE_BIT);
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void wasExploded(Level* level, int x, int y, int z) {
|
||||
PrimedTnt* primed = new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f);
|
||||
primed->life = level->random.nextInt(primed->life / 4) + primed->life / 8;
|
||||
level->addEntity(primed);
|
||||
}
|
||||
|
||||
void destroy(Level* level, int x, int y, int z, int data) {
|
||||
if (level->isClientSide) return;
|
||||
|
||||
if ((data & EXPLODE_BIT) == 1) {
|
||||
PrimedTnt* tnt = new PrimedTnt(level, x + 0.5f, y + 0.5f, z + 0.5f);
|
||||
level->addEntity(tnt);
|
||||
level->playSound(tnt, "random.fuse", 1, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
ItemInstance* carried = player->getSelectedItem();
|
||||
if (carried && carried->id == Item::flintAndSteel->id) {
|
||||
carried->hurt(1);
|
||||
destroy(level, x, y, z, EXPLODE_BIT);
|
||||
level->setTile(x, y, z, 0);
|
||||
return true;
|
||||
}
|
||||
return super::use(level, x, y, z, player);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__TntTile_H__*/
|
||||
97
src/world/level/tile/TopSnowTile.h
Executable file
97
src/world/level/tile/TopSnowTile.h
Executable file
@@ -0,0 +1,97 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TopSnowTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TopSnowTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/item/ItemEntity.h"
|
||||
#include "../../item/ItemInstance.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class TopSnowTile: public Tile
|
||||
{
|
||||
public:
|
||||
TopSnowTile(int id, int tex)
|
||||
: Tile(id, tex, Material::topSnow)
|
||||
{
|
||||
setShape(0, 0, 0, 1, 1 / 8.0f, 1);
|
||||
setTicking(true);
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
int t = level->getTile(x, y - 1, z);
|
||||
if (t == 0 || !Tile::tiles[t]->isSolidRender()) return false;
|
||||
return level->getMaterial(x, y - 1, z)->blocksMotion();
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
checkCanSurvive(level, x, y, z);
|
||||
}
|
||||
|
||||
void playerDestroy(Level* level, Player* player, int x, int y, int z, int data) {
|
||||
if (level->isClientSide)
|
||||
return;
|
||||
|
||||
int type = Item::snowBall->id;
|
||||
float s = 0.7f;
|
||||
float xo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float yo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
float zo = level->random.nextFloat() * s + (1 - s) * 0.5f;
|
||||
ItemEntity* item = new ItemEntity(level, x + xo, y + yo, z + zo, ItemInstance(type, 1, 0));
|
||||
item->throwTime = 10;
|
||||
level->addEntity(item);
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Item::snowBall->id;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
if (level->getBrightness(LightLayer::Block, x, y, z) > 11) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face) {
|
||||
const Material* m = level->getMaterial(x, y, z);
|
||||
if (face == 1) return true;
|
||||
if (m == this->material) return false;
|
||||
return Tile::shouldRenderFace(level, x, y, z, face);
|
||||
}
|
||||
|
||||
private:
|
||||
bool checkCanSurvive(Level* level, int x, int y, int z) {
|
||||
if (!mayPlace(level, x, y, z)) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, 0);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__TopSnowTile_H__*/
|
||||
177
src/world/level/tile/TorchTile.h
Executable file
177
src/world/level/tile/TorchTile.h
Executable file
@@ -0,0 +1,177 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TorchTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TorchTile_H__
|
||||
|
||||
//package net.minecraft.world.level->tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
|
||||
class TorchTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
|
||||
public:
|
||||
TorchTile(int id, int tex)
|
||||
: super(id, tex, Material::decoration)
|
||||
{
|
||||
this->setTicking(true);
|
||||
}
|
||||
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_TORCH;
|
||||
}
|
||||
|
||||
int getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
bool mayPlace(Level* level, int x, int y, int z) {
|
||||
if (level->isSolidBlockingTile(x - 1, y, z)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x + 1, y, z)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x, y, z - 1)) {
|
||||
return true;
|
||||
} else if (level->isSolidBlockingTile(x, y, z + 1)) {
|
||||
return true;
|
||||
} else if (isConnection(level, x, y - 1, z)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue)
|
||||
{
|
||||
int dir = itemValue;
|
||||
|
||||
if (face == 1 && isConnection(level, x, y - 1, z)) dir = 5;
|
||||
if (face == 2 && level->isSolidBlockingTile(x, y, z + 1)) dir = 4;
|
||||
if (face == 3 && level->isSolidBlockingTile(x, y, z - 1)) dir = 3;
|
||||
if (face == 4 && level->isSolidBlockingTile(x + 1, y, z)) dir = 2;
|
||||
if (face == 5 && level->isSolidBlockingTile(x - 1, y, z)) dir = 1;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
void tick(Level* level, int x, int y, int z, Random* random) {
|
||||
super::tick(level, x, y, z, random);
|
||||
if (level->getData(x, y, z) == 0) onPlace(level, x, y, z);
|
||||
}
|
||||
|
||||
void onPlace(Level* level, int x, int y, int z) {
|
||||
if (level->isSolidBlockingTile(x - 1, y, z)) {
|
||||
level->setData(x, y, z, 1);
|
||||
} else if (level->isSolidBlockingTile(x + 1, y, z)) {
|
||||
level->setData(x, y, z, 2);
|
||||
} else if (level->isSolidBlockingTile(x, y, z - 1)) {
|
||||
level->setData(x, y, z, 3);
|
||||
} else if (level->isSolidBlockingTile(x, y, z + 1)) {
|
||||
level->setData(x, y, z, 4);
|
||||
} else if (isConnection(level, x, y - 1, z)) {
|
||||
level->setData(x, y, z, 5);
|
||||
}
|
||||
checkCanSurvive(level, x, y, z);
|
||||
}
|
||||
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type) {
|
||||
if (checkCanSurvive(level, x, y, z)) {
|
||||
int dir = level->getData(x, y, z);
|
||||
bool replace = false;
|
||||
|
||||
if (!level->isSolidBlockingTile(x - 1, y, z) && dir == 1) replace = true;
|
||||
if (!level->isSolidBlockingTile(x + 1, y, z) && dir == 2) replace = true;
|
||||
if (!level->isSolidBlockingTile(x, y, z - 1) && dir == 3) replace = true;
|
||||
if (!level->isSolidBlockingTile(x, y, z + 1) && dir == 4) replace = true;
|
||||
if (!isConnection(level, x, y - 1, z) && dir == 5) replace = true;
|
||||
|
||||
if (replace) {
|
||||
this->spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HitResult clip(Level* level, int x, int y, int z, const Vec3& a, const Vec3& b) {
|
||||
int dir = level->getData(x, y, z) & 7;
|
||||
|
||||
float r = 0.15f;
|
||||
if (dir == 1) {
|
||||
setShape(0, 0.2f, 0.5f - r, r * 2, 0.8f, 0.5f + r);
|
||||
} else if (dir == 2) {
|
||||
setShape(1 - r * 2, 0.2f, 0.5f - r, 1, 0.8f, 0.5f + r);
|
||||
} else if (dir == 3) {
|
||||
setShape(0.5f - r, 0.2f, 0, 0.5f + r, 0.8f, r * 2);
|
||||
} else if (dir == 4) {
|
||||
setShape(0.5f - r, 0.2f, 1 - r * 2, 0.5f + r, 0.8f, 1);
|
||||
} else {
|
||||
r = 0.1f;
|
||||
setShape(0.5f - r, 0.0f, 0.5f - r, 0.5f + r, 0.6f, 0.5f + r);
|
||||
}
|
||||
|
||||
return super::clip(level, x, y, z, a, b);
|
||||
}
|
||||
|
||||
void animateTick(Level* level, int xt, int yt, int zt, Random* random) {
|
||||
int dir = level->getData(xt, yt, zt);
|
||||
float x = xt + 0.5f;
|
||||
float y = yt + 0.7f;
|
||||
float z = zt + 0.5f;
|
||||
float h = 0.22f;
|
||||
float r = 0.27f;
|
||||
if (dir == 1) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x - r, y + h, z, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x - r, y + h, z, 0, 0, 0);
|
||||
} else if (dir == 2) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x + r, y + h, z, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x + r, y + h, z, 0, 0, 0);
|
||||
} else if (dir == 3) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x, y + h, z - r, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x, y + h, z - r, 0, 0, 0);
|
||||
} else if (dir == 4) {
|
||||
level->addParticle(PARTICLETYPE(smoke), x, y + h, z + r, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x, y + h, z + r, 0, 0, 0);
|
||||
} else {
|
||||
level->addParticle(PARTICLETYPE(smoke), x, y, z, 0, 0, 0);
|
||||
level->addParticle(PARTICLETYPE(flame), x, y, z, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool isConnection(Level* level, int x, int y, int z) {
|
||||
if (level->isSolidBlockingTile(x, y, z)) {
|
||||
return true;
|
||||
}
|
||||
int tile = level->getTile(x, y, z);
|
||||
if (tile == Tile::fence->id || tile == Tile::glass->id /*|| tile == Tile::cobbleWall->id*/) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool checkCanSurvive(Level* level, int x, int y, int z) {
|
||||
if (!mayPlace(level, x, y, z)) {
|
||||
if (level->getTile(x, y, z) == id) {
|
||||
spawnResources(level, x, y, z, level->getData(x, y, z));
|
||||
level->setTile(x, y, z, 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__TorchTile_H__*/
|
||||
40
src/world/level/tile/TransparentTile.h
Executable file
40
src/world/level/tile/TransparentTile.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TransparentTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TransparentTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../LevelSource.h"
|
||||
class Material;
|
||||
|
||||
class TransparentTile: public Tile
|
||||
{
|
||||
public:
|
||||
/*protected*/
|
||||
bool allowSame;
|
||||
|
||||
/*protected*/
|
||||
TransparentTile(int id, int tex, const Material* material, bool allowSame)
|
||||
: Tile(id, tex, material)
|
||||
{
|
||||
this->allowSame = allowSame;
|
||||
}
|
||||
|
||||
bool isSolidRender()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face)
|
||||
{
|
||||
int id = level->getTile(x, y, z);
|
||||
if (!allowSame && id == this->id) return false;
|
||||
return Tile::shouldRenderFace(level, x, y, z, face);
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__TransparentTile_H__*/
|
||||
154
src/world/level/tile/TrapDoorTile.cpp
Executable file
154
src/world/level/tile/TrapDoorTile.cpp
Executable file
@@ -0,0 +1,154 @@
|
||||
#include "TrapDoorTile.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
#include "LevelEvent.h"
|
||||
TrapDoorTile::TrapDoorTile( int id, const Material* material ) : super(id, material) {
|
||||
tex = 4 + 5 * 16;
|
||||
if(material == Material::metal) tex++;
|
||||
float r = 0.5f;
|
||||
float h = 1.0f;
|
||||
super::setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r);
|
||||
}
|
||||
|
||||
bool TrapDoorTile::blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TrapDoorTile::isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TrapDoorTile::isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
int TrapDoorTile::getRenderShape() {
|
||||
return Tile::SHAPE_BLOCK;
|
||||
}
|
||||
|
||||
int TrapDoorTile::getRenderLayer() {
|
||||
return Tile::RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
AABB TrapDoorTile::getTileAABB( Level* level, int x, int y, int z ) {
|
||||
updateShape(level, x, y, z);
|
||||
return super::getTileAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
AABB* TrapDoorTile::getAABB( Level* level, int x, int y, int z ) {
|
||||
updateShape(level, x, y, z);
|
||||
return super::getAABB(level, x, y, z);
|
||||
}
|
||||
|
||||
void TrapDoorTile::updateShape( LevelSource* level, int x, int y, int z ) {
|
||||
setShape(level->getData(x, y, z));
|
||||
}
|
||||
|
||||
void TrapDoorTile::updateDefaultShape() {
|
||||
float r = 3 / 16.0f;
|
||||
super::setShape(0, 0.5f - r / 2, 0, 1, 0.5f + r / 2, 1);
|
||||
}
|
||||
|
||||
void TrapDoorTile::setShape( int data ) {
|
||||
float r = 3 / 16.0f;
|
||||
super::setShape(0, 0, 0, 1, r, 1);
|
||||
if (isOpen(data)) {
|
||||
if ((data & 3) == 0) super::setShape(0, 0, 1 - r, 1, 1, 1);
|
||||
if ((data & 3) == 1) super::setShape(0, 0, 0, 1, 1, r);
|
||||
if ((data & 3) == 2) super::setShape(1 - r, 0, 0, 1, 1, 1);
|
||||
if ((data & 3) == 3) super::setShape(0, 0, 0, r, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void TrapDoorTile::attack( Level* level, int x, int y, int z, Player* player ) {
|
||||
use(level, x, y, z, player);
|
||||
}
|
||||
|
||||
bool TrapDoorTile::use( Level* level, int x, int y, int z, Player* player ) {
|
||||
if (material == Material::metal) return true;
|
||||
|
||||
int dir = level->getData(x, y, z);
|
||||
level->setData(x, y, z, dir ^ 4);
|
||||
|
||||
level->levelEvent(player, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TrapDoorTile::setOpen( Level* level, int x, int y, int z, bool shouldOpen ) {
|
||||
int dir = level->getData(x, y, z);
|
||||
|
||||
bool wasOpen = (dir & 4) > 0;
|
||||
if (wasOpen == shouldOpen) return;
|
||||
|
||||
level->setData(x, y, z, dir ^ 4);
|
||||
|
||||
level->levelEvent(NULL, LevelEvent::SOUND_OPEN_DOOR, x, y, z, 0);
|
||||
}
|
||||
|
||||
void TrapDoorTile::neighborChanged( Level* level, int x, int y, int z, int type ) {
|
||||
if (level->isClientSide) return;
|
||||
|
||||
int data = level->getData(x, y, z);
|
||||
int xt = x;
|
||||
int zt = z;
|
||||
if ((data & 3) == 0) zt++;
|
||||
if ((data & 3) == 1) zt--;
|
||||
if ((data & 3) == 2) xt++;
|
||||
if ((data & 3) == 3) xt--;
|
||||
|
||||
if (!attachesTo(level->getTile(xt, y, zt))) {
|
||||
level->setTile(x, y, z, 0);
|
||||
popResource(level, x, y, z, ItemInstance(Tile::trapdoor));
|
||||
}
|
||||
|
||||
bool signal = level->hasNeighborSignal(x, y, z);
|
||||
if (signal || ((type > 0 && Tile::tiles[type]->isSignalSource()) || type == 0)) {
|
||||
setOpen(level, x, y, z, signal);
|
||||
}
|
||||
}
|
||||
|
||||
HitResult TrapDoorTile::clip( Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b ) {
|
||||
updateShape(level, xt, yt, zt);
|
||||
return super::clip(level, xt, yt, zt, a, b);
|
||||
}
|
||||
|
||||
int TrapDoorTile::getDir( int dir ) {
|
||||
if ((dir & 4) == 0) {
|
||||
return ((dir - 1) & 3);
|
||||
} else {
|
||||
return (dir & 3);
|
||||
}
|
||||
}
|
||||
|
||||
int TrapDoorTile::getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue) {
|
||||
int dir = 0;
|
||||
if (face == 2) dir = 0;
|
||||
if (face == 3) dir = 1;
|
||||
if (face == 4) dir = 2;
|
||||
if (face == 5) dir = 3;
|
||||
return dir;
|
||||
}
|
||||
|
||||
bool TrapDoorTile::mayPlace( Level* level, int x, int y, int z, unsigned char face) {
|
||||
if (face == 0) return false;
|
||||
if (face == 1) return false;
|
||||
if (face == 2) z++;
|
||||
if (face == 3) z--;
|
||||
if (face == 4) x++;
|
||||
if (face == 5) x--;
|
||||
|
||||
return attachesTo(level->getTile(x, y, z));
|
||||
}
|
||||
|
||||
bool TrapDoorTile::isOpen( int data ) {
|
||||
return (data & 4) != 0;
|
||||
}
|
||||
|
||||
bool TrapDoorTile::attachesTo( int id ) {
|
||||
if (id <= 0) {
|
||||
return false;
|
||||
}
|
||||
Tile* tile = Tile::tiles[id];
|
||||
bool isStair = tile != NULL && tile->getRenderShape() == Tile::SHAPE_STAIRS;
|
||||
return tile != NULL && (tile->material->isSolidBlocking() && tile->isCubeShaped()) || tile == Tile::lightGem || tile == Tile::stoneSlabHalf || isStair;
|
||||
}
|
||||
36
src/world/level/tile/TrapDoorTile.h
Executable file
36
src/world/level/tile/TrapDoorTile.h
Executable file
@@ -0,0 +1,36 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TrapDoorTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TrapDoorTile_H__
|
||||
|
||||
#include "Tile.h"
|
||||
class TrapDoorTile : public Tile {
|
||||
typedef Tile super;
|
||||
|
||||
public:
|
||||
TrapDoorTile(int id, const Material* material);
|
||||
bool blocksLight();
|
||||
bool isSolidRender();
|
||||
bool isCubeShaped();
|
||||
int getRenderLayer();
|
||||
//@Override
|
||||
// public boolean isPathfindable(LevelSource level, int x, int y, int z) {
|
||||
// return !isOpen(level.getData(x, y, z));
|
||||
//}
|
||||
int getRenderShape();
|
||||
AABB getTileAABB(Level* level, int x, int y, int z);
|
||||
AABB* getAABB(Level* level, int x, int y, int z);
|
||||
void updateShape(LevelSource* level, int x, int y, int z);
|
||||
void updateDefaultShape();
|
||||
void setShape(int data);
|
||||
void attack(Level* level, int x, int y, int z, Player* player);
|
||||
bool use(Level* level, int x, int y, int z, Player* player);
|
||||
void setOpen(Level* level, int x, int y, int z, bool shouldOpen);
|
||||
void neighborChanged(Level* level, int x, int y, int z, int type);
|
||||
HitResult clip(Level* level, int xt, int yt, int zt, const Vec3& a, const Vec3& b);
|
||||
int getDir(int dir);
|
||||
int getPlacedOnFaceDataValue(Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue);
|
||||
bool mayPlace(Level* level, int x, int y, int z, unsigned char face);
|
||||
static bool isOpen(int data);
|
||||
static bool attachesTo(int id);
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE__TrapDoorTile_H__ */
|
||||
67
src/world/level/tile/TreeTile.h
Executable file
67
src/world/level/tile/TreeTile.h
Executable file
@@ -0,0 +1,67 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__TreeTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__TreeTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../Level.h"
|
||||
|
||||
#include "Tile.h"
|
||||
#include "LeafTile.h"
|
||||
|
||||
class TreeTile: public Tile
|
||||
{
|
||||
public:
|
||||
static const int NORMAL_TRUNK = 0;
|
||||
static const int DARK_TRUNK = 1;
|
||||
static const int BIRCH_TRUNK = 2;
|
||||
|
||||
TreeTile(int id)
|
||||
: Tile(id, Material::wood)
|
||||
{
|
||||
tex = 20;
|
||||
}
|
||||
|
||||
int getResourceCount(Random* random) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getResource(int data, Random* random) {
|
||||
return Tile::treeTrunk->id;
|
||||
}
|
||||
|
||||
void onRemove(Level* level, int x, int y, int z) {
|
||||
int r = LeafTile::REQUIRED_WOOD_RANGE;
|
||||
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);
|
||||
if ((currentData & LeafTile::UPDATE_LEAF_BIT) == 0) {
|
||||
level->setDataNoUpdate(x + xo, y + yo, z + zo, currentData | LeafTile::UPDATE_LEAF_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getTexture(int face, int data) {
|
||||
if (face == 1) return 21;
|
||||
if (face == 0) return 21;
|
||||
if (data == DARK_TRUNK) return 4 + 7 * 16;
|
||||
if (data == BIRCH_TRUNK) return 5 + 7 * 16;
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected:
|
||||
int getSpawnResourcesAuxValue(int data) {
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__TreeTile_H__*/
|
||||
59
src/world/level/tile/WebTile.h
Executable file
59
src/world/level/tile/WebTile.h
Executable file
@@ -0,0 +1,59 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__WebTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__WebTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "../../entity/Entity.h"
|
||||
#include "../../item/Item.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../phys/AABB.h"
|
||||
|
||||
class WebTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
WebTile(int id, int tex)
|
||||
: super(id, tex, Material::web)
|
||||
{
|
||||
}
|
||||
|
||||
int getRenderLayer(){
|
||||
return RENDERLAYER_ALPHATEST;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void entityInside(Level* level, int x, int y, int z, Entity* entity) {
|
||||
entity->makeStuckInWeb();
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
bool isSolidRender() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
AABB* getAABB(Level* level, int x, int y, int z) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getRenderShape() {
|
||||
return Tile::SHAPE_CROSS_TEXTURE;
|
||||
}
|
||||
|
||||
bool blocksLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isCubeShaped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
int getResource(int data, Random* random) {
|
||||
return Item::string->id;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__WebTile_H__*/
|
||||
34
src/world/level/tile/WorkbenchTile.h
Executable file
34
src/world/level/tile/WorkbenchTile.h
Executable file
@@ -0,0 +1,34 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE__WorkbenchTile_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE__WorkbenchTile_H__
|
||||
|
||||
//package net.minecraft.world.level.tile;
|
||||
|
||||
#include "Tile.h"
|
||||
#include "../Level.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../../entity/player/Player.h"
|
||||
|
||||
class WorkbenchTile: public Tile
|
||||
{
|
||||
typedef Tile super;
|
||||
public:
|
||||
WorkbenchTile(int id)
|
||||
: super(id, Material::wood)
|
||||
{
|
||||
tex = 11 + 16 * 3;
|
||||
}
|
||||
|
||||
int getTexture(int face) {
|
||||
if (face == 1) return tex - 16;
|
||||
if (face == 0) return Tile::wood->getTexture(0);
|
||||
if (face == 2 || face == 4) return tex + 1;
|
||||
return tex;
|
||||
}
|
||||
|
||||
bool use(Level* level, int x, int y, int z, Player* player) {
|
||||
player->startCrafting(x, y, z, Recipe::SIZE_3X3);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE__WorkbenchTile_H__*/
|
||||
239
src/world/level/tile/entity/ChestTileEntity.cpp
Executable file
239
src/world/level/tile/entity/ChestTileEntity.cpp
Executable file
@@ -0,0 +1,239 @@
|
||||
#include "ChestTileEntity.h"
|
||||
#include "../ChestTile.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../../entity/player/Player.h"
|
||||
#include "../../../../nbt/NbtIo.h"
|
||||
|
||||
ChestTileEntity::ChestTileEntity()
|
||||
: super(TileEntityType::Chest),
|
||||
FillingContainer(ItemsSize, 0, ContainerType::CONTAINER, false),
|
||||
tickInterval(0),
|
||||
openCount(0),
|
||||
openness(0), oOpenness(0),
|
||||
hasCheckedNeighbors(false),
|
||||
n(NULL), s(NULL), w(NULL), e(NULL)
|
||||
{
|
||||
//rendererId = TR_CHEST_RENDERER;
|
||||
}
|
||||
|
||||
int ChestTileEntity::getContainerSize() const
|
||||
{
|
||||
return ItemsSize;
|
||||
}
|
||||
|
||||
ItemInstance* ChestTileEntity::getItem( int slot )
|
||||
{
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
/*
|
||||
ItemInstance ChestTileEntity::removeItem( int slot, int count )
|
||||
{
|
||||
if (!items[slot].isNull()) {
|
||||
if (items[slot].count <= count) {
|
||||
ItemInstance item = items[slot];
|
||||
items[slot].setNull();
|
||||
this->setChanged();
|
||||
return item;
|
||||
} else {
|
||||
ItemInstance i = items[slot].remove(count);
|
||||
if (items[slot].count == 0) items[slot].setNull();
|
||||
this->setChanged();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return ItemInstance();
|
||||
}
|
||||
|
||||
ItemInstance ChestTileEntity::removeItemNoUpdate( int slot )
|
||||
{
|
||||
if (!items[slot].isNull()) {
|
||||
ItemInstance item = items[slot];
|
||||
items[slot].setNull();
|
||||
return item;
|
||||
}
|
||||
return ItemInstance();
|
||||
}
|
||||
|
||||
void ChestTileEntity::setItem( int slot, ItemInstance* item )
|
||||
{
|
||||
items[slot] = item? *item : ItemInstance();
|
||||
if (item != NULL && item->count > getMaxStackSize()) item->count = getMaxStackSize();
|
||||
this->setChanged();
|
||||
}
|
||||
*/
|
||||
|
||||
std::string ChestTileEntity::getName() const
|
||||
{
|
||||
return "container.chest";
|
||||
}
|
||||
|
||||
bool ChestTileEntity::shouldSave() {
|
||||
for (int i = 0; i < ItemsSize; ++i)
|
||||
if (items[i] && !items[i]->isNull()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChestTileEntity::load( CompoundTag* base )
|
||||
{
|
||||
super::load(base);
|
||||
|
||||
if (!base->contains("Items"))//, Tag::TAG_List)
|
||||
return;
|
||||
|
||||
ListTag* inventoryList = base->getList("Items");
|
||||
for (int i = 0; i < inventoryList->size(); i++) {
|
||||
Tag* ttag = inventoryList->get(i);
|
||||
if (ttag->getId() != Tag::TAG_Compound)
|
||||
continue;
|
||||
|
||||
CompoundTag* tag = (CompoundTag*) ttag;
|
||||
int slot = tag->getByte("Slot") & 0xff;
|
||||
if (slot >= 0 && slot < ItemsSize) {
|
||||
if (!items[slot]) items[slot] = new ItemInstance(); //@chestodo
|
||||
items[slot]->load(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ChestTileEntity::save( CompoundTag* base )
|
||||
{
|
||||
if (!super::save(base))
|
||||
return false;
|
||||
|
||||
ListTag* listTag = new ListTag();
|
||||
|
||||
for (int i = 0; i < ItemsSize; i++) {
|
||||
if (items[i] && !items[i]->isNull()) {
|
||||
CompoundTag* tag = new CompoundTag();
|
||||
tag->putByte("Slot", (char) i);
|
||||
items[i]->save(tag);
|
||||
listTag->add(tag);
|
||||
}
|
||||
}
|
||||
base->put("Items", listTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
int ChestTileEntity::getMaxStackSize() const
|
||||
{
|
||||
return Container::LARGE_MAX_STACK_SIZE;
|
||||
}
|
||||
|
||||
bool ChestTileEntity::stillValid( Player* player )
|
||||
{
|
||||
if (level->getTileEntity(x, y, z) != this) return false;
|
||||
if (player->distanceToSqr(x + 0.5f, y + 0.5f, z + 0.5f) > 8 * 8) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChestTileEntity::clearCache()
|
||||
{
|
||||
super::clearCache();
|
||||
hasCheckedNeighbors = false;
|
||||
}
|
||||
|
||||
void ChestTileEntity::checkNeighbors()
|
||||
{
|
||||
if (hasCheckedNeighbors)
|
||||
return;
|
||||
|
||||
hasCheckedNeighbors = true;
|
||||
n = NULL;
|
||||
e = NULL;
|
||||
w = NULL;
|
||||
s = NULL;
|
||||
|
||||
// if (getTile() != NULL) {
|
||||
if (level->getTile(x - 1, y, z) == Tile::chest->id) {
|
||||
w = (ChestTileEntity*) level->getTileEntity(x - 1, y, z);
|
||||
}
|
||||
if (level->getTile(x + 1, y, z) == Tile::chest->id) {
|
||||
e = (ChestTileEntity*) level->getTileEntity(x + 1, y, z);
|
||||
}
|
||||
if (level->getTile(x, y, z - 1) == Tile::chest->id) {
|
||||
n = (ChestTileEntity*) level->getTileEntity(x, y, z - 1);
|
||||
}
|
||||
if (level->getTile(x, y, z + 1) == Tile::chest->id) {
|
||||
s = (ChestTileEntity*) level->getTileEntity(x, y, z + 1);
|
||||
}
|
||||
|
||||
if (n != NULL) n->clearCache();
|
||||
if (s != NULL) s->clearCache();
|
||||
if (e != NULL) e->clearCache();
|
||||
if (w != NULL) w->clearCache();
|
||||
// }
|
||||
}
|
||||
|
||||
void ChestTileEntity::tick()
|
||||
{
|
||||
super::tick();
|
||||
checkNeighbors();
|
||||
|
||||
if (++tickInterval >= 4 * SharedConstants::TicksPerSecond) {
|
||||
level->tileEvent(x, y, z, ChestTile::EVENT_SET_OPEN_COUNT, openCount);
|
||||
tickInterval = 0;
|
||||
}
|
||||
|
||||
oOpenness = openness;
|
||||
|
||||
float speed = 0.10f;
|
||||
if (openCount > 0 && openness == 0) {
|
||||
if (n == NULL && w == NULL) {
|
||||
float xc = x + 0.5f;
|
||||
float zc = z + 0.5f;
|
||||
if (s != NULL) zc += 0.5f;
|
||||
if (e != NULL) xc += 0.5f;
|
||||
|
||||
level->playSound(xc, y + 0.5f, zc, "random.chestopen", 0.5f, level->random.nextFloat() * 0.1f + 0.9f);
|
||||
}
|
||||
}
|
||||
if ((openCount == 0 && openness > 0) || (openCount > 0 && openness < 1)) {
|
||||
float oldOpen = openness;
|
||||
if (openCount > 0) openness += speed;
|
||||
else openness -= speed;
|
||||
if (openness > 1) {
|
||||
openness = 1;
|
||||
}
|
||||
float lim = 0.5f;
|
||||
if (openness < lim && oldOpen >= lim) {
|
||||
if (n == NULL && w == NULL) {
|
||||
float xc = x + 0.5f;
|
||||
float zc = z + 0.5f;
|
||||
if (s != NULL) zc += 0.5f;
|
||||
if (e != NULL) xc += 0.5f;
|
||||
|
||||
level->playSound(xc, y + 0.5f, zc, "random.chestclosed", 0.5f, level->random.nextFloat() * 0.1f + 0.9f);
|
||||
}
|
||||
}
|
||||
if (openness < 0) {
|
||||
openness = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChestTileEntity::triggerEvent( int b0, int b1 )
|
||||
{
|
||||
if (b0 == ChestTile::EVENT_SET_OPEN_COUNT) {
|
||||
openCount = b1;
|
||||
}
|
||||
}
|
||||
|
||||
void ChestTileEntity::startOpen()
|
||||
{
|
||||
openCount++;
|
||||
level->tileEvent(x, y, z, ChestTile::EVENT_SET_OPEN_COUNT, openCount);
|
||||
}
|
||||
|
||||
void ChestTileEntity::stopOpen()
|
||||
{
|
||||
openCount--;
|
||||
level->tileEvent(x, y, z, ChestTile::EVENT_SET_OPEN_COUNT, openCount);
|
||||
}
|
||||
|
||||
void ChestTileEntity::setRemoved()
|
||||
{
|
||||
clearCache();
|
||||
checkNeighbors();
|
||||
super::setRemoved();
|
||||
}
|
||||
66
src/world/level/tile/entity/ChestTileEntity.h
Executable file
66
src/world/level/tile/entity/ChestTileEntity.h
Executable file
@@ -0,0 +1,66 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__ChestTileEntity_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__ChestTileEntity_H__
|
||||
|
||||
//package net.minecraft.world.level->tile.entity;
|
||||
|
||||
#include "TileEntity.h"
|
||||
#include "../../../inventory/FillingContainer.h"
|
||||
#include "../../../item/ItemInstance.h"
|
||||
#include <string>
|
||||
|
||||
class CompoundTag;
|
||||
class Player;
|
||||
|
||||
/* import com.mojang.nbt.* */
|
||||
|
||||
class ChestTileEntity: public TileEntity,
|
||||
public FillingContainer
|
||||
{
|
||||
typedef TileEntity super;
|
||||
public:
|
||||
ChestTileEntity();
|
||||
|
||||
int getContainerSize() const;
|
||||
int getMaxStackSize() const;
|
||||
std::string getName() const;
|
||||
|
||||
ItemInstance* getItem(int slot);
|
||||
//void setItem(int slot, ItemInstance* item);
|
||||
//ItemInstance removeItem(int slot, int count);
|
||||
//ItemInstance removeItemNoUpdate(int slot);
|
||||
|
||||
bool shouldSave();
|
||||
void load(CompoundTag* base);
|
||||
bool save(CompoundTag* base);
|
||||
|
||||
bool stillValid(Player* player);
|
||||
|
||||
void clearCache();
|
||||
void checkNeighbors();
|
||||
|
||||
/*@Override*/
|
||||
void tick();
|
||||
|
||||
void triggerEvent(int b0, int b1);
|
||||
|
||||
void startOpen();
|
||||
void stopOpen();
|
||||
|
||||
/*@Override*/
|
||||
void setRemoved();
|
||||
|
||||
bool hasCheckedNeighbors;
|
||||
ChestTileEntity* n;
|
||||
ChestTileEntity* e;
|
||||
ChestTileEntity* w;
|
||||
ChestTileEntity* s;
|
||||
|
||||
float openness, oOpenness;
|
||||
int openCount;
|
||||
|
||||
private:
|
||||
static const int ItemsSize = 9*3;
|
||||
int tickInterval;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__ChestTileEntity_H__*/
|
||||
251
src/world/level/tile/entity/FurnaceTileEntity.cpp
Executable file
251
src/world/level/tile/entity/FurnaceTileEntity.cpp
Executable file
@@ -0,0 +1,251 @@
|
||||
#include "FurnaceTileEntity.h"
|
||||
|
||||
#include "../FurnaceTile.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../Container.h"
|
||||
#include "../../../entity/player/Player.h"
|
||||
//#include "../../../item/crafting/FurnaceRecipes.h"
|
||||
#include "../../../item/ItemInstance.h"
|
||||
#include "../../../../nbt/ListTag.h"
|
||||
#include "../../../item/crafting/FurnaceRecipes.h"
|
||||
|
||||
FurnaceTileEntity::FurnaceTileEntity()
|
||||
: super(TileEntityType::Furnace),
|
||||
Container(ContainerType::FURNACE),
|
||||
litTime(0),
|
||||
litDuration(0),
|
||||
tickCount(0),
|
||||
finished(false),
|
||||
_canBeFinished(false)
|
||||
{
|
||||
//LOGI("CREATING FurnaceTileEntity! %p\n", this);
|
||||
}
|
||||
|
||||
FurnaceTileEntity::~FurnaceTileEntity() {
|
||||
//LOGI("DELETING FurnaceTileEntity! %p @ %d, %d, %d\n", this, x, y, z);
|
||||
}
|
||||
|
||||
ItemInstance* FurnaceTileEntity::getItem(int slot) {// @todo @container @fix
|
||||
return &items[slot];
|
||||
}
|
||||
|
||||
ItemInstance FurnaceTileEntity::removeItem(int slot, int count) {
|
||||
if (!items[slot].isNull()) {
|
||||
if (items[slot].count <= count) {
|
||||
ItemInstance item = items[slot];
|
||||
items[slot].setNull();
|
||||
return item;
|
||||
} else {
|
||||
ItemInstance i = items[slot].remove(count);
|
||||
if (items[slot].count == 0) items[slot].setNull();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return ItemInstance();
|
||||
}
|
||||
|
||||
void FurnaceTileEntity::setItem(int slot, ItemInstance* item) {
|
||||
items[slot] = *item;
|
||||
if (item != NULL && item->count > getMaxStackSize())
|
||||
items[slot].count = getMaxStackSize();
|
||||
//LOGI("Furnace: Setting slot %d : %s\n", slot, item->getDescriptionId().c_str());
|
||||
}
|
||||
|
||||
std::string FurnaceTileEntity::getName() const {
|
||||
return "Furnace";
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::shouldSave() {
|
||||
if (litTime > 0) return true;
|
||||
for (int i = 0; i < NumItems; ++i)
|
||||
if (!items[i].isNull()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FurnaceTileEntity::load(CompoundTag* base) {
|
||||
super::load(base);
|
||||
ListTag* inventoryList = base->getList("Items");
|
||||
for (int i = 0; i < 3; ++i)
|
||||
items[i].setNull();
|
||||
for (int i = 0; i < inventoryList->size(); i++) {
|
||||
Tag* tt = inventoryList->get(i);
|
||||
if (tt->getId() == Tag::TAG_Compound) {
|
||||
CompoundTag* tag = (CompoundTag*)tt;
|
||||
int slot = tag->getByte("Slot");
|
||||
if (slot >= 0 && slot < NumItems) {
|
||||
ItemInstance* loaded = ItemInstance::fromTag(tag);
|
||||
if (loaded) {
|
||||
items[slot] = *loaded;
|
||||
delete loaded;
|
||||
} else
|
||||
items[slot].setNull();
|
||||
}
|
||||
} else {
|
||||
LOGE("load @ FurnaceTileEntity failed. item's not a compoundTag!\n");
|
||||
}
|
||||
}
|
||||
|
||||
litTime = base->getShort("BurnTime");
|
||||
tickCount = base->getShort("CookTime");
|
||||
litDuration = getBurnDuration(items[SLOT_FUEL]);
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::save(CompoundTag* base) {
|
||||
if (!super::save(base))
|
||||
return false;
|
||||
|
||||
base->putShort("BurnTime", (short) (litTime));
|
||||
base->putShort("CookTime", (short) (tickCount));
|
||||
ListTag* listTag = new ListTag();
|
||||
|
||||
for (int i = 0; i < NumItems; i++) {
|
||||
if (!items[i].isNull()) {
|
||||
CompoundTag* tag = new CompoundTag();
|
||||
tag->putByte("Slot", (char) i);
|
||||
items[i].save(tag);
|
||||
listTag->add(tag);
|
||||
}
|
||||
}
|
||||
base->put("Items", listTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
int FurnaceTileEntity::getMaxStackSize() const {
|
||||
return Container::LARGE_MAX_STACK_SIZE;
|
||||
}
|
||||
|
||||
int FurnaceTileEntity::getContainerSize() const {
|
||||
return NumItems;
|
||||
}
|
||||
|
||||
int FurnaceTileEntity::getBurnProgress(int max) {
|
||||
return tickCount * max / BURN_INTERVAL;
|
||||
}
|
||||
|
||||
int FurnaceTileEntity::getLitProgress(int max) {
|
||||
if (litDuration == 0) litDuration = BURN_INTERVAL;
|
||||
return litTime * max / litDuration;
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::isLit() {
|
||||
return litTime > 0;
|
||||
}
|
||||
|
||||
void FurnaceTileEntity::tick()
|
||||
{
|
||||
//LOGI("lit|time, tick, dur: %d, %d, %d\n", litTime, tickCount, litDuration);
|
||||
|
||||
bool wasLit = litTime > 0;
|
||||
bool changed = false;
|
||||
if (litTime > 0) {
|
||||
--litTime;
|
||||
}
|
||||
|
||||
//LOGI("Ticking FurnaceTileEntity: %d\n", litTime);
|
||||
|
||||
if (!level->isClientSide) {
|
||||
if (litTime == 0 && canBurn()) {
|
||||
litDuration = litTime = getBurnDuration(items[SLOT_FUEL]);
|
||||
if (litTime > 0) {
|
||||
changed = true;
|
||||
if (!items[SLOT_FUEL].isNull()) {
|
||||
if (--items[SLOT_FUEL].count == 0) items[SLOT_FUEL].setNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isLit() && canBurn()) {
|
||||
if (++tickCount == BURN_INTERVAL) {
|
||||
tickCount = 0;
|
||||
burn();
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
tickCount = 0;
|
||||
}
|
||||
|
||||
if (wasLit != (litTime > 0)) {
|
||||
changed = true;
|
||||
FurnaceTile::setLit(litTime > 0, level, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) setChanged();
|
||||
else {
|
||||
if (!wasLit) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::isFinished()
|
||||
{
|
||||
return _canBeFinished && finished;
|
||||
}
|
||||
|
||||
|
||||
void FurnaceTileEntity::burn() {
|
||||
if (!canBurn()) return;
|
||||
|
||||
ItemInstance result = FurnaceRecipes::getInstance()->getResult(items[0].getItem()->id);
|
||||
if (items[2].isNull()) items[2] = result;
|
||||
else if (items[2].id == result.id) items[2].count++;
|
||||
|
||||
if (--items[0].count <= 0) items[0].setNull();
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::stillValid(Player* player) {
|
||||
if (level->getTileEntity(x, y, z) != this) return false;
|
||||
if (player->distanceToSqr(x + 0.5f, y + 0.5f, z + 0.5f) > 8 * 8) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FurnaceTileEntity::startOpen() {
|
||||
//_canBeFinished = false;
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
void FurnaceTileEntity::stopOpen() {
|
||||
//_canBeFinished = true;
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::canBurn() {
|
||||
if (items[SLOT_INGREDIENT].isNull()) return false;
|
||||
ItemInstance burnResult = FurnaceRecipes::getInstance()->getResult(items[SLOT_INGREDIENT].getItem()->id);
|
||||
if (burnResult.isNull()) return false;
|
||||
if (items[SLOT_RESULT].isNull()) return true;
|
||||
if (!items[SLOT_RESULT].sameItem(&burnResult)) return false;
|
||||
if (items[SLOT_RESULT].count < getMaxStackSize() && items[SLOT_RESULT].count < items[SLOT_RESULT].getMaxStackSize()) return true;
|
||||
if (items[SLOT_RESULT].count < burnResult.getMaxStackSize()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
int FurnaceTileEntity::getBurnDuration(const ItemInstance& itemInstance) {
|
||||
//if (itemInstance == NULL) return 0;
|
||||
if (itemInstance.isNull()) return 0;
|
||||
int id = itemInstance.getItem()->id;
|
||||
|
||||
if (id < 256 && Tile::tiles[id]->material == Material::wood)
|
||||
return BURN_INTERVAL * 3 / 2;
|
||||
|
||||
if (id == Item::stick->id) return BURN_INTERVAL / 2;
|
||||
if (id == Item::coal->id) return BURN_INTERVAL * 8;
|
||||
//case Item::bucket_lava->id: return BURN_INTERVAL * 100;
|
||||
//case Tile::sapling->id: return BURN_INTERVAL / 2;
|
||||
//case Item::blazeRod->id: return BURN_INTERVAL * 12;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::isFuel( const ItemInstance& itemInstance )
|
||||
{
|
||||
return getBurnDuration(itemInstance) > 0;
|
||||
}
|
||||
|
||||
bool FurnaceTileEntity::isSlotEmpty( int slot )
|
||||
{
|
||||
return items[slot].isNull();
|
||||
}
|
||||
74
src/world/level/tile/entity/FurnaceTileEntity.h
Executable file
74
src/world/level/tile/entity/FurnaceTileEntity.h
Executable file
@@ -0,0 +1,74 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__FurnaceTileEntity_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__FurnaceTileEntity_H__
|
||||
|
||||
//package net.minecraft.world.level->tile.entity;
|
||||
|
||||
#include "TileEntity.h"
|
||||
#include "../../../Container.h"
|
||||
#include "../../../item/ItemInstance.h"
|
||||
|
||||
class CompoundTag;
|
||||
class Player;
|
||||
|
||||
class FurnaceTileEntity: public TileEntity,
|
||||
public Container
|
||||
{
|
||||
typedef TileEntity super;
|
||||
static const int BURN_INTERVAL = 10 * 20;
|
||||
static const int NumItems = 3;
|
||||
public:
|
||||
FurnaceTileEntity();
|
||||
~FurnaceTileEntity();
|
||||
|
||||
// Container
|
||||
ItemInstance* getItem(int slot);
|
||||
void setItem(int slot, ItemInstance* item);
|
||||
ItemInstance removeItem(int slot, int count);
|
||||
|
||||
std::string getName() const;
|
||||
int getMaxStackSize() const;
|
||||
int getContainerSize() const;
|
||||
|
||||
bool stillValid(Player* player);
|
||||
|
||||
void startOpen();
|
||||
void stopOpen();
|
||||
|
||||
void setContainerChanged();
|
||||
|
||||
// Furnace
|
||||
void load(CompoundTag* base);
|
||||
bool save(CompoundTag* base);
|
||||
bool shouldSave();
|
||||
|
||||
int getBurnProgress(int max);
|
||||
int getLitProgress(int max);
|
||||
|
||||
bool isLit();
|
||||
bool isFinished();
|
||||
bool isSlotEmpty( int slot );
|
||||
|
||||
void tick();
|
||||
|
||||
void burn();
|
||||
|
||||
static bool isFuel(const ItemInstance& itemInstance);
|
||||
static int getBurnDuration(const ItemInstance& itemInstance);
|
||||
private:
|
||||
bool canBurn();
|
||||
|
||||
public:
|
||||
int litTime;
|
||||
int litDuration;
|
||||
int tickCount;
|
||||
ItemInstance items[NumItems];
|
||||
|
||||
static const int SLOT_INGREDIENT = 0;
|
||||
static const int SLOT_FUEL = 1;
|
||||
static const int SLOT_RESULT = 2;
|
||||
private:
|
||||
bool _canBeFinished;
|
||||
bool finished;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__FurnaceTileEntity_H__*/
|
||||
402
src/world/level/tile/entity/NetherReactorTileEntity.cpp
Executable file
402
src/world/level/tile/entity/NetherReactorTileEntity.cpp
Executable file
@@ -0,0 +1,402 @@
|
||||
#include "NetherReactorTileEntity.h"
|
||||
#include "../../../../nbt/CompoundTag.h"
|
||||
#include "../../../../SharedConstants.h"
|
||||
#include "../../../phys/Vec3.h"
|
||||
#include "../../../level/Level.h"
|
||||
#include "../../../level/MobSpawner.h"
|
||||
#include "../../../entity/MobFactory.h"
|
||||
#include "../NetherReactor.h"
|
||||
#include "../../../entity/Entity.h"
|
||||
#include "../../../Difficulty.h"
|
||||
#include "../../../phys/AABB.h"
|
||||
#include "../NetherReactorPattern.h"
|
||||
NetherReactorTileEntity::NetherReactorTileEntity()
|
||||
: super(TileEntityType::NetherReactor)
|
||||
, isInitialized(false)
|
||||
, progress(0)
|
||||
, curLevel(0)
|
||||
, hasFinished(false)
|
||||
{ }
|
||||
|
||||
bool NetherReactorTileEntity::shouldSave() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::lightItUp( int x, int y, int z ) {
|
||||
//if(!isInitilized && !hasFinished) {
|
||||
curLevel = 0;
|
||||
NetherReactor::setPhase(level, x, y, z, 1);
|
||||
isInitialized = true;
|
||||
//clearDomeSpace(x, y, z);
|
||||
buildDome(x, y, z);
|
||||
|
||||
level->setNightMode(true);
|
||||
//}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::tick() {
|
||||
if(level->isClientSide)
|
||||
return;
|
||||
if(progress < 0) {
|
||||
remove = true;
|
||||
}
|
||||
if(isInitialized && !hasFinished) {
|
||||
progress++;
|
||||
if(progress % SharedConstants::TicksPerSecond == 0) {
|
||||
int currentTime = progress / SharedConstants::TicksPerSecond;
|
||||
if(currentTime < 10) {
|
||||
tickGlowingRedstoneTransformation(currentTime);
|
||||
}
|
||||
if(currentTime > 42 && currentTime <= 45) {
|
||||
// start with the top layer and move down
|
||||
int currentLayer = 45 - currentTime;
|
||||
turnGlowingObsidianLayerToObsidian(currentLayer);
|
||||
}
|
||||
if(checkLevelChange(progress / SharedConstants::TicksPerSecond)) {
|
||||
curLevel++;
|
||||
spawnItems(getNumItemsPerLevel(curLevel));
|
||||
trySpawnPigZombies(NUM_PIG_ZOMBIE_SLOTS, getNumEnemiesPerLevel(curLevel));
|
||||
}
|
||||
}
|
||||
if(progress > SharedConstants::TicksPerSecond * 46) {
|
||||
finishReactorRun();
|
||||
}
|
||||
} else if(hasFinished) {
|
||||
if(progress % SharedConstants::TicksPerSecond * 60 == 0) {
|
||||
if(playersAreCloseBy()) {
|
||||
trySpawnPigZombies(2, 3);
|
||||
} else {
|
||||
killPigZombies();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::load( CompoundTag* tag ) {
|
||||
super::load(tag);
|
||||
isInitialized = tag->getBoolean("IsInitialized");
|
||||
if(isInitialized) {
|
||||
progress = tag->getShort("Progress");
|
||||
hasFinished = tag->getBoolean("HasFinished");
|
||||
}
|
||||
}
|
||||
|
||||
bool NetherReactorTileEntity::save( CompoundTag* tag ) {
|
||||
super::save(tag);
|
||||
tag->putBoolean("IsInitialized", isInitialized);
|
||||
tag->putShort("Progress", progress);
|
||||
tag->putBoolean("HasFinished", hasFinished);
|
||||
if(isInitialized && !hasFinished)
|
||||
level->setNightMode(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string NetherReactorTileEntity::getName() const {
|
||||
return "NetherReactor";
|
||||
}
|
||||
|
||||
int NetherReactorTileEntity::getNumEnemiesPerLevel( int curLevel ) {
|
||||
if(curLevel == 0)
|
||||
return 3;
|
||||
else if(curLevel < 4)
|
||||
return 2;
|
||||
else if(curLevel < 6)
|
||||
return Mth::Max(0, level->random.nextInt(2));
|
||||
else
|
||||
return Mth::Max(0, level->random.nextInt(1));
|
||||
}
|
||||
|
||||
int NetherReactorTileEntity::getNumItemsPerLevel( int curLevel ) {
|
||||
if(curLevel == 0)
|
||||
return 3 * 3;
|
||||
else if(curLevel < 4)
|
||||
return 5 * 3;
|
||||
else if(curLevel < 8)
|
||||
return Mth::Max(0, level->random.nextInt(14 * 3) - 4);
|
||||
else
|
||||
return Mth::Max(0, level->random.nextInt(9 * 3) - 2);
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::spawnItems( int numItems ) {
|
||||
for (int ii = 0; ii < numItems ; ii++) {
|
||||
spawnItem();
|
||||
}
|
||||
}
|
||||
Vec3 NetherReactorTileEntity::getSpawnPosition( float minDistance, float varibleDistance, float offset ) {
|
||||
float distance = minDistance + level->random.nextFloat() * varibleDistance;
|
||||
float rad = level->random.nextFloat() * Mth::TWO_PI;
|
||||
return Vec3(sin(rad) * distance + x, offset + y, cos(rad) * distance + z);
|
||||
}
|
||||
void NetherReactorTileEntity::spawnEnemy() {
|
||||
Mob* mob = MobFactory::CreateMob(MobTypes::PigZombie, level);
|
||||
Vec3 enemyPosition = getSpawnPosition(3, 4, -1);
|
||||
while(enemyPosition.x < 0 || enemyPosition.z < 0 || enemyPosition.x >= LEVEL_WIDTH || enemyPosition.z >= LEVEL_DEPTH) {
|
||||
enemyPosition = getSpawnPosition(3, 4, -1);
|
||||
}
|
||||
MobSpawner::addMob(level, mob, enemyPosition.x, enemyPosition.y, enemyPosition.z, 0, 0, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NetherReactorTileEntity::spawnItem() {
|
||||
Vec3 itemPosition= getSpawnPosition(3, 4, -1);
|
||||
while(itemPosition.x < 0 || itemPosition.z < 0 || itemPosition.x >= LEVEL_WIDTH || itemPosition.z >= LEVEL_DEPTH) {
|
||||
itemPosition = getSpawnPosition(3, 4, -1);
|
||||
}
|
||||
ItemEntity* item = new ItemEntity(level, itemPosition.x, itemPosition.y, itemPosition.z, getSpawnItem());
|
||||
|
||||
item->throwTime = 10;
|
||||
item->age = item->getLifeTime() - SharedConstants::TicksPerSecond * 30;
|
||||
level->addEntity(item);
|
||||
}
|
||||
|
||||
ItemInstance NetherReactorTileEntity::getSpawnItem() {
|
||||
int itemType = level->random.nextInt(8);
|
||||
switch(itemType) {
|
||||
case 0: return ItemInstance(Item::yellowDust, 3);
|
||||
case 1: return ItemInstance(Item::seeds_melon);
|
||||
case 2: return ItemInstance(Tile::mushroom1);
|
||||
case 3: return ItemInstance(Tile::mushroom2);
|
||||
case 4: return ItemInstance(Item::reeds);
|
||||
case 5: return ItemInstance(Tile::cactus);
|
||||
case 6: return ItemInstance(Item::netherQuartz, 4);
|
||||
default: return GetLowOddsSpawnItem();
|
||||
}
|
||||
}
|
||||
|
||||
ItemInstance NetherReactorTileEntity::GetLowOddsSpawnItem() {
|
||||
if(level->random.nextInt(10) <= 9 ) {
|
||||
static Item* items[] = {
|
||||
Item::arrow,
|
||||
Item::bed,
|
||||
Item::bone,
|
||||
Item::book,
|
||||
Item::bow,
|
||||
Item::bowl,
|
||||
Item::feather,
|
||||
Item::painting,
|
||||
Item::door_wood
|
||||
};
|
||||
int itemIndex = level->random.nextInt(sizeof(items) / 4);
|
||||
Item* itemToSpawn = items[itemIndex];
|
||||
return ItemInstance(itemToSpawn);
|
||||
} else {
|
||||
static Tile* tiles[] = {
|
||||
Tile::bookshelf
|
||||
};
|
||||
int tileIndex = level->random.nextInt(sizeof(tiles) / 4);
|
||||
Tile* tileToSpawn = tiles[tileIndex];
|
||||
return ItemInstance(tileToSpawn);
|
||||
}
|
||||
}
|
||||
|
||||
bool NetherReactorTileEntity::checkLevelChange( int progress ) {
|
||||
static const int levelChangeTime[] = {10, 13, 20, 22, 25, 30, 34, 36, 38, 40};
|
||||
const int count = sizeof(levelChangeTime) / 4;
|
||||
for(int a = 0; a < count; ++a) {
|
||||
if(levelChangeTime[a] == progress)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::clearDomeSpace( int x, int y, int z ) {
|
||||
for(int curX = -12; curX <= 12; ++curX) {
|
||||
for(int curY = -3; curY < 40; ++curY) {
|
||||
for(int curZ = -12; curZ <= 12; ++curZ) {
|
||||
if(curY > 2 || curX < -1 || curX > 1 || curZ < -1 || curZ > 1)
|
||||
level->setTile(curX + x, curY + y, curZ + z, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::finishReactorRun() {
|
||||
NetherReactor::setPhase(level, x, y, z, 2);
|
||||
level->setNightMode(false);
|
||||
hasFinished = true;
|
||||
deterioateDome(x, y, z);
|
||||
for(int curX = x - 1; curX <= x + 1; ++curX) {
|
||||
for(int curY = y - 1; curY <= y + 1; ++curY) {
|
||||
for(int curZ = z - 1; curZ <= z + 1; ++curZ) {
|
||||
if(curX != x || curY != y || curZ != z)
|
||||
level->setTile(curX, curY, curZ, Tile::obsidian->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int NetherReactorTileEntity::numOfFreeEnemySlots() {
|
||||
int numPigZombiesFound = 0;
|
||||
AABB bb((float)x, (float)y, (float)z, x + 1.0f, y + 1.0f, z + 1.0f);
|
||||
EntityList nearby = level->getEntities(NULL, bb.grow(7, 7, 7));
|
||||
for(EntityList::iterator it = nearby.begin(); it != nearby.end(); ++it) {
|
||||
if((*it)->isEntityType(MobTypes::PigZombie) && (*it)->isAlive()) {
|
||||
numPigZombiesFound++;
|
||||
}
|
||||
}
|
||||
return NUM_PIG_ZOMBIE_SLOTS - numPigZombiesFound;
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::trySpawnPigZombies( int maxNumOfEnemies, int maxToSpawn ) {
|
||||
if(level->difficulty == Difficulty::PEACEFUL)
|
||||
return;
|
||||
int currentNumOfPigZombies = NUM_PIG_ZOMBIE_SLOTS - numOfFreeEnemySlots();
|
||||
if(currentNumOfPigZombies < maxNumOfEnemies) {
|
||||
for(int a = 0; a < maxToSpawn && currentNumOfPigZombies < maxNumOfEnemies; ++a) {
|
||||
spawnEnemy();
|
||||
currentNumOfPigZombies++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::tickGlowingRedstoneTransformation( int currentTime ) {
|
||||
switch(currentTime) {
|
||||
case 2: return turnLayerToGlowingObsidian(0, Tile::stoneBrick->id);
|
||||
case 3: return turnLayerToGlowingObsidian(1, Tile::stoneBrick->id);
|
||||
case 4: return turnLayerToGlowingObsidian(2, Tile::stoneBrick->id);
|
||||
case 7: return turnLayerToGlowingObsidian(0, Tile::goldBlock->id);
|
||||
case 8: return turnLayerToGlowingObsidian(1, Tile::goldBlock->id);
|
||||
case 9: return turnLayerToGlowingObsidian(2, Tile::goldBlock->id);
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::turnLayerToGlowingObsidian( int layer, const int type ) {
|
||||
NetherReactorPattern pattern;
|
||||
for(int checkX = -1; checkX <= 1; ++checkX) {
|
||||
for(int checkZ = -1; checkZ <= 1; ++checkZ) {
|
||||
if(pattern.getTileAt(layer, checkX + 1, checkZ + 1) == type) {
|
||||
level->setTile(x + checkX, y - 1 + layer, z + checkZ, Tile::glowingObsidian->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::turnGlowingObsidianLayerToObsidian( int layer ) {
|
||||
NetherReactorPattern pattern;
|
||||
for(int checkX = -1; checkX <= 1; ++checkX) {
|
||||
for(int checkZ = -1; checkZ <= 1; ++checkZ) {
|
||||
if(level->getTile(x + checkX, y - 1 + layer, z + checkZ) != Tile::netherReactor->id) {
|
||||
level->setTile(x + checkX, y - 1 + layer, z + checkZ, Tile::obsidian->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::buildDome( int x, int y, int z ) {
|
||||
buildFloorVolume(x, y - 3, z, 8, 2, Tile::netherrack->id);
|
||||
buildHollowedVolume(x, y - 1, z, 8, 4, Tile::netherrack->id, 0);
|
||||
buildFloorVolume(x, y - 1 + 4, z, 8, 1, Tile::netherrack->id);
|
||||
buildCrockedRoofVolume(false, x, y - 1 + 5, z, 8, 1, Tile::netherrack->id);
|
||||
buildCrockedRoofVolume(true, x, y - 1 + 6, z, 5, 8, Tile::netherrack->id);
|
||||
buildCrockedRoofVolume(false, x, y + -1 + 12, z, 3, 14, Tile::netherrack->id);
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::buildHollowedVolume( int x, int y, int z, int expandWidth, int height, const int wallTileId, const int clearTileId ) {
|
||||
for(int curY = 0; curY < height; ++curY) {
|
||||
for(int curX = -expandWidth; curX <= expandWidth; ++curX) {
|
||||
for(int curZ = -expandWidth; curZ <= expandWidth; ++curZ) {
|
||||
if((curX == -expandWidth || curX == expandWidth)
|
||||
|| (curZ == -expandWidth || curZ == expandWidth)) {
|
||||
level->setTile(curX + x, curY + y, curZ + z, wallTileId);
|
||||
} else if(curY > 2 || curX < -1 || curX > 1 || curZ < -1 || curZ > 1) {
|
||||
level->setTile(curX + x, curY + y, curZ + z, clearTileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::buildFloorVolume( int x, int y, int z, int expandWidth, int height, const int tileId ) {
|
||||
for(int curY = 0; curY < height; ++curY) {
|
||||
for(int curX = -expandWidth; curX <= expandWidth; ++curX) {
|
||||
for(int curZ = -expandWidth; curZ <= expandWidth; ++curZ) {
|
||||
level->setTile(curX + x, curY + y, curZ + z, tileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::buildCrockedRoofVolume( bool inverted, int x, int y, int z, int expandWidth, int height, const int tileId ) {
|
||||
int fullHeight = height + expandWidth;
|
||||
for(int curX = -expandWidth; curX <= expandWidth; ++curX) {
|
||||
for(int curZ = -expandWidth; curZ <= expandWidth; ++curZ) {
|
||||
int offset = inverted ? ((-curX - curZ) / 2) : ((curX + curZ) / 2);
|
||||
int acceptHeight = fullHeight + offset;
|
||||
for(int curY = 0; curY < fullHeight + expandWidth; ++curY) {
|
||||
if(acceptHeight >= curY
|
||||
&& (isEdge(curX, expandWidth, curZ)
|
||||
|| acceptHeight == curY )) {
|
||||
level->setTile(curX + x, curY + y, curZ + z, tileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NetherReactorTileEntity::isEdge( int curX, int expandWidth, int curZ ) {
|
||||
return (curX == -expandWidth || curX == expandWidth)
|
||||
|| (curZ == -expandWidth || curZ == expandWidth);
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::deterioateDome( int x, int y, int z ) {
|
||||
deterioateHollowedVolume(x, y - 1, z, 8, 5, 0);
|
||||
deterioateCrockedRoofVolume(false, x, y - 1 + 5, z, 8, 1, 0);
|
||||
deterioateCrockedRoofVolume(true, x, y - 1 + 6, z, 5, 8, 0);
|
||||
deterioateCrockedRoofVolume(false, x, y + -1 + 12, z, 3, 14, 0);
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::deterioateCrockedRoofVolume( bool inverted, int x, int y, int z, int expandWidth, int height, int tileId ) {
|
||||
int fullHeight = height + expandWidth;
|
||||
for(int curX = -expandWidth; curX <= expandWidth; ++curX) {
|
||||
for(int curZ = -expandWidth; curZ <= expandWidth; ++curZ) {
|
||||
int offset = inverted ? ((-curX - curZ) / 2) : ((curX + curZ) / 2);
|
||||
int acceptHeight = fullHeight + offset;
|
||||
for(int curY = 0; curY < fullHeight + expandWidth; ++curY) {
|
||||
if(acceptHeight >= curY
|
||||
&& (isEdge(curX, expandWidth, curZ))) {
|
||||
if(level->random.nextInt(4) == 0) {
|
||||
level->setTile(curX + x, curY + y, curZ + z, tileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::deterioateHollowedVolume( int x, int y, int z, int expandWidth, int height, int tileId ) {
|
||||
for(int curY = 0; curY < height; ++curY) {
|
||||
for(int curX = -expandWidth; curX <= expandWidth; ++curX) {
|
||||
for(int curZ = -expandWidth; curZ <= expandWidth; ++curZ) {
|
||||
if((curX == -expandWidth || curX == expandWidth)
|
||||
|| (curZ == -expandWidth || curZ == expandWidth)) {
|
||||
if(level->random.nextInt(3) == 0)
|
||||
level->setTile(curX + x, curY + y, curZ + z, tileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NetherReactorTileEntity::playersAreCloseBy() {
|
||||
int numPlayers = 0;
|
||||
AABB bb((float)x, (float)y, (float)z, x + 1.0f, y + 1.0f, z + 1.0f);
|
||||
EntityList nearby = level->getEntities(NULL, bb.grow(40, 40, 40));
|
||||
for(EntityList::iterator it = nearby.begin(); it != nearby.end(); ++it) {
|
||||
if((*it)->isPlayer() && (*it)->isAlive() ) {
|
||||
if((*it)->distanceTo((float)x, (float)y, (float)z) < 40)
|
||||
numPlayers++;
|
||||
}
|
||||
}
|
||||
return numPlayers != 0;
|
||||
}
|
||||
|
||||
void NetherReactorTileEntity::killPigZombies() {
|
||||
AABB bb((float)x, (float)y, (float)z, x + 1.0f, y + 1.0f, z + 1.0f);
|
||||
EntityList nearby = level->getEntities(NULL, bb.grow(40, 40, 40));
|
||||
for(EntityList::iterator it = nearby.begin(); it != nearby.end(); ++it) {
|
||||
if((*it)->isEntityType(MobTypes::PigZombie)) {
|
||||
(*it)->remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/world/level/tile/entity/NetherReactorTileEntity.h
Executable file
55
src/world/level/tile/entity/NetherReactorTileEntity.h
Executable file
@@ -0,0 +1,55 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__NetherReactorTileEntity_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__NetherReactorTileEntity_H__
|
||||
#include "../../../Pos.h"
|
||||
#include "TileEntity.h"
|
||||
class NetherReactorTileEntity : public TileEntity {
|
||||
typedef TileEntity super;
|
||||
static const int NUM_PIG_ZOMBIE_SLOTS = 3;
|
||||
public:
|
||||
NetherReactorTileEntity();
|
||||
bool shouldSave();
|
||||
void lightItUp(int x, int y, int z);
|
||||
|
||||
void buildDome(int x, int y, int z);
|
||||
void clearDomeSpace( int x, int y, int z );
|
||||
|
||||
void tick();
|
||||
|
||||
void finishReactorRun();
|
||||
|
||||
bool save(CompoundTag* tag);
|
||||
void load(CompoundTag* tag);
|
||||
int getNumEnemiesPerLevel(int curLevel);
|
||||
int getNumItemsPerLevel(int curLevel);
|
||||
void spawnItems(int numItems);
|
||||
std::string getName() const;
|
||||
void spawnEnemy();
|
||||
void spawnItem();
|
||||
ItemInstance getSpawnItem();
|
||||
|
||||
ItemInstance GetLowOddsSpawnItem();
|
||||
bool checkLevelChange( int progress );
|
||||
int numOfFreeEnemySlots();
|
||||
void trySpawnPigZombies( int maxNumOfEnemies, int maxToSpawn );
|
||||
void tickGlowingRedstoneTransformation( int currentTime );
|
||||
void turnLayerToGlowingObsidian( int layer, const int type );
|
||||
void turnGlowingObsidianLayerToObsidian( int layer );
|
||||
Vec3 getSpawnPosition( float minDistance, float varibleDistance, float offset );
|
||||
void buildHollowedVolume( int x, int y, int z, int expandWidth, int height, const int wallTileId, const int clearTileId );
|
||||
void buildFloorVolume( int x, int y, int z, int expandWidth, int heightm, const int tileId );
|
||||
void buildCrockedRoofVolume( bool inverted, int x, int y, int z, int expandWidth, int height, const int tileId );
|
||||
|
||||
bool isEdge( int curX, int expandWidth, int curZ );
|
||||
void deterioateDome( int x, int y, int z );
|
||||
void deterioateCrockedRoofVolume( bool inverted, int x, int y, int z, int expandWidth, int height, int tileId );
|
||||
void deterioateHollowedVolume( int x, int y, int z, int expandWidth, int height, int tileId );
|
||||
bool playersAreCloseBy();
|
||||
void killPigZombies();
|
||||
private:
|
||||
bool isInitialized;
|
||||
bool hasFinished;
|
||||
int curLevel;
|
||||
short progress;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__NetherReactorTileEntity_H__ */
|
||||
58
src/world/level/tile/entity/SignTileEntity.cpp
Executable file
58
src/world/level/tile/entity/SignTileEntity.cpp
Executable file
@@ -0,0 +1,58 @@
|
||||
#include "SignTileEntity.h"
|
||||
#include "../../../../network/packet/SignUpdatePacket.h"
|
||||
#include "../../Level.h"
|
||||
SignTileEntity::SignTileEntity()
|
||||
: super(TileEntityType::Sign),
|
||||
selectedLine(-1),
|
||||
editable(true)
|
||||
{
|
||||
rendererId = TR_SIGN_RENDERER;
|
||||
}
|
||||
|
||||
bool SignTileEntity::save( CompoundTag* tag ) {
|
||||
if (!super::save(tag))
|
||||
return false;
|
||||
|
||||
tag->putString("Text1", messages[0]);
|
||||
tag->putString("Text2", messages[1]);
|
||||
tag->putString("Text3", messages[2]);
|
||||
tag->putString("Text4", messages[3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SignTileEntity::load( CompoundTag* tag ) {
|
||||
editable = false;
|
||||
super::load(tag);
|
||||
|
||||
messages[0] = tag->getString("Text1");
|
||||
messages[1] = tag->getString("Text2");
|
||||
messages[2] = tag->getString("Text3");
|
||||
messages[3] = tag->getString("Text4");
|
||||
|
||||
for (int i = 0; i < NUM_LINES; i++)
|
||||
if (messages[i].length() > MAX_LINE_LENGTH)
|
||||
messages[i].resize(MAX_LINE_LENGTH);
|
||||
}
|
||||
|
||||
bool SignTileEntity::shouldSave() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SignTileEntity::isEditable() {
|
||||
return editable;
|
||||
}
|
||||
|
||||
void SignTileEntity::setEditable( bool isEditable ) {
|
||||
this->editable = isEditable;
|
||||
}
|
||||
|
||||
Packet* SignTileEntity::getUpdatePacket() {
|
||||
return new SignUpdatePacket(x, y, z, messages);
|
||||
}
|
||||
|
||||
void SignTileEntity::setLevelAndPos( Level* level, int x, int y, int z ) {
|
||||
super::setLevelAndPos(level, x, y, z);
|
||||
if(level->getTile(x, y, z) != Tile::sign->id) {
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
39
src/world/level/tile/entity/SignTileEntity.h
Executable file
39
src/world/level/tile/entity/SignTileEntity.h
Executable file
@@ -0,0 +1,39 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__SignTileEntity_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__SignTileEntity_H__
|
||||
|
||||
//package net.minecraft.world.level.tile.entity;
|
||||
|
||||
/* import net.minecraft.network.packet.* */
|
||||
|
||||
#include "../../../../nbt/CompoundTag.h"
|
||||
|
||||
#include "TileEntity.h"
|
||||
|
||||
class SignTileEntity: public TileEntity
|
||||
{
|
||||
typedef TileEntity super;
|
||||
public:
|
||||
static const int MAX_LINE_LENGTH = 15;
|
||||
static const int NUM_LINES = 4;
|
||||
|
||||
SignTileEntity();
|
||||
|
||||
/*@Override*/
|
||||
bool save(CompoundTag* tag);
|
||||
/*@Override*/
|
||||
void load(CompoundTag* tag);
|
||||
bool shouldSave();
|
||||
|
||||
bool isEditable();
|
||||
void setEditable(bool isEditable);
|
||||
void setLevelAndPos(Level* level, int x, int y, int z);
|
||||
|
||||
Packet* getUpdatePacket();
|
||||
|
||||
std::string messages[NUM_LINES];
|
||||
int selectedLine;
|
||||
private:
|
||||
bool editable;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__SignTileEntity_H__*/
|
||||
221
src/world/level/tile/entity/TileEntity.cpp
Executable file
221
src/world/level/tile/entity/TileEntity.cpp
Executable file
@@ -0,0 +1,221 @@
|
||||
#include "TileEntity.h"
|
||||
|
||||
TileEntity::MapIdType TileEntity::idClassMap;
|
||||
TileEntity::MapTypeId TileEntity::classIdMap;
|
||||
|
||||
#include "FurnaceTileEntity.h"
|
||||
#include "ChestTileEntity.h"
|
||||
#include "NetherReactorTileEntity.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../../../nbt/CompoundTag.h"
|
||||
#include "SignTileEntity.h"
|
||||
|
||||
int TileEntity::_runningId = 0;
|
||||
|
||||
//
|
||||
// TileEntityFactory
|
||||
//
|
||||
TileEntity* TileEntityFactory::createTileEntity( int type )
|
||||
{
|
||||
switch(type) {
|
||||
case TileEntityType::Furnace: return new FurnaceTileEntity();
|
||||
case TileEntityType::Chest: return new ChestTileEntity();
|
||||
case TileEntityType::Sign: return new SignTileEntity();
|
||||
case TileEntityType::NetherReactor: return new NetherReactorTileEntity();
|
||||
default:
|
||||
LOGE("Can't find TileEntity of type: %d\n", type);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TileEntity
|
||||
//
|
||||
|
||||
void TileEntity::initTileEntities()
|
||||
{
|
||||
setId(TileEntityType::Furnace, "Furnace");
|
||||
setId(TileEntityType::Chest, "Chest");
|
||||
setId(TileEntityType::NetherReactor, "NetherReactor");
|
||||
// setId(ChestTileEntity.class, "Chest");
|
||||
// setId(RecordPlayerTile.Entity.class, "RecordPlayer");
|
||||
// setId(DispenserTileEntity.class, "Trap");
|
||||
setId(TileEntityType::Sign, "Sign");
|
||||
// setId(MobSpawnerTileEntity.class, "MobSpawner");
|
||||
// setId(MusicTileEntity.class, "Music");
|
||||
// setId(PistonPieceEntity.class, "Piston");
|
||||
// setId(BrewingStandTileEntity.class, "Cauldron");
|
||||
// setId(EnchantmentTableEntity.class, "EnchantTable");
|
||||
// setId(TheEndPortalTileEntity.class, "Airportal");
|
||||
}
|
||||
|
||||
void TileEntity::teardownTileEntities()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TileEntity::TileEntity( int tileEntityType )
|
||||
: data(-1),
|
||||
type(tileEntityType),
|
||||
remove(false),
|
||||
level(NULL),
|
||||
tile(NULL),
|
||||
clientSideOnly(false),
|
||||
rendererId(TR_DEFAULT_RENDERER),
|
||||
runningId(++_runningId)
|
||||
{
|
||||
}
|
||||
|
||||
void TileEntity::load( CompoundTag* tag )
|
||||
{
|
||||
x = tag->getInt("x");
|
||||
y = tag->getInt("y");
|
||||
z = tag->getInt("z");
|
||||
LOGI("Loaded tile entity @ %d, %d, %d\n", x, y, z);
|
||||
}
|
||||
|
||||
bool TileEntity::save( CompoundTag* tag )
|
||||
{
|
||||
MapTypeId::const_iterator it = classIdMap.find(type);
|
||||
if (it == classIdMap.end()) {
|
||||
LOGE("TileEntityType %d is missing a mapping! This is a bug!\n", type);
|
||||
return false;
|
||||
}
|
||||
tag->putString("id", it->second);
|
||||
tag->putInt("x", x);
|
||||
tag->putInt("y", y);
|
||||
tag->putInt("z", z);
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntity* TileEntity::loadStatic( CompoundTag* tag )
|
||||
{
|
||||
TileEntity* entity = NULL;
|
||||
|
||||
std::string id = tag->getString("id");
|
||||
MapIdType::const_iterator cit = idClassMap.find(id);
|
||||
if (cit != idClassMap.end()) {
|
||||
//LOGI("Loading Tile Entity @ %d,%d,%d\n", ));
|
||||
entity = TileEntityFactory::createTileEntity(cit->second);
|
||||
if (entity) {
|
||||
//LOGI("Loading TileEntity: %d\n", entity->type);
|
||||
entity->load(tag);
|
||||
}
|
||||
else
|
||||
LOGE("Couldn't create TileEntity of type: '%d'\n", cit->second);
|
||||
} else {
|
||||
LOGE("Couldn't find TileEntity type: '%s'\n", id.c_str());
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
int TileEntity::getData()
|
||||
{
|
||||
if (data == -1) data = level->getData(x, y, z);
|
||||
return data;
|
||||
}
|
||||
|
||||
void TileEntity::setData( int data )
|
||||
{
|
||||
this->data = data;
|
||||
level->setData(x, y, z, data);
|
||||
}
|
||||
|
||||
void TileEntity::setChanged()
|
||||
{
|
||||
if (level != NULL) {
|
||||
data = level->getData(x, y, z);
|
||||
level->tileEntityChanged(x, y, z, this);
|
||||
}
|
||||
}
|
||||
|
||||
float TileEntity::distanceToSqr( float xPlayer, float yPlayer, float zPlayer )
|
||||
{
|
||||
float xd = (x + 0.5f) - xPlayer;
|
||||
float yd = (y + 0.5f) - yPlayer;
|
||||
float zd = (z + 0.5f) - zPlayer;
|
||||
return xd * xd + yd * yd + zd * zd;
|
||||
}
|
||||
|
||||
Tile* TileEntity::getTile() {
|
||||
if (tile == NULL) tile = Tile::tiles[level->getTile(x, y, z)];
|
||||
return tile;
|
||||
}
|
||||
|
||||
bool TileEntity::isRemoved() const
|
||||
{
|
||||
return remove;
|
||||
}
|
||||
|
||||
void TileEntity::setRemoved()
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
|
||||
void TileEntity::clearRemoved()
|
||||
{
|
||||
remove = false;
|
||||
}
|
||||
|
||||
void TileEntity::triggerEvent( int b0, int b1 )
|
||||
{
|
||||
}
|
||||
|
||||
void TileEntity::clearCache()
|
||||
{
|
||||
tile = NULL;
|
||||
data = -1;
|
||||
}
|
||||
|
||||
void TileEntity::setId( int type, const std::string& id )
|
||||
{
|
||||
MapIdType::const_iterator cit = idClassMap.find(id);
|
||||
if (cit != idClassMap.end()) {
|
||||
LOGE("Duplicate id: %s\n", id.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
idClassMap.insert(std::make_pair(id, type));
|
||||
classIdMap.insert(std::make_pair(type, id));
|
||||
}
|
||||
|
||||
void TileEntity::setLevelAndPos( Level* level, int x, int y, int z ) {
|
||||
this->level = level;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
|
||||
if (level) {
|
||||
this->tile = Tile::tiles[level->getTile(x, y, z)];
|
||||
}
|
||||
}
|
||||
|
||||
bool TileEntity::isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Packet* TileEntity::getUpdatePacket() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool TileEntity::isType( int Type ) {
|
||||
return type == Type;
|
||||
}
|
||||
|
||||
bool TileEntity::isType( TileEntity* te, int Type ) {
|
||||
return te != NULL && te->isType(Type);
|
||||
}
|
||||
|
||||
|
||||
int partitionTileEntities( const std::vector<TileEntity*>& in, std::vector<TileEntity*>& keep, std::vector<TileEntity*>& dontKeep ) {
|
||||
std::map<TilePos, TileEntity*> m;
|
||||
for (unsigned int i = 0; i < in.size(); ++i) {
|
||||
TileEntity* e = in[i];
|
||||
TilePos p(e->x, e->y, e->z);
|
||||
if (m.find(p) == m.end() && e->shouldSave()) {
|
||||
m.insert(std::make_pair(p, e));
|
||||
keep.push_back(e);
|
||||
} else dontKeep.push_back(e);
|
||||
}
|
||||
return (int)keep.size();
|
||||
}
|
||||
98
src/world/level/tile/entity/TileEntity.h
Executable file
98
src/world/level/tile/entity/TileEntity.h
Executable file
@@ -0,0 +1,98 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__TileEntity_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__TileEntity_H__
|
||||
|
||||
//package net.minecraft.world.level->tile.entity;
|
||||
|
||||
#include "../Tile.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "TileEntityRendererId.h"
|
||||
|
||||
class Level;
|
||||
class TileEntity;
|
||||
class CompoundTag;
|
||||
class Packet;
|
||||
|
||||
class TileEntityType {
|
||||
public:
|
||||
static const int Undefined = 0;
|
||||
static const int Furnace = 1;
|
||||
static const int Chest = 2;
|
||||
static const int NetherReactor = 3;
|
||||
static const int Sign = 4;
|
||||
};
|
||||
|
||||
class TileEntityFactory {
|
||||
public:
|
||||
static TileEntity* createTileEntity(int type);
|
||||
};
|
||||
|
||||
class TileEntity
|
||||
{
|
||||
typedef std::map<std::string, int> MapIdType;
|
||||
typedef std::map<int, std::string> MapTypeId;
|
||||
|
||||
static int _runningId;
|
||||
public:
|
||||
static void initTileEntities();
|
||||
static void teardownTileEntities();
|
||||
|
||||
TileEntity(int tileEntityType);
|
||||
virtual ~TileEntity() {}
|
||||
|
||||
virtual bool shouldSave() = 0;
|
||||
virtual void load(CompoundTag* tag);
|
||||
virtual bool save(CompoundTag* tag);
|
||||
|
||||
virtual void tick() {}
|
||||
virtual bool isFinished();
|
||||
|
||||
static TileEntity* loadStatic(CompoundTag* tag);
|
||||
|
||||
virtual void setLevelAndPos(Level* level, int x, int y, int z);
|
||||
|
||||
int getData();
|
||||
void setData(int data);
|
||||
|
||||
void setChanged();
|
||||
|
||||
float distanceToSqr(float xPlayer, float yPlayer, float zPlayer);
|
||||
|
||||
Tile* getTile();
|
||||
|
||||
virtual Packet* getUpdatePacket();
|
||||
|
||||
bool isRemoved() const;
|
||||
void setRemoved();
|
||||
void clearRemoved();
|
||||
|
||||
virtual void triggerEvent(int b0, int b1);
|
||||
virtual void clearCache();
|
||||
|
||||
bool isType(int Type);
|
||||
static bool isType(TileEntity* te, int Type);
|
||||
public:
|
||||
Level* level;
|
||||
int x, y, z;
|
||||
|
||||
int data;
|
||||
int type;
|
||||
int runningId;
|
||||
|
||||
bool clientSideOnly;
|
||||
|
||||
TileEntityRendererId rendererId;
|
||||
|
||||
protected:
|
||||
Tile* tile;
|
||||
bool remove;
|
||||
|
||||
private:
|
||||
static MapIdType idClassMap;
|
||||
static MapTypeId classIdMap;
|
||||
static void setId(int type, const std::string& id);
|
||||
};
|
||||
|
||||
int partitionTileEntities(const std::vector<TileEntity*>& in, std::vector<TileEntity*>& keep, std::vector<TileEntity*>& dontKeep);
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_TILE_ENTITY__TileEntity_H__*/
|
||||
10
src/world/level/tile/entity/TileEntityRendererId.h
Executable file
10
src/world/level/tile/entity/TileEntityRendererId.h
Executable file
@@ -0,0 +1,10 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_ENTITY__TileEntityRendererId_H__
|
||||
#define NET_MINECRAFT_WORLD_ENTITY__TileEntityRendererId_H__
|
||||
|
||||
enum TileEntityRendererId {
|
||||
TR_DEFAULT_RENDERER,
|
||||
TR_CHEST_RENDERER,
|
||||
TR_SIGN_RENDERER
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_ENTITY__TileEntityRendererId_H__*/
|
||||
Reference in New Issue
Block a user