Dimension.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "Dimension.h"
  2. #include "Constants.h"
  3. #include "Datei.h"
  4. #include "Game.h"
  5. #include "Globals.h"
  6. using namespace Framework;
  7. #define MAX_VIEW_DISTANCE CHUNK_SIZE * 8
  8. Dimension::Dimension( int id )
  9. : dimensionId( id ),
  10. chunks( new Trie<Chunk>() ),
  11. entities( new RCArray<Entity>() )
  12. {}
  13. Dimension::~Dimension()
  14. {
  15. entities->release();
  16. chunks->release();
  17. }
  18. void Dimension::updateVisibility()
  19. {
  20. bool changed = true;
  21. while( changed )
  22. {
  23. changed = false;
  24. for( auto chunk : chunkList )
  25. {
  26. if( chunk )
  27. changed |= chunk->updateVisibility();
  28. }
  29. }
  30. }
  31. void Dimension::getAddrOf( Punkt cPos, char* addr ) const
  32. {
  33. *(int*)addr = cPos.x;
  34. *((int*)addr + 1) = cPos.y;
  35. }
  36. void Dimension::getAddrOfWorld( Punkt wPos, char* addr ) const
  37. {
  38. if( wPos.x < 0 )
  39. wPos.x -= CHUNK_SIZE;
  40. if( wPos.y < 0 ) // needed because otherwise would (-8, -8) have the same adress as (8, 8)
  41. wPos.y -= CHUNK_SIZE;
  42. wPos /= CHUNK_SIZE;
  43. getAddrOf( wPos, addr );
  44. }
  45. Chunk* Dimension::zChunk( Punkt wPos ) const
  46. {
  47. char addr[ 8 ];
  48. getAddrOfWorld( wPos, addr );
  49. return chunks->z( addr, 8 );
  50. }
  51. Framework::Either<Block*, int> Dimension::zBlock( Vec3<int> location )
  52. {
  53. Chunk* c = zChunk( currentGame->getChunkCenter( location.x, location.y ) );
  54. if( c )
  55. {
  56. int x = location.x % CHUNK_SIZE;
  57. int y = location.y % CHUNK_SIZE;
  58. if( x < 0 )
  59. x += CHUNK_SIZE;
  60. if( y < 0 )
  61. y += CHUNK_SIZE;
  62. return c->zBlockAt( Vec3<int>( x, y, location.z ) );
  63. }
  64. return 0;
  65. }
  66. void Dimension::addEntity( Entity* entity )
  67. {
  68. entities->add( entity );
  69. }
  70. void Dimension::setChunk( Chunk* chunk, Punkt center )
  71. {
  72. char addr[ 8 ];
  73. getAddrOfWorld( center, addr );
  74. Chunk* old = chunks->z( addr, 8 );
  75. if( old )
  76. {
  77. for( int i = 0; i < chunkList.getEintragAnzahl(); i++ )
  78. {
  79. if( chunkList.get( i ) == old )
  80. {
  81. chunkList.remove( i );
  82. break;
  83. }
  84. }
  85. }
  86. chunks->set( addr, 8, chunk );
  87. if( chunk )
  88. {
  89. chunkList.add( chunk );
  90. chunk->setAdded();
  91. }
  92. getAddrOfWorld( center + Punkt( CHUNK_SIZE, 0 ), addr );
  93. Chunk* zChunk = chunks->z( addr, 8 );
  94. if( zChunk )
  95. {
  96. zChunk->setNeighbor( WEST, chunk );
  97. if( chunk )
  98. chunk->setNeighbor( EAST, zChunk );
  99. }
  100. getAddrOfWorld( center + Punkt( -CHUNK_SIZE, 0 ), addr );
  101. zChunk = chunks->z( addr, 8 );
  102. if( zChunk )
  103. {
  104. zChunk->setNeighbor( EAST, chunk );
  105. if( chunk )
  106. chunk->setNeighbor( WEST, zChunk );
  107. }
  108. getAddrOfWorld( center + Punkt( 0, CHUNK_SIZE ), addr );
  109. zChunk = chunks->z( addr, 8 );
  110. if( zChunk )
  111. {
  112. zChunk->setNeighbor( NORTH, chunk );
  113. if( chunk )
  114. chunk->setNeighbor( SOUTH, zChunk );
  115. }
  116. getAddrOfWorld( center + Punkt( 0, -CHUNK_SIZE ), addr );
  117. zChunk = chunks->z( addr, 8 );
  118. if( zChunk )
  119. {
  120. zChunk->setNeighbor( SOUTH, chunk );
  121. if( chunk )
  122. chunk->setNeighbor( NORTH, zChunk );
  123. }
  124. }
  125. int Dimension::getDimensionId() const
  126. {
  127. return dimensionId;
  128. }
  129. bool Dimension::hasChunck( int x, int y ) const
  130. {
  131. return zChunk( Punkt( x, y ) );
  132. }
  133. void Dimension::removeDistantChunks( Punkt wPos )
  134. {
  135. Array<int> removed;
  136. int index = 0;
  137. for( Chunk* chunk : chunkList )
  138. {
  139. if( (chunk->getCenter() - wPos).getLength() > MAX_VIEW_DISTANCE )
  140. removed.add( index, 0 );
  141. index++;
  142. }
  143. for( int i : removed )
  144. {
  145. Chunk* chunk = chunkList.get( i );
  146. chunk->prepareRemove();
  147. setChunk( 0, chunk->getCenter() );
  148. }
  149. }