elevator.lua 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. -- This version of the travelnet box allows to move up or down only.
  2. -- The network name is determined automaticly from the position (x/z coordinates).
  3. -- Author: Sokomine
  4. local S = minetest.get_translator("travelnet")
  5. function travelnet.show_nearest_elevator(pos, owner_name, param2)
  6. if not pos or not pos.x or not pos.z or not owner_name then
  7. return
  8. end
  9. local player_travelnets = travelnet.get_travelnets(owner_name)
  10. if not player_travelnets then
  11. minetest.chat_send_player(owner_name,
  12. S("Congratulations! This is your first elevator. " ..
  13. "You can build an elevator network by placing further elevators somewhere above " ..
  14. "or below this one. Just make sure that the x and z coordinate are the same."))
  15. return
  16. end
  17. local network_name = travelnet.elevator_network(pos)
  18. -- will this be an elevator that will be added to an existing network?
  19. if player_travelnets[network_name]
  20. -- does the network have any members at all?
  21. and next(player_travelnets[network_name], nil)
  22. then
  23. minetest.chat_send_player(owner_name,
  24. S("This elevator will automatically connect to the " ..
  25. "other elevators you have placed at different heights. Just enter a station name " ..
  26. "and click on \"store\" to set it up. Or just punch it to set the height as station " ..
  27. "name."))
  28. return
  29. end
  30. local nearest_name, nearest_dist = travelnet.find_nearest_elevator_network(pos, owner_name)
  31. if not nearest_name then
  32. minetest.chat_send_player(owner_name,
  33. S("This is your first elevator. It differs from " ..
  34. "travelnet networks by only allowing movement in vertical direction (up or down). " ..
  35. "All further elevators which you will place at the same x,z coordinates at different " ..
  36. "heights will be able to connect to this elevator."))
  37. return
  38. end
  39. local direction_strings = {
  40. S("m to the right"),
  41. S("m behind this elevator and"),
  42. S("m to the left"),
  43. S("m in front of this elevator and")
  44. }
  45. local direction_indexes = { x=param2+1, z=((param2+1) % 4)+1 }
  46. -- Should X or Z be displayed first?
  47. local direction_order = ({ [0]={"z","x"}, [1]={"x","z"} })[param2 % 2]
  48. local text = S("Your nearest elevator network is located") .. " "
  49. for index, direction in ipairs(direction_order) do
  50. local nearest_dist_direction = nearest_dist[direction]
  51. local direction_index = direction_indexes[direction]
  52. if nearest_dist_direction < 0 then
  53. direction_index = ((direction_indexes[direction]+1) % 4)+1
  54. end
  55. text = text .. tostring(math.abs(nearest_dist_direction)) .. " " .. direction_strings[direction_index]
  56. if index == 1 then text = text .. " " end
  57. end
  58. minetest.chat_send_player(owner_name, text .. S(", located at x") ..
  59. ("=%f, z=%f. "):format(pos.x + nearest_dist.x, pos.z + nearest_dist.z) ..
  60. S("This elevator here will start a new shaft/network."))
  61. end
  62. local function on_interact(pos, _, player)
  63. local meta = minetest.get_meta(pos)
  64. local legacy_formspec = meta:get_string("formspec")
  65. if not travelnet.is_falsey_string(legacy_formspec) then
  66. meta:set_string("formspec", "")
  67. end
  68. local player_name = player:get_player_name()
  69. travelnet.show_current_formspec(pos, meta, player_name)
  70. end
  71. minetest.register_node(":travelnet:elevator", {
  72. description = S("Elevator"),
  73. drawtype = "mesh",
  74. mesh = "travelnet_elevator.obj",
  75. sunlight_propagates = true,
  76. paramtype = "light",
  77. paramtype2 = "facedir",
  78. wield_scale = { x=0.6, y=0.6, z=0.6 },
  79. selection_box = travelnet.node_box,
  80. collision_box = travelnet.node_box,
  81. tiles = travelnet.tiles_elevator,
  82. inventory_image = travelnet.elevator_inventory_image,
  83. groups = {
  84. elevator = 1
  85. },
  86. light_source = 10,
  87. after_place_node = function(pos, placer)
  88. local meta = minetest.get_meta(pos)
  89. meta:set_string("infotext", S("Elevator (unconfigured)"))
  90. meta:set_string("station_name", "")
  91. meta:set_string("station_network","")
  92. meta:set_string("owner", placer:get_player_name())
  93. minetest.set_node(vector.add(pos, { x=0, y=1, z=0 }), { name="travelnet:hidden_top" })
  94. travelnet.show_nearest_elevator(pos, placer:get_player_name(), minetest.dir_to_facedir(placer:get_look_dir()))
  95. end,
  96. on_rightclick = on_interact,
  97. on_punch = on_interact,
  98. can_dig = function(pos, player)
  99. return travelnet.can_dig(pos, player, "elevator")
  100. end,
  101. after_dig_node = function(pos, oldnode, oldmetadata, digger)
  102. travelnet.remove_box(pos, oldnode, oldmetadata, digger)
  103. end,
  104. -- TNT and overenthusiastic DMs do not destroy elevators either
  105. on_blast = function()
  106. end,
  107. -- taken from VanessaEs homedecor fridge
  108. on_place = function(itemstack, placer, pointed_thing)
  109. local node = minetest.get_node(vector.add(pointed_thing.above, { x=0, y=1, z=0 }))
  110. local def = minetest.registered_nodes[node.name]
  111. -- leftover top nodes can be removed by placing a new elevator underneath
  112. if (not def or not def.buildable_to) and node.name ~= "travelnet:hidden_top" then
  113. minetest.chat_send_player(
  114. placer:get_player_name(),
  115. S("Not enough vertical space to place the travelnet box!")
  116. )
  117. return
  118. end
  119. return minetest.item_place(itemstack, placer, pointed_thing)
  120. end,
  121. on_destruct = function(pos)
  122. local above = vector.add(pos, vector.new(0, 1, 0))
  123. if minetest.get_node(above).name == "travelnet:hidden_top" then
  124. minetest.remove_node(above)
  125. end
  126. end
  127. })
  128. minetest.register_craft({
  129. output = "travelnet:elevator",
  130. recipe = travelnet.elevator_recipe,
  131. })