From 77bdce5cea2044f65961b97b3149af7f2dca318c Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 29 Oct 2022 00:18:48 +0200 Subject: [PATCH] Add structure mob respawning mechanic this sets a metadata field "spawnblock" in the nodes mobs spawn on and registers an abm to respan them --- mods/MAPGEN/mcl_nether_fortresses/init.lua | 30 +++++-------- mods/MAPGEN/mcl_structures/api.lua | 50 +++++++++++++++++++--- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/mods/MAPGEN/mcl_nether_fortresses/init.lua b/mods/MAPGEN/mcl_nether_fortresses/init.lua index 40d6d55d7..4067398ad 100644 --- a/mods/MAPGEN/mcl_nether_fortresses/init.lua +++ b/mods/MAPGEN/mcl_nether_fortresses/init.lua @@ -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" ] ={ diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua index c11d62203..05522ca44 100644 --- a/mods/MAPGEN/mcl_structures/api.lua +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -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",