spawnblock/init.lua

132 lines
4.2 KiB
Lua

minetest.register_privilege("trapsetter","Allow player to set traps")
local fsn = "spawnblock:configure"
local conflabel = "Set the trap"
local buildform = function(fields)
formspeccer:clear("spawnblock:configure")
formspeccer:newform("spawnblock:configure","10,9")
for i=1,#fields do
local def = fields[i]
formspeccer:add_field(fsn,{name=def.name,label=def.label,value=def.value})
end
formspeccer:add_button(fsn,{name="submit",label=conflabel,xy="2,8",wh="5,1"},true)
return fsn
end
buildform({
{name="mobstring",label="Mob to spawn:",value=""},
{name="playerradius",label="How close can player get before triggering",value=5},
{name="spawnradius",label="Spawn radius",value=10},
{name="maxobjects",label="Max number of things in spawn range",value=1},
})
minetest.register_node("spawnblock:cobble",{
groups = {unbreakable = 1,},
description = "Cobble spawn trap",
tiles = {"default_cobble.png"},
after_place_node = function(pos,player)
local meta = minetest.get_meta(pos)
meta:set_string("formspec",formspeccer:to_string(fsn))
end,
on_receive_fields = function(pos,formname,fields,player)
--minetest.chat_send_all(dump(fields))
if fields.submit ~= conflabel
-- and not (fields.quit == "true" and fields.submit == nil)
then
return
end
if not minetest.check_player_privs(player:get_player_name(), {trapsetter=true}) then
minetest.chat_send_player(player:get_player_name(),"I cannot let you do that "..player:get_player_name())
return
end
local meta = minetest.get_meta(pos)
meta:set_string("mobstring",fields.mobstring)
meta:set_int("maxobjects",tonumber(fields.maxobjects) )
meta:set_int("playerradius",tonumber(fields.playerradius) )
meta:set_int("spawnradius",tonumber(fields.spawnradius) )
buildform({
{name="mobstring",label="Mob to spawn:",value=fields.mobstring},
{name="playerradius",label="How close can player get before triggering",value=fields.playerradius},
{name="spawnradius",label="Spawn radius",value=fields.spawnradius},
{name="maxobjects",label="Max number of things in spawn range",value=fields.maxobjects},
})
meta:set_string("formspec",formspeccer:to_string(fsn))
minetest.chat_send_player(player:get_player_name(),"Trap set!")
end,
})
local count_nearby_mobs = function(pos,radius)
-- check if there are entities around already
local objcount = 0
for _,obj in pairs(minetest.get_objects_inside_radius(pos ,radius)) do
if not obj:is_player() then
objcount = objcount+1
end
end
return objcount
end
local spawn_mob = function(pos,mobname,range)
-- spawn a mob within spawnrange nodes of position pos
local mobdef = minetest.registered_entities[mobname]
if mobdef == nil then return end
local spawninnode = {"air"}
if mobdef.fly_in then spawninnode = {mobdef.fly_in} end
local candidatenodes = minetest.find_nodes_in_area(
{x = pos.x -range, y = pos.y+3, z = pos.z -range},
{x = pos.x +range, y = pos.y+5, z = pos.z +range},
spawninnode
)
local newpos = candidatenodes[ math.random(1,#candidatenodes) ]
minetest.add_entity(newpos,mobname)
end
minetest.register_abm({
nodenames = {"spawnblock:cobble"},
neighbors = nil,
interval = 1,
chance = 1,
action = function(pos)
local fields = {}
local meta = minetest.get_meta(pos)
fields.mobstring = meta:get_string("mobstring")
fields.playerradius = meta:get_int("playerradius")
fields.spawnradius = meta:get_int("spawnradius")
fields.maxobjects = meta:get_int("maxobjects")
if fields.mobstring == nil or fields.mobstring == "" then return end
for _,obj in pairs(minetest.get_objects_inside_radius(pos ,fields.playerradius)) do
if obj:is_player() then
if count_nearby_mobs(pos,math.ceil(fields.spawnradius)*1.4) < fields.maxobjects then
if fields.mobstring ~= nil then
local mobname = fields.mobstring
local colonidx = mobname:find(':')
if not colonidx then return end
local mobnicename = mobname:sub(colonidx+1,#mobname )
minetest.debug("Player "..obj:get_player_name().." triggered spawn trap at "..minetest.pos_to_string(pos))
minetest.chat_send_player(obj:get_player_name(),"A wild "..mobnicename.." appeared!")
spawn_mob(pos,mobname,fields.spawnradius)
else
minetest.debug("Failed to determine a mob for "..mobname)
end
else
end
end
end
end,
})