#include "mapgen_v6.h"
#include "biome.h"
#include "config.h"
+#include "server.h"
#include "database.h"
#include "database-dummy.h"
#include "database-sqlite3.h"
m_gamedef(gamedef),
m_sector_cache(NULL)
{
- /*m_sector_mutex.Init();
- assert(m_sector_mutex.IsInitialized());*/
}
Map::~Map()
/*
*/
void Map::addNodeAndUpdate(v3s16 p, MapNode n,
- std::map<v3s16, MapBlock*> &modified_blocks)
+ std::map<v3s16, MapBlock*> &modified_blocks,
+ bool remove_metadata)
{
INodeDefManager *ndef = m_gamedef->ndef();
/*
Remove node metadata
*/
-
- removeNodeMetadata(p);
+ if (remove_metadata) {
+ removeNodeMetadata(p);
+ }
/*
Set the node on the map
}
}
-bool Map::addNodeWithEvent(v3s16 p, MapNode n)
+bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata)
{
MapEditEvent event;
- event.type = MEET_ADDNODE;
+ event.type = remove_metadata ? MEET_ADDNODE : MEET_SWAPNODE;
event.p = p;
event.n = n;
bool succeeded = true;
try{
std::map<v3s16, MapBlock*> modified_blocks;
- addNodeAndUpdate(p, n, modified_blocks);
+ addNodeAndUpdate(p, n, modified_blocks, remove_metadata);
// Copy modified_blocks to event
for(std::map<v3s16, MapBlock*>::iterator
v3s16 p0 = m_transforming_liquid.pop_front();
u16 total_level = 0;
// surrounding flowing liquid nodes
- NodeNeighbor neighbors[7];
+ NodeNeighbor neighbors[7];
// current level of every block
s8 liquid_levels[7] = {-1, -1, -1, -1, -1, -1, -1};
// target levels
liquid_levels[D_BOTTOM] == LIQUID_LEVEL_SOURCE &&
total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level-
(can_liquid_same_level - relax) &&
- can_liquid_same_level >= relax + 1) {
- total_level = LIQUID_LEVEL_SOURCE * can_liquid_same_level;
+ can_liquid_same_level >= relax + 1) {
+ total_level = LIQUID_LEVEL_SOURCE * can_liquid_same_level;
}
// prevent lakes in air above unloaded blocks
}
// calculate self level 5 blocks
- u8 want_level =
+ u8 want_level =
total_level >= LIQUID_LEVEL_SOURCE * can_liquid_same_level
- ? LIQUID_LEVEL_SOURCE
+ ? LIQUID_LEVEL_SOURCE
: total_level / can_liquid_same_level;
total_level -= want_level * can_liquid_same_level;
/*
if (total_level > 0) //|| flowed != volume)
- infostream <<" AFTER level=" << (int)total_level
+ infostream <<" AFTER level=" << (int)total_level
//<< " flowed="<<flowed<< " volume=" << volume
<< " wantsame="<<(int)want_level<< " top="
<< (int)liquid_levels_want[D_TOP]<< " topwas="
//u8 changed = 0;
for (u16 i = 0; i < 7; i++) {
- if (liquid_levels_want[i] < 0 || !neighbors[i].l)
+ if (liquid_levels_want[i] < 0 || !neighbors[i].l)
continue;
MapNode & n0 = neighbors[i].n;
p0 = neighbors[i].p;
*/
/*
if (
- new_node_content == n0.getContent()
+ new_node_content == n0.getContent()
&& (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
(n0.getLevel(nodemgr) == (u8)new_node_level
//&& ((n0.param2 & LIQUID_FLOW_DOWN_MASK) ==
content_t new_node_content;
s8 new_node_level = -1;
s8 max_node_level = -1;
+ u8 range = rangelim(nodemgr->get(liquid_kind).liquid_range, 0, LIQUID_LEVEL_MAX+1);
if ((num_sources >= 2 && nodemgr->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) {
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
// or the flowing alternative of the first of the surrounding sources (if it's air), so
// liquid_kind is set properly, see above
new_node_content = liquid_kind;
max_node_level = new_node_level = LIQUID_LEVEL_MAX;
+ if (new_node_level < (LIQUID_LEVEL_MAX+1-range))
+ new_node_content = CONTENT_AIR;
} else {
// no surrounding sources, so get the maximum level that can flow into this node
for (u16 i = 0; i < num_flows; i++) {
} else
new_node_level = max_node_level;
- u8 range = rangelim(nodemgr->get(liquid_kind).liquid_range, 0, LIQUID_LEVEL_MAX+1);
- if (new_node_level >= (LIQUID_LEVEL_MAX+1-range))
+ if (max_node_level >= (LIQUID_LEVEL_MAX+1-range))
new_node_content = liquid_kind;
else
new_node_content = CONTENT_AIR;
updateLighting(lighting_modified_blocks, modified_blocks);
}
-NodeMetadata* Map::getNodeMetadata(v3s16 p)
+NodeMetadata *Map::getNodeMetadata(v3s16 p)
{
v3s16 blockpos = getNodeBlockPos(p);
v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
<<PP(blockpos)<<std::endl;
block = emergeBlock(blockpos, false);
}
- if(!block)
- {
+ if(!block){
infostream<<"WARNING: Map::getNodeMetadata(): Block not found"
<<std::endl;
return NULL;
return meta;
}
-void Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
+bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
{
v3s16 blockpos = getNodeBlockPos(p);
v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE;
<<PP(blockpos)<<std::endl;
block = emergeBlock(blockpos, false);
}
- if(!block)
- {
+ if(!block){
infostream<<"WARNING: Map::setNodeMetadata(): Block not found"
<<std::endl;
- return;
+ return false;
}
block->m_node_metadata.set(p_rel, meta);
+ return true;
}
void Map::removeNodeMetadata(v3s16 p)
<<PP(blockpos)<<std::endl;
block = emergeBlock(blockpos, false);
}
- if(!block)
- {
+ if(!block){
infostream<<"WARNING: Map::getNodeTimer(): Block not found"
<<std::endl;
return NodeTimer();
<<PP(blockpos)<<std::endl;
block = emergeBlock(blockpos, false);
}
- if(!block)
- {
+ if(!block){
infostream<<"WARNING: Map::setNodeTimer(): Block not found"
<<std::endl;
return;
*/
ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge):
Map(dout_server, gamedef),
- m_seed(0),
+ m_emerge(emerge),
m_map_metadata_changed(true)
{
verbosestream<<__FUNCTION_NAME<<std::endl;
- m_emerge = emerge;
- m_mgparams = m_emerge->getParamsFromSettings(g_settings);
- if (!m_mgparams)
- m_mgparams = new MapgenV6Params();
-
- m_seed = m_mgparams->seed;
-
- if (g_settings->get("fixed_map_seed").empty())
- {
- m_seed = (((u64)(myrand() & 0xffff) << 0)
- | ((u64)(myrand() & 0xffff) << 16)
- | ((u64)(myrand() & 0xffff) << 32)
- | ((u64)(myrand() & 0xffff) << 48));
- m_mgparams->seed = m_seed;
- }
-
- /*
- Experimental and debug stuff
- */
-
- {
- }
-
/*
Try to load map; if not found, create a new one.
*/
infostream<<"ServerMap: Successfully loaded map "
<<"metadata from "<<savedir
<<", assuming valid save directory."
- <<" seed="<<m_seed<<"."
+ <<" seed="<< m_emerge->params.seed <<"."
<<std::endl;
m_map_saving_enabled = true;
/*
Close database if it was opened
*/
- delete(dbase);
+ delete dbase;
#if 0
/*
delete chunk;
}
#endif
+}
+
+u64 ServerMap::getSeed()
+{
+ return m_emerge->params.seed;
+}
- delete m_mgparams;
+s16 ServerMap::getWaterLevel()
+{
+ return m_emerge->params.water_level;
}
bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
bool enable_mapgen_debug_info = m_emerge->mapgen_debug_info;
EMERGE_DBG_OUT("initBlockMake(): " PP(blockpos) " - " PP(blockpos));
- s16 chunksize = m_mgparams->chunksize;
+ s16 chunksize = m_emerge->params.chunksize;
s16 coffset = -chunksize / 2;
v3s16 chunk_offset(coffset, coffset, coffset);
v3s16 blockpos_div = getContainerPos(blockpos - chunk_offset, chunksize);
blockpos_over_limit(blockpos_max + extra_borders))
return false;
- data->seed = m_seed;
+ data->seed = m_emerge->params.seed;
data->blockpos_min = blockpos_min;
data->blockpos_max = blockpos_max;
data->blockpos_requested = blockpos;
/*infostream<<"finishBlockMake() done for ("<<blockpos_requested.X
<<","<<blockpos_requested.Y<<","
<<blockpos_requested.Z<<")"<<std::endl;*/
+
+ /*
+ Update weather data in blocks
+ */
+ ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
+ for(s16 x=blockpos_min.X-extra_borders.X;
+ x<=blockpos_max.X+extra_borders.X; x++)
+ for(s16 z=blockpos_min.Z-extra_borders.Z;
+ z<=blockpos_max.Z+extra_borders.Z; z++)
+ for(s16 y=blockpos_min.Y-extra_borders.Y;
+ y<=blockpos_max.Y+extra_borders.Y; y++)
+ {
+ v3s16 p(x, y, z);
+ MapBlock *block = getBlockNoCreateNoEx(p);
+ block->heat_last_update = 0;
+ block->humidity_last_update = 0;
+ if (senv->m_use_weather) {
+ updateBlockHeat(senv, p * MAP_BLOCKSIZE, block);
+ updateBlockHumidity(senv, p * MAP_BLOCKSIZE, block);
+ } else {
+ block->heat = HEAT_UNDEFINED;
+ block->humidity = HUMIDITY_UNDEFINED;
+ }
+ }
+
#if 0
if(enable_mapgen_debug_info)
{
return NULL;
}
+void ServerMap::prepareBlock(MapBlock *block) {
+ ServerEnvironment *senv = &((Server *)m_gamedef)->getEnv();
+
+ // Calculate weather conditions
+ block->heat_last_update = 0;
+ block->humidity_last_update = 0;
+ if (senv->m_use_weather) {
+ v3s16 p = block->getPos() * MAP_BLOCKSIZE;
+ updateBlockHeat(senv, p, block);
+ updateBlockHumidity(senv, p, block);
+ } else {
+ block->heat = HEAT_UNDEFINED;
+ block->humidity = HUMIDITY_UNDEFINED;
+ }
+}
+
s16 ServerMap::findGroundLevel(v2s16 p2d)
{
#if 0
Settings params;
- m_emerge->setParamsToSettings(¶ms);
+ m_emerge->saveParamsToSettings(¶ms);
params.writeLines(ss);
ss<<"[end_of_params]\n";
params.parseConfigLine(line);
}
- MapgenParams *mgparams;
- try {
- mgparams = m_emerge->getParamsFromSettings(¶ms);
- } catch (SettingNotFoundException &e) {
- infostream << "Couldn't get a setting from map_meta.txt: "
- << e.what() << std::endl;
- mgparams = NULL;
- }
-
- if (mgparams) {
- if (m_mgparams)
- delete m_mgparams;
- m_mgparams = mgparams;
- m_seed = mgparams->seed;
- } else {
- if (params.exists("seed")) {
- m_seed = params.getU64("seed");
- m_mgparams->seed = m_seed;
- }
- }
+ m_emerge->loadParamsFromSettings(¶ms);
- verbosestream<<"ServerMap::loadMapMeta(): "<<"seed="<<m_seed<<std::endl;
+ verbosestream<<"ServerMap::loadMapMeta(): seed="
+ << m_emerge->params.seed<<std::endl;
}
void ServerMap::saveSectorMeta(ServerMapSector *sector)
out<<"ServerMap: ";
}
-s16 ServerMap::getHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
+s16 ServerMap::updateBlockHeat(ServerEnvironment *env, v3s16 p, MapBlock *block)
{
- if(block == NULL)
- block = getBlockNoCreateNoEx(getNodeBlockPos(p));
- if(block != NULL) {
- if (env->getGameTime() - block->heat_time < 10)
+ u32 gametime = env->getGameTime();
+
+ if (block) {
+ if (gametime - block->heat_last_update < 10)
return block->heat;
+ } else {
+ block = getBlockNoCreateNoEx(getNodeBlockPos(p));
}
- //variant 1: full random
- //f32 heat = NoisePerlin3D(m_emerge->biomedef->np_heat, p.X, env->getGameTime()/100, p.Z, m_emerge->params->seed);
-
- //variant 2: season change based on default heat map
- const f32 offset = 20; // = m_emerge->biomedef->np_heat->offset
- const f32 scale = 20; // = m_emerge->biomedef->np_heat->scale
- const f32 range = 20;
- f32 heat = NoisePerlin2D(m_emerge->biomedef->np_heat, p.X, p.Z,
- m_emerge->params->seed); // 0..50..100
-
- heat -= m_emerge->biomedef->np_heat->offset; // -50..0..+50
-
- // normalizing - todo REMOVE after fixed NoiseParams nparams_biome_def_heat = {50, 50, -> 20, 50,
- if(m_emerge->biomedef->np_heat->scale)
- heat /= m_emerge->biomedef->np_heat->scale / scale; // -20..0..+20
+ f32 heat = m_emerge->biomedef->calcBlockHeat(p, getSeed(),
+ env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
- f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
- seasonv /= 86400 * g_settings->getS16("year_days"); // season change speed
- seasonv += (f32)p.X / 3000; // you can walk to area with other season
- seasonv = sin(seasonv * M_PI);
- heat += (range * (heat < 0 ? 2 : 0.5)) * seasonv; // -60..0..30
-
- heat += offset; // -40..0..50
- heat += p.Y / -333; // upper=colder, lower=hotter, 3c per 1000
-
- // daily change, hotter at sun +4, colder at night -4
- heat += 8 * (sin(cycle_shift(env->getTimeOfDayF(), -0.25) * M_PI) - 0.5); //-44..20..54
-
- if(block != NULL) {
+ if(block) {
block->heat = heat;
- block->heat_time = env->getGameTime();
+ block->heat_last_update = gametime;
}
return heat;
}
-s16 ServerMap::getHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
+s16 ServerMap::updateBlockHumidity(ServerEnvironment *env, v3s16 p, MapBlock *block)
{
- if(block == NULL)
- block = getBlockNoCreateNoEx(getNodeBlockPos(p));
- if(block != NULL) {
- if (env->getGameTime() - block->humidity_time < 10)
+ u32 gametime = env->getGameTime();
+
+ if (block) {
+ if (gametime - block->humidity_last_update < 10)
return block->humidity;
+ } else {
+ block = getBlockNoCreateNoEx(getNodeBlockPos(p));
}
- f32 humidity = NoisePerlin2D(m_emerge->biomedef->np_humidity, p.X, p.Z,
- m_emerge->params->seed);
-
- f32 seasonv = (f32)env->getGameTime() * env->getTimeOfDaySpeed();
- seasonv /= 86400 * 2; // bad weather change speed (2 days)
- seasonv += (f32)p.Z / 300;
- humidity += 30 * sin(seasonv * M_PI);
-
- humidity += -12 * ( sin(cycle_shift(env->getTimeOfDayF(), -0.1) * M_PI) - 0.5);
- humidity = rangelim(humidity, 0, 100);
-
- if(block != NULL) {
+ f32 humidity = m_emerge->biomedef->calcBlockHumidity(p, getSeed(),
+ env->getTimeOfDayF(), gametime * env->getTimeOfDaySpeed());
+
+ if(block) {
block->humidity = humidity;
- block->humidity_time = env->getGameTime();
+ block->humidity_last_update = gametime;
}
return humidity;
}