From d3436bafab3a635ff93e7a8e22e44d6315e474a6 Mon Sep 17 00:00:00 2001 From: MoNTE48 Date: Sun, 15 Dec 2019 22:43:28 +0100 Subject: [PATCH] Backport 'Add 'place_offset_y' placement parameter' form MT5 --- doc/lua_api.txt | 17 +++++++++++++++++ src/mg_decoration.cpp | 25 +++++++++++++++++++------ src/mg_decoration.h | 1 + src/script/lua_api/l_mapgen.cpp | 1 + 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 1e11f265..f0b617ca 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4662,6 +4662,14 @@ The Biome API is still in an experimental phase and subject to change. param2 = 0, -- ^ Param2 value of placed decoration node. + place_offset_y = 0, + -- Y offset of the decoration base node relative to the standard base + -- node position. + -- Can be positive or negative. Default is 0. + -- Effect is inverted for "all_ceilings" decorations. + -- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer + -- to the 'place_on' node. + ----- Schematic-type parameters schematic = "foobar.mts", -- ^ If schematic is a string, it is the filepath relative to the current working directory of the @@ -4692,6 +4700,15 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Rotation can be "0", "90", "180", "270", or "random". } + place_offset_y = 0, + -- If the flag 'place_center_y' is set this parameter is ignored. + -- Y offset of the schematic base node layer relative to the 'place_on' + -- node. + -- Can be positive or negative. Default is 0. + -- Effect is inverted for "all_ceilings" decorations. + -- Ignored by 'y_min', 'y_max' and 'spawn_by' checks, which always refer + -- to the 'place_on' node. + ### Chat command definition (`register_chatcommand`) { diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp index 71335b00..a4bf35a7 100644 --- a/src/mg_decoration.cpp +++ b/src/mg_decoration.cpp @@ -297,6 +297,10 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p) // Don't bother if there aren't any decorations to place if (c_decos.size() == 0) return 0; + + // Check for a negative place_offset_y causing placement below the voxelmanip + if (p.Y + 1 + place_offset_y < vm->m_area.MinEdge.Y) + return 0; if (!canPlaceDecoration(vm, p)) return 0; @@ -310,6 +314,8 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p) v3s16 em = vm->m_area.getExtent(); u32 vi = vm->m_area.index(p); + vm->m_area.add_y(em, vi, place_offset_y); + for (int i = 0; i < height; i++) { vm->m_area.add_y(em, vi, 1); @@ -327,7 +333,8 @@ size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p) int DecoSimple::getHeight() { - return (deco_height_max > 0) ? deco_height_max : deco_height; + return ((deco_height_max > 0) ? deco_height_max : deco_height) + + place_offset_y; } @@ -352,10 +359,16 @@ 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; @@ -371,8 +384,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 7eaf0665..d4ff938f 100644 --- a/src/mg_decoration.h +++ b/src/mg_decoration.h @@ -86,6 +86,7 @@ public: NoiseParams np; std::vector c_spawnby; s16 nspawnby; + s16 place_offset_y = 0; UNORDERED_SET biomes; //std::list cutoffs; diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index 254b90d6..b877d043 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -911,6 +911,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L) deco->y_min = getintfield_default(L, index, "y_min", -31000); deco->y_max = getintfield_default(L, index, "y_max", 31000); deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); + deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be "