Permalink
Browse files

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.
  • Loading branch information...
paramat committed Sep 22, 2017
1 parent 4c0d4e4 commit d45e5da8ca808e552123bcd94e76b0b435a6ea79
Showing with 302 additions and 39 deletions.
  1. +71 −36 doc/lua_api.txt
  2. +59 −1 src/mapgen/mg_biome.cpp
  3. +7 −0 src/mapgen/mg_biome.h
  4. +152 −1 src/script/lua_api/l_mapgen.cpp
  5. +13 −1 src/script/lua_api/l_mapgen.h
@@ -2816,58 +2816,93 @@ and `minetest.auth_reload` call the authentication handler.
* Return voxel manipulator object.
* Loads the manipulator from the map if positions are passed.
* `minetest.set_gen_notify(flags, {deco_ids})`
* Set the types of on-generate notifications that should be collected
* `flags` is a flag field with the available flags: `dungeon`, `temple`, `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
* Set the types of on-generate notifications that should be collected.
* `flags` is a flag field with the available flags:
* dungeon
* temple
* 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)`
* 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)`
* Returns the biome id, as used in the biomemap Mapgen object, for a
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
* Returns the biome id, as used in the biomemap Mapgen object and returned
by `minetest.get_biome_data(pos)`, for a given biome_name string.
* `minetest.get_mapgen_params()`
* Deprecated: use `minetest.get_mapgen_setting(name)` instead.
* Returns a table containing:
* `mgname`
* `seed`
* `chunksize`
* `water_level`
* `flags`
* `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`
* Takes a table as an argument with the fields `mgname`, `seed`, `water_level`,
and `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`
* 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`.
* Takes a table as an argument with the fields:
* `mgname`
* `seed`
* `chunksize`
* `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)`
* Gets the *active* mapgen setting (or nil if none exists) in string format with the following
order of precedence:
* 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
* 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])`
* Sets a mapgen param to `value`, and will take effect if the corresponding mapgen setting
is not already present in map_meta.txt.
* `override_meta` is an optional boolean (default: `false`). If this is set to true,
the setting will become the active setting regardless of the map metafile contents.
* Note: to set the seed, use `"seed"`, not `"fixed_map_seed"`
* Sets a mapgen param to `value`, and will take effect if the corresponding
mapgen setting is not already present in map_meta.txt.
* `override_meta` is an optional boolean (default: `false`). If this is set
to true, the 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])`
* 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)`
* 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
should be applied to the default config or current active config
* `minetest.get_noiseparams(name)`: returns a table of the noiseparams for name
* 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 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)`
* 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.
* `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.
* `minetest.clear_objects([options])`
* Clear all objects in the environment
@@ -84,8 +84,66 @@ void BiomeManager::clear()
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)
{
@@ -225,6 +225,13 @@ class BiomeManager : public ObjDefManager {

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:
Server *m_server;

@@ -463,7 +463,7 @@ size_t get_biome_list(lua_State *L, int index,
///////////////////////////////////////////////////////////////////////////////

// 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)
{
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)
// returns the requested object used during map generation
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)
{
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_params);
Oops, something went wrong.

0 comments on commit d45e5da

Please sign in to comment.