Rogier
2015-02-07 fcef0ef987f7bd7d26d1c8a4d27a562822b580bc
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")
R 4 if not minetest.get_modpath("pipeworks") then
5     -- Pipeworks is not installed. Simulate using a dummy table...
6     pipeworks = {}
7     local pipeworks_meta = {}
8     setmetatable(pipeworks, pipeworks_meta)
9     local dummy = function()
10         end
11     pipeworks_meta.__index = function(table, key)
12             print("[technic_chests] WARNING: variable or method '"..key.."' not present in dummy pipeworks table - assuming it is a method...")
13             pipeworks[key] = dummy
14             return dummy
15         end
16     pipeworks.after_place = dummy
17     pipeworks.after_dig = dummy
18 end
19
78cacd 20 local chest_mark_colors = {
179364 21     {"black", S("Black")},
S 22     {"blue", S("Blue")},
23     {"brown", S("Brown")},
39c41a 24     {"cyan", S("Cyan")},
179364 25     {"dark_green", S("Dark Green")},
S 26     {"dark_grey", S("Dark Grey")},
27     {"green", S("Green")},
28     {"grey", S("Grey")},
29     {"magenta", S("Magenta")},
30     {"orange", S("Orange")},
31     {"pink", S("Pink")},
32     {"red", S("Red")},
33     {"violet", S("Violet")},
34     {"white", S("White")},
35     {"yellow", S("Yellow")},
78cacd 36 }
S 37
38
39 local function colorid_to_postfix(id)
179364 40     return chest_mark_colors[id] and "_"..chest_mark_colors[id][1] or ""
78cacd 41 end
S 42
43
1bf52c 44 local function get_color_buttons(coleft, lotop)
78cacd 45     local buttons_string = ""
S 46     for y = 0, 3 do
47         for x = 0, 3 do
48             local file_name = "technic_colorbutton"..(y * 4 + x)..".png"
49             buttons_string = buttons_string.."image_button["
1bf52c 50                 ..(coleft + 0.1 + x * 0.7)..","..(lotop + 0.1 + y * 0.7)
78cacd 51                 ..";0.8,0.8;"..file_name..";color_button"
S 52                 ..(y * 4 + x + 1)..";]"
53         end
54     end
55     return buttons_string
56 end
57
58
59 local function check_color_buttons(pos, meta, chest_name, fields)
60     for i = 1, 16 do
61         if fields["color_button"..i] then
d60e3f 62             local node = minetest.get_node(pos)
Z 63             node.name = chest_name..colorid_to_postfix(i)
64             minetest.swap_node(pos, node)
179364 65             meta:set_string("color", i)
78cacd 66             return
S 67         end
68     end
69 end
70
5c689a 71 local function set_formspec(pos, data, page)
R 72     local meta = minetest.get_meta(pos)
73     local node = minetest.get_node(pos)
1bf52c 74     local formspec = data.base_formspec
5c689a 75     if data.autosort then
R 76         local status = meta:get_int("autosort")
1bf52c 77         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 78     end
5c689a 79     if data.infotext then
78cacd 80         local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext"))
5c689a 81         if page == "main" then
1bf52c 82             formspec = formspec.."image_button["..(data.hileft+2.1)..",0.1;0.8,0.8;"
78cacd 83                     .."technic_pencil_icon.png;edit_infotext;]"
1bf52c 84                     .."label["..(data.hileft+3)..",0;"..formspec_infotext.."]"
5c689a 85         elseif page == "edit_infotext" then
1bf52c 86             formspec = formspec.."image_button["..(data.hileft+2.1)..",0.1;0.8,0.8;"
78cacd 87                     .."technic_checkmark_icon.png;save_infotext;]"
1bf52c 88                     .."field["..(data.hileft+3.3)..",0.2;4.8,1;"
179364 89                     .."infotext_box;"..S("Edit chest description:")..";"
78cacd 90                     ..formspec_infotext.."]"
S 91         end
5c689a 92     end
R 93     if data.color then
94         local colorID = meta:get_int("color")
95         local colorName
96         if chest_mark_colors[colorID] then
97             colorName = chest_mark_colors[colorID][2]
98         else
99             colorName = S("None")
100         end
1bf52c 101         formspec = formspec.."label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]"
5c689a 102     end
R 103     meta:set_string("formspec", formspec)
104 end
105
106 local function sort_inventory(inv)
107     local inlist = inv:get_list("main")
108     local typecnt = {}
109     local typekeys = {}
110     for _, st in ipairs(inlist) do
111         if not st:is_empty() then
112             local n = st:get_name()
113             local w = st:get_wear()
114             local m = st:get_metadata()
115             local k = string.format("%s %05d %s", n, w, m)
116             if not typecnt[k] then
117                 typecnt[k] = {
118                     name = n,
119                     wear = w,
120                     metadata = m,
121                     stack_max = st:get_stack_max(),
122                     count = 0,
123                 }
124                 table.insert(typekeys, k)
125             end
126             typecnt[k].count = typecnt[k].count + st:get_count()
127         end
128     end
129     table.sort(typekeys)
130     local outlist = {}
131     for _, k in ipairs(typekeys) do
132         local tc = typecnt[k]
133         while tc.count > 0 do
134             local c = math.min(tc.count, tc.stack_max)
135             table.insert(outlist, ItemStack({
136                 name = tc.name,
137                 wear = tc.wear,
138                 metadata = tc.metadata,
139                 count = c,
140             }))
141             tc.count = tc.count - c
142         end
143     end
144     if #outlist > #inlist then return end
145     while #outlist < #inlist do
146         table.insert(outlist, ItemStack(nil))
147     end
148     inv:set_list("main", outlist)
149 end
150
151 local function get_receive_fields(name, data)
152     local lname = name:lower()
153     return function(pos, formname, fields, sender)
154         local meta = minetest.get_meta(pos)
155         local page = "main"
156         if fields.sort or (data.autosort and fields.quit and meta:get_int("autosort") == 1) then
157             sort_inventory(meta:get_inventory())
158         end
159         if fields.edit_infotext then
160             page = "edit_infotext"
161         end
162         if fields.autosort_to_1 then meta:set_int("autosort", 1) end
163         if fields.autosort_to_0 then meta:set_int("autosort", 0) end
164         if fields.infotext_box then
165             meta:set_string("infotext", fields.infotext_box)
166         end
78cacd 167         if data.color then
S 168             -- This sets the node
169             local nn = "technic:"..lname..(data.locked and "_locked" or "").."_chest"
170             check_color_buttons(pos, meta, nn, fields)
171         end
96ad67 172         meta:get_inventory():set_size("main", data.width * data.height)
5c689a 173         set_formspec(pos, data, page)
78cacd 174     end
S 175 end
176
177
1d7cb7 178 function technic.chests:definition(name, data)
78cacd 179     local lname = name:lower()
179364 180     name = S(name)
1bf52c 181     local d = {}
Z 182     for k, v in pairs(data) do d[k] = v end
183     data = d
78cacd 184
1bf52c 185     data.lowidth = 8
Z 186     data.ovwidth = math.max(data.lowidth, data.width)
187     data.hileft = (data.ovwidth - data.width) / 2
188     data.loleft = (data.ovwidth - data.lowidth) / 2
189     if data.color then
190         if data.lowidth + 3 <= data.ovwidth then
191             data.coleft = data.ovwidth - 3
192             if data.loleft + data.lowidth > data.coleft then
193                 data.loleft = data.coleft - data.lowidth
194             end
195         else
196             data.loleft = 0
197             data.coleft = data.lowidth
198             data.ovwidth = data.lowidth + 3
199         end
200     end
201     data.lotop = data.height + 2
202     data.ovheight = data.lotop + 4
78cacd 203
S 204     local locked_after_place = nil
205     local front = {"technic_"..lname.."_chest_front.png"}
473505 206     data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]"..
39c41a 207             "label[0,0;"..S("%s Chest"):format(name).."]"..
473505 208             "list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]"..
1bf52c 209             "list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]"..
24eca0 210             "background[-0.19,-0.25;"..(data.ovwidth+0.4)..","..(data.ovheight+0.75)..";technic_chest_form_bg.png]"..
1bf52c 211             "background["..data.hileft..",1;"..data.width..","..data.height..";technic_"..lname.."_chest_inventory.png]"..
d452d1 212             "background["..data.loleft..","..data.lotop..";8,4;technic_main_inventory.png]"
5c689a 213     if data.sort then
1bf52c 214         data.base_formspec = data.base_formspec.."button["..data.hileft..","..(data.height+1.1)..";1,0.8;sort;"..S("Sort").."]"
5c689a 215     end
78cacd 216     if data.color then
1bf52c 217         data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop)
78cacd 218     end
S 219
220     if data.locked then
221         locked_after_place = function(pos, placer)
222             local meta = minetest.get_meta(pos)
223             meta:set_string("owner", placer:get_player_name() or "")
179364 224             meta:set_string("infotext",
S 225                     S("%s Locked Chest (owned by %s)")
226                     :format(name, meta:get_string("owner")))
cbfeb0 227             pipeworks.after_place(pos)
78cacd 228         end
S 229         table.insert(front, "technic_"..lname.."_chest_lock_overlay.png")
cbfeb0 230     else
VE 231         locked_after_place = pipeworks.after_place
78cacd 232     end
S 233
179364 234     local desc
S 235     if data.locked then
236         desc = S("%s Locked Chest"):format(name)
237     else
238         desc = S("%s Chest"):format(name)
239     end
240
78cacd 241     local def = {
179364 242         description = desc,
78cacd 243         tiles = {"technic_"..lname.."_chest_top.png", "technic_"..lname.."_chest_top.png",
S 244             "technic_"..lname.."_chest_side.png", "technic_"..lname.."_chest_side.png",
245             "technic_"..lname.."_chest_side.png", table.concat(front, "^")},
246         paramtype2 = "facedir",
247         groups = self.groups,
248         tube = self.tube,
249         legacy_facedir_simple = true,
250         sounds = default.node_sound_wood_defaults(),
cbfeb0 251         after_place_node = locked_after_place,
d5db18 252         after_dig_node = pipeworks.after_dig,
VE 253
78cacd 254         on_construct = function(pos)
S 255             local meta = minetest.get_meta(pos)
179364 256             meta:set_string("infotext", S("%s Chest"):format(name))
5c689a 257             set_formspec(pos, data, "main")
78cacd 258             local inv = meta:get_inventory()
96ad67 259             inv:set_size("main", data.width * data.height)
78cacd 260         end,
S 261         can_dig = self.can_dig,
262         on_receive_fields = get_receive_fields(name, data),
263         on_metadata_inventory_move = self.on_inv_move,
264         on_metadata_inventory_put = self.on_inv_put,
265         on_metadata_inventory_take = self.on_inv_take,
266     }
267     if data.locked then
268         def.allow_metadata_inventory_move = self.inv_move
269         def.allow_metadata_inventory_put = self.inv_put
270         def.allow_metadata_inventory_take = self.inv_take
271     end
1d7cb7 272     return def
Z 273 end
78cacd 274
1d7cb7 275 function technic.chests:register(name, data)
Z 276     local def = technic.chests:definition(name, data)
78cacd 277
1d7cb7 278     local nn = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
78cacd 279     minetest.register_node(":"..nn, def)
S 280
281     if data.color then
1d7cb7 282         local mk_front
Z 283         if string.find(def.tiles[6], "%^") then
284             mk_front = function (overlay) return def.tiles[6]:gsub("%^", "^"..overlay.."^") end
285         else
286             mk_front = function (overlay) return def.tiles[6].."^"..overlay end
287         end
78cacd 288         for i = 1, 15 do
S 289             local postfix = colorid_to_postfix(i)
290             local colordef = {}
291             for k, v in pairs(def) do
292                 colordef[k] = v
293             end
294             colordef.drop = nn
295             colordef.groups = self.groups_noinv
1d7cb7 296             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 297             minetest.register_node(":"..nn..postfix, colordef)
S 298         end
299     end
300
301 end
302