Dimension.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "Dimension.h"
  2. #include "Constants.h"
  3. #include "Datei.h"
  4. #include "Game.h"
  5. using namespace Framework;
  6. Dimension::Dimension( int id )
  7. : dimensionId( id ),
  8. chunks( new Trie<Chunk>() ),
  9. entities( new RCArray<Entity>() )
  10. {}
  11. Dimension::~Dimension()
  12. {
  13. entities->release();
  14. chunks->release();
  15. }
  16. void Dimension::tickEntities( Game *zGame )
  17. {
  18. int index = 0;
  19. Array<int> removed;
  20. for( auto entity = entities->getIterator(); entity; entity++, index++ )
  21. {
  22. if( zChunk( Punkt( entity->getPosition().x, entity->getPosition().y ) ) )
  23. entity->tick( this, zGame );
  24. if( entity->isRemoved() )
  25. removed.add( index, 0 );
  26. }
  27. for( auto i = removed.getIterator(); i; i++ )
  28. entities->remove( i );
  29. }
  30. void Dimension::getAddrOf( Punkt cPos, char *addr ) const
  31. {
  32. *(int *)addr = cPos.x;
  33. *( (int *)addr + 1 ) = cPos.y;
  34. addr[ 8 ] = 0;
  35. }
  36. void Dimension::getAddrOfWorld( Punkt wPos, char *addr ) const
  37. {
  38. wPos.x = (int)floor( ( (float)wPos.x + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
  39. wPos.y = (int)floor( ( (float)wPos.y + CHUNK_SIZE / 2 ) / CHUNK_SIZE );
  40. getAddrOf( wPos, addr );
  41. }
  42. Chunk *Dimension::zChunk( Punkt wPos ) const
  43. {
  44. char addr[ 9 ];
  45. getAddrOfWorld( wPos, addr );
  46. return chunks->z( addr );
  47. }
  48. Block *Dimension::zBlock( Vec3<int> location )
  49. {
  50. return zChunk( Punkt( location.x, location.y ) )->zBlockAt( Vec3<int>( ( location.x + CHUNK_SIZE / 2 ) % CHUNK_SIZE, ( location.y + CHUNK_SIZE / 2 ) % CHUNK_SIZE, location.z ) );
  51. }
  52. void Dimension::addEntity( Entity *entity )
  53. {
  54. entities->add( entity );
  55. }
  56. void Dimension::addChunk( Chunk *chunk )
  57. {
  58. char addr[ 9 ];
  59. getAddrOf( chunk->getCenter(), addr );
  60. if( !chunks->z( addr ) )
  61. {
  62. chunks->set( addr, chunk );
  63. getAddrOf( chunk->getCenter() + Punkt( CHUNK_SIZE, 0 ), addr );
  64. Chunk *zChunk = chunks->z( addr );
  65. if( zChunk )
  66. {
  67. zChunk->setNeighbor( WEST, chunk );
  68. chunk->setNeighbor( EAST, chunk );
  69. }
  70. getAddrOf( chunk->getCenter() + Punkt( -CHUNK_SIZE, 0 ), addr );
  71. zChunk = chunks->z( addr );
  72. if( zChunk )
  73. {
  74. zChunk->setNeighbor( EAST, chunk );
  75. chunk->setNeighbor( WEST, chunk );
  76. }
  77. getAddrOf( chunk->getCenter() + Punkt( 0, CHUNK_SIZE ), addr );
  78. zChunk = chunks->z( addr );
  79. if( zChunk )
  80. {
  81. zChunk->setNeighbor( NORTH, chunk );
  82. chunk->setNeighbor( SOUTH, chunk );
  83. }
  84. getAddrOf( chunk->getCenter() + Punkt( 0, -CHUNK_SIZE ), addr );
  85. zChunk = chunks->z( addr );
  86. if( zChunk )
  87. {
  88. zChunk->setNeighbor( SOUTH, chunk ); // TODO: correct this in setBlock
  89. chunk->setNeighbor( NORTH, chunk );
  90. }
  91. }
  92. else
  93. chunk->release();
  94. }
  95. void Dimension::save( Text worldDir ) const
  96. {
  97. for( auto chunk = chunks->getIterator(); chunk; chunk++ )
  98. {
  99. if( !chunk._ )
  100. continue;
  101. Datei *file = new Datei();
  102. Text filePath = worldDir + "/dim/" + dimensionId + "/";
  103. filePath.appendHex( chunk->getCenter().x );
  104. filePath += "_";
  105. filePath.appendHex( chunk->getCenter().y );
  106. filePath += ".chunk";
  107. file->setDatei( filePath );
  108. if( file->open( Datei::Style::schreiben ) )
  109. chunk->save( file );
  110. file->close();
  111. file->release();
  112. }
  113. Text filePath = worldDir + "/dim/" + dimensionId + "/entities";
  114. Datei *file = new Datei();
  115. file->setDatei( filePath );
  116. if( file->open( Datei::Style::schreiben ) )
  117. {
  118. for( auto entity = entities->getIterator(); entity; entity++ )
  119. {
  120. if( entity->zType()->getId() != PlayerEntityType::ID )
  121. {
  122. if( !entity->isRemoved() )
  123. {
  124. int type = entity->zType()->getId();
  125. file->schreibe( (char *)&type, 4 );
  126. StaticRegistry<EntityType>::INSTANCE.zElement( type )->saveEntity( entity, file );
  127. }
  128. }
  129. else
  130. {
  131. Datei pFile;
  132. pFile.setDatei( worldDir + "/player/" + ( (Player *)entity.val() )->getName() );
  133. if( pFile.open( Datei::Style::schreiben ) )
  134. PlayerEntityType::INSTANCE->saveEntity( entity, &pFile );
  135. }
  136. }
  137. file->close();
  138. }
  139. }
  140. int Dimension::getDimensionId() const
  141. {
  142. return dimensionId;
  143. }
  144. bool Dimension::hasChunck( int x, int y ) const
  145. {
  146. return zChunk( Punkt( x, y ) );
  147. }