Chunk.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "Chunk.h"
  2. #include "Constants.h"
  3. #include "Game.h"
  4. Chunk::Chunk( Framework::Punkt location, Game *zGame, int dimensionId )
  5. : EventThrower(),
  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::Reader *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. Block *Chunk::getBlockAt( Framework::Vec3<int> location ) const
  32. {
  33. location.x += CHUNK_SIZE / 2;
  34. location.y += CHUNK_SIZE / 2;
  35. Block *result = dynamic_cast<Block *>( blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ]->getThis() );
  36. return result;
  37. }
  38. Block *Chunk::zBlockAt( Framework::Vec3<int> location ) const
  39. {
  40. location.x += CHUNK_SIZE / 2;
  41. location.y += CHUNK_SIZE / 2;
  42. return blocks[ ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z ];
  43. }
  44. void Chunk::putBlockAt( Framework::Vec3<int> location, Block *block )
  45. {
  46. location.x -= this->location.x - CHUNK_SIZE / 2;
  47. location.y -= this->location.x - CHUNK_SIZE / 2;
  48. int index = ( location.x * CHUNK_SIZE + location.y ) * CHUNK_SIZE + location.z;
  49. Block *old = blocks[ index ];
  50. blocks[ index ] = block;
  51. Block *neighbor = zGame->zBlockAt( location + getDirection( NORTH ), dimensionId );
  52. if( neighbor )
  53. {
  54. neighbor->neighbours[ SOUTH ] = block;
  55. block->neighbours[ NORTH ] = neighbor;
  56. }
  57. neighbor = zGame->zBlockAt( location + getDirection( EAST ), dimensionId );
  58. if( neighbor )
  59. {
  60. neighbor->neighbours[ WEST ] = block;
  61. block->neighbours[ EAST ] = neighbor;
  62. }
  63. neighbor = zGame->zBlockAt( location + getDirection( SOUTH ), dimensionId );
  64. if( neighbor ) {}
  65. {
  66. neighbor->neighbours[ NORTH ] = block;
  67. block->neighbours[ SOUTH ] = neighbor;
  68. }
  69. neighbor = zGame->zBlockAt( location + getDirection( WEST ), dimensionId );
  70. if( neighbor )
  71. {
  72. neighbor->neighbours[ EAST ] = block;
  73. block->neighbours[ WEST ] = neighbor;
  74. }
  75. neighbor = zGame->zBlockAt( location + getDirection( TOP ), dimensionId );
  76. if( neighbor )
  77. {
  78. neighbor->neighbours[ BOTTOM ] = block;
  79. block->neighbours[ TOP ] = neighbor;
  80. }
  81. neighbor = zGame->zBlockAt( location + getDirection( BOTTOM ), dimensionId );
  82. if( neighbor )
  83. {
  84. neighbor->neighbours[ TOP ] = block;
  85. block->neighbours[ BOTTOM ] = neighbor;
  86. }
  87. if( old )
  88. old->release();
  89. }
  90. void Chunk::setNeighbor( Direction dir, Chunk *zChunk )
  91. {
  92. zNeighbours[ dir ] = zChunk;
  93. for( int i = 0; i < CHUNK_SIZE; i++ )
  94. {
  95. for( int z = 0; z < WORLD_HEIGHT; z++ )
  96. {
  97. if( dir == NORTH )
  98. {
  99. int index = i * CHUNK_SIZE * CHUNK_SIZE + z;
  100. if( blocks[ index ] )
  101. blocks[ index ]->neighbours[ NORTH ] = zChunk->blocks[ ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z ];
  102. }
  103. else if( dir == EAST )
  104. {
  105. int index = ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z;
  106. if( blocks[ index ] )
  107. blocks[ index ]->neighbours[ EAST ] = zChunk->blocks[ i * CHUNK_SIZE + z ];
  108. }
  109. else if( dir == SOUTH )
  110. {
  111. int index = ( i * CHUNK_SIZE + CHUNK_SIZE - 1 ) * CHUNK_SIZE + z;
  112. if( blocks[ index ] )
  113. blocks[ index ]->neighbours[ SOUTH ] = zChunk->blocks[ i * CHUNK_SIZE * CHUNK_SIZE + z ];
  114. }
  115. else if( dir == WEST )
  116. {
  117. int index = i * CHUNK_SIZE + z;
  118. if( blocks[ index ] )
  119. blocks[ index ]->neighbours[ WEST ] = zChunk->blocks[ ( ( CHUNK_SIZE - 1 ) * CHUNK_SIZE + i ) * CHUNK_SIZE + z ];
  120. }
  121. }
  122. }
  123. }
  124. void Chunk::load( Framework::Reader *zReader )
  125. {
  126. for( int x = 0; x < CHUNK_SIZE; x++ )
  127. {
  128. for( int y = 0; y < CHUNK_SIZE; y++ )
  129. {
  130. for( int z = 0; z < WORLD_HEIGHT; z++ )
  131. {
  132. int blockType;
  133. zReader->lese( (char *)&blockType, 4 );
  134. if( blockType >= 0 )
  135. {
  136. Block *block = StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->loadBlock( Framework::Vec3<int>( x, y, z ), zGame, zReader );
  137. blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ] = block;
  138. }
  139. }
  140. }
  141. }
  142. }
  143. void Chunk::save( Framework::Writer *zWriter )
  144. {
  145. for( int x = 0; x < CHUNK_SIZE; x++ )
  146. {
  147. for( int y = 0; y < CHUNK_SIZE; y++ )
  148. {
  149. for( int z = 0; z < WORLD_HEIGHT; z++ )
  150. {
  151. int index = ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z;
  152. int blockType = blocks[ index ] ? blocks[ ( x * CHUNK_SIZE + y ) * CHUNK_SIZE + z ]->zType->getId() : -1;
  153. zWriter->schreibe( (char *)&blockType, 4 );
  154. if( blockType >= 0 )
  155. StaticRegistry<BlockType>::INSTANCE.zElement( blockType )->saveBlock( blocks[ index ], zWriter );
  156. }
  157. }
  158. }
  159. }
  160. int Chunk::getDimensionId() const
  161. {
  162. return dimensionId;
  163. }
  164. Framework::Punkt Chunk::getCenter() const
  165. {
  166. return location;
  167. }
  168. Game *Chunk::zGameObj() const
  169. {
  170. return zGame;
  171. }