From f1720763d947788739676497cb83439301986d16 Mon Sep 17 00:00:00 2001 From: Axinite Date: Mon, 12 Mar 2018 23:51:48 +0000 Subject: [PATCH] commit initial --- README.md | 5 ++ depends.txt | 1 + init.lua | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mod.conf | 1 + 4 files changed, 138 insertions(+) create mode 100644 README.md create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 mod.conf diff --git a/README.md b/README.md new file mode 100644 index 0000000..c9fffaf --- /dev/null +++ b/README.md @@ -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. diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..3a63969 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +formspeccer diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..e56696f --- /dev/null +++ b/init.lua @@ -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, +}) diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..8c4eebd --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = spawnblock