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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
-- Copyright (c) 2013-18 rubenwardy. MIT.
local S, NS = awards.gettext, awards.ngettext
awards.registered_awards = {}
awards.on = {}
awards.on_unlock = {}
local default_def = {}
function default_def:run_callbacks(player, data, table_func)
for i = 1, #self.on do
local res = nil
local entry = self.on[i]
if type(entry) == "function" then
res = entry(player, data)
elseif type(entry) == "table" and entry.award then
res = table_func(entry)
end
if res then
awards.unlock(player:get_player_name(), res)
end
end
end
function awards.register_trigger(tname, tdef)
assert(type(tdef) == "table",
"Passing a callback to register_trigger is not supported in 3.0")
tdef.name = tname
for key, value in pairs(default_def) do
tdef[key] = value
end
if tdef.type == "counted" then
local old_reg = tdef.on_register
function tdef:on_register(def)
local tmp = {
award = def.name,
target = def.trigger.target,
}
tdef.register(tmp)
function def.getProgress(_, data)
local done = math.min(data[tname] or 0, tmp.target)
return {
perc = done / tmp.target,
label = S(tdef.progress, done, tmp.target),
}
end
function def.getDefaultDescription(_)
local n = def.trigger.target
return NS(tdef.auto_description[1], tdef.auto_description[2], n, n)
end
if old_reg then
return old_reg(tdef, def)
end
end
function tdef.notify(player)
assert(player and player.is_player and player:is_player())
local name = player:get_player_name()
local data = awards.player(name)
-- Increment counter
local currentVal = (data[tname] or 0) + 1
data[tname] = currentVal
tdef:run_callbacks(player, data, function(entry)
if entry.target and entry.award and currentVal and
currentVal >= entry.target then
return entry.award
end
end)
end
awards["notify_" .. tname] = tdef.notify
elseif tdef.type == "counted_key" then
if tdef.key_is_item then
tdef.watched_groups = {}
end
-- On award register
local old_reg = tdef.on_register
function tdef:on_register(def)
-- Register trigger
local tmp = {
award = def.name,
key = tdef:get_key(def),
target = def.trigger.target,
}
tdef.register(tmp)
-- If group, add it to watch list
if tdef.key_is_item and tmp.key and tmp.key:sub(1, 6) == "group:" then
tdef.watched_groups[tmp.key:sub(7, #tmp.key)] = true
end
-- Called to get progress values and labels
function def.getProgress(_, data)
data[tname] = data[tname] or {}
local done
if tmp.key then
done = data[tname][tmp.key] or 0
else
done = data[tname].__total or 0
end
done = math.min(done, tmp.target)
return {
perc = done / tmp.target,
label = S(tdef.progress, done, tmp.target),
}
end
-- Build description if none is specificed by the award
function def.getDefaultDescription(_)
local n = def.trigger.target
if tmp.key then
local nname = tmp.key
return NS(tdef.auto_description[1],
tdef.auto_description[2], n, n, nname)
else
return NS(tdef.auto_description_total[1],
tdef.auto_description_total[2], n, n)
end
end
-- Call on_register in trigger type definition
if old_reg then
return old_reg(tdef, def)
end
end
function tdef.notify(player, key, n)
n = n or 1
if tdef.key_is_item and key:sub(1, 6) ~= "group:" then
local itemdef = minetest.registered_items[key]
if itemdef then
for groupname, _ in pairs(itemdef.groups or {}) do
if tdef.watched_groups[groupname] then
tdef.notify(player, "group:" .. groupname, n)
end
end
end
end
assert(player and player.is_player and player:is_player() and key)
local name = player:get_player_name()
local data = awards.player(name)
-- Increment counter
data[tname] = data[tname] or {}
local currentVal = (data[tname][key] or 0) + n
data[tname][key] = currentVal
if key:sub(1, 6) ~= "group:" then
data[tname].__total = (data[tname].__total or 0) + n
end
tdef:run_callbacks(player, data, function(entry)
local current
if entry.key == key then
current = currentVal
elseif entry.key == nil then
current = data[tname].__total
else
return
end
if current >= entry.target then
return entry.award
end
end)
end
awards["notify_" .. tname] = tdef.notify
elseif tdef.type and tdef.type ~= "custom" then
error("Unrecognised trigger type " .. tdef.type)
end
awards.registered_triggers[tname] = tdef
tdef.on = {}
tdef.register = function(func)
table.insert(tdef.on, func)
end
-- Backwards compat
awards.on[tname] = tdef.on
awards['register_on_' .. tname] = tdef.register
return tdef
end
function awards.increment_item_counter(data, field, itemname, count)
itemname = minetest.registered_aliases[itemname] or itemname
data[field][itemname] = (data[field][itemname] or 0) + 1
end
function awards.get_item_count(data, field, itemname)
itemname = minetest.registered_aliases[itemname] or itemname
return data[field][itemname] or 0
end
function awards.get_total_keyed_count(data, field)
return data[field].__total or 0
end
function awards.register_on_unlock(func)
table.insert(awards.on_unlock, func)
end
|