Skip to content

Commit 20e3d55

Browse files
committedDec 1, 2013
Decoration: Add schematic Y-slice probability support
1 parent de0cdbc commit 20e3d55

File tree

4 files changed

+107
-46
lines changed

4 files changed

+107
-46
lines changed
 

‎doc/lua_api.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ minetest.delete_particlespawner(id, player)
14911491
^ otherwise on all clients
14921492

14931493
Schematics:
1494-
minetest.create_schematic(p1, p2, probability_list, filename)
1494+
minetest.create_schematic(p1, p2, probability_list, filename, slice_prob_list)
14951495
^ Create a schematic from the volume of map specified by the box formed by p1 and p2.
14961496
^ Apply the specified probability values to the specified nodes in probability_list.
14971497
^ probability_list is an array of tables containing two fields, pos and prob.
@@ -1500,6 +1500,9 @@ minetest.create_schematic(p1, p2, probability_list, filename)
15001500
^ If there are two or more entries with the same pos value, the last occuring in the array is used.
15011501
^ If pos is not inside the box formed by p1 and p2, it is ignored.
15021502
^ If probability_list is nil, no probabilities are applied.
1503+
^ Slice probability works in the same manner, except takes a field called ypos instead which indicates
1504+
^ the y position of the slice with a probability applied.
1505+
^ If slice probability list is nil, no slice probabilities are applied.
15031506
^ Saves schematic in the Minetest Schematic format to filename.
15041507

15051508
minetest.place_schematic(pos, schematic, rotation, replacements)

‎src/mapgen.cpp

+76-39
Original file line numberDiff line numberDiff line change
@@ -482,16 +482,18 @@ std::string DecoSimple::getName() {
482482

483483

484484
DecoSchematic::DecoSchematic() {
485-
node_names = NULL;
486-
schematic = NULL;
487-
flags = 0;
488-
size = v3s16(0, 0, 0);
485+
node_names = NULL;
486+
schematic = NULL;
487+
slice_probs = NULL;
488+
flags = 0;
489+
size = v3s16(0, 0, 0);
489490
}
490491

491492

492493
DecoSchematic::~DecoSchematic() {
493494
delete node_names;
494495
delete []schematic;
496+
delete []slice_probs;
495497
}
496498

497499

@@ -599,37 +601,44 @@ void DecoSchematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
599601
i_step_x = xstride;
600602
i_step_z = zstride;
601603
}
602-
603-
for (s16 z = 0; z != sz; z++)
604+
605+
s16 y_map = p.Y;
604606
for (s16 y = 0; y != sy; y++) {
605-
u32 i = z * i_step_z + y * ystride + i_start;
606-
for (s16 x = 0; x != sx; x++, i += i_step_x) {
607-
u32 vi = vm->m_area.index(p.X + x, p.Y + y, p.Z + z);
608-
if (!vm->m_area.contains(vi))
609-
continue;
610-
611-
if (schematic[i].getContent() == CONTENT_IGNORE)
612-
continue;
613-
614-
if (schematic[i].param1 == MTSCHEM_PROB_NEVER)
615-
continue;
607+
if (slice_probs[y] != MTSCHEM_PROB_ALWAYS &&
608+
myrand_range(1, 255) > slice_probs[y])
609+
continue;
616610

617-
if (!force_placement) {
618-
content_t c = vm->m_data[vi].getContent();
619-
if (c != CONTENT_AIR && c != CONTENT_IGNORE)
611+
for (s16 z = 0; z != sz; z++) {
612+
u32 i = z * i_step_z + y * ystride + i_start;
613+
for (s16 x = 0; x != sx; x++, i += i_step_x) {
614+
u32 vi = vm->m_area.index(p.X + x, y_map, p.Z + z);
615+
if (!vm->m_area.contains(vi))
620616
continue;
617+
618+
if (schematic[i].getContent() == CONTENT_IGNORE)
619+
continue;
620+
621+
if (schematic[i].param1 == MTSCHEM_PROB_NEVER)
622+
continue;
623+
624+
if (!force_placement) {
625+
content_t c = vm->m_data[vi].getContent();
626+
if (c != CONTENT_AIR && c != CONTENT_IGNORE)
627+
continue;
628+
}
629+
630+
if (schematic[i].param1 != MTSCHEM_PROB_ALWAYS &&
631+
myrand_range(1, 255) > schematic[i].param1)
632+
continue;
633+
634+
vm->m_data[vi] = schematic[i];
635+
vm->m_data[vi].param1 = 0;
636+
637+
if (rot)
638+
vm->m_data[vi].rotateAlongYAxis(ndef, rot);
621639
}
622-
623-
if (schematic[i].param1 != MTSCHEM_PROB_ALWAYS &&
624-
myrand_range(1, 255) > schematic[i].param1)
625-
continue;
626-
627-
vm->m_data[vi] = schematic[i];
628-
vm->m_data[vi].param1 = 0;
629-
630-
if (rot)
631-
vm->m_data[vi].rotateAlongYAxis(ndef, rot);
632640
}
641+
y_map++;
633642
}
634643
}
635644

@@ -690,13 +699,24 @@ bool DecoSchematic::loadSchematicFile() {
690699
}
691700

692701
u16 version = readU16(is);
693-
if (version > 2) {
702+
if (version > MTSCHEM_FILE_VER_HIGHEST_READ) {
694703
errorstream << "loadSchematicFile: unsupported schematic "
695704
"file version" << std::endl;
696705
return false;
697706
}
698707

699708
size = readV3S16(is);
709+
710+
delete []slice_probs;
711+
slice_probs = new u8[size.Y];
712+
if (version >= 3) {
713+
for (int y = 0; y != size.Y; y++)
714+
slice_probs[y] = readU8(is);
715+
} else {
716+
for (int y = 0; y != size.Y; y++)
717+
slice_probs[y] = MTSCHEM_PROB_ALWAYS;
718+
}
719+
700720
int nodecount = size.X * size.Y * size.Z;
701721

702722
u16 nidmapcount = readU16(is);
@@ -712,7 +732,7 @@ bool DecoSchematic::loadSchematicFile() {
712732
node_names->push_back(name);
713733
}
714734

715-
delete schematic;
735+
delete []schematic;
716736
schematic = new MapNode[nodecount];
717737
MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST_READ, schematic,
718738
nodecount, 2, 2, true);
@@ -735,10 +755,12 @@ bool DecoSchematic::loadSchematicFile() {
735755
736756
All values are stored in big-endian byte order.
737757
[u32] signature: 'MTSM'
738-
[u16] version: 2
758+
[u16] version: 3
739759
[u16] size X
740760
[u16] size Y
741761
[u16] size Z
762+
For each Y:
763+
[u8] slice probability value
742764
[Name-ID table] Name ID Mapping Table
743765
[u16] name-id count
744766
For each name-id mapping:
@@ -760,10 +782,13 @@ bool DecoSchematic::loadSchematicFile() {
760782
void DecoSchematic::saveSchematicFile(INodeDefManager *ndef) {
761783
std::ostringstream ss(std::ios_base::binary);
762784

763-
writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature
764-
writeU16(ss, 2); // version
765-
writeV3S16(ss, size); // schematic size
766-
785+
writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature
786+
writeU16(ss, MTSCHEM_FILE_VER_HIGHEST_WRITE); // version
787+
writeV3S16(ss, size); // schematic size
788+
789+
for (int y = 0; y != size.Y; y++) // Y slice probabilities
790+
writeU8(ss, slice_probs[y]);
791+
767792
std::vector<content_t> usednodes;
768793
int nodecount = size.X * size.Y * size.Z;
769794
build_nnlist_and_update_ids(schematic, nodecount, &usednodes);
@@ -813,6 +838,11 @@ bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2) {
813838
vm->initialEmerge(bp1, bp2);
814839

815840
size = p2 - p1 + 1;
841+
842+
slice_probs = new u8[size.Y];
843+
for (s16 y = 0; y != size.Y; y++)
844+
slice_probs[y] = MTSCHEM_PROB_ALWAYS;
845+
816846
schematic = new MapNode[size.X * size.Y * size.Z];
817847

818848
u32 i = 0;
@@ -830,8 +860,10 @@ bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2) {
830860
}
831861

832862

833-
void DecoSchematic::applyProbabilities(std::vector<std::pair<v3s16, u8> > *plist,
834-
v3s16 p0) {
863+
void DecoSchematic::applyProbabilities(v3s16 p0,
864+
std::vector<std::pair<v3s16, u8> > *plist,
865+
std::vector<std::pair<s16, u8> > *splist) {
866+
835867
for (size_t i = 0; i != plist->size(); i++) {
836868
v3s16 p = (*plist)[i].first - p0;
837869
int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X;
@@ -844,6 +876,11 @@ void DecoSchematic::applyProbabilities(std::vector<std::pair<v3s16, u8> > *plist
844876
schematic[index].setContent(CONTENT_AIR);
845877
}
846878
}
879+
880+
for (size_t i = 0; i != splist->size(); i++) {
881+
s16 y = (*splist)[i].first - p0.Y;
882+
slice_probs[y] = (*splist)[i].second;
883+
}
847884
}
848885

849886

‎src/mapgen.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ class DecoSimple : public Decoration {
256256
};
257257

258258
#define MTSCHEM_FILE_SIGNATURE 0x4d54534d // 'MTSM'
259+
#define MTSCHEM_FILE_VER_HIGHEST_READ 3
260+
#define MTSCHEM_FILE_VER_HIGHEST_WRITE 3
261+
259262
#define MTSCHEM_PROB_NEVER 0x00
260263
#define MTSCHEM_PROB_ALWAYS 0xFF
261264

@@ -271,6 +274,7 @@ class DecoSchematic : public Decoration {
271274
Rotation rotation;
272275
v3s16 size;
273276
MapNode *schematic;
277+
u8 *slice_probs;
274278

275279
DecoSchematic();
276280
~DecoSchematic();
@@ -288,7 +292,9 @@ class DecoSchematic : public Decoration {
288292

289293
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
290294
void placeStructure(Map *map, v3s16 p);
291-
void applyProbabilities(std::vector<std::pair<v3s16, u8> > *plist, v3s16 p0);
295+
void applyProbabilities(v3s16 p0,
296+
std::vector<std::pair<v3s16, u8> > *plist,
297+
std::vector<std::pair<s16, u8> > *splist);
292298
};
293299

294300
void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,

‎src/script/lua_api/l_mapgen.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
475475
v3s16 p2 = read_v3s16(L, 2);
476476
sortBoxVerticies(p1, p2);
477477

478-
std::vector<std::pair<v3s16, u8> > probability_list;
478+
std::vector<std::pair<v3s16, u8> > prob_list;
479479
if (lua_istable(L, 3)) {
480480
lua_pushnil(L);
481481
while (lua_next(L, 3)) {
@@ -485,22 +485,37 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
485485
lua_pop(L, 1);
486486

487487
u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
488-
probability_list.push_back(std::make_pair(pos, prob));
488+
prob_list.push_back(std::make_pair(pos, prob));
489489
}
490490

491491
lua_pop(L, 1);
492492
}
493493
}
494494

495-
dschem.filename = std::string(lua_tostring(L, 4));
495+
std::vector<std::pair<s16, u8> > slice_prob_list;
496+
if (lua_istable(L, 5)) {
497+
lua_pushnil(L);
498+
while (lua_next(L, 5)) {
499+
if (lua_istable(L, -1)) {
500+
s16 ypos = getintfield_default(L, -1, "ypos", 0);
501+
u8 prob = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS);
502+
slice_prob_list.push_back(std::make_pair(ypos, prob));
503+
}
504+
505+
lua_pop(L, 1);
506+
}
507+
}
508+
509+
const char *s = lua_tostring(L, 4);
510+
dschem.filename = std::string(s ? s : "");
496511

497512
if (!dschem.getSchematicFromMap(map, p1, p2)) {
498513
errorstream << "create_schematic: failed to get schematic "
499514
"from map" << std::endl;
500515
return 0;
501516
}
502-
503-
dschem.applyProbabilities(&probability_list, p1);
517+
518+
dschem.applyProbabilities(p1, &prob_list, &slice_prob_list);
504519

505520
dschem.saveSchematicFile(ndef);
506521
actionstream << "create_schematic: saved schematic file '"

0 commit comments

Comments
 (0)
Please sign in to comment.