-
Notifications
You must be signed in to change notification settings - Fork 5
/
api.lua
189 lines (166 loc) · 4.98 KB
/
api.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
186
187
188
189
sfinv = {
pages = {},
pages_unordered = {},
contexts = {},
enabled = true
}
function sfinv.register_page(name, def)
assert(name, "Invalid sfinv page. Requires a name")
assert(def, "Invalid sfinv page. Requires a def[inition] table")
assert(def.get, "Invalid sfinv page. Def requires a get function.")
assert(not sfinv.pages[name], "Attempt to register already registered sfinv page " .. dump(name))
sfinv.pages[name] = def
def.name = name
table.insert(sfinv.pages_unordered, def)
end
function sfinv.override_page(name, def)
assert(name, "Invalid sfinv page override. Requires a name")
assert(def, "Invalid sfinv page override. Requires a def[inition] table")
local page = sfinv.pages[name]
assert(page, "Attempt to override sfinv page " .. dump(name) .. " which does not exist.")
for key, value in pairs(def) do
page[key] = value
end
end
function sfinv.get_nav_fs(player, context, nav, current_idx)
-- Only show tabs if there is more than one page
if #nav > 1 then
return "tabheader[0,0;sfinv_nav_tabs;" .. table.concat(nav, ",") ..
";" .. current_idx .. ";true;false]"
else
return ""
end
end
local theme_inv = [[
image[0,5.2;1,1;gui_hb_bg.png]
image[1,5.2;1,1;gui_hb_bg.png]
image[2,5.2;1,1;gui_hb_bg.png]
image[3,5.2;1,1;gui_hb_bg.png]
image[4,5.2;1,1;gui_hb_bg.png]
image[5,5.2;1,1;gui_hb_bg.png]
image[6,5.2;1,1;gui_hb_bg.png]
image[7,5.2;1,1;gui_hb_bg.png]
list[current_player;main;0,5.2;8,1;]
list[current_player;main;0,6.35;8,3;8]
]]
function sfinv.make_formspec(player, context, content, show_inv, size)
local tmp = {
size or "size[8,9.1]",
sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx),
show_inv and theme_inv or "",
content
}
return table.concat(tmp, "")
end
function sfinv.get_homepage_name(player)
return "sfinv:crafting"
end
function sfinv.get_formspec(player, context)
-- Generate navigation tabs
local nav = {}
local nav_ids = {}
local current_idx = 1
for i, pdef in pairs(sfinv.pages_unordered) do
if not pdef.is_in_nav or pdef:is_in_nav(player, context) then
nav[#nav + 1] = pdef.title
nav_ids[#nav_ids + 1] = pdef.name
if pdef.name == context.page then
current_idx = #nav_ids
end
end
end
context.nav = nav_ids
context.nav_titles = nav
context.nav_idx = current_idx
-- Generate formspec
local page = sfinv.pages[context.page] or sfinv.pages["404"]
if page then
return page:get(player, context)
else
local old_page = context.page
local home_page = sfinv.get_homepage_name(player)
if old_page == home_page then
minetest.log("error", "[sfinv] Couldn't find " .. dump(old_page) ..
", which is also the old page")
return ""
end
context.page = home_page
assert(sfinv.pages[context.page], "[sfinv] Invalid homepage")
minetest.log("warning", "[sfinv] Couldn't find " .. dump(old_page) ..
" so switching to homepage")
return sfinv.get_formspec(player, context)
end
end
function sfinv.get_or_create_context(player)
local name = player:get_player_name()
local context = sfinv.contexts[name]
if not context then
context = {
page = sfinv.get_homepage_name(player)
}
sfinv.contexts[name] = context
end
return context
end
function sfinv.set_context(player, context)
sfinv.contexts[player:get_player_name()] = context
end
function sfinv.set_player_inventory_formspec(player, context)
local fs = sfinv.get_formspec(player,
context or sfinv.get_or_create_context(player))
player:set_inventory_formspec(fs)
end
function sfinv.set_page(player, pagename)
local context = sfinv.get_or_create_context(player)
local oldpage = sfinv.pages[context.page]
if oldpage and oldpage.on_leave then
oldpage:on_leave(player, context)
end
context.page = pagename
local page = sfinv.pages[pagename]
if page.on_enter then
page:on_enter(player, context)
end
sfinv.set_player_inventory_formspec(player, context)
end
function sfinv.get_page(player)
local context = sfinv.contexts[player:get_player_name()]
return context and context.page or sfinv.get_homepage_name(player)
end
minetest.register_on_joinplayer(function(player)
if sfinv.enabled then
sfinv.set_player_inventory_formspec(player)
end
end)
minetest.register_on_leaveplayer(function(player)
sfinv.contexts[player:get_player_name()] = nil
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "" or not sfinv.enabled then
return false
end
-- Get Context
local name = player:get_player_name()
local context = sfinv.contexts[name]
if not context then
sfinv.set_player_inventory_formspec(player)
return false
end
-- Was a tab selected?
if fields.sfinv_nav_tabs and context.nav then
local tid = tonumber(fields.sfinv_nav_tabs)
if tid and tid > 0 then
local id = context.nav[tid]
local page = sfinv.pages[id]
if id and page then
sfinv.set_page(player, id)
end
end
else
-- Pass event to page
local page = sfinv.pages[context.page]
if page and page.on_player_receive_fields then
return page:on_player_receive_fields(player, context, fields)
end
end
end)