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