WorldGenerator.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "WorldGenerator.h"
  2. #include "StaticRegistry.h"
  3. #include "Game.h"
  4. #include "PerlinNoise.h"
  5. #include "AddChunkUpdate.h"
  6. #include "NoiseInterpolator.h"
  7. using namespace Framework;
  8. WorldGenerator::WorldGenerator( int seed, Game* zGame )
  9. : Thread(),
  10. zGame( zGame ),
  11. noise( new NoiseInterpolator( seed, []( int s ) {return new PerlinNoise( s ); }, CHUNK_SIZE * 10, CHUNK_SIZE * 10 ) ),
  12. exit( 0 )
  13. {
  14. start();
  15. }
  16. WorldGenerator::~WorldGenerator()
  17. {
  18. noise->release();
  19. }
  20. void WorldGenerator::thread()
  21. {
  22. while( !exit )
  23. {
  24. cs.lock();
  25. Area next;
  26. bool hasNext = 0;
  27. if( requestQueue.getEintragAnzahl() > 0 )
  28. {
  29. next = requestQueue.get( 0 );
  30. requestQueue.remove( 0 );
  31. hasNext = 1;
  32. }
  33. cs.unlock();
  34. if( !hasNext )
  35. {
  36. sleep( 1 );
  37. continue;
  38. }
  39. Punkt start = zGame->getChunkCenter( next.startX, next.startY );
  40. Punkt end = zGame->getChunkCenter( next.endX, next.endY );
  41. int xDir = start.x > end.x ? -1 : 1;
  42. int yDir = start.y > end.y ? -1 : 1;
  43. for( int x = start.x; xDir < 0 ? x >= end.x : x <= end.x; x += CHUNK_SIZE * xDir )
  44. {
  45. for( int y = start.y; yDir < 0 ? y >= end.y : y <= end.y; y += CHUNK_SIZE * yDir )
  46. {
  47. if( !zGame->doesChunkExist( x, y, next.dimensionId ) )
  48. {
  49. Chunk* generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement( next.dimensionId )->generateChunk( noise, zGame, x, y );
  50. generatedChunk->removeUnusedBlocks();
  51. zGame->requestWorldUpdate( new AddChunkUpdate( generatedChunk ) );
  52. }
  53. }
  54. }
  55. }
  56. }
  57. void WorldGenerator::requestGeneration( Area request )
  58. {
  59. cs.lock();
  60. requestQueue.add( request );
  61. cs.unlock();
  62. }
  63. void WorldGenerator::exitAndWait()
  64. {
  65. exit = 1;
  66. warteAufThread( 10000 );
  67. ende();
  68. }
  69. Framework::Either<Block*, int> WorldGenerator::generateSingleBlock( Framework::Vec3<int> location, int dimensionId )
  70. {
  71. return StaticRegistry<DimensionGenerator>::INSTANCE.zElement( dimensionId )->generateBlock( noise, zGame, location );
  72. }