functions.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. function utility.detach_player_with_message(player)
  2. local k = default.detach_player_if_attached(player)
  3. if k then
  4. local t = player:get_player_name()
  5. if k == "cart" then
  6. minetest.chat_send_all("# Server: Someone threw <" .. rename.gpn(t) .. "> out of a minecart.")
  7. elseif k == "boat" then
  8. minetest.chat_send_all("# Server: Boater <" .. rename.gpn(t) .. "> was tossed overboard.")
  9. elseif k == "sled" then
  10. minetest.chat_send_all("# Server: Someone kicked <" .. rename.gpn(t) .. "> off a sled.")
  11. elseif k == "bed" then
  12. minetest.chat_send_all("# Server: <" .. rename.gpn(t) .. "> was rudely kicked out of bed.")
  13. end
  14. end
  15. end
  16. -- Function to find an ignore node NOT beyond the world edge.
  17. -- This is useful when we must check for `ignore`, but don't want to be confused at the edge of the world.
  18. function utility.find_node_near_not_world_edge(pos, rad, node)
  19. local minp = vector.subtract(pos, rad)
  20. local maxp = vector.add(pos, rad)
  21. minp.x = math.max(minp.x, -30912)
  22. minp.y = math.max(minp.y, -30912)
  23. minp.z = math.max(minp.z, -30912)
  24. maxp.x = math.min(maxp.x, 30927)
  25. maxp.y = math.min(maxp.y, 30927)
  26. maxp.z = math.min(maxp.z, 30927)
  27. local positions = minetest.find_nodes_in_area(minp, maxp, node)
  28. if (#positions > 0) then
  29. return positions[math.random(1, #positions)]
  30. end
  31. end
  32. local function add_effects(pos, radius)
  33. minetest.add_particlespawner({
  34. amount = 8,
  35. time = 0.5,
  36. minpos = vector.subtract(pos, radius / 2),
  37. maxpos = vector.add(pos, radius / 2),
  38. minvel = {x=-10, y=-10, z=-10},
  39. maxvel = {x=10, y=10, z=10},
  40. minacc = vector.new(),
  41. maxacc = vector.new(),
  42. minexptime = 0.5,
  43. maxexptime = 1,
  44. minsize = 0.5,
  45. maxsize = 1,
  46. texture = "tnt_smoke.png",
  47. })
  48. end
  49. function utility.shell_boom(pos)
  50. minetest.sound_play("throwing_shell_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
  51. -- Don't destroy things.
  52. if minetest.get_node(pos).name == "air" then
  53. minetest.set_node(pos, {name="tnt:boom"})
  54. minetest.get_node_timer(pos):start(0.5)
  55. end
  56. add_effects(pos, 1)
  57. end
  58. -- Note: this works for boats, too.
  59. -- Returns [""] if player wasn't attached. Otherwise, name of previous attachment type.
  60. function default.detach_player_if_attached(player)
  61. local pname = player:get_player_name()
  62. -- Player might be in bed! Get them out properly.
  63. if beds.kick_one_player(pname) then
  64. return "bed"
  65. end
  66. local ents = minetest.get_objects_inside_radius(utility.get_foot_pos(player:get_pos()), 2)
  67. local result = ""
  68. for k, obj in ipairs(ents) do
  69. local ent = obj:get_luaentity()
  70. if ent and ent.name == "carts:cart" then
  71. -- Must detach player from cart.
  72. carts:manage_attachment(player, nil)
  73. result = "cart"
  74. elseif ent and ent.name == "boats:boat" then
  75. if ent.driver and ent.driver == player then
  76. -- Since boat driver == player, this should always detach.
  77. boats.on_rightclick(ent, player)
  78. result = "boat"
  79. end
  80. elseif ent and ent.name == "sleds:sled" then
  81. if ent.driver and ent.driver == player then
  82. sleds.on_rightclick(ent, player)
  83. result = "sled"
  84. end
  85. end
  86. end
  87. return result
  88. end