@@ -482,16 +482,18 @@ std::string DecoSimple::getName() {
482482
483483
484484DecoSchematic::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
492493DecoSchematic::~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() {
760782void 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
0 commit comments