Biomes: Add 'get heat', 'get humidity', 'get biome data' APIs

'get biome data' returns biome id, heat and humidity.
Clean up nearby lines in lua_api.txt.
This commit is contained in:
paramat 2017-09-22 12:38:55 +01:00 committed by paramat
parent 4c0d4e4105
commit d45e5da8ca
5 changed files with 302 additions and 39 deletions

@ -2816,58 +2816,93 @@ and `minetest.auth_reload` call the authentication handler.
* Return voxel manipulator object. * Return voxel manipulator object.
* Loads the manipulator from the map if positions are passed. * Loads the manipulator from the map if positions are passed.
* `minetest.set_gen_notify(flags, {deco_ids})` * `minetest.set_gen_notify(flags, {deco_ids})`
* Set the types of on-generate notifications that should be collected * Set the types of on-generate notifications that should be collected.
* `flags` is a flag field with the available flags: `dungeon`, `temple`, `cave_begin`, * `flags` is a flag field with the available flags:
`cave_end`, `large_cave_begin`, `large_cave_end`, `decoration` * dungeon
* The second parameter is a list of IDS of decorations which notification is requested for * temple
* `get_gen_notify()`: returns a flagstring and a table with the `deco_id`s * cave_begin
* cave_end
* large_cave_begin
* large_cave_end
* decoration
* The second parameter is a list of IDS of decorations which notification
is requested for.
* `get_gen_notify()`
* Returns a flagstring and a table with the `deco_id`s.
* `minetest.get_mapgen_object(objectname)` * `minetest.get_mapgen_object(objectname)`
* Return requested mapgen object if available (see "Mapgen objects") * Return requested mapgen object if available (see "Mapgen objects")
* `minetest.get_heat(pos)`
* Returns the heat at the position, or `nil` on failure.
* `minetest.get_humidity(pos)`
* Returns the humidity at the position, or `nil` on failure.
* `minetest.get_biome_data(pos)`
* Returns a table containing:
* `biome` the biome id of the biome at that position
* `heat` the heat at the position
* `humidity` the humidity at the position
* Or returns `nil` on failure.
* `minetest.get_biome_id(biome_name)` * `minetest.get_biome_id(biome_name)`
* Returns the biome id, as used in the biomemap Mapgen object, for a * Returns the biome id, as used in the biomemap Mapgen object and returned
given biome_name string. by `minetest.get_biome_data(pos)`, for a given biome_name string.
* `minetest.get_mapgen_params()` Returns mapgen parameters, a table containing * `minetest.get_mapgen_params()`
`mgname`, `seed`, `chunksize`, `water_level`, and `flags`. * Deprecated: use `minetest.get_mapgen_setting(name)` instead.
* Deprecated: use `minetest.get_mapgen_setting(name)` instead * Returns a table containing:
* `mgname`
* `seed`
* `chunksize`
* `water_level`
* `flags`
* `minetest.set_mapgen_params(MapgenParams)` * `minetest.set_mapgen_params(MapgenParams)`
* Deprecated: use `minetest.set_mapgen_setting(name, value, override)` instead * Deprecated: use `minetest.set_mapgen_setting(name, value, override)`
* Set map generation parameters instead.
* Function cannot be called after the registration period; only initialization * Set map generation parameters.
and `on_mapgen_init` * Function cannot be called after the registration period; only
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`, initialization and `on_mapgen_init`.
and `flags`. * Takes a table as an argument with the fields:
* Leave field unset to leave that parameter unchanged * `mgname`
* `flags` contains a comma-delimited string of flags to set, * `seed`
or if the prefix `"no"` is attached, clears instead. * `chunksize`
* `flags` is in the same format and has the same options as `mg_flags` in `minetest.conf` * `water_level`
* `flags`
* Leave field unset to leave that parameter unchanged.
* `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)` * `minetest.get_mapgen_setting(name)`
* Gets the *active* mapgen setting (or nil if none exists) in string format with the following * Gets the *active* mapgen setting (or nil if none exists) in string
order of precedence: format with the following order of precedence:
1) Settings loaded from map_meta.txt or overrides set during mod execution 1) Settings loaded from map_meta.txt or overrides set during mod execution
2) Settings set by mods without a metafile override 2) Settings set by mods without a metafile override
3) Settings explicitly set in the user config file, minetest.conf 3) Settings explicitly set in the user config file, minetest.conf
4) Settings set as the user config default 4) Settings set as the user config default
* `minetest.get_mapgen_setting_noiseparams(name)` * `minetest.get_mapgen_setting_noiseparams(name)`
* Same as above, but returns the value as a NoiseParams table if the setting `name` exists * Same as above, but returns the value as a NoiseParams table if the
and is a valid NoiseParams setting `name` exists and is a valid NoiseParams.
* `minetest.set_mapgen_setting(name, value, [override_meta])` * `minetest.set_mapgen_setting(name, value, [override_meta])`
* Sets a mapgen param to `value`, and will take effect if the corresponding mapgen setting * Sets a mapgen param to `value`, and will take effect if the corresponding
is not already present in map_meta.txt. mapgen setting is not already present in map_meta.txt.
* `override_meta` is an optional boolean (default: `false`). If this is set to true, * `override_meta` is an optional boolean (default: `false`). If this is set
the setting will become the active setting regardless of the map metafile contents. to true, the setting will become the active setting regardless of the map
* Note: to set the seed, use `"seed"`, not `"fixed_map_seed"` metafile contents.
* Note: to set the seed, use `"seed"`, not `"fixed_map_seed"`.
* `minetest.set_mapgen_setting_noiseparams(name, value, [override_meta])` * `minetest.set_mapgen_setting_noiseparams(name, value, [override_meta])`
* Same as above, except value is a NoiseParams table. * Same as above, except value is a NoiseParams table.
* `minetest.set_noiseparams(name, noiseparams, set_default)` * `minetest.set_noiseparams(name, noiseparams, set_default)`
* Sets the noiseparams setting of `name` to the noiseparams table specified in `noiseparams`. * Sets the noiseparams setting of `name` to the noiseparams table specified
* `set_default` is an optional boolean (default: `true`) that specifies whether the setting in `noiseparams`.
should be applied to the default config or current active config * `set_default` is an optional boolean (default: `true`) that specifies
* `minetest.get_noiseparams(name)`: returns a table of the noiseparams for name whether the setting should be applied to the default config or current
active config.
* `minetest.get_noiseparams(name)`
* Returns a table of the noiseparams for name.
* `minetest.generate_ores(vm, pos1, pos2)` * `minetest.generate_ores(vm, pos1, pos2)`
* Generate all registered ores within the VoxelManip `vm` and in the area from `pos1` to `pos2`. * Generate all registered ores within the VoxelManip `vm` and in the area
from `pos1` to `pos2`.
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp. * `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
* `minetest.generate_decorations(vm, pos1, pos2)` * `minetest.generate_decorations(vm, pos1, pos2)`
* Generate all registered decorations within the VoxelManip `vm` and in the area from `pos1` to `pos2`. * Generate all registered decorations within the VoxelManip `vm` and in the
area from `pos1` to `pos2`.
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp. * `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
* `minetest.clear_objects([options])` * `minetest.clear_objects([options])`
* Clear all objects in the environment * Clear all objects in the environment

@ -84,8 +84,66 @@ void BiomeManager::clear()
m_objects.resize(1); m_objects.resize(1);
} }
////////////////////////////////////////////////////////////////////////////////
// For BiomeGen type 'BiomeGenOriginal'
float BiomeManager::getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat,
NoiseParams &np_heat_blend, u64 seed)
{
return
NoisePerlin2D(&np_heat, pos.X, pos.Z, seed) +
NoisePerlin2D(&np_heat_blend, pos.X, pos.Z, seed);
}
// For BiomeGen type 'BiomeGenOriginal'
float BiomeManager::getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity,
NoiseParams &np_humidity_blend, u64 seed)
{
return
NoisePerlin2D(&np_humidity, pos.X, pos.Z, seed) +
NoisePerlin2D(&np_humidity_blend, pos.X, pos.Z, seed);
}
// For BiomeGen type 'BiomeGenOriginal'
Biome *BiomeManager::getBiomeFromNoiseOriginal(float heat, float humidity, s16 y)
{
Biome *biome_closest = nullptr;
Biome *biome_closest_blend = nullptr;
float dist_min = FLT_MAX;
float dist_min_blend = FLT_MAX;
for (size_t i = 1; i < getNumObjects(); i++) {
Biome *b = (Biome *)getRaw(i);
if (!b || y > b->y_max + b->vertical_blend || y < b->y_min)
continue;
float d_heat = heat - b->heat_point;
float d_humidity = humidity - b->humidity_point;
float dist = (d_heat * d_heat) + (d_humidity * d_humidity);
if (y <= b->y_max) { // Within y limits of biome b
if (dist < dist_min) {
dist_min = dist;
biome_closest = b;
}
} else if (dist < dist_min_blend) { // Blend area above biome b
dist_min_blend = dist;
biome_closest_blend = b;
}
}
mysrand(y + (heat - humidity) * 2);
if (biome_closest_blend &&
myrand_range(0, biome_closest_blend->vertical_blend) >=
y - biome_closest_blend->y_max)
return biome_closest_blend;
return (biome_closest) ? biome_closest : (Biome *)getRaw(BIOME_NONE);
}
////////////////////////////////////////////////////////////////////////////////
void BiomeParamsOriginal::readParams(const Settings *settings) void BiomeParamsOriginal::readParams(const Settings *settings)
{ {

@ -225,6 +225,13 @@ public:
virtual void clear(); virtual void clear();
// For BiomeGen type 'BiomeGenOriginal'
float getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat,
NoiseParams &np_heat_blend, u64 seed);
float getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity,
NoiseParams &np_humidity_blend, u64 seed);
Biome *getBiomeFromNoiseOriginal(float heat, float humidity, s16 y);
private: private:
Server *m_server; Server *m_server;

@ -463,7 +463,7 @@ size_t get_biome_list(lua_State *L, int index,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// get_biome_id(biomename) // get_biome_id(biomename)
// returns the biome id used in biomemap // returns the biome id as used in biomemap and returned by 'get_biome_data()'
int ModApiMapgen::l_get_biome_id(lua_State *L) int ModApiMapgen::l_get_biome_id(lua_State *L)
{ {
NO_MAP_LOCK_REQUIRED; NO_MAP_LOCK_REQUIRED;
@ -488,6 +488,154 @@ int ModApiMapgen::l_get_biome_id(lua_State *L)
} }
// get_heat(pos)
// returns the heat at the position
int ModApiMapgen::l_get_heat(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
v3s16 pos = read_v3s16(L, 1);
NoiseParams np_heat;
NoiseParams np_heat_blend;
MapSettingsManager *settingsmgr =
getServer(L)->getEmergeManager()->map_settings_mgr;
if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat",
&np_heat) ||
!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat_blend",
&np_heat_blend))
return 0;
std::string value;
if (!settingsmgr->getMapSetting("seed", &value))
return 0;
std::istringstream ss(value);
u64 seed;
ss >> seed;
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
if (!bmgr)
return 0;
float heat = bmgr->getHeatAtPosOriginal(pos, np_heat, np_heat_blend, seed);
if (!heat)
return 0;
lua_pushnumber(L, heat);
return 1;
}
// get_humidity(pos)
// returns the humidity at the position
int ModApiMapgen::l_get_humidity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
v3s16 pos = read_v3s16(L, 1);
NoiseParams np_humidity;
NoiseParams np_humidity_blend;
MapSettingsManager *settingsmgr =
getServer(L)->getEmergeManager()->map_settings_mgr;
if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity",
&np_humidity) ||
!settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity_blend",
&np_humidity_blend))
return 0;
std::string value;
if (!settingsmgr->getMapSetting("seed", &value))
return 0;
std::istringstream ss(value);
u64 seed;
ss >> seed;
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
if (!bmgr)
return 0;
float humidity = bmgr->getHumidityAtPosOriginal(pos, np_humidity,
np_humidity_blend, seed);
if (!humidity)
return 0;
lua_pushnumber(L, humidity);
return 1;
}
// get_biome_data(pos)
// returns a table containing the biome id, heat and humidity at the position
int ModApiMapgen::l_get_biome_data(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
v3s16 pos = read_v3s16(L, 1);
NoiseParams np_heat;
NoiseParams np_heat_blend;
NoiseParams np_humidity;
NoiseParams np_humidity_blend;
MapSettingsManager *settingsmgr =
getServer(L)->getEmergeManager()->map_settings_mgr;
if (!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat",
&np_heat) ||
!settingsmgr->getMapSettingNoiseParams("mg_biome_np_heat_blend",
&np_heat_blend) ||
!settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity",
&np_humidity) ||
!settingsmgr->getMapSettingNoiseParams("mg_biome_np_humidity_blend",
&np_humidity_blend))
return 0;
std::string value;
if (!settingsmgr->getMapSetting("seed", &value))
return 0;
std::istringstream ss(value);
u64 seed;
ss >> seed;
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
if (!bmgr)
return 0;
float heat = bmgr->getHeatAtPosOriginal(pos, np_heat, np_heat_blend, seed);
if (!heat)
return 0;
float humidity = bmgr->getHumidityAtPosOriginal(pos, np_humidity,
np_humidity_blend, seed);
if (!humidity)
return 0;
Biome *biome = (Biome *)bmgr->getBiomeFromNoiseOriginal(heat, humidity, pos.Y);
if (!biome || biome->index == OBJDEF_INVALID_INDEX)
return 0;
lua_newtable(L);
lua_pushinteger(L, biome->index);
lua_setfield(L, -2, "biome");
lua_pushnumber(L, heat);
lua_setfield(L, -2, "heat");
lua_pushnumber(L, humidity);
lua_setfield(L, -2, "humidity");
return 1;
}
// get_mapgen_object(objectname) // get_mapgen_object(objectname)
// returns the requested object used during map generation // returns the requested object used during map generation
int ModApiMapgen::l_get_mapgen_object(lua_State *L) int ModApiMapgen::l_get_mapgen_object(lua_State *L)
@ -1520,6 +1668,9 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L)
void ModApiMapgen::Initialize(lua_State *L, int top) void ModApiMapgen::Initialize(lua_State *L, int top)
{ {
API_FCT(get_biome_id); API_FCT(get_biome_id);
API_FCT(get_heat);
API_FCT(get_humidity);
API_FCT(get_biome_data);
API_FCT(get_mapgen_object); API_FCT(get_mapgen_object);
API_FCT(get_mapgen_params); API_FCT(get_mapgen_params);

@ -25,9 +25,21 @@ class ModApiMapgen : public ModApiBase
{ {
private: private:
// get_biome_id(biomename) // get_biome_id(biomename)
// returns the biome id used in biomemap // returns the biome id as used in biomemap and returned by 'get_biome_data()'
static int l_get_biome_id(lua_State *L); static int l_get_biome_id(lua_State *L);
// get_heat(pos)
// returns the heat at the position
static int l_get_heat(lua_State *L);
// get_humidity(pos)
// returns the humidity at the position
static int l_get_humidity(lua_State *L);
// get_biome_data(pos)
// returns a table containing the biome id, heat and humidity at the position
static int l_get_biome_data(lua_State *L);
// get_mapgen_object(objectname) // get_mapgen_object(objectname)
// returns the requested object used during map generation // returns the requested object used during map generation
static int l_get_mapgen_object(lua_State *L); static int l_get_mapgen_object(lua_State *L);