b89f2b7d86
Apparently on top of dungeons regenerating over top of themselves, caves can also carve into dungeons, and this may cause issues with dungeon loot, where the loot nodes are removed (but w/o the destructor) so that floating fake visinv entities are sometimes left floating in place. Instead, give the engine time to finish initializing dungeons, and then use only the ABM (sigh, it's always only ABMs that are actually eventually reliable after all) to do delayed initialization. This kind of sucks if the player starts out in a dungeon in a new map, but the old "fast" methods weren't fast enough to prevent a flash of uninitialized dungeon anyway, so we just have to hope that the dungeons will get initialized while on the map horizon before the player gets close enough for it to matter. Get rid of the different dungeon cobble now to mitigate this, also since we no longer need it to debug uninitialized dungeons.
88 lines
2.5 KiB
Lua
88 lines
2.5 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ipairs, math, minetest, nodecore, table
|
|
= ipairs, math, minetest, nodecore, table
|
|
local math_floor, table_insert
|
|
= math.floor, table.insert
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
local cobble = modname .. ":cobble"
|
|
|
|
------------------------------------------------------------------------
|
|
-- REGISTER PRIORITIZED DUNGEON MODIFIERS
|
|
|
|
local dungens = {}
|
|
nodecore.registered_dungeongens = dungens
|
|
|
|
local counters = {}
|
|
function nodecore.register_dungeongen(def)
|
|
local label = def.label
|
|
if not label then
|
|
label = minetest.get_current_modname()
|
|
local i = (counters[label] or 0) + 1
|
|
counters[label] = i
|
|
label = label .. ":" .. i
|
|
end
|
|
|
|
local prio = def.priority or 0
|
|
def.priority = prio
|
|
local min = 1
|
|
local max = #dungens + 1
|
|
while max > min do
|
|
local try = math_floor((min + max) / 2)
|
|
local oldp = dungens[try].priority
|
|
if (prio < oldp) or (prio == oldp and label > dungens[try].label) then
|
|
min = try + 1
|
|
else
|
|
max = try
|
|
end
|
|
end
|
|
table_insert(dungens, min, def)
|
|
end
|
|
|
|
local function dungeonprocess(pos, node)
|
|
for _, def in ipairs(dungens) do
|
|
if def.enabled ~= false then
|
|
def.func(pos, node)
|
|
if minetest.get_node(pos).name ~= node.name then return end
|
|
end
|
|
end
|
|
return minetest.set_node(pos, {name = cobble})
|
|
end
|
|
|
|
------------------------------------------------------------------------
|
|
-- REGISTER DUNGEON NODES, BIOME DEFAULTS
|
|
|
|
local function regdungeon(name)
|
|
local def = nodecore.underride({groups = {dungeon_mapgen = 1}},
|
|
minetest.registered_nodes[cobble])
|
|
def.description = "Dungeon Cobble"
|
|
def.mapgen = nil
|
|
return minetest.register_node(modname .. ":" .. name, def)
|
|
end
|
|
|
|
regdungeon("dungeon_cobble")
|
|
regdungeon("dungeon_cobble_alt")
|
|
regdungeon("dungeon_cobble_stair")
|
|
|
|
local oldbiome = minetest.register_biome
|
|
function minetest.register_biome(def, ...)
|
|
if not def then return oldbiome(def, ...) end
|
|
def.node_dungeon = def.node_dungeon or modname .. ":dungeon_cobble"
|
|
def.node_dungeon_alt = def.node_dungeon_alt or modname .. ":dungeon_cobble_alt"
|
|
def.node_dungeon_stair = def.node_dungeon_stair or modname .. ":dungeon_cobble_stair"
|
|
return oldbiome(def, ...)
|
|
end
|
|
|
|
------------------------------------------------------------------------
|
|
-- DUNGEON MODIFIER HOOKS
|
|
|
|
minetest.register_abm({
|
|
label = modname .. " dungeon cleanup",
|
|
interval = 1,
|
|
chance = 1,
|
|
nodenames = {"group:dungeon_mapgen"},
|
|
action = dungeonprocess
|
|
})
|