-
Notifications
You must be signed in to change notification settings - Fork 11
/
areas.lua
186 lines (153 loc) · 4.33 KB
/
areas.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
-- id -> { max=1000, min=100 }
local xp_areas = {}
function xp_redo.get_area_xp_limits(id)
return xp_areas[id] or {}
end
-- protection check
local old_is_protected = minetest.is_protected
function minetest.is_protected(pos, name)
local area_list
if areas.config.use_smallest_area_precedence then
local _, id = areas:getSmallestAreaAtPos(pos)
area_list = id and { [id] = true } or {}
else
area_list = areas:getAreasAtPos(pos)
end
for id in pairs(area_list) do
local xp_area = xp_areas[id]
if xp_area then
local xp = xp_redo.get_xp(name)
if xp_area.min and xp < xp_area.min then
return true
elseif xp_area.max and xp > xp_area.max then
return true
end
end
end
return old_is_protected(pos, name)
end
-- File writing / reading utilities
local wpath = minetest.get_worldpath()
local filename = wpath.."/xp_areas.dat"
local function load_xp_areas()
local f = io.open(filename, "r")
if f == nil then return {} end
local t = f:read("*all")
f:close()
if t == "" or t == nil then return {} end
return minetest.deserialize(t)
end
local function save_xp_areas()
local f = io.open(filename, "w")
f:write(minetest.serialize(xp_areas))
f:close()
end
xp_areas = load_xp_areas()
-- cleanup for removed areas
areas:registerOnRemove(function(id)
xp_areas[id] = nil
save_xp_areas()
end)
-- chat
minetest.register_chatcommand("area_xp_set_max", {
params = "<ID> <xp_limit>",
description = "Set or clear the max-xp value of an area",
func = function(playername, param)
local matcher = param:gmatch("(%S+)")
local id_str = matcher()
local xp = matcher()
if id_str == nil then
return true, "Invalid syntax!"
end
local id = tonumber(id_str)
if not id then
return true, "area-id is not numeric: " .. id_str
end
if not areas:isAreaOwner(id, playername) and
not minetest.check_player_privs(playername, { protection_bypas = true })
then
return true, "you are not the owner of area: " .. id
end
local xp_area = xp_areas[id]
if not xp_area then
xp_area = {}
end
xp_area.max = tonumber(xp)
xp_areas[id] = xp_area
save_xp_areas()
return true, "Area " .. id .. " max-xp value: " .. (xp_area.max or "<none>")
end,
})
minetest.register_chatcommand("area_xp_get_max", {
params = "<ID>",
description = "Returns the max-xp value of an area",
func = function(playername, param)
if param == nil then
return true, "Invalid syntax!"
end
local id = tonumber(param)
if not id then
return true, "area-id is not numeric: " .. param
end
if not areas:isAreaOwner(id, playername) and
not minetest.check_player_privs(playername, { protection_bypas = true })
then
return true, "you are not the owner of area: " .. id
end
local xp_area = xp_areas[id]
if not xp_area then
xp_area = {}
end
return true, "Area " .. id .. " max-xp value: " .. (xp_area.max or "<none>")
end,
})
minetest.register_chatcommand("area_xp_set_min", {
params = "<ID> <xp_limit>",
description = "Set or clear the min-xp value of an area",
func = function(playername, param)
local matcher = param:gmatch("(%S+)")
local id_str = matcher()
local xp = matcher()
if id_str == nil then
return true, "Invalid syntax!"
end
local id = tonumber(id_str)
if not id then
return true, "area-id is not numeric: " .. id_str
end
if not areas:isAreaOwner(id, playername) and
not minetest.check_player_privs(playername, { protection_bypas=true }) then
return true, "you are not the owner of area: " .. id
end
local xp_area = xp_areas[id]
if not xp_area then
xp_area = {}
end
xp_area.min = tonumber(xp)
xp_areas[id] = xp_area
save_xp_areas()
return true, "Area " .. id .. " min-xp value: " .. (xp_area.min or "<none>")
end,
})
minetest.register_chatcommand("area_xp_get_min", {
params = "<ID>",
description = "Returns the min-xp value of an area",
func = function(playername, param)
if param == nil then
return true, "Invalid syntax!"
end
local id = tonumber(param)
if not id then
return true, "area-id is not numeric: " .. param
end
if not areas:isAreaOwner(id, playername) and
not minetest.check_player_privs(playername, { protection_bypas=true }) then
return true, "you are not the owner of area: " .. id
end
local xp_area = xp_areas[id]
if not xp_area then
xp_area = {}
end
return true, "Area " .. id .. " min-xp value: " .. (xp_area.min or "<none>")
end,
})