inventory.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. local player_inventory = {}
  2. function creative.init_creative_inventory(player)
  3. local player_name = player:get_player_name()
  4. player_inventory[player_name] = {
  5. size = 0,
  6. filter = "",
  7. start_i = 0
  8. }
  9. minetest.create_detached_inventory("creative_" .. player_name, {
  10. allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
  11. local name = player2 and player2:get_player_name() or ""
  12. if not creative.is_enabled_for(name) or
  13. to_list == "main" then
  14. return 0
  15. end
  16. return count
  17. end,
  18. allow_put = function(inv, listname, index, stack, player2)
  19. return 0
  20. end,
  21. allow_take = function(inv, listname, index, stack, player2)
  22. local name = player2 and player2:get_player_name() or ""
  23. if not creative.is_enabled_for(name) then
  24. return 0
  25. end
  26. return -1
  27. end,
  28. on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
  29. end,
  30. on_take = function(inv, listname, index, stack, player2)
  31. if stack and stack:get_count() > 0 then
  32. minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory")
  33. end
  34. end,
  35. }, player_name)
  36. return player_inventory[player_name]
  37. end
  38. function creative.update_creative_inventory(player_name, tab_content)
  39. local creative_list = {}
  40. local inv = player_inventory[player_name] or
  41. creative.init_creative_inventory(minetest.get_player_by_name(player_name))
  42. local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name})
  43. for name, def in pairs(tab_content) do
  44. if not (def.groups.not_in_creative_inventory == 1) and
  45. def.description and def.description ~= "" and
  46. (def.name:find(inv.filter, 1, true) or
  47. def.description:lower():find(inv.filter, 1, true)) then
  48. creative_list[#creative_list+1] = name
  49. end
  50. end
  51. table.sort(creative_list)
  52. player_inv:set_size("main", #creative_list)
  53. player_inv:set_list("main", creative_list)
  54. inv.size = #creative_list
  55. end
  56. -- Create the trash field
  57. local trash = minetest.create_detached_inventory("creative_trash", {
  58. -- Allow the stack to be placed and remove it in on_put()
  59. -- This allows the creative inventory to restore the stack
  60. allow_put = function(inv, listname, index, stack, player)
  61. return stack:get_count()
  62. end,
  63. on_put = function(inv, listname)
  64. inv:set_list(listname, {})
  65. end,
  66. })
  67. trash:set_size("main", 1)
  68. creative.formspec_add = ""
  69. function creative.register_tab(name, title, items)
  70. sfinv.register_page("creative:" .. name, {
  71. title = title,
  72. is_in_nav = function(self, player, context)
  73. return creative.is_enabled_for(player:get_player_name())
  74. end,
  75. get = function(self, player, context)
  76. local player_name = player:get_player_name()
  77. creative.update_creative_inventory(player_name, items)
  78. local inv = player_inventory[player_name]
  79. local start_i = inv.start_i or 0
  80. local pagenum = math.floor(start_i / (3*8) + 1)
  81. local pagemax = math.ceil(inv.size / (3*8))
  82. return sfinv.make_formspec(player, context,
  83. "label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" ..
  84. [[
  85. image[4.06,3.4;0.8,0.8;creative_trash_icon.png]
  86. listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
  87. list[current_player;main;0,4.7;8,1;]
  88. list[current_player;main;0,5.85;8,3;8]
  89. list[detached:creative_trash;main;4,3.3;1,1;]
  90. listring[]
  91. button[5.4,3.2;0.8,0.9;creative_prev;<]
  92. button[7.25,3.2;0.8,0.9;creative_next;>]
  93. button[2.1,3.4;0.8,0.5;creative_search;?]
  94. button[2.75,3.4;0.8,0.5;creative_clear;X]
  95. tooltip[creative_search;Search]
  96. tooltip[creative_clear;Reset]
  97. listring[current_player;main]
  98. field_close_on_enter[creative_filter;false]
  99. ]] ..
  100. "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" ..
  101. "listring[detached:creative_" .. player_name .. ";main]" ..
  102. "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" ..
  103. default.get_hotbar_bg(0,4.7) ..
  104. default.gui_bg .. default.gui_bg_img .. default.gui_slots
  105. .. creative.formspec_add, false)
  106. end,
  107. on_enter = function(self, player, context)
  108. local player_name = player:get_player_name()
  109. local inv = player_inventory[player_name]
  110. if inv then
  111. inv.start_i = 0
  112. end
  113. end,
  114. on_player_receive_fields = function(self, player, context, fields)
  115. local player_name = player:get_player_name()
  116. local inv = player_inventory[player_name]
  117. assert(inv)
  118. if fields.creative_clear then
  119. inv.start_i = 0
  120. inv.filter = ""
  121. creative.update_creative_inventory(player_name, items)
  122. sfinv.set_player_inventory_formspec(player, context)
  123. elseif fields.creative_search or
  124. fields.key_enter_field == "creative_filter" then
  125. inv.start_i = 0
  126. inv.filter = fields.creative_filter:lower()
  127. creative.update_creative_inventory(player_name, items)
  128. sfinv.set_player_inventory_formspec(player, context)
  129. elseif not fields.quit then
  130. local start_i = inv.start_i or 0
  131. if fields.creative_prev then
  132. start_i = start_i - 3*8
  133. if start_i < 0 then
  134. start_i = inv.size - (inv.size % (3*8))
  135. if inv.size == start_i then
  136. start_i = math.max(0, inv.size - (3*8))
  137. end
  138. end
  139. elseif fields.creative_next then
  140. start_i = start_i + 3*8
  141. if start_i >= inv.size then
  142. start_i = 0
  143. end
  144. end
  145. inv.start_i = start_i
  146. sfinv.set_player_inventory_formspec(player, context)
  147. end
  148. end
  149. })
  150. end
  151. minetest.register_on_joinplayer(function(player)
  152. creative.update_creative_inventory(player:get_player_name(), minetest.registered_items)
  153. end)
  154. creative.register_tab("all", "All", minetest.registered_items)
  155. creative.register_tab("nodes", "Nodes", minetest.registered_nodes)
  156. creative.register_tab("tools", "Tools", minetest.registered_tools)
  157. creative.register_tab("craftitems", "Items", minetest.registered_craftitems)
  158. local old_homepage_name = sfinv.get_homepage_name
  159. function sfinv.get_homepage_name(player)
  160. if creative.is_enabled_for(player:get_player_name()) then
  161. return "creative:all"
  162. else
  163. return old_homepage_name(player)
  164. end
  165. end