mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add NodeResolver and clean up node name -> content ID resolution system
This commit is contained in:
parent
b49e5cfc70
commit
d274cbfce6
11 changed files with 445 additions and 342 deletions
|
@ -80,26 +80,28 @@ struct EnumString ModApiMapgen::es_Rotation[] =
|
|||
};
|
||||
|
||||
|
||||
static void read_schematic_replacements(lua_State *L, DecoSchematic *dschem, int index)
|
||||
static void read_schematic_replacements(lua_State *L,
|
||||
std::map<std::string, std::string> replace_names, int index)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, index)) {
|
||||
// key at index -2 and value at index -1
|
||||
std::string replace_from;
|
||||
std::string replace_to;
|
||||
if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format
|
||||
|
||||
if (lua_istable(L, -1)) { // Old {{"x", "y"}, ...} format
|
||||
lua_rawgeti(L, -1, 1);
|
||||
replace_from = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 2);
|
||||
replace_to = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
} else { // New {x = "y", ...} format
|
||||
} else { // New {x = "y", ...} format
|
||||
replace_from = lua_tostring(L, -2);
|
||||
replace_to = lua_tostring(L, -1);
|
||||
}
|
||||
dschem->replacements[replace_from] = replace_to;
|
||||
// removes value, keeps key for next iteration
|
||||
|
||||
replace_names[replace_from] = replace_to;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +300,8 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
|
||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||
BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
|
||||
if (!bmgr) {
|
||||
verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
|
||||
return 0;
|
||||
|
@ -308,32 +311,25 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||
"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
|
||||
Biome *b = bmgr->createBiome(terrain);
|
||||
|
||||
b->name = getstringfield_default(L, index, "name",
|
||||
"<no name>");
|
||||
b->nname_top = getstringfield_default(L, index, "node_top",
|
||||
"mapgen_dirt_with_grass");
|
||||
b->nname_filler = getstringfield_default(L, index, "node_filler",
|
||||
"mapgen_dirt");
|
||||
b->nname_water = getstringfield_default(L, index, "node_water",
|
||||
"mapgen_water_source");
|
||||
b->nname_dust = getstringfield_default(L, index, "node_dust",
|
||||
"air");
|
||||
b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
|
||||
"mapgen_water_source");
|
||||
resolver->addNode(getstringfield_default(L, index, "node_top", ""),
|
||||
"mapgen_dirt_with_grass", CONTENT_AIR, &b->c_top);
|
||||
resolver->addNode(getstringfield_default(L, index, "node_filler", ""),
|
||||
"mapgen_dirt", CONTENT_AIR, &b->c_filler);
|
||||
resolver->addNode(getstringfield_default(L, index, "node_water", ""),
|
||||
"mapgen_water_source", CONTENT_AIR, &b->c_water);
|
||||
resolver->addNode(getstringfield_default(L, index, "node_dust", ""),
|
||||
"air", CONTENT_IGNORE, &b->c_dust);
|
||||
resolver->addNode(getstringfield_default(L, index, "node_dust_water", ""),
|
||||
"mapgen_water_source", CONTENT_IGNORE, &b->c_dust_water);
|
||||
|
||||
b->name = getstringfield_default(L, index, "name", "<no name>");
|
||||
b->depth_top = getintfield_default(L, index, "depth_top", 1);
|
||||
b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
|
||||
b->height_min = getintfield_default(L, index, "height_min", 0);
|
||||
b->height_max = getintfield_default(L, index, "height_max", 0);
|
||||
b->heat_point = getfloatfield_default(L, index, "heat_point", 0.);
|
||||
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
|
||||
|
||||
b->flags = 0; //reserved
|
||||
b->c_top = CONTENT_IGNORE;
|
||||
b->c_filler = CONTENT_IGNORE;
|
||||
b->c_water = CONTENT_IGNORE;
|
||||
b->c_dust = CONTENT_IGNORE;
|
||||
b->c_dust_water = CONTENT_IGNORE;
|
||||
b->flags = 0; //reserved
|
||||
|
||||
verbosestream << "register_biome: " << b->name << std::endl;
|
||||
bmgr->addBiome(b);
|
||||
|
@ -349,6 +345,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
BiomeDefManager *bdef = emerge->biomedef;
|
||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||
|
||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||
"deco_type", es_DecorationType, 0);
|
||||
|
@ -364,11 +361,9 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
<< decotype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
deco->c_place_on = CONTENT_IGNORE;
|
||||
deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
|
||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
|
||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
if (deco->sidelen <= 0) {
|
||||
errorstream << "register_decoration: sidelen must be "
|
||||
"greater than 0" << std::endl;
|
||||
|
@ -376,51 +371,35 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//// Get node name(s) to place decoration on
|
||||
std::vector<const char *> place_on_names;
|
||||
getstringlistfield(L, index, "place_on", place_on_names);
|
||||
for (size_t i = 0; i != place_on_names.size(); i++)
|
||||
resolver->addNodeList(place_on_names[i], &deco->c_place_on);
|
||||
|
||||
//// Get NoiseParams to define how decoration is placed
|
||||
lua_getfield(L, index, "noise_params");
|
||||
deco->np = read_noiseparams(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "biomes");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
u8 biomeid = bdef->getBiomeIdByName(s);
|
||||
if (biomeid)
|
||||
deco->biomes.insert(biomeid);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
//// Get biomes associated with this decoration (if any)
|
||||
std::vector<const char *> biome_list;
|
||||
getstringlistfield(L, index, "biomes", biome_list);
|
||||
for (size_t i = 0; i != biome_list.size(); i++) {
|
||||
u8 biomeid = bdef->getBiomeIdByName(biome_list[i]);
|
||||
if (biomeid)
|
||||
deco->biomes.insert(biomeid);
|
||||
}
|
||||
|
||||
//// Handle decoration type-specific parameters
|
||||
switch (decotype) {
|
||||
case DECO_SIMPLE: {
|
||||
DecoSimple *dsimple = (DecoSimple *)deco;
|
||||
dsimple->c_deco = CONTENT_IGNORE;
|
||||
dsimple->c_spawnby = CONTENT_IGNORE;
|
||||
dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air");
|
||||
|
||||
dsimple->deco_height = getintfield_default(L, index, "height", 1);
|
||||
dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
||||
dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||
|
||||
lua_getfield(L, index, "decoration");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
const char *s = lua_tostring(L, -1);
|
||||
std::string str(s);
|
||||
dsimple->decolist_names.push_back(str);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
dsimple->deco_name = std::string(lua_tostring(L, -1));
|
||||
} else {
|
||||
dsimple->deco_name = std::string("air");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (dsimple->deco_height <= 0) {
|
||||
errorstream << "register_decoration: simple decoration height"
|
||||
" must be greater than 0" << std::endl;
|
||||
|
@ -428,7 +407,31 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
break; }
|
||||
std::vector<const char *> deco_names;
|
||||
getstringlistfield(L, index, "decoration", deco_names);
|
||||
if (deco_names.size() == 0) {
|
||||
errorstream << "register_decoration: no decoration nodes "
|
||||
"defined" << std::endl;
|
||||
delete dsimple;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<const char *> spawnby_names;
|
||||
getstringlistfield(L, index, "spawn_by", spawnby_names);
|
||||
if (dsimple->nspawnby != -1 && spawnby_names.size() == 0) {
|
||||
errorstream << "register_decoration: no spawn_by nodes defined,"
|
||||
" but num_spawn_by specified" << std::endl;
|
||||
delete dsimple;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i != deco_names.size(); i++)
|
||||
resolver->addNodeList(deco_names[i], &dsimple->c_decos);
|
||||
for (size_t i = 0; i != spawnby_names.size(); i++)
|
||||
resolver->addNodeList(spawnby_names[i], &dsimple->c_spawnby);
|
||||
|
||||
break;
|
||||
}
|
||||
case DECO_SCHEMATIC: {
|
||||
DecoSchematic *dschem = (DecoSchematic *)deco;
|
||||
|
||||
|
@ -439,10 +442,10 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
dschem->rotation = (Rotation)getenumfield(L, index,
|
||||
"rotation", es_Rotation, ROTATE_0);
|
||||
|
||||
std::map<std::string, std::string> replace_names;
|
||||
lua_getfield(L, index, "replacements");
|
||||
if (lua_istable(L, -1)) {
|
||||
read_schematic_replacements(L, dschem, lua_gettop(L));
|
||||
}
|
||||
if (lua_istable(L, -1))
|
||||
read_schematic_replacements(L, replace_names, lua_gettop(L));
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "schematic");
|
||||
|
@ -452,17 +455,20 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
}
|
||||
lua_pop(L, -1);
|
||||
|
||||
if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
|
||||
errorstream << "register_decoration: failed to load schematic file '"
|
||||
<< dschem->filename << "'" << std::endl;
|
||||
if (!dschem->filename.empty() &&
|
||||
!dschem->loadSchematicFile(resolver, replace_names)) {
|
||||
errorstream << "register_decoration: failed to load schematic"
|
||||
" file '" << dschem->filename << "'" << std::endl;
|
||||
delete dschem;
|
||||
return 0;
|
||||
}
|
||||
break; }
|
||||
|
||||
break;
|
||||
}
|
||||
case DECO_LSYSTEM: {
|
||||
//DecoLSystem *decolsystem = (DecoLSystem *)deco;
|
||||
|
||||
break; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emerge->decorations.push_back(deco);
|
||||
|
@ -478,7 +484,8 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||
int index = 1;
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||
|
||||
enum OreType oretype = (OreType)getenumfield(L, index,
|
||||
"ore_type", es_OreType, ORE_SCATTER);
|
||||
|
@ -489,7 +496,9 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ore->ore_name = getstringfield_default(L, index, "ore", "");
|
||||
resolver->addNode(getstringfield_default(L, index, "ore", ""),
|
||||
"", CONTENT_AIR, &ore->c_ore);
|
||||
|
||||
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
|
||||
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
|
||||
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
|
||||
|
@ -500,20 +509,10 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||
ore->flags = 0;
|
||||
getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);
|
||||
|
||||
lua_getfield(L, index, "wherein");
|
||||
if (lua_istable(L, -1)) {
|
||||
int i = lua_gettop(L);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, i) != 0) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
} else if (lua_isstring(L, -1)) {
|
||||
ore->wherein_names.push_back(lua_tostring(L, -1));
|
||||
} else {
|
||||
ore->wherein_names.push_back("");
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
std::vector<const char *> wherein_names;
|
||||
getstringlistfield(L, index, "wherein", wherein_names);
|
||||
for (size_t i = 0; i != wherein_names.size(); i++)
|
||||
resolver->addNodeList(wherein_names[i], &ore->c_wherein);
|
||||
|
||||
lua_getfield(L, index, "noise_params");
|
||||
ore->np = read_noiseparams(L, -1);
|
||||
|
@ -530,8 +529,8 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||
|
||||
emerge->ores.push_back(ore);
|
||||
|
||||
verbosestream << "register_ore: ore '" << ore->ore_name
|
||||
<< "' registered" << std::endl;
|
||||
//verbosestream << "register_ore: ore '" << ore->ore_name
|
||||
// << "' registered" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -603,7 +602,7 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
|
|||
DecoSchematic dschem;
|
||||
|
||||
Map *map = &(getEnv(L)->getMap());
|
||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||
|
||||
v3s16 p = read_v3s16(L, 1);
|
||||
if (!read_schematic(L, 2, &dschem, getServer(L)))
|
||||
|
@ -615,21 +614,20 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
|
|||
|
||||
dschem.rotation = (Rotation)rot;
|
||||
|
||||
if (lua_istable(L, 4)) {
|
||||
read_schematic_replacements(L, &dschem, 4);
|
||||
}
|
||||
std::map<std::string, std::string> replace_names;
|
||||
if (lua_istable(L, 4))
|
||||
read_schematic_replacements(L, replace_names, 4);
|
||||
|
||||
bool force_placement = true;
|
||||
if (lua_isboolean(L, 5))
|
||||
force_placement = lua_toboolean(L, 5);
|
||||
|
||||
if (!dschem.filename.empty()) {
|
||||
if (!dschem.loadSchematicFile()) {
|
||||
if (!dschem.loadSchematicFile(resolver, replace_names)) {
|
||||
errorstream << "place_schematic: failed to load schematic file '"
|
||||
<< dschem.filename << "'" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
dschem.resolveNodeNames(ndef);
|
||||
}
|
||||
|
||||
dschem.placeStructure(map, p, force_placement);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue