Aaron Suen b89f2b7d86 Disable fast dungeon initialization methods
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.
2021-03-05 21:02:36 -05:00

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
})