|
@@ -11,7 +11,6 @@ GameClient::GameClient( Player* zPlayer, FCKlient* client )
|
|
: ReferenceCounter(),
|
|
: ReferenceCounter(),
|
|
zPlayer( zPlayer ),
|
|
zPlayer( zPlayer ),
|
|
client( client ),
|
|
client( client ),
|
|
- writer( client->zClient() ),
|
|
|
|
viewDistance( DEFAULT_VIEW_DISTANCE ),
|
|
viewDistance( DEFAULT_VIEW_DISTANCE ),
|
|
first( 1 ),
|
|
first( 1 ),
|
|
online( 1 )
|
|
online( 1 )
|
|
@@ -22,60 +21,70 @@ GameClient::~GameClient()
|
|
client->release();
|
|
client->release();
|
|
}
|
|
}
|
|
|
|
|
|
-void GameClient::sendWorldUpdate( WorldUpdate* zUpdate )
|
|
|
|
|
|
+void GameClient::sendWorldUpdate( WorldUpdate* update )
|
|
{
|
|
{
|
|
- if( zPlayer->getCurrentDimensionId() == zUpdate->getAffectedDimension() )
|
|
|
|
|
|
+ bool add = 0;
|
|
|
|
+ if( zPlayer->getCurrentDimensionId() == update->getAffectedDimension() )
|
|
{
|
|
{
|
|
auto pos = (Vec3<int>)zPlayer->getPosition();
|
|
auto pos = (Vec3<int>)zPlayer->getPosition();
|
|
- if( abs( pos.x - zUpdate->getMinAffectedPoint().x ) < viewDistance * CHUNK_SIZE || (abs( pos.x - zUpdate->getMaxAffectedPoint().x ) < viewDistance * CHUNK_SIZE) || abs( pos.y - zUpdate->getMinAffectedPoint().y ) < viewDistance * CHUNK_SIZE || (abs( pos.y - zUpdate->getMaxAffectedPoint().y ) < viewDistance * CHUNK_SIZE) )
|
|
|
|
|
|
+ if( abs( pos.x - update->getMinAffectedPoint().x ) < viewDistance * CHUNK_SIZE || (abs( pos.x - update->getMaxAffectedPoint().x ) < viewDistance * CHUNK_SIZE) || abs( pos.y - update->getMinAffectedPoint().y ) < viewDistance * CHUNK_SIZE || (abs( pos.y - update->getMaxAffectedPoint().y ) < viewDistance * CHUNK_SIZE) )
|
|
{
|
|
{
|
|
- cs.Enter();
|
|
|
|
- writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
- writer.schreibe( (char*)&Message::WORLD_UPDATE, 1 );
|
|
|
|
- zUpdate->write( &writer );
|
|
|
|
- cs.Leave();
|
|
|
|
|
|
+ other.Enter();
|
|
|
|
+ updateQueue.add( update );
|
|
|
|
+ other.Leave();
|
|
|
|
+ add = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ if( !add )
|
|
|
|
+ update->release();
|
|
}
|
|
}
|
|
|
|
|
|
void GameClient::reply( Game* zGame )
|
|
void GameClient::reply( Game* zGame )
|
|
{
|
|
{
|
|
- cs.Enter();
|
|
|
|
|
|
+ other.Enter();
|
|
for( auto req : requests )
|
|
for( auto req : requests )
|
|
zGame->api( req, this );
|
|
zGame->api( req, this );
|
|
requests.leeren();
|
|
requests.leeren();
|
|
- cs.Leave();
|
|
|
|
|
|
+ other.Leave();
|
|
int x = (int)zPlayer->getPosition().x;
|
|
int x = (int)zPlayer->getPosition().x;
|
|
int y = (int)zPlayer->getPosition().y;
|
|
int y = (int)zPlayer->getPosition().y;
|
|
int d = zPlayer->getCurrentDimensionId();
|
|
int d = zPlayer->getCurrentDimensionId();
|
|
- cs.Enter();
|
|
|
|
- writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
- writer.schreibe( (char*)&Message::POSITION_UPDATE, 1 );
|
|
|
|
|
|
+ foreground.Enter();
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1 );
|
|
float f = zPlayer->getPosition().x;
|
|
float f = zPlayer->getPosition().x;
|
|
- writer.schreibe( (char*)&f, 4 );
|
|
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
f = zPlayer->getPosition().y;
|
|
f = zPlayer->getPosition().y;
|
|
- writer.schreibe( (char*)&f, 4 );
|
|
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
f = zPlayer->getPosition().z;
|
|
f = zPlayer->getPosition().z;
|
|
- writer.schreibe( (char*)&f, 4 );
|
|
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
f = zPlayer->getFaceDir().x;
|
|
f = zPlayer->getFaceDir().x;
|
|
- writer.schreibe( (char*)&f, 4 );
|
|
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
f = zPlayer->getFaceDir().y;
|
|
f = zPlayer->getFaceDir().y;
|
|
- writer.schreibe( (char*)&f, 4 );
|
|
|
|
- cs.Leave();
|
|
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
|
|
+ foreground.Leave();
|
|
|
|
+ other.Enter();
|
|
|
|
+ if( updateQueue.hat( 0 ) )
|
|
|
|
+ {
|
|
|
|
+ background.Enter();
|
|
|
|
+ client->zBackgroundWriter()->schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
+ client->zBackgroundWriter()->schreibe( (char*)&Message::WORLD_UPDATE, 1 );
|
|
|
|
+ updateQueue.z( 0 )->write( client->zBackgroundWriter() );
|
|
|
|
+ updateQueue.remove( 0 );
|
|
|
|
+ background.Leave();
|
|
|
|
+ }
|
|
|
|
+ other.Leave();
|
|
// send world to client
|
|
// send world to client
|
|
if( first )
|
|
if( first )
|
|
{
|
|
{
|
|
first = 0;
|
|
first = 0;
|
|
- for( int xP = x - CHUNK_SIZE * viewDistance; x <= x + CHUNK_SIZE * viewDistance; x += CHUNK_SIZE )
|
|
|
|
|
|
+ for( int xP = x - CHUNK_SIZE * viewDistance; xP <= x + CHUNK_SIZE * viewDistance; xP += CHUNK_SIZE )
|
|
{
|
|
{
|
|
- for( int yP = y - CHUNK_SIZE * viewDistance; y <= y + CHUNK_SIZE * viewDistance; y += CHUNK_SIZE )
|
|
|
|
|
|
+ for( int yP = y - CHUNK_SIZE * viewDistance; yP <= y + CHUNK_SIZE * viewDistance; yP += CHUNK_SIZE )
|
|
{
|
|
{
|
|
Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( xP, yP ) );
|
|
Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( xP, yP ) );
|
|
if( chunk )
|
|
if( chunk )
|
|
- {
|
|
|
|
- AddChunkUpdate update( dynamic_cast<Chunk*>(chunk->getThis()) );
|
|
|
|
- sendWorldUpdate( &update );
|
|
|
|
- }
|
|
|
|
|
|
+ sendWorldUpdate( new AddChunkUpdate( dynamic_cast<Chunk*>(chunk->getThis()) ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
zGame->requestArea( { x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance, x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance, d } );
|
|
zGame->requestArea( { x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance, x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance, d } );
|
|
@@ -86,22 +95,17 @@ void GameClient::reply( Game* zGame )
|
|
Punkt curMin = zGame->getChunkCenter( x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance );
|
|
Punkt curMin = zGame->getChunkCenter( x - CHUNK_SIZE * viewDistance, y - CHUNK_SIZE * viewDistance );
|
|
Punkt lastMax = zGame->getChunkCenter( (int)lastPos.x + CHUNK_SIZE * viewDistance, (int)lastPos.y + CHUNK_SIZE * viewDistance );
|
|
Punkt lastMax = zGame->getChunkCenter( (int)lastPos.x + CHUNK_SIZE * viewDistance, (int)lastPos.y + CHUNK_SIZE * viewDistance );
|
|
Punkt curMax = zGame->getChunkCenter( x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance );
|
|
Punkt curMax = zGame->getChunkCenter( x + CHUNK_SIZE * viewDistance, y + CHUNK_SIZE * viewDistance );
|
|
- for( int xP = curMin.x; x <= curMax.x; x += CHUNK_SIZE )
|
|
|
|
|
|
+ for( int xP = curMin.x; xP <= curMax.x; xP += CHUNK_SIZE )
|
|
{
|
|
{
|
|
- for( int yP = curMin.y; y <= curMax.y; y += 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 )
|
|
if( xP < lastMin.x || xP > lastMax.x || yP < lastMin.y || yP > lastMax.y )
|
|
{
|
|
{
|
|
- Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( x, y ) );
|
|
|
|
|
|
+ Chunk* chunk = zGame->zDimension( d )->zChunk( zGame->getChunkCenter( xP, yP ) );
|
|
if( chunk )
|
|
if( chunk )
|
|
- {
|
|
|
|
- AddChunkUpdate update( dynamic_cast<Chunk*>(chunk->getThis()) );
|
|
|
|
- sendWorldUpdate( &update );
|
|
|
|
- }
|
|
|
|
|
|
+ sendWorldUpdate( new AddChunkUpdate( dynamic_cast<Chunk*>(chunk->getThis()) ) );
|
|
else
|
|
else
|
|
- {
|
|
|
|
- zGame->requestArea( zGame->getChunckArea( Punkt( xP, yP ) ) );
|
|
|
|
- }
|
|
|
|
|
|
+ zGame->requestArea( zGame->getChunckArea( zGame->getChunkCenter( xP, yP ) ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -123,9 +127,9 @@ void GameClient::addMessage( StreamReader* reader )
|
|
reader->lese( tmp, len );
|
|
reader->lese( tmp, len );
|
|
buffer->schreibe( tmp, len );
|
|
buffer->schreibe( tmp, len );
|
|
delete[]tmp;
|
|
delete[]tmp;
|
|
- cs.Enter();
|
|
|
|
|
|
+ other.Enter();
|
|
requests.add( buffer );
|
|
requests.add( buffer );
|
|
- cs.Leave();
|
|
|
|
|
|
+ other.Leave();
|
|
}
|
|
}
|
|
|
|
|
|
bool GameClient::isOnline() const
|
|
bool GameClient::isOnline() const
|
|
@@ -137,11 +141,22 @@ 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->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 } ) )
|
|
{
|
|
{
|
|
- cs.Leave();
|
|
|
|
- writer.schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
- writer.schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
|
- zResponse->writeTo( client->zWriter() );
|
|
|
|
- cs.Leave();
|
|
|
|
|
|
+ if( zResponse->isUseBackground() )
|
|
|
|
+ {
|
|
|
|
+ background.Leave();
|
|
|
|
+ client->zBackgroundWriter()->schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
+ client->zBackgroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
|
+ zResponse->writeTo( client->zBackgroundWriter() );
|
|
|
|
+ background.Leave();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ foreground.Leave();
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&Message::INGAME_MESSAGE, 1 );
|
|
|
|
+ client->zForegroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
|
+ zResponse->writeTo( client->zForegroundWriter() );
|
|
|
|
+ foreground.Leave();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -224,13 +239,11 @@ void Game::thread()
|
|
while( updates->hat( 0 ) )
|
|
while( updates->hat( 0 ) )
|
|
{
|
|
{
|
|
WorldUpdate* update = updates->z( 0 );
|
|
WorldUpdate* update = updates->z( 0 );
|
|
- cs.Leave();
|
|
|
|
for( auto client : *clients )
|
|
for( auto client : *clients )
|
|
- client->sendWorldUpdate( update );
|
|
|
|
|
|
+ client->sendWorldUpdate( dynamic_cast<WorldUpdate*>(update->getThis()) );
|
|
if( !zDimension( update->getAffectedDimension() ) )
|
|
if( !zDimension( update->getAffectedDimension() ) )
|
|
addDimension( new Dimension( update->getAffectedDimension() ) );
|
|
addDimension( new Dimension( update->getAffectedDimension() ) );
|
|
update->onUpdate( zDimension( update->getAffectedDimension() ) );
|
|
update->onUpdate( zDimension( update->getAffectedDimension() ) );
|
|
- cs.Enter();
|
|
|
|
updates->remove( 0 );
|
|
updates->remove( 0 );
|
|
}
|
|
}
|
|
cs.Leave();
|
|
cs.Leave();
|
|
@@ -338,9 +351,20 @@ bool Game::isChunkLoaded( int x, int y, int dimension ) const
|
|
return (dim && dim->hasChunck( x, y ));
|
|
return (dim && dim->hasChunck( x, y ));
|
|
}
|
|
}
|
|
|
|
|
|
-bool Game::doesChunkExist( int x, int y, int dimension ) const
|
|
|
|
|
|
+bool Game::doesChunkExist( int x, int y, int dimension )
|
|
{
|
|
{
|
|
- return isChunkLoaded( x, y, dimension ) || loader->existsChunk( x, y, dimension );
|
|
|
|
|
|
+ cs.Enter();
|
|
|
|
+ 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.Leave();
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
Framework::Either<Block*, int> Game::zBlockAt( Framework::Vec3<int> location, int dimension ) const
|
|
Framework::Either<Block*, int> Game::zBlockAt( Framework::Vec3<int> location, int dimension ) const
|
|
@@ -363,12 +387,12 @@ Dimension* Game::zDimension( int id ) const
|
|
|
|
|
|
Framework::Punkt Game::getChunkCenter( int x, int y ) const
|
|
Framework::Punkt Game::getChunkCenter( int x, int y ) const
|
|
{
|
|
{
|
|
- return Punkt( (x / CHUNK_SIZE) * CHUNK_SIZE + (x < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2, (y / CHUNK_SIZE) * CHUNK_SIZE + (y < 0 ? -CHUNK_SIZE : CHUNK_SIZE) / 2 );
|
|
|
|
|
|
+ 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, center.y + CHUNK_SIZE / 2, 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
|