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:
parent
b1a74df26d
commit
c1b829077a
8 changed files with 589 additions and 22 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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[];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue