SmallJoker
2018-07-19 fb93388f06fe87ee75aaaf04cf6edcf01a26d981
commit | author | age
41a10a 1 local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
179364 2
fcef0e 3 local pipeworks = rawget(_G, "pipeworks")
11f20d 4 local fs_helpers = rawget(_G, "fs_helpers")
VE 5
6 local allow_label = ""
b6d343 7 local tube_entry = ""
11f20d 8 local shift_edit_field = 0
VE 9
fcef0e 10 if not minetest.get_modpath("pipeworks") then
R 11     -- Pipeworks is not installed. Simulate using a dummy table...
12     pipeworks = {}
11f20d 13     fs_helpers = {}
fcef0e 14     local pipeworks_meta = {}
R 15     setmetatable(pipeworks, pipeworks_meta)
16     local dummy = function()
17         end
18     pipeworks_meta.__index = function(table, key)
19             print("[technic_chests] WARNING: variable or method '"..key.."' not present in dummy pipeworks table - assuming it is a method...")
20             pipeworks[key] = dummy
21             return dummy
22         end
23     pipeworks.after_place = dummy
24     pipeworks.after_dig = dummy
11f20d 25     fs_helpers.cycling_button = function() return "" end
VE 26 else
27     fs_helpers = pipeworks.fs_helpers
28     allow_label = "label[0.9,0.36;Allow splitting incoming stacks from tubes]"
29     shift_edit_field = 3
b6d343 30     tube_entry = "^pipeworks_tube_connection_metallic.png"
fcef0e 31 end
R 32
78cacd 33 local chest_mark_colors = {
179364 34     {"black", S("Black")},
S 35     {"blue", S("Blue")},
36     {"brown", S("Brown")},
39c41a 37     {"cyan", S("Cyan")},
179364 38     {"dark_green", S("Dark Green")},
S 39     {"dark_grey", S("Dark Grey")},
40     {"green", S("Green")},
41     {"grey", S("Grey")},
42     {"magenta", S("Magenta")},
43     {"orange", S("Orange")},
44     {"pink", S("Pink")},
45     {"red", S("Red")},
46     {"violet", S("Violet")},
47     {"white", S("White")},
48     {"yellow", S("Yellow")},
78cacd 49 }
S 50
51
52 local function colorid_to_postfix(id)
179364 53     return chest_mark_colors[id] and "_"..chest_mark_colors[id][1] or ""
78cacd 54 end
S 55
56
1bf52c 57 local function get_color_buttons(coleft, lotop)
78cacd 58     local buttons_string = ""
S 59     for y = 0, 3 do
60         for x = 0, 3 do
61             local file_name = "technic_colorbutton"..(y * 4 + x)..".png"
62             buttons_string = buttons_string.."image_button["
1bf52c 63                 ..(coleft + 0.1 + x * 0.7)..","..(lotop + 0.1 + y * 0.7)
78cacd 64                 ..";0.8,0.8;"..file_name..";color_button"
S 65                 ..(y * 4 + x + 1)..";]"
66         end
67     end
68     return buttons_string
69 end
70
71
72 local function check_color_buttons(pos, meta, chest_name, fields)
73     for i = 1, 16 do
74         if fields["color_button"..i] then
d60e3f 75             local node = minetest.get_node(pos)
Z 76             node.name = chest_name..colorid_to_postfix(i)
77             minetest.swap_node(pos, node)
179364 78             meta:set_string("color", i)
78cacd 79             return
S 80         end
81     end
82 end
83
5c689a 84 local function set_formspec(pos, data, page)
R 85     local meta = minetest.get_meta(pos)
86     local node = minetest.get_node(pos)
1bf52c 87     local formspec = data.base_formspec
11f20d 88     formspec = formspec..fs_helpers.cycling_button(
VE 89                 meta,
90                 "image_button[0,0.35;1,0.6",
91                 "splitstacks",
92                 {
fab2c4 93                     pipeworks.button_off,
d2fb24 94                     pipeworks.button_on
11f20d 95                 }
VE 96             )..allow_label
97
5c689a 98     if data.autosort then
R 99         local status = meta:get_int("autosort")
1bf52c 100         formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]"
78cacd 101     end
5c689a 102     if data.infotext then
78cacd 103         local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext"))
5c689a 104         if page == "main" then
11f20d 105             formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
78cacd 106                     .."technic_pencil_icon.png;edit_infotext;]"
11f20d 107                     .."label["..(shift_edit_field+data.hileft+3)..",0;"..formspec_infotext.."]"
5c689a 108         elseif page == "edit_infotext" then
11f20d 109             formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
78cacd 110                     .."technic_checkmark_icon.png;save_infotext;]"
11f20d 111                     .."field["..(shift_edit_field+data.hileft+3.3)..",0.2;4.8,1;"
179364 112                     .."infotext_box;"..S("Edit chest description:")..";"
78cacd 113                     ..formspec_infotext.."]"
S 114         end
5c689a 115     end
R 116     if data.color then
117         local colorID = meta:get_int("color")
118         local colorName
119         if chest_mark_colors[colorID] then
120             colorName = chest_mark_colors[colorID][2]
121         else
122             colorName = S("None")
123         end
1bf52c 124         formspec = formspec.."label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]"
5c689a 125     end
R 126     meta:set_string("formspec", formspec)
127 end
128
129 local function sort_inventory(inv)
130     local inlist = inv:get_list("main")
131     local typecnt = {}
132     local typekeys = {}
133     for _, st in ipairs(inlist) do
134         if not st:is_empty() then
135             local n = st:get_name()
136             local w = st:get_wear()
137             local m = st:get_metadata()
138             local k = string.format("%s %05d %s", n, w, m)
139             if not typecnt[k] then
930c51 140                 typecnt[k] = {st}
5c689a 141                 table.insert(typekeys, k)
930c51 142             else
D 143                 table.insert(typecnt[k], st)
5c689a 144             end
R 145         end
146     end
147     table.sort(typekeys)
930c51 148     inv:set_list("main", {})
5c689a 149     for _, k in ipairs(typekeys) do
930c51 150         for _, item in ipairs(typecnt[k]) do
D 151             inv:add_item("main", item)
5c689a 152         end
R 153     end
154 end
155
156 local function get_receive_fields(name, data)
157     local lname = name:lower()
158     return function(pos, formname, fields, sender)
159         local meta = minetest.get_meta(pos)
160         local page = "main"
161         if fields.sort or (data.autosort and fields.quit and meta:get_int("autosort") == 1) then
162             sort_inventory(meta:get_inventory())
163         end
164         if fields.edit_infotext then
165             page = "edit_infotext"
166         end
167         if fields.autosort_to_1 then meta:set_int("autosort", 1) end
168         if fields.autosort_to_0 then meta:set_int("autosort", 0) end
169         if fields.infotext_box then
170             meta:set_string("infotext", fields.infotext_box)
171         end
78cacd 172         if data.color then
S 173             -- This sets the node
174             local nn = "technic:"..lname..(data.locked and "_locked" or "").."_chest"
175             check_color_buttons(pos, meta, nn, fields)
176         end
11f20d 177         if fields["fs_helpers_cycling:0:splitstacks"]
VE 178           or fields["fs_helpers_cycling:1:splitstacks"] then
179             if not pipeworks.may_configure(pos, sender) then return end
180             fs_helpers.on_receive_fields(pos, fields)
181         end
182
96ad67 183         meta:get_inventory():set_size("main", data.width * data.height)
5c689a 184         set_formspec(pos, data, page)
78cacd 185     end
S 186 end
187
1d7cb7 188 function technic.chests:definition(name, data)
78cacd 189     local lname = name:lower()
179364 190     name = S(name)
1bf52c 191     local d = {}
Z 192     for k, v in pairs(data) do d[k] = v end
193     data = d
78cacd 194
1bf52c 195     data.lowidth = 8
Z 196     data.ovwidth = math.max(data.lowidth, data.width)
197     data.hileft = (data.ovwidth - data.width) / 2
198     data.loleft = (data.ovwidth - data.lowidth) / 2
199     if data.color then
200         if data.lowidth + 3 <= data.ovwidth then
201             data.coleft = data.ovwidth - 3
202             if data.loleft + data.lowidth > data.coleft then
203                 data.loleft = data.coleft - data.lowidth
204             end
205         else
206             data.loleft = 0
207             data.coleft = data.lowidth
208             data.ovwidth = data.lowidth + 3
209         end
210     end
211     data.lotop = data.height + 2
212     data.ovheight = data.lotop + 4
78cacd 213
S 214     local locked_after_place = nil
215     local front = {"technic_"..lname.."_chest_front.png"}
473505 216     data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]"..
39c41a 217             "label[0,0;"..S("%s Chest"):format(name).."]"..
473505 218             "list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]"..
1bf52c 219             "list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]"..
24eca0 220             "background[-0.19,-0.25;"..(data.ovwidth+0.4)..","..(data.ovheight+0.75)..";technic_chest_form_bg.png]"..
1bf52c 221             "background["..data.hileft..",1;"..data.width..","..data.height..";technic_"..lname.."_chest_inventory.png]"..
d732c8 222             "background["..data.loleft..","..data.lotop..";8,4;technic_main_inventory.png]"..
E 223             "listring[]"
11f20d 224
5c689a 225     if data.sort then
1bf52c 226         data.base_formspec = data.base_formspec.."button["..data.hileft..","..(data.height+1.1)..";1,0.8;sort;"..S("Sort").."]"
5c689a 227     end
78cacd 228     if data.color then
1bf52c 229         data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop)
78cacd 230     end
S 231
232     if data.locked then
233         locked_after_place = function(pos, placer)
234             local meta = minetest.get_meta(pos)
235             meta:set_string("owner", placer:get_player_name() or "")
179364 236             meta:set_string("infotext",
S 237                     S("%s Locked Chest (owned by %s)")
238                     :format(name, meta:get_string("owner")))
cbfeb0 239             pipeworks.after_place(pos)
78cacd 240         end
S 241         table.insert(front, "technic_"..lname.."_chest_lock_overlay.png")
cbfeb0 242     else
VE 243         locked_after_place = pipeworks.after_place
78cacd 244     end
S 245
179364 246     local desc
S 247     if data.locked then
248         desc = S("%s Locked Chest"):format(name)
249     else
250         desc = S("%s Chest"):format(name)
251     end
252
b6d343 253     local tentry = tube_entry
VE 254     if tube_entry ~= "" then
255         if lname == "wooden" then
256             tentry = "^pipeworks_tube_connection_wooden.png"
257         elseif lname == "mithril" then
258             tentry = "^pipeworks_tube_connection_stony.png"
259         end
260     end
78cacd 261     local def = {
179364 262         description = desc,
b6d343 263         tiles = {
VE 264             "technic_"..lname.."_chest_top.png"..tentry,
265             "technic_"..lname.."_chest_top.png"..tentry,
266             "technic_"..lname.."_chest_side.png"..tentry,
267             "technic_"..lname.."_chest_side.png"..tentry,
268             "technic_"..lname.."_chest_side.png"..tentry,
269             table.concat(front, "^")
270         },
78cacd 271         paramtype2 = "facedir",
S 272         groups = self.groups,
273         tube = self.tube,
274         legacy_facedir_simple = true,
275         sounds = default.node_sound_wood_defaults(),
cbfeb0 276         after_place_node = locked_after_place,
d5db18 277         after_dig_node = pipeworks.after_dig,
VE 278
78cacd 279         on_construct = function(pos)
S 280             local meta = minetest.get_meta(pos)
179364 281             meta:set_string("infotext", S("%s Chest"):format(name))
5c689a 282             set_formspec(pos, data, "main")
78cacd 283             local inv = meta:get_inventory()
96ad67 284             inv:set_size("main", data.width * data.height)
78cacd 285         end,
S 286         can_dig = self.can_dig,
287         on_receive_fields = get_receive_fields(name, data),
288         on_metadata_inventory_move = self.on_inv_move,
289         on_metadata_inventory_put = self.on_inv_put,
930c51 290         on_metadata_inventory_take = self.on_inv_take,
6b52c7 291         on_blast = function(pos)
T 292             local drops = {}
293             default.get_inventory_drops(pos, "main", drops)
ec6354 294             drops[#drops+1] = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
6b52c7 295             minetest.remove_node(pos)
T 296             return drops
297         end,
78cacd 298     }
S 299     if data.locked then
300         def.allow_metadata_inventory_move = self.inv_move
301         def.allow_metadata_inventory_put = self.inv_put
302         def.allow_metadata_inventory_take = self.inv_take
35da22 303         def.on_blast = function() end
ec6354 304         def.can_dig = function(pos,player)
T 305             local meta = minetest.get_meta(pos);
306             local inv = meta:get_inventory()
307             return inv:is_empty("main") and default.can_interact_with_node(player, pos)
35da22 308         end
6b52c7 309         def.on_skeleton_key_use = function(pos, player, newsecret)
T 310             local meta = minetest.get_meta(pos)
311             local owner = meta:get_string("owner")
312             local name = player:get_player_name()
313
314             -- verify placer is owner of lockable chest
315             if owner ~= name then
316                 minetest.record_protection_violation(pos, name)
317                 minetest.chat_send_player(name, "You do not own this chest.")
318                 return nil
319             end
320
321             local secret = meta:get_string("key_lock_secret")
322             if secret == "" then
323                 secret = newsecret
324                 meta:set_string("key_lock_secret", secret)
325             end
326
327             return secret, "a locked chest", owner
35da22 328         end
78cacd 329     end
1d7cb7 330     return def
Z 331 end
78cacd 332
1d7cb7 333 function technic.chests:register(name, data)
Z 334     local def = technic.chests:definition(name, data)
78cacd 335
1d7cb7 336     local nn = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
78cacd 337     minetest.register_node(":"..nn, def)
S 338
339     if data.color then
1d7cb7 340         local mk_front
Z 341         if string.find(def.tiles[6], "%^") then
342             mk_front = function (overlay) return def.tiles[6]:gsub("%^", "^"..overlay.."^") end
343         else
344             mk_front = function (overlay) return def.tiles[6].."^"..overlay end
345         end
78cacd 346         for i = 1, 15 do
S 347             local postfix = colorid_to_postfix(i)
348             local colordef = {}
349             for k, v in pairs(def) do
350                 colordef[k] = v
351             end
352             colordef.drop = nn
353             colordef.groups = self.groups_noinv
1d7cb7 354             colordef.tiles = { def.tiles[1], def.tiles[2], def.tiles[3], def.tiles[4], def.tiles[5], mk_front("technic_chest_overlay"..postfix..".png") }
78cacd 355             minetest.register_node(":"..nn..postfix, colordef)
S 356         end
357     end
358
359 end
360