From c1b829077a3518f3a129eee11887b2358a53f20b Mon Sep 17 00:00:00 2001 From: kwolekr Date: Sat, 22 Jun 2013 00:29:44 -0400 Subject: Decoration: Add Schematic decoration type --- src/script/common/c_content.cpp | 49 +++++++++++++++++ src/script/common/c_content.h | 5 ++ src/script/lua_api/luaapi.cpp | 116 +++++++++++++++++++++++++++++++++++----- src/script/lua_api/luaapi.h | 6 +++ 4 files changed, 164 insertions(+), 12 deletions(-) (limited to 'src/script') diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 64c76ef7c..4ea296523 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "tool.h" #include "server.h" +#include "mapgen.h" struct EnumString es_TileAnimationType[] = { @@ -922,3 +923,51 @@ NoiseParams *read_noiseparams(lua_State *L, int index) return np; } + +/******************************************************************************/ +bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *server) { + if (index < 0) + index = lua_gettop(L) + 1 + index; + + INodeDefManager *ndef = server->getNodeDefManager(); + + if (lua_istable(L, index)) { + lua_getfield(L, index, "size"); + v3s16 size = read_v3s16(L, -1); + lua_pop(L, 1); + + int numnodes = size.X * size.Y * size.Z; + MapNode *schemdata = new MapNode[numnodes]; + int i = 0; + + lua_getfield(L, index, "data"); + luaL_checktype(L, -1, LUA_TTABLE); + + lua_pushnil(L); + while (lua_next(L, -2)) { + if (i < numnodes) + schemdata[i] = readnode(L, -1, ndef); + + i++; + lua_pop(L, 1); + } + + dschem->size = size; + dschem->schematic = schemdata; + + if (i != numnodes) { + errorstream << "read_schematic: incorrect number of " + "nodes provided in raw schematic data (got " << i << + ", expected " << numnodes << ")." << std::endl; + return false; + } + } else if (lua_isstring(L, index)) { + dschem->filename = std::string(lua_tostring(L, index)); + } else { + errorstream << "read_schematic: missing schematic " + "filename or raw schematic data" << std::endl; + return false; + } + + return true; +} diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 58be7118c..fc00ce089 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -57,6 +57,7 @@ struct DigParams; struct HitParams; struct EnumString; struct NoiseParams; +class DecoSchematic; ContentFeatures read_content_features (lua_State *L, int index); @@ -139,6 +140,10 @@ bool string_to_enum (const EnumString *spec, NoiseParams* read_noiseparams (lua_State *L, int index); +bool read_schematic (lua_State *L, int index, + DecoSchematic *dschem, + Server *server); + void luaentity_get (lua_State *L,u16 id); extern struct EnumString es_TileAnimationType[]; diff --git a/src/script/lua_api/luaapi.cpp b/src/script/lua_api/luaapi.cpp index e19c90952..dea4ccf33 100644 --- a/src/script/lua_api/luaapi.cpp +++ b/src/script/lua_api/luaapi.cpp @@ -101,6 +101,8 @@ bool ModApiBasic::Initialize(lua_State* L,int top) { retval &= API_FCT(register_ore); retval &= API_FCT(register_decoration); + retval &= API_FCT(create_schematic); + retval &= API_FCT(place_schematic); return retval; } @@ -680,7 +682,7 @@ int ModApiBasic::l_register_decoration(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); - + EmergeManager *emerge = getServer(L)->getEmergeManager(); BiomeDefManager *bdef = emerge->biomedef; @@ -701,8 +703,14 @@ int ModApiBasic::l_register_decoration(lua_State *L) deco->c_place_on = CONTENT_IGNORE; deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore"); - 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; + delete deco; + return 0; + } lua_getfield(L, index, "noise_params"); deco->np = read_noiseparams(L, -1); @@ -743,7 +751,7 @@ int ModApiBasic::l_register_decoration(lua_State *L) lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { - dsimple->deco_name = std::string(lua_tostring(L, -1)); + dsimple->deco_name = std::string(lua_tostring(L, -1)); } else { dsimple->deco_name = std::string("air"); } @@ -758,22 +766,29 @@ int ModApiBasic::l_register_decoration(lua_State *L) break; } case DECO_SCHEMATIC: { - //DecoSchematic *decoschematic = (DecoSchematic *)deco; + DecoSchematic *dschem = (DecoSchematic *)deco; + dschem->flags = getflagsfield(L, index, "flags", flagdesc_deco_schematic); + lua_getfield(L, index, "schematic"); + if (!read_schematic(L, -1, dschem, getServer(L))) { + delete dschem; + return 0; + } + lua_pop(L, -1); + + if (!dschem->filename.empty() && !dschem->loadSchematicFile()) { + errorstream << "register_decoration: failed to load schematic file '" + << dschem->filename << "'" << std::endl; + delete dschem; + return 0; + } break; } case DECO_LSYSTEM: { //DecoLSystem *decolsystem = (DecoLSystem *)deco; break; } } - - if (deco->sidelen <= 0) { - errorstream << "register_decoration: sidelen must be " - "greater than 0" << std::endl; - delete deco; - return 0; - } - + emerge->decorations.push_back(deco); verbosestream << "register_decoration: decoration '" << deco->getName() @@ -781,5 +796,82 @@ int ModApiBasic::l_register_decoration(lua_State *L) return 0; } +// create_schematic(p1, p2, probability_list, filename) +int ModApiBasic::l_create_schematic(lua_State *L) +{ + DecoSchematic dschem; + + Map *map = &(getEnv(L)->getMap()); + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + v3s16 p1 = read_v3s16(L, 1); + v3s16 p2 = read_v3s16(L, 2); + sortBoxVerticies(p1, p2); + + std::vector > probability_list; + if (lua_istable(L, 3)) { + lua_pushnil(L); + while (lua_next(L, 3)) { + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "pos"); + v3s16 pos = read_v3s16(L, -1); + lua_pop(L, 1); + + int prob = getintfield_default(L, -1, "prob", 0); + if (prob < 0 || prob >= UCHAR_MAX) { + errorstream << "create_schematic: probability value of " + << prob << " at " << PP(pos) << " out of range" << std::endl; + } else { + probability_list.push_back(std::make_pair(pos, (u8)prob)); + } + } + + lua_pop(L, 1); + } + } + + dschem.filename = std::string(lua_tostring(L, 4)); + + if (!dschem.getSchematicFromMap(map, p1, p2)) { + errorstream << "create_schematic: failed to get schematic " + "from map" << std::endl; + return 0; + } + + dschem.applyProbabilities(&probability_list, p1); + + dschem.saveSchematicFile(ndef); + actionstream << "create_schematic: saved schematic file '" << dschem.filename << "'." << std::endl; + + return 1; +} + + +// place_schematic(p, schematic) +int ModApiBasic::l_place_schematic(lua_State *L) +{ + DecoSchematic dschem; + + Map *map = &(getEnv(L)->getMap()); + INodeDefManager *ndef = getServer(L)->getNodeDefManager(); + + v3s16 p = read_v3s16(L, 1); + if (!read_schematic(L, 2, &dschem, getServer(L))) + return 0; + + if (!dschem.filename.empty()) { + if (!dschem.loadSchematicFile()) { + errorstream << "place_schematic: failed to load schematic file '" + << dschem.filename << "'" << std::endl; + return 0; + } + dschem.resolveNodeNames(ndef); + } + + dschem.placeStructure(map, p); + + return 1; +} + ModApiBasic modapibasic_prototype; diff --git a/src/script/lua_api/luaapi.h b/src/script/lua_api/luaapi.h index d03c14117..ba76117d4 100644 --- a/src/script/lua_api/luaapi.h +++ b/src/script/lua_api/luaapi.h @@ -132,6 +132,12 @@ private: // register_decoration(deco) static int l_register_decoration(lua_State *L); + + // create_schematic(p1, p2, filename) + static int l_create_schematic(lua_State *L); + + // place_schematic(p, filename) + static int l_place_schematic(lua_State *L); static struct EnumString es_OreType[]; static struct EnumString es_DecorationType[]; -- cgit v1.2.3