210 lines
6.4 KiB
Lua
210 lines
6.4 KiB
Lua
-- ZCG mod for minetest
|
|
-- See README for more information
|
|
-- Released by Zeg9 under WTFPL
|
|
|
|
zcg = {}
|
|
|
|
zcg.users = {}
|
|
zcg.crafts = {}
|
|
zcg.itemlist = {}
|
|
|
|
zcg.items_in_group = function(group)
|
|
local items = {}
|
|
local ok = true
|
|
for name, item in pairs(minetest.registered_items) do
|
|
-- the node should be in all groups
|
|
ok = true
|
|
for _, g in pairs(group:split(',')) do
|
|
if not item.groups[g] then
|
|
ok = false
|
|
end
|
|
end
|
|
if ok then table.insert(items,name) end
|
|
end
|
|
return items
|
|
end
|
|
|
|
local table_copy = function(table)
|
|
local out = {}
|
|
for k,v in pairs(table) do
|
|
out[k] = v
|
|
end
|
|
return out
|
|
end
|
|
|
|
zcg.add_craft = function(input, output, groups)
|
|
if minetest.get_item_group(output, "not_in_craft_guide") > 0 then
|
|
return
|
|
end
|
|
if not groups then groups = {} end
|
|
local c = {}
|
|
c.width = input.width
|
|
c.type = input.type
|
|
c.items = input.items
|
|
if c.items == nil then return end
|
|
for i, item in pairs(c.items) do
|
|
if item:sub(0,6) == "group:" then
|
|
local groupname = item:sub(7)
|
|
if groups[groupname] ~= nil then
|
|
c.items[i] = groups[groupname]
|
|
else
|
|
for _, gi in pairs(zcg.items_in_group(groupname)) do
|
|
local g2 = groups
|
|
g2[groupname] = gi
|
|
zcg.add_craft({
|
|
width = c.width,
|
|
type = c.type,
|
|
items = table_copy(c.items)
|
|
}, output, g2) -- it is needed to copy the table, else groups won't work right
|
|
end
|
|
return
|
|
end
|
|
end
|
|
end
|
|
if c.width == 0 then c.width = 3 end
|
|
table.insert(zcg.crafts[output],c)
|
|
end
|
|
|
|
zcg.load_crafts = function(name)
|
|
zcg.crafts[name] = {}
|
|
local _recipes = minetest.get_all_craft_recipes(name)
|
|
if _recipes then
|
|
for i, recipe in pairs(_recipes) do
|
|
if (recipe and recipe.items and recipe.type) then
|
|
zcg.add_craft(recipe, name)
|
|
end
|
|
end
|
|
end
|
|
if zcg.crafts[name] == nil or #zcg.crafts[name] == 0 then
|
|
zcg.crafts[name] = nil
|
|
else
|
|
table.insert(zcg.itemlist,name)
|
|
end
|
|
end
|
|
|
|
zcg.need_load_all = true
|
|
|
|
zcg.load_all = function()
|
|
minetest.log("action","Loading all crafts, this may take some time...")
|
|
local i = 0
|
|
for name, item in pairs(minetest.registered_items) do
|
|
if (name and name ~= "") then
|
|
zcg.load_crafts(name)
|
|
end
|
|
i = i+1
|
|
end
|
|
table.sort(zcg.itemlist)
|
|
zcg.need_load_all = false
|
|
minetest.log("action","All crafts loaded !")
|
|
end
|
|
|
|
zcg.formspec = function(pn)
|
|
if zcg.need_load_all then zcg.load_all() end
|
|
local page = zcg.users[pn].page
|
|
local alt = zcg.users[pn].alt
|
|
local current_item = zcg.users[pn].current_item
|
|
local formspec = "size[8,7.5]"
|
|
.. "button[0,0;2,.5;main;Back]"
|
|
if zcg.users[pn].history.index > 1 then
|
|
formspec = formspec .. "image_button[0,1;1,1;zcg_previous.png;zcg_previous;;false;false;zcg_previous_press.png]"
|
|
else
|
|
formspec = formspec .. "image[0,1;1,1;zcg_previous_inactive.png]"
|
|
end
|
|
if zcg.users[pn].history.index < #zcg.users[pn].history.list then
|
|
formspec = formspec .. "image_button[1,1;1,1;zcg_next.png;zcg_next;;false;false;zcg_next_press.png]"
|
|
else
|
|
formspec = formspec .. "image[1,1;1,1;zcg_next_inactive.png]"
|
|
end
|
|
-- Show craft recipe
|
|
if current_item ~= "" then
|
|
if zcg.crafts[current_item] then
|
|
if alt > #zcg.crafts[current_item] then
|
|
alt = #zcg.crafts[current_item]
|
|
end
|
|
if alt > 1 then
|
|
formspec = formspec .. "button[7,0;1,1;zcg_alt:"..(alt-1)..";^]"
|
|
end
|
|
if alt < #zcg.crafts[current_item] then
|
|
formspec = formspec .. "button[7,2;1,1;zcg_alt:"..(alt+1)..";v]"
|
|
end
|
|
local c = zcg.crafts[current_item][alt]
|
|
if c then
|
|
local x = 3
|
|
local y = 0
|
|
for i, item in pairs(c.items) do
|
|
formspec = formspec .. "item_image_button["..((i-1)%c.width+x)..","..(math.floor((i-1)/c.width+y))..";1,1;"..item..";zcg:"..item..";]"
|
|
end
|
|
if c.type == "normal" or c.type == "cooking" then
|
|
formspec = formspec .. "image[6,2;1,1;zcg_method_"..c.type..".png]"
|
|
else -- we don't have an image for other types of crafting
|
|
formspec = formspec .. "label[0,2;Method: "..c.type.."]"
|
|
end
|
|
formspec = formspec .. "image[6,1;1,1;zcg_craft_arrow.png]"
|
|
formspec = formspec .. "item_image_button[7,1;1,1;"..zcg.users[pn].current_item..";;]"
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Node list
|
|
local npp = 8*3 -- nodes per page
|
|
local i = 0 -- for positionning buttons
|
|
local s = 0 -- for skipping pages
|
|
for _, name in pairs(zcg.itemlist) do
|
|
if s < page*npp then s = s+1 else
|
|
if i >= npp then break end
|
|
formspec = formspec .. "item_image_button["..(i%8)..","..(math.floor(i/8)+3.5)..";1,1;"..name..";zcg:"..name..";]"
|
|
i = i+1
|
|
end
|
|
end
|
|
if page > 0 then
|
|
formspec = formspec .. "button[0,7;1,.5;zcg_page:"..(page-1)..";<<]"
|
|
end
|
|
if i >= npp then
|
|
formspec = formspec .. "button[1,7;1,.5;zcg_page:"..(page+1)..";>>]"
|
|
end
|
|
formspec = formspec .. "label[2,6.85;Page "..(page+1).."/"..(math.floor(#zcg.itemlist/npp+1)).."]" -- The Y is approximatively the good one to have it centered vertically...
|
|
return formspec
|
|
end
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
inventory_plus.register_button(player,"zcg","Craft guide")
|
|
end)
|
|
|
|
minetest.register_on_player_receive_fields(function(player,formname,fields)
|
|
local pn = player:get_player_name();
|
|
if zcg.users[pn] == nil then zcg.users[pn] = {current_item = "", alt = 1, page = 0, history={index=0,list={}}} end
|
|
if fields.zcg then
|
|
inventory_plus.set_inventory_formspec(player, zcg.formspec(pn))
|
|
return
|
|
elseif fields.zcg_previous then
|
|
if zcg.users[pn].history.index > 1 then
|
|
zcg.users[pn].history.index = zcg.users[pn].history.index - 1
|
|
zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index]
|
|
inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
|
|
end
|
|
elseif fields.zcg_next then
|
|
if zcg.users[pn].history.index < #zcg.users[pn].history.list then
|
|
zcg.users[pn].history.index = zcg.users[pn].history.index + 1
|
|
zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index]
|
|
inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
|
|
end
|
|
end
|
|
for k, v in pairs(fields) do
|
|
if (k:sub(0,4)=="zcg:") then
|
|
local ni = k:sub(5)
|
|
if zcg.crafts[ni] then
|
|
zcg.users[pn].current_item = ni
|
|
table.insert(zcg.users[pn].history.list, ni)
|
|
zcg.users[pn].history.index = #zcg.users[pn].history.list
|
|
inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
|
|
end
|
|
elseif (k:sub(0,9)=="zcg_page:") then
|
|
zcg.users[pn].page = tonumber(k:sub(10))
|
|
inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
|
|
elseif (k:sub(0,8)=="zcg_alt:") then
|
|
zcg.users[pn].alt = tonumber(k:sub(9))
|
|
inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
|
|
end
|
|
end
|
|
end)
|