commit initial
commit
f1720763d9
|
@ -0,0 +1,5 @@
|
|||
# SpawnBlock
|
||||
|
||||
Set traps for players.
|
||||
|
||||
Set a trap node that will activate when a player is near ; configure by right-clicking. Need `trapsetter` privilege.
|
|
@ -0,0 +1 @@
|
|||
formspeccer
|
|
@ -0,0 +1,131 @@
|
|||
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,
|
||||
})
|
Loading…
Reference in New Issue