mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-30 19:22:14 +00:00
Extend core.generate_decorations to generate biomes respecting the biome map (#16397)
Large structures which are generated in on_generated callbacks independently by Lua cannot influence decoration placement. This change enables such a callback to assume responsibility for generating decorations itself, presumably after structures are placed, by disabling decorations in mg_flags and executing core.generate_decorations. --------- Co-authored-by: Po Lu <luangruo@yahoo.com>
This commit is contained in:
parent
29490cb0f7
commit
fc6bef7de6
3 changed files with 52 additions and 15 deletions
|
@ -50,6 +50,7 @@ core.features = {
|
|||
object_guids = true,
|
||||
on_timer_four_args = true,
|
||||
particlespawner_exclude_player = true,
|
||||
generate_decorations_biomes = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
|
|
@ -5847,6 +5847,8 @@ Utilities
|
|||
on_timer_four_args = true,
|
||||
-- `ParticleSpawner` definition supports `exclude_player` field (5.14.0)
|
||||
particlespawner_exclude_player = true,
|
||||
-- core.generate_decorations() supports `use_mapgen_biomes` parameter (5.14.0)
|
||||
generate_decorations_biomes = true,
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -6739,10 +6741,14 @@ Environment access
|
|||
* Generate all registered ores within the VoxelManip `vm` and in the area
|
||||
from `pos1` to `pos2`.
|
||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
||||
* `core.generate_decorations(vm[, pos1, pos2])`
|
||||
* `core.generate_decorations(vm[, pos1, pos2, [use_mapgen_biomes]])`
|
||||
* Generate all registered decorations within the VoxelManip `vm` and in the
|
||||
area from `pos1` to `pos2`.
|
||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
||||
* `use_mapgen_biomes` (optional boolean). For use in on_generated callbacks only.
|
||||
If set to true, decorations are placed in respect to the biome map of the current chunk.
|
||||
`pos1` and `pos2` must match the positions of the current chunk, or an error will be raised.
|
||||
default: `false`
|
||||
* `core.clear_objects([options])`
|
||||
* Clear all objects in the environment
|
||||
* Takes an optional table as an argument with the field `mode`.
|
||||
|
|
|
@ -1611,7 +1611,7 @@ int ModApiMapgen::l_generate_ores(lua_State *L)
|
|||
}
|
||||
|
||||
|
||||
// generate_decorations(vm, p1, p2)
|
||||
// generate_decorations(vm, p1, p2, use_mapgen_biomes)
|
||||
int ModApiMapgen::l_generate_decorations(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
@ -1621,26 +1621,56 @@ int ModApiMapgen::l_generate_decorations(lua_State *L)
|
|||
return 0;
|
||||
|
||||
DecorationManager *decomgr;
|
||||
if (auto mg = getMapgen(L))
|
||||
Mapgen mg, *mgp = nullptr;
|
||||
bool use_mapgen_biomes = readParam<bool>(L, 4, false);
|
||||
MMVManip *oldvm = nullptr, *vm = checkObject<LuaVoxelManip>(L, 1)->vm;
|
||||
if (auto mg = getMapgen(L)) {
|
||||
decomgr = mg->m_emerge->decomgr;
|
||||
else
|
||||
if (use_mapgen_biomes) {
|
||||
mgp = mg;
|
||||
oldvm = mgp->vm;
|
||||
if (!oldvm) {
|
||||
goto no_vm;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (use_mapgen_biomes) {
|
||||
no_vm:
|
||||
throw LuaError("use_mapgen_biomes specified outside a "
|
||||
"map generation context");
|
||||
}
|
||||
decomgr = emerge->decomgr;
|
||||
}
|
||||
if (!mgp) {
|
||||
mgp = &mg;
|
||||
// Intentionally truncates to s32, see Mapgen::Mapgen()
|
||||
mg.seed = (s32)emerge->mgparams->seed;
|
||||
mg.ndef = emerge->ndef;
|
||||
}
|
||||
|
||||
Mapgen mg;
|
||||
// Intentionally truncates to s32, see Mapgen::Mapgen()
|
||||
mg.seed = (s32)emerge->mgparams->seed;
|
||||
mg.vm = checkObject<LuaVoxelManip>(L, 1)->vm;
|
||||
mg.ndef = emerge->ndef;
|
||||
|
||||
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) :
|
||||
mg.vm->m_area.MinEdge + v3s16(1,1,1) * MAP_BLOCKSIZE;
|
||||
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) :
|
||||
mg.vm->m_area.MaxEdge - v3s16(1,1,1) * MAP_BLOCKSIZE;
|
||||
const v3s16 default_pmin = vm->m_area.MinEdge + MAP_BLOCKSIZE,
|
||||
default_pmax = vm->m_area.MaxEdge - MAP_BLOCKSIZE;
|
||||
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : default_pmin;
|
||||
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : default_pmax;
|
||||
sortBoxVerticies(pmin, pmax);
|
||||
if (use_mapgen_biomes) {
|
||||
assert(oldvm);
|
||||
const v3s16 required_pmin = oldvm->m_area.MinEdge + MAP_BLOCKSIZE,
|
||||
required_pmax = oldvm->m_area.MaxEdge - MAP_BLOCKSIZE;
|
||||
if (pmin != required_pmin || pmax != required_pmax)
|
||||
throw LuaError("use_mapgen_biomes requires extents matching chunk area");
|
||||
}
|
||||
|
||||
u32 blockseed = Mapgen::getBlockSeed(pmin, mg.seed);
|
||||
|
||||
decomgr->placeAllDecos(&mg, blockseed, pmin, pmax);
|
||||
mgp->vm = vm;
|
||||
try {
|
||||
decomgr->placeAllDecos(mgp, blockseed, pmin, pmax);
|
||||
} catch (...) {
|
||||
mgp->vm = oldvm;
|
||||
throw;
|
||||
}
|
||||
mgp->vm = oldvm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue