Differences From
Artifact [c21bb1a7ca]:
34 34
35 35 metal_grindvalue = 4;
36 36 -- how many powders an ingot is worth
37 37
38 38 default_grindvalue = 1;
39 39 -- number of items produced when not otherwise
40 40 -- specified
41 +
42 + default_grindcost = 1;
43 + -- number of items needed to perform a grind when
44 + -- not otherwise specified
41 45
42 46 default_hardness = 1;
43 47 -- difficulty to grind an item when not otherwise
44 48 -- specified
45 49
46 50 metal_grindcost = 1;
47 51 -- number of metal items needed to perform a grind
48 52 }
49 53 local mill_formspec_update = function(pos,pct,stat1,stat2)
50 54 -- eventually we'll want to display available
51 - -- energy here, but for now we're just assuming
52 - -- max energy available
55 + -- energy here
53 56
54 57 -- local meta = minetest.get_meta(pos)
55 58 -- local inv = meta:get_inventory()
56 59 -- local torque = 20
57 60 stat1 = stat1 or 'off'
58 61 minetest.get_meta(pos):set_string('formspec', string.format([[
59 62 size[8,7.2]
................................................................................
79 82 if slot == 'grinder' then
80 83 if minetest.get_item_group(item:get_name(), 'sorcery_mill_grindhead')~=0
81 84 then return 1 end
82 85 elseif slot == 'input' then
83 86 local metal = sorcery.data.metallookup[item:get_name()]
84 87 local mat = sorcery.matreg.lookup[item:get_name()]
85 88 local comp = sorcery.data.compat.grindables[item:get_name()]
86 - if metal or mat.metal or comp then
89 + if metal or (mat and mat.metal) or comp then
87 90 return item:get_count()
88 91 else
89 - local mat = item:get_definition()._matprop
92 + mat = item:get_definition()._matprop
90 93 if mat and mat.grindvalue then
91 94 return item:get_count()
92 95 end
93 96 end
94 97 end
95 98 return 0
96 99 end
97 100 local matprops = function(item)
98 101 local metal = sorcery.data.metallookup[item:get_name()]
99 102 if not metal then
100 103 -- allow grinding of armor and tools back to their
101 104 -- original components
102 105 local mat = sorcery.matreg.lookup[item:get_name()]
103 - if mat.metal then
106 + if mat and mat.metal then
104 107 metal = mat
105 - else
106 - return nil
107 108 end
108 109 end
109 110 local mp = item:get_definition()._matprop
110 111 or sorcery.data.compat.grindables[item:get_name()]
111 112 or {}
112 113
113 114 again = true
114 115 if metal then mp = {
115 - hardness = metal.data.hardness or mp.hardness or constants.default_hardness;
116 - grindvalue = metal.value or mp.grindvalue or (metal and constants.metal_grindvalue) or constants.default_grindvalue;
117 - powder = metal.data.parts.powder or mp.powder;
118 - grindcost = constants.metal_grindcost or mp.grindcost; -- invariant for metal
116 + hardness = mp.hardness or metal.data.hardness;
117 + grindvalue = ((mp.grindvalue or metal.value) or (metal and constants.metal_grindvalue));
118 + powder = mp.powder or metal.data.parts.powder;
119 + grindcost = mp.grindcost or constants.metal_grindcost; -- invariant for metal
119 120 } end
120 121
121 - mp.torque = constants.grind_torque_factor * mp.hardness
122 + mp.torque = constants.grind_torque_factor * mp.hardness
123 + mp.grindvalue = mp.grindvalue or constants.default_grindvalue
124 + mp.grindcost = mp.grindcost or constants.default_grindcost
125 + mp.hardness = mp.hardness or constants.default_hardness;
122 126
123 127 if item:get_wear() ~= 0 then
124 128 -- prevent cheating by recovering metal from items before they
125 129 -- are destroyed
126 130 local wearfac = (item:get_wear() / 65535)
127 131 mp.grindvalue = math.max(1,math.ceil(mp.grindvalue * wearfac))
128 132 mp.hardness = math.max(1,math.ceil(mp.grindcost * wearfac))
................................................................................
134 138 minetest.register_node('sorcery:mill',{
135 139 description = 'Mill';
136 140 groups = {
137 141 cracky = 2;
138 142 sorcery_ley_device = 1;
139 143 };
140 144 paramtype2 = 'facedir';
145 + after_dig_node = sorcery.lib.node.purge_container;
141 146 on_construct = function(pos)
142 147 local meta = minetest.get_meta(pos)
143 148 local inv = meta:get_inventory()
144 149 inv:set_size('input',1)
145 150 inv:set_size('output',4)
146 151 inv:set_size('grinder',2)
147 152 meta:set_float('grindtime',0)
................................................................................
163 168 on_metadata_inventory_move = function(pos,fl,fi,tl,ti)
164 169 if fl == 'input' or tl == 'input' then
165 170 minetest.get_meta(pos):set_float('grindtime',0)
166 171 end
167 172 mill_update(pos)
168 173 end;
169 174 _sorcery = {
170 - ley = { mode = 'consume'; affinity = {'praxic'}};
171 - on_leyconnect = mill_update;
172 - on_leycalc = function(pos,time)
173 - local meta = minetest.get_meta(pos)
174 - local active = meta:get_int('active') == 1
175 - if not active then return { power = 0; } end
176 - local inv = meta:get_inventory()
177 - local item = inv:get_stack('input',1)
178 - if item:is_empty() then
179 - meta:set_int('active', 0)
180 - return { power = 0; }
181 - end
182 - return {
183 - power = matprops(item).torque * time;
184 - }
185 - end;
175 + ley = {
176 + mode = 'consume', affinity = {'praxic'};
177 + power = function(pos,time)
178 + local meta = minetest.get_meta(pos)
179 + local active = meta:get_int('active') == 1
180 + if not active then return 0 end
181 + local inv = meta:get_inventory()
182 + local item = inv:get_stack('input',1)
183 + if item:is_empty() then
184 + meta:set_int('active', 0)
185 + return 0
186 + end
187 + return matprops(item).torque * time;
188 + end;
189 + };
190 + on_leychange = mill_update;
186 191 };
187 192 on_timer = function(pos,delta)
188 193 local meta = minetest.get_meta(pos)
189 194 local inv = meta:get_inventory()
190 195 local elapsed = meta:get_float('grindtime') + delta
191 196 local ley = sorcery.ley.netcaps(pos,delta,pos)
192 197 local again = false
193 198 local active = false
194 199 local reqtime -- sigh
195 200 local statcolor = 'off'
196 201 local grinders_on
197 202 if inv:is_empty('input') or inv:is_empty('grinder') then
198 - print('empty')
199 203 elapsed = 0
200 204 mill_formspec_update(pos, 0)
201 205 else
202 206 local item = inv:get_stack('input',1)
203 207 local mp = matprops(item)
204 208 if mp.grindcost > item:get_count() then
205 209 elapsed = 0
206 210 mill_formspec_update(pos, 0)
207 - print('bad grindcost')
208 211 goto stop
209 212 end
210 213
211 - -- print('power supply',ley.maxpower)
212 - -- print('power available',ley.freepower)
213 - -- print('power needed',mp.torque*delta)
214 214 if ley.maxpower < (mp.torque * delta) then
215 215 -- not enough potential energy in the system to grind
216 216 -- so don't bother
217 - print('not enough power')
218 217 statcolor = 'red'
219 218 elapsed = 0 goto stop
220 219 elseif ley.freepower < (mp.torque * delta) then
221 220 -- the net has enough potential energy to supply us,
222 221 -- but too much of it is in use right now. give up
223 222 -- on this round, but try again in a bit to see if
224 223 -- more energy is available
225 - print('currently not enough power')
226 224 statcolor = 'yellow'
227 225 elapsed = 0 again = true goto stop
228 226 end
229 227
230 228 local grinders = 0
231 229 local grindpower = 0
232 230 local grind_wear = {}
................................................................................
242 240 if dif == 0 then
243 241 wear = constants.grind_wear
244 242 elseif dif < 0 then
245 243 wear = constants.grind_wear * ((dif * -1)/constants.grind_range)
246 244 elseif dif > 0 then
247 245 if dif > constants.grind_grace_range then
248 246 wear = 0
249 - print('grinder reject')
250 247 goto reject
251 248 else
252 249 wear = constants.grind_wear * (1 + (dif/constants.grind_range)) * constants.grind_grace_penalty
253 250 end
254 251 end
255 252 ::accept:: grinders = grinders + 1
256 253 grindpower = grindpower + hh
................................................................................
269 266 if grindpower < mp.hardness then
270 267 statcolor = 'yellow'
271 268 else statcolor='green' end
272 269 grindpower = grindpower / grinders
273 270 -- if there is more power available than needed,
274 271 -- and/or if the blades are stronger than needed,
275 272 -- speed up the grind
276 - local speedboost = math.max(0.05,((grindpower - mp.hardness)/constants.grind_range) * grinders) * ((mp.torque * delta) / ley.freepower)
273 + local speedboost = math.max(0.05,((grindpower - mp.hardness)/constants.grind_range) * grinders)
277 274 reqtime = mp.grindvalue * mp.hardness * constants.grind_factor * (1-speedboost)
278 275 if elapsed >= reqtime then
279 276 item:take_item(mp.grindcost)
280 277 inv:set_stack('input',1,item)
281 278 local pw = ItemStack{
282 279 name=mp.powder;
283 280 count=mp.grindvalue;
................................................................................
345 342 metal = name;
346 343 };
347 344 });
348 345 minetest.register_craft {
349 346 output = id;
350 347 recipe = {
351 348 {f,i,f};
352 - {i,i,i};
349 + {i,'',i};
353 350 {f,i,f};
354 351 };
355 352 }
356 353 end