tool.lua 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. -- protector placement tool (thanks to Shara for code and idea)
  2. local S = protector.intllib
  3. -- get protection radius
  4. local r = tonumber(minetest.settings:get("protector_radius")) or 5
  5. -- radius limiter (minetest cannot handle node volume of more than 4096000)
  6. if r > 22 then r = 22 end
  7. minetest.register_craftitem("protector:tool", {
  8. description = S("Protector Placer Tool (stand near protector, face direction and use)"),
  9. inventory_image = "protector_tool.png",
  10. stack_max = 1,
  11. on_use = function(itemstack, user, pointed_thing)
  12. local name = user:get_player_name()
  13. -- check for protector near player (2 block radius)
  14. local pos = user:get_pos()
  15. local pp = minetest.find_nodes_in_area(
  16. vector.subtract(pos, 2), vector.add(pos, 2),
  17. {"protector:protect", "protector:protect2", "protector:protect_hidden"})
  18. if #pp == 0 then return end -- none found
  19. pos = pp[1] -- take position of first protector found
  20. -- get members on protector
  21. local meta = minetest.get_meta(pos)
  22. local members = meta:get_string("members") or ""
  23. -- get direction player is facing
  24. local dir = minetest.dir_to_facedir( user:get_look_dir() )
  25. local vec = {x = 0, y = 0, z = 0}
  26. local gap = (r * 2) + 1
  27. local pit = user:get_look_vertical()
  28. -- set placement coords
  29. if pit > 1.2 then
  30. vec.y = -gap -- up
  31. elseif pit < -1.2 then
  32. vec.y = gap -- down
  33. elseif dir == 0 then
  34. vec.z = gap -- north
  35. elseif dir == 1 then
  36. vec.x = gap -- east
  37. elseif dir == 2 then
  38. vec.z = -gap -- south
  39. elseif dir == 3 then
  40. vec.x = -gap -- west
  41. end
  42. -- new position
  43. pos.x = pos.x + vec.x
  44. pos.y = pos.y + vec.y
  45. pos.z = pos.z + vec.z
  46. -- does placing a protector overlap existing area
  47. if not protector.can_dig(r * 2, pos, user:get_player_name(), true, 3) then
  48. minetest.chat_send_player(name,
  49. S("Overlaps into above players protected area"))
  50. return
  51. end
  52. -- does a protector already exist ?
  53. if #minetest.find_nodes_in_area(
  54. vector.subtract(pos, 1), vector.add(pos, 1),
  55. {"protector:protect", "protector:protect2",
  56. "protector:protect_hidden"}) > 0 then
  57. minetest.chat_send_player(name, S("Protector already in place!"))
  58. return
  59. end
  60. -- do not place protector out of map bounds
  61. if minetest.find_node_near(pos, 1, {"ignore"}) then
  62. return
  63. end
  64. -- do we have protectors to use ?
  65. local nod
  66. local inv = user:get_inventory()
  67. if not inv:contains_item("main", "protector:protect")
  68. and not inv:contains_item("main", "protector:protect2") then
  69. minetest.chat_send_player(name,
  70. S("No protectors available to place!"))
  71. return
  72. end
  73. -- take protector (block first then logo)
  74. if inv:contains_item("main", "protector:protect") then
  75. inv:remove_item("main", "protector:protect")
  76. nod = "protector:protect"
  77. elseif inv:contains_item("main", "protector:protect2") then
  78. inv:remove_item("main", "protector:protect2")
  79. nod = "protector:protect2"
  80. end
  81. -- do not replace containers with inventory space
  82. local inv = minetest.get_inventory({type = "node", pos = pos})
  83. if inv then
  84. minetest.chat_send_player(name,
  85. S("Cannot place protector, container at") ..
  86. " " .. minetest.pos_to_string(pos))
  87. return
  88. end
  89. -- protection check for other mods like Areas
  90. if minetest.is_protected(pos, name) then
  91. minetest.chat_send_player(name,
  92. S("Cannot place protector, already protected at") ..
  93. " " .. minetest.pos_to_string(pos))
  94. return
  95. end
  96. -- place protector
  97. minetest.set_node(pos, {name = nod, param2 = 1})
  98. -- set protector metadata
  99. local meta = minetest.get_meta(pos)
  100. meta:set_string("owner", name)
  101. meta:set_string("infotext", "Protection (owned by " .. name .. ")")
  102. -- copy members across if holding sneak when using tool
  103. if user:get_player_control().sneak then
  104. meta:set_string("members", members)
  105. else
  106. meta:set_string("members", "")
  107. end
  108. minetest.chat_send_player(name,
  109. S("Protector placed at") ..
  110. " " .. minetest.pos_to_string(pos))
  111. end,
  112. })
  113. -- tool recipe
  114. local df = "default:steel_ingot"
  115. if not minetest.registered_items[df] then
  116. df = "mcl_core:iron_ingot"
  117. end
  118. minetest.register_craft({
  119. output = "protector:tool",
  120. recipe = {
  121. {df, df, df},
  122. {df, "protector:protect", df},
  123. {df, df, df}
  124. }
  125. })