#include "filesys.h"
#include "utility.h"
#include "voxel.h"
-
-#ifdef _WIN32
- #include <windows.h>
- #define sleep_ms(x) Sleep(x)
-#else
- #include <unistd.h>
- #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="<<m_from_cache_count
- <<" from_map_count="<<m_from_map_count
- <<std::endl;*/
-}
-
-MapBlock * MapBlockPointerCache::getBlockNoCreate(v3s16 p)
-{
- core::map<v3s16, MapBlock*>::Node *n = NULL;
- n = m_blocks.find(p);
- if(n != NULL)
- {
- m_from_cache_count++;
- return n->getValue();
- }
-
- m_from_map_count++;
-
- // Throws InvalidPositionException if not found
- MapBlock *b = m_map->getBlockNoCreate(p);
- m_blocks[p] = b;
- return b;
-}
+#include "porting.h"
/*
Map
return block;
}
+MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
+{
+ try
+ {
+ v2s16 p2d(p3d.X, p3d.Z);
+ MapSector * sector = getSectorNoGenerate(p2d);
+ MapBlock *block = sector->getBlockNoCreate(p3d.Y);
+ return block;
+ }
+ catch(InvalidPositionException &e)
+ {
+ return NULL;
+ }
+}
+
f32 Map::getGroundHeight(v2s16 p, bool generate)
{
try{
Starting point gets sunlight.
Returns the lowest y value of where the sunlight went.
+
+ Mud is turned into grass in where the sunlight stops.
*/
s16 Map::propagateSunlight(v3s16 start,
core::map<v3s16, MapBlock*> & modified_blocks)
modified_blocks.insert(blockpos, block);
}
- else{
+ else
+ {
+ // Turn mud into grass
+ if(n.d == CONTENT_MUD)
+ {
+ n.d = CONTENT_GRASS;
+ block->setNode(relpos, n);
+ modified_blocks.insert(blockpos, block);
+ }
+
+ // Sunlight goes no further
break;
}
}
}
{
- //TimeTaker timer("unspreadLight", g_device);
+ //TimeTaker timer("unspreadLight");
unspreadLight(bank, unlight_from, light_sources, modified_blocks);
}
// - Find out why it works
{
- //TimeTaker timer("spreadLight", g_device);
+ //TimeTaker timer("spreadLight");
spreadLight(bank, light_sources, modified_blocks);
}
*/
v3s16 toppos = p + v3s16(0,1,0);
+ v3s16 bottompos = p + v3s16(0,-1,0);
bool node_under_sunlight = true;
core::map<v3s16, bool> light_sources;
catch(InvalidPositionException &e)
{
}
+
+ if(n.d != CONTENT_TORCH)
+ {
+ /*
+ If there is grass below, change it to mud
+ */
+ try{
+ MapNode bottomnode = getNode(bottompos);
+
+ if(bottomnode.d == CONTENT_GRASS
+ || bottomnode.d == CONTENT_GRASS_FOOTSTEPS)
+ {
+ bottomnode.d = CONTENT_MUD;
+ setNode(bottompos, bottomnode);
+ }
+ }
+ catch(InvalidPositionException &e)
+ {
+ }
+ }
enum LightBank banks[] =
{
#ifndef SERVER
void Map::expireMeshes(bool only_daynight_diffed)
{
- TimeTaker timer("expireMeshes()", g_device);
+ TimeTaker timer("expireMeshes()");
core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator();
b->updateMesh(daynight_ratio);
}
catch(InvalidPositionException &e){}
+ // Leading edge
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio);
}
catch(InvalidPositionException &e){}
+ /*// Trailing edge
+ try{
+ v3s16 p = blockpos + v3s16(1,0,0);
+ MapBlock *b = getBlockNoCreate(p);
+ b->updateMesh(daynight_ratio);
+ }
+ catch(InvalidPositionException &e){}
+ try{
+ v3s16 p = blockpos + v3s16(0,1,0);
+ MapBlock *b = getBlockNoCreate(p);
+ b->updateMesh(daynight_ratio);
+ }
+ catch(InvalidPositionException &e){}
+ try{
+ v3s16 p = blockpos + v3s16(0,0,1);
+ MapBlock *b = getBlockNoCreate(p);
+ b->updateMesh(daynight_ratio);
+ }
+ catch(InvalidPositionException &e){}*/
}
#endif
return true;
}
catch(InvalidPositionException &e){}
+ // Leading edges
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
return true;
}
catch(InvalidPositionException &e){}
+ // Trailing edges
+ try{
+ v3s16 p = blockpos + v3s16(1,0,0);
+ MapBlock *b = getBlockNoCreate(p);
+ if(b->dayNightDiffed())
+ return true;
+ }
+ catch(InvalidPositionException &e){}
+ try{
+ v3s16 p = blockpos + v3s16(0,1,0);
+ MapBlock *b = getBlockNoCreate(p);
+ if(b->dayNightDiffed())
+ return true;
+ }
+ catch(InvalidPositionException &e){}
+ try{
+ v3s16 p = blockpos + v3s16(0,0,1);
+ MapBlock *b = getBlockNoCreate(p);
+ if(b->dayNightDiffed())
+ return true;
+ }
+ catch(InvalidPositionException &e){}
return false;
}
tree_max = a / (t/0.03);
else
tree_max = a;
- u32 count = (rand()%(tree_max+1));
+ u32 count = (myrand()%(tree_max+1));
//u32 count = tree_max;
for(u32 i=0; i<count; i++)
{
- s16 x = (rand()%(MAP_BLOCKSIZE-2))+1;
- s16 z = (rand()%(MAP_BLOCKSIZE-2))+1;
+ s16 x = (myrand()%(MAP_BLOCKSIZE-2))+1;
+ s16 z = (myrand()%(MAP_BLOCKSIZE-2))+1;
s16 y = sector->getGroundHeight(v2s16(x,z))+1;
if(y < WATER_LEVEL)
continue;
bush_max = (pitness*a*4);
if(bush_max > a)
bush_max = a;
- u32 count = (rand()%(bush_max+1));
+ u32 count = (myrand()%(bush_max+1));
for(u32 i=0; i<count; i++)
{
- s16 x = rand()%(MAP_BLOCKSIZE-0)+0;
- s16 z = rand()%(MAP_BLOCKSIZE-0)+0;
+ s16 x = myrand()%(MAP_BLOCKSIZE-0)+0;
+ s16 z = myrand()%(MAP_BLOCKSIZE-0)+0;
s16 y = sector->getGroundHeight(v2s16(x,z))+1;
if(y < WATER_LEVEL)
continue;
*/
if(m_params.ravines_amount != 0)
{
- if(rand()%(s32)(20.0 / m_params.ravines_amount) == 0)
+ if(myrand()%(s32)(20.0 / m_params.ravines_amount) == 0)
{
s16 s = 6;
- s16 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s;
- s16 z = rand()%(MAP_BLOCKSIZE-s*2-1)+s;
+ s16 x = myrand()%(MAP_BLOCKSIZE-s*2-1)+s;
+ s16 z = myrand()%(MAP_BLOCKSIZE-s*2-1)+s;
/*s16 x = 8;
s16 z = 8;*/
s16 y = sector->getGroundHeight(v2s16(x,z))+1;
}
//dstream<<"Not found on disk, generating."<<std::endl;
+ //TimeTaker("emergeBlock()", g_irrlicht);
/*
Do not generate over-limit
// Allocate the block to be a proper one.
block->unDummify();
}
-
- // Randomize a bit. This makes dungeons.
- /*bool low_block_is_empty = false;
- if(rand() % 4 == 0)
- low_block_is_empty = true;*/
- const s32 ued = 4;
- //const s32 ued = 8;
+ /*
+ Create dungeon making table
+ */
+ const s32 ued = MAP_BLOCKSIZE;
bool underground_emptiness[ued*ued*ued];
for(s32 i=0; i<ued*ued*ued; i++)
{
- underground_emptiness[i] = ((rand() % 5) == 0);
+ underground_emptiness[i] = 0;
}
+ // Generate dungeons
+ {
+ /*
+ Initialize orp and ors. Try to find if some neighboring
+ MapBlock has a tunnel ended in its side
+ */
-#if 0
- /*
- This is a messy hack to sort the emptiness a bit
- */
- for(s32 j=0; j<2; j++)
- for(s32 y0=0; y0<ued; y0++)
- for(s32 z0=0; z0<ued; z0++)
- for(s32 x0=0; x0<ued; x0++)
- {
- v3s16 p0(x0,y0,z0);
- bool &e0 = underground_emptiness[
- ued*ued*(z0*ued/MAP_BLOCKSIZE)
- +ued*(y0*ued/MAP_BLOCKSIZE)
- +(x0*ued/MAP_BLOCKSIZE)];
-
- v3s16 dirs[6] = {
- v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left
- /*v3s16(0,1,0), // top
- v3s16(0,-1,0), // bottom*/
- };
- for(s32 i=0; i<4; i++)
+ v3f orp(
+ (float)(myrand()%ued)+0.5,
+ (float)(myrand()%ued)+0.5,
+ (float)(myrand()%ued)+0.5
+ );
+
+ bool found_existing = false;
+
+ // Check z-
+ try
{
- v3s16 p1 = p0 + dirs[i];
- if(isInArea(p1, ued) == false)
- continue;
- bool &e1 = underground_emptiness[
- ued*ued*(p1.Z*ued/MAP_BLOCKSIZE)
- +ued*(p1.Y*ued/MAP_BLOCKSIZE)
- +(p1.X*ued/MAP_BLOCKSIZE)];
- if(e0 == e1)
- continue;
-
- v3s16 dirs[6] = {
- v3s16(0,1,0), // top
- v3s16(0,-1,0), // bottom
- /*v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left*/
- };
- for(s32 i=0; i<2; i++)
+ s16 z = -1;
+ for(s16 y=0; y<ued; y++)
+ for(s16 x=0; x<ued; x++)
{
- v3s16 p2 = p1 + dirs[i];
- if(p2 == p0)
- continue;
- if(isInArea(p2, ued) == false)
- continue;
- bool &e2 = underground_emptiness[
- ued*ued*(p2.Z*ued/MAP_BLOCKSIZE)
- +ued*(p2.Y*ued/MAP_BLOCKSIZE)
- +(p2.X*ued/MAP_BLOCKSIZE)];
- if(e2 != e0)
- continue;
+ v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+ if(getNode(ap).d == CONTENT_AIR)
+ {
+ orp = v3f(x+1,y+1,0);
+ found_existing = true;
+ goto continue_generating;
+ }
+ }
+ }
+ catch(InvalidPositionException &e){}
+
+ // Check z+
+ try
+ {
+ s16 z = ued;
+ for(s16 y=0; y<ued; y++)
+ for(s16 x=0; x<ued; x++)
+ {
+ v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+ if(getNode(ap).d == CONTENT_AIR)
+ {
+ orp = v3f(x+1,y+1,ued-1);
+ found_existing = true;
+ goto continue_generating;
+ }
+ }
+ }
+ catch(InvalidPositionException &e){}
+
+ // Check x-
+ try
+ {
+ s16 x = -1;
+ for(s16 y=0; y<ued; y++)
+ for(s16 z=0; z<ued; z++)
+ {
+ v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+ if(getNode(ap).d == CONTENT_AIR)
+ {
+ orp = v3f(0,y+1,z+1);
+ found_existing = true;
+ goto continue_generating;
+ }
+ }
+ }
+ catch(InvalidPositionException &e){}
+
+ // Check x+
+ try
+ {
+ s16 x = ued;
+ for(s16 y=0; y<ued; y++)
+ for(s16 z=0; z<ued; z++)
+ {
+ v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+ if(getNode(ap).d == CONTENT_AIR)
+ {
+ orp = v3f(ued-1,y+1,z+1);
+ found_existing = true;
+ goto continue_generating;
+ }
+ }
+ }
+ catch(InvalidPositionException &e){}
+
+continue_generating:
+
+ /*
+ Don't always generate dungeon
+ */
+ if(found_existing || rand() % 3 == 0)
+ {
+ /*
+ Generate some tunnel starting from orp and ors
+ */
+ for(u16 i=0; i<3; i++)
+ {
+ v3f rp(
+ (float)(myrand()%ued)+0.5,
+ (float)(myrand()%ued)+0.5,
+ (float)(myrand()%ued)+0.5
+ );
+ s16 min_d = 0;
+ s16 max_d = 4;
+ s16 rs = (myrand()%(max_d-min_d+1))+min_d;
- bool t = e1;
- e1 = e2;
- e2 = t;
+ v3f vec = rp - orp;
- break;
+ for(float f=0; f<1.0; f+=0.04)
+ {
+ v3f fp = orp + vec * f;
+ v3s16 cp(fp.X, fp.Y, fp.Z);
+ s16 d0 = -rs/2;
+ s16 d1 = d0 + rs - 1;
+ for(s16 z0=d0; z0<=d1; z0++)
+ {
+ s16 si = rs - abs(z0);
+ for(s16 x0=-si; x0<=si-1; x0++)
+ {
+ s16 si2 = rs - abs(x0);
+ for(s16 y0=-si2+1; y0<=si2-1; y0++)
+ {
+ s16 z = cp.Z + z0;
+ s16 y = cp.Y + y0;
+ s16 x = cp.X + x0;
+ v3s16 p(x,y,z);
+ if(isInArea(p, ued) == false)
+ continue;
+ underground_emptiness[ued*ued*z + ued*y + x] = 1;
+ }
+ }
+ }
+ }
+
+ orp = rp;
}
- //break;
}
}
-#endif
- // This is the basic material of what the visible flat ground
- // will consist of
- u8 material = CONTENT_GRASS;
-
u8 water_material = CONTENT_WATER;
if(g_settings.getBool("endless_water"))
water_material = CONTENT_OCEAN;
Calculate material
*/
- if(real_y <= surface_y - surface_depth)
+ // If node is over heightmap y, it's air or water
+ if(real_y > surface_y)
+ {
+ // If under water level, it's water
+ if(real_y < WATER_LEVEL)
+ {
+ n.d = water_material;
+ n.setLight(LIGHTBANK_DAY,
+ diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
+ }
+ // else air
+ else
+ n.d = CONTENT_AIR;
+ }
+ // Else it's ground or dungeons (air)
+ else
+ {
+ // Create dungeons
+ if(underground_emptiness[
+ ued*ued*(z0*ued/MAP_BLOCKSIZE)
+ +ued*(y0*ued/MAP_BLOCKSIZE)
+ +(x0*ued/MAP_BLOCKSIZE)])
+ {
+ n.d = CONTENT_AIR;
+ }
+ else
+ {
+ // If it's surface_depth under ground, it's stone
+ if(real_y <= surface_y - surface_depth)
+ {
+ n.d = CONTENT_STONE;
+ }
+ else
+ {
+ // It is mud if it is under the first ground
+ // level or under water
+ if(real_y < WATER_LEVEL || real_y <= surface_y - 1)
+ {
+ n.d = CONTENT_MUD;
+ }
+ else
+ {
+ n.d = CONTENT_GRASS;
+ }
+
+ //n.d = CONTENT_MUD;
+
+ /*// If under water level, it's mud
+ if(real_y < WATER_LEVEL)
+ n.d = CONTENT_MUD;
+ // Only the topmost node is grass
+ else if(real_y <= surface_y - 1)
+ n.d = CONTENT_MUD;
+ else
+ n.d = CONTENT_GRASS;*/
+ }
+ }
+ }
+#if 0
+ else if(real_y <= surface_y - surface_depth)
{
// Create dungeons
if(underground_emptiness[
else
n.d = material;
}
- // If node is over heightmap y
- else{
- // If under water level, it's water
- if(real_y < WATER_LEVEL)
- {
- n.d = water_material;
- n.setLight(LIGHTBANK_DAY,
- diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
- }
- // else air
- else
- n.d = CONTENT_AIR;
- }
+#endif
block->setNode(v3s16(x0,y0,z0), n);
}
}
Add some minerals
*/
- //if(is_underground)
if(some_part_underground)
{
s16 underground_level = (lowest_ground_y/MAP_BLOCKSIZE - block_y)+1;
- for(s16 i=0; i<underground_level*3; i++)
+
+ /*
+ Add meseblocks
+ */
+ for(s16 i=0; i<underground_level*1; i++)
{
- if(rand()%2 == 0)
+ if(myrand()%2 == 0)
{
v3s16 cp(
- (rand()%(MAP_BLOCKSIZE-2))+1,
- (rand()%(MAP_BLOCKSIZE-2))+1,
- (rand()%(MAP_BLOCKSIZE-2))+1
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1
);
MapNode n;
//if(is_ground_content(block->getNode(cp).d))
if(block->getNode(cp).d == CONTENT_STONE)
- if(rand()%8 == 0)
+ if(myrand()%8 == 0)
block->setNode(cp, n);
for(u16 i=0; i<26; i++)
{
//if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
if(block->getNode(cp+g_26dirs[i]).d == CONTENT_STONE)
- if(rand()%8 == 0)
+ if(myrand()%8 == 0)
+ block->setNode(cp+g_26dirs[i], n);
+ }
+ }
+ }
+
+ /*
+ Add coal
+ */
+ u16 coal_amount = 30.0 * g_settings.getFloat("coal_amount");
+ u16 coal_rareness = 60 / coal_amount;
+ if(coal_rareness == 0)
+ coal_rareness = 1;
+ if(myrand()%coal_rareness == 0)
+ {
+ u16 a = myrand() % 16;
+ u16 amount = coal_amount * a*a*a / 1000;
+ for(s16 i=0; i<amount; i++)
+ {
+ v3s16 cp(
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1
+ );
+
+ MapNode n;
+ n.d = CONTENT_COALSTONE;
+
+ //dstream<<"Adding coalstone"<<std::endl;
+
+ //if(is_ground_content(block->getNode(cp).d))
+ if(block->getNode(cp).d == CONTENT_STONE)
+ if(myrand()%8 == 0)
+ block->setNode(cp, n);
+
+ for(u16 i=0; i<26; i++)
+ {
+ //if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
+ if(block->getNode(cp+g_26dirs[i]).d == CONTENT_STONE)
+ if(myrand()%8 == 0)
block->setNode(cp+g_26dirs[i], n);
}
}
//for(u16 i=0; i<2; i++)
{
v3s16 cp(
- (rand()%(MAP_BLOCKSIZE-2))+1,
- (rand()%(MAP_BLOCKSIZE-2))+1,
- (rand()%(MAP_BLOCKSIZE-2))+1
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1,
+ (myrand()%(MAP_BLOCKSIZE-2))+1
);
// Check that the place is empty
n.d = CONTENT_STONE;
MapNode n2;
n2.d = CONTENT_AIR;
- s16 depth = maxdepth + (rand()%10);
+ s16 depth = maxdepth + (myrand()%10);
s16 z = 0;
s16 minz = -6 - (-2);
s16 maxz = 6 -1;
for(s16 x=-6; x<=6; x++)
{
- z += -1 + (rand()%3);
+ z += -1 + (myrand()%3);
if(z < minz)
z = minz;
if(z > maxz)
z = maxz;
- for(s16 y=depth+(rand()%2); y<=6; y++)
+ for(s16 y=depth+(myrand()%2); y<=6; y++)
{
/*std::cout<<"("<<p2.X<<","<<p2.Y<<","<<p2.Z<<")"
<<std::endl;*/
{
v3s16 p2 = p + v3s16(x,y,z-2);
- if(is_ground_content(sector->getNode(p2).d))
+ if(is_ground_content(sector->getNode(p2).d)
+ && !is_mineral(sector->getNode(p2).d))
sector->setNode(p2, n);
}
{
v3s16 p2 = p + v3s16(x,y,z-1);
- if(is_ground_content(sector->getNode(p2).d))
+ if(is_ground_content(sector->getNode(p2).d)
+ && !is_mineral(sector->getNode(p2).d))
sector->setNode(p2, n2);
}
{
v3s16 p2 = p + v3s16(x,y,z+0);
- if(is_ground_content(sector->getNode(p2).d))
+ if(is_ground_content(sector->getNode(p2).d)
+ && !is_mineral(sector->getNode(p2).d))
sector->setNode(p2, n2);
}
{
v3s16 p2 = p + v3s16(x,y,z+1);
- if(is_ground_content(sector->getNode(p2).d))
+ if(is_ground_content(sector->getNode(p2).d)
+ && !is_mineral(sector->getNode(p2).d))
sector->setNode(p2, n);
}
}//sectorlock
- u32 deleted_count = 0;
- deleted_count = deleteUnusedSectors(
- SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
-
/*
Only print if something happened or saved whole map
*/
if(only_changed == false || sector_meta_count != 0
- || block_count != 0 || deleted_count != 0)
+ || block_count != 0)
{
dstream<<DTIME<<"ServerMap: Written: "
<<sector_meta_count<<" sector metadata files, "
- <<block_count<<" block files, "
- <<deleted_count<<" sectors unloaded from memory."
+ <<block_count<<" block files"
<<std::endl;
}
}
*/
if(version >= 9)
{
- block->updateObjects(is, version, NULL);
+ block->updateObjects(is, version, NULL, 0);
}
if(created_new)
ClientMap::ClientMap(
Client *client,
- JMutex &range_mutex,
- s16 &viewing_range_nodes,
- bool &viewing_range_all,
+ MapDrawControl &control,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
scene::ISceneNode(parent, mgr, id),
m_client(client),
mesh(NULL),
- m_range_mutex(range_mutex),
- m_viewing_range_nodes(viewing_range_nodes),
- m_viewing_range_all(viewing_range_all)
+ m_control(control)
{
mesh_mutex.Init();
*/
int time1 = time(0);
- //s32 daynight_i = m_client->getDayNightIndex();
u32 daynight_ratio = m_client->getDayNightRatio();
- /*
- Collect all blocks that are in the view range
-
- Should not optimize more here as we want to auto-update
- all changed nodes in viewing range at the next step.
- */
-
- s16 viewing_range_nodes;
- bool viewing_range_all;
- {
- JMutexAutoLock lock(m_range_mutex);
- viewing_range_nodes = m_viewing_range_nodes;
- viewing_range_all = m_viewing_range_all;
- }
-
m_camera_mutex.Lock();
v3f camera_position = m_camera_position;
v3f camera_direction = m_camera_direction;
camera_position.Y / BS,
camera_position.Z / BS);
- v3s16 box_nodes_d = viewing_range_nodes * v3s16(1,1,1);
+ v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1);
v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
// For limiting number of mesh updates per frame
u32 mesh_update_count = 0;
+
+ u32 blocks_would_have_drawn = 0;
+ u32 blocks_drawn = 0;
//NOTE: The sectors map should be locked but we're not doing it
// because it'd cause too much delays
int timecheck_counter = 0;
-
core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator();
for(; si.atEnd() == false; si++)
MapSector *sector = si.getNode()->getValue();
v2s16 sp = sector->getPos();
- if(viewing_range_all == false)
+ if(m_control.range_all == false)
{
if(sp.X < p_blocks_min.X
|| sp.X > p_blocks_max.X
// Total distance
f32 d = blockpos_relative.getLength();
- if(viewing_range_all == false)
+ if(m_control.range_all == false)
{
// If block is far away, don't draw it
- if(d > viewing_range_nodes * BS)
+ if(d > m_control.wanted_range * BS)
// This is nicer when fog is used
- //if((dforward+d)/2 > viewing_range_nodes * BS)
+ //if((dforward+d)/2 > m_control.wanted_range * BS)
continue;
}
}
f32 faraway = BS*50;
- //f32 faraway = viewing_range_nodes * BS;
+ //f32 faraway = m_control.wanted_range * BS;
/*
This has to be done with the mesh_mutex unlocked
*/
- if(mesh_expired && mesh_update_count < 6
- && (d < faraway || mesh_update_count < 3))
- //if(mesh_expired && mesh_update_count < 4)
+ // Pretty random but this should work somewhat nicely
+ if(mesh_expired && (
+ (mesh_update_count < 3
+ && (d < faraway || mesh_update_count < 2)
+ )
+ ||
+ (m_control.range_all && mesh_update_count < 20)
+ )
+ )
+ /*if(mesh_expired && mesh_update_count < 6
+ && (d < faraway || mesh_update_count < 3))*/
{
mesh_update_count++;
if(mesh == NULL)
continue;
+
+ blocks_would_have_drawn++;
+ if(blocks_drawn >= m_control.wanted_max_blocks
+ && m_control.range_all == false
+ && d > m_control.wanted_min_range * BS)
+ continue;
+ blocks_drawn++;
u32 c = mesh->getMeshBufferCount();
}
} // foreach sectorblocks
}
+
+ m_control.blocks_drawn = blocks_drawn;
+ m_control.blocks_would_have_drawn = blocks_would_have_drawn;
/*dstream<<"renderMap(): is_transparent_pass="<<is_transparent_pass
<<", rendered "<<vertex_count<<" vertices."<<std::endl;*/
}
-void ClientMap::updateMesh()
+v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod)
+{
+ /*
+ Add it to all blocks touching it
+ */
+ v3s16 dirs[7] = {
+ v3s16(0,0,0), // this
+ v3s16(0,0,1), // back
+ v3s16(0,1,0), // top
+ v3s16(1,0,0), // right
+ v3s16(0,0,-1), // front
+ v3s16(0,-1,0), // bottom
+ v3s16(-1,0,0), // left
+ };
+ for(u16 i=0; i<7; i++)
+ {
+ v3s16 p2 = p + dirs[i];
+ // Block position of neighbor (or requested) node
+ v3s16 blockpos = getNodeBlockPos(p2);
+ MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+ if(blockref == NULL)
+ continue;
+ // Relative position of requested node
+ v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+ blockref->setTempMod(relpos, mod);
+ }
+ return getNodeBlockPos(p);
+}
+v3s16 ClientMap::clearTempMod(v3s16 p)
{
- //TODO: Remove this
+ v3s16 dirs[7] = {
+ v3s16(0,0,0), // this
+ v3s16(0,0,1), // back
+ v3s16(0,1,0), // top
+ v3s16(1,0,0), // right
+ v3s16(0,0,-1), // front
+ v3s16(0,-1,0), // bottom
+ v3s16(-1,0,0), // left
+ };
+ for(u16 i=0; i<7; i++)
+ {
+ v3s16 p2 = p + dirs[i];
+ // Block position of neighbor (or requested) node
+ v3s16 blockpos = getNodeBlockPos(p2);
+ MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+ if(blockref == NULL)
+ continue;
+ // Relative position of requested node
+ v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+ blockref->clearTempMod(relpos);
+ }
+ return getNodeBlockPos(p);
}
void ClientMap::PrintInfo(std::ostream &out)
#if 1
void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
{
- TimeTaker timer1("emerge", g_device, &emerge_time);
+ TimeTaker timer1("emerge", &emerge_time);
// Units of these are MapBlocks
v3s16 p_min = getNodeBlockPos(a.MinEdge);
bool block_data_inexistent = false;
try
{
- TimeTaker timer1("emerge load", g_device, &emerge_load_time);
+ TimeTaker timer1("emerge load", &emerge_load_time);
/*dstream<<"Loading block (caller_id="<<caller_id<<")"
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
#if 0
void MapVoxelManipulator::emerge(VoxelArea a)
{
- TimeTaker timer1("emerge", g_device, &emerge_time);
+ TimeTaker timer1("emerge", &emerge_time);
v3s16 size = a.getExtent();
continue;
try
{
- TimeTaker timer1("emerge load", g_device, &emerge_load_time);
+ TimeTaker timer1("emerge load", &emerge_load_time);
MapNode n = m_map->getNode(a.MinEdge + p);
m_data[i] = n;
m_flags[i] = 0;
if(m_area.getExtent() == v3s16(0,0,0))
return;
- //TimeTaker timer1("blitBack", g_device);
+ //TimeTaker timer1("blitBack");
/*
Initialize block cache