Add structure mob respawning mechanic

this sets a metadata field "spawnblock" in the nodes mobs spawn on
and registers an abm to respan them
This commit is contained in:
cora 2022-10-29 00:18:48 +02:00
parent 1f58cfb240
commit 77bdce5cea
2 changed files with 55 additions and 25 deletions

View File

@ -3,21 +3,6 @@ local S = minetest.get_translator(modname)
local modpath = minetest.get_modpath(modname)
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local function spawn_mobs(mob,spawnon,p1,p2,pr,n)
if peaceful then return end
n = n or 1
local sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon)
if sp and #sp > 0 then
for i=1,n do
local pos = vector.offset(sp[pr:next(1,#sp)],0,1,0)
if pos then
minetest.add_entity(pos,mob)
end
end
end
end
mcl_structures.register_structure("nether_outpost",{
place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"},
fill_ratio = 0.01,
@ -58,10 +43,17 @@ mcl_structures.register_structure("nether_bridge",{
after_place = function(pos,def,pr)
local p1 = vector.offset(pos,-14,0,-14)
local p2 = vector.offset(pos,14,24,14)
spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5)
mcl_structures.spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5)
end
})
mcl_structures.register_structure_spawn({
name = "mobs_mc:witherskeleton",
y_min = mcl_vars.mg_lava_nether_max,
y_max = mcl_vars.mg_lava_nether_max + 32,
spawnon = { "mcl_blackstone:blackstone_chiseled_polished" },
})
mcl_structures.register_structure("nether_bulwark",{
place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"},
fill_ratio = 0.01,
@ -91,9 +83,9 @@ mcl_structures.register_structure("nether_bulwark",{
after_place = function(pos,def,pr)
local p1 = vector.offset(pos,-14,0,-14)
local p2 = vector.offset(pos,14,24,14)
spawn_mobs("mobs_mc:piglin",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr,5)
spawn_mobs("mobs_mc:piglin_brute",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr)
spawn_mobs("mobs_mc:hoglin",{"mcl_blackstone:nether_gold"},p1,p2,pr,4)
mcl_structures.spawn_mobs("mobs_mc:piglin",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr,5)
mcl_structures.spawn_mobs("mobs_mc:piglin_brute",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr)
mcl_structures.spawn_mobs("mobs_mc:hoglin",{"mcl_blackstone:nether_gold"},p1,p2,pr,4)
end,
loot = {
["mcl_chests:chest_small" ] ={

View File

@ -1,15 +1,12 @@
mcl_structures.registered_structures = {}
local rotations = {
"0",
"90",
"180",
"270"
}
local place_queue = {}
local disabled_structures = minetest.settings:get("mcl_disabled_structures")
if disabled_structures then disabled_structures = disabled_structures:split(",")
else disabled_structures = {} end
local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false)
local logging = minetest.settings:get_bool("mcl_logging_structures",true)
local rotations = {
@ -226,6 +223,20 @@ local function process_queue()
minetest.after(0.5,process_queue)
end
function mcl_structures.spawn_mobs(mob,spawnon,p1,p2,pr,n)
n = n or 1
local sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon)
table.shuffle(sp)
for i,node in pairs(sp) do
if not peaceful and i < n then
local pos = vector.offset(node,0,1,0)
if pos then
minetest.add_entity(pos,mob)
end
end
minetest.get_meta(node):set_string("spawnblock","yes")
end
end
function mcl_structures.place_structure(pos, def, pr, blockseed)
if not def then return end
@ -352,6 +363,33 @@ function mcl_structures.register_structure(name,def,nospawn) --nospawn means it
mcl_structures.registered_structures[name] = def
end
local structure_spawns = {}
function mcl_structures.register_structure_spawn(def)
--name,y_min,y_max,spawnon,biomes
minetest.register_abm({
label = "Spawn "..def.name,
nodenames = def.spawnon,
min_y = def.y_min or -31000,
max_y = def.y_max or 31000,
interval = 15,
chance = 3,
action = function(pos, node, active_object_count, active_object_count_wider)
local p = vector.offset(pos,0,1,0)
if active_object_count > 7 then return end
if minetest.get_node(p).name ~= "air" then return end
if minetest.get_meta(pos):get_string("spawnblock") == "" then return end
if mg_name ~= "v6" and mg_name ~= "singlenode" and def.biomes then
if table.indexof(def.biomes,minetest.get_biome_name(minetest.get_biome_data(p).biome)) == -1 then
return
end
end
local mobdef = minetest.registered_entities[def.name]
if mobdef.can_spawn and not mobdef.can_spawn(p) then return end
minetest.add_entity(p,def.name)
end,
})
end
--lbm for secondary structures (structblock included in base structure)
minetest.register_lbm({
name = "mcl_structures:struct_lbm",