tidy code, add protected spawn feature

This commit is contained in:
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 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. 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 https://forum.minetest.net/viewtopic.php?f=11&t=9376
@ -39,6 +39,8 @@ Change log:
added support for "protection_bypass" privelage. added support for "protection_bypass" privelage.
1.8 - Added 'protector_flip' setting to stop players using lag to grief into 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. 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) Usage: (requires server privelage)
@ -66,8 +68,8 @@ protector_radius = 5
protector_pvp = true 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. - 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 protector_spawn = 10
- Sets an area 10 nodes around spawn where pvp is disabled completely. - Sets an area 10 nodes around static spawnpoint that is protected.
protector_drop = true protector_drop = true
- When true players who dig inside a protected area will automatically drop tools to stop them going any further. - 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 -- 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 -- 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 local S = protector.intllib

136
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") minetest.register_privilege("delprotect","Ignore player protection")
-- get minetest.conf settings
protector = {} protector = {}
protector.mod = "redo" 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.drop = minetest.setting_getbool("protector_drop") or false
protector.flip = minetest.setting_getbool("protector_flip") 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 -- Intllib
local S local S
@ -30,16 +38,19 @@ else
end end
protector.intllib = S protector.intllib = S
-- return list of members as a table
protector.get_member_list = function(meta) protector.get_member_list = function(meta)
return meta:get_string("members"):split(" ") return meta:get_string("members"):split(" ")
end end
-- write member list table in protector meta as string
protector.set_member_list = function(meta, list) protector.set_member_list = function(meta, list)
meta:set_string("members", table.concat(list, " ")) meta:set_string("members", table.concat(list, " "))
end end
-- check if player name is a member
protector.is_member = function (meta, name) protector.is_member = function (meta, name)
for _, n in pairs(protector.get_member_list(meta)) do for _, n in pairs(protector.get_member_list(meta)) do
@ -52,6 +63,7 @@ protector.is_member = function (meta, name)
return false return false
end end
-- add player name to table as member
protector.add_member = function(meta, name) protector.add_member = function(meta, name)
if protector.is_member(meta, name) then if protector.is_member(meta, name) then
@ -65,6 +77,7 @@ protector.add_member = function(meta, name)
protector.set_member_list(meta, list) protector.set_member_list(meta, list)
end end
-- remove player name from table
protector.del_member = function(meta, name) protector.del_member = function(meta, name)
local list = protector.get_member_list(meta) local list = protector.get_member_list(meta)
@ -80,8 +93,7 @@ protector.del_member = function(meta, name)
protector.set_member_list(meta, list) protector.set_member_list(meta, list)
end end
-- Protector Interface -- protector interface
protector.generate_formspec = function(meta) protector.generate_formspec = function(meta)
local formspec = "size[8,7]" 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") .. "]" .. "button_exit[2.5,6.2;3,0.5;close_me;" .. S("Close") .. "]"
local members = protector.get_member_list(meta) 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 local i = 0
for n = 1, #members do for n = 1, #members do
@ -131,6 +143,26 @@ protector.generate_formspec = function(meta)
return formspec return formspec
end 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: -- Infolevel:
-- 0 for no info -- 0 for no info
-- 1 for "This area is owned by <owner> !" if you can't dig -- 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 return false
end end
-- Delprotect privileged users can override protections -- delprotect and protector_bypass privileged users can override protection
if ( minetest.check_player_privs(digger, {delprotect = true}) if ( minetest.check_player_privs(digger, {delprotect = true})
or minetest.check_player_privs(digger, {protection_bypass = true}) ) or minetest.check_player_privs(digger, {protection_bypass = true}) )
and infolevel == 1 then and infolevel == 1 then
return true return true
end end
-- infolevel 3 is only used to bypass priv check, change to 1 now
if infolevel == 3 then infolevel = 1 end 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( 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},
{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 "" owner = meta:get_string("owner") or ""
members = meta:get_string("members") 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 if onlyowner
or not protector.is_member(meta, digger) then 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)) S("This area is owned by @1!", owner))
elseif infolevel == 2 then return false
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
end end
end end
-- when using protector as tool, show protector information
if infolevel == 2 then if infolevel == 2 then
minetest.chat_send_player(digger, minetest.chat_send_player(digger,
@ -217,6 +245,7 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
end end
-- show when you can build on unprotected area
if infolevel == 2 then if infolevel == 2 then
if #pos < 1 then if #pos < 1 then
@ -231,12 +260,13 @@ protector.can_dig = function(r, pos, digger, onlyowner, infolevel)
return true return true
end end
-- Can node be added or removed, if so return node else true (for protected)
protector.old_is_protected = minetest.is_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) function minetest.is_protected(pos, digger)
-- is area protected against digger?
if not protector.can_dig(protector.radius, pos, digger, false, 1) then if not protector.can_dig(protector.radius, pos, digger, false, 1) then
local player = minetest.get_player_by_name(digger) local player = minetest.get_player_by_name(digger)
@ -308,33 +338,45 @@ function minetest.is_protected(pos, digger)
return true return true
end end
-- otherwise can dig or place
return protector.old_is_protected(pos, digger) return protector.old_is_protected(pos, digger)
end 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) function protector.check_overlap(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
return itemstack return itemstack
end 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 placer:get_player_name(), true, 3) then
minetest.chat_send_player(placer:get_player_name(), minetest.chat_send_player(placer:get_player_name(),
S("Overlaps into above players protected area")) S("Overlaps into above players protected area"))
return return itemstack
end end
return minetest.item_place(itemstack, placer, pointed_thing) return minetest.item_place(itemstack, placer, pointed_thing)
end end
--= Protection Block -- protection node
minetest.register_node("protector:protect", { minetest.register_node("protector:protect", {
description = S("Protection Block"), description = S("Protection Block"),
drawtype = "nodebox", drawtype = "nodebox",
@ -413,8 +455,7 @@ minetest.register_craft({
} }
}) })
--= Protection Logo -- protection logo
minetest.register_node("protector:protect2", { minetest.register_node("protector:protect2", {
description = S("Protection Logo"), description = S("Protection Logo"),
tiles = {"protector_logo.png"}, 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) 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 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_s = string.sub(formname, string.len("protector:node_") + 1)
local pos = minetest.string_to_pos(pos_s) local pos = minetest.string_to_pos(pos_s)
local meta = minetest.get_meta(pos) 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 if not protector.can_dig(1, pos, player:get_player_name(), true, 1) then
return return
end end
-- add member [+]
if fields.protector_add_member then if fields.protector_add_member then
for _, i in pairs(fields.protector_add_member:split(" ")) do 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
end end
-- remove member [x]
for field, value in pairs(fields) do for field, value in pairs(fields) do
if string.sub(field, 0, string.len("protector_del_member_")) == "protector_del_member_" then if string.sub(field, 0,
protector.del_member(meta, string.sub(field,string.len("protector_del_member_") + 1)) string.len("protector_del_member_")) == "protector_del_member_" then
protector.del_member(meta,
string.sub(field,string.len("protector_del_member_") + 1))
end end
end end
-- reset formspec until close button pressed
if not fields.close_me then if not fields.close_me then
minetest.show_formspec(player:get_player_name(), formname, protector.generate_formspec(meta)) minetest.show_formspec(player:get_player_name(), formname, protector.generate_formspec(meta))
end end
end end
end) end)
-- Display entity shown when protector node is punched -- display entity shown when protector node is punched
minetest.register_entity("protector:display", { minetest.register_entity("protector:display", {
physical = false, physical = false,
collisionbox = {0, 0, 0, 0, 0, 0}, collisionbox = {0, 0, 0, 0, 0, 0},
@ -554,6 +599,7 @@ minetest.register_entity("protector:display", {
self.timer = self.timer + dtime self.timer = self.timer + dtime
-- remove after 5 seconds
if self.timer > 5 then if self.timer > 5 then
self.object:remove() self.object:remove()
end end

View File

@ -2,13 +2,12 @@
local S = protector.intllib local S = protector.intllib
-- get static spawn position -- 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.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.setting_getbool("enable_pvp") and protector.pvp then
if minetest.register_on_punchplayer then if minetest.register_on_punchplayer then