compat-chests.lua 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. -- this bit of code modifies the default chests and furnaces to be compatible
  2. -- with pipeworks.
  3. --
  4. -- the formspecs found here are basically copies of the ones from minetest_game
  5. -- plus bits from pipeworks' sorting tubes
  6. -- Pipeworks Specific
  7. local fs_helpers = pipeworks.fs_helpers
  8. local tube_entry = "^pipeworks_tube_connection_wooden.png"
  9. -- Chest Locals
  10. local open_chests = {}
  11. local function get_chest_formspec(pos)
  12. local spos = pos.x .. "," .. pos.y .. "," .. pos.z
  13. local formspec =
  14. "size[8,9]" ..
  15. default.gui_bg ..
  16. default.gui_bg_img ..
  17. default.gui_slots ..
  18. "list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" ..
  19. "list[current_player;main;0,4.85;8,1;]" ..
  20. "list[current_player;main;0,6.08;8,3;8]" ..
  21. "listring[nodemeta:" .. spos .. ";main]" ..
  22. "listring[current_player;main]" ..
  23. default.get_hotbar_bg(0,4.85)
  24. -- Pipeworks Switch
  25. formspec = formspec ..
  26. fs_helpers.cycling_button(
  27. minetest.get_meta(pos),
  28. pipeworks.button_base,
  29. "splitstacks",
  30. {
  31. pipeworks.button_off,
  32. pipeworks.button_on
  33. }
  34. )..pipeworks.button_label
  35. return formspec
  36. end
  37. local function chest_lid_obstructed(pos)
  38. local above = { x = pos.x, y = pos.y + 1, z = pos.z }
  39. local def = minetest.registered_nodes[minetest.get_node(above).name]
  40. -- allow ladders, signs, wallmounted things and torches to not obstruct
  41. if not def then return true end
  42. if def.drawtype == "airlike" or
  43. def.drawtype == "signlike" or
  44. def.drawtype == "torchlike" or
  45. (def.drawtype == "nodebox" and def.paramtype2 == "wallmounted") then
  46. return false
  47. end
  48. return true
  49. end
  50. minetest.register_on_player_receive_fields(function(player, formname, fields)
  51. if formname == "pipeworks:chest_formspec" and player then
  52. local pn = player:get_player_name()
  53. if open_chests[pn] then
  54. local pos = open_chests[pn].pos
  55. if fields.quit then
  56. local sound = open_chests[pn].sound
  57. local swap = open_chests[pn].swap
  58. local node = minetest.get_node(pos)
  59. open_chests[pn] = nil
  60. for k, v in pairs(open_chests) do
  61. if v.pos.x == pos.x and v.pos.y == pos.y and v.pos.z == pos.z then
  62. return true
  63. end
  64. end
  65. minetest.after(0.2, function()
  66. minetest.swap_node(pos, { name = "default:" .. swap, param2 = node.param2 })
  67. -- Pipeworks notification
  68. pipeworks.after_place(pos)
  69. end)
  70. minetest.sound_play(sound, {gain = 0.3, pos = pos, max_hear_distance = 10})
  71. elseif pipeworks.may_configure(pos, player) then
  72. -- Pipeworks Switch
  73. fs_helpers.on_receive_fields(pos, fields)
  74. minetest.show_formspec(player:get_player_name(), "pipeworks:chest_formspec", get_chest_formspec(pos))
  75. end
  76. return true
  77. end
  78. end
  79. end)
  80. -- Original Definitions
  81. local old_chest_def = table.copy(minetest.registered_items["default:chest"])
  82. local old_chest_open_def = table.copy(minetest.registered_items["default:chest_open"])
  83. local old_chest_locked_def = table.copy(minetest.registered_items["default:chest_locked"])
  84. local old_chest_locked_open_def = table.copy(minetest.registered_items["default:chest_locked_open"])
  85. -- Override Construction
  86. local override_protected, override, override_open, override_protected_open
  87. override_protected = {
  88. tiles = {
  89. "default_chest_top.png"..tube_entry,
  90. "default_chest_top.png"..tube_entry,
  91. "default_chest_side.png"..tube_entry,
  92. "default_chest_side.png"..tube_entry,
  93. "default_chest_lock.png",
  94. "default_chest_inside.png"
  95. },
  96. after_place_node = function(pos, placer)
  97. old_chest_locked_def.after_place_node(pos, placer)
  98. pipeworks.after_place(pos)
  99. end,
  100. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  101. if not default.can_interact_with_node(clicker, pos) then
  102. return itemstack
  103. end
  104. minetest.sound_play(old_chest_locked_def.sound_open, {gain = 0.3,
  105. pos = pos, max_hear_distance = 10})
  106. if not chest_lid_obstructed(pos) then
  107. minetest.swap_node(pos,
  108. { name = "default:" .. "chest_locked" .. "_open",
  109. param2 = node.param2 })
  110. end
  111. minetest.after(0.2, minetest.show_formspec,
  112. clicker:get_player_name(),
  113. "pipeworks:chest_formspec", get_chest_formspec(pos))
  114. open_chests[clicker:get_player_name()] = { pos = pos,
  115. sound = old_chest_locked_def.sound_close, swap = "chest_locked" }
  116. end,
  117. groups = table.copy(old_chest_locked_def.groups),
  118. tube = {
  119. insert_object = function(pos, node, stack, direction)
  120. local meta = minetest.get_meta(pos)
  121. local inv = meta:get_inventory()
  122. return inv:add_item("main", stack)
  123. end,
  124. can_insert = function(pos, node, stack, direction)
  125. local meta = minetest.get_meta(pos)
  126. local inv = meta:get_inventory()
  127. if meta:get_int("splitstacks") == 1 then
  128. stack = stack:peek_item(1)
  129. end
  130. return inv:room_for_item("main", stack)
  131. end,
  132. input_inventory = "main",
  133. connect_sides = {left = 1, right = 1, back = 1, bottom = 1, top = 1}
  134. },
  135. after_dig_node = pipeworks.after_dig,
  136. on_rotate = pipeworks.on_rotate
  137. }
  138. override = {
  139. tiles = {
  140. "default_chest_top.png"..tube_entry,
  141. "default_chest_top.png"..tube_entry,
  142. "default_chest_side.png"..tube_entry,
  143. "default_chest_side.png"..tube_entry,
  144. "default_chest_front.png",
  145. "default_chest_inside.png"
  146. },
  147. on_rightclick = function(pos, node, clicker)
  148. minetest.sound_play(old_chest_def.sound_open, {gain = 0.3, pos = pos,
  149. max_hear_distance = 10})
  150. if not chest_lid_obstructed(pos) then
  151. minetest.swap_node(pos, {
  152. name = "default:" .. "chest" .. "_open",
  153. param2 = node.param2 })
  154. end
  155. minetest.after(0.2, minetest.show_formspec,
  156. clicker:get_player_name(),
  157. "pipeworks:chest_formspec", get_chest_formspec(pos))
  158. open_chests[clicker:get_player_name()] = { pos = pos,
  159. sound = old_chest_def.sound_close, swap = "chest" }
  160. end,
  161. groups = table.copy(old_chest_def.groups),
  162. tube = {
  163. insert_object = function(pos, node, stack, direction)
  164. local meta = minetest.get_meta(pos)
  165. local inv = meta:get_inventory()
  166. return inv:add_item("main", stack)
  167. end,
  168. can_insert = function(pos, node, stack, direction)
  169. local meta = minetest.get_meta(pos)
  170. local inv = meta:get_inventory()
  171. if meta:get_int("splitstacks") == 1 then
  172. stack = stack:peek_item(1)
  173. end
  174. return inv:room_for_item("main", stack)
  175. end,
  176. input_inventory = "main",
  177. connect_sides = {left = 1, right = 1, back = 1, bottom = 1, top = 1}
  178. },
  179. after_place_node = pipeworks.after_place,
  180. after_dig_node = pipeworks.after_dig,
  181. on_rotate = pipeworks.on_rotate
  182. }
  183. --[[local override_common = {
  184. }
  185. for k,v in pairs(override_common) do
  186. override_protected[k] = v
  187. override[k] = v
  188. end]]
  189. override_open = table.copy(override)
  190. override_open.groups = table.copy(old_chest_open_def.groups)
  191. override_open.tube = table.copy(override.tube)
  192. override_open.tube.connect_sides = table.copy(override.tube.connect_sides)
  193. override_open.tube.connect_sides.top = nil
  194. override_protected_open = table.copy(override_protected)
  195. override_protected_open.groups = table.copy(old_chest_locked_open_def.groups)
  196. override_protected_open.tube = table.copy(override_protected.tube)
  197. override_protected_open.tube.connect_sides = table.copy(override_protected.tube.connect_sides)
  198. override_protected_open.tube.connect_sides.top = nil
  199. override_protected.tiles = { -- Rearranged according to the chest registration in Minetest_Game.
  200. "default_chest_top.png"..tube_entry,
  201. "default_chest_top.png"..tube_entry,
  202. "default_chest_side.png"..tube_entry.."^[transformFX",
  203. "default_chest_side.png"..tube_entry,
  204. "default_chest_side.png"..tube_entry,
  205. "default_chest_lock.png",
  206. }
  207. override.tiles = {
  208. "default_chest_top.png"..tube_entry,
  209. "default_chest_top.png"..tube_entry,
  210. "default_chest_side.png"..tube_entry.."^[transformFX",
  211. "default_chest_side.png"..tube_entry,
  212. "default_chest_side.png"..tube_entry,
  213. "default_chest_front.png",
  214. }
  215. -- Add the extra groups
  216. for i,v in ipairs({override_protected, override, override_open, override_protected_open}) do
  217. v.groups.tubedevice = 1
  218. v.groups.tubedevice_receiver = 1
  219. end
  220. -- Override with the new modifications.
  221. minetest.override_item("default:chest", override)
  222. minetest.override_item("default:chest_open", override_open)
  223. minetest.override_item("default:chest_locked", override_protected)
  224. minetest.override_item("default:chest_locked_open", override_protected_open)