Schematic decorations: Add 'place_offset_y' placement parameter
authorparamat <paramat@users.noreply.github.com>
Wed, 6 Sep 2017 21:20:09 +0000 (22:20 +0100)
committerparamat <mat.gregory@virginmedia.com>
Sun, 10 Sep 2017 00:31:30 +0000 (01:31 +0100)
For precise control of schematic vertical position relative to the
'place_on' node.
Avoids workarounds that add empty nodes to a schematic and therefore
reduce performance.

Also remove long-unused decoration cutoff code.

doc/lua_api.txt
src/mg_decoration.cpp
src/mg_decoration.h
src/script/lua_api/l_mapgen.cpp

index ec5a8ff3238d6539a63ea457e2dc413e65f192c9..ef62f1356845cf64aa37cd85f1d51103f8690238 100644 (file)
@@ -4743,6 +4743,13 @@ The Biome API is still in an experimental phase and subject to change.
     --  ^ Flags for schematic decorations.  See 'Schematic attributes'.
         rotation = "90" -- rotate schematic 90 degrees on placement
     --  ^ Rotation can be "0", "90", "180", "270", or "random".
+        place_offset_y = 0,
+    --  ^ Y offset of the schematic base node layer relative to the 'place_on'
+    --  ^ node.
+    --  ^ Can be positive or negative. Default is 0.
+    --  ^ If the flag 'place_center_y' is set this parameter is ignored.
+    --  ^ If absent or 0 the schematic base node layer will be placed level
+    --  ^ with the 'place_on' node.
     }
 
 ### Chat command definition (`register_chatcommand`)
index db640626d5d01c74dd788bf3b45132547058d24c..1872e32e7fb79fb7a4bad5f01994ba651f5c6ead 100644 (file)
@@ -67,6 +67,7 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
 
 ///////////////////////////////////////////////////////////////////////////////
 
+
 void Decoration::resolveNodeNames()
 {
        getIdsFromNrBacklog(&c_place_on);
@@ -192,15 +193,8 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed,
                        if (y < y_min_disp || y > y_max_disp || y < nmin.Y || y > nmax.Y)
                                continue;
 
-                       if (y + getHeight() > mg->vm->m_area.MaxEdge.Y) {
+                       if (y + getHeight() > mg->vm->m_area.MaxEdge.Y)
                                continue;
-#if 0
-                               printf("Decoration at (%d %d %d) cut off\n", x, y, z);
-                               //add to queue
-                               MutexAutoLock cutofflock(cutoff_mutex);
-                               cutoffs.push_back(CutoffData(x, y, z, height));
-#endif
-                       }
 
                        if (mg->biomemap && !biomes.empty()) {
                                std::unordered_set<u8>::const_iterator iter =
@@ -219,60 +213,6 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed,
 }
 
 
-#if 0
-void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
-{
-       PcgRandom pr(blockseed + 53);
-       std::vector<CutoffData> handled_cutoffs;
-
-       // Copy over the cutoffs we're interested in so we don't needlessly hold a lock
-       {
-               MutexAutoLock cutofflock(cutoff_mutex);
-               for (std::list<CutoffData>::iterator i = cutoffs.begin();
-                       i != cutoffs.end(); ++i) {
-                       CutoffData cutoff = *i;
-                       v3s16 p    = cutoff.p;
-                       s16 height = cutoff.height;
-                       if (p.X < nmin.X || p.X > nmax.X ||
-                               p.Z < nmin.Z || p.Z > nmax.Z)
-                               continue;
-                       if (p.Y + height < nmin.Y || p.Y > nmax.Y)
-                               continue;
-
-                       handled_cutoffs.push_back(cutoff);
-               }
-       }
-
-       // Generate the cutoffs
-       for (size_t i = 0; i != handled_cutoffs.size(); i++) {
-               v3s16 p    = handled_cutoffs[i].p;
-               s16 height = handled_cutoffs[i].height;
-
-               if (p.Y + height > nmax.Y) {
-                       //printf("Decoration at (%d %d %d) cut off again!\n", p.X, p.Y, p.Z);
-                       cuttoffs.push_back(v3s16(p.X, p.Y, p.Z));
-               }
-
-               generate(mg, &pr, nmax.Y, nmin.Y - p.Y, v3s16(p.X, nmin.Y, p.Z));
-       }
-
-       // Remove cutoffs that were handled from the cutoff list
-       {
-               MutexAutoLock cutofflock(cutoff_mutex);
-               for (std::list<CutoffData>::iterator i = cutoffs.begin();
-                       i != cutoffs.end(); ++i) {
-
-                       for (size_t j = 0; j != handled_cutoffs.size(); j++) {
-                               CutoffData coff = *i;
-                               if (coff.p == handled_cutoffs[j].p)
-                                       i = cutoffs.erase(i);
-                       }
-               }
-       }
-}
-#endif
-
-
 ///////////////////////////////////////////////////////////////////////////////
 
 
@@ -324,6 +264,7 @@ int DecoSimple::getHeight()
 
 ///////////////////////////////////////////////////////////////////////////////
 
+
 size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
 {
        // Schematic could have been unloaded but not the decoration
@@ -336,11 +277,17 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
 
        if (flags & DECO_PLACE_CENTER_X)
                p.X -= (schematic->size.X - 1) / 2;
-       if (flags & DECO_PLACE_CENTER_Y)
-               p.Y -= (schematic->size.Y - 1) / 2;
        if (flags & DECO_PLACE_CENTER_Z)
                p.Z -= (schematic->size.Z - 1) / 2;
 
+       if (flags & DECO_PLACE_CENTER_Y)
+               p.Y -= (schematic->size.Y - 1) / 2;
+       else
+               p.Y += place_offset_y;
+       // Check shifted schematic base is in voxelmanip
+       if (p.Y < vm->m_area.MinEdge.Y)
+               return 0;
+
        Rotation rot = (rotation == ROTATE_RAND) ?
                (Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
 
@@ -355,8 +302,8 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
 int DecoSchematic::getHeight()
 {
        // Account for a schematic being sunk into the ground by flag.
-       // When placed normally account for how a schematic is placed
-       // sunk 1 node into the ground.
+       // When placed normally account for how a schematic is by default placed
+       // sunk 1 node into the ground or is vertically shifted by 'y_offset'.
        return (flags & DECO_PLACE_CENTER_Y) ?
-               (schematic->size.Y - 1) / 2 : schematic->size.Y - 1;
+               (schematic->size.Y - 1) / 2 : schematic->size.Y - 1 + place_offset_y;
 }
index fd6e89e798bb94d43204ef139454f6c4b07ed479..01e063ca27bc976a18129718e5761948b6ea3bb6 100644 (file)
@@ -46,21 +46,6 @@ enum DecorationType {
 extern FlagDesc flagdesc_deco[];
 
 
-#if 0
-struct CutoffData {
-       VoxelArea a;
-       Decoration *deco;
-       //v3s16 p;
-       //v3s16 size;
-       //s16 height;
-
-       CutoffData(s16 x, s16 y, s16 z, s16 h) {
-               p = v3s16(x, y, z);
-               height = h;
-       }
-};
-#endif
-
 class Decoration : public ObjDef, public NodeResolver {
 public:
        Decoration() = default;
@@ -71,7 +56,6 @@ public:
        bool canPlaceDecoration(MMVManip *vm, v3s16 p);
        size_t placeDeco(Mapgen *mg, u32 blockseed,
                v3s16 nmin, v3s16 nmax, s16 deco_zero_level);
-       //size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
 
        virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p) = 0;
        virtual int getHeight() = 0;
@@ -90,6 +74,7 @@ public:
        std::unordered_set<u8> biomes;
 };
 
+
 class DecoSimple : public Decoration {
 public:
        virtual void resolveNodeNames();
@@ -102,6 +87,7 @@ public:
        u8 deco_param2;
 };
 
+
 class DecoSchematic : public Decoration {
 public:
        DecoSchematic() = default;
@@ -110,6 +96,7 @@ public:
        virtual int getHeight();
 
        Rotation rotation;
+       s16 place_offset_y = 0;
        Schematic *schematic = nullptr;
 };
 
@@ -121,6 +108,7 @@ public:
 };
 */
 
+
 class DecorationManager : public ObjDefManager {
 public:
        DecorationManager(IGameDef *gamedef);
index c2b256228e8cef60f53193c26c31d8316db319ec..7757ea80c748588ea37d79c5574269d296d3024b 100644 (file)
@@ -1018,6 +1018,8 @@ bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic
        deco->rotation = (Rotation)getenumfield(L, index, "rotation",
                ModApiMapgen::es_Rotation, ROTATE_0);
 
+       deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
+
        StringMap replace_names;
        lua_getfield(L, index, "replacements");
        if (lua_istable(L, -1))