From 309c5f3641dccaf1260953f098ccd593396dee64 Mon Sep 17 00:00:00 2001
From: kwolekr <kwolekr@minetest.net>
Date: Sat, 22 Jun 2013 20:48:19 -0400
Subject: [PATCH] Decoration: Add support for zero probability, fix breakage
 from last commit

---
 doc/lua_api.txt               | 18 +++++++++++++-----
 src/mapgen.cpp                | 18 +++++++++++++++---
 src/mapgen.h                  |  2 +-
 src/script/lua_api/luaapi.cpp | 12 ++++++------
 4 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 7be94ac03..8231364fb 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -432,14 +432,22 @@ Schematic specifier
 or through raw data supplied through Lua, in the form of a table.  This table must specify two fields:
  - The 'size' field is a 3d vector containing the dimensions of the provided schematic.
  - The 'data' field is a flat table of MapNodes making up the schematic, in the order of [z [y [x]]].
+
 In the bulk MapNode data, param1, instead of the typical light values, instead represents the 
-probability of that node appearing in the structure.  It is an integer with a value from 0-255; 0 means
-that node will always appear.  If the probability value p is non-zero, then there is a
-(p / 256 * 100)% chance that node will appear when the schematic is placed on the map.
+probability of that node appearing in the structure.
+When passed to minetest.create_schematic, probability is an integer value ranging from -1 to 255:
+ - A probability value of 0 means that node will always appear.
+ - A probability value of -1 means the node will never appear.
+ - If the probability value p is greater than 0, then there is a (p / 256 * 100)% chance that node
+   will appear when the schematic is placed on the map.
+
+If registering a structure in the raw format, however, -1 is not a valid probability value; in order to
+have a node that is not placed, it must be CONTENT_IGNORE (the name for which is "ignore").
+
 Important note: Node aliases cannot be used for a raw schematic provided when registering as a decoration.
 
 Schematic attributes
------------------
+---------------------
 Currently supported flags:  place_center_x, place_center_y, place_center_z
  - place_center_x
     Placement of this decoration is centered along the X axis.
@@ -1281,7 +1289,7 @@ minetest.create_schematic(p1, p2, probability_list, filename)
 ^ Apply the specified probability values to the specified nodes in probability_list.
    ^ probability_list is an array of tables containing two fields, pos and prob.
    ^ pos is the 3d vector specifying the absolute coordinates of the node being modified,
-   ^ and prob is the integer value from 0 to 255 of the probability (see: Schematic specifier).
+   ^ and prob is the integer value from -1 to 255 of the probability (see: Schematic specifier).
    ^ If there are two or more entries with the same pos value, the last occuring in the array is used.
    ^ If pos is not inside the box formed by p1 and p2, it is ignored.
    ^ If probability_list is nil, no probabilities are applied.
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 53982e964..d1a38bb20 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -542,6 +542,9 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
 			if (!vm->m_area.contains(vi))
 				continue;
 				
+			if (schematic[i].getContent() == CONTENT_IGNORE)
+				continue;
+				
 			content_t c = vm->m_data[vi].getContent();
 			if (c != CONTENT_AIR && c != CONTENT_IGNORE)
 				continue;
@@ -588,6 +591,10 @@ void DecoSchematic::placeStructure(Map *map, v3s16 p) {
 		for (s16 x = 0; x != size.X; x++, i++, vi++) {
 			if (!vm->m_area.contains(vi))
 				continue;
+				
+			if (schematic[i].getContent() == CONTENT_IGNORE)
+				continue;
+				
 			if (schematic[i].param1 && myrand_range(1, 256) > schematic[i].param1)
 				continue;
 			
@@ -746,12 +753,17 @@ bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2) {
 }
 
 
-void DecoSchematic::applyProbabilities(std::vector<std::pair<v3s16, u8> > *plist, v3s16 p0) {
+void DecoSchematic::applyProbabilities(std::vector<std::pair<v3s16, s16> > *plist, v3s16 p0) {
 	for (size_t i = 0; i != plist->size(); i++) {
 		v3s16 p = (*plist)[i].first - p0;
 		int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X;
-		if (index < size.Z * size.Y * size.X)
-			schematic[index].param1 = (*plist)[i].second;
+		if (index < size.Z * size.Y * size.X) {
+			s16 prob = (*plist)[i].second;
+			if (prob != -1)
+				schematic[index].param1 = prob;
+			else
+				schematic[index].setContent(CONTENT_IGNORE);
+		}
 	}
 }
 
diff --git a/src/mapgen.h b/src/mapgen.h
index b2fbe7429..0090b0eda 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -271,7 +271,7 @@ class DecoSchematic : public Decoration {
 	
 	bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
 	void placeStructure(Map *map, v3s16 p);
-	void applyProbabilities(std::vector<std::pair<v3s16, u8> > *plist, v3s16 p0);
+	void applyProbabilities(std::vector<std::pair<v3s16, s16> > *plist, v3s16 p0);
 };
 
 void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
diff --git a/src/script/lua_api/luaapi.cpp b/src/script/lua_api/luaapi.cpp
index a5993fa47..d457d257e 100644
--- a/src/script/lua_api/luaapi.cpp
+++ b/src/script/lua_api/luaapi.cpp
@@ -674,7 +674,7 @@ int ModApiBasic::l_register_ore(lua_State *L)
 
 	verbosestream << "register_ore: ore '" << ore->ore_name
 		<< "' registered" << std::endl;
-	return 1;
+	return 0;
 }
 
 // register_decoration({lots of stuff})
@@ -793,7 +793,7 @@ int ModApiBasic::l_register_decoration(lua_State *L)
 
 	verbosestream << "register_decoration: decoration '" << deco->getName()
 		<< "' registered" << std::endl;
-	return 1;
+	return 0;
 }
 
 // create_schematic(p1, p2, probability_list, filename)
@@ -808,7 +808,7 @@ int ModApiBasic::l_create_schematic(lua_State *L)
 	v3s16 p2 = read_v3s16(L, 2);
 	sortBoxVerticies(p1, p2);
 	
-	std::vector<std::pair<v3s16, u8> > probability_list;
+	std::vector<std::pair<v3s16, s16> > probability_list;
 	if (lua_istable(L, 3)) {
 		lua_pushnil(L);
 		while (lua_next(L, 3)) {
@@ -817,12 +817,12 @@ int ModApiBasic::l_create_schematic(lua_State *L)
 				v3s16 pos = read_v3s16(L, -1);
 				lua_pop(L, 1);
 				
-				int prob = getintfield_default(L, -1, "prob", 0);
-				if (prob < 0 || prob >= UCHAR_MAX) {
+				s16 prob = getintfield_default(L, -1, "prob", 0);
+				if (prob < -1 || 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));
+					probability_list.push_back(std::make_pair(pos, prob));
 				}
 			}
 
-- 
GitLab