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, })