123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #include "Dimension.h"
- #include "Constants.h"
- #include "Datei.h"
- #include "Game.h"
- #include "Globals.h"
- #include "World.h"
- using namespace Framework;
- #define MAX_VIEW_DISTANCE CHUNK_SIZE * 8
- Dimension::Dimension( int id )
- : dimensionId( id ),
- chunks( new Trie<Chunk>() ),
- entities( new RCArray<Entity>() )
- {}
- Dimension::~Dimension()
- {
- entities->release();
- chunks->release();
- }
- void Dimension::getAddrOf( Punkt cPos, char* addr ) const
- {
- *(int*)addr = cPos.x;
- *((int*)addr + 1) = cPos.y;
- }
- void Dimension::getAddrOfWorld( Punkt wPos, char* addr ) const
- {
- if( wPos.x < 0 )
- wPos.x -= CHUNK_SIZE;
- if( wPos.y < 0 ) // needed because otherwise would (-8, -8) have the same adress as (8, 8)
- wPos.y -= CHUNK_SIZE;
- wPos /= CHUNK_SIZE;
- getAddrOf( wPos, addr );
- }
- Chunk* Dimension::zChunk( Punkt wPos ) const
- {
- char addr[ 8 ];
- getAddrOfWorld( wPos, addr );
- return chunks->z( addr, 8 );
- }
- Block* Dimension::zBlock( Vec3<int> location )
- {
- Chunk* c = zChunk( currentGame->getChunkCenter( location.x, location.y ) );
- if( c )
- return c->zBlockAt( location );
- return 0;
- }
- Block* Dimension::getBlock( Vec3<int> location )
- {
- cs.lock();
- Chunk* c = zChunk( currentGame->getChunkCenter( location.x, location.y ) );
- if( c )
- {
- Block* b = c->zBlockAt( location );
- b = b ? dynamic_cast<Block*>(b->getThis()) : 0;
- cs.unlock();
- return b;
- }
- cs.unlock();
- return 0;
- }
- void Dimension::addEntity( Entity* entity )
- {
- entities->add( entity );
- }
- void Dimension::setChunk( Chunk* chunk, Punkt center, World* zWorld )
- {
- char addr[ 8 ];
- getAddrOfWorld( center, addr );
- Chunk* old = chunks->z( addr, 8 );
- cs.lock();
- if( old )
- {
- zWorld->setVisibility( old, 0 );
- int index = 0;
- for( auto iterator = chunkList.begin(); iterator; ++iterator, ++index )
- {
- if( (Chunk*)iterator == old )
- {
- if( chunk )
- iterator.set( chunk );
- else
- chunkList.remove( index );
- break;
- }
- }
- }
- else if( chunk )
- chunkList.add( chunk );
- chunks->set( addr, 8, chunk );
- if( chunk )
- {
- zWorld->setVisibility( chunk, 1 );
- }
- cs.unlock();
- }
- int Dimension::getDimensionId() const
- {
- return dimensionId;
- }
- bool Dimension::hasChunck( int x, int y ) const
- {
- return zChunk( Punkt( x, y ) );
- }
- void Dimension::removeDistantChunks( Punkt wPos, World* zWorld )
- {
- Array<int> removed;
- int index = 0;
- for( Chunk* chunk : chunkList )
- {
- if( (chunk->getCenter() - wPos).getLength() > MAX_VIEW_DISTANCE )
- removed.add( index, 0 );
- index++;
- }
- for( int i : removed )
- {
- Chunk* chunk = chunkList.get( i );
- zWorld->setVisibility( chunk, 0 );
- setChunk( 0, chunk->getCenter(), zWorld );
- }
- }
- void Dimension::setBlock( Block* block )
- {
- cs.lock();
- Chunk* c = zChunk( currentGame->getChunkCenter( (int)floor( block->getPos().x ), (int)floor( block->getPos().y ) ) );
- if( c )
- c->setBlock( block );
- else
- block->release();
- cs.unlock();
- }
- void Dimension::removeBlock( Block* zBlock )
- {
- cs.lock();
- Chunk* c = zChunk( currentGame->getChunkCenter( (int)floor( zBlock->getPos().x ), (int)floor( zBlock->getPos().y ) ) );
- if( c )
- c->removeBlock( zBlock );
- cs.unlock();
- }
- Entity* Dimension::zEntity( int id )
- {
- cs.lock();
- for( Entity* e : *entities )
- {
- if( e->getId() == id )
- {
- cs.unlock();
- return e;
- }
- }
- cs.unlock();
- return 0;
- }
- Entity* Dimension::getEntity( int id )
- {
- cs.lock();
- for( Entity* e : *entities )
- {
- if( e->getId() == id )
- {
- Entity* result = dynamic_cast<Entity*>(e->getThis());
- cs.unlock();
- return result;
- }
- }
- cs.unlock();
- return 0;
- }
- void Dimension::removeEntity( int id )
- {
- currentGame->lockWorld();
- cs.lock();
- int index = 0;
- for( Entity* e : *entities )
- {
- if( e->getId() == id )
- {
- currentGame->setVisibility( e, 0 );
- entities->remove( index );
- cs.unlock();
- currentGame->unlockWorld();
- return;
- }
- index++;
- }
- cs.unlock();
- currentGame->unlockWorld();
- }
|