tidy code, add protected spawn feature

master
TenPlus1 2016-11-02 16:54:19 +00:00
parent fdbb241518
commit 9c5fd8b6ef
4 changed files with 101 additions and 54 deletions

View File

@ -3,7 +3,7 @@ Protector Redo mod [protect]
Protector redo for minetest is a mod that protects a players builds by placing
a block that stops other players from digging or placing blocks in that area.
based on glomie's mod, remade by Zeg9 and reworked by TenPlus1.
based on glomie's mod, remade by Zeg9 and rewritten by TenPlus1.
https://forum.minetest.net/viewtopic.php?f=11&t=9376
@ -39,6 +39,8 @@ Change log:
added support for "protection_bypass" privelage.
1.8 - Added 'protector_flip' setting to stop players using lag to grief into
another players house, it flips them around to stop them digging.
1.9 - Renamed 'protector_pvp_spawn' setting to 'protector_spawn' which protects
an area around static spawnpoint. (note: previous name can still be used)
Usage: (requires server privelage)
@ -66,8 +68,8 @@ protector_radius = 5
protector_pvp = true
- true or false this setting disabled pvp inside of protected areas for all players apart from those listed on the protector node.
protector_pvp_spawn = 10
- Sets an area 10 nodes around spawn where pvp is disabled completely.
protector_spawn = 10
- Sets an area 10 nodes around static spawnpoint that is protected.
protector_drop = true
- When true players who dig inside a protected area will automatically drop tools to stop them going any further.

View File

@ -1,7 +1,7 @@
-- Since the doors mod has changed in the latest daily builds I have taken the
-- WTFPL licenced code from the old doors mod and included an edited version
-- of it within this mod for local use.
-- within this mod for local use.
local S = protector.intllib

138
init.lua
View File

@ -1,12 +1,20 @@
-- older privelage for admins to rbypass protected nodes, do not use anymore
-- instead grant admin 'protection_bypass' privelage.
minetest.register_privilege("delprotect","Ignore player protection")
-- get minetest.conf settings
protector = {}
protector.mod = "redo"
protector.radius = (tonumber(minetest.setting_get("protector_radius")) or 5)
protector.radius = tonumber(minetest.setting_get("protector_radius")) or 5
protector.drop = minetest.setting_getbool("protector_drop") or false
protector.flip = minetest.setting_getbool("protector_flip") or false
protector.hurt = (tonumber(minetest.setting_get("protector_hurt")) or 0)
protector.hurt = tonumber(minetest.setting_get("protector_hurt")) or 0
protector.spawn = tonumber(minetest.setting_get("protector_spawn")
or minetest.setting_get("protector_pvp_spawn")) or 0
-- get static spawn position
local statspawn = minetest.setting_get_pos("static_spawnpoint") or {x = 0, y = 2, z = 0}
-- Intllib
local S
@ -30,16 +38,19 @@ else
end
protector.intllib = S
-- return list of members as a table
protector.get_member_list = function(meta)
return meta:get_string("members"):split(" ")
end
-- write member list table in protector meta as string
protector.set_member_list = function(meta, list)
meta:set_string("members", table.concat(list, " "))
end
-- check if player name is a member
protector.is_member = function (meta, name)
for _, n in pairs(protector.get_member_list(meta)) do
@ -52,6 +63,7 @@ protector.is_member = function (meta, name)
return false
end
-- add player name to table as member
protector.add_member = function(meta, name)
if protector.is_member(meta, name) then
@ -65,6 +77,7 @@ protector.add_member = function(meta, name)
protector.set_member_list(meta, list)
end
-- remove player name from table
protector.del_member = function(meta, name)
local list = protector.get_member_list(meta)
@ -80,8 +93,7 @@ protector.del_member = function(meta, name)
protector.set_member_list(meta, list)
end
-- Protector Interface
-- protector interface
protector.generate_formspec = function(meta)
local formspec = "size[8,7]"
@ -94,7 +106,7 @@ protector.generate_formspec = function(meta)
.. "button_exit[2.5,6.2;3,0.5;close_me;" .. S("Close") .. "]"
local members = protector.get_member_list(meta)
local npp = 12 -- max users added onto protector list
local npp = 12 -- max users added to protector list
local i = 0
for n = 1, #members do
@ -131,6 +143,26 @@ protector.generate_formspec = function(meta)
return formspec
end
-- check if pos is inside a protected spawn area
local function inside_spawn(pos, radius)
if protector.spawn <= 0 then
return false
end
if pos.x < statspawn.x + radius
and pos.x > statspawn.x - radius
and pos.y < statspawn.y + radius
and pos.y > statspawn.y - radius
and pos.z < statspawn.z + radius
and pos.z > statspawn.z - radius then
return true
end
return false
end
-- Infolevel:
-- 0 for no info
-- 1 for "This area is owned by <owner> !" if you can't dig
@ -144,18 +176,27 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
return false
end
-- Delprotect privileged users can override protections
-- delprotect and protector_bypass privileged users can override protection
if ( minetest.check_player_privs(digger, {delprotect = true})
or minetest.check_player_privs(digger, {protection_bypass = true}) )
and infolevel == 1 then
return true
end
-- infolevel 3 is only used to bypass priv check, change to 1 now
if infolevel == 3 then infolevel = 1 end
-- Find the protector nodes
-- is spawn area protected ?
if inside_spawn(pos, protector.spawn) then
minetest.chat_send_player(digger,
S("Spawn @1 has been protected up to a @2 block radius.",
minetest.pos_to_string(statspawn), protector.spawn))
return false
end
-- find the protector nodes
local pos = minetest.find_nodes_in_area(
{x = pos.x - r, y = pos.y - r, z = pos.z - r},
{x = pos.x + r, y = pos.y + r, z = pos.z + r},
@ -169,35 +210,22 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
owner = meta:get_string("owner") or ""
members = meta:get_string("members") or ""
if owner ~= digger then
-- node change and digger isn't owner
if owner ~= digger
and infolevel == 1 then
-- and you aren't on the member list
if onlyowner
or not protector.is_member(meta, digger) then
if infolevel == 1 then
minetest.chat_send_player(digger,
minetest.chat_send_player(digger,
S("This area is owned by @1!", owner))
elseif infolevel == 2 then
minetest.chat_send_player(digger,
S("This area is owned by @1.", owner))
minetest.chat_send_player(digger,
S("Protection located at: @1", minetest.pos_to_string(pos[n])))
if members ~= "" then
minetest.chat_send_player(digger,
S("Members: @1.", members))
end
end
return false
return false
end
end
-- when using protector as tool, show protector information
if infolevel == 2 then
minetest.chat_send_player(digger,
@ -217,6 +245,7 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
end
-- show when you can build on unprotected area
if infolevel == 2 then
if #pos < 1 then
@ -231,12 +260,13 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
return true
end
-- Can node be added or removed, if so return node else true (for protected)
protector.old_is_protected = minetest.is_protected
-- check for protected area, return true if protected and digger isn't on list
function minetest.is_protected(pos, digger)
-- is area protected against digger?
if not protector.can_dig(protector.radius, pos, digger, false, 1) then
local player = minetest.get_player_by_name(digger)
@ -308,33 +338,45 @@ function minetest.is_protected(pos, digger)
return true
end
-- otherwise can dig or place
return protector.old_is_protected(pos, digger)
end
-- Make sure protection block doesn't overlap another protector's area
-- make sure protection block doesn't overlap another protector's area
function protector.check_overlap(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
if not protector.can_dig(protector.radius * 2, pointed_thing.above,
local pos = pointed_thing.above
-- make sure protector doesn't overlap onto protected spawn area
if inside_spawn(pos, protector.spawn + protector.radius) then
minetest.chat_send_player(placer:get_player_name(),
S("Spawn @1 has been protected up to a @2 block radius.",
minetest.pos_to_string(statspawn), protector.spawn))
return itemstack
end
-- make sure protector doesn't overlap any other player's area
if not protector.can_dig(protector.radius * 2, pos,
placer:get_player_name(), true, 3) then
minetest.chat_send_player(placer:get_player_name(),
S("Overlaps into above players protected area"))
return
return itemstack
end
return minetest.item_place(itemstack, placer, pointed_thing)
end
--= Protection Block
-- protection node
minetest.register_node("protector:protect", {
description = S("Protection Block"),
drawtype = "nodebox",
@ -413,8 +455,7 @@ minetest.register_craft({
}
})
--= Protection Logo
-- protection logo
minetest.register_node("protector:protect2", {
description = S("Protection Logo"),
tiles = {"protector_logo.png"},
@ -494,20 +535,22 @@ minetest.register_craft({
}
})
-- If name entered or button press
-- check formspec buttons or when name entered
minetest.register_on_player_receive_fields(function(player, formname, fields)
-- protector formspec found
if string.sub(formname, 0, string.len("protector:node_")) == "protector:node_" then
local pos_s = string.sub(formname, string.len("protector:node_") + 1)
local pos = minetest.string_to_pos(pos_s)
local meta = minetest.get_meta(pos)
-- only owner can add names
if not protector.can_dig(1, pos, player:get_player_name(), true, 1) then
return
end
-- add member [+]
if fields.protector_add_member then
for _, i in pairs(fields.protector_add_member:split(" ")) do
@ -515,23 +558,25 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end
-- remove member [x]
for field, value in pairs(fields) do
if string.sub(field, 0, string.len("protector_del_member_")) == "protector_del_member_" then
protector.del_member(meta, string.sub(field,string.len("protector_del_member_") + 1))
if string.sub(field, 0,
string.len("protector_del_member_")) == "protector_del_member_" then
protector.del_member(meta,
string.sub(field,string.len("protector_del_member_") + 1))
end
end
-- reset formspec until close button pressed
if not fields.close_me then
minetest.show_formspec(player:get_player_name(), formname, protector.generate_formspec(meta))
end
end
end)
-- Display entity shown when protector node is punched
-- display entity shown when protector node is punched
minetest.register_entity("protector:display", {
physical = false,
collisionbox = {0, 0, 0, 0, 0, 0},
@ -554,6 +599,7 @@ minetest.register_entity("protector:display", {
self.timer = self.timer + dtime
-- remove after 5 seconds
if self.timer > 5 then
self.object:remove()
end

View File

@ -2,13 +2,12 @@
local S = protector.intllib
-- get static spawn position
local statspawn = (minetest.setting_get_pos("static_spawnpoint") or {x = 0, y = 2, z = 0})
local statspawn = minetest.setting_get_pos("static_spawnpoint") or {x = 0, y = 2, z = 0}
-- is pvp protection enabled and spawn protected
-- is pvp protection enabled
protector.pvp = minetest.setting_getbool("protector_pvp")
protector.spawn = (tonumber(minetest.setting_get("protector_pvp_spawn")) or 0)
-- Disable PVP in your own protected areas
-- disables PVP in your own protected areas
if minetest.setting_getbool("enable_pvp") and protector.pvp then
if minetest.register_on_punchplayer then