Differences From
Artifact [e643a56c3c]:
1 1 -- by use of the enchanter, it is possible to reveal a random
2 2 -- recipe and enscribe it on a sheet of paper. these sheets of
3 3 -- paper can then bound together into books, combining like
4 4 -- recipes
5 5
6 6 sorcery.cookbook = {}
7 +local log = sorcery.logger('cookbook')
8 +
7 9 local constants = {
8 10 -- do not show recipes for items in these groups
9 11 exclude_groups = {
10 12 };
11 13 exclude_names = {
12 14 'stairs';
13 15 'slab';
................................................................................
51 53 return {}
52 54 end
53 55 local modofname = function(id)
54 56 local sep = string.find(id,':')
55 57 if sep == nil then return nil end -- uh oh
56 58 return string.sub(id, 1, sep - 1)
57 59 end
60 +local item_restrict_eval = function(name, restrict)
61 + for _,n in pairs(constants.exclude_names) do
62 + if string.find(name,n) ~= nil then
63 + return false
64 + end
65 + end
66 + for _,g in pairs(constants.exclude_groups) do
67 + if minetest.get_item_group(name, g) > 0 then
68 + return false
69 + end
70 + end
71 +
72 + local props = minetest.registered_items[name]._sorcery
73 + local module = modofname(name)
74 +
75 + return not (excluded
76 + or sorcery.lib.tbl.has(constants.blacklist_mods,module)
77 + or (props and props.recipe and props.recipe.secret)
78 + or (restrict and (
79 + (restrict.pred and restrict.pred {
80 + mod = module, item = name, props = props
81 + } ~= true)
82 + or (restrict.mod and module ~= restrict.mod)
83 + or (restrict.group and (minetest.get_item_group(name, restrict.group) == 0))
84 + )))
85 +end
86 +
58 87 local pick_builtin = function(kind) return function(restrict)
59 88 -- ow ow ow ow ow ow ow
60 89 local names = {}
61 90 for k in pairs(minetest.registered_items) do
62 91 local rec = minetest.get_craft_recipe(k)
63 92 if rec.items ~= nil and (rec.method == kind or (rec.method == 'shapeless' and kind == 'normal')) then -- is this last bit necessary?
64 - local excluded = false
65 - for _,n in pairs(constants.exclude_names) do
66 - if string.find(k,n) ~= nil then
67 - excluded = true break end
68 - end
69 - if not excluded then for _,g in pairs(constants.exclude_groups) do
70 - if minetest.get_item_group(k, g) > 0 then
71 - excluded = true break end
72 - end end
73 - local props = minetest.registered_items[k]._sorcery
74 - local module = modofname(k)
75 - if not (excluded
76 - or sorcery.lib.tbl.has(constants.blacklist_mods,module)
77 - or (props and props.recipe and props.recipe.secret)
78 - or (restrict and (
79 - (restrict.mod and module ~= restrict.mod)
80 - or (restrict.group and (minetest.get_item_group(k, restrict.group) == 0))
81 - ))) then names[#names + 1] = k end
93 + if item_restrict_eval(k, restrict) then names[#names + 1] = k end
82 94 end
83 95 end
84 96 return names[math.random(#names)]
85 97 end end
86 98 local find_builtin = function(method,kind)
87 99 return function(out)
88 100 local rec = {}
................................................................................
219 231 chance = 4;
220 232 slots = {
221 233 {0,0};
222 234 {0,1};
223 235 };
224 236 pick = function(restrict)
225 237 -- TODO make sure affinity restrictions match
226 - return sorcery.register.infusions.db[math.random(#sorcery.register.infusions.db)].output
238 + if restrict then
239 + local t = {}
240 + for _, i in pairs(sorcery.register.infusions.db) do
241 + if item_restrict_eval(i.output, restrict) and not (
242 + -- conditions which cause failure of restriction test
243 + (restrict.ipred and restrict.ipred {
244 + mod = module;
245 + infusion = i;
246 + output = i.output;
247 + } ~= true)
248 + ) then t[#t+1] = i.output end
249 + end
250 + return select(2, sorcery.lib.tbl.pick(t))
251 + else
252 + return sorcery.register.infusions.db[math.random(#sorcery.register.infusions.db)].output
253 + end
227 254 end;
228 255 title = function(output)
229 256 for _,i in pairs(sorcery.register.infusions.db) do
230 257 if i.output == output then
231 258 if i._proto and i._proto.name
232 259 then return i._proto.name
233 260 else break end
................................................................................
254 281 name = 'Milling Guide';
255 282 node = 'sorcery:mill';
256 283 booksuf = 'Manual';
257 284 chance = 1;
258 285 w = 1, h = 2;
259 286 pick = function(restrict)
260 287 cache:populate_grindables()
261 - local i = cache.grindables[math.random(#cache.grindables)]
262 - local pd = sorcery.itemclass.get(i, 'grindable')
263 - return pd.powder
288 + if restrict then
289 + local t = {}
290 + for _, i in pairs(cache.grindables) do
291 + local pd = sorcery.itemclass.get(i, 'grindable')
292 + if item_restrict_eval(pd.powder, restrict) then
293 + t[#t+1] = pd.powder
294 + end
295 + end
296 + return select(2, sorcery.lib.tbl.pick(t))
297 + else
298 + local gd = cache.grindables[math.random(#cache.grindables)]
299 + local pd = sorcery.itemclass.get(gd, 'grindable')
300 + return pd.powder
301 + end
264 302 end;
265 303 props = props_builtin;
266 304 slots = {
267 305 {0,1},
268 306 {0,0};
269 307 };
270 308 find = function(out)
................................................................................
400 438 end
401 439 if kind == nil then -- oh well, we tried
402 440 local rks = sorcery.lib.tbl.keys(recipe_kinds)
403 441 kind = rks[math.random(#rks)]
404 442 end
405 443 end
406 444
445 + if not recipe_kinds[kind] then
446 + log.fatalf('attempted to pick recipe of unknown kind "%s"', kind)
447 + end
407 448 return recipe_kinds[kind].pick(restrict), kind
408 449 end
409 450
410 451 local render_recipe = function(kind,ingredients,result,notes_right)
411 452 local k = recipe_kinds[kind]
412 453 local t = ''
413 454 local props = k.props(result)
................................................................................
464 505 local ing = rec.find(out)
465 506 return render_recipe(kind,ing,out,notes_right), rec.w, rec.h
466 507 end
467 508
468 509 sorcery.cookbook.setrecipe = function(stack,k,r,restrict)
469 510 local meta = stack:get_meta()
470 511 if not r then r,k = sorcery.cookbook.pickrecipe(k,restrict) end
512 + if not r then return false end
471 513 local t = recipe_kinds[k]
472 514 meta:set_string('recipe_kind', k)
473 515 meta:set_string('recipe_name', r)
474 516 meta:set_string('description',
475 517 (t.title and t.title(r) or desc_builtin(r)) .. ' ' .. t.name)
476 518 end
477 519