From c707e00195f1035ae535f3fc8697af42e73190c0 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 29 Nov 2010 10:52:07 +0200 Subject: sitä sun tätä tekeillä, toimii kivasti MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/map.cpp | 419 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 312 insertions(+), 107 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 35bf8bb40..33f40f064 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -9,6 +9,7 @@ #include "client.h" #include "filesys.h" #include "utility.h" +#include "voxel.h" #ifdef _WIN32 #include @@ -18,6 +19,47 @@ #define sleep_ms(x) usleep(x*1000) #endif +MapBlockPointerCache::MapBlockPointerCache(Map *map) +{ + m_map = map; + m_map->m_blockcachelock.cacheCreated(); + + m_from_cache_count = 0; + m_from_map_count = 0; +} + +MapBlockPointerCache::~MapBlockPointerCache() +{ + m_map->m_blockcachelock.cacheRemoved(); + + dstream<<"MapBlockPointerCache:" + <<" from_cache_count="<isDummy()) continue; - + // Calculate relative position in block - v3s16 relpos = n2pos - blockpos * MAP_BLOCKSIZE; + v3s16 relpos = pos - blockpos_last * MAP_BLOCKSIZE; + // Get node straight from the block - MapNode n2 = block->getNode(relpos); - - /* - If the neighbor is dimmer than what was specified - as oldlight (the light of the previous node) - */ - if(n2.getLight() < oldlight) - { - /* - And the neighbor is transparent and it has some light - */ - if(n2.light_propagates() && n2.getLight() != 0) + MapNode n = block->getNode(relpos); + + u8 oldlight = n.getLight(); + u8 newlight = diminish_light(oldlight); + + // Loop through 6 neighbors + for(u16 i=0; i<6; i++){ + // Get the position of the neighbor node + v3s16 n2pos = pos + dirs[i]; + + // Get the block where the node is located + v3s16 blockpos = getNodeBlockPos(n2pos); + + try { + // Only fetch a new block if the block position has changed + try{ + if(block == NULL || blockpos != blockpos_last){ + block = getBlockNoCreate(blockpos); + blockpos_last = blockpos; + + block_checked_in_modified = false; + blockchangecount++; + } + } + catch(InvalidPositionException &e) + { + continue; + } + + // Calculate relative position in block + v3s16 relpos = n2pos - blockpos * MAP_BLOCKSIZE; + // Get node straight from the block + MapNode n2 = block->getNode(relpos); + + bool changed = false; /* - Set light to 0 and recurse. + If the neighbor is brighter than the current node, + add to list (it will light up this node on its turn) */ - u8 current_light = n2.getLight(); - n2.setLight(0); - block->setNode(relpos, n2); - unLightNeighbors(n2pos, current_light, - light_sources, modified_blocks); - - if(block_checked_in_modified == false) + if(n2.getLight() > undiminish_light(oldlight)) + { + lighted_nodes.insert(n2pos, true); + //lighted_nodes.push_back(n2pos); + changed = true; + } + /* + If the neighbor is dimmer than how much light this node + would spread on it, add to list + */ + if(n2.getLight() < newlight) + { + if(n2.light_propagates()) + { + n2.setLight(newlight); + block->setNode(relpos, n2); + lighted_nodes.insert(n2pos, true); + //lighted_nodes.push_back(n2pos); + changed = true; + } + } + + // Add to modified_blocks + if(changed == true && block_checked_in_modified == false) { // If the block is not found in modified_blocks, add. if(modified_blocks.find(blockpos) == NULL) @@ -263,12 +333,20 @@ void Map::unLightNeighbors(v3s16 pos, u8 oldlight, block_checked_in_modified = true; } } - } - else{ - //light_sources.push_back(n2pos); - light_sources.insert(n2pos, true); + catch(InvalidPositionException &e) + { + continue; + } } } + + /*dstream<<"spreadLight(): Changed block " + < 0) + spreadLight(lighted_nodes, modified_blocks); } #endif @@ -1090,6 +1168,13 @@ void Map::timerUpdate(float dtime) void Map::deleteSectors(core::list &list, bool only_blocks) { + /* + Wait for caches to be removed before continuing. + + This disables the existence of caches while locked + */ + SharedPtr cachelock(m_blockcachelock.waitCaches()); + core::list::Iterator j; for(j=list.begin(); j!=list.end(); j++) { @@ -1215,13 +1300,13 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): // Create master heightmap ValueGenerator *maxgen = - ValueGenerator::deSerialize(hmp.height_randmax); + ValueGenerator::deSerialize(hmp.randmax); ValueGenerator *factorgen = - ValueGenerator::deSerialize(hmp.height_randfactor); + ValueGenerator::deSerialize(hmp.randfactor); ValueGenerator *basegen = - ValueGenerator::deSerialize(hmp.height_base); + ValueGenerator::deSerialize(hmp.base); m_heightmap = new UnlimitedHeightmap - (hmp.heightmap_blocksize, maxgen, factorgen, basegen); + (hmp.blocksize, maxgen, factorgen, basegen); // Set map parameters m_params = mp; @@ -1409,6 +1494,9 @@ MapSector * ServerMap::emergeSector(v2s16 p2d) SECTOR_OBJECT_TREE_1); } } + /* + Plant some bushes if sector is pit-like + */ { // Pitness usually goes at around -0.5...0.5 u32 bush_max = 0; @@ -1429,6 +1517,22 @@ MapSector * ServerMap::emergeSector(v2s16 p2d) SECTOR_OBJECT_BUSH_1); } } + /* + Add ravine (randomly) + */ + { + if(rand()%10 == 0) + { + s16 s = 6; + s16 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s; + s16 z = rand()%(MAP_BLOCKSIZE-s*2-1)+s; + /*s16 x = 8; + s16 z = 8;*/ + s16 y = sector->getGroundHeight(v2s16(x,z))+1; + objects->insert(v3s16(x, y, z), + SECTOR_OBJECT_RAVINE); + } + } /* Insert to container @@ -1533,9 +1637,16 @@ MapBlock * ServerMap::emergeBlock( } // Randomize a bit. This makes dungeons. - bool low_block_is_empty = false; + /*bool low_block_is_empty = false; if(rand() % 4 == 0) - low_block_is_empty = true; + low_block_is_empty = true;*/ + + s32 ued = 4; + bool underground_emptiness[ued*ued*ued]; + for(s32 i=0; isetYaw(45); - block->addObject(obj); - } + TimeTaker timer("interpolation", g_device); + + MapVoxelManipulator vmanip(this); + + v3s16 relpos = block->getPosRelative(); + + vmanip.interpolate(VoxelArea(relpos-v3s16(1,1,1), + relpos+v3s16(1,1,1)*(MAP_BLOCKSIZE+1))); + /*vmanip.interpolate(VoxelArea(relpos, + relpos+v3s16(1,1,1)*(MAP_BLOCKSIZE-1)));*/ + + core::map modified_blocks; + vmanip.blitBack(modified_blocks); + dstream<<"blitBack modified "<::Iterator + i = modified_blocks.getIterator(); + i.atEnd() == false; i++) { - v3s16 pos(8, 11, 8); - RatObject *obj = new RatObject(NULL, -1, intToFloat(pos)); - block->addObject(obj); + MapBlock *block = i.getNode()->getValue(); + + changed_blocks.insert(block->getPos(), block); + //lighting_invalidated_blocks.insert(block->getPos(), block); } - */ + + } +#endif /* - Add block to sector. + Sector object stuff */ - sector->insertBlock(block); - - // An y-wise container if changed blocks + + // An y-wise container of changed blocks core::map changed_blocks_sector; /* @@ -1722,6 +1866,7 @@ MapBlock * ServerMap::emergeBlock( i.atEnd() == false; i++) { v3s16 p = i.getNode()->getKey(); + v2s16 p2d(p.X,p.Z); u8 d = i.getNode()->getValue(); //v3s16 p = p_sector - v3s16(0, block_y*MAP_BLOCKSIZE, 0); @@ -1795,6 +1940,66 @@ MapBlock * ServerMap::emergeBlock( objects_to_remove.push_back(p); } } + else if(d == SECTOR_OBJECT_RAVINE) + { + s16 maxdepth = -20; + v3s16 p_min = p + v3s16(-6,maxdepth,-6); + v3s16 p_max = p + v3s16(6,6,6); + if(sector->isValidArea(p_min, p_max, + &changed_blocks_sector)) + { + MapNode n; + n.d = MATERIAL_STONE; + MapNode n2; + n2.d = MATERIAL_AIR; + s16 depth = maxdepth + (rand()%10); + s16 z = 0; + s16 minz = -6 - (-2); + s16 maxz = 6 -1; + for(s16 x=-6; x<=6; x++) + { + z += -1 + (rand()%3); + if(z < minz) + z = minz; + if(z > maxz) + z = maxz; + for(s16 y=depth+(rand()%2); y<=6; y++) + { + /*std::cout<<"("<getNode(p2).d)) + sector->setNode(p2, n); + } + { + v3s16 p2 = p + v3s16(x,y,z-1); + if(is_ground_material(sector->getNode(p2).d)) + sector->setNode(p2, n2); + } + { + v3s16 p2 = p + v3s16(x,y,z+0); + if(is_ground_material(sector->getNode(p2).d)) + sector->setNode(p2, n2); + } + { + v3s16 p2 = p + v3s16(x,y,z+1); + if(is_ground_material(sector->getNode(p2).d)) + sector->setNode(p2, n); + } + + //if(sector->getNode(p+v3s16(x,y,z+1)).solidness()==2) + //if(p.Y+y <= sector->getGroundHeight(p2d+v2s16(x,z-2))+0.5) + } + } + + objects_to_remove.push_back(p); + + // Lighting has to be recalculated for this one. + sector->getBlocksInArea(p_min, p_max, + lighting_invalidated_blocks); + } + } else { dstream<<"ServerMap::emergeBlock(): " @@ -1807,7 +2012,7 @@ MapBlock * ServerMap::emergeBlock( { dstream<<"WARNING: "<<__FUNCTION_NAME <<": while inserting object "<<(int)d - <<" to ("<