#include "Chunk.h" #include "Constants.h" #include "Game.h" Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId ) : EventThrower(), zGame( zGame ), dimensionId( dimensionId ), location( location ) { blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ]; memset( blocks, 0, sizeof( Block * ) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ); zNeighbours[ 0 ] = 0; zNeighbours[ 1 ] = 0; zNeighbours[ 2 ] = 0; zNeighbours[ 3 ] = 0; } Chunk::~Chunk() { for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ ) { if( blocks[ i ] ) blocks[ i ]->release(); } delete[] blocks; } Block *Chunk::getBlockAt( Framework::Vec3 location ) { location.x -= this->location.x - CHUNK_SIZE / 2; location.y -= this->location.x - CHUNK_SIZE / 2; Block *result = dynamic_cast( blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ]->getThis() ); return result; } void Chunk::putBlockAt( Framework::Vec3 location, Block *block ) { location.x -= this->location.x - CHUNK_SIZE / 2; location.y -= this->location.x - CHUNK_SIZE / 2; int index = ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z; Block *old = blocks[ index ]; blocks[ index ] = block; Block *neighbor = zGame->zBlockAt( Framework::Vec3( location.x - 1, location.y, location.z ), dimensionId ); if( neighbor ) neighbor->neighbours[ WEST ] = block; neighbor = zGame->zBlockAt( Framework::Vec3( location.x + 1, location.y, location.z ), dimensionId ); if( neighbor ) neighbor->neighbours[ EAST ] = block; neighbor = zGame->zBlockAt( Framework::Vec3( location.x, location.y - 1, location.z ), dimensionId ); if( neighbor ) neighbor->neighbours[ NORTH ] = block; neighbor = zGame->zBlockAt( Framework::Vec3( location.x, location.y + 1, location.z ), dimensionId ); if( neighbor ) neighbor->neighbours[ SOUTH ] = block; neighbor = zGame->zBlockAt( Framework::Vec3( location.x, location.y, location.z - 1 ), dimensionId ); if( neighbor ) neighbor->neighbours[ BOTTOM ] = block; neighbor = zGame->zBlockAt( Framework::Vec3( location.x, location.y, location.z + 1 ), dimensionId ); if( neighbor ) neighbor->neighbours[ TOP ] = block; if( old ) old->release(); } void Chunk::setNeighbor( Direction dir, Chunk *zChunk ) { zNeighbours[ dir ] = zChunk; for( int i = 0; i < CHUNK_SIZE; i++ ) { for( int z = 0; z < WORLD_HEIGHT; z++ ) { if( dir == NORTH ) { int index = i * CHUNK_SIZE * CHUNK_SIZE + z; if( blocks[ index ] ) blocks[ index ]->neighbours[ NORTH ] = zChunk->blocks[ ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z ]; } else if( dir == EAST ) { int index = ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z; if( blocks[ index ] ) blocks[ index ]->neighbours[ EAST ] = zChunk->blocks[ i * CHUNK_SIZE + z ]; } else if( dir == SOUTH ) { int index = ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z; if( blocks[ index ] ) blocks[ index ]->neighbours[ SOUTH ] = zChunk->blocks[ i * CHUNK_SIZE * CHUNK_SIZE + z ]; } else if( dir == WEST ) { int index = i * CHUNK_SIZE + z; if( blocks[ index ] ) blocks[ index ]->neighbours[ WEST ] = zChunk->blocks[ ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z ]; } } } } void Chunk::load( Framework::Reader *zReader ) { for( int x = 0; x < CHUNK_SIZE; x++ ) { for( int y = 0; y < CHUNK_SIZE; y++ ) { for( int z = 0; z < WORLD_HEIGHT; z++ ) { int blockType; zReader->lese( (char *)&blockType, 4 ); if( blockType >= 0 ) { Block *block = StaticRegistry::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3( x, y, z ), zGame, zReader ); blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ] = block; } } } } } void Chunk::save( Framework::Writer *zWriter ) { for( int x = 0; x < CHUNK_SIZE; x++ ) { for( int y = 0; y < CHUNK_SIZE; y++ ) { for( int z = 0; z < WORLD_HEIGHT; z++ ) { int index = ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z; int blockType = blocks[ index ] ? blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ]->zType->getId() : -1; zWriter->schreibe( (char *)&blockType, 4 ); if( blockType >= 0 ) StaticRegistry::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter ); } } } } int Chunk::getDimensionId() const { return dimensionId; }