Skip to content

Commit

Permalink
Biomes: Add 'get heat', 'get humidity', 'get biome data' APIs
Browse files Browse the repository at this point in the history
'get biome data' returns biome id, heat and humidity.
Clean up nearby lines in lua_api.txt.
  • Loading branch information
paramat committed Jan 16, 2018
1 parent 4c0d4e4 commit d45e5da
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 39 deletions.
107 changes: 71 additions & 36 deletions doc/lua_api.txt
Expand Up @@ -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
Expand Down
60 changes: 59 additions & 1 deletion src/mapgen/mg_biome.cpp
Expand Up @@ -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)
{
Expand Down
7 changes: 7 additions & 0 deletions src/mapgen/mg_biome.h
Expand Up @@ -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;

Expand Down
153 changes: 152 additions & 1 deletion src/script/lua_api/l_mapgen.cpp
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit d45e5da

Please sign in to comment.