Skip to content
Permalink
Browse files

Add MapSettingsManager and new mapgen setting script API functions

This commit refactors the majority of the Mapgen settings system.
- MapgenParams is now owned by MapSettingsManager, itself a part of ServerMap,
  instead of the EmergeManager.
- New Script API functions added:
    core.get_mapgen_setting
    core.get_mapgen_setting_noiseparams,
    core.set_mapgen_setting, and
    core.set_mapgen_setting_noiseparams.
- minetest.get/set_mapgen_params are deprecated by the above new functions.
- It is now possible to view and modify any arbitrary mapgen setting from a mod,
  rather than the base MapgenParams structure.
- MapgenSpecificParams has been removed.
  • Loading branch information
kwolekr committed Jul 3, 2016
1 parent 9270530 commit 3c63c3044d5e4ca36c2649c530f31622581d90fd
@@ -169,6 +169,7 @@ LOCAL_SRC_FILES := \
jni/src/log.cpp \
jni/src/main.cpp \
jni/src/map.cpp \
jni/src/map_settings_manager.cpp \
jni/src/mapblock.cpp \
jni/src/mapblock_mesh.cpp \
jni/src/mapgen.cpp \
@@ -238,6 +239,7 @@ LOCAL_SRC_FILES := \
jni/src/unittest/test_connection.cpp \
jni/src/unittest/test_filepath.cpp \
jni/src/unittest/test_inventory.cpp \
jni/src/unittest/test_map_settings_manager.cpp \
jni/src/unittest/test_mapnode.cpp \
jni/src/unittest/test_nodedef.cpp \
jni/src/unittest/test_noderesolver.cpp \
@@ -2089,7 +2089,9 @@ and `minetest.auth_reload` call the authetification handler.
given biome_name string.
* `minetest.get_mapgen_params()` Returns mapgen parameters, a table containing
`mgname`, `seed`, `chunksize`, `water_level`, and `flags`.
* Deprecated: use minetest.get_mapgen_setting(name) instead
* `minetest.set_mapgen_params(MapgenParams)`
* Deprecated: use minetest.set_mapgen_setting(name, value, override) instead
* Set map generation parameters
* Function cannot be called after the registration period; only initialization
and `on_mapgen_init`
@@ -2099,6 +2101,23 @@ and `minetest.auth_reload` call the authetification handler.
* `flags` contains a comma-delimited string of flags to set,
or if the prefix `"no"` is attached, clears instead.
* `flags` is in the same format and has the same options as `mg_flags` in `minetest.conf`
* `minetest.get_mapgen_setting(name)`
* Gets the *active* mapgen setting (or nil if none exists) in string format with the following
order of precedence:
1) Settings loaded from map_meta.txt or overrides set during mod execution
2) Settings set by mods without a metafile override
3) Settings explicitly set in the user config file, minetest.conf
4) Settings set as the user config default
* `minetest.get_mapgen_setting_noiseparams(name)`
* Same as above, but returns the value as a NoiseParams table if the setting `name` exists
and is a valid NoiseParams
* `minetest.set_mapgen_setting(name, value, [override_meta=false])`
* Sets a mapgen param to `value`, and will take effect if the corresponding mapgen setting
is not already present in map_meta.txt. If the optional boolean override_meta is set to true,
this setting will become the active setting regardless of the map metafile contents.
* Note: to set the seed, use "seed", not "fixed_map_seed"
* `minetest.set_mapgen_setting_noiseparams(name, value, [override_meta=false])`
* Same as above, except value is a NoiseParams table
* `minetest.set_noiseparams(name, noiseparams, set_default)`
* Sets the noiseparams setting of `name` to the noiseparams table specified in `noiseparams`.
* `set_default` is an optional boolean (default: `true`) that specifies whether the setting
@@ -414,6 +414,7 @@ set(common_SRCS
light.cpp
log.cpp
map.cpp
map_settings_manager.cpp
mapblock.cpp
mapgen.cpp
mapgen_flat.cpp
@@ -156,37 +156,19 @@ EmergeManager::~EmergeManager()
}


void EmergeManager::loadMapgenParams()
{
params.load(*g_settings);
}


void EmergeManager::initMapgens()
bool EmergeManager::initMapgens(MapgenParams *params)
{
if (m_mapgens.size())
return;

MapgenType mgtype = Mapgen::getMapgenType(params.mg_name);
if (mgtype == MAPGEN_INVALID) {
const char *default_mapgen_name = Mapgen::getMapgenName(MAPGEN_DEFAULT);
errorstream << "EmergeManager: mapgen " << params.mg_name <<
" not registered; falling back to " <<
default_mapgen_name << std::endl;

params.mg_name = default_mapgen_name;
mgtype = MAPGEN_DEFAULT;
}
return false;

if (!params.sparams) {
params.sparams = Mapgen::createMapgenParams(mgtype);
params.sparams->readParams(g_settings);
}
this->mgparams = params;

for (u32 i = 0; i != m_threads.size(); i++) {
Mapgen *mg = Mapgen::createMapgen(mgtype, i, &params, this);
Mapgen *mg = Mapgen::createMapgen(params->mgtype, i, params, this);
m_mapgens.push_back(mg);
}

return true;
}


@@ -288,12 +270,14 @@ bool EmergeManager::enqueueBlockEmergeEx(
// Mapgen-related helper functions
//


// TODO(hmmmm): Move this to ServerMap
v3s16 EmergeManager::getContainingChunk(v3s16 blockpos)
{
return getContainingChunk(blockpos, params.chunksize);
return getContainingChunk(blockpos, mgparams->chunksize);
}


// TODO(hmmmm): Move this to ServerMap
v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize)
{
s16 coff = -chunksize / 2;
@@ -327,7 +311,7 @@ int EmergeManager::getGroundLevelAtPoint(v2s16 p)
return m_mapgens[0]->getGroundLevelAtPoint(p);
}


// TODO(hmmmm): Move this to ServerMap
bool EmergeManager::isBlockUnderground(v3s16 blockpos)
{
#if 0
@@ -338,7 +322,7 @@ bool EmergeManager::isBlockUnderground(v3s16 blockpos)
#endif

// Use a simple heuristic; the above method is wildly inaccurate anyway.
return blockpos.Y * (MAP_BLOCKSIZE + 1) <= params.water_level;
return blockpos.Y * (MAP_BLOCKSIZE + 1) <= mgparams->water_level;
}

bool EmergeManager::pushBlockEmergeData(
@@ -97,8 +97,16 @@ class EmergeManager {
u32 gen_notify_on;
std::set<u32> gen_notify_on_deco_ids;

// Map generation parameters
MapgenParams params;
// Parameters passed to mapgens owned by ServerMap
// TODO(hmmmm): Remove this after mapgen helper methods using them
// are moved to ServerMap
MapgenParams *mgparams;

// Hackish workaround:
// For now, EmergeManager must hold onto a ptr to the Map's setting manager
// since the Map can only be accessed through the Environment, and the
// Environment is not created until after script initialization.
MapSettingsManager *map_settings_mgr;

// Managers of various map generation-related components
BiomeManager *biomemgr;
@@ -110,8 +118,7 @@ class EmergeManager {
EmergeManager(IGameDef *gamedef);
~EmergeManager();

void loadMapgenParams();
void initMapgens();
bool initMapgens(MapgenParams *mgparams);

void startThreads();
void stopThreads();
@@ -2130,11 +2130,15 @@ void Map::removeNodeTimer(v3s16 p)
*/
ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge):
Map(dout_server, gamedef),
settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"),
m_emerge(emerge),
m_map_metadata_changed(true)
{
verbosestream<<FUNCTION_NAME<<std::endl;

// Tell the EmergeManager about our MapSettingsManager
emerge->map_settings_mgr = &settings_mgr;

/*
Try to load map; if not found, create a new one.
*/
@@ -2170,26 +2174,15 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer
}
else
{
try{
// Load map metadata (seed, chunksize)
loadMapMeta();
}
catch(SettingNotFoundException &e){
infostream<<"ServerMap: Some metadata not found."
<<" Using default settings."<<std::endl;
}
catch(FileNotGoodException &e){
warningstream<<"Could not load map metadata"
//<<" Disabling chunk-based generator."
<<std::endl;
//m_chunksize = 0;
}

infostream<<"ServerMap: Successfully loaded map "
<<"metadata from "<<savedir
<<", assuming valid save directory."
<<" seed="<< m_emerge->params.seed <<"."
<<std::endl;
if (settings_mgr.loadMapMeta()) {
infostream << "ServerMap: Metadata loaded from "
<< savedir << std::endl;
} else {
infostream << "ServerMap: Metadata could not be loaded "
"from " << savedir << ", assuming valid save "
"directory." << std::endl;
}

m_map_saving_enabled = true;
// Map loaded, not creating new one
@@ -2259,19 +2252,26 @@ ServerMap::~ServerMap()
#endif
}

MapgenParams *ServerMap::getMapgenParams()
{
// getMapgenParams() should only ever be called after Server is initialized
assert(settings_mgr.mapgen_params != NULL);
return settings_mgr.mapgen_params;
}

u64 ServerMap::getSeed()
{
return m_emerge->params.seed;
return getMapgenParams()->seed;
}

s16 ServerMap::getWaterLevel()
{
return m_emerge->params.water_level;
return getMapgenParams()->water_level;
}

bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
{
s16 csize = m_emerge->params.chunksize;
s16 csize = getMapgenParams()->chunksize;
v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);

@@ -2287,7 +2287,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
blockpos_over_limit(full_bpmax))
return false;

data->seed = m_emerge->params.seed;
data->seed = getSeed();
data->blockpos_min = bpmin;
data->blockpos_max = bpmax;
data->blockpos_requested = blockpos;
@@ -2905,8 +2905,9 @@ void ServerMap::save(ModifiedState save_level)
infostream<<"ServerMap: Saving whole map, this can take time."
<<std::endl;

if(m_map_metadata_changed || save_level == MOD_STATE_CLEAN) {
saveMapMeta();
if (m_map_metadata_changed || save_level == MOD_STATE_CLEAN) {
if (settings_mgr.saveMapMeta())
m_map_metadata_changed = false;
}

// Profile modified reasons
@@ -3005,55 +3006,6 @@ void ServerMap::listAllLoadedBlocks(std::vector<v3s16> &dst)
}
}

void ServerMap::saveMapMeta()
{
DSTACK(FUNCTION_NAME);

createDirs(m_savedir);

std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
std::ostringstream oss(std::ios_base::binary);
Settings conf;

m_emerge->params.save(conf);
conf.writeLines(oss);

oss << "[end_of_params]\n";

if(!fs::safeWriteToFile(fullpath, oss.str())) {
errorstream << "ServerMap::saveMapMeta(): "
<< "could not write " << fullpath << std::endl;
throw FileNotGoodException("Cannot save chunk metadata");
}

m_map_metadata_changed = false;
}

void ServerMap::loadMapMeta()
{
DSTACK(FUNCTION_NAME);

Settings conf;
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";

std::ifstream is(fullpath.c_str(), std::ios_base::binary);
if (!is.good()) {
errorstream << "ServerMap::loadMapMeta(): "
"could not open " << fullpath << std::endl;
throw FileNotGoodException("Cannot open map metadata");
}

if (!conf.parseConfigLines(is, "[end_of_params]")) {
throw SerializationError("ServerMap::loadMapMeta(): "
"[end_of_params] not found!");
}

m_emerge->params.load(conf);

verbosestream << "ServerMap::loadMapMeta(): seed="
<< m_emerge->params.seed << std::endl;
}

void ServerMap::saveSectorMeta(ServerMapSector *sector)
{
DSTACK(FUNCTION_NAME);
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "modifiedstate.h"
#include "util/container.h"
#include "nodetimer.h"
#include "map_settings_manager.h"

class Settings;
class Database;
@@ -46,8 +47,6 @@ class IRollbackManager;
class EmergeManager;
class ServerEnvironment;
struct BlockMakeData;
struct MapgenParams;


/*
MapEditEvent
@@ -463,9 +462,8 @@ class ServerMap : public Map
void save(ModifiedState save_level);
void listAllLoadableBlocks(std::vector<v3s16> &dst);
void listAllLoadedBlocks(std::vector<v3s16> &dst);
// Saves map seed and possibly other stuff
void saveMapMeta();
void loadMapMeta();

MapgenParams *getMapgenParams();

/*void saveChunkMeta();
void loadChunkMeta();*/
@@ -506,6 +504,8 @@ class ServerMap : public Map
u64 getSeed();
s16 getWaterLevel();

MapSettingsManager settings_mgr;

private:
// Emerge manager
EmergeManager *m_emerge;

0 comments on commit 3c63c30

Please sign in to comment.