@@ -83,9 +83,9 @@ end end local find_builtin = function(out) local rec = {} local i = minetest.get_craft_recipe(out) - if #i.items == 0 then return nil end + if i == nil or i.items == nil or #i.items == 0 then return nil end local w = (i.width == 0) and 3 or i.width for j=1,#i.items do local row = math.floor((j-1) / w) local col = (j-1) % w @@ -114,17 +114,23 @@ local function desc_builtin(i) local desc i, desc = group_eval(i) -- print('describing ',i,dump(minetest.registered_items[i])) - if not minetest.registered_items[i] then + local s = ItemStack(i) + if not minetest.registered_items[s:get_name()] then minetest.log('WARNING: unknown item in recipe ' .. i) return 'Unknown Item' end - if not desc then desc = minetest.registered_items[i].description end + if not desc then desc = minetest.registered_items[s:get_name()].description end if not desc then return 'Peculiar Item' end local eol = string.find(desc,'\n') - if not eol then return desc else return string.sub(desc,1,eol-1) end + if eol then desc = string.sub(desc,1,eol-1) end + + if s:get_count() > 1 then + desc = string.format("%s (%u)",desc,s:get_count()) + end + return desc end; local bookadjs = { -- sets are in reverse order! {'Celestial', 'Divine', 'Inspired', 'Heavenly'; @@ -138,8 +144,20 @@ 'Fulsome', 'Fearsome', 'Curious', 'Fascinating'; 'Notorious', 'Infamous'}; } +local cache = { + populate_grindables = function(cache) + if not cache.grindables then + cache.grindables = {} + for k,v in pairs(minetest.registered_items) do + if sorcery.itemclass.get(k, 'grindable') then + cache.grindables[#cache.grindables+1] = k + end + end + end + end; +} sorcery.cookbook.classes = { craft = { name = 'Crafting Guide'; node = 'xdecor:workbench'; @@ -161,9 +179,9 @@ name = 'Cooking Recipe'; node = 'default:furnace'; booksuf = 'Cookbook'; w = 1, h = 1; - chance = 5; + chance = 3; slots = {{-0.2,0}}; pick = pick_builtin('cooking'); find = find_builtin; props = props_builtin; @@ -173,9 +191,9 @@ name = 'Infusion Recipe'; node = 'sorcery:infuser'; booksuf = 'Pharmacopeia'; w = 1, h = 2; - chance = 2; + chance = 4; slots = { {0,0}; {0,1}; }; @@ -184,9 +202,8 @@ return sorcery.data.infusions[math.random(#sorcery.data.infusions)].output end; title = function(output) for _,i in pairs(sorcery.data.infusions) do - print(dump(i)) if i.output == output then if i._proto and i._proto.name then return i._proto.name else break end @@ -201,10 +218,54 @@ end end end; props = function(out) - local i = sorcery.cookbook.classes.infuse.find(out) - if i.recipe then return i.info else return {} end + for _,i in pairs(sorcery.data.infusions) do + if i.output == out then + if i.recipe then return i.recipe else return {} end + end + end + end; + }; + grind = { + name = 'Milling Guide'; + node = 'sorcery:mill'; + booksuf = 'Manual'; + chance = 1; + w = 1, h = 2; + pick = function(restrict) + cache:populate_grindables() + local i = cache.grindables[math.random(#cache.grindables)] + local pd = sorcery.itemclass.get(i, 'grindable') + return pd.powder + end; + desc = desc_builtin; + props = props_builtin; + slots = { + {0,1}, + {0,0}; + }; + find = function(out) + cache:populate_grindables() + for _,v in pairs(cache.grindables) do + local g = sorcery.itemclass.get(v,'grindable') + if g.powder == out then + if g.grindcost then + v = v .. ' ' .. tostring(g.grindcost) + end + local mbh = sorcery.lib.tbl.keys(sorcery.data.metals) + table.sort(mbh, function(a,b) + return sorcery.data.metals[a].hardness < sorcery.data.metals[b].hardness + end) + for _,metal in pairs(mbh) do + local md = sorcery.data.metals[metal] + if ((not md.no_tools) or md.grindhead) and md.hardness >= g.hardness then + return {v, 'sorcery:mill_grindhead_' .. metal} + end + end + return {v,''} -- !! + end + end end; }; -- wand = { -- booksuf = 'Grimoire'; @@ -213,9 +274,9 @@ name = 'Enchantment Matrix'; node = 'sorcery:enchanter'; booksuf = 'Grimoire'; drawslots = false; - chance = 1; + chance = 6; w = 2, h = 2; pick = function(restrict) -- TODO make sure affinity restrictions match local names = {} @@ -286,16 +347,18 @@ if math.random(v.chance) == 1 then kind = k break end end - -- local rks = sorcery.lib.tbl.keys(recipe_kinds) - -- kind = rks[math.random(#rks)] + if kind == nil then -- oh well, we tried + local rks = sorcery.lib.tbl.keys(recipe_kinds) + kind = rks[math.random(#rks)] + end end return recipe_kinds[kind].pick(restrict), kind end -local render_recipe = function(kind,ingredients,result) +local render_recipe = function(kind,ingredients,result,notes_right) local k = recipe_kinds[kind] local t = '' for i=1,#k.slots do local x, y = k.slots[i][1], k.slots[i][2] @@ -315,11 +378,19 @@ end local img, ot local props = k.props(result) if props.note then + local nx, ny, nw, nh + if notes_right then + nx = 5 ny = 0 + nw = 3 nh = 3 + else + nx = 0 ny = 3 + nw = 4 nh = 1 + end t = t .. string.format([[ - textarea[0,3;4,1;;;%s] - ]], minetest.formspec_escape(props.note)) + textarea[%f,%f;%f,%f;;;%s] + ]], nx,ny,nw,nh, minetest.formspec_escape(props.note)) end if k.icon then img = k.icon(result) end if k.outdesc then ot = k.outdesc(result) else ot = desc_builtin(result) end -- image[%f,%f;1,1;gui_furnace_arrow_bg.png^[transformR270] @@ -335,12 +406,12 @@ k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(img or result), k.w+1.1, k.h/2 - 0.5, minetest.formspec_escape(ot)) end; -local retrieve_recipe = function(kind,out) +local retrieve_recipe = function(kind,out,notes_right) local rec = recipe_kinds[kind] local ing = rec.find(out) - return render_recipe(kind,ing,out), rec.w, rec.h + return render_recipe(kind,ing,out,notes_right), rec.w, rec.h end sorcery.cookbook.setrecipe = function(stack,k,r,restrict) local meta = stack:get_meta() @@ -445,10 +516,8 @@ -- {0,1.3}, {4, 1.3}; -- {0,4.7}, {4, 4.7}; -- {0,8.1}, {4, 8.1}; } - print('book:',dump(book)) - print('pgofs',pgofs) for i=pgofs,(pgofs + constants.recipes_per_cookbook_page-1) do local maxw, maxh = 3, 2 if not book.pages[i+1] then break end local nr = 1+(i - pgofs) @@ -455,9 +524,9 @@ local x,y = coords[nr][1], coords[nr][2] local k = recipe_kinds[book.pages[i+1].kind] local ox,oy = maxw - k.w, maxh - k.h form = form .. string.format('container[%f,%f]%scontainer_end[]',(x+ox)-0.5,y, - retrieve_recipe(book.pages[i+1].kind, book.pages[i+1].name)) + retrieve_recipe(book.pages[i+1].kind, book.pages[i+1].name, true)) end minetest.show_formspec(user:get_player_name(), 'sorcery:cookbook', form) end