2024-03-18 15:04:47 +01:00

104 lines
3.3 KiB
Lua

rp_mobs_spawn = {}
-- SETTINGS
-- If true, mobs may spawn naturally
local setting_spawn_mobs = minetest.settings:get_bool("mobs_spawn", true)
-- Whether to allow *natural* spawning mobs in protected areas.
-- * number 1 or non-false value = disallow spawning in protected areas
-- (the numeric value is used for backwards-compability)
local setting_spawn_protected = minetest.settings:get("mobs_spawn_protected")
if tonumber(setting_spawn_protected) == 1 or setting_spawn_protected == "false" then
-- mobs can't spawn naturally in protected areas
setting_spawn_protected = false
else
-- mobs can spawn naturally in protected areas
setting_spawn_protected = true
end
-- If true, then only peaceful mobs may spawn
local setting_peaceful_only = minetest.settings:get_bool("only_peaceful_mobs", false)
-- END OF SETTINGS
local mg_corner_1, mg_corner_2 = minetest.get_mapgen_edges()
local MIN_Y, MAX_Y = mg_corner_1.y, mg_corner_2.y
function rp_mobs_spawn.register_spawn(name, params)
local p_nodes = params.nodes
local p_neighbors = params.neighbors
local p_interval = params.interval
local p_chance = params.chance
local active_object_limit = params.active_object_limit
local active_object_limit_wider = params.active_object_limit_wider
local min_light = params.min_light or 0
local max_light = params.max_light or minetest.LIGHT_MAX
local min_height = params.min_height or MIN_Y
local max_height = params.max_height or MAX_Y
if not minetest.registered_entities[name] then
minetest.log("error", "[rp_mobs_spawn] rp_mobs_spawn.register_spawn: Mob '"..tostring(name).."' is undefined")
return
end
minetest.register_abm({
label = "Mob spawn: " .. name,
nodenames = p_nodes,
neighbors = p_neighbors,
interval = p_interval,
chance = p_chance,
action = function(pos, node, active_object_count, active_object_count_wider)
-- Do not spawn if mob spawning is disabled
if not setting_spawn_mobs then
return
end
-- Do not spawn if too many active objects in area
if active_object_count > active_object_limit then
return
end
if active_object_count_wider > active_object_limit_wider then
return
end
-- Non-peaceful mobs cannot spawn if setting restricts it
if setting_peaceful_only and rp_mobs.mobdef_has_tag(name, "peaceful") then
return
end
local spawn_pos = table.copy(pos)
-- Spawn above node
spawn_pos.y = spawn_pos.y + 1
-- Mobs cannot spawn inside protected areas if setting restricts it
if setting_spawn_protected == false and minetest.is_protected(spawn_pos, "") then
return
end
-- Check if light and height levels are ok to spawn
local light = minetest.get_node_light(spawn_pos)
if not light or light > max_light or light < min_light or spawn_pos.y > max_height or spawn_pos.y < min_height then
return
end
-- Are we spawning inside air?
-- NOTE: Support for spawning inside other nodes (like water)
-- might be desirable as well (ideally via a function argument).
local spawn_in = minetest.get_node(spawn_pos)
if spawn_in.name ~= "air" then
return
end
-- Spawn mob half block higher
spawn_pos.y = spawn_pos.y + 0.5
-- Spawn
minetest.add_entity(spawn_pos, name)
minetest.log("action", "[mobs] Spawned "..name.." at "..minetest.pos_to_string(spawn_pos, 1).." on "..node.name)
end
})
end