-
Notifications
You must be signed in to change notification settings - Fork 1
/
sfinv.lua
164 lines (135 loc) · 4.74 KB
/
sfinv.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
local S = sfcg.get_translator
local esc = minetest.formspec_escape
local function coords(i, cols)
return i % cols, math.floor(i / cols)
end
local function recipe_fs(fs, data)
local recipe = data.recipes[data.rnum]
local width = recipe.width
local cooktime, shapeless
if recipe.method == "cooking" then
cooktime, width = width, 1
elseif width == 0 then
shapeless = true
if #recipe.items == 1 then
width = 1
elseif #recipe.items <= 4 then
width = 2
else
width = 3
end
end
table.insert(fs, ("label[5.5,1;%s]"):format(esc(data.show_usages
and S("Usage @1 of @2", data.rnum, #data.recipes)
or S("Recipe @1 of @2", data.rnum, #data.recipes))))
if #data.recipes > 1 then
table.insert(fs,
"image_button[5.5,1.6;0.8,0.8;craftguide_prev_icon.png;recipe_prev;]"..
"image_button[6.2,1.6;0.8,0.8;craftguide_next_icon.png;recipe_next;]"..
"tooltip[recipe_prev;"..esc(S("Previous recipe")).."]"..
"tooltip[recipe_next;"..esc(S("Next recipe")).."]")
end
local rows = math.ceil(table.maxn(recipe.items) / width)
if width > 3 or rows > 3 then
table.insert(fs, ("label[0,1;%s]")
:format(esc(S("Recipe is too big to be displayed."))))
return
end
local base_x = 3 - width
local base_y = rows == 1 and 1 or 0
-- Use local variables for faster execution in loop
local item_button_fs = sfcg.item_button_fs
local extract_groups = sfcg.extract_groups
local groups_to_item = sfcg.groups_to_item
for i, item in pairs(recipe.items) do
local x, y = coords(i - 1, width)
local elem_name = item
local groups = extract_groups(item)
if groups then
item = groups_to_item(groups)
elem_name = esc(item.."."..table.concat(groups, "+"))
end
item_button_fs(fs, base_x + x, base_y + y, item, elem_name, groups)
end
if shapeless or recipe.method == "cooking" then
table.insert(fs, ("image[3.2,0.5;0.5,0.5;craftguide_%s.png]")
:format(shapeless and "shapeless" or "furnace"))
local tooltip = shapeless and S("Shapeless") or
S("Cooking time: @1", minetest.colorize("yellow", cooktime))
table.insert(fs, "tooltip[3.2,0.5;0.5,0.5;"..esc(tooltip).."]")
end
table.insert(fs, "image[3,1;1,1;sfinv_crafting_arrow.png]")
item_button_fs(fs, 4, 1, recipe.output, recipe.output:match("%S*"))
end
local function get_formspec(player)
local name = player:get_player_name()
local data = sfcg.player_data[name]
data.pagemax = math.max(1, math.ceil(#data.items / 32))
local fs = {}
table.insert(fs,
"style_type[item_image_button;padding=2]"..
"field[0.3,4.2;2.8,1.2;filter;;"..esc(data.filter).."]"..
"label[5.8,4.15;"..minetest.colorize("yellow", data.pagenum).." / "..
data.pagemax.."]"..
"image_button[2.63,4.05;0.8,0.8;craftguide_search_icon.png;search;]"..
"image_button[3.25,4.05;0.8,0.8;craftguide_clear_icon.png;clear;]"..
"image_button[5,4.05;0.8,0.8;craftguide_prev_icon.png;prev;]"..
"image_button[7.25,4.05;0.8,0.8;craftguide_next_icon.png;next;]"..
"tooltip[search;"..esc(S("Search")).."]"..
"tooltip[clear;"..esc(S("Reset")).."]"..
"tooltip[prev;"..esc(S("Previous page")).."]"..
"tooltip[next;"..esc(S("Next page")).."]"..
"field_close_on_enter[filter;false]")
if #data.items == 0 then
table.insert(fs, "label[3,2;"..esc(S("No items to show.")).."]")
else
local item_button_fs = sfcg.item_button_fs
local first_item = (data.pagenum - 1) * 32
for i = first_item, first_item + 31 do
local item = data.items[i + 1]
if not item then
break
end
local x, y = coords(i % 32, 8)
item_button_fs(fs, x, y, item, item)
end
end
table.insert(fs, "container[0,5.6]")
if data.recipes then
recipe_fs(fs, data)
elseif data.prev_item then
table.insert(fs, ("label[2,1;%s]"):format(esc(data.show_usages
and S("No usages.").."\n"..S("Click again to show recipes.")
or S("No recipes.").."\n"..S("Click again to show usages."))))
end
table.insert(fs, "container_end[]")
return table.concat(fs)
end
local orig_update_for_player = sfcg.update_for_player
function sfcg.update_for_player(playername)
local player = orig_update_for_player(playername)
if player then
sfinv.set_player_inventory_formspec(player)
end
return player
end
sfinv.register_page("sfcraftguide:craftguide", {
title = esc(S("Recipes")),
get = function(self, player, context)
return sfinv.make_formspec(player, context, get_formspec(player))
end,
on_player_receive_fields = function(self, player, context, fields)
if sfcg.on_receive_fields(player, fields) then
sfinv.set_player_inventory_formspec(player)
end
end
})
minetest.register_on_mods_loaded(function()
sfinv.pages["mtg_craftguide:craftguide"] = nil
for idx = #sfinv.pages_unordered, 1, -1 do
local page = sfinv.pages_unordered[idx]
if page.name == "mtg_craftguide:craftguide" then
table.remove(sfinv.pages_unordered, idx)
end
end
end)