#include #include #include #include #include "World.h" #include "Globals.h" #include "WorldUpdate.h" #include "Constants.h" #include "Registries.h" #include "BasicBlocks.h" #include "Game.h" #include using namespace Network; using namespace Framework; World::World( Bildschirm3D* zScreen ) : Thread() { renderedWorld = new Welt3D(); renderedWorld->addDiffuseLight( DiffuseLight{ Vec3( 0.5f, 0.5f, -1.f ), Vec3( 1.f, 1.f, 1.f ) } ); dimensions = new RCArray(); currentPlayer = new CurrentPlayer(); zScreenPtr = zScreen; kam = new PlayerKam( zScreen ); kam->setWelt( renderedWorld ); zScreen->addKamera( kam ); firstMessage = 1; hasTarget = 0; entityTarget = -1; ownEntityId = -1; currentTarget = 0; start(); } World::~World() { zScreenPtr->removeKamera( kam ); dimensions->release(); currentPlayer->release(); if( currentTarget ) currentTarget->release(); } void World::update( bool background ) { NetworkReader* serverMessageReader = 0; unsigned char type = 0; while( background ? serverMessageReader = network->zFactoryClient()->getNextBackgroundMessage() : serverMessageReader = network->zFactoryClient()->getNextForegroundMessage() ) { serverMessageReader->lese( (char*)&type, 1 ); if( type == 2 ) // WORLD UPDATE { int id = 0; serverMessageReader->lese( (char*)&id, 4 ); STATIC_REGISTRY( WorldUpdateType ).zElement( id )->applyUpdateAndCheck( serverMessageReader ); } if( type == 3 ) // API MESSAGE { // TODO: process messages } if( type == 4 ) // POSITION UPDATE { serverMessageReader->lese( (char*)&ownEntityId, 4 ); } network->zFactoryClient()->endMessageReading( background ); } network->zFactoryClient()->endMessageReading( background ); Entity* player = getCurrentPlayerEntity(); if( player ) { renderedWorld->lock(); for( Dimension* dim : *dimensions ) dim->removeDistantChunks( { (int)player->getPos().x, (int)player->getPos().y }, this ); renderedWorld->unlock(); } } void World::setChunk( Chunk* chunk, int dimensionId ) { zScreenPtr->lock(); Dimension* zDim = zDimension( dimensionId ); if( !zDim ) { zDim = new Dimension( dimensionId ); dimensions->add( zDim ); } zDim->setChunk( chunk, chunk->getCenter(), this ); zScreenPtr->unlock(); } void World::thread() { new AsynchronCall( "World Update", [this]() { while( true ) { zScreenPtr->lock(); if( currentGame != this ) { zScreenPtr->unlock(); return; } zScreenPtr->unlock(); update( 0 ); Sleep( 10 ); } } ); while( true ) { zScreenPtr->lock(); if( currentGame != this ) { zScreenPtr->unlock(); return; } zScreenPtr->unlock(); update( 1 ); Sleep( 10 ); } } Block* World::zBlockAt( Framework::Vec3 location, int dimension ) const { Dimension* dim = zDimension( dimension ); if( dim ) return dim->zBlock( location ); return 0; } Block* World::getBlockAt( Framework::Vec3 location, int dimension ) const { Dimension* dim = zDimension( dimension ); if( dim ) return dim->getBlock( location ); return 0; } Dimension* World::zDimension( int id ) const { for( auto dim : *dimensions ) { if( dim->getDimensionId() == id ) return dim; } return 0; } Dimension* World::zDimensionOrCreate( int id ) { zScreenPtr->lock(); Dimension* d = zDimension( id ); if( !d ) { d = new Dimension( id ); dimensions->add( d ); } zScreenPtr->unlock(); return d; } void World::setVisibility( Chunk* zChunk, bool visible ) { renderedWorld->lock(); if( visible ) renderedWorld->addCollection( dynamic_cast(zChunk->getThis()) ); else renderedWorld->removeCollection( zChunk ); renderedWorld->unlock(); } void World::setVisibility( Entity* zEntity, bool visible ) { renderedWorld->lock(); if( visible ) renderedWorld->addZeichnung( dynamic_cast(zEntity->getThis()) ); else renderedWorld->removeZeichnung( zEntity ); renderedWorld->unlock(); } Framework::Punkt World::getChunkCenter( int x, int y ) const { return Punkt( ((x < 0 ? x + 1 : x) / CHUNK_SIZE) * CHUNK_SIZE + (x < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2, ((y < 0 ? y + 1 : y) / CHUNK_SIZE) * CHUNK_SIZE + (y < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2 ); } Entity* World::zEntity( int id ) const { for( Dimension* d : *dimensions ) { Entity* e = d->zEntity( id ); if( e ) return e; } return 0; } Entity* World::getEntity( int id ) const { for( Dimension* d : *dimensions ) { Entity* e = d->getEntity( id ); if( e ) return e; } return 0; } void World::removeEntity( int id ) { for( Dimension* d : *dimensions ) d->removeEntity( id ); } PlayerKam* World::zKamera() const { return kam; } int World::getCurrentPlayerId() const { return ownEntityId; } Entity* World::getCurrentPlayerEntity() const { for( Dimension* d : *dimensions ) { Entity* e = d->zEntity( ownEntityId ); if( e ) return e; } return 0; } void World::setTarget( Framework::Model3D* zTarget ) { if( zTarget != currentTarget ) { if( currentTarget ) { currentTarget->setAmbientFactor( currentTarget->getAmbientFactor() - 0.2f ); currentTarget->release(); currentTarget = 0; } if( zTarget ) { currentTarget = dynamic_cast(zTarget->getThis()); if( currentTarget ) currentTarget->setAmbientFactor( currentTarget->getAmbientFactor() + 0.2f ); } } } void World::lockWorld() { renderedWorld->lock(); } void World::unlockWorld() { renderedWorld->unlock(); }