123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- -- mob spawner
- local spawner_default = "mobs:pumba 10 15 0"
- 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
- meta:set_string("formspec", "field[text;mob_name min_light max_light amount;${command}]")
- meta:set_string("infotext", "Spawner Not Active (enter settings)")
- meta:set_string("command", spawner_default)
- end,
- on_right_click = function(pos, placer)
- local meta = minetest.get_meta(pos)
- 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
- local mob = comm[1]
- local mlig = tonumber(comm[2])
- local xlig = tonumber(comm[3])
- local num = tonumber(comm[4])
- if mob and mob ~= ""
- and num and num >= 0 and num <= 10
- and mlig and mlig >= 0 and mlig <= 15
- and xlig and xlig >= 0 and xlig <= 15 then
- 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])
- -- if amount is 0 then do nothing
- if num == 0 then
- return
- end
- local count = 0
- local ent = nil
- -- count objects of same type in area
- 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
- -- 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)]
- local lig = minetest.get_node_light(pos2)
- pos2.y = pos2.y + 0.5
- -- only if light levels are within range
- if lig and lig >= mlig and lig <= xlig then
- minetest.add_entity(pos2, mob)
- end
- end
- end
- })
|