|
@@ -10,535 +10,552 @@
|
|
|
|
|
|
using namespace Framework;
|
|
using namespace Framework;
|
|
|
|
|
|
-GameClient::GameClient( Player* zPlayer, FCKlient* client )
|
|
|
|
- : ReferenceCounter(),
|
|
|
|
- zPlayer( zPlayer ),
|
|
|
|
- client( client ),
|
|
|
|
- viewDistance( DEFAULT_VIEW_DISTANCE ),
|
|
|
|
- first( 1 ),
|
|
|
|
- online( 1 ),
|
|
|
|
- finished( 0 )
|
|
|
|
-{
|
|
|
|
- new AsynchronCall( "Game Client", [this]() {
|
|
|
|
- while( online )
|
|
|
|
- {
|
|
|
|
- other.lock();
|
|
|
|
- if( updateQueue.hat( 0 ) )
|
|
|
|
- {
|
|
|
|
- WorldUpdate* update = updateQueue.get( 0 );
|
|
|
|
- updateQueue.remove( 0 );
|
|
|
|
- other.unlock();
|
|
|
|
- background.lock();
|
|
|
|
- this->client->zBackgroundWriter()->schreibe( (char*)&Message::WORLD_UPDATE, 1 );
|
|
|
|
- update->writeAndCheck( this->client->zBackgroundWriter() );
|
|
|
|
- background.unlock();
|
|
|
|
- update->release();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- other.unlock();
|
|
|
|
- updateSync.wait();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- finished = 1;
|
|
|
|
- } );
|
|
|
|
|
|
+GameClient::GameClient(Player* zPlayer, FCKlient* client)
|
|
|
|
+ : ReferenceCounter(),
|
|
|
|
+ zPlayer(zPlayer),
|
|
|
|
+ client(client),
|
|
|
|
+ viewDistance(DEFAULT_VIEW_DISTANCE),
|
|
|
|
+ first(1),
|
|
|
|
+ online(1),
|
|
|
|
+ finished(0)
|
|
|
|
+{
|
|
|
|
+ new AsynchronCall("Game Client", [this]()
|
|
|
|
+ {
|
|
|
|
+ while (online)
|
|
|
|
+ {
|
|
|
|
+ other.lock();
|
|
|
|
+ if (updateQueue.hat(0))
|
|
|
|
+ {
|
|
|
|
+ WorldUpdate* update = updateQueue.get(0);
|
|
|
|
+ updateQueue.remove(0);
|
|
|
|
+ other.unlock();
|
|
|
|
+ background.lock();
|
|
|
|
+ this->client->zBackgroundWriter()->schreibe((char*)&Message::WORLD_UPDATE, 1);
|
|
|
|
+ update->writeAndCheck(this->client->zBackgroundWriter());
|
|
|
|
+ background.unlock();
|
|
|
|
+ update->release();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ other.unlock();
|
|
|
|
+ updateSync.wait();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ finished = 1;
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
GameClient::~GameClient()
|
|
GameClient::~GameClient()
|
|
{
|
|
{
|
|
- online = 0;
|
|
|
|
- updateSync.notify();
|
|
|
|
- while( !finished )
|
|
|
|
- Sleep( 100 );
|
|
|
|
- client->release();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void GameClient::sendWorldUpdate( WorldUpdate* update )
|
|
|
|
-{
|
|
|
|
- bool add = 0;
|
|
|
|
- if( zPlayer->getCurrentDimensionId() == update->getAffectedDimension() )
|
|
|
|
- {
|
|
|
|
- auto pos = (Vec3<int>)zPlayer->getPosition();
|
|
|
|
- int dist = update->distanceTo( pos.x, pos.y );
|
|
|
|
- if( dist < viewDistance * CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- other.lock();
|
|
|
|
- int index = 0;
|
|
|
|
- for( auto update2 : updateQueue )
|
|
|
|
- {
|
|
|
|
- int dist2 = update2->distanceTo( pos.x, pos.y );
|
|
|
|
- if( dist2 > dist )
|
|
|
|
- break;
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- if( update->getType() == AddChunkUpdateType::ID )
|
|
|
|
- ((AddChunkUpdate*)update)->zChunk()->addView( zPlayer );
|
|
|
|
- updateQueue.add( update, index );
|
|
|
|
- other.unlock();
|
|
|
|
- updateSync.notify();
|
|
|
|
- add = 1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if( !add )
|
|
|
|
- update->release();
|
|
|
|
|
|
+ online = 0;
|
|
|
|
+ updateSync.notify();
|
|
|
|
+ while (!finished)
|
|
|
|
+ Sleep(100);
|
|
|
|
+ client->release();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void GameClient::sendWorldUpdate(WorldUpdate* update)
|
|
|
|
+{
|
|
|
|
+ bool add = 0;
|
|
|
|
+ if (zPlayer->getCurrentDimensionId() == update->getAffectedDimension())
|
|
|
|
+ {
|
|
|
|
+ auto pos = (Vec3<int>)zPlayer->getPosition();
|
|
|
|
+ int dist = update->distanceTo(pos.x, pos.y);
|
|
|
|
+ if (dist < viewDistance * CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ other.lock();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (auto update2 : updateQueue)
|
|
|
|
+ {
|
|
|
|
+ int dist2 = update2->distanceTo(pos.x, pos.y);
|
|
|
|
+ if (dist2 > dist)
|
|
|
|
+ break;
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ if (update->getType() == AddChunkUpdateType::ID)
|
|
|
|
+ ((AddChunkUpdate*)update)->zChunk()->addView(zPlayer);
|
|
|
|
+ updateQueue.add(update, index);
|
|
|
|
+ other.unlock();
|
|
|
|
+ updateSync.notify();
|
|
|
|
+ add = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!add)
|
|
|
|
+ update->release();
|
|
}
|
|
}
|
|
|
|
|
|
void GameClient::reply()
|
|
void GameClient::reply()
|
|
{
|
|
{
|
|
- other.lock();
|
|
|
|
- for( auto req : requests )
|
|
|
|
- Game::INSTANCE->api( req, this );
|
|
|
|
- requests.leeren();
|
|
|
|
- other.unlock();
|
|
|
|
- int x = (int)floor( zPlayer->getPosition().x );
|
|
|
|
- int y = (int)floor( zPlayer->getPosition().y );
|
|
|
|
- int d = zPlayer->getCurrentDimensionId();
|
|
|
|
- // send world to client
|
|
|
|
- if( first )
|
|
|
|
- {
|
|
|
|
- foreground.lock();
|
|
|
|
- int id = zPlayer->getId();
|
|
|
|
- client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1 );
|
|
|
|
- client->zForegroundWriter()->schreibe( (char*)&id, 4 );
|
|
|
|
- foreground.unlock();
|
|
|
|
- first = 0;
|
|
|
|
- Dimension* dim = Game::INSTANCE->zDimension( d );
|
|
|
|
- if( dim )
|
|
|
|
- {
|
|
|
|
- for( int xP = x - CHUNK_SIZE * viewDistance; xP <= x + CHUNK_SIZE * viewDistance; xP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- for( int yP = y - CHUNK_SIZE * viewDistance; yP <= y + CHUNK_SIZE * viewDistance; yP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- Chunk* chunk = dim->zChunk( Game::INSTANCE->getChunkCenter( xP, yP ) );
|
|
|
|
- if( chunk )
|
|
|
|
- sendWorldUpdate( new AddChunkUpdate( dynamic_cast<Chunk*>(chunk->getThis()) ) );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- Game::INSTANCE->requestArea( { x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance, x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance, d } );
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- Punkt lastMin = Game::INSTANCE->getChunkCenter( (int)floor( lastPos.x ) - CHUNK_SIZE * viewDistance, (int)floor( lastPos.y ) - CHUNK_SIZE * viewDistance );
|
|
|
|
- Punkt curMin = Game::INSTANCE->getChunkCenter( x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance );
|
|
|
|
- Punkt lastMax = Game::INSTANCE->getChunkCenter( (int)floor( lastPos.x ) + CHUNK_SIZE * viewDistance, (int)floor( lastPos.y ) + CHUNK_SIZE * viewDistance );
|
|
|
|
- Punkt curMax = Game::INSTANCE->getChunkCenter( x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance );
|
|
|
|
- Dimension* dim = Game::INSTANCE->zDimension( d );
|
|
|
|
- if( dim )
|
|
|
|
- {
|
|
|
|
- for( int xP = curMin.x; xP <= curMax.x; xP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- for( int yP = curMin.y; yP <= curMax.y; yP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- if( xP < lastMin.x || xP > lastMax.x || yP < lastMin.y || yP > lastMax.y )
|
|
|
|
- {
|
|
|
|
- Chunk* chunk = dim->zChunk( Game::INSTANCE->getChunkCenter( xP, yP ) );
|
|
|
|
- if( chunk )
|
|
|
|
- sendWorldUpdate( new AddChunkUpdate( dynamic_cast<Chunk*>(chunk->getThis()) ) );
|
|
|
|
- else
|
|
|
|
- Game::INSTANCE->requestArea( Game::INSTANCE->getChunckArea( Game::INSTANCE->getChunkCenter( xP, yP ) ) );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- for( int xP = lastMin.x; xP <= lastMax.x; xP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- for( int yP = lastMin.y; yP <= lastMax.y; yP += CHUNK_SIZE )
|
|
|
|
- {
|
|
|
|
- if( xP < curMin.x || xP > curMax.x || yP < curMin.y || yP > curMax.y )
|
|
|
|
- {
|
|
|
|
- Chunk* chunk = dim->zChunk( Game::INSTANCE->getChunkCenter( xP, yP ) );
|
|
|
|
- if( chunk )
|
|
|
|
- chunk->removeView( zPlayer );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- lastPos = zPlayer->getPosition();
|
|
|
|
|
|
+ other.lock();
|
|
|
|
+ for (auto req : requests)
|
|
|
|
+ Game::INSTANCE->api(req, this);
|
|
|
|
+ requests.leeren();
|
|
|
|
+ other.unlock();
|
|
|
|
+ int x = (int)floor(zPlayer->getPosition().x);
|
|
|
|
+ int y = (int)floor(zPlayer->getPosition().y);
|
|
|
|
+ int d = zPlayer->getCurrentDimensionId();
|
|
|
|
+ // send world to client
|
|
|
|
+ if (first)
|
|
|
|
+ {
|
|
|
|
+ foreground.lock();
|
|
|
|
+ int id = zPlayer->getId();
|
|
|
|
+ client->zForegroundWriter()->schreibe((char*)&Message::POSITION_UPDATE, 1);
|
|
|
|
+ client->zForegroundWriter()->schreibe((char*)&id, 4);
|
|
|
|
+ foreground.unlock();
|
|
|
|
+ first = 0;
|
|
|
|
+ Dimension* dim = Game::INSTANCE->zDimension(d);
|
|
|
|
+ if (dim)
|
|
|
|
+ {
|
|
|
|
+ for (int xP = x - CHUNK_SIZE * viewDistance; xP <= x + CHUNK_SIZE * viewDistance; xP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ for (int yP = y - CHUNK_SIZE * viewDistance; yP <= y + CHUNK_SIZE * viewDistance; yP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ Chunk* chunk = dim->zChunk(Game::INSTANCE->getChunkCenter(xP, yP));
|
|
|
|
+ if (chunk)
|
|
|
|
+ sendWorldUpdate(new AddChunkUpdate(dynamic_cast<Chunk*>(chunk->getThis())));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Game::INSTANCE->requestArea({ x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance, x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance, d });
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ Punkt lastMin = Game::INSTANCE->getChunkCenter((int)floor(lastPos.x) - CHUNK_SIZE * viewDistance, (int)floor(lastPos.y) - CHUNK_SIZE * viewDistance);
|
|
|
|
+ Punkt curMin = Game::INSTANCE->getChunkCenter(x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance);
|
|
|
|
+ Punkt lastMax = Game::INSTANCE->getChunkCenter((int)floor(lastPos.x) + CHUNK_SIZE * viewDistance, (int)floor(lastPos.y) + CHUNK_SIZE * viewDistance);
|
|
|
|
+ Punkt curMax = Game::INSTANCE->getChunkCenter(x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance);
|
|
|
|
+ Dimension* dim = Game::INSTANCE->zDimension(d);
|
|
|
|
+ if (dim)
|
|
|
|
+ {
|
|
|
|
+ for (int xP = curMin.x; xP <= curMax.x; xP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ for (int yP = curMin.y; yP <= curMax.y; yP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ if (xP < lastMin.x || xP > lastMax.x || yP < lastMin.y || yP > lastMax.y)
|
|
|
|
+ {
|
|
|
|
+ Chunk* chunk = dim->zChunk(Game::INSTANCE->getChunkCenter(xP, yP));
|
|
|
|
+ if (chunk)
|
|
|
|
+ sendWorldUpdate(new AddChunkUpdate(dynamic_cast<Chunk*>(chunk->getThis())));
|
|
|
|
+ else
|
|
|
|
+ Game::INSTANCE->requestArea(Game::INSTANCE->getChunckArea(Game::INSTANCE->getChunkCenter(xP, yP)));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for (int xP = lastMin.x; xP <= lastMax.x; xP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ for (int yP = lastMin.y; yP <= lastMax.y; yP += CHUNK_SIZE)
|
|
|
|
+ {
|
|
|
|
+ if (xP < curMin.x || xP > curMax.x || yP < curMin.y || yP > curMax.y)
|
|
|
|
+ {
|
|
|
|
+ Chunk* chunk = dim->zChunk(Game::INSTANCE->getChunkCenter(xP, yP));
|
|
|
|
+ if (chunk)
|
|
|
|
+ chunk->removeView(zPlayer);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ lastPos = zPlayer->getPosition();
|
|
}
|
|
}
|
|
|
|
|
|
void GameClient::logout()
|
|
void GameClient::logout()
|
|
{
|
|
{
|
|
- online = 0;
|
|
|
|
|
|
+ online = 0;
|
|
}
|
|
}
|
|
|
|
|
|
-void GameClient::addMessage( StreamReader* reader )
|
|
|
|
|
|
+void GameClient::addMessage(StreamReader* reader)
|
|
{
|
|
{
|
|
- short len = 0;
|
|
|
|
- reader->lese( (char*)&len, 2 );
|
|
|
|
- InMemoryBuffer* buffer = new InMemoryBuffer();
|
|
|
|
- char* tmp = new char[ len ];
|
|
|
|
- reader->lese( tmp, len );
|
|
|
|
- buffer->schreibe( tmp, len );
|
|
|
|
- delete[]tmp;
|
|
|
|
- other.lock();
|
|
|
|
- requests.add( buffer );
|
|
|
|
- other.unlock();
|
|
|
|
|
|
+ short len = 0;
|
|
|
|
+ reader->lese((char*)&len, 2);
|
|
|
|
+ InMemoryBuffer* buffer = new InMemoryBuffer();
|
|
|
|
+ char* tmp = new char[len];
|
|
|
|
+ reader->lese(tmp, len);
|
|
|
|
+ buffer->schreibe(tmp, len);
|
|
|
|
+ delete[]tmp;
|
|
|
|
+ other.lock();
|
|
|
|
+ requests.add(buffer);
|
|
|
|
+ other.unlock();
|
|
}
|
|
}
|
|
|
|
|
|
bool GameClient::isOnline() const
|
|
bool GameClient::isOnline() const
|
|
{
|
|
{
|
|
- return online;
|
|
|
|
|
|
+ return online;
|
|
}
|
|
}
|
|
|
|
|
|
-void GameClient::sendResponse( NetworkResponse* zResponse )
|
|
|
|
|
|
+void GameClient::sendResponse(NetworkResponse* zResponse)
|
|
{
|
|
{
|
|
- if( zResponse->isAreaAffected( { lastPos.x - (float)CHUNK_SIZE * (float)viewDistance, lastPos.y - (float)CHUNK_SIZE * (float)viewDistance, 0.f }, { lastPos.x + (float)CHUNK_SIZE * (float)viewDistance, lastPos.y + (float)CHUNK_SIZE * (float)viewDistance, (float)WORLD_HEIGHT } ) )
|
|
|
|
- {
|
|
|
|
- if( zResponse->isUseBackground() )
|
|
|
|
- {
|
|
|
|
- background.unlock();
|
|
|
|
- client->zBackgroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
|
- zResponse->writeTo( client->zBackgroundWriter() );
|
|
|
|
- background.unlock();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- foreground.unlock();
|
|
|
|
- client->zForegroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
|
- zResponse->writeTo( client->zForegroundWriter() );
|
|
|
|
- foreground.unlock();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if (zResponse->isAreaAffected({ lastPos.x - (float)CHUNK_SIZE * (float)viewDistance, lastPos.y - (float)CHUNK_SIZE * (float)viewDistance, 0.f }, { lastPos.x + (float)CHUNK_SIZE * (float)viewDistance, lastPos.y + (float)CHUNK_SIZE * (float)viewDistance, (float)WORLD_HEIGHT }))
|
|
|
|
+ {
|
|
|
|
+ if (zResponse->isUseBackground())
|
|
|
|
+ {
|
|
|
|
+ background.unlock();
|
|
|
|
+ client->zBackgroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
|
|
|
|
+ zResponse->writeTo(client->zBackgroundWriter());
|
|
|
|
+ background.unlock();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ foreground.unlock();
|
|
|
|
+ client->zForegroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1);
|
|
|
|
+ zResponse->writeTo(client->zForegroundWriter());
|
|
|
|
+ foreground.unlock();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
Player* GameClient::zEntity() const
|
|
Player* GameClient::zEntity() const
|
|
{
|
|
{
|
|
- return zPlayer;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-Game::Game( Framework::Text name, Framework::Text worldsDir )
|
|
|
|
- : Thread(),
|
|
|
|
- name( name ),
|
|
|
|
- dimensions( new RCArray<Dimension>() ),
|
|
|
|
- updates( new RCArray<WorldUpdate>() ),
|
|
|
|
- clients( new RCArray<GameClient>() ),
|
|
|
|
- ticker( new TickOrganizer() ),
|
|
|
|
- path( (const char*)(worldsDir + "/" + name) ),
|
|
|
|
- stop( 0 ),
|
|
|
|
- tickId( 0 ),
|
|
|
|
- nextEntityId( 0 ),
|
|
|
|
- generator( 0 ),
|
|
|
|
- loader( 0 )
|
|
|
|
-{
|
|
|
|
- if( !DateiExistiert( worldsDir + "/" + name ) )
|
|
|
|
- DateiPfadErstellen( worldsDir + "/" + name + "/" );
|
|
|
|
- Datei d;
|
|
|
|
- d.setDatei( path + "/eid" );
|
|
|
|
- if( d.existiert() )
|
|
|
|
- {
|
|
|
|
- d.open( Datei::Style::lesen );
|
|
|
|
- d.lese( (char*)&nextEntityId, 4 );
|
|
|
|
- d.close();
|
|
|
|
- }
|
|
|
|
- start();
|
|
|
|
|
|
+ return zPlayer;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Game::Game(Framework::Text name, Framework::Text worldsDir)
|
|
|
|
+ : Thread(),
|
|
|
|
+ name(name),
|
|
|
|
+ dimensions(new RCArray<Dimension>()),
|
|
|
|
+ updates(new RCArray<WorldUpdate>()),
|
|
|
|
+ clients(new RCArray<GameClient>()),
|
|
|
|
+ ticker(new TickOrganizer()),
|
|
|
|
+ path((const char*)(worldsDir + "/" + name)),
|
|
|
|
+ stop(0),
|
|
|
|
+ tickId(0),
|
|
|
|
+ nextEntityId(0),
|
|
|
|
+ generator(0),
|
|
|
|
+ loader(0)
|
|
|
|
+{
|
|
|
|
+ if (!DateiExistiert(worldsDir + "/" + name))
|
|
|
|
+ DateiPfadErstellen(worldsDir + "/" + name + "/");
|
|
|
|
+ Datei d;
|
|
|
|
+ d.setDatei(path + "/eid");
|
|
|
|
+ if (d.existiert())
|
|
|
|
+ {
|
|
|
|
+ d.open(Datei::Style::lesen);
|
|
|
|
+ d.lese((char*)&nextEntityId, 4);
|
|
|
|
+ d.close();
|
|
|
|
+ }
|
|
|
|
+ start();
|
|
}
|
|
}
|
|
|
|
|
|
Game::~Game()
|
|
Game::~Game()
|
|
{
|
|
{
|
|
- dimensions->release();
|
|
|
|
- updates->release();
|
|
|
|
- clients->release();
|
|
|
|
- generator->release();
|
|
|
|
- loader->release();
|
|
|
|
|
|
+ dimensions->release();
|
|
|
|
+ updates->release();
|
|
|
|
+ clients->release();
|
|
|
|
+ generator->release();
|
|
|
|
+ loader->release();
|
|
}
|
|
}
|
|
|
|
|
|
void Game::initialize()
|
|
void Game::initialize()
|
|
{
|
|
{
|
|
- int seed = 0;
|
|
|
|
- int index = 0;
|
|
|
|
- for( char* n = name; *n; n++ )
|
|
|
|
- seed += (int)pow( (float)*n * 31, (float)++index );
|
|
|
|
- generator = new WorldGenerator( seed );
|
|
|
|
- loader = new WorldLoader();
|
|
|
|
|
|
+ int seed = 0;
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (char* n = name; *n; n++)
|
|
|
|
+ seed += (int)pow((float)*n * 31, (float)++index);
|
|
|
|
+ generator = new WorldGenerator(seed);
|
|
|
|
+ loader = new WorldLoader();
|
|
|
|
+ recipies.loadRecipies("data/recipies");
|
|
}
|
|
}
|
|
|
|
|
|
void Game::thread()
|
|
void Game::thread()
|
|
{
|
|
{
|
|
- ZeitMesser m;
|
|
|
|
- while( !stop )
|
|
|
|
- {
|
|
|
|
- m.messungStart();
|
|
|
|
- ticker->nextTick();
|
|
|
|
- Array<int> removed;
|
|
|
|
- cs.lock();
|
|
|
|
- int index = 0;
|
|
|
|
- for( auto player : *clients )
|
|
|
|
- {
|
|
|
|
- if( !player->isOnline() )
|
|
|
|
- {
|
|
|
|
- Datei pFile;
|
|
|
|
- pFile.setDatei( path + "/player/" + player->zEntity()->getName() );
|
|
|
|
- if( pFile.open( Datei::Style::schreiben ) )
|
|
|
|
- PlayerEntityType::INSTANCE->saveEntity( player->zEntity(), &pFile );
|
|
|
|
- removed.add( index, 0 );
|
|
|
|
- }
|
|
|
|
- index++;
|
|
|
|
- }
|
|
|
|
- for( auto i : removed )
|
|
|
|
- clients->remove( i );
|
|
|
|
- cs.unlock();
|
|
|
|
- for( auto dim : *dimensions )
|
|
|
|
- dim->tickEntities();
|
|
|
|
- cs.lock();
|
|
|
|
- while( updates->hat( 0 ) )
|
|
|
|
- {
|
|
|
|
- WorldUpdate* update = updates->z( 0 );
|
|
|
|
- for( auto client : *clients )
|
|
|
|
- client->sendWorldUpdate( dynamic_cast<WorldUpdate*>(update->getThis()) );
|
|
|
|
- if( !zDimension( update->getAffectedDimension() ) )
|
|
|
|
- addDimension( new Dimension( update->getAffectedDimension() ) );
|
|
|
|
- update->onUpdate( zDimension( update->getAffectedDimension() ) );
|
|
|
|
- updates->remove( 0 );
|
|
|
|
- }
|
|
|
|
- cs.unlock();
|
|
|
|
- for( auto client : *clients )
|
|
|
|
- client->reply();
|
|
|
|
- cs.lock();
|
|
|
|
- for( auto dim : *dimensions )
|
|
|
|
- dim->removeOldChunks();
|
|
|
|
- cs.unlock();
|
|
|
|
- m.messungEnde();
|
|
|
|
- double sec = m.getSekunden();
|
|
|
|
- if( sec < 0.05 )
|
|
|
|
- Sleep( (int)((0.05 - sec) * 1000) );
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- std::cout << "WARNING: tick needed " << sec << " seconds. The game will run sower then normal.\n";
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- save();
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void Game::api( Framework::StreamReader* zRequest, GameClient* zOrigin )
|
|
|
|
-{
|
|
|
|
- char type;
|
|
|
|
- zRequest->lese( &type, 1 );
|
|
|
|
- NetworkResponse response;
|
|
|
|
- switch( type )
|
|
|
|
- {
|
|
|
|
- case 1: // world
|
|
|
|
- {
|
|
|
|
- int dimensionId;
|
|
|
|
- zRequest->lese( (char*)&dimensionId, 4 );
|
|
|
|
- Dimension* dim = zDimension( dimensionId );
|
|
|
|
- if( !dim )
|
|
|
|
- {
|
|
|
|
- dim = new Dimension( dimensionId );
|
|
|
|
- addDimension( dim );
|
|
|
|
- }
|
|
|
|
- dim->api( zRequest, &response );
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- case 2: // player
|
|
|
|
- zOrigin->zEntity()->api( zRequest, &response );
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- std::cout << "received unknown api request in game with type " << (int)type << "\n";
|
|
|
|
- }
|
|
|
|
- if( !response.isEmpty() )
|
|
|
|
- {
|
|
|
|
- if( response.isBroadcast() )
|
|
|
|
- distributeResponse( &response );
|
|
|
|
- else
|
|
|
|
- zOrigin->sendResponse( &response );
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void Game::distributeResponse( NetworkResponse* zResponse )
|
|
|
|
-{
|
|
|
|
- for( auto client : *clients )
|
|
|
|
- client->sendResponse( zResponse );
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool Game::requestWorldUpdate( WorldUpdate* update )
|
|
|
|
-{
|
|
|
|
- cs.lock();
|
|
|
|
- for( WorldUpdate* u : *updates )
|
|
|
|
- {
|
|
|
|
- if( u->getMaxAffectedPoint().x >= update->getMinAffectedPoint().x && u->getMinAffectedPoint().x <= update->getMaxAffectedPoint().x &&
|
|
|
|
- u->getMaxAffectedPoint().y >= update->getMinAffectedPoint().y && u->getMinAffectedPoint().y <= update->getMaxAffectedPoint().y &&
|
|
|
|
- u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z && u->getType() == update->getType() )
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- update->release();
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- updates->add( update );
|
|
|
|
- cs.unlock();
|
|
|
|
- return 1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
|
|
|
|
-{
|
|
|
|
- cs.lock();
|
|
|
|
- Datei pFile;
|
|
|
|
- pFile.setDatei( path + "/player/" + name );
|
|
|
|
- Player* player;
|
|
|
|
- bool isNew = 0;
|
|
|
|
- if( !pFile.existiert() || !pFile.open( Datei::Style::lesen ) )
|
|
|
|
- {
|
|
|
|
- player = (Player*)PlayerEntityType::INSTANCE->createEntityAt( Vec3<float>( 0.5, 0.5, 0 ), OverworldDimension::ID );
|
|
|
|
- player->setName( name );
|
|
|
|
- isNew = 1;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- player = (Player*)PlayerEntityType::INSTANCE->loadEntity( &pFile );
|
|
|
|
- pFile.close();
|
|
|
|
- }
|
|
|
|
- GameClient* gameClient = new GameClient( player, client );
|
|
|
|
- clients->add( gameClient );
|
|
|
|
- requestArea( getChunckArea( getChunkCenter( (int)player->getPosition().x, (int)player->getPosition().y ) ) );
|
|
|
|
- while( !zDimension( player->getCurrentDimensionId() ) || (isNew && !zDimension( player->getCurrentDimensionId() )->zChunk( getChunkCenter( (int)player->getPosition().x, (int)player->getPosition().y ) )) )
|
|
|
|
- {
|
|
|
|
- cs.unlock();
|
|
|
|
- Sleep( 1000 );
|
|
|
|
- cs.lock();
|
|
|
|
- }
|
|
|
|
- if( isNew )
|
|
|
|
- {
|
|
|
|
- Either<Block*, int> b = AirBlockBlockType::ID;
|
|
|
|
- int h = WORLD_HEIGHT;
|
|
|
|
- while( ((b.isA() && (!(Block*)b || ((Block*)b)->isPassable())) || (b.isB() && StaticRegistry<BlockType>::INSTANCE.zElement( b )->zDefault()->isPassable())) && h > 0 )
|
|
|
|
- b = zBlockAt( { (int)player->getPosition().x, (int)player->getPosition().y, --h }, player->getCurrentDimensionId() );
|
|
|
|
- player->setPosition( { player->getPosition().x, player->getPosition().y, (float)h + 1.f } );
|
|
|
|
- }
|
|
|
|
- requestWorldUpdate( new AddEntityUpdate( player, player->getCurrentDimensionId() ) );
|
|
|
|
- cs.unlock();
|
|
|
|
- return dynamic_cast<GameClient*>(gameClient->getThis());
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool Game::isChunkLoaded( int x, int y, int dimension ) const
|
|
|
|
-{
|
|
|
|
- Dimension* dim = zDimension( dimension );
|
|
|
|
- return (dim && dim->hasChunck( x, y ));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool Game::doesChunkExist( int x, int y, int dimension )
|
|
|
|
-{
|
|
|
|
- cs.lock();
|
|
|
|
- bool result = isChunkLoaded( x, y, dimension ) || loader->existsChunk( x, y, dimension );
|
|
|
|
- if( !result )
|
|
|
|
- {
|
|
|
|
- for( WorldUpdate* update : *updates )
|
|
|
|
- {
|
|
|
|
- if( update->getType() == AddChunkUpdateType::ID )
|
|
|
|
- result |= ((AddChunkUpdate*)update)->zChunk()->getCenter() == Framework::Punkt( x, y );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- cs.unlock();
|
|
|
|
- return result;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-Framework::Either<Block*, int> Game::zBlockAt( Framework::Vec3<int> location, int dimension ) const
|
|
|
|
-{
|
|
|
|
- Dimension* dim = zDimension( dimension );
|
|
|
|
- if( dim )
|
|
|
|
- return dim->zBlock( location );
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ZeitMesser m;
|
|
|
|
+ while (!stop)
|
|
|
|
+ {
|
|
|
|
+ m.messungStart();
|
|
|
|
+ ticker->nextTick();
|
|
|
|
+ Array<int> removed;
|
|
|
|
+ cs.lock();
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (auto player : *clients)
|
|
|
|
+ {
|
|
|
|
+ if (!player->isOnline())
|
|
|
|
+ {
|
|
|
|
+ Datei pFile;
|
|
|
|
+ pFile.setDatei(path + "/player/" + player->zEntity()->getName());
|
|
|
|
+ if (pFile.open(Datei::Style::schreiben))
|
|
|
|
+ PlayerEntityType::INSTANCE->saveEntity(player->zEntity(), &pFile);
|
|
|
|
+ removed.add(index, 0);
|
|
|
|
+ }
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ for (auto i : removed)
|
|
|
|
+ clients->remove(i);
|
|
|
|
+ cs.unlock();
|
|
|
|
+ for (auto dim : *dimensions)
|
|
|
|
+ dim->tickEntities();
|
|
|
|
+ cs.lock();
|
|
|
|
+ while (updates->hat(0))
|
|
|
|
+ {
|
|
|
|
+ WorldUpdate* update = updates->z(0);
|
|
|
|
+ for (auto client : *clients)
|
|
|
|
+ client->sendWorldUpdate(dynamic_cast<WorldUpdate*>(update->getThis()));
|
|
|
|
+ if (!zDimension(update->getAffectedDimension()))
|
|
|
|
+ addDimension(new Dimension(update->getAffectedDimension()));
|
|
|
|
+ update->onUpdate(zDimension(update->getAffectedDimension()));
|
|
|
|
+ updates->remove(0);
|
|
|
|
+ }
|
|
|
|
+ cs.unlock();
|
|
|
|
+ for (auto client : *clients)
|
|
|
|
+ client->reply();
|
|
|
|
+ cs.lock();
|
|
|
|
+ for (auto dim : *dimensions)
|
|
|
|
+ dim->removeOldChunks();
|
|
|
|
+ cs.unlock();
|
|
|
|
+ m.messungEnde();
|
|
|
|
+ double sec = m.getSekunden();
|
|
|
|
+ if (sec < 0.05)
|
|
|
|
+ Sleep((int)((0.05 - sec) * 1000));
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ std::cout << "WARNING: tick needed " << sec << " seconds. The game will run sower then normal.\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ save();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Game::api(Framework::StreamReader* zRequest, GameClient* zOrigin)
|
|
|
|
+{
|
|
|
|
+ char type;
|
|
|
|
+ zRequest->lese(&type, 1);
|
|
|
|
+ NetworkResponse response;
|
|
|
|
+ switch (type)
|
|
|
|
+ {
|
|
|
|
+ case 1: // world
|
|
|
|
+ {
|
|
|
|
+ int dimensionId;
|
|
|
|
+ zRequest->lese((char*)&dimensionId, 4);
|
|
|
|
+ Dimension* dim = zDimension(dimensionId);
|
|
|
|
+ if (!dim)
|
|
|
|
+ {
|
|
|
|
+ dim = new Dimension(dimensionId);
|
|
|
|
+ addDimension(dim);
|
|
|
|
+ }
|
|
|
|
+ dim->api(zRequest, &response);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 2: // player
|
|
|
|
+ zOrigin->zEntity()->playerApi(zRequest, &response);
|
|
|
|
+ break;
|
|
|
|
+ case 3: // entity
|
|
|
|
+ {
|
|
|
|
+ int id;
|
|
|
|
+ zRequest->lese((char*)&id, 4);
|
|
|
|
+ for (Dimension* dim : *dimensions)
|
|
|
|
+ {
|
|
|
|
+ Entity* entity = dim->zEntity(id);
|
|
|
|
+ if (entity)
|
|
|
|
+ {
|
|
|
|
+ entity->api(zRequest, &response);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ std::cout << "received unknown api request in game with type " << (int)type << "\n";
|
|
|
|
+ }
|
|
|
|
+ if (!response.isEmpty())
|
|
|
|
+ {
|
|
|
|
+ if (response.isBroadcast())
|
|
|
|
+ distributeResponse(&response);
|
|
|
|
+ else
|
|
|
|
+ zOrigin->sendResponse(&response);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Game::distributeResponse(NetworkResponse* zResponse)
|
|
|
|
+{
|
|
|
|
+ for (auto client : *clients)
|
|
|
|
+ client->sendResponse(zResponse);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Game::requestWorldUpdate(WorldUpdate* update)
|
|
|
|
+{
|
|
|
|
+ cs.lock();
|
|
|
|
+ for (WorldUpdate* u : *updates)
|
|
|
|
+ {
|
|
|
|
+ if (u->getMaxAffectedPoint().x >= update->getMinAffectedPoint().x && u->getMinAffectedPoint().x <= update->getMaxAffectedPoint().x &&
|
|
|
|
+ u->getMaxAffectedPoint().y >= update->getMinAffectedPoint().y && u->getMinAffectedPoint().y <= update->getMaxAffectedPoint().y &&
|
|
|
|
+ u->getMaxAffectedPoint().z >= update->getMinAffectedPoint().z && u->getMinAffectedPoint().z <= update->getMaxAffectedPoint().z && u->getType() == update->getType())
|
|
|
|
+ {
|
|
|
|
+ cs.unlock();
|
|
|
|
+ update->release();
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ updates->add(update);
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+GameClient* Game::addPlayer(FCKlient* client, Framework::Text name)
|
|
|
|
+{
|
|
|
|
+ cs.lock();
|
|
|
|
+ Datei pFile;
|
|
|
|
+ pFile.setDatei(path + "/player/" + name);
|
|
|
|
+ Player* player;
|
|
|
|
+ bool isNew = 0;
|
|
|
|
+ if (!pFile.existiert() || !pFile.open(Datei::Style::lesen))
|
|
|
|
+ {
|
|
|
|
+ player = (Player*)PlayerEntityType::INSTANCE->createEntityAt(Vec3<float>(0.5, 0.5, 0), OverworldDimension::ID);
|
|
|
|
+ player->setName(name);
|
|
|
|
+ isNew = 1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ player = (Player*)PlayerEntityType::INSTANCE->loadEntity(&pFile);
|
|
|
|
+ pFile.close();
|
|
|
|
+ }
|
|
|
|
+ GameClient* gameClient = new GameClient(player, client);
|
|
|
|
+ clients->add(gameClient);
|
|
|
|
+ requestArea(getChunckArea(getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y)));
|
|
|
|
+ while (!zDimension(player->getCurrentDimensionId()) || (isNew && !zDimension(player->getCurrentDimensionId())->zChunk(getChunkCenter((int)player->getPosition().x, (int)player->getPosition().y))))
|
|
|
|
+ {
|
|
|
|
+ cs.unlock();
|
|
|
|
+ Sleep(1000);
|
|
|
|
+ cs.lock();
|
|
|
|
+ }
|
|
|
|
+ if (isNew)
|
|
|
|
+ {
|
|
|
|
+ Either<Block*, int> b = AirBlockBlockType::ID;
|
|
|
|
+ int h = WORLD_HEIGHT;
|
|
|
|
+ while (((b.isA() && (!(Block*)b || ((Block*)b)->isPassable())) || (b.isB() && StaticRegistry<BlockType>::INSTANCE.zElement(b)->zDefault()->isPassable())) && h > 0)
|
|
|
|
+ b = zBlockAt({ (int)player->getPosition().x, (int)player->getPosition().y, --h }, player->getCurrentDimensionId());
|
|
|
|
+ player->setPosition({ player->getPosition().x, player->getPosition().y, (float)h + 1.f });
|
|
|
|
+ }
|
|
|
|
+ requestWorldUpdate(new AddEntityUpdate(player, player->getCurrentDimensionId()));
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return dynamic_cast<GameClient*>(gameClient->getThis());
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Game::isChunkLoaded(int x, int y, int dimension) const
|
|
|
|
+{
|
|
|
|
+ Dimension* dim = zDimension(dimension);
|
|
|
|
+ return (dim && dim->hasChunck(x, y));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Game::doesChunkExist(int x, int y, int dimension)
|
|
|
|
+{
|
|
|
|
+ cs.lock();
|
|
|
|
+ bool result = isChunkLoaded(x, y, dimension) || loader->existsChunk(x, y, dimension);
|
|
|
|
+ if (!result)
|
|
|
|
+ {
|
|
|
|
+ for (WorldUpdate* update : *updates)
|
|
|
|
+ {
|
|
|
|
+ if (update->getType() == AddChunkUpdateType::ID)
|
|
|
|
+ result |= ((AddChunkUpdate*)update)->zChunk()->getCenter() == Framework::Punkt(x, y);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return result;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Framework::Either<Block*, int> Game::zBlockAt(Framework::Vec3<int> location, int dimension) const
|
|
|
|
+{
|
|
|
|
+ Dimension* dim = zDimension(dimension);
|
|
|
|
+ if (dim)
|
|
|
|
+ return dim->zBlock(location);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-Block* Game::zRealBlockInstance( Framework::Vec3<int> location, int dimension )
|
|
|
|
|
|
+Block* Game::zRealBlockInstance(Framework::Vec3<int> location, int dimension)
|
|
{
|
|
{
|
|
- Dimension* dim = zDimension( dimension );
|
|
|
|
- if( dim )
|
|
|
|
- return dim->zRealBlockInstance( location );
|
|
|
|
- return 0;
|
|
|
|
|
|
+ Dimension* dim = zDimension(dimension);
|
|
|
|
+ if (dim)
|
|
|
|
+ return dim->zRealBlockInstance(location);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
-
|
|
|
|
-Dimension* Game::zDimension( int id ) const
|
|
|
|
|
|
+
|
|
|
|
+Dimension* Game::zDimension(int id) const
|
|
{
|
|
{
|
|
- for( auto dim : *dimensions )
|
|
|
|
- {
|
|
|
|
- if( dim->getDimensionId() == id )
|
|
|
|
- return dim;
|
|
|
|
- }
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-Framework::Punkt Game::getChunkCenter( int x, int y )
|
|
|
|
-{
|
|
|
|
- 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 );
|
|
|
|
|
|
+ for (auto dim : *dimensions)
|
|
|
|
+ {
|
|
|
|
+ if (dim->getDimensionId() == id)
|
|
|
|
+ return dim;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Framework::Punkt Game::getChunkCenter(int x, int y)
|
|
|
|
+{
|
|
|
|
+ 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);
|
|
}
|
|
}
|
|
|
|
|
|
-Area Game::getChunckArea( Punkt center ) const
|
|
|
|
|
|
+Area Game::getChunckArea(Punkt center) const
|
|
{
|
|
{
|
|
- return { center.x - CHUNK_SIZE / 2, center.y - CHUNK_SIZE / 2, center.x + CHUNK_SIZE / 2 - 1, center.y + CHUNK_SIZE / 2 - 1, 0 };
|
|
|
|
|
|
+ return { center.x - CHUNK_SIZE / 2, center.y - CHUNK_SIZE / 2, center.x + CHUNK_SIZE / 2 - 1, center.y + CHUNK_SIZE / 2 - 1, 0 };
|
|
}
|
|
}
|
|
|
|
|
|
Framework::Text Game::getWorldDirectory() const
|
|
Framework::Text Game::getWorldDirectory() const
|
|
{
|
|
{
|
|
- return path;
|
|
|
|
|
|
+ return path;
|
|
}
|
|
}
|
|
|
|
|
|
-void Game::requestArea( Area area )
|
|
|
|
|
|
+void Game::requestArea(Area area)
|
|
{
|
|
{
|
|
- generator->requestGeneration( area );
|
|
|
|
- loader->requestLoading( area );
|
|
|
|
|
|
+ generator->requestGeneration(area);
|
|
|
|
+ loader->requestLoading(area);
|
|
}
|
|
}
|
|
|
|
|
|
void Game::save() const
|
|
void Game::save() const
|
|
{
|
|
{
|
|
- Datei d;
|
|
|
|
- d.setDatei( path + "/eid" );
|
|
|
|
- d.open( Datei::Style::schreiben );
|
|
|
|
- d.schreibe( (char*)&nextEntityId, 4 );
|
|
|
|
- d.close();
|
|
|
|
- for( auto dim : *dimensions )
|
|
|
|
- dim->save( path );
|
|
|
|
|
|
+ Datei d;
|
|
|
|
+ d.setDatei(path + "/eid");
|
|
|
|
+ d.open(Datei::Style::schreiben);
|
|
|
|
+ d.schreibe((char*)&nextEntityId, 4);
|
|
|
|
+ d.close();
|
|
|
|
+ for (auto dim : *dimensions)
|
|
|
|
+ dim->save(path);
|
|
}
|
|
}
|
|
|
|
|
|
void Game::requestStop()
|
|
void Game::requestStop()
|
|
{
|
|
{
|
|
- stop = 1;
|
|
|
|
- warteAufThread( 1000000 );
|
|
|
|
|
|
+ stop = 1;
|
|
|
|
+ warteAufThread(1000000);
|
|
}
|
|
}
|
|
|
|
|
|
-void Game::addDimension( Dimension* d )
|
|
|
|
|
|
+void Game::addDimension(Dimension* d)
|
|
{
|
|
{
|
|
- dimensions->add( d );
|
|
|
|
|
|
+ dimensions->add(d);
|
|
}
|
|
}
|
|
|
|
|
|
int Game::getNextEntityId()
|
|
int Game::getNextEntityId()
|
|
{
|
|
{
|
|
- cs.lock();
|
|
|
|
- int result = nextEntityId++;
|
|
|
|
- cs.unlock();
|
|
|
|
- return result;
|
|
|
|
|
|
+ cs.lock();
|
|
|
|
+ int result = nextEntityId++;
|
|
|
|
+ cs.unlock();
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
WorldGenerator* Game::zGenerator() const
|
|
WorldGenerator* Game::zGenerator() const
|
|
{
|
|
{
|
|
- return generator;
|
|
|
|
|
|
+ return generator;
|
|
}
|
|
}
|
|
|
|
|
|
Game* Game::INSTANCE = 0;
|
|
Game* Game::INSTANCE = 0;
|
|
|
|
|
|
-void Game::initialize( Framework::Text name, Framework::Text worldsDir )
|
|
|
|
|
|
+void Game::initialize(Framework::Text name, Framework::Text worldsDir)
|
|
{
|
|
{
|
|
- if( !Game::INSTANCE )
|
|
|
|
- {
|
|
|
|
- Game::INSTANCE = new Game( name, worldsDir );
|
|
|
|
- Game::INSTANCE->initialize();
|
|
|
|
- }
|
|
|
|
|
|
+ if (!Game::INSTANCE)
|
|
|
|
+ {
|
|
|
|
+ Game::INSTANCE = new Game(name, worldsDir);
|
|
|
|
+ Game::INSTANCE->initialize();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-Entity* Game::zEntity( int id, int dimensionId ) const
|
|
|
|
|
|
+Entity* Game::zEntity(int id, int dimensionId) const
|
|
{
|
|
{
|
|
- Dimension* d = zDimension( dimensionId );
|
|
|
|
- if( d )
|
|
|
|
- return d->zEntity( id );
|
|
|
|
- return 0;
|
|
|
|
|
|
+ Dimension* d = zDimension(dimensionId);
|
|
|
|
+ if (d)
|
|
|
|
+ return d->zEntity(id);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-Entity* Game::zNearestEntity( int dimensionId, Framework::Vec3<float> pos, std::function<bool( Entity* )> filter )
|
|
|
|
|
|
+Entity* Game::zNearestEntity(int dimensionId, Framework::Vec3<float> pos, std::function<bool(Entity*)> filter)
|
|
{
|
|
{
|
|
- Dimension* d = zDimension( dimensionId );
|
|
|
|
- if( !d )
|
|
|
|
- return 0;
|
|
|
|
- return d->zNearestEntity( pos, filter );
|
|
|
|
|
|
+ Dimension* d = zDimension(dimensionId);
|
|
|
|
+ if (!d)
|
|
|
|
+ return 0;
|
|
|
|
+ return d->zNearestEntity(pos, filter);
|
|
}
|
|
}
|
|
|
|
|