Decoration API: Add flag for placement on liquid surface

Add findLiquidSurface() function to mapgen.cpp
Update lua_api.txt
This commit is contained in:
paramat 2015-10-21 08:51:59 +01:00
parent c32847838d
commit 59fa117d13
5 changed files with 38 additions and 8 deletions

@ -801,15 +801,13 @@ Decoration types
---------------- ----------------
The varying types of decorations that can be placed. The varying types of decorations that can be placed.
The default value is `simple`, and is currently the only type supported.
### `simple` ### `simple`
Creates a 1 times `H` times 1 column of a specified node (or a random node from Creates a 1 times `H` times 1 column of a specified node (or a random node from
a list, if a decoration list is specified). Can specify a certain node it must a list, if a decoration list is specified). Can specify a certain node it must
spawn next to, such as water or lava, for example. Can also generate a spawn next to, such as water or lava, for example. Can also generate a
decoration of random height between a specified lower and upper bound. decoration of random height between a specified lower and upper bound.
This type of decoration is intended for placement of grass, flowers, cacti, This type of decoration is intended for placement of grass, flowers, cacti,
papyri, and so on. papyri, waterlilies and so on.
### `schematic` ### `schematic`
Copies a box of `MapNodes` from a specified schematic file (or raw description). Copies a box of `MapNodes` from a specified schematic file (or raw description).
@ -848,8 +846,8 @@ Schematic attributes
-------------------- --------------------
See section "Flag Specifier Format". See section "Flag Specifier Format".
Currently supported flags: `place_center_x`, `place_center_y`, Currently supported flags: `place_center_x`, `place_center_y`, `place_center_z`,
`place_center_z`, `force_placement`. `force_placement`.
* `place_center_x`: Placement of this decoration is centered along the X axis. * `place_center_x`: Placement of this decoration is centered along the X axis.
* `place_center_y`: Placement of this decoration is centered along the Y axis. * `place_center_y`: Placement of this decoration is centered along the Y axis.
@ -3418,6 +3416,11 @@ Definition tables
-- ^ Minimum and maximum `y` positions these decorations can be generated at. -- ^ Minimum and maximum `y` positions these decorations can be generated at.
-- ^ This parameter refers to the `y` position of the decoration base, so -- ^ This parameter refers to the `y` position of the decoration base, so
-- the actual maximum height would be `height_max + size.Y`. -- the actual maximum height would be `height_max + size.Y`.
flags = "liquid_surface",
-- ^ Flags for all decoration types.
-- ^ "liquid_surface": Instead of placement on the highest solid surface
-- ^ in a mapchunk column, placement is on the highest liquid surface.
-- ^ Placement is disabled if solid nodes are found above the liquid surface.
----- Simple-type parameters ----- Simple-type parameters
decoration = "default:grass", decoration = "default:grass",

@ -161,6 +161,26 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
} }
// Returns -MAX_MAP_GENERATION_LIMIT if not found or if ground is found first
s16 Mapgen::findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax)
{
v3s16 em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
s16 y;
for (y = ymax; y >= ymin; y--) {
MapNode &n = vm->m_data[i];
if (ndef->get(n).walkable)
return -MAX_MAP_GENERATION_LIMIT;
else if (ndef->get(n).isLiquid())
break;
vm->m_area.add_y(em, i, -1);
}
return (y >= ymin) ? y : -MAX_MAP_GENERATION_LIMIT;
}
void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax)
{ {
if (!heightmap) if (!heightmap)

@ -166,6 +166,7 @@ public:
static u32 getBlockSeed2(v3s16 p, int seed); static u32 getBlockSeed2(v3s16 p, int seed);
s16 findGroundLevelFull(v2s16 p2d); s16 findGroundLevelFull(v2s16 p2d);
s16 findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax); s16 findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax);
s16 findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax);
void updateHeightmap(v3s16 nmin, v3s16 nmax); void updateHeightmap(v3s16 nmin, v3s16 nmax);
void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax); void updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax);

@ -30,6 +30,7 @@ FlagDesc flagdesc_deco[] = {
{"place_center_y", DECO_PLACE_CENTER_Y}, {"place_center_y", DECO_PLACE_CENTER_Y},
{"place_center_z", DECO_PLACE_CENTER_Z}, {"place_center_z", DECO_PLACE_CENTER_Z},
{"force_placement", DECO_FORCE_PLACEMENT}, {"force_placement", DECO_FORCE_PLACEMENT},
{"liquid_surface", DECO_LIQUID_SURFACE},
{NULL, 0} {NULL, 0}
}; };
@ -124,9 +125,13 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X); int mapindex = carea_size * (z - nmin.Z) + (x - nmin.X);
s16 y = mg->heightmap ? s16 y = -MAX_MAP_GENERATION_LIMIT;
mg->heightmap[mapindex] : if (flags & DECO_LIQUID_SURFACE)
mg->findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y); y = mg->findLiquidSurface(v2s16(x, z), nmin.Y, nmax.Y);
else if (mg->heightmap)
y = mg->heightmap[mapindex];
else
y = mg->findGroundLevel(v2s16(x, z), nmin.Y, nmax.Y);
if (y < nmin.Y || y > nmax.Y || if (y < nmin.Y || y > nmax.Y ||
y < y_min || y > y_max) y < y_min || y > y_max)

@ -41,6 +41,7 @@ enum DecorationType {
#define DECO_PLACE_CENTER_Z 0x04 #define DECO_PLACE_CENTER_Z 0x04
#define DECO_USE_NOISE 0x08 #define DECO_USE_NOISE 0x08
#define DECO_FORCE_PLACEMENT 0x10 #define DECO_FORCE_PLACEMENT 0x10
#define DECO_LIQUID_SURFACE 0x20
extern FlagDesc flagdesc_deco[]; extern FlagDesc flagdesc_deco[];