init.lua 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. -- ZCG mod for minetest
  2. -- See README for more information
  3. -- Released by Zeg9 under WTFPL
  4. zcg = {}
  5. zcg.users = {}
  6. zcg.crafts = {}
  7. zcg.itemlist = {}
  8. zcg.items_in_group = function(group)
  9. local items = {}
  10. local ok = true
  11. for name, item in pairs(minetest.registered_items) do
  12. -- the node should be in all groups
  13. ok = true
  14. for _, g in ipairs(group:split(',')) do
  15. if not item.groups[g] then
  16. ok = false
  17. end
  18. end
  19. if ok then table.insert(items,name) end
  20. end
  21. return items
  22. end
  23. local table_copy = function(table)
  24. local out = {}
  25. for k,v in pairs(table) do
  26. out[k] = v
  27. end
  28. return out
  29. end
  30. zcg.add_craft = function(input, output, groups)
  31. if minetest.get_item_group(output, "not_in_craft_guide") > 0 then
  32. return
  33. end
  34. if not groups then groups = {} end
  35. local c = {}
  36. c.width = input.width
  37. c.type = input.type
  38. c.items = input.items
  39. if c.items == nil then return end
  40. for i, item in pairs(c.items) do
  41. if item:sub(0,6) == "group:" then
  42. local groupname = item:sub(7)
  43. if groups[groupname] ~= nil then
  44. c.items[i] = groups[groupname]
  45. else
  46. for _, gi in ipairs(zcg.items_in_group(groupname)) do
  47. local g2 = groups
  48. g2[groupname] = gi
  49. zcg.add_craft({
  50. width = c.width,
  51. type = c.type,
  52. items = table_copy(c.items)
  53. }, output, g2) -- it is needed to copy the table, else groups won't work right
  54. end
  55. return
  56. end
  57. end
  58. end
  59. if c.width == 0 then c.width = 3 end
  60. table.insert(zcg.crafts[output],c)
  61. end
  62. zcg.load_crafts = function(name)
  63. zcg.crafts[name] = {}
  64. local _recipes = minetest.get_all_craft_recipes(name)
  65. if _recipes then
  66. for i, recipe in ipairs(_recipes) do
  67. if (recipe and recipe.items and recipe.type) then
  68. zcg.add_craft(recipe, name)
  69. end
  70. end
  71. end
  72. if zcg.crafts[name] == nil or #zcg.crafts[name] == 0 then
  73. zcg.crafts[name] = nil
  74. else
  75. table.insert(zcg.itemlist,name)
  76. end
  77. end
  78. zcg.need_load_all = true
  79. zcg.load_all = function()
  80. print("Loading all crafts, this may take some time...")
  81. local i = 0
  82. for name, item in pairs(minetest.registered_items) do
  83. if (name and name ~= "") then
  84. zcg.load_crafts(name)
  85. end
  86. i = i+1
  87. end
  88. table.sort(zcg.itemlist)
  89. zcg.need_load_all = false
  90. print("All crafts loaded !")
  91. end
  92. zcg.formspec = function(pn)
  93. if zcg.need_load_all then zcg.load_all() end
  94. local page = zcg.users[pn].page
  95. local alt = zcg.users[pn].alt
  96. local current_item = zcg.users[pn].current_item
  97. local formspec = "size[8,7.5]"
  98. .. "button[0,0;2,.5;main;Back]"
  99. if zcg.users[pn].history.index > 1 then
  100. formspec = formspec .. "image_button[0,1;1,1;zcg_previous.png;zcg_previous;;false;false;zcg_previous_press.png]"
  101. else
  102. formspec = formspec .. "image[0,1;1,1;zcg_previous_inactive.png]"
  103. end
  104. if zcg.users[pn].history.index < #zcg.users[pn].history.list then
  105. formspec = formspec .. "image_button[1,1;1,1;zcg_next.png;zcg_next;;false;false;zcg_next_press.png]"
  106. else
  107. formspec = formspec .. "image[1,1;1,1;zcg_next_inactive.png]"
  108. end
  109. -- Show craft recipe
  110. if current_item ~= "" then
  111. if zcg.crafts[current_item] then
  112. if alt > #zcg.crafts[current_item] then
  113. alt = #zcg.crafts[current_item]
  114. end
  115. if alt > 1 then
  116. formspec = formspec .. "button[7,0;1,1;zcg_alt:"..(alt-1)..";^]"
  117. end
  118. if alt < #zcg.crafts[current_item] then
  119. formspec = formspec .. "button[7,2;1,1;zcg_alt:"..(alt+1)..";v]"
  120. end
  121. local c = zcg.crafts[current_item][alt]
  122. if c then
  123. local x = 3
  124. local y = 0
  125. for i, item in pairs(c.items) do
  126. formspec = formspec .. "item_image_button["..((i-1)%c.width+x)..","..(math.floor((i-1)/c.width+y))..";1,1;"..item..";zcg:"..item..";]"
  127. end
  128. if c.type == "normal" or c.type == "cooking" then
  129. formspec = formspec .. "image[6,2;1,1;zcg_method_"..c.type..".png]"
  130. else -- we don't have an image for other types of crafting
  131. formspec = formspec .. "label[0,2;Method: "..c.type.."]"
  132. end
  133. formspec = formspec .. "image[6,1;1,1;zcg_craft_arrow.png]"
  134. formspec = formspec .. "item_image_button[7,1;1,1;"..zcg.users[pn].current_item..";;]"
  135. end
  136. end
  137. end
  138. -- Node list
  139. local npp = 8*3 -- nodes per page
  140. local i = 0 -- for positionning buttons
  141. local s = 0 -- for skipping pages
  142. for _, name in ipairs(zcg.itemlist) do
  143. if s < page*npp then s = s+1 else
  144. if i >= npp then break end
  145. formspec = formspec .. "item_image_button["..(i%8)..","..(math.floor(i/8)+3.5)..";1,1;"..name..";zcg:"..name..";]"
  146. i = i+1
  147. end
  148. end
  149. if page > 0 then
  150. formspec = formspec .. "button[0,7;1,.5;zcg_page:"..(page-1)..";<<]"
  151. end
  152. if i >= npp then
  153. formspec = formspec .. "button[1,7;1,.5;zcg_page:"..(page+1)..";>>]"
  154. end
  155. 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...
  156. return formspec
  157. end
  158. minetest.register_on_joinplayer(function(player)
  159. inventory_plus.register_button(player,"zcg","Craft guide")
  160. end)
  161. minetest.register_on_player_receive_fields(function(player,formname,fields)
  162. local pn = player:get_player_name();
  163. if zcg.users[pn] == nil then zcg.users[pn] = {current_item = "", alt = 1, page = 0, history={index=0,list={}}} end
  164. if fields.zcg then
  165. inventory_plus.set_inventory_formspec(player, zcg.formspec(pn))
  166. return
  167. elseif fields.zcg_previous then
  168. if zcg.users[pn].history.index > 1 then
  169. zcg.users[pn].history.index = zcg.users[pn].history.index - 1
  170. zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index]
  171. inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
  172. end
  173. elseif fields.zcg_next then
  174. if zcg.users[pn].history.index < #zcg.users[pn].history.list then
  175. zcg.users[pn].history.index = zcg.users[pn].history.index + 1
  176. zcg.users[pn].current_item = zcg.users[pn].history.list[zcg.users[pn].history.index]
  177. inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
  178. end
  179. end
  180. for k, v in pairs(fields) do
  181. if (k:sub(0,4)=="zcg:") then
  182. local ni = k:sub(5)
  183. if zcg.crafts[ni] then
  184. zcg.users[pn].current_item = ni
  185. table.insert(zcg.users[pn].history.list, ni)
  186. zcg.users[pn].history.index = #zcg.users[pn].history.list
  187. inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
  188. end
  189. elseif (k:sub(0,9)=="zcg_page:") then
  190. zcg.users[pn].page = tonumber(k:sub(10))
  191. inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
  192. elseif (k:sub(0,8)=="zcg_alt:") then
  193. zcg.users[pn].alt = tonumber(k:sub(9))
  194. inventory_plus.set_inventory_formspec(player,zcg.formspec(pn))
  195. end
  196. end
  197. end)