World.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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 } );
  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() )
  81. block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() - 0.2 );
  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. hasTarget = 1;
  95. }
  96. else
  97. hasTarget = 0;
  98. if( hasTarget && dimensions->hat( 0 ) )
  99. {
  100. if( entityTarget == -1 )
  101. {
  102. auto block = zBlockAt( target, dimensions->z( 0 )->getDimensionId() );
  103. if( block.isA() )
  104. block.getA()->setAmbientFactor( block.getA()->getAmbientFactor() + 0.2 );
  105. }
  106. }
  107. }
  108. network->zFactoryClient()->endMessageReading( background );
  109. }
  110. network->zFactoryClient()->endMessageReading( background );
  111. }
  112. void World::setChunk( Chunk* chunk, int dimensionId )
  113. {
  114. zScreenPtr->lock();
  115. Dimension* zDim = zDimension( dimensionId );
  116. if( !zDim )
  117. {
  118. zDim = new Dimension( dimensionId );
  119. dimensions->add( zDim );
  120. }
  121. zDim->setChunk( chunk, chunk->getCenter() );
  122. zScreenPtr->unlock();
  123. zDim->updateVisibility();
  124. }
  125. void World::thread()
  126. {
  127. new AsynchronCall( [this]() {
  128. while( true )
  129. {
  130. zScreenPtr->lock();
  131. if( currentGame != this )
  132. {
  133. zScreenPtr->unlock();
  134. return;
  135. }
  136. zScreenPtr->unlock();
  137. update( 0 );
  138. Sleep( 10 );
  139. }
  140. } );
  141. while( true )
  142. {
  143. zScreenPtr->lock();
  144. if( currentGame != this )
  145. {
  146. zScreenPtr->unlock();
  147. return;
  148. }
  149. zScreenPtr->unlock();
  150. update( 1 );
  151. Sleep( 10 );
  152. }
  153. }
  154. Framework::Either<Block*, int> World::zBlockAt( Framework::Vec3<int> location, int dimension ) const
  155. {
  156. Dimension* dim = zDimension( dimension );
  157. if( dim )
  158. return dim->zBlock( location );
  159. return 0;
  160. }
  161. Dimension* World::zDimension( int id ) const
  162. {
  163. for( auto dim : *dimensions )
  164. {
  165. if( dim->getDimensionId() == id )
  166. return dim;
  167. }
  168. return 0;
  169. }
  170. void World::setVisibility( Framework::Model3D* zModel, bool visible )
  171. {
  172. renderedWorld->lock();
  173. if( visible )
  174. renderedWorld->addZeichnung( dynamic_cast<Framework::Model3D*>(zModel->getThis()) );
  175. else
  176. renderedWorld->removeZeichnung( zModel );
  177. renderedWorld->unlock();
  178. }
  179. Framework::Bildschirm3D* World::zScreen() const
  180. {
  181. return zScreenPtr;
  182. }
  183. Framework::Punkt World::getChunkCenter( int x, int y ) const
  184. {
  185. 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 );
  186. }