1
0
mirror of https://github.com/sys4-fr/server-nalc.git synced 2024-12-27 11:10:37 +01:00
server-nalc/mods/mobs/spawner.lua

158 lines
3.5 KiB
Lua
Raw Normal View History

2016-02-01 12:45:12 +01:00
-- mob spawner
2016-02-03 04:22:41 +01:00
local spawner_default = "mobs:pig 10 15 0 0"
2016-02-01 12:45:12 +01:00
minetest.register_node("mobs:spawner", {
tiles = {"mob_spawner.png"},
drawtype = "glasslike",
paramtype = "light",
walkable = true,
description = "Mob Spawner",
groups = {cracky = 1},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
-- text entry formspec
2016-02-03 04:22:41 +01:00
meta:set_string("formspec", "field[text;Mob MinLight MaxLight Amount PlayerDist;${command}]")
2016-02-01 12:45:12 +01:00
meta:set_string("infotext", "Spawner Not Active (enter settings)")
meta:set_string("command", spawner_default)
end,
on_right_click = function(pos, placer)
2016-02-03 04:22:41 +01:00
if minetest.is_protected(pos, placer:get_player_name()) then
return
end
-- local meta = minetest.get_meta(pos)
2016-02-01 12:45:12 +01:00
end,
on_receive_fields = function(pos, formname, fields, sender)
if not fields.text or fields.text == "" then
return
end
local meta = minetest.get_meta(pos)
local comm = fields.text:split(" ")
local name = sender:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return
end
2016-02-03 04:22:41 +01:00
local mob = comm[1] -- mob to spawn
local mlig = tonumber(comm[2]) -- min light
local xlig = tonumber(comm[3]) -- max light
local num = tonumber(comm[4]) -- total mobs in area
local pla = tonumber(comm[5])-- player distance (0 to disable)
2016-02-01 12:45:12 +01:00
2016-02-03 04:22:41 +01:00
if mob and mob ~= "" and mobs.spawning_mobs[mob] == true
2016-02-01 12:45:12 +01:00
and num and num >= 0 and num <= 10
and mlig and mlig >= 0 and mlig <= 15
2016-02-03 04:22:41 +01:00
and xlig and xlig >= 0 and xlig <= 15
and pla and pla >=0 and pla <= 20 then
2016-02-01 12:45:12 +01:00
meta:set_string("command", fields.text)
meta:set_string("infotext", "Spawner Active (" .. mob .. ")")
else
minetest.chat_send_player(name, "Mob Spawner settings failed!")
end
end,
})
-- spawner abm
minetest.register_abm({
nodenames = {"mobs:spawner"},
interval = 10,
chance = 4,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
-- check objects inside 9x9 area around spawner
local objs = minetest.get_objects_inside_radius(pos, 9)
-- get meta and command
local meta = minetest.get_meta(pos)
local comm = meta:get_string("command"):split(" ")
-- get settings from command
local mob = comm[1]
local mlig = tonumber(comm[2])
local xlig = tonumber(comm[3])
local num = tonumber(comm[4])
2016-02-03 04:22:41 +01:00
local pla = tonumber(comm[5]) or 0
2016-02-01 12:45:12 +01:00
-- if amount is 0 then do nothing
if num == 0 then
return
end
local count = 0
local ent = nil
2016-02-03 04:22:41 +01:00
-- count mob objects of same type in area
2016-02-01 12:45:12 +01:00
for k, obj in pairs(objs) do
ent = obj:get_luaentity()
if ent and ent.name == mob then
count = count + 1
end
end
-- is there too many of same type?
if count >= num then
return
end
2016-02-03 04:22:41 +01:00
-- spawn mob if player detected and in range
if pla > 0 then
local in_range = 0
local objs = minetest.get_objects_inside_radius(pos, pla)
for _,oir in pairs(objs) do
if oir:is_player() then
in_range = 1
break
end
end
-- player not found
if in_range == 0 then
return
end
end
2016-02-01 12:45:12 +01:00
-- find air blocks within 5 nodes of spawner
local air = minetest.find_nodes_in_area(
{x = pos.x - 5, y = pos.y, z = pos.z - 5},
{x = pos.x + 5, y = pos.y, z = pos.z + 5},
{"air"})
-- spawn in random air block
if air and #air > 0 then
local pos2 = air[math.random(#air)]
2016-02-03 04:22:41 +01:00
local lig = minetest.get_node_light(pos2) or 0
2016-02-01 12:45:12 +01:00
pos2.y = pos2.y + 0.5
-- only if light levels are within range
2016-02-03 04:22:41 +01:00
if lig >= mlig and lig <= xlig then
2016-02-01 12:45:12 +01:00
minetest.add_entity(pos2, mob)
end
end
end
})