Decoration: Add support for zero probability, fix breakage from last commit

This commit is contained in:
kwolekr 2013-06-22 20:48:19 -04:00
parent 130464c268
commit 309c5f3641
4 changed files with 35 additions and 15 deletions

@ -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: 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 '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]]]. - 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 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 probability of that node appearing in the structure.
that node will always appear. If the probability value p is non-zero, then there is a When passed to minetest.create_schematic, probability is an integer value ranging from -1 to 255:
(p / 256 * 100)% chance that node will appear when the schematic is placed on the map. - 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. Important note: Node aliases cannot be used for a raw schematic provided when registering as a decoration.
Schematic attributes Schematic attributes
----------------- ---------------------
Currently supported flags: place_center_x, place_center_y, place_center_z Currently supported flags: place_center_x, place_center_y, place_center_z
- place_center_x - place_center_x
Placement of this decoration is centered along the X axis. 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. ^ 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. ^ 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, ^ 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 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 pos is not inside the box formed by p1 and p2, it is ignored.
^ If probability_list is nil, no probabilities are applied. ^ If probability_list is nil, no probabilities are applied.

@ -542,6 +542,9 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
if (!vm->m_area.contains(vi)) if (!vm->m_area.contains(vi))
continue; continue;
if (schematic[i].getContent() == CONTENT_IGNORE)
continue;
content_t c = vm->m_data[vi].getContent(); content_t c = vm->m_data[vi].getContent();
if (c != CONTENT_AIR && c != CONTENT_IGNORE) if (c != CONTENT_AIR && c != CONTENT_IGNORE)
continue; continue;
@ -588,6 +591,10 @@ void DecoSchematic::placeStructure(Map *map, v3s16 p) {
for (s16 x = 0; x != size.X; x++, i++, vi++) { for (s16 x = 0; x != size.X; x++, i++, vi++) {
if (!vm->m_area.contains(vi)) if (!vm->m_area.contains(vi))
continue; continue;
if (schematic[i].getContent() == CONTENT_IGNORE)
continue;
if (schematic[i].param1 && myrand_range(1, 256) > schematic[i].param1) if (schematic[i].param1 && myrand_range(1, 256) > schematic[i].param1)
continue; 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++) { for (size_t i = 0; i != plist->size(); i++) {
v3s16 p = (*plist)[i].first - p0; v3s16 p = (*plist)[i].first - p0;
int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X; int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X;
if (index < size.Z * size.Y * size.X) if (index < size.Z * size.Y * size.X) {
schematic[index].param1 = (*plist)[i].second; s16 prob = (*plist)[i].second;
if (prob != -1)
schematic[index].param1 = prob;
else
schematic[index].setContent(CONTENT_IGNORE);
}
} }
} }

@ -271,7 +271,7 @@ public:
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2); bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
void placeStructure(Map *map, v3s16 p); 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, void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,

@ -674,7 +674,7 @@ int ModApiBasic::l_register_ore(lua_State *L)
verbosestream << "register_ore: ore '" << ore->ore_name verbosestream << "register_ore: ore '" << ore->ore_name
<< "' registered" << std::endl; << "' registered" << std::endl;
return 1; return 0;
} }
// register_decoration({lots of stuff}) // register_decoration({lots of stuff})
@ -793,7 +793,7 @@ int ModApiBasic::l_register_decoration(lua_State *L)
verbosestream << "register_decoration: decoration '" << deco->getName() verbosestream << "register_decoration: decoration '" << deco->getName()
<< "' registered" << std::endl; << "' registered" << std::endl;
return 1; return 0;
} }
// create_schematic(p1, p2, probability_list, filename) // 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); v3s16 p2 = read_v3s16(L, 2);
sortBoxVerticies(p1, p2); sortBoxVerticies(p1, p2);
std::vector<std::pair<v3s16, u8> > probability_list; std::vector<std::pair<v3s16, s16> > probability_list;
if (lua_istable(L, 3)) { if (lua_istable(L, 3)) {
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, 3)) { while (lua_next(L, 3)) {
@ -817,12 +817,12 @@ int ModApiBasic::l_create_schematic(lua_State *L)
v3s16 pos = read_v3s16(L, -1); v3s16 pos = read_v3s16(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
int prob = getintfield_default(L, -1, "prob", 0); s16 prob = getintfield_default(L, -1, "prob", 0);
if (prob < 0 || prob >= UCHAR_MAX) { if (prob < -1 || prob >= UCHAR_MAX) {
errorstream << "create_schematic: probability value of " errorstream << "create_schematic: probability value of "
<< prob << " at " << PP(pos) << " out of range" << std::endl; << prob << " at " << PP(pos) << " out of range" << std::endl;
} else { } else {
probability_list.push_back(std::make_pair(pos, (u8)prob)); probability_list.push_back(std::make_pair(pos, prob));
} }
} }