Chunk.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "Chunk.h"
  2. #include "Constants.h"
  3. #include "Globals.h"
  4. #include "Registries.h"
  5. Chunk::Chunk( Framework::Punkt location, int dimensionId )
  6. : ReferenceCounter(),
  7. dimensionId( dimensionId ),
  8. location( location ),
  9. isLoading( 0 )
  10. {}
  11. Chunk::Chunk( Framework::Punkt location, int dimensionId, Framework::StreamReader* zReader )
  12. : Chunk( location, dimensionId )
  13. {
  14. load( zReader );
  15. }
  16. Chunk::~Chunk()
  17. {}
  18. Block* Chunk::zBlockAt( Framework::Vec3<int> location )
  19. {
  20. cs.lock();
  21. for( Block* b : blocks )
  22. {
  23. if( Framework::Vec3<int>( (int)floor( b->getPos().x ), (int)floor( b->getPos().y ), (int)floor( b->getPos().z ) ) == location )
  24. {
  25. cs.unlock();
  26. return b;
  27. }
  28. }
  29. cs.unlock();
  30. return 0;
  31. }
  32. void Chunk::setBlock( Block* block )
  33. {
  34. cs.lock();
  35. Framework::Vec3<int> pos = (Framework::Vec3<int>)block->getPos();
  36. for( Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++ )
  37. {
  38. if( pos == (Framework::Vec3<int>)iterator->getPos() )
  39. {
  40. iterator->release();
  41. iterator.set( block );
  42. cs.unlock();
  43. return;
  44. }
  45. }
  46. blocks.add( block );
  47. cs.unlock();
  48. if( !isLoading )
  49. updateVisibility();
  50. }
  51. void Chunk::removeBlock( Block* zBlock )
  52. {
  53. cs.lock();
  54. int index = 0;
  55. for( Framework::Iterator<Block*> iterator = blocks.begin(); iterator; iterator++, index++ )
  56. {
  57. if( zBlock == (Block*)iterator )
  58. {
  59. blocks.remove( index );
  60. cs.unlock();
  61. if( !isLoading )
  62. updateVisibility();
  63. return;
  64. }
  65. }
  66. cs.unlock();
  67. }
  68. void Chunk::load( Framework::StreamReader* zReader )
  69. {
  70. isLoading = 1;
  71. Framework::Vec3<int> pos = { 0, 0, 0 };
  72. unsigned short id;
  73. zReader->lese( (char*)&id, 2 );
  74. while( id )
  75. {
  76. zReader->lese( (char*)&pos.x, 4 );
  77. zReader->lese( (char*)&pos.y, 4 );
  78. zReader->lese( (char*)&pos.z, 4 );
  79. bool d;
  80. zReader->lese( (char*)&d, 1 );
  81. if( d )
  82. {
  83. Block* block = STATIC_REGISTRY( BlockType ).zElement( id )->loadBlock( { pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z }, zReader );
  84. if( block )
  85. setBlock( block );
  86. }
  87. else if( STATIC_REGISTRY( BlockType ).zElement( id )->needsInstance() )
  88. setBlock( STATIC_REGISTRY( BlockType ).zElement( id )->createBlock( { pos.x + location.x - CHUNK_SIZE / 2, pos.y + location.y - CHUNK_SIZE / 2, pos.z } ) );
  89. zReader->lese( (char*)&id, 2 );
  90. }
  91. isLoading = 0;
  92. updateVisibility();
  93. }
  94. int Chunk::getDimensionId() const
  95. {
  96. return dimensionId;
  97. }
  98. Framework::Punkt Chunk::getCenter() const
  99. {
  100. return location;
  101. }
  102. Framework::Vec3<int> Chunk::getMin() const
  103. {
  104. return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
  105. }
  106. Framework::Vec3<int> Chunk::getMax() const
  107. {
  108. return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
  109. }
  110. void Chunk::forAll( std::function<void( Model3D* )> f )
  111. {
  112. cs.lock();
  113. for( Block* b : blocks )
  114. f( b );
  115. cs.unlock();
  116. }
  117. void Chunk::updateVisibility()
  118. {
  119. cs.lock();
  120. for( Block* b : blocks )
  121. {
  122. Framework::Vec3<int> pos = Framework::Vec3<int>( (int)floor( b->getPos().x ), (int)floor( b->getPos().y ), (int)floor( b->getPos().z ) );
  123. for( int i = 0; i < 6; i++ )
  124. {
  125. Block* c = zBlockAt( pos + getDirection( getDirectionFromIndex( i ) ) );
  126. b->setSideVisible( getDirectionFromIndex( i ), !c || c->isTransparent() || c->isPassable() );
  127. }
  128. }
  129. cs.unlock();
  130. }