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,
|
object_guids = true,
|
||||||
on_timer_four_args = true,
|
on_timer_four_args = true,
|
||||||
particlespawner_exclude_player = true,
|
particlespawner_exclude_player = true,
|
||||||
|
generate_decorations_biomes = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -5847,6 +5847,8 @@ Utilities
|
||||||
on_timer_four_args = true,
|
on_timer_four_args = true,
|
||||||
-- `ParticleSpawner` definition supports `exclude_player` field (5.14.0)
|
-- `ParticleSpawner` definition supports `exclude_player` field (5.14.0)
|
||||||
particlespawner_exclude_player = true,
|
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
|
* Generate all registered ores within the VoxelManip `vm` and in the area
|
||||||
from `pos1` to `pos2`.
|
from `pos1` to `pos2`.
|
||||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
* `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
|
* Generate all registered decorations within the VoxelManip `vm` and in the
|
||||||
area from `pos1` to `pos2`.
|
area from `pos1` to `pos2`.
|
||||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
* `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])`
|
* `core.clear_objects([options])`
|
||||||
* Clear all objects in the environment
|
* Clear all objects in the environment
|
||||||
* Takes an optional table as an argument with the field `mode`.
|
* 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)
|
int ModApiMapgen::l_generate_decorations(lua_State *L)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
@ -1621,26 +1621,56 @@ int ModApiMapgen::l_generate_decorations(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DecorationManager *decomgr;
|
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;
|
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;
|
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;
|
const v3s16 default_pmin = vm->m_area.MinEdge + MAP_BLOCKSIZE,
|
||||||
// Intentionally truncates to s32, see Mapgen::Mapgen()
|
default_pmax = vm->m_area.MaxEdge - MAP_BLOCKSIZE;
|
||||||
mg.seed = (s32)emerge->mgparams->seed;
|
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : default_pmin;
|
||||||
mg.vm = checkObject<LuaVoxelManip>(L, 1)->vm;
|
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : default_pmax;
|
||||||
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;
|
|
||||||
sortBoxVerticies(pmin, 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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue