An extensible inventory mod which allows searching crafting and browsing for recipes in the same dialogue. https://content.minetest.net/packages/RealBadAngel/unified_inventory/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.7KB

  1. local function default_refill(stack)
  2. stack:set_count(stack:get_stack_max())
  3. local itemdef = minetest.registered_items[stack:get_name()]
  4. if itemdef
  5. and (itemdef.wear_represents or "mechanical_wear") == "mechanical_wear"
  6. and stack:get_wear() ~= 0 then
  7. stack:set_wear(0)
  8. end
  9. return stack
  10. end
  11. minetest.register_on_joinplayer(function(player)
  12. local player_name = player:get_player_name()
  13. unified_inventory.players[player_name] = {}
  14. unified_inventory.current_index[player_name] = 1
  15. unified_inventory.filtered_items_list[player_name] =
  16. unified_inventory.items_list
  17. unified_inventory.activefilter[player_name] = ""
  18. unified_inventory.active_search_direction[player_name] = "nochange"
  19. unified_inventory.apply_filter(player, "", "nochange")
  20. unified_inventory.current_searchbox[player_name] = ""
  21. unified_inventory.alternate[player_name] = 1
  22. unified_inventory.current_item[player_name] = nil
  23. unified_inventory.current_craft_direction[player_name] = "recipe"
  24. unified_inventory.set_inventory_formspec(player,
  25. unified_inventory.default)
  26. -- Refill slot
  27. local refill = minetest.create_detached_inventory(player_name.."refill", {
  28. allow_put = function(inv, listname, index, stack, player)
  29. if unified_inventory.is_creative(player_name) then
  30. return stack:get_count()
  31. else
  32. return 0
  33. end
  34. end,
  35. on_put = function(inv, listname, index, stack, player)
  36. local handle_refill = (minetest.registered_items[stack:get_name()] or {}).on_refill or default_refill
  37. stack = handle_refill(stack)
  38. inv:set_stack(listname, index, stack)
  39. minetest.sound_play("electricity",
  40. {to_player=player_name, gain = 1.0})
  41. end,
  42. }, player_name)
  43. refill:set_size("main", 1)
  44. end)
  45. local function apply_new_filter(player, search_text, new_dir)
  46. local player_name = player:get_player_name()
  47. minetest.sound_play("click", {to_player=player_name, gain = 0.1})
  48. unified_inventory.apply_filter(player, search_text, new_dir)
  49. unified_inventory.current_searchbox[player_name] = search_text
  50. unified_inventory.set_inventory_formspec(player,
  51. unified_inventory.current_page[player_name])
  52. end
  53. minetest.register_on_player_receive_fields(function(player, formname, fields)
  54. local player_name = player:get_player_name()
  55. local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name)
  56. if formname ~= "" then
  57. return
  58. end
  59. -- always take new search text, even if not searching on it yet
  60. if fields.searchbox
  61. and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
  62. unified_inventory.current_searchbox[player_name] = fields.searchbox
  63. end
  64. for i, def in pairs(unified_inventory.buttons) do
  65. if fields[def.name] then
  66. def.action(player)
  67. minetest.sound_play("click",
  68. {to_player=player_name, gain = 0.1})
  69. return
  70. end
  71. end
  72. -- Inventory page controls
  73. local start = math.floor(
  74. unified_inventory.current_index[player_name] / ui_peruser.items_per_page + 1)
  75. local start_i = start
  76. local pagemax = math.floor(
  77. (#unified_inventory.filtered_items_list[player_name] - 1)
  78. / (ui_peruser.items_per_page) + 1)
  79. if fields.start_list then
  80. start_i = 1
  81. end
  82. if fields.rewind1 then
  83. start_i = start_i - 1
  84. end
  85. if fields.forward1 then
  86. start_i = start_i + 1
  87. end
  88. if fields.rewind3 then
  89. start_i = start_i - 3
  90. end
  91. if fields.forward3 then
  92. start_i = start_i + 3
  93. end
  94. if fields.end_list then
  95. start_i = pagemax
  96. end
  97. if start_i < 1 then
  98. start_i = 1
  99. end
  100. if start_i > pagemax then
  101. start_i = pagemax
  102. end
  103. if start_i ~= start then
  104. minetest.sound_play("paperflip1",
  105. {to_player=player_name, gain = 1.0})
  106. unified_inventory.current_index[player_name] = (start_i - 1) * ui_peruser.items_per_page + 1
  107. unified_inventory.set_inventory_formspec(player,
  108. unified_inventory.current_page[player_name])
  109. end
  110. -- Check clicked item image button
  111. local clicked_item
  112. for name, value in pairs(fields) do
  113. local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
  114. if new_dir and mangled_item then
  115. clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
  116. if string.sub(clicked_item, 1, 6) == "group:" then
  117. -- Change search filter to this group
  118. apply_new_filter(player, clicked_item, new_dir)
  119. return
  120. end
  121. if new_dir == "recipe" or new_dir == "usage" then
  122. unified_inventory.current_craft_direction[player_name] = new_dir
  123. end
  124. break
  125. end
  126. end
  127. if clicked_item then
  128. minetest.sound_play("click",
  129. {to_player=player_name, gain = 0.1})
  130. local page = unified_inventory.current_page[player_name]
  131. local player_creative = unified_inventory.is_creative(player_name)
  132. if not player_creative then
  133. page = "craftguide"
  134. end
  135. if page == "craftguide" then
  136. unified_inventory.current_item[player_name] = clicked_item
  137. unified_inventory.alternate[player_name] = 1
  138. unified_inventory.set_inventory_formspec(player, "craftguide")
  139. elseif player_creative then
  140. -- Creative page: Add entire stack to inventory
  141. local inv = player:get_inventory()
  142. local stack = ItemStack(clicked_item)
  143. stack:set_count(stack:get_stack_max())
  144. if inv:room_for_item("main", stack) then
  145. inv:add_item("main", stack)
  146. end
  147. end
  148. end
  149. if fields.searchbutton
  150. or fields.key_enter_field == "searchbox" then
  151. unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange")
  152. unified_inventory.set_inventory_formspec(player,
  153. unified_inventory.current_page[player_name])
  154. minetest.sound_play("paperflip2",
  155. {to_player=player_name, gain = 1.0})
  156. elseif fields.searchresetbutton then
  157. apply_new_filter(player, "", "nochange")
  158. end
  159. -- alternate buttons
  160. if not (fields.alternate or fields.alternate_prev) then
  161. return
  162. end
  163. minetest.sound_play("click",
  164. {to_player=player_name, gain = 0.1})
  165. local item_name = unified_inventory.current_item[player_name]
  166. if not item_name then
  167. return
  168. end
  169. local crafts = unified_inventory.crafts_for[unified_inventory.current_craft_direction[player_name]][item_name]
  170. if not crafts then
  171. return
  172. end
  173. local alternates = #crafts
  174. if alternates <= 1 then
  175. return
  176. end
  177. local alternate
  178. if fields.alternate then
  179. alternate = unified_inventory.alternate[player_name] + 1
  180. if alternate > alternates then
  181. alternate = 1
  182. end
  183. elseif fields.alternate_prev then
  184. alternate = unified_inventory.alternate[player_name] - 1
  185. if alternate < 1 then
  186. alternate = alternates
  187. end
  188. end
  189. unified_inventory.alternate[player_name] = alternate
  190. unified_inventory.set_inventory_formspec(player,
  191. unified_inventory.current_page[player_name])
  192. end)
  193. if minetest.delete_detached_inventory then
  194. minetest.register_on_leaveplayer(function(player)
  195. local player_name = player:get_player_name()
  196. minetest.delete_detached_inventory(player_name.."_bags")
  197. minetest.delete_detached_inventory(player_name.."craftrecipe")
  198. minetest.delete_detached_inventory(player_name.."refill")
  199. end)
  200. end