World.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <Network.h>
  2. #include <Welt3D.h>
  3. #include <GraphicsApi.h>
  4. #include <iostream>
  5. #include "World.h"
  6. #include "Globals.h"
  7. #include "WorldUpdate.h"
  8. #include "Constants.h"
  9. #include "Registries.h"
  10. #include "BasicBlocks.h"
  11. #include "Game.h"
  12. #include <AsynchronCall.h>
  13. using namespace Network;
  14. using namespace Framework;
  15. World::World( Bildschirm3D* zScreen )
  16. : Thread()
  17. {
  18. renderedWorld = new Welt3D();
  19. renderedWorld->addDiffuseLight( DiffuseLight{ Vec3<float>( 0.5f, 0.5f, -1.f ), Vec3<float>( 1.f, 1.f, 1.f ) } );
  20. dimensions = new RCArray<Dimension>();
  21. currentPlayer = new CurrentPlayer();
  22. zScreenPtr = zScreen;
  23. kam = new PlayerKam( zScreen );
  24. kam->setWelt( renderedWorld );
  25. zScreen->addKamera( kam );
  26. firstMessage = 1;
  27. hasTarget = 0;
  28. entityTarget = -1;
  29. start();
  30. }
  31. World::~World()
  32. {
  33. zScreenPtr->removeKamera( kam );
  34. dimensions->release();
  35. currentPlayer->release();
  36. }
  37. void World::update( bool background )
  38. {
  39. NetworkReader* serverMessageReader = 0;
  40. unsigned char type = 0;
  41. while( background ? serverMessageReader = network->zFactoryClient()->getNextBackgroundMessage() : serverMessageReader = network->zFactoryClient()->getNextForegroundMessage() )
  42. {
  43. serverMessageReader->lese( (char*)&type, 1 );
  44. if( type == 2 ) // WORLD UPDATE
  45. {
  46. int id = 0;
  47. serverMessageReader->lese( (char*)&id, 4 );
  48. STATIC_REGISTRY( WorldUpdateType ).zElement( id )->applyUpdate( serverMessageReader );
  49. }
  50. if( type == 3 ) // API MESSAGE
  51. {
  52. // TODO: process messages
  53. }
  54. if( type == 4 ) // POSITION UPDATE
  55. {
  56. Vec3<float> pos;
  57. Vec3<float> dir;
  58. serverMessageReader->lese( (char*)&pos.x, 4 );
  59. serverMessageReader->lese( (char*)&pos.y, 4 );
  60. serverMessageReader->lese( (char*)&pos.z, 4 );
  61. kam->setPosition( pos + Vec3<float>( 0.f, 0.f, 1.5f ) );
  62. if( firstMessage )
  63. {
  64. firstMessage = 0;
  65. serverMessageReader->lese( (char*)&dir.x, 4 );
  66. serverMessageReader->lese( (char*)&dir.y, 4 );
  67. serverMessageReader->lese( (char*)&dir.z, 4 );
  68. kam->setDirection( dir );
  69. }
  70. ((Game*)(Menu*)menuRegister->get( "game" ))->updatePosition( pos );
  71. for( Dimension* dim : *dimensions )
  72. dim->removeDistantChunks( { (int)pos.x, (int)pos.y }, this );
  73. char b = 0;
  74. serverMessageReader->lese( &b, 1 );
  75. if( hasTarget && dimensions->hat( 0 ) )
  76. {
  77. if( entityTarget == -1 )
  78. {
  79. auto block = zBlockAt( target, dimensions->z( 0 )->getDimensionId() );
  80. if( block.isA() && block.getA() )
  81. block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() - 0.2f );
  82. }
  83. }
  84. if( b == 1 )
  85. {
  86. serverMessageReader->lese( (char*)&entityTarget, 4 );
  87. hasTarget = 1;
  88. }
  89. else if( b == 2 )
  90. {
  91. serverMessageReader->lese( (char*)&target.x, 4 );
  92. serverMessageReader->lese( (char*)&target.y, 4 );
  93. serverMessageReader->lese( (char*)&target.z, 4 );
  94. int side = 0;
  95. serverMessageReader->lese( (char*)&side, 4 );
  96. hasTarget = 1;
  97. }
  98. else
  99. hasTarget = 0;
  100. if( hasTarget && dimensions->hat( 0 ) )
  101. {
  102. if( entityTarget == -1 )
  103. {
  104. auto block = zBlockAt( target, dimensions->z( 0 )->getDimensionId() );
  105. if( block.isA() && block.getA() )
  106. block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() + 0.2f );
  107. }
  108. }
  109. }
  110. network->zFactoryClient()->endMessageReading( background );
  111. }
  112. network->zFactoryClient()->endMessageReading( background );
  113. }
  114. void World::setChunk( Chunk* chunk, int dimensionId )
  115. {
  116. zScreenPtr->lock();
  117. Dimension* zDim = zDimension( dimensionId );
  118. if( !zDim )
  119. {
  120. zDim = new Dimension( dimensionId );
  121. dimensions->add( zDim );
  122. }
  123. zDim->setChunk( chunk, chunk->getCenter(), this );
  124. zScreenPtr->unlock();
  125. }
  126. void World::thread()
  127. {
  128. new AsynchronCall( [this]() {
  129. while( true )
  130. {
  131. zScreenPtr->lock();
  132. if( currentGame != this )
  133. {
  134. zScreenPtr->unlock();
  135. return;
  136. }
  137. zScreenPtr->unlock();
  138. update( 0 );
  139. Sleep( 10 );
  140. }
  141. } );
  142. while( true )
  143. {
  144. zScreenPtr->lock();
  145. if( currentGame != this )
  146. {
  147. zScreenPtr->unlock();
  148. return;
  149. }
  150. zScreenPtr->unlock();
  151. update( 1 );
  152. Sleep( 10 );
  153. }
  154. }
  155. Framework::Either<Block*, int> World::zBlockAt( Framework::Vec3<int> location, int dimension ) const
  156. {
  157. Dimension* dim = zDimension( dimension );
  158. if( dim )
  159. return dim->zBlock( location );
  160. return 0;
  161. }
  162. Dimension* World::zDimension( int id ) const
  163. {
  164. for( auto dim : *dimensions )
  165. {
  166. if( dim->getDimensionId() == id )
  167. return dim;
  168. }
  169. return 0;
  170. }
  171. void World::setVisibility( Chunk* zChunk, bool visible )
  172. {
  173. renderedWorld->lock();
  174. if( visible )
  175. renderedWorld->addCollection( dynamic_cast<Framework::Model3DCollection*>(zChunk->getThis()) );
  176. else
  177. renderedWorld->removeCollection( zChunk );
  178. renderedWorld->unlock();
  179. }
  180. Framework::Bildschirm3D* World::zScreen() const
  181. {
  182. return zScreenPtr;
  183. }
  184. Framework::Punkt World::getChunkCenter( int x, int y ) const
  185. {
  186. 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 );
  187. }