Merge branch 'dedicated-rewrite'
This commit is contained in:
@@ -880,8 +880,8 @@ bool Entity::load( CompoundTag* tag )
|
||||
|
||||
// Add a small padding if standing next to the world edges
|
||||
const float padding = bbWidth * 0.5f + 0.001f;
|
||||
xx = Mth::clamp(xx, padding, (float)LEVEL_WIDTH - padding);
|
||||
zz = Mth::clamp(zz, padding, (float)LEVEL_DEPTH - padding);
|
||||
xx = Mth::clamp(xx, padding, (float)LevelConstants::LEVEL_WIDTH - padding);
|
||||
zz = Mth::clamp(zz, padding, (float)LevelConstants::LEVEL_DEPTH - padding);
|
||||
|
||||
xo = xOld = x = xx;
|
||||
yo = yOld = y = yy;
|
||||
|
||||
@@ -131,6 +131,7 @@ public:
|
||||
virtual bool isHangingEntity();
|
||||
|
||||
virtual int getAuxData();
|
||||
virtual void checkFallDamage(float ya, bool onGround);
|
||||
|
||||
protected:
|
||||
virtual void setRot(float yRot, float xRot);
|
||||
@@ -139,7 +140,6 @@ protected:
|
||||
virtual void resetPos(bool clearMore);
|
||||
virtual void outOfWorld();
|
||||
|
||||
virtual void checkFallDamage(float ya, bool onGround);
|
||||
virtual void causeFallDamage(float fallDamage2);
|
||||
virtual void markHurt();
|
||||
|
||||
|
||||
@@ -743,7 +743,6 @@ bool Mob::isWaterMob()
|
||||
void Mob::aiStep()
|
||||
{
|
||||
//@todo? 30 lines of code here in java version
|
||||
|
||||
TIMER_PUSH("ai");
|
||||
if (isImmobile()) {
|
||||
jumping = false;
|
||||
|
||||
@@ -224,6 +224,9 @@ protected:
|
||||
double xc, yc, zc;
|
||||
|
||||
public:
|
||||
void setxxa(float xxa) { this->xxa = xxa; }
|
||||
void setyya(float yya) { this->yya = yya; }
|
||||
|
||||
// Cape position accessors (for renderers)
|
||||
double getCapeX() const { return xCape; }
|
||||
double getCapeY() const { return yCape; }
|
||||
|
||||
@@ -358,3 +358,12 @@ bool Inventory::removeItem( const ItemInstance* samePtr ) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Inventory::print() {
|
||||
LOGI("%s's Inventory:\n", player->name.c_str());
|
||||
|
||||
for (int i = 0; i < numTotalSlots; i++) {
|
||||
auto item = getItem(i);
|
||||
if (item) LOGI("\t %i: %s (%i) %s\n", i, item->getName().c_str(), item->count, (player->inventory->getLinked(i))? "(Linked)" : "");
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
int getAttackDamage(Entity* entity);
|
||||
float getDestroySpeed(Tile* tile);
|
||||
bool canDestroy(Tile* tile);
|
||||
|
||||
void print();
|
||||
private:
|
||||
void setupDefault();
|
||||
public:
|
||||
|
||||
@@ -141,6 +141,11 @@ bool FillingContainer::add( ItemInstance* item )
|
||||
// // silently destroy the item when having a full inventory
|
||||
// item->count = 0;
|
||||
// return true;
|
||||
|
||||
LOGI("Inventory:\n");
|
||||
for (int i = 0; i < numTotalSlots; i++) {
|
||||
LOGI("\t %i: %s (%i)\n", i, items.at(i)->getName().c_str(), items.at(i)->count);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -290,3 +290,7 @@ bool ItemInstance::isArmorItem( const ItemInstance* instance ) {
|
||||
|
||||
return item->isArmor();
|
||||
}
|
||||
|
||||
bool ItemInstance::isBlock(const ItemInstance* instance) {
|
||||
return instance->id < 256;
|
||||
}
|
||||
@@ -81,6 +81,8 @@ public:
|
||||
|
||||
static bool isArmorItem(const ItemInstance* instance);
|
||||
|
||||
static bool isBlock(const ItemInstance* instance);
|
||||
|
||||
/**
|
||||
* Checks if this item is the same item as the other one, disregarding the
|
||||
* 'count' value.
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
if (level->setTileAndData(x, y, z, tileId, data)) {
|
||||
Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player);
|
||||
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, tile->soundType->getStepSound(), (tile->soundType->getVolume() + 1) / 2, tile->soundType->getPitch() * 0.8f);
|
||||
|
||||
printf("%f %f %f \n", player->x, player->y, player->z);
|
||||
/*
|
||||
PlaceBlockPacket packet(player->entityId, x, y, z, face, tileId, instance->getAuxValue());
|
||||
//LOGI("Place block at @ %d, %d, %d\n", x, y, z);
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#include "../Difficulty.h"
|
||||
#include "../../network/packet/ExplodePacket.h"
|
||||
|
||||
const int Level::DEPTH = LevelConstants::LEVEL_HEIGHT;
|
||||
const int Level::SEA_LEVEL = Level::DEPTH / 2 - 1;
|
||||
|
||||
Level::Level(LevelStorage* levelStorage, const std::string& levelName, const LevelSettings& settings, int generatorVersion, Dimension* fixedDimension /* = NULL */)
|
||||
: levelStorage(levelStorage),
|
||||
isClientSide(false),
|
||||
@@ -278,8 +281,8 @@ void Level::tickTiles() {
|
||||
for (int i = 0; i < pollChunkOffsetsSize; i += 2) {
|
||||
const int xp = xx + pollChunkOffsets[i];
|
||||
const int zp = zz + pollChunkOffsets[i+1];
|
||||
if (xp >= 0 && xp < CHUNK_CACHE_WIDTH &&
|
||||
zp >= 0 && zp < CHUNK_CACHE_WIDTH)
|
||||
if (xp >= 0 && xp < LevelConstants::CHUNK_CACHE_WIDTH &&
|
||||
zp >= 0 && zp < LevelConstants::CHUNK_CACHE_WIDTH)
|
||||
_chunksToPoll.insert(ChunkPos(xp, zp));
|
||||
}
|
||||
}
|
||||
@@ -427,21 +430,21 @@ bool Level::findPath(Path* path, Entity* from, int xBest, int yBest, int zBest,
|
||||
*/
|
||||
/*protected*/
|
||||
void Level::setInitialSpawn() {
|
||||
isFindingSpawn = true;
|
||||
int xSpawn = CHUNK_CACHE_WIDTH * CHUNK_WIDTH / 2; // (Level.MAX_LEVEL_SIZE - 100) * 0;
|
||||
int ySpawn = 64;
|
||||
int zSpawn = CHUNK_CACHE_WIDTH * CHUNK_DEPTH / 2; // (Level.MAX_LEVEL_SIZE - 100) * 0;
|
||||
while (!dimension->isValidSpawn(xSpawn, zSpawn)) {
|
||||
xSpawn += random.nextInt(32) - random.nextInt(32);
|
||||
zSpawn += random.nextInt(32) - random.nextInt(32);
|
||||
isFindingSpawn = true;
|
||||
int xSpawn = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_WIDTH / 2; // (Level.MAX_LEVEL_SIZE - 100) * 0;
|
||||
int ySpawn = 64;
|
||||
int zSpawn = LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_DEPTH / 2; // (Level.MAX_LEVEL_SIZE - 100) * 0;
|
||||
while (!dimension->isValidSpawn(xSpawn, zSpawn)) {
|
||||
xSpawn += random.nextInt(32) - random.nextInt(32);
|
||||
zSpawn += random.nextInt(32) - random.nextInt(32);
|
||||
|
||||
if (xSpawn < 4) xSpawn += 32;
|
||||
if (xSpawn >= LEVEL_WIDTH-4) xSpawn -= 32;
|
||||
if (xSpawn >= LevelConstants::LEVEL_WIDTH-4) xSpawn -= 32;
|
||||
if (zSpawn < 4) zSpawn += 32;
|
||||
if (zSpawn >= LEVEL_DEPTH-4) zSpawn -= 32;
|
||||
}
|
||||
levelData.setSpawn(xSpawn, ySpawn, zSpawn);
|
||||
isFindingSpawn = false;
|
||||
if (zSpawn >= LevelConstants::LEVEL_DEPTH-4) zSpawn -= 32;
|
||||
}
|
||||
levelData.setSpawn(xSpawn, ySpawn, zSpawn);
|
||||
isFindingSpawn = false;
|
||||
}
|
||||
|
||||
/*public*/
|
||||
@@ -456,12 +459,12 @@ void Level::validateSpawn() {
|
||||
zSpawn += random.nextInt(8) - random.nextInt(8);
|
||||
|
||||
if (xSpawn < 4) xSpawn += 8;
|
||||
if (xSpawn >= LEVEL_WIDTH-4) xSpawn -= 8;
|
||||
if (xSpawn >= LevelConstants::LEVEL_WIDTH-4) xSpawn -= 8;
|
||||
if (zSpawn < 4) zSpawn += 8;
|
||||
if (zSpawn >= LEVEL_DEPTH-4) zSpawn -= 8;
|
||||
}
|
||||
levelData.setXSpawn(xSpawn);
|
||||
levelData.setZSpawn(zSpawn);
|
||||
if (zSpawn >= LevelConstants::LEVEL_DEPTH-4) zSpawn -= 8;
|
||||
}
|
||||
levelData.setXSpawn(xSpawn);
|
||||
levelData.setZSpawn(zSpawn);
|
||||
}
|
||||
|
||||
int Level::getTopTile(int x, int z) {
|
||||
@@ -944,7 +947,7 @@ HitResult Level::clip(const Vec3& A, const Vec3& b, bool liquid /*= false*/, boo
|
||||
if (solidOnly && tile != NULL && tile->getAABB(this, xTile0, yTile0, zTile0) == NULL) {
|
||||
// No collision
|
||||
} else if (t > 0 && tile->mayPick(data, liquid)) {
|
||||
if(xTile0 >= 0 && zTile0 >= 0 && xTile0 < LEVEL_WIDTH && zTile0 < LEVEL_WIDTH) {
|
||||
if(xTile0 >= 0 && zTile0 >= 0 && xTile0 < LevelConstants::LEVEL_WIDTH && zTile0 < LevelConstants::LEVEL_WIDTH) {
|
||||
HitResult r = tile->clip(this, xTile0, yTile0, zTile0, a, b);
|
||||
if (r.isHit()) return r;
|
||||
}
|
||||
@@ -1984,10 +1987,10 @@ void Level::prepare() {
|
||||
;
|
||||
}
|
||||
|
||||
bool Level::mayPlace(int tileId, int x, int y, int z, bool ignoreEntities,unsigned char face) {
|
||||
int targetType = getTile(x, y, z);
|
||||
const Tile* targetTile = Tile::tiles[targetType];
|
||||
Tile* tile = Tile::tiles[tileId];
|
||||
bool Level::mayPlace(int tileId, int x, int y, int z, bool ignoreEntities,unsigned char face) {
|
||||
int targetType = getTile(x, y, z);
|
||||
const Tile* targetTile = Tile::tiles[targetType];
|
||||
Tile* tile = Tile::tiles[tileId];
|
||||
|
||||
AABB* aabb = tile->getAABB(this, x, y, z);
|
||||
if (ignoreEntities) aabb = NULL;
|
||||
@@ -2247,9 +2250,9 @@ void Level::setNightMode( bool isNightMode ) {
|
||||
}
|
||||
|
||||
bool Level::inRange( int x, int y, int z ) {
|
||||
return x >= 0 && x < LEVEL_WIDTH
|
||||
&& y >= 0 && y < LEVEL_HEIGHT
|
||||
&& z >= 0 && z < LEVEL_DEPTH;
|
||||
return x >= 0 && x < LevelConstants::LEVEL_WIDTH
|
||||
&& y >= 0 && y < LevelConstants::LEVEL_HEIGHT
|
||||
&& z >= 0 && z < LevelConstants::LEVEL_DEPTH;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -67,8 +67,8 @@ class Level: public LevelSource
|
||||
|
||||
public:
|
||||
static const int MAX_LEVEL_SIZE = 32000000;
|
||||
static const short DEPTH = LEVEL_HEIGHT;
|
||||
static const short SEA_LEVEL = DEPTH / 2 - 1;
|
||||
static const int DEPTH;
|
||||
static const int SEA_LEVEL;
|
||||
|
||||
static const int MAX_BRIGHTNESS = 15;
|
||||
static const int TICKS_PER_DAY = SharedConstants::TicksPerSecond * 60 * 16;// SharedConstants::TicksPerSecond * 60 * 12; // ORG:20*60*20
|
||||
@@ -310,6 +310,9 @@ public:
|
||||
Dimension* dimension;
|
||||
IRakNetInstance* raknetInstance;
|
||||
Random random;
|
||||
|
||||
std::set<std::string> ops;
|
||||
std::set<std::string> bannedPpl;
|
||||
protected:
|
||||
bool isFindingSpawn;
|
||||
|
||||
|
||||
10
src/world/level/LevelConstants.cpp
Normal file
10
src/world/level/LevelConstants.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "LevelConstants.h"
|
||||
|
||||
int LevelConstants::LEVEL_HEIGHT = 128;
|
||||
int LevelConstants::CHUNK_CACHE_WIDTH = 16; // in chunks
|
||||
int LevelConstants::CHUNK_WIDTH = 16; // in blocks
|
||||
int LevelConstants::CHUNK_DEPTH = 16;
|
||||
int LevelConstants::LEVEL_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH * CHUNK_WIDTH;
|
||||
int LevelConstants::LEVEL_DEPTH = LevelConstants::CHUNK_CACHE_WIDTH * CHUNK_DEPTH;
|
||||
int LevelConstants::CHUNK_COLUMNS = LevelConstants::CHUNK_WIDTH * LevelConstants::CHUNK_DEPTH;
|
||||
int LevelConstants::CHUNK_BLOCK_COUNT = LevelConstants::CHUNK_COLUMNS * LevelConstants::LEVEL_HEIGHT;
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef _MINECRAFT_WORLD_LEVELCONSTANTS_H_
|
||||
#define _MINECRAFT_WORLD_LEVELCONSTANTS_H_
|
||||
#pragma once
|
||||
|
||||
|
||||
const int LEVEL_HEIGHT = 128;
|
||||
const int CHUNK_CACHE_WIDTH = 16; // in chunks
|
||||
const int CHUNK_WIDTH = 16; // in blocks
|
||||
const int CHUNK_DEPTH = 16;
|
||||
const int LEVEL_WIDTH = CHUNK_CACHE_WIDTH * CHUNK_WIDTH;
|
||||
const int LEVEL_DEPTH = CHUNK_CACHE_WIDTH * CHUNK_DEPTH;
|
||||
const int CHUNK_COLUMNS = CHUNK_WIDTH * CHUNK_DEPTH;
|
||||
const int CHUNK_BLOCK_COUNT = CHUNK_COLUMNS * LEVEL_HEIGHT;
|
||||
|
||||
#endif
|
||||
class LevelConstants {
|
||||
public:
|
||||
static int CHUNK_CACHE_WIDTH; // in chunks
|
||||
static int LEVEL_WIDTH;
|
||||
static int LEVEL_DEPTH;
|
||||
static int LEVEL_HEIGHT;
|
||||
|
||||
static int CHUNK_WIDTH; // in blocks
|
||||
static int CHUNK_DEPTH;
|
||||
static int CHUNK_COLUMNS;
|
||||
static int CHUNK_BLOCK_COUNT;
|
||||
};
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "../LevelConstants.h"
|
||||
|
||||
class ChunkCache: public ChunkSource {
|
||||
//static const int CHUNK_CACHE_WIDTH = CHUNK_CACHE_WIDTH; // WAS 32;
|
||||
//static const int LevelConstants::CHUNK_CACHE_WIDTH = LevelConstants::CHUNK_CACHE_WIDTH; // WAS 32;
|
||||
static const int MAX_SAVES = 2;
|
||||
public:
|
||||
ChunkCache(Level* level_, ChunkStorage* storage_, ChunkSource* source_)
|
||||
@@ -24,14 +24,17 @@ public:
|
||||
isChunkCache = true;
|
||||
//emptyChunk = new EmptyLevelChunk(level_, emptyChunkBlocks, 0, 0);
|
||||
emptyChunk = new EmptyLevelChunk(level_, NULL, 0, 0);
|
||||
memset(chunks, 0, sizeof(LevelChunk*) * CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH);
|
||||
|
||||
chunks = new LevelChunk *[LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH];
|
||||
memset(chunks, 0, sizeof(LevelChunk*) * LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH);
|
||||
LOGI("Chunks allocated.");
|
||||
}
|
||||
|
||||
~ChunkCache() {
|
||||
delete source;
|
||||
delete emptyChunk;
|
||||
|
||||
for (int i = 0; i < CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH; i++)
|
||||
for (int i = 0; i < LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH; i++)
|
||||
{
|
||||
if (chunks[i])
|
||||
{
|
||||
@@ -42,7 +45,7 @@ public:
|
||||
}
|
||||
|
||||
bool fits(int x, int z) {
|
||||
return (x >= 0 && z >= 0 && x < CHUNK_CACHE_WIDTH && z < CHUNK_CACHE_WIDTH);
|
||||
return (x >= 0 && z >= 0 && x < LevelConstants::CHUNK_CACHE_WIDTH && z < LevelConstants::CHUNK_CACHE_WIDTH);
|
||||
}
|
||||
|
||||
bool hasChunk(int x, int z) {
|
||||
@@ -52,9 +55,9 @@ public:
|
||||
if (x == xLast && z == zLast && last != NULL) {
|
||||
return true;
|
||||
}
|
||||
int xs = x & (CHUNK_CACHE_WIDTH - 1);
|
||||
int zs = z & (CHUNK_CACHE_WIDTH - 1);
|
||||
int slot = xs + zs * CHUNK_CACHE_WIDTH;
|
||||
int xs = x & (LevelConstants::CHUNK_CACHE_WIDTH - 1);
|
||||
int zs = z & (LevelConstants::CHUNK_CACHE_WIDTH - 1);
|
||||
int slot = xs + zs * LevelConstants::CHUNK_CACHE_WIDTH;
|
||||
return chunks[slot] != NULL && (chunks[slot] == emptyChunk || chunks[slot]->isAt(x, z));
|
||||
}
|
||||
|
||||
@@ -71,9 +74,9 @@ public:
|
||||
}
|
||||
if (!fits(x, z)) return emptyChunk;
|
||||
//if (!level->isFindingSpawn && !fits(x, z)) return emptyChunk;
|
||||
int xs = x & (CHUNK_CACHE_WIDTH - 1);
|
||||
int zs = z & (CHUNK_CACHE_WIDTH - 1);
|
||||
int slot = xs + zs * CHUNK_CACHE_WIDTH;
|
||||
int xs = x & (LevelConstants::CHUNK_CACHE_WIDTH - 1);
|
||||
int zs = z & (LevelConstants::CHUNK_CACHE_WIDTH - 1);
|
||||
int slot = xs + zs * LevelConstants::CHUNK_CACHE_WIDTH;
|
||||
if (!hasChunk(x, z)) {
|
||||
if (chunks[slot] != NULL) {
|
||||
chunks[slot]->unload();
|
||||
@@ -202,8 +205,8 @@ public:
|
||||
void saveAll(bool onlyUnsaved) {
|
||||
if (storage != NULL) {
|
||||
std::vector<LevelChunk*> chunks;
|
||||
for (int z = 0; z < CHUNK_CACHE_WIDTH; ++z)
|
||||
for (int x = 0; x < CHUNK_CACHE_WIDTH; ++x) {
|
||||
for (int z = 0; z < LevelConstants::CHUNK_CACHE_WIDTH; ++z)
|
||||
for (int x = 0; x < LevelConstants::CHUNK_CACHE_WIDTH; ++x) {
|
||||
LevelChunk* chunk = level->getChunk(x, z);
|
||||
if (!onlyUnsaved || chunk->shouldSave(false))
|
||||
chunks.push_back( chunk );
|
||||
@@ -214,7 +217,7 @@ public:
|
||||
private:
|
||||
LevelChunk* load(int x, int z) {
|
||||
if (storage == NULL) return emptyChunk;
|
||||
if (x < 0 || x >= CHUNK_CACHE_WIDTH || z < 0 || z >= CHUNK_CACHE_WIDTH)
|
||||
if (x < 0 || x >= LevelConstants::CHUNK_CACHE_WIDTH || z < 0 || z >= LevelConstants::CHUNK_CACHE_WIDTH)
|
||||
{
|
||||
return emptyChunk;
|
||||
}
|
||||
@@ -257,7 +260,7 @@ private:
|
||||
LevelChunk* emptyChunk;
|
||||
ChunkSource* source;
|
||||
ChunkStorage* storage;
|
||||
LevelChunk* chunks[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
||||
LevelChunk** chunks;
|
||||
Level* level;
|
||||
|
||||
LevelChunk* last;
|
||||
|
||||
@@ -12,13 +12,14 @@
|
||||
|
||||
/*static*/
|
||||
bool LevelChunk::touchedSky = false;
|
||||
int LevelChunk::ChunkBlockCount;
|
||||
|
||||
LevelChunk::LevelChunk( Level* level, int x, int z )
|
||||
: level(level),
|
||||
x(x),
|
||||
z(z),
|
||||
xt(x * CHUNK_WIDTH),
|
||||
zt(z * CHUNK_DEPTH)
|
||||
xt(x * LevelConstants::CHUNK_WIDTH),
|
||||
zt(z * LevelConstants::CHUNK_DEPTH)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -27,8 +28,8 @@ LevelChunk::LevelChunk( Level* level, unsigned char* blocks, int x, int z )
|
||||
: level(level),
|
||||
x(x),
|
||||
z(z),
|
||||
xt(x * CHUNK_WIDTH),
|
||||
zt(z * CHUNK_DEPTH),
|
||||
xt(x * LevelConstants::CHUNK_WIDTH),
|
||||
zt(z * LevelConstants::CHUNK_DEPTH),
|
||||
blocks(blocks),
|
||||
data(ChunkBlockCount),
|
||||
skyLight(ChunkBlockCount),
|
||||
@@ -45,6 +46,9 @@ LevelChunk::~LevelChunk()
|
||||
|
||||
void LevelChunk::init()
|
||||
{
|
||||
heightmap = new char[LevelConstants::CHUNK_COLUMNS];
|
||||
updateMap = new unsigned char[LevelConstants::CHUNK_COLUMNS];
|
||||
|
||||
terrainPopulated = false;
|
||||
dontSave = false;
|
||||
unsaved = false;
|
||||
|
||||
@@ -106,9 +106,9 @@ private:
|
||||
void recalcHeight(int x, int yStart, int z);
|
||||
public:
|
||||
static bool touchedSky;
|
||||
static const int ChunkBlockCount = CHUNK_BLOCK_COUNT;
|
||||
static const int ChunkSize = ChunkBlockCount;
|
||||
static const int UpdateMapBitShift = 4; // power of (LEVEL_HEIGHT / 8) == 16
|
||||
static int ChunkBlockCount;
|
||||
const int ChunkSize = ChunkBlockCount;
|
||||
static const int UpdateMapBitShift = 4; // power of (LevelConstants::LEVEL_HEIGHT / 8) == 16
|
||||
|
||||
int blocksLength; // ? needed or not? (i.e. are all chunks the same size?)
|
||||
|
||||
@@ -118,12 +118,12 @@ public:
|
||||
DataLayer skyLight;
|
||||
DataLayer blockLight;
|
||||
|
||||
char heightmap[CHUNK_COLUMNS];
|
||||
unsigned char updateMap[CHUNK_COLUMNS]; // marks regions within block columns that have been modified
|
||||
char* heightmap; // [LevelConstants::CHUNK_COLUMNS]
|
||||
unsigned char* updateMap; // marks regions within block columns that have been modified [LevelConstants::CHUNK_COLUMNS]
|
||||
int minHeight;
|
||||
|
||||
const int x, z;
|
||||
const int xt, zt;
|
||||
int x, z;
|
||||
int xt, zt;
|
||||
|
||||
bool terrainPopulated;
|
||||
bool unsaved;
|
||||
|
||||
@@ -64,9 +64,9 @@ RandomLevelSource::~RandomLevelSource() {
|
||||
|
||||
/*public*/
|
||||
void RandomLevelSource::prepareHeights(int xOffs, int zOffs, unsigned char* blocks, /*Biome*/void* biomes, float* temperatures) {
|
||||
|
||||
int xChunks = 16 / CHUNK_WIDTH;
|
||||
int waterHeight = Level::DEPTH - 64;
|
||||
|
||||
int xChunks = 16 / LevelConstants::CHUNK_WIDTH;
|
||||
int waterHeight = Level::DEPTH - 64;
|
||||
|
||||
int xSize = xChunks + 1;
|
||||
int ySize = 128 / CHUNK_HEIGHT + 1;
|
||||
@@ -87,36 +87,36 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, unsigned char* bloc
|
||||
float s2a = (buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 1)] - s2) * yStep;
|
||||
float s3a = (buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 1)] - s3) * yStep;
|
||||
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
float xStep = 1 / (float) CHUNK_WIDTH;
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
float xStep = 1 / (float) LevelConstants::CHUNK_WIDTH;
|
||||
|
||||
float _s0 = s0;
|
||||
float _s1 = s1;
|
||||
float _s0a = (s2 - s0) * xStep;
|
||||
float _s1a = (s3 - s1) * xStep;
|
||||
|
||||
for (int x = 0; x < CHUNK_WIDTH; x++) {
|
||||
int offs = (x + xc * CHUNK_WIDTH) << 11 | (0 + zc * CHUNK_WIDTH) << 7 | (yc * CHUNK_HEIGHT + y);
|
||||
int step = 1 << 7;
|
||||
float zStep = 1 / (float) CHUNK_WIDTH;
|
||||
for (int x = 0; x < LevelConstants::CHUNK_WIDTH; x++) {
|
||||
int offs = (x + xc * LevelConstants::CHUNK_WIDTH) << 11 | (0 + zc * LevelConstants::CHUNK_WIDTH) << 7 | (yc * CHUNK_HEIGHT + y);
|
||||
int step = 1 << 7;
|
||||
float zStep = 1 / (float) LevelConstants::CHUNK_WIDTH;
|
||||
|
||||
float val = _s0;
|
||||
float vala = (_s1 - _s0) * zStep;
|
||||
for (int z = 0; z < CHUNK_WIDTH; z++) {
|
||||
// + (zc * CHUNK_WIDTH + z)];
|
||||
float temp = temperatures[(xc * CHUNK_WIDTH + x) * 16 + (zc * CHUNK_WIDTH + z)];
|
||||
int tileId = 0;
|
||||
if (yc * CHUNK_HEIGHT + y < waterHeight) {
|
||||
if (temp < SNOW_CUTOFF && yc * CHUNK_HEIGHT + y >= waterHeight - 1) {
|
||||
tileId = Tile::ice->id;
|
||||
} else {
|
||||
tileId = Tile::calmWater->id;
|
||||
}
|
||||
}
|
||||
if (val > 0) {
|
||||
tileId = Tile::rock->id;
|
||||
} else {
|
||||
}
|
||||
float val = _s0;
|
||||
float vala = (_s1 - _s0) * zStep;
|
||||
for (int z = 0; z < LevelConstants::CHUNK_WIDTH; z++) {
|
||||
// + (zc * LevelConstants::CHUNK_WIDTH + z)];
|
||||
float temp = temperatures[(xc * LevelConstants::CHUNK_WIDTH + x) * 16 + (zc * LevelConstants::CHUNK_WIDTH + z)];
|
||||
int tileId = 0;
|
||||
if (yc * CHUNK_HEIGHT + y < waterHeight) {
|
||||
if (temp < SNOW_CUTOFF && yc * CHUNK_HEIGHT + y >= waterHeight - 1) {
|
||||
tileId = Tile::ice->id;
|
||||
} else {
|
||||
tileId = Tile::calmWater->id;
|
||||
}
|
||||
}
|
||||
if (val > 0) {
|
||||
tileId = Tile::rock->id;
|
||||
} else {
|
||||
}
|
||||
|
||||
blocks[offs] = (unsigned char) tileId;
|
||||
offs += step;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#if !defined(DEMO_MODE) && !defined(APPLE_DEMO_PROMOTION)
|
||||
|
||||
#include "LevelData.h"
|
||||
@@ -88,6 +91,9 @@ ExternalFileLevelStorage::ExternalFileLevelStorage(const std::string& levelId, c
|
||||
{
|
||||
createFolderIfNotExists(levelPath.c_str());
|
||||
|
||||
std::string playerFolder = levelPath + "/players";
|
||||
createFolderIfNotExists(playerFolder.c_str());
|
||||
|
||||
std::string datFileName = levelPath + "/" + fnLevelDat;
|
||||
std::string levelFileName = levelPath + "/" + fnPlayerDat;
|
||||
loadedLevelData = new LevelData();
|
||||
@@ -113,6 +119,7 @@ void ExternalFileLevelStorage::saveLevelData(LevelData& levelData, std::vector<P
|
||||
|
||||
void ExternalFileLevelStorage::saveLevelData( const std::string& levelPath, LevelData& levelData, std::vector<Player*>* players )
|
||||
{
|
||||
// @todo: completely rewrite
|
||||
std::string directory = levelPath + "/";
|
||||
std::string tmpFile = directory + fnLevelDatNew;
|
||||
std::string datFile = directory + fnLevelDat;
|
||||
@@ -141,6 +148,67 @@ void ExternalFileLevelStorage::saveLevelData( const std::string& levelPath, Leve
|
||||
|
||||
// Remove the temporary save, if the rename didn't do it
|
||||
remove(tmpFile.c_str());
|
||||
|
||||
// Save players
|
||||
// fuck mojang for that
|
||||
if (!players || players->empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& player : *players) {
|
||||
if (player != NULL) {
|
||||
savePlayer(*player, directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalFileLevelStorage::savePlayer(Player& player, const std::string& worldDir) {
|
||||
std::string playerPath = worldDir + "/players/" + player.name + ".dat";
|
||||
|
||||
LOGI("Saving player %s to %s...\n", player.name.c_str(), playerPath.c_str());
|
||||
|
||||
RakNet::BitStream data;
|
||||
RakDataOutput buf(data);
|
||||
CompoundTag playerTag;
|
||||
player.saveWithoutId(&playerTag);
|
||||
|
||||
NbtIo::write(&playerTag, &buf);
|
||||
|
||||
std::ofstream file(playerPath, std::ios::out | std::ios::binary);
|
||||
file.write((const char*)data.GetData(), (size_t)data.GetNumberOfBytesUsed());
|
||||
}
|
||||
|
||||
bool ExternalFileLevelStorage::loadPlayer(Player& player, const std::string& worldDir) {
|
||||
std::string playerPath = worldDir + "/players/" + player.name + ".dat";
|
||||
|
||||
LOGI("Loading player %s from %s...\n", player.name.c_str(), playerPath.c_str());
|
||||
|
||||
std::ifstream file(playerPath, std::ios::in | std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
RakNet::BitStream bitStream(data.data(), data.size(), false);
|
||||
RakDataInput stream(bitStream);
|
||||
|
||||
CompoundTag* tag = NbtIo::read(&stream);
|
||||
if (tag) {
|
||||
player.load(tag);
|
||||
tag->deleteChildren();
|
||||
delete tag;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExternalFileLevelStorage::savePlayer(Player& player) {
|
||||
ExternalFileLevelStorage::savePlayer(player, levelPath);
|
||||
}
|
||||
|
||||
bool ExternalFileLevelStorage::loadPlayer(Player& player) {
|
||||
return ExternalFileLevelStorage::loadPlayer(player, levelPath);
|
||||
}
|
||||
|
||||
LevelData* ExternalFileLevelStorage::prepareLevel(Level* _level)
|
||||
@@ -275,8 +343,8 @@ bool ExternalFileLevelStorage::readPlayerData(const std::string& filename, Level
|
||||
Vec3& pos = dest.playerData.pos;
|
||||
if (pos.x < 0.5f) pos.x = 0.5f;
|
||||
if (pos.z < 0.5f) pos.z = 0.5f;
|
||||
if (pos.x > (LEVEL_WIDTH - 0.5f)) pos.x = LEVEL_WIDTH - 0.5f;
|
||||
if (pos.z > (LEVEL_DEPTH - 0.5f)) pos.z = LEVEL_DEPTH - 0.5f;
|
||||
if (pos.x > (LevelConstants::LEVEL_WIDTH - 0.5f)) pos.x = LevelConstants::LEVEL_WIDTH - 0.5f;
|
||||
if (pos.z > (LevelConstants::LEVEL_DEPTH - 0.5f)) pos.z = LevelConstants::LEVEL_DEPTH - 0.5f;
|
||||
if (pos.y < 0) pos.y = 64;
|
||||
|
||||
dest.playerDataVersion = version;
|
||||
@@ -294,14 +362,14 @@ void ExternalFileLevelStorage::tick()
|
||||
LOGI("Saving level...\n");
|
||||
|
||||
// look for chunks that needs to be saved
|
||||
for (int z = 0; z < CHUNK_CACHE_WIDTH; z++)
|
||||
for (int z = 0; z < LevelConstants::CHUNK_CACHE_WIDTH; z++)
|
||||
{
|
||||
for (int x = 0; x < CHUNK_CACHE_WIDTH; x++)
|
||||
for (int x = 0; x < LevelConstants::CHUNK_CACHE_WIDTH; x++)
|
||||
{
|
||||
LevelChunk* chunk = level->getChunk(x, z);
|
||||
if (chunk && chunk->unsaved)
|
||||
{
|
||||
int pos = x + z * CHUNK_CACHE_WIDTH;
|
||||
int pos = x + z * LevelConstants::CHUNK_CACHE_WIDTH;
|
||||
UnsavedChunkList::iterator prev = unsavedChunkList.begin();
|
||||
for ( ; prev != unsavedChunkList.end(); ++prev)
|
||||
{
|
||||
@@ -347,13 +415,13 @@ void ExternalFileLevelStorage::save(Level* level, LevelChunk* levelChunk)
|
||||
|
||||
// Write chunk
|
||||
RakNet::BitStream chunkData;
|
||||
chunkData.Write((const char*)levelChunk->getBlockData(), CHUNK_BLOCK_COUNT);
|
||||
chunkData.Write((const char*)levelChunk->data.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData.Write((const char*)levelChunk->getBlockData(), LevelConstants::CHUNK_BLOCK_COUNT);
|
||||
chunkData.Write((const char*)levelChunk->data.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
|
||||
chunkData.Write((const char*)levelChunk->skyLight.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData.Write((const char*)levelChunk->blockLight.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData.Write((const char*)levelChunk->skyLight.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData.Write((const char*)levelChunk->blockLight.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
|
||||
chunkData.Write((const char*)levelChunk->updateMap, CHUNK_COLUMNS);
|
||||
chunkData.Write((const char*)levelChunk->updateMap, LevelConstants::CHUNK_COLUMNS);
|
||||
|
||||
regionFile->writeChunk(levelChunk->x, levelChunk->z, chunkData);
|
||||
|
||||
@@ -385,16 +453,16 @@ LevelChunk* ExternalFileLevelStorage::load(Level* level, int x, int z)
|
||||
|
||||
chunkData->ResetReadPointer();
|
||||
|
||||
unsigned char* blockIds = new unsigned char[CHUNK_BLOCK_COUNT];
|
||||
chunkData->Read((char*)blockIds, CHUNK_BLOCK_COUNT);
|
||||
unsigned char* blockIds = new unsigned char[LevelConstants::CHUNK_BLOCK_COUNT];
|
||||
chunkData->Read((char*)blockIds, LevelConstants::CHUNK_BLOCK_COUNT);
|
||||
|
||||
LevelChunk* levelChunk = new LevelChunk(level, blockIds, x, z);
|
||||
chunkData->Read((char*)levelChunk->data.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData->Read((char*)levelChunk->data.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
if (loadedStorageVersion >= ChunkVersion_Light) {
|
||||
chunkData->Read((char*)levelChunk->skyLight.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData->Read((char*)levelChunk->blockLight.data, CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData->Read((char*)levelChunk->skyLight.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
chunkData->Read((char*)levelChunk->blockLight.data, LevelConstants::CHUNK_BLOCK_COUNT / 2);
|
||||
}
|
||||
chunkData->Read((char*)levelChunk->updateMap, CHUNK_COLUMNS);
|
||||
chunkData->Read((char*)levelChunk->updateMap, LevelConstants::CHUNK_COLUMNS);
|
||||
// This will be difficult to maintain.. Storage version could be per chunk
|
||||
// too (but probably better to just read all -> write all, so that all
|
||||
// chunks got same version anyway)
|
||||
@@ -417,7 +485,7 @@ LevelChunk* ExternalFileLevelStorage::load(Level* level, int x, int z)
|
||||
//bool dbg = (x == 7 && z == 9);
|
||||
|
||||
//int t = 0;
|
||||
//for (int i = 0; i < CHUNK_COLUMNS; ++i) {
|
||||
//for (int i = 0; i < LevelConstants::CHUNK_COLUMNS; ++i) {
|
||||
// char bits = levelChunk->updateMap[i];
|
||||
// t += (bits != 0);
|
||||
// int xx = x * 16 + i%16;
|
||||
|
||||
@@ -67,6 +67,19 @@ public:
|
||||
void saveGame(Level* level);
|
||||
void saveAll(Level* level, std::vector<LevelChunk*>& levelChunks);
|
||||
|
||||
/**
|
||||
* @brief Save player to <world name>/player/<player name>.dat file
|
||||
*/
|
||||
static void savePlayer(Player& player, const std::string& worldDir);
|
||||
|
||||
/**
|
||||
* @brief Load player from <world name>/player/<player name>.dat file
|
||||
*/
|
||||
static bool loadPlayer(Player& player, const std::string& worldDir);
|
||||
|
||||
virtual void savePlayer(Player& player);
|
||||
virtual bool loadPlayer(Player& player);
|
||||
|
||||
virtual void tick();
|
||||
virtual void flush() {}
|
||||
private:
|
||||
|
||||
@@ -32,6 +32,9 @@ public:
|
||||
virtual void saveGame(Level* level) {}
|
||||
virtual void loadEntities(Level* level, LevelChunk* levelChunk) {}
|
||||
|
||||
virtual void savePlayer(Player& player) = 0;
|
||||
virtual bool loadPlayer(Player& player) = 0;
|
||||
|
||||
//void checkSession() throws LevelConflictException;
|
||||
//PlayerIO getPlayerIO();
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ bool Mushroom::mayPlaceOn( int tile ) {
|
||||
}
|
||||
|
||||
bool Mushroom::canSurvive( Level* level, int x, int y, int z ) {
|
||||
if (y < 0 || y >= LEVEL_HEIGHT/*Level::maxBuildHeight*/)
|
||||
if (y < 0 || y >= LevelConstants::LEVEL_HEIGHT/*Level::maxBuildHeight*/)
|
||||
return false;
|
||||
|
||||
int below = level->getTile(x, y - 1, z);
|
||||
|
||||
@@ -53,7 +53,7 @@ bool NetherReactor::canSpawnStartNetherReactor( Level* level, int x, int y, int
|
||||
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) {
|
||||
} else if(y > LevelConstants::LEVEL_HEIGHT - 28) {
|
||||
player->displayClientMessage("The nether reactor needs to be built lower down.");
|
||||
return false;
|
||||
} else if(y < 2) {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "../../item/StoneSlabTileItem.h"
|
||||
#include "../../item/SaplingTileItem.h"
|
||||
#include "../../item/ItemCategory.h"
|
||||
#include "world/level/LevelConstants.h"
|
||||
|
||||
const int Tile::RENDERLAYER_OPAQUE = 0;
|
||||
const int Tile::RENDERLAYER_ALPHATEST = 1;
|
||||
@@ -512,10 +513,15 @@ 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
|
||||
// @fixme @ahtung temp fix
|
||||
|
||||
auto xz = LevelConstants::CHUNK_CACHE_WIDTH == 16 ? 256 :
|
||||
LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH / (LevelConstants::CHUNK_CACHE_WIDTH * LevelConstants::CHUNK_CACHE_WIDTH / 256 / 2);
|
||||
|
||||
if (face == 2 && z == -1) return false;
|
||||
if (face == 3 && z == 256) return false;
|
||||
if (face == 3 && z == xz) return false;
|
||||
if (face == 4 && x == -1) return false;
|
||||
if (face == 5 && x == 256) return false;
|
||||
if (face == 5 && x == xz) return false;
|
||||
// Common
|
||||
if (face == 0 && yy0 > 0) return true;
|
||||
if (face == 1 && yy1 < 1) return true;
|
||||
|
||||
@@ -130,7 +130,7 @@ Vec3 NetherReactorTileEntity::getSpawnPosition( float minDistance, float varible
|
||||
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) {
|
||||
while(enemyPosition.x < 0 || enemyPosition.z < 0 || enemyPosition.x >= LevelConstants::LEVEL_WIDTH || enemyPosition.z >= LevelConstants::LEVEL_DEPTH) {
|
||||
enemyPosition = getSpawnPosition(3, 4, -1);
|
||||
}
|
||||
MobSpawner::addMob(level, mob, enemyPosition.x, enemyPosition.y, enemyPosition.z, 0, 0, true);
|
||||
@@ -140,7 +140,7 @@ void NetherReactorTileEntity::spawnEnemy() {
|
||||
|
||||
void NetherReactorTileEntity::spawnItem() {
|
||||
Vec3 itemPosition= getSpawnPosition(3, 4, -1);
|
||||
while(itemPosition.x < 0 || itemPosition.z < 0 || itemPosition.x >= LEVEL_WIDTH || itemPosition.z >= LEVEL_DEPTH) {
|
||||
while(itemPosition.x < 0 || itemPosition.z < 0 || itemPosition.x >= LevelConstants::LEVEL_WIDTH || itemPosition.z >= LevelConstants::LEVEL_DEPTH) {
|
||||
itemPosition = getSpawnPosition(3, 4, -1);
|
||||
}
|
||||
ItemEntity* item = new ItemEntity(level, itemPosition.x, itemPosition.y, itemPosition.z, getSpawnItem());
|
||||
|
||||
Reference in New Issue
Block a user