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.

217 lines
6.8KB

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