@@ -16,25 +16,24 @@ local after = core.after
16
16
local colorize = core .colorize
17
17
local reg_items = core .registered_items
18
18
local get_result = core .get_craft_result
19
- local show_formspec = core .show_formspec
20
19
local get_players = core .get_connected_players
20
+ local show_formspec = core .show_formspec
21
21
local get_all_recipes = core .get_all_craft_recipes
22
22
local get_player_by_name = core .get_player_by_name
23
23
local serialize , deserialize = core .serialize , core .deserialize
24
24
25
25
local ESC = core .formspec_escape
26
26
local S = core .get_translator (" craftguide" )
27
27
28
- local maxn , sort , concat , insert , copy =
29
- table.maxn , table.sort , table.concat , table.insert ,
30
- table .copy
28
+ local maxn , sort , concat , copy =
29
+ table.maxn , table.sort , table.concat , table .copy
31
30
32
31
local fmt , find , gmatch , match , sub , split , upper , lower =
33
32
string.format , string.find , string.gmatch , string.match ,
34
33
string.sub , string .split , string.upper , string.lower
35
34
36
35
local min , max , floor , ceil = math.min , math.max , math.floor , math.ceil
37
- local pairs , next , unpack = pairs , next , unpack
36
+ local pairs , next = pairs , next
38
37
local vec_add , vec_mul = vector .add , vector .multiply
39
38
40
39
local DEFAULT_SIZE = 10
@@ -44,10 +43,10 @@ DEFAULT_SIZE = min(MAX_LIMIT, max(MIN_LIMIT, DEFAULT_SIZE))
44
43
local GRID_LIMIT = 5
45
44
46
45
local FMT = {
47
- box = " box[%f,%f;%f,%f;%s]" ,
48
- label = " label[%f,%f;%s]" ,
49
- image = " image[%f,%f;%f,%f;%s]" ,
50
- button = " button[%f,%f;%f,%f;%s;%s]" ,
46
+ box = " box[%f,%f;%f,%f;%s]" ,
47
+ label = " label[%f,%f;%s]" ,
48
+ image = " image[%f,%f;%f,%f;%s]" ,
49
+ button = " button[%f,%f;%f,%f;%s;%s]" ,
51
50
tooltip = " tooltip[%f,%f;%f,%f;%s]" ,
52
51
item_image = " item_image[%f,%f;%f,%f;%s]" ,
53
52
image_button = " image_button[%f,%f;%f,%f;%s;%s;%s]" ,
@@ -244,30 +243,6 @@ function craftguide.get_search_filters()
244
243
return search_filters
245
244
end
246
245
247
- local formspec_elements = {}
248
-
249
- function craftguide .add_formspec_element (name , def )
250
- local func = " craftguide." .. __func () .. " (): "
251
- assert (is_str (name ), func .. " formspec element name missing" )
252
- assert (is_str (def .element ), func .. " 'element' field not defined" )
253
- assert (is_str (def .type ), func .. " 'type' field not defined" )
254
- assert (FMT [def .type ], func .. " '" .. def .type .. " ' type not supported by the API" )
255
-
256
- formspec_elements [name ] = {
257
- type = def .type ,
258
- element = def .element ,
259
- action = def .action ,
260
- }
261
- end
262
-
263
- function craftguide .remove_formspec_element (name )
264
- formspec_elements [name ] = nil
265
- end
266
-
267
- function craftguide .get_formspec_elements ()
268
- return formspec_elements
269
- end
270
-
271
246
local function item_has_groups (item_groups , groups )
272
247
for i = 1 , # groups do
273
248
local group = groups [i ]
@@ -332,22 +307,33 @@ local function get_usages(item)
332
307
return usages
333
308
end
334
309
335
- local function get_filtered_items (player )
310
+ local function get_filtered_items (player , data )
336
311
local items , c = {}, 0
312
+ local known = 0
337
313
338
314
for i = 1 , # init_items do
339
315
local item = init_items [i ]
340
316
local recipes = recipes_cache [item ]
341
317
local usages = usages_cache [item ]
342
318
343
- if recipes and # apply_recipe_filters (recipes , player ) > 0 or
344
- usages and # apply_recipe_filters (usages , player ) > 0 then
345
- c = c + 1
346
- items [c ] = item
319
+ recipes = # apply_recipe_filters (recipes or {}, player )
320
+ usages = # apply_recipe_filters (usages or {}, player )
321
+
322
+ if recipes > 0 or usages > 0 then
323
+ if not data then
324
+ c = c + 1
325
+ items [c ] = item
326
+ else
327
+ known = known + recipes + usages
328
+ end
347
329
end
348
330
end
349
331
350
- return items
332
+ if data then
333
+ data .known_recipes = known
334
+ else
335
+ return items
336
+ end
351
337
end
352
338
353
339
local function cache_recipes (output )
@@ -707,17 +693,6 @@ local function make_formspec(name)
707
693
fs [# fs + 1 ] = get_recipe_fs (data , iY )
708
694
end
709
695
710
- for elem_name , def in pairs (formspec_elements ) do
711
- local element = def .element (data )
712
- if element then
713
- if find (def .type , " button" ) then
714
- insert (element , # element , elem_name )
715
- end
716
-
717
- fs [# fs + 1 ] = fmt (FMT [def .type ], unpack (element ))
718
- end
719
- end
720
-
721
696
return concat (fs )
722
697
end
723
698
@@ -860,12 +835,6 @@ local function on_receive_fields(player, fields)
860
835
local name = player :get_player_name ()
861
836
local data = pdata [name ]
862
837
863
- for elem_name , def in pairs (formspec_elements ) do
864
- if fields [elem_name ] and def .action then
865
- return def .action (player , data )
866
- end
867
- end
868
-
869
838
if fields .clear then
870
839
reset_data (data )
871
840
show_fs (player , name )
@@ -1110,6 +1079,10 @@ if progressive_mode then
1110
1079
end
1111
1080
1112
1081
local function progressive_filter (recipes , player )
1082
+ if not recipes then
1083
+ return {}
1084
+ end
1085
+
1113
1086
local name = player :get_player_name ()
1114
1087
local data = pdata [name ]
1115
1088
@@ -1154,8 +1127,48 @@ if progressive_mode then
1154
1127
return inv_items
1155
1128
end
1156
1129
1130
+ local function show_hud_success (player , data , dtime )
1131
+ local hud_info_bg = player :hud_get (data .hud .bg )
1132
+
1133
+ if hud_info_bg .position .y <= 0.9 then
1134
+ data .show_hud = false
1135
+ data .hud_timer = (data .hud_timer or 0 ) + dtime
1136
+ end
1137
+
1138
+ if data .show_hud then
1139
+ for _ , def in pairs (data .hud ) do
1140
+ local hud_info = player :hud_get (def )
1141
+
1142
+ player :hud_change (def , " position" , {
1143
+ x = hud_info .position .x ,
1144
+ y = hud_info .position .y - (dtime / 5 )
1145
+ })
1146
+ end
1147
+
1148
+ player :hud_change (data .hud .text , " text" ,
1149
+ S (" @1 new recipe(s) discovered!" , data .discovered ))
1150
+
1151
+ elseif data .show_hud == false then
1152
+ if data .hud_timer > 3 then
1153
+ for _ , def in pairs (data .hud ) do
1154
+ local hud_info = player :hud_get (def )
1155
+
1156
+ player :hud_change (def , " position" , {
1157
+ x = hud_info .position .x ,
1158
+ y = hud_info .position .y + (dtime / 5 )
1159
+ })
1160
+ end
1161
+
1162
+ if hud_info_bg .position .y >= 1 then
1163
+ data .show_hud = nil
1164
+ data .hud_timer = nil
1165
+ end
1166
+ end
1167
+ end
1168
+ end
1169
+
1157
1170
-- Workaround. Need an engine call to detect when the contents
1158
- -- of the player inventory changed, instead.
1171
+ -- of the player inventory changed, instead
1159
1172
local function poll_new_items ()
1160
1173
for i = 1 , # PLAYERS do
1161
1174
local player = PLAYERS [i ]
@@ -1167,6 +1180,14 @@ if progressive_mode then
1167
1180
1168
1181
if # diff > 0 then
1169
1182
data .inv_items = table_merge (diff , data .inv_items )
1183
+
1184
+ local oldknown = data .known_recipes or 0
1185
+ get_filtered_items (player , data )
1186
+ data .discovered = data .known_recipes - oldknown
1187
+
1188
+ if data .show_hud == nil and data .discovered > 0 then
1189
+ data .show_hud = true
1190
+ end
1170
1191
end
1171
1192
end
1172
1193
@@ -1175,6 +1196,18 @@ if progressive_mode then
1175
1196
1176
1197
poll_new_items ()
1177
1198
1199
+ minetest .register_globalstep (function (dtime )
1200
+ for i = 1 , # PLAYERS do
1201
+ local player = PLAYERS [i ]
1202
+ local name = player :get_player_name ()
1203
+ local data = pdata [name ]
1204
+
1205
+ if data .show_hud ~= nil then
1206
+ show_hud_success (player , data , dtime )
1207
+ end
1208
+ end
1209
+ end )
1210
+
1178
1211
craftguide .add_recipe_filter (" Default progressive filter" , progressive_filter )
1179
1212
1180
1213
core .register_on_joinplayer (function (player )
@@ -1185,6 +1218,33 @@ if progressive_mode then
1185
1218
local data = pdata [name ]
1186
1219
1187
1220
data .inv_items = deserialize (meta :get_string (" inv_items" )) or {}
1221
+ data .known_recipes = deserialize (meta :get_string (" known_recipes" )) or 0
1222
+
1223
+ data .hud = {
1224
+ bg = player :hud_add ({
1225
+ hud_elem_type = " image" ,
1226
+ position = {x = 0.8 , y = 1 },
1227
+ alignment = {x = 1 , y = 1 },
1228
+ scale = {x = 320 , y = 112 },
1229
+ text = " craftguide_bg.png" ,
1230
+ }),
1231
+
1232
+ book = player :hud_add ({
1233
+ hud_elem_type = " image" ,
1234
+ position = {x = 0.81 , y = 1.02 },
1235
+ alignment = {x = 1 , y = 1 },
1236
+ scale = {x = 4 , y = 4 },
1237
+ text = " craftguide_book.png" ,
1238
+ }),
1239
+
1240
+ text = player :hud_add ({
1241
+ hud_elem_type = " text" ,
1242
+ position = {x = 0.85 , y = 1.04 },
1243
+ alignment = {x = 1 , y = 1 },
1244
+ number = 0xFFFFFF ,
1245
+ text = " " ,
1246
+ }),
1247
+ }
1188
1248
end )
1189
1249
1190
1250
local function save_meta (player )
@@ -1193,6 +1253,7 @@ if progressive_mode then
1193
1253
local data = pdata [name ]
1194
1254
1195
1255
meta :set_string (" inv_items" , serialize (data .inv_items ))
1256
+ meta :set_string (" known_recipes" , serialize (data .known_recipes ))
1196
1257
end
1197
1258
1198
1259
core .register_on_leaveplayer (function (player )
0 commit comments