From 732d7b9a7c2a89bc21abb40b333f974a4b2474c4 Mon Sep 17 00:00:00 2001 From: kwolekr Date: Mon, 23 Mar 2015 22:10:59 -0400 Subject: [PATCH] Add core.register_schematic() and cache schematics on use --- src/mapgen.h | 2 + src/script/lua_api/l_mapgen.cpp | 226 +++++++++++++++++++------------- src/script/lua_api/l_mapgen.h | 9 +- 3 files changed, 146 insertions(+), 91 deletions(-) diff --git a/src/mapgen.h b/src/mapgen.h index 8cac58599..5b5ed19a2 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -204,6 +204,8 @@ public: virtual GenElement *getByName(const std::string &name); + INodeDefManager *getNodeDef() { return m_ndef; } + protected: INodeDefManager *m_ndef; std::vector m_elements; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index a76e8625c..8806581de 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -89,7 +89,7 @@ struct EnumString ModApiMapgen::es_Rotation[] = /////////////////////////////////////////////////////////////////////////////// -bool read_schematic(lua_State *L, int index, Schematic *schem, +bool read_schematic_def(lua_State *L, int index, Schematic *schem, INodeDefManager *ndef, std::map &replace_names) { //// Get schematic size @@ -175,20 +175,45 @@ bool read_schematic(lua_State *L, int index, Schematic *schem, } -bool get_schematic(lua_State *L, int index, Schematic *schem, - INodeDefManager *ndef, std::map &replace_names) +Schematic *get_schematic(lua_State *L, int index, SchematicManager *schemmgr, + std::map &replace_names) { if (index < 0) index = lua_gettop(L) + 1 + index; - if (lua_istable(L, index)) { - return read_schematic(L, index, schem, ndef, replace_names); - } else if (lua_isstring(L, index)) { + Schematic *schem; + + if (lua_isnumber(L, index)) { + return (Schematic *)schemmgr->get(lua_tointeger(L, index)); + } else if (lua_istable(L, index)) { + schem = new Schematic; + if (!read_schematic_def(L, index, schem, + schemmgr->getNodeDef(), replace_names)) { + delete schem; + return NULL; + } + } else if (lua_isstring(L, index)) { const char *filename = lua_tostring(L, index); - return schem->loadSchematicFromFile(filename, ndef, replace_names); + schem = (Schematic *)schemmgr->getByName(filename); + if (schem) + return schem; + + schem = new Schematic; + if (!schem->loadSchematicFromFile(filename, + schemmgr->getNodeDef(), replace_names)) { + delete schem; + return NULL; + } } else { - return false; + return NULL; } + + if (schemmgr->add(schem) == (u32)-1) { + delete schem; + return 0; + } + + return schem; } @@ -469,32 +494,10 @@ int ModApiMapgen::l_register_biome(lua_State *L) ndef->pendNodeResolve(nri); verbosestream << "register_biome: " << b->name << std::endl; - lua_pushinteger(L, id); return 1; } -int ModApiMapgen::l_clear_registered_biomes(lua_State *L) -{ - BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; - bmgr->clear(); - return 0; -} - -int ModApiMapgen::l_clear_registered_decorations(lua_State *L) -{ - DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr; - dmgr->clear(); - return 0; -} - -int ModApiMapgen::l_clear_registered_ores(lua_State *L) -{ - OreManager *omgr = getServer(L)->getEmergeManager()->oremgr; - omgr->clear(); - return 0; -} - // register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { @@ -504,6 +507,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L) INodeDefManager *ndef = getServer(L)->getNodeDefManager(); DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); @@ -562,7 +566,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L) success = regDecoSimple(L, nri, (DecoSimple *)deco); break; case DECO_SCHEMATIC: - success = regDecoSchematic(L, ndef, (DecoSchematic *)deco); + success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco); break; case DECO_LSYSTEM: break; @@ -582,7 +586,6 @@ int ModApiMapgen::l_register_decoration(lua_State *L) } verbosestream << "register_decoration: " << deco->name << std::endl; - lua_pushinteger(L, id); return 1; } @@ -627,8 +630,8 @@ bool ModApiMapgen::regDecoSimple(lua_State *L, return true; } -bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef, - DecoSchematic *deco) +bool ModApiMapgen::regDecoSchematic(lua_State *L, + SchematicManager *schemmgr, DecoSchematic *deco) { int index = 1; @@ -641,19 +644,12 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef, read_schematic_replacements(L, replace_names, lua_gettop(L)); lua_pop(L, 1); - // TODO(hmmmm): get a ref from registered schematics - Schematic *schem = new Schematic; lua_getfield(L, index, "schematic"); - if (!get_schematic(L, -1, schem, ndef, replace_names)) { - lua_pop(L, 1); - delete schem; - return false; - } + Schematic *schem = get_schematic(L, -1, schemmgr, replace_names); lua_pop(L, 1); deco->schematic = schem; - - return true; + return schem != NULL; } // register_ore({lots of stuff}) @@ -741,11 +737,100 @@ int ModApiMapgen::l_register_ore(lua_State *L) ndef->pendNodeResolve(nri); verbosestream << "register_ore: " << ore->name << std::endl; - lua_pushinteger(L, id); return 1; } +// register_schematic({schematic}, replacements={}) +int ModApiMapgen::l_register_schematic(lua_State *L) +{ + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; + + std::map replace_names; + if (lua_istable(L, 2)) + read_schematic_replacements(L, replace_names, 2); + + Schematic *schem = get_schematic(L, 1, schemmgr, replace_names); + if (!schem) + return 0; + printf("register_schematic!\n"); + verbosestream << "register_schematic: " << schem->name << std::endl; + lua_pushinteger(L, schem->id); + return 1; +} + +// clear_registered_biomes() +int ModApiMapgen::l_clear_registered_biomes(lua_State *L) +{ + BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; + bmgr->clear(); + return 0; +} + +// clear_registered_decorations() +int ModApiMapgen::l_clear_registered_decorations(lua_State *L) +{ + DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr; + dmgr->clear(); + return 0; +} + +// clear_registered_ores() +int ModApiMapgen::l_clear_registered_ores(lua_State *L) +{ + OreManager *omgr = getServer(L)->getEmergeManager()->oremgr; + omgr->clear(); + return 0; +} + +// clear_registered_schematics() +int ModApiMapgen::l_clear_registered_schematics(lua_State *L) +{ + SchematicManager *smgr = getServer(L)->getEmergeManager()->schemmgr; + smgr->clear(); + return 0; +} + +// generate_ores(vm, p1, p2, [ore_id]) +int ModApiMapgen::l_generate_ores(lua_State *L) +{ + EmergeManager *emerge = getServer(L)->getEmergeManager(); + + Mapgen mg; + mg.seed = emerge->params.seed; + mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; + mg.ndef = getServer(L)->getNodeDefManager(); + + u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed); + + v3s16 pmin = read_v3s16(L, 2); + v3s16 pmax = read_v3s16(L, 3); + + emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax); + + return 0; +} + +// generate_decorations(vm, p1, p2, [deco_id]) +int ModApiMapgen::l_generate_decorations(lua_State *L) +{ + EmergeManager *emerge = getServer(L)->getEmergeManager(); + + Mapgen mg; + mg.seed = emerge->params.seed; + mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; + mg.ndef = getServer(L)->getNodeDefManager(); + + u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed); + + v3s16 pmin = read_v3s16(L, 2); + v3s16 pmax = read_v3s16(L, 3); + + emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax); + + return 0; +} + // create_schematic(p1, p2, probability_list, filename) int ModApiMapgen::l_create_schematic(lua_State *L) { @@ -806,53 +891,11 @@ int ModApiMapgen::l_create_schematic(lua_State *L) return 1; } -// generate_ores(vm, p1, p2, [ore_id]) -int ModApiMapgen::l_generate_ores(lua_State *L) -{ - EmergeManager *emerge = getServer(L)->getEmergeManager(); - - Mapgen mg; - mg.seed = emerge->params.seed; - mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; - mg.ndef = getServer(L)->getNodeDefManager(); - - u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed); - - v3s16 pmin = read_v3s16(L, 2); - v3s16 pmax = read_v3s16(L, 3); - - emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax); - - return 0; -} - -// generate_decorations(vm, p1, p2, [deco_id]) -int ModApiMapgen::l_generate_decorations(lua_State *L) -{ - EmergeManager *emerge = getServer(L)->getEmergeManager(); - - Mapgen mg; - mg.seed = emerge->params.seed; - mg.vm = LuaVoxelManip::checkobject(L, 1)->vm; - mg.ndef = getServer(L)->getNodeDefManager(); - - u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed); - - v3s16 pmin = read_v3s16(L, 2); - v3s16 pmax = read_v3s16(L, 3); - - emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax); - - return 0; -} - // place_schematic(p, schematic, rotation, replacement) int ModApiMapgen::l_place_schematic(lua_State *L) { - Schematic schem; - Map *map = &(getEnv(L)->getMap()); - INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; //// Read position v3s16 p = read_v3s16(L, 1); @@ -873,12 +916,14 @@ int ModApiMapgen::l_place_schematic(lua_State *L) read_schematic_replacements(L, replace_names, 4); //// Read schematic - if (!get_schematic(L, 2, &schem, ndef, replace_names)) { + Schematic *schem = get_schematic(L, 2, schemmgr, replace_names); + if (!schem) { errorstream << "place_schematic: failed to get schematic" << std::endl; return 0; } - schem.placeStructure(map, p, 0, (Rotation)rot, force_placement, ndef); + schem->placeStructure(map, p, 0, (Rotation)rot, force_placement, + schemmgr->getNodeDef()); return 1; } @@ -895,14 +940,15 @@ void ModApiMapgen::Initialize(lua_State *L, int top) API_FCT(register_biome); API_FCT(register_decoration); API_FCT(register_ore); + API_FCT(register_schematic); API_FCT(clear_registered_biomes); API_FCT(clear_registered_decorations); API_FCT(clear_registered_ores); + API_FCT(clear_registered_schematics); API_FCT(generate_ores); API_FCT(generate_decorations); - API_FCT(create_schematic); API_FCT(place_schematic); } diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h index dfed8475f..2ad436e77 100644 --- a/src/script/lua_api/l_mapgen.h +++ b/src/script/lua_api/l_mapgen.h @@ -26,6 +26,7 @@ class INodeDefManager; struct NodeResolveInfo; class DecoSimple; class DecoSchematic; +class SchematicManager; class ModApiMapgen : public ModApiBase { private: @@ -56,12 +57,18 @@ private: // register_ore({lots of stuff}) static int l_register_ore(lua_State *L); + // register_schematic({schematic}, replacements={}) + static int l_register_schematic(lua_State *L); + // clear_registered_biomes() static int l_clear_registered_biomes(lua_State *L); // clear_registered_decorations() static int l_clear_registered_decorations(lua_State *L); + // clear_registered_schematics() + static int l_clear_registered_schematics(lua_State *L); + // generate_ores(vm, p1, p2) static int l_generate_ores(lua_State *L); @@ -80,7 +87,7 @@ private: static bool regDecoSimple(lua_State *L, NodeResolveInfo *nri, DecoSimple *deco); static bool regDecoSchematic(lua_State *L, - INodeDefManager *ndef, DecoSchematic *deco); + SchematicManager *schemmgr, DecoSchematic *deco); static struct EnumString es_BiomeTerrainType[]; static struct EnumString es_DecorationType[];