Differences From
Artifact [800ac068f1]:
8 8 -- a+b = compose a new spec from the spec parts a and b.
9 9 -- this is used e.g. for creating tier-based
10 10 -- fabspecs.
11 11 --
12 12 -- * used for determining quantities. that is,
13 13 -- f*x = spec to make x instances of f
14 14 --
15 --- new fab fields must be defined in starlit.type.fab.opClass.
15 +-- new fab fields must be defined in starlit.type.fab.fields.
16 16 -- this maps a name to fn(a,b,n) -> quant, where a is the first
17 17 -- argument, b is a compounding amount, and n is a quantity of
18 18 -- items to produce. fields that are unnamed will be underwritten
19 19
20 20 local function fQuant(a,b,n) return ((a or 0)+(b or 0))*n end
21 21 local function fFac (a,b,n)
22 22 if a == nil and b == nil then return nil end
................................................................................
26 26 f = (a or 1)*(b or 1)
27 27 end
28 28 return f*n
29 29 end
30 30 local function fReq (a,b,n) return a or b end
31 31 local function fFlag (a,b,n) return a and b end
32 32 local function fSize (a,b,n) return math.max(a,b) end
33 -local opClass = {
33 +
34 +local F = string.format
35 +local lib = starlit.mod.lib
36 +
37 +local fields = {
34 38 -- fabrication eligibility will be determined by which kinds
35 39 -- of input a particular fabricator can introduce. e.g. a
36 40 -- printer with a but no cache can only print items whose
37 41 -- recipe only names elements as ingredients
38 -
39 - -- ingredients
40 - element = fQuant; -- (g)
41 - gas = fQuant; -- ()
42 - liquid = fQuant; -- (l)
43 - crystal = fQuant; -- (g)
44 - item = fQuant; -- n
45 - metal = fQuant; -- (g)
46 - metalIngot = fQuant; -- (g)
42 + element = {
43 + name = {"element", "elements"};
44 + string = function(x, n, long)
45 + local el = starlit.world.material.element.db[x]
46 + return lib.math.si('g', n) .. ' ' .. ((not long and el.sym) or el.name)
47 + end;
48 + image = function(x, n)
49 + return string.format('starlit-element-%s.png', x)
50 + end;
51 + op = fQuant;
52 + };
53 + metal ={
54 + name = {"metal", "metals"};
55 + string = function(x, n)
56 + local met = starlit.world.material.metal.db[x]
57 + return lib.math.si('g', n) .. ' ' .. met.name
58 + end;
59 + image = function(x, n)
60 + local met = starlit.world.material.metal.db[x]
61 + return ItemStack(met.form.ingot):get_definition().inventory_image
62 + end;
63 + op = fQuant;
64 + };
65 + liquid = {
66 + name = {"liquid", "liquids"};
67 + string = function(x, n)
68 + local liq = starlit.world.material.liquid.db[x]
69 + return lib.math.si('L', n) .. ' ' .. liq.name
70 + end;
71 + op = fQuant;
72 + };
73 + gas = {
74 + name = {"gas", "gasses"};
75 + string = function(x, n)
76 + local gas = starlit.world.material.gas.db[x]
77 + return lib.math.si('g', n) .. ' ' .. gas.name
78 + end;
79 + op = fQuant;
80 + };
81 +-- crystal = {
82 +-- op = fQuant;
83 +-- };
84 + item = {
85 + name = {"item", "items"};
86 + string = function(x, n)
87 + local i = minetest.registered_items[x]
88 + return tostring(n) .. 'x ' .. i.short_description
89 + end;
90 + };
91 +
47 92 -- factors
48 - cost = fFac; -- units vary
49 - time = fFac; -- (s)
93 +
94 + cost = {op=fFac}; -- units vary
95 + time = {op=fFac}; -- (s)
50 96 -- print: base printing time
51 - size = fSize;
97 + size = {op=fSize};
52 98 -- printBay: size of the printer bay necessary to produce the item
53 - req = fReq;
54 - flag = fFlag; -- means that can be used to produce the item & misc flags
99 + req = {op=fReq};
100 + flag = {op=fFlag}; -- means that can be used to produce the item & misc flags
55 101 -- print: allow production with a printer
56 102 -- smelt: allow production with a smelter
57 103 -- all else defaults to underwrite
58 104 }
59 105
60 -local F = string.format
61 -local strClass = {
62 - element = function(x, n)
63 - local el = starlit.world.material.element[x]
64 - return lib.math.si('g', n) .. ' ' .. (el.sym or el.name)
65 - end;
66 - metal = function(x, n)
67 - local met = starlit.world.material.metal[x]
68 - return lib.math.si('g', n) .. ' ' .. met.name
69 - end;
70 - liquid = function(x, n)
71 - local liq = starlit.world.material.liquid[x]
72 - return lib.math.si('L', n) .. ' ' .. liq.name
73 - end;
74 - gas = function(x, n)
75 - local gas = starlit.world.material.gas[x]
76 - return lib.math.si('g', n) .. ' ' .. gas.name
77 - end;
78 - item = function(x, n)
79 - local i = minetest.registered_items[x]
80 - return tostring(n) .. 'x ' .. i.short_description
81 - end;
82 -}
83 -
84 106 local order = {
85 107 'element', 'metal', 'liquid', 'gas', 'item'
86 108 }
87 109
88 110 local lib = starlit.mod.lib
89 111
90 112 local fab fab = lib.class {
91 113 __name = 'starlit:fab';
92 114
93 - opClass = opClass;
94 - strClass = strClass;
115 + fields = fields;
95 116 order = order;
96 117 construct = function(q) return q end;
97 118 __index = {
98 119 elementalize = function(self)
99 120 local e = fab {element = self.element or {}}
100 121 for _, kind in pairs {'metal', 'gas', 'liquid'} do
101 122 for m,mass in pairs(self[kind] or {}) do
................................................................................
154 175 local fml = {}
155 176 for i, v in ipairs(sub) do fml[i] = v.f end
156 177 if f then table.insert(fml, f) end
157 178 fml = table.concat(fml, ' + ')
158 179
159 180 return fml, ts
160 181 end;
182 +
183 + visualize = function(self)
184 + local all = {}
185 + for i,o in ipairs(order) do
186 + local t = {}
187 + if self[o] then
188 + for mat,amt in pairs(self[o]) do
189 + local v = {}
190 + v.id = mat
191 + v.n = amt
192 + if fields[o].string then
193 + v.label = fields[o].string(mat,amt,true)
194 + end
195 + if fields[o].image then
196 + v.img = fields[o].image(mat,amt)
197 + end
198 + table.insert(t,v)
199 + end
200 + end
201 + if fields[o].sort then
202 + table.sort(t, function(a,b) return fields[o].sort(a.id, b.id) end)
203 + end
204 + if next(t) then table.insert(all, {
205 + id=o, list=t;
206 + header=fields[o].name[t[2] and 2 or 1];
207 + }) end
208 + end
209 + return all
210 + end;
161 211 };
162 212
163 213 __tostring = function(self)
164 214 local t = {}
165 215 for i,o in ipairs(order) do
166 - if self[o] then
216 + if self[o] and fields[o].string then
167 217 for mat,amt in pairs(self[o]) do
168 218 if amt > 0 then
169 - table.insert(t, strClass[o](mat, amt))
219 + table.insert(t, fields[o].string(mat, amt))
170 220 end
171 221 end
172 222 end
173 223 end
174 224 return table.concat(t, ", ")
175 225 end;
176 -
177 226
178 227 __add = function(a,b)
179 228 local new = fab {}
180 229 for cat, vals in pairs(a) do
181 230 new[cat] = lib.tbl.copy(vals)
182 231 end
183 232 for cat, vals in pairs(b) do
184 233 if not new[cat] then
185 234 new[cat] = lib.tbl.copy(vals)
186 235 else
187 - local f = opClass[cat]
236 + local f = fields[cat].op
188 237 for k,v in pairs(vals) do
189 238 local n = f(new[cat][k], v, 1)
190 239 new[cat][k] = n > 0 and n or nil
191 240 end
192 241 end
193 242 end
194 243 return new
195 244 end;
196 245
197 246 __mul = function(x,n)
198 247 local new = fab {}
199 248 for cat, vals in pairs(x) do
200 249 new[cat] = {}
201 - local f = opClass[cat]
250 + local f = fields[cat].op
202 251 for k,v in pairs(vals) do
203 252 local num = f(v,nil,n)
204 253 new[cat][k] = num > 0 and num or nil
205 254 end
206 255 end
207 256 return new
208 257 end;