From 45589fae58157c8a66c640a1db5795a42a86fc1c Mon Sep 17 00:00:00 2001
From: PilzAdam <pilzadam@minetest.net>
Date: Sat, 3 Aug 2013 01:58:29 +0200
Subject: [PATCH] Add replacements to schematics

---
 doc/lua_api.txt               |  5 ++++-
 src/mapgen.cpp                |  7 +++++-
 src/mapgen.h                  |  1 +
 src/script/lua_api/luaapi.cpp | 40 +++++++++++++++++++++++++++++++++--
 4 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index b5a9762b4..67ff823da 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1439,10 +1439,11 @@ minetest.create_schematic(p1, p2, probability_list, filename)
    ^ If probability_list is nil, no probabilities are applied.
 ^ Saves schematic in the Minetest Schematic format to filename.
 
-minetest.place_schematic(pos, schematic, rotation)
+minetest.place_schematic(pos, schematic, rotation, replacements)
 ^ Place the schematic specified by schematic (see: Schematic specifier) at pos.
 ^ Rotation can be "0", "90", "180", "270", or "random".
 ^ If the rotation parameter is omitted, the schematic is not rotated.
+^ replacements = {{"oldname", "convert_to"}, ...}
 
 Random:
 minetest.get_connected_players() -> list of ObjectRefs
@@ -2129,6 +2130,7 @@ Ore definition (register_ore)
     ore_type = "scatter", -- See "Ore types"
     ore = "default:stone_with_coal",
     wherein = "default:stone",
+    ^ a list of nodenames is supported too
     clust_scarcity = 8*8*8,
     ^ Ore has a 1 out of clust_scarcity chance of spawning in a node
     ^ This value should be *MUCH* higher than your intuition might tell you!
@@ -2196,6 +2198,7 @@ Decoration definition (register_decoration)
         }
     },
     ^ See 'Schematic specifier' for details.
+    replacements = {{"oldname", "convert_to"}, ...},
     flags = "place_center_x, place_center_z",
     ^ Flags for schematic decorations.  See 'Schematic attributes'.
     rotation = "90" --rotate schematic 90 degrees on placement
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index f446d05b7..397e52f74 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -506,7 +506,12 @@ void DecoSchematic::resolveNodeNames(INodeDefManager *ndef) {
 	}
 	
 	for (size_t i = 0; i != node_names->size(); i++) {
-		content_t c = ndef->getId(node_names->at(i));
+		std::string name = node_names->at(i);
+		std::map<std::string, std::string>::iterator it;
+		it = replacements.find(name);
+		if (it != replacements.end())
+			name = it->second;
+		content_t c = ndef->getId(name);
 		if (c == CONTENT_IGNORE) {
 			errorstream << "DecoSchematic::resolveNodeNames: node '"
 				<< node_names->at(i) << "' not defined" << std::endl;
diff --git a/src/mapgen.h b/src/mapgen.h
index 8aff33288..7b8ff57ca 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -269,6 +269,7 @@ class DecoSchematic : public Decoration {
 	
 	std::vector<std::string> *node_names;
 	std::vector<content_t> c_nodes;
+	std::map<std::string, std::string> replacements;
 
 	u32 flags;
 	Rotation rotation;
diff --git a/src/script/lua_api/luaapi.cpp b/src/script/lua_api/luaapi.cpp
index 0d4c7da7b..929aa40d0 100644
--- a/src/script/lua_api/luaapi.cpp
+++ b/src/script/lua_api/luaapi.cpp
@@ -808,7 +808,26 @@ int ModApiBasic::l_register_decoration(lua_State *L)
 			dschem->flags    = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
 			dschem->rotation = (Rotation)getenumfield(L, index,
 								"rotation", es_Rotation, ROTATE_0);
-			
+
+			lua_getfield(L, index, "replacements");
+			if (lua_istable(L, -1)) {
+				int i = lua_gettop(L);
+				lua_pushnil(L);
+				while (lua_next(L, i) != 0) {
+					// key at index -2 and value at index -1
+					lua_rawgeti(L, -1, 1);
+					std::string replace_from = lua_tostring(L, -1);
+					lua_pop(L, 1);
+					lua_rawgeti(L, -1, 2);
+					std::string replace_to = lua_tostring(L, -1);
+					lua_pop(L, 1);
+					dschem->replacements[replace_from] = replace_to;
+					// removes value, keeps key for next iteration
+					lua_pop(L, 1);
+				}
+			}
+			lua_pop(L, 1);
+
 			lua_getfield(L, index, "schematic");
 			if (!read_schematic(L, -1, dschem, getServer(L))) {
 				delete dschem;
@@ -888,7 +907,7 @@ int ModApiBasic::l_create_schematic(lua_State *L)
 }
 
 
-// place_schematic(p, schematic, rotation)
+// place_schematic(p, schematic, rotation, replacement)
 int ModApiBasic::l_place_schematic(lua_State *L)
 {
 	DecoSchematic dschem;
@@ -906,6 +925,23 @@ int ModApiBasic::l_place_schematic(lua_State *L)
 		
 	dschem.rotation = rot;
 
+	if (lua_istable(L, 4)) {
+		int index = 4;
+		lua_pushnil(L);
+		while (lua_next(L, index) != 0) {
+			// key at index -2 and value at index -1
+			lua_rawgeti(L, -1, 1);
+			std::string replace_from = lua_tostring(L, -1);
+			lua_pop(L, 1);
+			lua_rawgeti(L, -1, 2);
+			std::string replace_to = lua_tostring(L, -1);
+			lua_pop(L, 1);
+			dschem.replacements[replace_from] = replace_to;
+			// removes value, keeps key for next iteration
+			lua_pop(L, 1);
+		}
+	}
+
 	if (!dschem.filename.empty()) {
 		if (!dschem.loadSchematicFile()) {
 			errorstream << "place_schematic: failed to load schematic file '"
-- 
GitLab