forked from Mirrorlandia_minetest/minetest
Implement check_offset for decorations
This commit is contained in:
parent
c91182e1b3
commit
ba80d1ce1f
@ -9564,8 +9564,13 @@ See [Decoration types]. Used by `minetest.register_decoration`.
|
|||||||
|
|
||||||
spawn_by = "default:water",
|
spawn_by = "default:water",
|
||||||
-- Node (or list of nodes) that the decoration only spawns next to.
|
-- Node (or list of nodes) that the decoration only spawns next to.
|
||||||
-- Checks the 8 neighboring nodes on the same Y, and also the ones
|
-- Checks the 8 neighboring nodes on the same height,
|
||||||
-- at Y+1, excluding both center nodes.
|
-- and also the ones at the height plus the check_offset, excluding both center nodes.
|
||||||
|
|
||||||
|
check_offset = -1,
|
||||||
|
-- Specifies the offset that spawn_by should also check
|
||||||
|
-- The default value of -1 is useful to e.g check for water next to the base node.
|
||||||
|
-- 0 disables additional checks, valid values: {-1, 0, 1}
|
||||||
|
|
||||||
num_spawn_by = 1,
|
num_spawn_by = 1,
|
||||||
-- Number of spawn_by nodes that must be surrounding the decoration
|
-- Number of spawn_by nodes that must be surrounding the decoration
|
||||||
|
@ -87,6 +87,9 @@ void Decoration::resolveNodeNames()
|
|||||||
|
|
||||||
bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
||||||
{
|
{
|
||||||
|
// Note that `p` refers to the node the decoration will be placed ontop of,
|
||||||
|
// not to the decoration itself.
|
||||||
|
|
||||||
// Check if the decoration can be placed on this node
|
// Check if the decoration can be placed on this node
|
||||||
u32 vi = vm->m_area.index(p);
|
u32 vi = vm->m_area.index(p);
|
||||||
if (!CONTAINS(c_place_on, vm->m_data[vi].getContent()))
|
if (!CONTAINS(c_place_on, vm->m_data[vi].getContent()))
|
||||||
@ -97,16 +100,7 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
int nneighs = 0;
|
int nneighs = 0;
|
||||||
static const v3s16 dirs[16] = {
|
static const v3s16 dirs[8] = {
|
||||||
v3s16( 0, 0, 1),
|
|
||||||
v3s16( 0, 0, -1),
|
|
||||||
v3s16( 1, 0, 0),
|
|
||||||
v3s16(-1, 0, 0),
|
|
||||||
v3s16( 1, 0, 1),
|
|
||||||
v3s16(-1, 0, 1),
|
|
||||||
v3s16(-1, 0, -1),
|
|
||||||
v3s16( 1, 0, -1),
|
|
||||||
|
|
||||||
v3s16( 0, 1, 1),
|
v3s16( 0, 1, 1),
|
||||||
v3s16( 0, 1, -1),
|
v3s16( 0, 1, -1),
|
||||||
v3s16( 1, 1, 0),
|
v3s16( 1, 1, 0),
|
||||||
@ -117,6 +111,7 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
|||||||
v3s16( 1, 1, -1)
|
v3s16( 1, 1, -1)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Check these 16 neighboring nodes for enough spawnby nodes
|
// Check these 16 neighboring nodes for enough spawnby nodes
|
||||||
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
||||||
u32 index = vm->m_area.index(p + dirs[i]);
|
u32 index = vm->m_area.index(p + dirs[i]);
|
||||||
@ -127,6 +122,19 @@ bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
|||||||
nneighs++;
|
nneighs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (check_offset != 0) {
|
||||||
|
const v3s16 dir_offset(0, check_offset, 0);
|
||||||
|
|
||||||
|
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
||||||
|
u32 index = vm->m_area.index(p + dirs[i] + dir_offset);
|
||||||
|
if (!vm->m_area.contains(index))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (CONTAINS(c_spawnby, vm->m_data[index].getContent()))
|
||||||
|
nneighs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (nneighs < nspawnby)
|
if (nneighs < nspawnby)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -280,6 +288,7 @@ void Decoration::cloneTo(Decoration *def) const
|
|||||||
def->flags = flags;
|
def->flags = flags;
|
||||||
def->mapseed = mapseed;
|
def->mapseed = mapseed;
|
||||||
def->c_place_on = c_place_on;
|
def->c_place_on = c_place_on;
|
||||||
|
def->check_offset = check_offset;
|
||||||
def->sidelen = sidelen;
|
def->sidelen = sidelen;
|
||||||
def->y_min = y_min;
|
def->y_min = y_min;
|
||||||
def->y_max = y_max;
|
def->y_max = y_max;
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
std::vector<content_t> c_spawnby;
|
std::vector<content_t> c_spawnby;
|
||||||
s16 nspawnby;
|
s16 nspawnby;
|
||||||
s16 place_offset_y = 0;
|
s16 place_offset_y = 0;
|
||||||
|
s16 check_offset = -1;
|
||||||
|
|
||||||
std::unordered_set<biome_t> biomes;
|
std::unordered_set<biome_t> biomes;
|
||||||
|
|
||||||
|
@ -1097,6 +1097,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
deco->y_max = getintfield_default(L, index, "y_max", 31000);
|
deco->y_max = getintfield_default(L, index, "y_max", 31000);
|
||||||
deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||||
deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
|
deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
|
||||||
|
deco->check_offset = getintfield_default(L, index, "check_offset", -1);
|
||||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||||
if (deco->sidelen <= 0) {
|
if (deco->sidelen <= 0) {
|
||||||
errorstream << "register_decoration: sidelen must be "
|
errorstream << "register_decoration: sidelen must be "
|
||||||
@ -1131,6 +1132,10 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
errorstream << "register_decoration: no spawn_by nodes defined,"
|
errorstream << "register_decoration: no spawn_by nodes defined,"
|
||||||
" but num_spawn_by specified" << std::endl;
|
" but num_spawn_by specified" << std::endl;
|
||||||
}
|
}
|
||||||
|
if (deco->check_offset < -1 || deco->check_offset > 1) {
|
||||||
|
delete deco;
|
||||||
|
luaL_error(L, "register_decoration: check_offset out of range! Allowed values: [-1, 0, 1]");
|
||||||
|
}
|
||||||
|
|
||||||
//// Handle decoration type-specific parameters
|
//// Handle decoration type-specific parameters
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user