]> git.lizzy.rs Git - xdecor.git/blob - worktable.lua
Work Table : prevent putting unregistered node materials
[xdecor.git] / worktable.lua
1 local worktable = {}
2
3 local material = {
4         "cloud", -- Only used for the formspec display.
5         "wood", "junglewood", "pinewood", "acacia_wood",
6         "tree", "jungletree", "pinetree", "acacia_tree",
7         "cobble", "mossycobble", "desert_cobble",
8         "stone", "sandstone", "desert_stone", "obsidian",
9         "stonebrick", "sandstonebrick", "desert_stonebrick", "obsidianbrick",
10         "snowblock", "coalblock", "copperblock", "steelblock", "goldblock", 
11         "bronzeblock", "mese", "diamondblock",
12         "brick", "cactus", "clay", "ice", "meselamp",
13         "glass", "obsidian_glass"
14 }
15
16 local def = { -- Node name, yield, nodebox shape.
17         {"nanoslab", "16", {-0.5, -0.5, -0.5, 0, -0.4375, 0}},
18         {"micropanel", "16", {-0.5, -0.5, -0.5, 0.5, -0.4375, 0}},
19         {"microslab", "8", {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}},
20         {"panel", "4", {-0.5, -0.5, -0.5, 0.5, 0, 0}},
21         {"slab", "2", {-0.5, -0.5, -0.5, 0.5, 0, 0.5}},
22         {"outerstair", "1", {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, 0, 0, 0, 0.5, 0.5}}},
23         {"stair", "1", {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, 0, 0, 0.5, 0.5, 0.5}}},
24         {"innerstair", "1", {{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, {-0.5, 0, 0, 0.5, 0.5, 0.5}, {-0.5, 0, -0.5, 0, 0.5, 0}}}
25 }
26
27 function worktable.construct(pos)
28         local meta = minetest.get_meta(pos)
29
30         local nodebtn = {}
31         for i=1, #def do
32                 nodebtn[#nodebtn+1] = "item_image_button["..(i-1)..
33                                 ",0.5;1,1;xdecor:"..def[i][1].."_cloud;"..def[i][1]..";]"
34         end
35         nodebtn = table.concat(nodebtn)
36
37         meta:set_string("formspec", "size[8,7;]"..xdecor.fancy_gui..
38                 "label[0,0;Cut your material into...]"..
39                 nodebtn..
40                 "label[0,1.5;Input]"..
41                 "list[current_name;input;0,2;1,1;]"..
42                 "image[1,2;1,1;xdecor_saw.png]"..
43                 "label[2,1.5;Output]"..
44                 "list[current_name;output;2,2;1,1;]"..
45                 "label[5,1.5;Tool]"..
46                 "list[current_name;tool;5,2;1,1;]"..
47                 "image[6,2;1,1;xdecor_anvil.png]"..
48                 "label[6.8,1.5;Hammer]"..
49                 "list[current_name;hammer;7,2;1,1;]"..
50                 "list[current_player;main;0,3.25;8,4;]")
51         meta:set_string("infotext", "Work Table")
52
53         local inv = meta:get_inventory()
54         inv:set_size("output", 1)
55         inv:set_size("input", 1)
56         inv:set_size("tool", 1)
57         inv:set_size("hammer", 1)
58 end
59
60 function worktable.fields(pos, formname, fields, sender)
61         local meta = minetest.get_meta(pos)
62         local inv = meta:get_inventory()
63         local inputstack = inv:get_stack("input", 1)
64         local outputstack = inv:get_stack("output", 1)
65         local outputcount = outputstack:get_count()
66         local inputname = inputstack:get_name()
67         local outputname = outputstack:get_name()
68         local shape, get, outputshape = {}, {}, {}
69         local anz = 0
70
71         for _, d in pairs(def) do
72                 local nb, anz = d[1], d[2]
73                 if outputcount < 99 and fields[nb] then
74                         outputshape = outputname:match(nb)
75                         if nb ~= outputshape and outputcount > 0 then return end
76                         shape = "xdecor:"..nb.."_"..inputname:sub(9)
77                         get = shape.." "..anz
78
79                         if minetest.registered_nodes[shape] then
80                                 inv:add_item("output", get)
81                                 inputstack:take_item()
82                                 inv:set_stack("input", 1, inputstack)
83                         end
84                 end
85         end
86 end
87
88 function worktable.dig(pos, player)
89         local meta = minetest.get_meta(pos)
90         local inv = meta:get_inventory()
91
92         if not inv:is_empty("input") or not inv:is_empty("output") or not
93                         inv:is_empty("hammer") or not inv:is_empty("tool") then
94                 return false
95         end
96         return true
97 end
98
99 function worktable.put(pos, listname, index, stack, player)
100         local stackname = stack:get_name()
101         local count = stack:get_count()
102         local mat = dump(material)
103
104         if listname == "output" then return 0 end
105         if listname == "input" then
106                 if stackname:find("default:") and mat:match(stackname:sub(9)) then
107                         return count
108                 else return 0 end
109         end
110         if listname == "hammer" then
111                 if not (stackname == "xdecor:hammer") then return 0 end
112         end
113         if listname == "tool" then
114                 local tdef = minetest.registered_tools[stackname]
115                 local twear = stack:get_wear()
116                 if not (tdef and twear > 0) then return 0 end
117         end
118
119         return count
120 end
121
122 function worktable.move(pos, from_list, from_index, to_list, to_index, count, player)
123         return 0 end
124
125 xdecor.register("worktable", {
126         description = "Work Table",
127         groups = {cracky=2},
128         sounds = xdecor.wood,
129         tiles = {
130                 "xdecor_worktable_top.png", "xdecor_worktable_top.png",
131                 "xdecor_worktable_sides.png", "xdecor_worktable_sides.png",
132                 "xdecor_worktable_front.png", "xdecor_worktable_front.png"
133         },
134         on_construct = worktable.construct,
135         on_receive_fields = worktable.fields,
136         can_dig = worktable.dig,
137         allow_metadata_inventory_put = worktable.put,
138         allow_metadata_inventory_move = worktable.move
139 })
140
141 for _, m in pairs(material) do
142 for n=1, #def do
143         local w = def[n]
144         local nodename = "default:"..m
145         local ndef = minetest.registered_nodes[nodename]
146         if not ndef then return end
147
148         local function description(m)
149                 if m == "cloud" then return "" end
150                 return m:gsub("%l", string.upper, 1).." "..w[1]:gsub("%l", string.upper, 1)
151         end
152
153         local function groups(m)
154                 if m:find("tree") or m:find("wood") or m == "cactus" then
155                         return {choppy=3, not_in_creative_inventory=1}
156                 elseif m == "clay" or m == "snowblock" then
157                         return {snappy=3, not_in_creative_inventory=1}
158                 end
159                 return {cracky=3, not_in_creative_inventory=1}
160         end
161
162         local function shady(w)
163                 if w:find("stair") or w == "slab" then return false end
164                 return true
165         end
166
167         xdecor.register(w[1].."_"..m, {
168                 description = description(m),
169                 light_source = ndef.light_source,
170                 sounds = ndef.sounds,
171                 tiles = ndef.tiles,
172                 groups = groups(m),
173                 node_box = {type = "fixed", fixed = w[3]},
174                 sunlight_propagates = shady(w[1]),
175                 on_place = minetest.rotate_node
176         })
177 end
178 end
179
180 minetest.register_abm({
181         nodenames = {"xdecor:worktable"},
182         interval = 3, chance = 1,
183         action = function(pos, node, active_object_count, active_object_count_wider)
184                 local meta = minetest.get_meta(pos)
185                 local inv = meta:get_inventory()
186                 local tool = inv:get_stack("tool", 1)
187                 local hammer = inv:get_stack("hammer", 1)
188                 local wear = tool:get_wear()
189                 local wear2 = hammer:get_wear()
190
191                 local repair = -500 -- Tool's repairing factor (0-65535 -- 0 = new condition).
192                 local wearhammer = 250 -- Hammer's wearing factor (0-65535 -- 0 = new condition).
193
194                 if tool:is_empty() or hammer:is_empty() or wear == 0 then return end
195
196                 tool:add_wear(repair)
197                 hammer:add_wear(wearhammer)
198
199                 inv:set_stack("tool", 1, tool)
200                 inv:set_stack("hammer", 1, hammer)
201         end
202 })