-
Notifications
You must be signed in to change notification settings - Fork 11
/
protector.lua
159 lines (123 loc) · 4.4 KB
/
protector.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
local has_protector_mod = minetest.get_modpath("protector")
local has_mesecons_mvps_mod = minetest.get_modpath("mesecons_mvps")
local update_formspec = function(meta)
local threshold = meta:get_int("xpthreshold")
local owner = meta:get_string("owner")
meta:set_string("infotext", "XP Protector, threshold: " .. threshold .. ", owner: " .. owner)
meta:set_string("formspec", "size[6,3;]" ..
"field[0,1;6,1;xpthreshold;XP Threshold;" .. threshold .. "]" ..
"button_exit[0,2;6,1;save;Save]"
)
end
local last_player_xp_map = {}
local function get_last_player_user_xp(name)
return last_player_xp_map[name] or 1000
end
local function set_last_player_user_xp(name, xp)
last_player_xp_map[name] = xp
end
minetest.register_node("xp_redo:protector", {
description = "XP Protector",
tiles = {
"default_bronze_block.png^xp_protector_overlay.png",
"default_bronze_block.png^xp_protector_overlay.png",
"default_bronze_block.png^xp_protector_overlay.png^xp_protector_logo.png"
},
groups = {cracky=3,oddly_breakable_by_hand=3},
is_ground_content = false,
sounds = default.node_sound_glass_defaults(),
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
meta:set_int("xpthreshold", get_last_player_user_xp(placer:get_player_name()))
update_formspec(meta)
end,
on_receive_fields = function(pos, _, fields, sender)
local meta = minetest.get_meta(pos)
local name = sender:get_player_name()
if name == meta:get_string("owner") then
-- ownder
if fields.xpthreshold then
local xpthreshold = tonumber(fields.xpthreshold)
if xpthreshold ~= nil then
meta:set_int("xpthreshold", fields.xpthreshold)
set_last_player_user_xp(name, fields.xpthreshold)
end
end
update_formspec(meta)
end
end,
on_punch = function(pos, _, puncher)
if minetest.is_protected(pos, puncher:get_player_name()) then
return
end
if has_protector_mod then
minetest.add_entity(pos, "protector:display")
end
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local name = player:get_player_name()
return name == meta:get_string("owner") or minetest.check_player_privs(name, {protection_bypass=true})
end,
after_destruct = function(pos)
local objects = minetest.get_objects_inside_radius(pos, 0.5)
for _, v in ipairs(objects) do
local ent = v:get_luaentity()
if ent and ent.name == "protector:display" then
v:remove()
end
end
end
})
local 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)
local radius = 5
digger = digger or "" -- nil check
if minetest.check_player_privs(digger, {protection_bypass = true}) then
return false
end
local xp = xp_redo.get_xp(digger)
local nodes = minetest.find_nodes_in_area(
{x = pos.x - radius, y = pos.y - radius, z = pos.z - radius},
{x = pos.x + radius, y = pos.y + radius, z = pos.z + radius},
{"xp_redo:protector"})
for n = 1, #nodes do
local meta = minetest.get_meta(nodes[n])
local xpthreshold = meta:get_int("xpthreshold") or 0
if xpthreshold > xp then
minetest.chat_send_player(digger, "This area is protected with a minimum-xp of " .. xpthreshold .. "!")
return true
end
end
-- otherwise can dig or place
return old_is_protected(pos, digger)
end
if has_protector_mod and protector.tool and protector.tool.register_protector then
protector.tool:register_protector('xp_redo:protector', {
nodes = nil, -- Compatible nodes for protector tool, uses same on_place, radius, etc.
param2 = nil, -- Default param2 for protector
on_place = nil, -- on_place callback, protector is about to be placed
after_place = function(user, meta, src_meta)
-- copy members across if holding sneak when using tool
if user:get_player_control().sneak then
-- get priv on source protector / set target protector metadata
local xpthreshold = src_meta:get_int("xpthreshold") or 1000
meta:set_int("xpthreshold", xpthreshold)
else
local name = user:get_player_name()
meta:set_int("xpthreshold", get_last_player_user_xp(name))
end
update_formspec(meta)
end,
})
end
minetest.register_craft({
output = 'xp_redo:protector',
type = 'shapeless',
recipe = {"default:bronzeblock", "default:steel_ingot"}
})
if has_mesecons_mvps_mod then
mesecon.register_mvps_stopper("xp_redo:protector")
end