functions.lua 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. lottinventory = {}
  2. function lottinventory.items_in_group(group)
  3. local items = {}
  4. local ok = true
  5. for name, item in pairs(minetest.registered_items) do
  6. -- the node should be in all groups
  7. ok = true
  8. for _, g in ipairs(group:split(',')) do
  9. if not item.groups[g] then
  10. ok = false
  11. end
  12. end
  13. if ok then table.insert(items,name) end
  14. end
  15. return items
  16. end
  17. function lottinventory.table_copy(table)
  18. local out = {}
  19. for k,v in pairs(table) do
  20. out[k] = v
  21. end
  22. return out
  23. end
  24. function lottinventory.add_craft(input, output, needed_groups, forbidden_groups,
  25. output_table, type, not_type, groups)
  26. local has_groups = true
  27. if needed_groups and #needed_groups ~= 0 then
  28. has_groups = false
  29. for _, group in pairs(needed_groups) do
  30. if type then
  31. if minetest.get_item_group(output, group) > 0 or type == input.type then
  32. has_groups = true
  33. end
  34. else
  35. if minetest.get_item_group(output, group) > 0 then
  36. has_groups = true
  37. end
  38. end
  39. end
  40. end
  41. local not_groups = true
  42. if forbidden_groups and #forbidden_groups ~= 0 then
  43. for _, group in pairs(forbidden_groups) do
  44. if minetest.get_item_group(output, group) ~= 0 then
  45. not_groups = false
  46. end
  47. end
  48. end
  49. if not not_groups or not has_groups
  50. or (not_type and not_type == input.type) then
  51. return
  52. end
  53. if not groups then groups = {} end
  54. local c = {}
  55. c.width = input.width
  56. c.type = input.type
  57. c.items = input.items
  58. c.output = input.output
  59. if c.items == nil then return end
  60. for i, item in pairs(c.items) do
  61. if item:sub(0,6) == "group:" then
  62. local groupname = item:sub(7)
  63. if groups[groupname] ~= nil then
  64. c.items[i] = groups[groupname]
  65. else
  66. for _, gi in ipairs(lottinventory.items_in_group(groupname)) do
  67. local g2 = groups
  68. g2[groupname] = gi
  69. lottinventory.add_craft({
  70. width = c.width,
  71. type = c.type,
  72. items = lottinventory.table_copy(c.items),
  73. output = c.output
  74. },
  75. output, needed_groups, forbidden_groups,
  76. output_table, type, not_type, g2)
  77. end
  78. return
  79. end
  80. end
  81. end
  82. if c.width == 0 then c.width = 3 end
  83. table.insert(output_table.crafts[output], c)
  84. end
  85. function lottinventory.load_crafts(name, ctable, needed_groups,
  86. forbidden_groups, type, not_type)
  87. ctable.crafts[name] = {}
  88. local _recipes = minetest.get_all_craft_recipes(name)
  89. if _recipes then
  90. for i, recipe in ipairs(_recipes) do
  91. if (recipe and recipe.items and recipe.type) then
  92. lottinventory.add_craft(recipe, name, needed_groups,
  93. forbidden_groups, ctable, type, not_type)
  94. end
  95. end
  96. end
  97. if ctable.crafts[name] == nil or #ctable.crafts[name] == 0 then
  98. ctable.crafts[name] = nil
  99. else
  100. table.insert(ctable.itemlist, name)
  101. end
  102. end
  103. function lottinventory.load_all(ctable, needed_groups, forbidden_groups,
  104. type, not_type)
  105. print("Loading all crafts, this may take some time...")
  106. for name, item in pairs(minetest.registered_items) do
  107. if (name and name ~= "") then
  108. lottinventory.load_crafts(name, ctable, needed_groups,
  109. forbidden_groups, type, not_type)
  110. end
  111. end
  112. table.sort(ctable.itemlist)
  113. ctable.need_load_all = false
  114. print("All crafts loaded !")
  115. end
  116. function lottinventory.formspec(pn, ctable, fname, master)
  117. local page = ctable.users[pn].page
  118. local alt = ctable.users[pn].alt
  119. local current_item = ctable.users[pn].current_item
  120. local formspec = "size[8,7.5]"
  121. .. "button_exit[6,7;2,0.5;;Exit]"
  122. if ctable.users[pn].history.index > 1 then
  123. formspec = formspec .. "image_button[0,1;1,1;zcg_previous.png;craftguide_previous;;false;false;zcg_previous_press.png]"
  124. else
  125. formspec = formspec .. "image[0,1;1,1;zcg_previous_inactive.png]"
  126. end
  127. if ctable.users[pn].history.index < #ctable.users[pn].history.list then
  128. formspec = formspec .. "image_button[1,1;1,1;zcg_next.png;craftguide_next;;false;false;zcg_next_press.png]"
  129. else
  130. formspec = formspec .. "image[1,1;1,1;zcg_next_inactive.png]"
  131. end
  132. -- Show craft recipe
  133. if current_item ~= "" then
  134. if ctable.crafts[current_item] then
  135. if alt > #ctable.crafts[current_item] then
  136. alt = #ctable.crafts[current_item]
  137. end
  138. if alt > 1 then
  139. formspec = formspec .. "button[7,0;1,1;craftguide_alt:"..(alt-1)..";^]"
  140. end
  141. if alt < #ctable.crafts[current_item] then
  142. formspec = formspec .. "button[7,2;1,1;craftguide_alt:"..(alt+1)..";v]"
  143. end
  144. local c = ctable.crafts[current_item][alt]
  145. if c then
  146. local x = 3
  147. local y = 0
  148. for i, item in pairs(c.items) do
  149. formspec = formspec .. "item_image_button[" .. ((i-1)%c.width+x) ..
  150. "," .. (math.floor((i - 1) / c.width + y)) ..
  151. ";1,1;" .. item .. ";craftguide:" .. item .. ";]"
  152. end
  153. if c.type == "normal" or c.type == "cooking" then
  154. formspec = formspec .. "image[6,2;1,1;zcg_method_"..c.type..".png]"
  155. else -- we don't have an image for other types of crafting
  156. formspec = formspec .. "label[0,2;Method: "..c.type.."]"
  157. end
  158. formspec = formspec .. "image[6,1;1,1;zcg_craft_arrow.png]"
  159. formspec = formspec .. "item_image_button[7,1;1,1;"..c.output..";;]"
  160. end
  161. end
  162. end
  163. -- Node list
  164. local npp = 8*3 -- nodes per page
  165. local i = 0 -- for positionning buttons
  166. local s = 0 -- for skipping pages
  167. for _, name in ipairs(ctable.itemlist) do
  168. if s < page*npp then s = s+1 else
  169. if i >= npp then break end
  170. formspec = formspec .. "item_image_button[" .. (i % 8) .. "," ..
  171. (math.floor(i / 8) + 3.5) .. ";1,1;" .. name .. ";craftguide:" ..name.. ";]"
  172. i = i+1
  173. end
  174. end
  175. if page > 0 then
  176. formspec = formspec .. "button[0,7;1,.5;craftguide_page:"..(page-1)..";<<]"
  177. end
  178. if i >= npp then
  179. formspec = formspec .. "button[1,7;1,.5;craftguide_page:"..(page+1)..";>>]"
  180. end
  181. formspec = formspec .. "label[2,6.85;Page " .. (page + 1) .. "/" ..
  182. (math.floor(#ctable.itemlist / npp + 1)) .. "]"
  183. -- This Y is approximatively the good one to have it centered vertically.
  184. formspec = formspec .. "label[0,0;" .. fname:gsub("^%l", string.upper) .. " Book]"
  185. formspec = formspec .. "background[5,5;1,1;craft_formbg.png;true]"
  186. if master then
  187. formspec = formspec .. "button[0,2.8;2,0.5;potions;Potions]"
  188. formspec = formspec .. "button[0,2.1;2,0.5;brews;Brewing]"
  189. end
  190. return formspec
  191. end
  192. function lottinventory.receive_fields(ctable, fname, master)
  193. minetest.register_on_player_receive_fields(function(player, formname, fields)
  194. if formname ~= fname then
  195. return
  196. end
  197. local pn = player:get_player_name()
  198. if ctable.users[pn] == nil then
  199. ctable.users[pn] = {current_item = "", alt = 1, page = 0, history={index=0,list={}}}
  200. end
  201. if fields.craftguide then
  202. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  203. return
  204. elseif fields.craftguide_previous then
  205. if ctable.users[pn].history.index > 1 then
  206. ctable.users[pn].history.index = ctable.users[pn].history.index - 1
  207. ctable.users[pn].current_item = ctable.users[pn].history.list[ctable.users[pn].history.index]
  208. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  209. end
  210. elseif fields.craftguide_next then
  211. if ctable.users[pn].history.index < #ctable.users[pn].history.list then
  212. ctable.users[pn].history.index = ctable.users[pn].history.index + 1
  213. ctable.users[pn].current_item = ctable.users[pn].history.list[ctable.users[pn].history.index]
  214. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  215. end
  216. end
  217. for k, v in pairs(fields) do
  218. if k:sub(0, 11) == "craftguide:" then
  219. local ni = k:sub(12)
  220. if ctable.crafts[ni] then
  221. ctable.users[pn].current_item = ni
  222. table.insert(ctable.users[pn].history.list, ni)
  223. ctable.users[pn].history.index = #ctable.users[pn].history.list
  224. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  225. end
  226. elseif k:sub(0, 16) == "craftguide_page:" then
  227. ctable.users[pn].page = tonumber(k:sub(17))
  228. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  229. elseif k:sub(0, 15)=="craftguide_alt:" then
  230. ctable.users[pn].alt = tonumber(k:sub(16))
  231. minetest.show_formspec(pn, fname, lottinventory.formspec(pn, ctable, fname, master))
  232. end
  233. end
  234. if master then
  235. if fields.brews then
  236. minetest.show_formspec(pn, "brews",
  237. lottinventory.get_brewing_formspec(player, "brews"))
  238. elseif fields.potions then
  239. minetest.show_formspec(pn, "potion",
  240. lottinventory.get_potion_formspec(player, "potions"))
  241. end
  242. end
  243. end)
  244. end
  245. function lottinventory.on_use(player, ctable, formname, needed_groups,
  246. forbidden_groups, type, not_type, master)
  247. if ctable.need_load_all then
  248. lottinventory.load_all(ctable, needed_groups, forbidden_groups,
  249. type, not_type)
  250. end
  251. local pn = player:get_player_name()
  252. if ctable.users[pn] == nil then
  253. ctable.users[pn] = {current_item = "", alt = 1, page = 0, history = {index = 0, list = {}}}
  254. end
  255. minetest.show_formspec(pn, formname, lottinventory.formspec(pn, ctable, formname, master))
  256. end