Chunk.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "Chunk.h"
  2. #include "Constants.h"
  3. #include "Game.h"
  4. Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId )
  5. : ReferenceCounter(),
  6. zGame( zGame ),
  7. dimensionId( dimensionId ),
  8. location( location )
  9. {
  10. blocks = new Block * [ CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT ];
  11. memset( blocks, 0, sizeof( Block * ) * CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT );
  12. zNeighbours[ 0 ] = 0;
  13. zNeighbours[ 1 ] = 0;
  14. zNeighbours[ 2 ] = 0;
  15. zNeighbours[ 3 ] = 0;
  16. }
  17. Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId, Framework::StreamReader *zReader )
  18. : Chunk( location, zGame, dimensionId )
  19. {
  20. load( zReader );
  21. }
  22. Chunk::~Chunk()
  23. {
  24. for( int i = 0; i < CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT; i++ )
  25. {
  26. if( blocks[ i ] )
  27. blocks[ i ]->release();
  28. }
  29. delete[] blocks;
  30. }
  31. void Chunk::api( Framework::StreamReader *zRequest, NetworkResponse *zResponse )
  32. {
  33. // TODO: answer api messages
  34. }
  35. Block *Chunk::getBlockAt( Framework::Vec3<int> location ) const
  36. {
  37. location.x += CHUNK_SIZE / 2;
  38. location.y += CHUNK_SIZE / 2;
  39. Block *result = dynamic_cast<Block *>( blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ]->getThis() );
  40. return result;
  41. }
  42. Block *Chunk::zBlockAt( Framework::Vec3<int> location ) const
  43. {
  44. location.x += CHUNK_SIZE / 2;
  45. location.y += CHUNK_SIZE / 2;
  46. return blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ];
  47. }
  48. void Chunk::putBlockAt( Framework::Vec3<int> location, Block *block )
  49. {
  50. location.x -= this->location.x - CHUNK_SIZE / 2;
  51. location.y -= this->location.x - CHUNK_SIZE / 2;
  52. int index = ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z;
  53. Block *old = blocks[ index ];
  54. blocks[ index ] = block;
  55. Block *neighbor = zGame->zBlockAt( location + getDirection( NORTH ), dimensionId );
  56. if( neighbor )
  57. {
  58. neighbor->neighbours[ SOUTH ] = block;
  59. block->neighbours[ NORTH ] = neighbor;
  60. }
  61. neighbor = zGame->zBlockAt( location + getDirection( EAST ), dimensionId );
  62. if( neighbor )
  63. {
  64. neighbor->neighbours[ WEST ] = block;
  65. block->neighbours[ EAST ] = neighbor;
  66. }
  67. neighbor = zGame->zBlockAt( location + getDirection( SOUTH ), dimensionId );
  68. if( neighbor ) {}
  69. {
  70. neighbor->neighbours[ NORTH ] = block;
  71. block->neighbours[ SOUTH ] = neighbor;
  72. }
  73. neighbor = zGame->zBlockAt( location + getDirection( WEST ), dimensionId );
  74. if( neighbor )
  75. {
  76. neighbor->neighbours[ EAST ] = block;
  77. block->neighbours[ WEST ] = neighbor;
  78. }
  79. neighbor = zGame->zBlockAt( location + getDirection( TOP ), dimensionId );
  80. if( neighbor )
  81. {
  82. neighbor->neighbours[ BOTTOM ] = block;
  83. block->neighbours[ TOP ] = neighbor;
  84. }
  85. neighbor = zGame->zBlockAt( location + getDirection( BOTTOM ), dimensionId );
  86. if( neighbor )
  87. {
  88. neighbor->neighbours[ TOP ] = block;
  89. block->neighbours[ BOTTOM ] = neighbor;
  90. }
  91. if( old )
  92. old->release();
  93. }
  94. void Chunk::setNeighbor( Direction dir, Chunk *zChunk )
  95. {
  96. zNeighbours[ dir ] = zChunk;
  97. for( int i = 0; i < CHUNK_SIZE; i++ )
  98. {
  99. for( int z = 0; z < WORLD_HEIGHT; z++ )
  100. {
  101. if( dir == NORTH )
  102. {
  103. int index = i * CHUNK_SIZE * CHUNK_SIZE + z;
  104. if( blocks[ index ] )
  105. blocks[ index ]->neighbours[ NORTH ] = zChunk->blocks[ ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z ];
  106. }
  107. else if( dir == EAST )
  108. {
  109. int index = ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z;
  110. if( blocks[ index ] )
  111. blocks[ index ]->neighbours[ EAST ] = zChunk->blocks[ i * CHUNK_SIZE + z ];
  112. }
  113. else if( dir == SOUTH )
  114. {
  115. int index = ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z;
  116. if( blocks[ index ] )
  117. blocks[ index ]->neighbours[ SOUTH ] = zChunk->blocks[ i * CHUNK_SIZE * CHUNK_SIZE + z ];
  118. }
  119. else if( dir == WEST )
  120. {
  121. int index = i * CHUNK_SIZE + z;
  122. if( blocks[ index ] )
  123. blocks[ index ]->neighbours[ WEST ] = zChunk->blocks[ ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z ];
  124. }
  125. }
  126. }
  127. }
  128. void Chunk::load( Framework::StreamReader *zReader )
  129. {
  130. for( int x = 0; x < CHUNK_SIZE; x++ )
  131. {
  132. for( int y = 0; y < CHUNK_SIZE; y++ )
  133. {
  134. for( int z = 0; z < WORLD_HEIGHT; z++ )
  135. {
  136. int blockType;
  137. zReader->lese( (char *)&blockType, 4 );
  138. if( blockType >= 0 )
  139. {
  140. Block *block = StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3<int>( x, y, z ), zGame, zReader );
  141. blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ] = block;
  142. }
  143. }
  144. }
  145. }
  146. }
  147. void Chunk::save( Framework::StreamWriter *zWriter )
  148. {
  149. for( int x = 0; x < CHUNK_SIZE; x++ )
  150. {
  151. for( int y = 0; y < CHUNK_SIZE; y++ )
  152. {
  153. for( int z = 0; z < WORLD_HEIGHT; z++ )
  154. {
  155. int index = ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z;
  156. int blockType = blocks[ index ] ? blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ]->zType->getId() : -1;
  157. zWriter->schreibe( (char *)&blockType, 4 );
  158. if( blockType >= 0 )
  159. StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter );
  160. }
  161. }
  162. }
  163. }
  164. int Chunk::getDimensionId() const
  165. {
  166. return dimensionId;
  167. }
  168. Framework::Punkt Chunk::getCenter() const
  169. {
  170. return location;
  171. }
  172. Framework::Vec3<int> Chunk::getMin() const
  173. {
  174. return { location.x - CHUNK_SIZE / 2, location.y - CHUNK_SIZE / 2, 0 };
  175. }
  176. Framework::Vec3<int> Chunk::getMax() const
  177. {
  178. return { location.x + CHUNK_SIZE / 2, location.y + CHUNK_SIZE / 2, WORLD_HEIGHT };
  179. }
  180. Game *Chunk::zGameObj() const
  181. {
  182. return zGame;
  183. }