mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Add function minetest.read_schematic
				
					
				
			This commit is contained in:
		@@ -4844,6 +4844,18 @@ Schematics
 | 
			
		||||
          the Lua code generated will use that number of spaces as indentation
 | 
			
		||||
          instead of a tab character.
 | 
			
		||||
 | 
			
		||||
* `minetest.read_schematic(schematic, options)`
 | 
			
		||||
    * Returns a Lua table representing the schematic (see: [Schematic specifier])
 | 
			
		||||
    * `schematic` is the schematic to read (see: [Schematic specifier])
 | 
			
		||||
    * `options` is a table containing the following optional parameters:
 | 
			
		||||
        * `write_yslice_prob`: string value:
 | 
			
		||||
            * `none`: no `write_yslice_prob` table is inserted,
 | 
			
		||||
            * `low`: only probabilities that are not 254 or 255 are written in
 | 
			
		||||
              the `write_ylisce_prob` table,
 | 
			
		||||
            * `all`: write all probabilities to the `write_yslice_prob` table.
 | 
			
		||||
            * The default for this option is `all`.
 | 
			
		||||
            * Any invalid value will be interpreted as `all`.
 | 
			
		||||
 | 
			
		||||
HTTP Requests
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1754,6 +1754,83 @@ int ModApiMapgen::l_serialize_schematic(lua_State *L)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// read_schematic(schematic, options={...})
 | 
			
		||||
int ModApiMapgen::l_read_schematic(lua_State *L)
 | 
			
		||||
{
 | 
			
		||||
	NO_MAP_LOCK_REQUIRED;
 | 
			
		||||
 | 
			
		||||
	SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
 | 
			
		||||
 | 
			
		||||
	//// Read options
 | 
			
		||||
	std::string write_yslice = getstringfield_default(L, 2, "write_yslice_prob", "all");
 | 
			
		||||
 | 
			
		||||
	//// Get schematic
 | 
			
		||||
	bool was_loaded = false;
 | 
			
		||||
	Schematic *schem = (Schematic *)get_objdef(L, 1, schemmgr);
 | 
			
		||||
	if (!schem) {
 | 
			
		||||
		schem = load_schematic(L, 1, NULL, NULL);
 | 
			
		||||
		was_loaded = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (!schem) {
 | 
			
		||||
		errorstream << "read_schematic: failed to get schematic" << std::endl;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	lua_pop(L, 2);
 | 
			
		||||
 | 
			
		||||
	//// Create the Lua table
 | 
			
		||||
	u32 numnodes = schem->size.X * schem->size.Y * schem->size.Z;
 | 
			
		||||
	const std::vector<std::string> &names = schem->m_nodenames;
 | 
			
		||||
 | 
			
		||||
	lua_createtable(L, 0, (write_yslice == "none") ? 2 : 3);
 | 
			
		||||
 | 
			
		||||
	// Create the size field
 | 
			
		||||
	push_v3s16(L, schem->size);
 | 
			
		||||
	lua_setfield(L, 1, "size");
 | 
			
		||||
 | 
			
		||||
	// Create the yslice_prob field
 | 
			
		||||
	if (write_yslice != "none") {
 | 
			
		||||
		lua_createtable(L, schem->size.Y, 0);
 | 
			
		||||
		for (u16 y = 0; y != schem->size.Y; ++y) {
 | 
			
		||||
			u8 probability = schem->slice_probs[y] & MTSCHEM_PROB_MASK;
 | 
			
		||||
			if (probability < MTSCHEM_PROB_ALWAYS || write_yslice != "low") {
 | 
			
		||||
				lua_createtable(L, 0, 2);
 | 
			
		||||
				lua_pushinteger(L, y);
 | 
			
		||||
				lua_setfield(L, 3, "ypos");
 | 
			
		||||
				lua_pushinteger(L, probability * 2);
 | 
			
		||||
				lua_setfield(L, 3, "prob");
 | 
			
		||||
				lua_rawseti(L, 2, y + 1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		lua_setfield(L, 1, "yslice_prob");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create the data field
 | 
			
		||||
	lua_createtable(L, numnodes, 0); // data table
 | 
			
		||||
	for (u32 i = 0; i < numnodes; ++i) {
 | 
			
		||||
		MapNode node = schem->schemdata[i];
 | 
			
		||||
		u8 probability   = node.param1 & MTSCHEM_PROB_MASK;
 | 
			
		||||
		bool force_place = node.param1 & MTSCHEM_FORCE_PLACE;
 | 
			
		||||
		lua_createtable(L, 0, force_place ? 4 : 3);
 | 
			
		||||
		lua_pushstring(L, names[schem->schemdata[i].getContent()].c_str());
 | 
			
		||||
		lua_setfield(L, 3, "name");
 | 
			
		||||
		lua_pushinteger(L, probability * 2);
 | 
			
		||||
		lua_setfield(L, 3, "prob");
 | 
			
		||||
		lua_pushinteger(L, node.param2);
 | 
			
		||||
		lua_setfield(L, 3, "param2");
 | 
			
		||||
		if (force_place) {
 | 
			
		||||
			lua_pushboolean(L, 1);
 | 
			
		||||
			lua_setfield(L, 3, "force_place");
 | 
			
		||||
		}
 | 
			
		||||
		lua_rawseti(L, 2, i + 1);
 | 
			
		||||
	}
 | 
			
		||||
	lua_setfield(L, 1, "data");
 | 
			
		||||
 | 
			
		||||
	if (was_loaded)
 | 
			
		||||
		delete schem;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ModApiMapgen::Initialize(lua_State *L, int top)
 | 
			
		||||
{
 | 
			
		||||
@@ -1793,4 +1870,5 @@ void ModApiMapgen::Initialize(lua_State *L, int top)
 | 
			
		||||
	API_FCT(place_schematic);
 | 
			
		||||
	API_FCT(place_schematic_on_vmanip);
 | 
			
		||||
	API_FCT(serialize_schematic);
 | 
			
		||||
	API_FCT(read_schematic);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -131,6 +131,9 @@ private:
 | 
			
		||||
	// serialize_schematic(schematic, format, options={...})
 | 
			
		||||
	static int l_serialize_schematic(lua_State *L);
 | 
			
		||||
 | 
			
		||||
	// read_schematic(schematic, options={...})
 | 
			
		||||
	static int l_read_schematic(lua_State *L);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	static void Initialize(lua_State *L, int top);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user