104 lines
3.3 KiB
Lua
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
|