mirror of
https://github.com/minetest/minetest.git
synced 2024-08-18 20:44:16 +02:00
Schematics: Add per-node force placement option
This commit is contained in:
parent
d59e6ad004
commit
2b99d904f6
@ -782,30 +782,27 @@ Schematic specifier
|
||||
--------------------
|
||||
A schematic specifier identifies a schematic by either a filename to a
|
||||
Minetest Schematic file (`.mts`) or through raw data supplied through Lua,
|
||||
in the form of a table. This table must specify two fields:
|
||||
in the form of a table. This table specifies the following 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]]]`.
|
||||
* The `size` field is a 3D vector containing the dimensions of the provided schematic. (required)
|
||||
* The `yslice_prob` field is a table of {ypos, prob} which sets the `ypos`th vertical slice
|
||||
of the schematic to have a `prob / 256 * 100` chance of occuring. (default: 255)
|
||||
* The `data` field is a flat table of MapNode tables making up the schematic,
|
||||
in the order of `[z [y [x]]]`. (required)
|
||||
Each MapNode table contains:
|
||||
* `name`: the name of the map node to place (required)
|
||||
* `prob` (alias `param1`): the probability of this node being placed (default: 255)
|
||||
* `param2`: the raw param2 value of the node being placed onto the map (default: 0)
|
||||
* `force_place`: boolean representing if the node should forcibly overwrite any
|
||||
previous contents (default: false)
|
||||
|
||||
**Important**: The default value for `param1` in MapNodes here is `255`,
|
||||
which represents "always place".
|
||||
|
||||
In the bulk `MapNode` data, `param1`, instead of the typical light values,
|
||||
instead represents the probability of that node appearing in the structure.
|
||||
|
||||
When passed to `minetest.create_schematic`, probability is an integer value
|
||||
ranging from `0` to `255`:
|
||||
|
||||
* A probability value of `0` means that node will never appear (0% chance).
|
||||
* A probability value of `255` means the node will always appear (100% chance).
|
||||
* 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
|
||||
About probability values:
|
||||
* A probability value of `0` or `1` means that node will never appear (0% chance).
|
||||
* A probability value of `254` or `255` means the node will always appear (100% chance).
|
||||
* If the probability value `p` is greater than `1`, then there is a
|
||||
`(p / 256 * 100)` percent chance that node will appear when the schematic is
|
||||
placed on the map.
|
||||
|
||||
**Important note**: Node aliases cannot be used for a raw schematic provided
|
||||
when registering as a decoration.
|
||||
|
||||
|
||||
Schematic attributes
|
||||
--------------------
|
||||
|
@ -133,8 +133,8 @@ void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot, bool force_pla
|
||||
|
||||
s16 y_map = p.Y;
|
||||
for (s16 y = 0; y != sy; y++) {
|
||||
if (slice_probs[y] != MTSCHEM_PROB_ALWAYS &&
|
||||
myrand_range(1, 255) > slice_probs[y])
|
||||
if ((slice_probs[y] != MTSCHEM_PROB_ALWAYS) &&
|
||||
(slice_probs[y] <= myrand_range(1, MTSCHEM_PROB_ALWAYS)))
|
||||
continue;
|
||||
|
||||
for (s16 z = 0; z != sz; z++) {
|
||||
@ -147,17 +147,20 @@ void Schematic::blitToVManip(v3s16 p, MMVManip *vm, Rotation rot, bool force_pla
|
||||
if (schemdata[i].getContent() == CONTENT_IGNORE)
|
||||
continue;
|
||||
|
||||
if (schemdata[i].param1 == MTSCHEM_PROB_NEVER)
|
||||
u8 placement_prob = schemdata[i].param1 & MTSCHEM_PROB_MASK;
|
||||
bool force_place_node = schemdata[i].param1 & MTSCHEM_FORCE_PLACE;
|
||||
|
||||
if (placement_prob == MTSCHEM_PROB_NEVER)
|
||||
continue;
|
||||
|
||||
if (!force_place) {
|
||||
if (!force_place && !force_place_node) {
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (c != CONTENT_AIR && c != CONTENT_IGNORE)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (schemdata[i].param1 != MTSCHEM_PROB_ALWAYS &&
|
||||
myrand_range(1, 255) > schemdata[i].param1)
|
||||
if ((placement_prob != MTSCHEM_PROB_ALWAYS) &&
|
||||
(placement_prob <= myrand_range(1, MTSCHEM_PROB_ALWAYS)))
|
||||
continue;
|
||||
|
||||
vm->m_data[vi] = schemdata[i];
|
||||
@ -225,6 +228,7 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
content_t cignore = CONTENT_IGNORE;
|
||||
bool have_cignore = false;
|
||||
|
||||
//// Read signature
|
||||
u32 signature = readU32(ss);
|
||||
if (signature != MTSCHEM_FILE_SIGNATURE) {
|
||||
errorstream << "Schematic::deserializeFromMts: invalid schematic "
|
||||
@ -232,6 +236,7 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
return false;
|
||||
}
|
||||
|
||||
//// Read version
|
||||
u16 version = readU16(ss);
|
||||
if (version > MTSCHEM_FILE_VER_HIGHEST_READ) {
|
||||
errorstream << "Schematic::deserializeFromMts: unsupported schematic "
|
||||
@ -239,18 +244,21 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
return false;
|
||||
}
|
||||
|
||||
//// Read size
|
||||
size = readV3S16(ss);
|
||||
|
||||
//// Read Y-slice probability values
|
||||
delete []slice_probs;
|
||||
slice_probs = new u8[size.Y];
|
||||
for (int y = 0; y != size.Y; y++)
|
||||
slice_probs[y] = (version >= 3) ? readU8(ss) : MTSCHEM_PROB_ALWAYS;
|
||||
slice_probs[y] = (version >= 3) ? readU8(ss) : MTSCHEM_PROB_ALWAYS_OLD;
|
||||
|
||||
//// Read node names
|
||||
u16 nidmapcount = readU16(ss);
|
||||
for (int i = 0; i != nidmapcount; i++) {
|
||||
std::string name = deSerializeString(ss);
|
||||
|
||||
// Instances of "ignore" from ver 1 are converted to air (and instances
|
||||
// Instances of "ignore" from v1 are converted to air (and instances
|
||||
// are fixed to have MTSCHEM_PROB_NEVER later on).
|
||||
if (name == "ignore") {
|
||||
name = "air";
|
||||
@ -261,6 +269,7 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
names->push_back(name);
|
||||
}
|
||||
|
||||
//// Read node data
|
||||
size_t nodecount = size.X * size.Y * size.Z;
|
||||
|
||||
delete []schemdata;
|
||||
@ -269,8 +278,8 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
MapNode::deSerializeBulk(ss, SER_FMT_VER_HIGHEST_READ, schemdata,
|
||||
nodecount, 2, 2, true);
|
||||
|
||||
// fix any probability values for nodes that were ignore
|
||||
if (version == 1) {
|
||||
// Fix probability values for nodes that were ignore; removed in v2
|
||||
if (version < 2) {
|
||||
for (size_t i = 0; i != nodecount; i++) {
|
||||
if (schemdata[i].param1 == 0)
|
||||
schemdata[i].param1 = MTSCHEM_PROB_ALWAYS;
|
||||
@ -279,6 +288,14 @@ bool Schematic::deserializeFromMts(std::istream *is,
|
||||
}
|
||||
}
|
||||
|
||||
// Fix probability values for probability range truncation introduced in v4
|
||||
if (version < 4) {
|
||||
for (s16 y = 0; y != size.Y; y++)
|
||||
slice_probs[y] >>= 1;
|
||||
for (size_t i = 0; i != nodecount; i++)
|
||||
schemdata[i].param1 >>= 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -331,9 +348,11 @@ bool Schematic::serializeToLua(std::ostream *os,
|
||||
ss << indent << "yslice_prob = {" << std::endl;
|
||||
|
||||
for (u16 y = 0; y != size.Y; y++) {
|
||||
u8 probability = slice_probs[y] & MTSCHEM_PROB_MASK;
|
||||
|
||||
ss << indent << indent << "{"
|
||||
<< "ypos=" << y
|
||||
<< ", prob=" << (u16)slice_probs[y]
|
||||
<< ", prob=" << (u16)probability * 2
|
||||
<< "}," << std::endl;
|
||||
}
|
||||
|
||||
@ -355,11 +374,18 @@ bool Schematic::serializeToLua(std::ostream *os,
|
||||
}
|
||||
|
||||
for (u16 x = 0; x != size.X; x++, i++) {
|
||||
u8 probability = schemdata[i].param1 & MTSCHEM_PROB_MASK;
|
||||
bool force_place = schemdata[i].param1 & MTSCHEM_FORCE_PLACE;
|
||||
|
||||
ss << indent << indent << "{"
|
||||
<< "name=\"" << names[schemdata[i].getContent()]
|
||||
<< "\", param1=" << (u16)schemdata[i].param1
|
||||
<< ", param2=" << (u16)schemdata[i].param2
|
||||
<< "}," << std::endl;
|
||||
<< "\", prob=" << (u16)probability * 2
|
||||
<< ", param2=" << (u16)schemdata[i].param2;
|
||||
|
||||
if (force_place)
|
||||
ss << ", force_place=true";
|
||||
|
||||
ss << "}," << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ class IGameDef;
|
||||
|
||||
All values are stored in big-endian byte order.
|
||||
[u32] signature: 'MTSM'
|
||||
[u16] version: 3
|
||||
[u16] version: 4
|
||||
[u16] size X
|
||||
[u16] size Y
|
||||
[u16] size Z
|
||||
@ -51,7 +51,9 @@ class IGameDef;
|
||||
For each node in schematic: (for z, y, x)
|
||||
[u16] content
|
||||
For each node in schematic:
|
||||
[u8] probability of occurance (param1)
|
||||
[u8] param1
|
||||
bit 0-6: probability
|
||||
bit 7: specific node force placement
|
||||
For each node in schematic:
|
||||
[u8] param2
|
||||
}
|
||||
@ -60,17 +62,21 @@ class IGameDef;
|
||||
1 - Initial version
|
||||
2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
|
||||
3 - Added y-slice probabilities; this allows for variable height structures
|
||||
4 - Compressed range of node occurence prob., added per-node force placement bit
|
||||
*/
|
||||
|
||||
/////////////////// Schematic flags
|
||||
#define SCHEM_CIDS_UPDATED 0x08
|
||||
|
||||
//// Schematic constants
|
||||
#define MTSCHEM_FILE_SIGNATURE 0x4d54534d // 'MTSM'
|
||||
#define MTSCHEM_FILE_VER_HIGHEST_READ 3
|
||||
#define MTSCHEM_FILE_VER_HIGHEST_WRITE 3
|
||||
#define MTSCHEM_FILE_VER_HIGHEST_READ 4
|
||||
#define MTSCHEM_FILE_VER_HIGHEST_WRITE 4
|
||||
|
||||
#define MTSCHEM_PROB_NEVER 0x00
|
||||
#define MTSCHEM_PROB_ALWAYS 0xFF
|
||||
#define MTSCHEM_PROB_MASK 0x7F
|
||||
|
||||
#define MTSCHEM_PROB_NEVER 0x00
|
||||
#define MTSCHEM_PROB_ALWAYS 0x7F
|
||||
#define MTSCHEM_PROB_ALWAYS_OLD 0xFF
|
||||
|
||||
#define MTSCHEM_FORCE_PLACE 0x80
|
||||
|
||||
enum SchematicType
|
||||
{
|
||||
|
@ -331,6 +331,19 @@ bool getintfield(lua_State *L, int table,
|
||||
return got;
|
||||
}
|
||||
|
||||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, u8 &result)
|
||||
{
|
||||
lua_getfield(L, table, fieldname);
|
||||
bool got = false;
|
||||
if(lua_isnumber(L, -1)){
|
||||
result = lua_tonumber(L, -1);
|
||||
got = true;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return got;
|
||||
}
|
||||
|
||||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, u16 &result)
|
||||
{
|
||||
|
@ -53,6 +53,8 @@ size_t getstringlistfield(lua_State *L, int table,
|
||||
std::vector<std::string> *result);
|
||||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, int &result);
|
||||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, u8 &result);
|
||||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, u16 &result);
|
||||
bool getintfield(lua_State *L, int table,
|
||||
|
@ -237,36 +237,32 @@ bool read_schematic_def(lua_State *L, int index,
|
||||
lua_getfield(L, index, "data");
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
||||
int numnodes = size.X * size.Y * size.Z;
|
||||
u32 numnodes = size.X * size.Y * size.Z;
|
||||
schem->schemdata = new MapNode[numnodes];
|
||||
int i = 0;
|
||||
|
||||
size_t names_base = names->size();
|
||||
std::map<std::string, content_t> name_id_map;
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
if (i >= numnodes) {
|
||||
i++;
|
||||
lua_pop(L, 1);
|
||||
u32 i = 0;
|
||||
for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) {
|
||||
if (i >= numnodes)
|
||||
continue;
|
||||
}
|
||||
|
||||
// same as readnode, except param1 default is MTSCHEM_PROB_CONST
|
||||
lua_getfield(L, -1, "name");
|
||||
std::string name = luaL_checkstring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
//// Read name
|
||||
std::string name;
|
||||
if (!getstringfield(L, -1, "name", name))
|
||||
throw LuaError("Schematic data definition with missing name field");
|
||||
|
||||
//// Read param1/prob
|
||||
u8 param1;
|
||||
lua_getfield(L, -1, "param1");
|
||||
param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS;
|
||||
lua_pop(L, 1);
|
||||
if (!getintfield(L, -1, "param1", param1) &&
|
||||
!getintfield(L, -1, "prob", param1))
|
||||
param1 = MTSCHEM_PROB_ALWAYS_OLD;
|
||||
|
||||
u8 param2;
|
||||
lua_getfield(L, -1, "param2");
|
||||
param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
|
||||
lua_pop(L, 1);
|
||||
//// Read param2
|
||||
u8 param2 = getintfield_default(L, -1, "param2", 0);
|
||||
|
||||
//// Find or add new nodename-to-ID mapping
|
||||
std::map<std::string, content_t>::iterator it = name_id_map.find(name);
|
||||
content_t name_index;
|
||||
if (it != name_id_map.end()) {
|
||||
@ -277,10 +273,13 @@ bool read_schematic_def(lua_State *L, int index,
|
||||
names->push_back(name);
|
||||
}
|
||||
|
||||
schem->schemdata[i] = MapNode(name_index, param1, param2);
|
||||
//// Perform probability/force_place fixup on param1
|
||||
param1 >>= 1;
|
||||
if (getboolfield_default(L, -1, "force_place", false))
|
||||
param1 |= MTSCHEM_FORCE_PLACE;
|
||||
|
||||
i++;
|
||||
lua_pop(L, 1);
|
||||
//// Actually set the node in the schematic
|
||||
schem->schemdata[i] = MapNode(name_index, param1, param2);
|
||||
}
|
||||
|
||||
if (i != numnodes) {
|
||||
@ -297,13 +296,13 @@ bool read_schematic_def(lua_State *L, int index,
|
||||
|
||||
lua_getfield(L, index, "yslice_prob");
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) {
|
||||
schem->slice_probs[i] = getintfield_default(L, -1,
|
||||
"prob", MTSCHEM_PROB_ALWAYS);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
u16 ypos;
|
||||
if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) ||
|
||||
!getintfield(L, -1, "prob", schem->slice_probs[ypos]))
|
||||
continue;
|
||||
|
||||
schem->slice_probs[ypos] >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,9 @@ public:
|
||||
void testLuaTableSerialize(INodeDefManager *ndef);
|
||||
void testFileSerializeDeserialize(INodeDefManager *ndef);
|
||||
|
||||
static const content_t test_schem_data[7 * 6 * 4];
|
||||
static const content_t test_schem_data2[3 * 3 * 3];
|
||||
static const content_t test_schem1_data[7 * 6 * 4];
|
||||
static const content_t test_schem2_data[3 * 3 * 3];
|
||||
static const u8 test_schem2_prob[3 * 3 * 3];
|
||||
static const char *expected_lua_output;
|
||||
};
|
||||
|
||||
@ -78,7 +79,7 @@ void TestSchematic::testMtsSerializeDeserialize(INodeDefManager *ndef)
|
||||
schem.schemdata = new MapNode[volume];
|
||||
schem.slice_probs = new u8[size.Y];
|
||||
for (size_t i = 0; i != volume; i++)
|
||||
schem.schemdata[i] = MapNode(test_schem_data[i], MTSCHEM_PROB_ALWAYS, 0);
|
||||
schem.schemdata[i] = MapNode(test_schem1_data[i], MTSCHEM_PROB_ALWAYS, 0);
|
||||
for (s16 y = 0; y != size.Y; y++)
|
||||
schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS;
|
||||
|
||||
@ -115,7 +116,7 @@ void TestSchematic::testLuaTableSerialize(INodeDefManager *ndef)
|
||||
schem.schemdata = new MapNode[volume];
|
||||
schem.slice_probs = new u8[size.Y];
|
||||
for (size_t i = 0; i != volume; i++)
|
||||
schem.schemdata[i] = MapNode(test_schem_data2[i], MTSCHEM_PROB_ALWAYS, 0);
|
||||
schem.schemdata[i] = MapNode(test_schem2_data[i], test_schem2_prob[i], 0);
|
||||
for (s16 y = 0; y != size.Y; y++)
|
||||
schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS;
|
||||
|
||||
@ -160,8 +161,8 @@ void TestSchematic::testFileSerializeDeserialize(INodeDefManager *ndef)
|
||||
schem1.slice_probs[2] = 240;
|
||||
|
||||
for (size_t i = 0; i != volume; i++) {
|
||||
content_t c = content_map[test_schem_data2[i]];
|
||||
schem1.schemdata[i] = MapNode(c, MTSCHEM_PROB_ALWAYS, 0);
|
||||
content_t c = content_map[test_schem2_data[i]];
|
||||
schem1.schemdata[i] = MapNode(c, test_schem2_prob[i], 0);
|
||||
}
|
||||
|
||||
std::string temp_file = getTestTempFile();
|
||||
@ -174,14 +175,14 @@ void TestSchematic::testFileSerializeDeserialize(INodeDefManager *ndef)
|
||||
UASSERT(schem2.slice_probs[2] == 240);
|
||||
|
||||
for (size_t i = 0; i != volume; i++) {
|
||||
content_t c = content_map2[test_schem_data2[i]];
|
||||
UASSERT(schem2.schemdata[i] == MapNode(c, MTSCHEM_PROB_ALWAYS, 0));
|
||||
content_t c = content_map2[test_schem2_data[i]];
|
||||
UASSERT(schem2.schemdata[i] == MapNode(c, test_schem2_prob[i], 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Should form a cross-shaped-thing...?
|
||||
const content_t TestSchematic::test_schem_data[7 * 6 * 4] = {
|
||||
const content_t TestSchematic::test_schem1_data[7 * 6 * 4] = {
|
||||
3, 3, 1, 1, 1, 3, 3, // Y=0, Z=0
|
||||
3, 0, 1, 2, 1, 0, 3, // Y=1, Z=0
|
||||
3, 0, 1, 2, 1, 0, 3, // Y=2, Z=0
|
||||
@ -211,7 +212,7 @@ const content_t TestSchematic::test_schem_data[7 * 6 * 4] = {
|
||||
3, 1, 1, 2, 1, 1, 3, // Y=5, Z=3
|
||||
};
|
||||
|
||||
const content_t TestSchematic::test_schem_data2[3 * 3 * 3] = {
|
||||
const content_t TestSchematic::test_schem2_data[3 * 3 * 3] = {
|
||||
0, 0, 0,
|
||||
0, 2, 0,
|
||||
0, 0, 0,
|
||||
@ -225,41 +226,55 @@ const content_t TestSchematic::test_schem_data2[3 * 3 * 3] = {
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
const u8 TestSchematic::test_schem2_prob[3 * 3 * 3] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0xFF, 0x00,
|
||||
0xFF, 0xFF, 0xFF,
|
||||
0x00, 0xFF, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
const char *TestSchematic::expected_lua_output =
|
||||
"schematic = {\n"
|
||||
"\tsize = {x=3, y=3, z=3},\n"
|
||||
"\tyslice_prob = {\n"
|
||||
"\t\t{ypos=0, prob=255},\n"
|
||||
"\t\t{ypos=1, prob=255},\n"
|
||||
"\t\t{ypos=2, prob=255},\n"
|
||||
"\t\t{ypos=0, prob=254},\n"
|
||||
"\t\t{ypos=1, prob=254},\n"
|
||||
"\t\t{ypos=2, prob=254},\n"
|
||||
"\t},\n"
|
||||
"\tdata = {\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:lava_source\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", param1=255, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"default:lava_source\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t\t{name=\"air\", prob=0, param2=0},\n"
|
||||
"\t},\n"
|
||||
"}\n";
|
||||
|
Loading…
Reference in New Issue
Block a user