132 lines
4.2 KiB
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,
|
|
})
|