/*
Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
m_dout(dout),
m_sector_cache(NULL)
{
- m_sector_mutex.Init();
- assert(m_sector_mutex.IsInitialized());
+ /*m_sector_mutex.Init();
+ assert(m_sector_mutex.IsInitialized());*/
}
Map::~Map()
MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
{
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
return getSectorNoGenerateNoExNoLock(p);
}
*/
void Map::timerUpdate(float dtime)
{
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Iterator si;
u32 Map::deleteUnusedSectors(float timeout, bool only_blocks,
core::list<v3s16> *deleted_blocks)
{
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::list<v2s16> sector_deletion_queue;
core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
ServerMap::ServerMap(std::string savedir):
Map(dout_server),
- m_seed(0)
+ m_seed(0),
+ m_map_metadata_changed(true)
{
+ dstream<<__FUNCTION_NAME<<std::endl;
//m_chunksize = 64;
//m_chunksize = 16; // Too slow
ServerMap::~ServerMap()
{
+ dstream<<__FUNCTION_NAME<<std::endl;
+
try
{
if(m_map_saving_enabled)
{
// The base ground level
double base = (double)WATER_LEVEL - (double)AVERAGE_MUD_AMOUNT
- + 25. * noise2d_perlin(
+ + 20. * noise2d_perlin(
0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
(seed>>32)+654879876, 6, 0.6);
base = base2;*/
#if 1
// Higher ground level
- double higher = (double)WATER_LEVEL + 25. + 45. * noise2d_perlin(
+ double higher = (double)WATER_LEVEL + 25. + 35. * noise2d_perlin(
0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
seed+85039, 5, 0.69);
//higher = 30; // For debugging
return h;
}
+double get_mud_add_amount(u64 seed, v2s16 p)
+{
+ return ((float)AVERAGE_MUD_AMOUNT + 3.0 * noise2d_perlin(
+ 0.5+(float)p.X/200, 0.5+(float)p.Y/200,
+ seed+91013, 3, 0.55));
+}
+
/*
Adds random objects to block, depending on the content of the block
*/
block->m_static_objects.insert(0, s_obj);
delete obj;
}
+ if(myrand() % 300 == 0)
+ {
+ v3f pos_f = intToFloat(p+block->getPosRelative(), BS);
+ pos_f.Y -= BS*0.4;
+ ServerActiveObject *obj = new Oerkki1SAO(NULL,0,pos_f);
+ std::string data = obj->getStaticData();
+ StaticObject s_obj(obj->getType(),
+ obj->getBasePosition(), data);
+ // Add one
+ block->m_static_objects.insert(0, s_obj);
+ delete obj;
+ }
}
}
}
/*
Generate general ground level to full area
*/
-
{
// 22ms @cs=8
- //TimeTaker timer1("ground level");
+ TimeTaker timer1("Generating ground level");
+
+#if 0
+ NoiseBuffer noisebuf1;
+ //NoiseBuffer noisebuf2;
+ {
+ v3f minpos_f(
+ data->sectorpos_bigbase.X*MAP_BLOCKSIZE,
+ y_nodes_min,
+ data->sectorpos_bigbase.Y*MAP_BLOCKSIZE
+ );
+ v3f maxpos_f = minpos_f + v3f(
+ data->sectorpos_bigbase_size*MAP_BLOCKSIZE,
+ y_nodes_max-y_nodes_min,
+ data->sectorpos_bigbase_size*MAP_BLOCKSIZE
+ );
+ v3f samplelength_f = v3f(4.0, 4.0, 4.0);
+
+ TimeTaker timer("noisebuf.create");
+
+ noisebuf1.create(data->seed+25104, 6, 0.60, 200.0,
+ minpos_f.X, minpos_f.Y, minpos_f.Z,
+ maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+ samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+ /*noisebuf1.create(data->seed+25104, 3, 0.60, 25.0,
+ minpos_f.X, minpos_f.Y, minpos_f.Z,
+ maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+ samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+ noisebuf2.create(data->seed+25105, 4, 0.50, 200.0,
+ minpos_f.X, minpos_f.Y, minpos_f.Z,
+ maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+ samplelength_f.X, samplelength_f.Y, samplelength_f.Z);*/
+ }
+ for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
+ for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
+ {
+ // Node position
+ v2s16 p2d = data->sectorpos_bigbase*MAP_BLOCKSIZE + v2s16(x,z);
+
+ // Ground height at this point
+ float surface_y_f = 0.0;
+
+ // Use perlin noise for ground height
+ surface_y_f = base_rock_level_2d(data->seed, p2d);
+ //surface_y_f = base_rock_level_2d(data->seed, p2d);
+
+ // Convert to integer
+ s16 surface_y = (s16)surface_y_f;
+
+ // Log it
+ if(surface_y > stone_surface_max_y)
+ stone_surface_max_y = surface_y;
+
+ /*
+ Fill ground with stone
+ */
+ {
+ // Use fast index incrementing
+ v3s16 em = data->vmanip.m_area.getExtent();
+ u32 i = data->vmanip.m_area.index(v3s16(p2d.X, y_nodes_min, p2d.Y));
+ for(s16 y=y_nodes_min; y<=y_nodes_max; y++)
+ {
+ // Skip if already generated.
+ // This is done here because there might be a cave at
+ // any point in ground, which could look like it
+ // wasn't generated.
+ if(data->vmanip.m_data[i].d != CONTENT_AIR)
+ break;
+
+ /*s16 noiseval = 50.0 * noise3d_perlin(
+ 0.5+(float)p2d.X/100.0,
+ 0.5+(float)y/100.0,
+ 0.5+(float)p2d.Y/100.0,
+ data->seed+123, 5, 0.5);*/
+ double noiseval = 64.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+ /*double noiseval = 30.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+ noiseval *= MYMAX(0, -0.2 + noisebuf2.get(p2d.X, y, p2d.Y));*/
+
+ //if(y < surface_y + noiseval)
+ if(noiseval > 0)
+ //if(noiseval > y)
+ data->vmanip.m_data[i].d = CONTENT_STONE;
+
+ data->vmanip.m_area.add_y(em, i, 1);
+ }
+ }
+ }
+#endif
+
+#if 1
for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
{
}
}
}
+#endif
}//timer1
/*
Loop this part, it will make stuff look older and newer nicely
*/
- //for(u32 i_age=0; i_age<1; i_age++)
- for(u32 i_age=0; i_age<2; i_age++)
+ const u32 age_loops = 2;
+ for(u32 i_age=0; i_age<age_loops; i_age++)
{ // Aging loop
/******************************
BEGINNING OF AGING LOOP
******************************/
+#if 1
{
// 24ms @cs=8
//TimeTaker timer1("caves");
}
}//timer1
+#endif
+
+#if 1
{
// 46ms @cs=8
//TimeTaker timer1("ore veins");
}
}//timer1
+#endif
+
+#if 1
{
// 15ms @cs=8
- //TimeTaker timer1("add mud");
+ TimeTaker timer1("add mud");
/*
Add mud to the central chunk
v2s16 p2d = data->sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
// Randomize mud amount
- s16 mud_add_amount = (s16)(2.5 + 2.0 * noise2d_perlin(
- 0.5+(float)p2d.X/200, 0.5+(float)p2d.Y/200,
- data->seed+1, 3, 0.55));
+ s16 mud_add_amount = get_mud_add_amount(data->seed, p2d) / 2.0;
// Find ground level
s16 surface_y = find_ground_level_clever(data->vmanip, p2d);
u32 i = data->vmanip.m_area.index(v3s16(p2d.X, surface_y, p2d.Y));
MapNode *n = &data->vmanip.m_data[i];
if(n->d == CONTENT_GRASS)
- n->d = CONTENT_MUD;
+ *n = MapNode(CONTENT_MUD);
+ //n->d = CONTENT_MUD;
}
/*
break;
MapNode &n = data->vmanip.m_data[i];
- n.d = CONTENT_MUD;
+ n = MapNode(CONTENT_MUD);
+ //n.d = CONTENT_MUD;
mudcount++;
data->vmanip.m_area.add_y(em, i, 1);
}
}//timer1
+#endif
+
+#if 1
{
// 340ms @cs=8
TimeTaker timer1("flow mud");
}
}//timer1
+#endif
+
+#if 1
{
// 50ms @cs=8
- //TimeTaker timer1("add water");
+ TimeTaker timer1("add water");
/*
Add water to the central chunk (and a bit more)
}
}//timer1
+#endif
} // Aging loop
/***********************
END OF AGING LOOP
************************/
+#if 1
{
//TimeTaker timer1("convert mud to sand");
}
}//timer1
+#endif
+
+#if 1
{
// 1ms @cs=8
//TimeTaker timer1("generate trees");
}
}//timer1
+#endif
+#if 1
{
// 19ms @cs=8
//TimeTaker timer1("grow grass");
}
}//timer1
+#endif
/*
Initial lighting (sunlight)
// 750ms @cs=8, can't optimize more
TimeTaker timer1("initial lighting");
+ // NOTE: This is no used... umm... for some reason!
#if 0
/*
Go through the edges and add all nodes that have light to light_sources
ServerMapSector * ServerMap::createSector(v2s16 p2d)
{
- DSTACK("%s: p2d=(%d,%d)",
+ DSTACKF("%s: p2d=(%d,%d)",
__FUNCTION_NAME,
p2d.X, p2d.Y);
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
)
{
- DSTACK("%s: p=(%d,%d,%d)",
+ DSTACKF("%s: p=(%d,%d,%d)",
__FUNCTION_NAME,
p.X, p.Y, p.Z);
block->unDummify();
}
+#if 0
+ /*
+ Generate a completely empty block
+ */
+ for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
+ for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
+ {
+ for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
+ {
+ MapNode n;
+ n.d = CONTENT_AIR;
+ block->setNode(v3s16(x0,y0,z0), n);
+ }
+ }
+#else
+ /*
+ Generate a proper block
+ */
+
u8 water_material = CONTENT_WATERSOURCE;
s32 lowest_ground_y = 32767;
//s16 surface_y = 0;
+ s16 mud_add_amount = get_mud_add_amount(m_seed, p2d_nodes+v2s16(x0,z0));
+
s16 surface_y = base_rock_level_2d(m_seed, p2d_nodes+v2s16(x0,z0))
- + AVERAGE_MUD_AMOUNT;
+ + mud_add_amount;
// If chunks are disabled
if(m_chunksize == 0)
surface_y = WATER_LEVEL + 1;
}
}
}
+
+#endif // end of proper block generation
/*
Add block to sector.
MapBlock * ServerMap::createBlock(v3s16 p)
{
- DSTACK("%s: p=(%d,%d,%d)",
+ DSTACKF("%s: p=(%d,%d,%d)",
__FUNCTION_NAME, p.X, p.Y, p.Z);
/*
core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
)
{
- DSTACK("%s: p=(%d,%d,%d), only_from_disk=%d",
+ DSTACKF("%s: p=(%d,%d,%d), only_from_disk=%d",
__FUNCTION_NAME,
p.X, p.Y, p.Z, only_from_disk);
/*
Plan B: Get from map generator perlin noise function
*/
- double level = base_rock_level_2d(m_seed, p2d);
+ // This won't work if proper generation is disabled
+ if(m_chunksize == 0)
+ return WATER_LEVEL+2;
+ double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT;
return (s16)level;
}
dstream<<DTIME<<"ServerMap: Saving whole map, this can take time."
<<std::endl;
- saveMapMeta();
+ if(only_changed == false || m_map_metadata_changed)
+ {
+ saveMapMeta();
+ }
- // Disable saving chunk metadata file if chunks are disabled
+ // Disable saving chunk metadata if chunks are disabled
if(m_chunksize != 0)
{
- saveChunkMeta();
+ if(only_changed == false || anyChunkModified())
+ saveChunkMeta();
}
u32 sector_meta_count = 0;
u32 block_count = 0;
{ //sectorlock
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
for(; i.atEnd() == false; i++)
dstream<<DTIME<<"There are "<<list.size()<<" sectors."<<std::endl;
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
s32 counter = 0;
s32 printed_counter = -100000;
os<<"[end_of_params]\n";
+ m_map_metadata_changed = false;
}
void ServerMap::loadMapMeta()
// Write chunk data
chunk->serialize(os, version);
}
+
+ setChunksNonModified();
}
void ServerMap::loadChunkMeta()
MapSector *sector = NULL;
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
try{
sector = loadSectorMeta(sectorsubdir);
ClientMapSector *sector = new ClientMapSector(this, p2d);
{
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
m_sectors.insert(p2d, sector);
}
DSTACK(__FUNCTION_NAME);
ClientMapSector *sector = NULL;
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d);
{
sector = new ClientMapSector(this, p2d);
{
- JMutexAutoLock lock(m_sector_mutex);
+ //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
m_sectors.insert(p2d, sector);
}
}