summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt7
-rw-r--r--src/mg_decoration.cpp81
-rw-r--r--src/mg_decoration.h20
-rw-r--r--src/script/lua_api/l_mapgen.cpp2
4 files changed, 27 insertions, 83 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index ec5a8ff32..ef62f1356 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -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`)
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index db640626d..1872e32e7 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -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;
}
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index fd6e89e79..01e063ca2 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -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);
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index c2b256228..7757ea80c 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -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))