1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Decoration: Add Schematic decoration type

This commit is contained in:
kwolekr 2013-06-22 00:29:44 -04:00
parent b1a74df26d
commit c1b829077a
8 changed files with 589 additions and 22 deletions

View file

@ -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;
}

View file

@ -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[];

View file

@ -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<std::pair<v3s16, u8> > 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;

View file

@ -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[];