From d274cbfce6ed39f5b7ad41261ede8c0fad7e980a Mon Sep 17 00:00:00 2001 From: kwolekr Date: Wed, 8 Oct 2014 15:28:14 -0400 Subject: Add NodeResolver and clean up node name -> content ID resolution system --- src/script/lua_api/l_mapgen.cpp | 194 ++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 98 deletions(-) (limited to 'src/script/lua_api/l_mapgen.cpp') diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index d31e84b3d..b75488815 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -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 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", - ""); - 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", ""); 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 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 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 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 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 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 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 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); -- cgit v1.2.3