functions.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. doors = {}
  2. local floor_dir = {
  3. [0] = 15,
  4. [1] = 8,
  5. [2] = 17,
  6. [3] = 6,
  7. }
  8. local ceil_dir = {
  9. [0] = 19,
  10. [1] = 4,
  11. [2] = 13,
  12. [3] = 10,
  13. }
  14. local wall_dir = {
  15. [0] = 20,
  16. [1] = 23,
  17. [2] = 22,
  18. [3] = 21,
  19. }
  20. function doors:register_door(name, def)
  21. local tiles = def.tiles
  22. -- Change door status
  23. local function use(pos, replace_dir)
  24. local node = minetest.get_node(pos)
  25. local param2 = node.param2
  26. minetest.sound_play("default_dig_choppy", {pos, gain = 0.5, max_hear_distance = 32})
  27. minetest.swap_node(pos, {name=replace_dir, param2=param2})
  28. end
  29. -- Check for other doors
  30. local function update(pos, dir)
  31. local node = minetest.get_node(pos)
  32. local status = minetest.registered_nodes[node.name].status
  33. local pos_next = {x=pos.x, y=pos.y+dir, z=pos.z}
  34. local node_next = minetest.get_node(pos_next)
  35. local status_next = minetest.registered_nodes[node_next.name].status
  36. if status_next == nil then return end
  37. if status_next == status then
  38. update(pos_next, dir)
  39. local name = minetest.registered_nodes[node_next.name].base_name
  40. if status == 1 then
  41. use(pos_next, name.."_2")
  42. elseif status == 2 then
  43. use(pos_next, name.."_1")
  44. end
  45. end
  46. end
  47. local function check_player_priv(pos, player)
  48. if not def.only_placer_can_open then
  49. return true
  50. end
  51. local meta = minetest.get_meta(pos)
  52. local playername = player:get_player_name()
  53. return meta:get_string("doors_owner") == playername
  54. end
  55. -- Closed door
  56. minetest.register_node(":"..name.."_1", {
  57. description = def.description,
  58. inventory_image = def.inventory_image,
  59. tiles = {tiles[1].."^[transformR180", tiles[1].."^[transformR180", tiles[1], tiles[1], tiles[1], tiles[1].."^[transformfx"},
  60. paramtype = "light",
  61. paramtype2 = "facedir",
  62. drop = name.."_1",
  63. drawtype = "nodebox",
  64. node_box = {
  65. type = "fixed",
  66. fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1/16}
  67. },
  68. selection_box = {
  69. type = "fixed",
  70. fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1/16}
  71. },
  72. groups = def.groups,
  73. status = 1,
  74. base_name = name,
  75. on_rightclick = function(pos, node, user)
  76. if user:get_player_control().sneak then return end
  77. if not check_player_priv(pos, user) then return end
  78. update(pos, 1)
  79. update(pos, -1)
  80. use(pos, name.."_2")
  81. end,
  82. on_place = function(itemstack, placer, pointed_thing)
  83. if not pointed_thing.type == "node" then
  84. return itemstack
  85. end
  86. local ptu = pointed_thing.under
  87. local pta = pointed_thing.above
  88. local param2 = minetest.dir_to_facedir(placer:get_look_dir())
  89. local nodeunder = minetest.get_node(ptu)
  90. local nodeunder_def = minetest.registered_nodes[nodeunder.name]
  91. if nodeunder_def and nodeunder_def.on_rightclick then
  92. return nodeunder_def.on_rightclick(ptu, nodeunder, placer, itemstack)
  93. end
  94. -- Place joint on the surface the placer is pointing to
  95. local face = param2
  96. if ptu.y < pta.y then
  97. face = floor_dir[param2]
  98. elseif ptu.y > pta.y then
  99. face = ceil_dir[param2]
  100. elseif (param2 == 0 and ptu.x > pta.x) or
  101. (param2 == 1 and ptu.z < pta.z) or
  102. (param2 == 2 and ptu.x < pta.x) or
  103. (param2 == 3 and ptu.z > pta.z) then
  104. face = wall_dir[param2]
  105. end
  106. -- In every other case place normal
  107. minetest.set_node(pta, {name=name.."_1", param2=face})
  108. if def.only_placer_can_open then
  109. local playername = placer:get_player_name()
  110. local meta = minetest.get_meta(pta)
  111. meta:set_string("doors_owner", playername)
  112. meta:set_string("infotext", "Owned by "..playername)
  113. end
  114. if not minetest.settings:get_bool("creative_mode") then
  115. itemstack:take_item()
  116. end
  117. minetest.sound_play("default_place_node", {ptu, gain = 0.5, max_hear_distance = 32})
  118. return itemstack
  119. end,
  120. })
  121. -- Open door
  122. minetest.register_node(":"..name.."_2", {
  123. tiles = {tiles[1].."^[transformfy^[transformR270", tiles[1].."^[transformfy^[transformR90", tiles[1].."^[transformfx", tiles[1], tiles[1].."^[transformfx", tiles[1].."^[transformfx"},
  124. paramtype = "light",
  125. paramtype2 = "facedir",
  126. drop = name.."_1",
  127. drawtype = "nodebox",
  128. node_box = {
  129. type = "fixed",
  130. fixed = {-0.5, -0.5, -0.5, -0.5+1/16, 0.5, 0.5}
  131. },
  132. selection_box = {
  133. type = "fixed",
  134. fixed = {-0.5, -0.5, -0.5, -0.5+1/16, 0.5, 0.5}
  135. },
  136. groups = def.groups,
  137. status = 2,
  138. base_name = name,
  139. on_rightclick = function(pos, node, user)
  140. if user:get_player_control().sneak then return end
  141. if not check_player_priv(pos, user) then return end
  142. update(pos, 1)
  143. update(pos, -1)
  144. use(pos, name.."_1")
  145. end,
  146. })
  147. end