#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 ); start(); } World::~World() { zScreenPtr->removeKamera( kam ); dimensions->release(); currentPlayer->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 )->applyUpdate( serverMessageReader ); } if( type == 3 ) // API MESSAGE { // TODO: process messages } if( type == 4 ) // POSITION UPDATE { Vec3 pos; Vec2 dir; serverMessageReader->lese( (char*)&pos.x, 4 ); serverMessageReader->lese( (char*)&pos.y, 4 ); serverMessageReader->lese( (char*)&pos.z, 4 ); kam->setPosition( pos + Vec3( 0.f, 0.f, 2.f ) ); serverMessageReader->lese( (char*)&dir.x, 4 ); serverMessageReader->lese( (char*)&dir.y, 4 ); ((Game*)(Menu*)menuRegister->get( "game" ))->updatePositionAndFace( pos, dir ); kam->setDirection( { dir.x, dir.y } ); for( Dimension* dim : *dimensions ) dim->removeDistantChunks( { (int)dir.x, (int)dir.y } ); } network->zFactoryClient()->endMessageReading( background ); } network->zFactoryClient()->endMessageReading( background ); } 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() ); zScreenPtr->unlock(); zDim->updateVisibility(); } void World::thread() { new AsynchronCall( [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 ); } } Framework::Either World::zBlockAt( Framework::Vec3 location, int dimension ) const { Dimension* dim = zDimension( dimension ); if( dim ) return dim->zBlock( location ); return 0; } Dimension* World::zDimension( int id ) const { for( auto dim : *dimensions ) { if( dim->getDimensionId() == id ) return dim; } return 0; } void World::setVisibility( Framework::Model3D* zModel, bool visible ) { renderedWorld->lock(); if( visible ) renderedWorld->addZeichnung( dynamic_cast(zModel->getThis()) ); else renderedWorld->removeZeichnung( zModel ); renderedWorld->unlock(); } Framework::Bildschirm3D* World::zScreen() const { return zScreenPtr; } 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 ); }