init.lua 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. enderpearl = {}
  2. local t = minetest.get_translator("enderpearl")
  3. local callbacks = {}
  4. ----------------------
  5. -- ! Item Section ! --
  6. ----------------------
  7. minetest.register_craftitem("enderpearl:ender_pearl", {
  8. description = "Enderpearl\n"..t("Left click to throw it@nIt will teleport you on the node it hit making you 2 damage@n(it won't work if you launch it in an unloaded world area)"),
  9. inventory_image = "enderpearl.png",
  10. stack_max = 16,
  11. on_use =
  12. function(_, player, pointed_thing)
  13. local throw_starting_pos = vector.add({x=0, y=1.5, z=0}, player:get_pos())
  14. local ender_pearl = minetest.add_entity(throw_starting_pos, "enderpearl:thrown_ender_pearl", player:get_player_name())
  15. minetest.after(0, function() player:get_inventory():remove_item("main", "enderpearl:ender_pearl") end)
  16. minetest.sound_play("enderpearl_throw", {max_hear_distance = 10, pos = player:get_pos()})
  17. end,
  18. })
  19. ------------------------
  20. -- ! Entity Section ! --
  21. ------------------------
  22. -- entity declaration
  23. local thrown_ender_pearl = {
  24. initial_properties = {
  25. hp_max = 1,
  26. physical = true,
  27. collide_with_objects = false,
  28. collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
  29. visual = "wielditem",
  30. visual_size = {x = 0.4, y = 0.4},
  31. textures = {"enderpearl:ender_pearl"},
  32. spritediv = {x = 1, y = 1},
  33. initial_sprite_basepos = {x = 0, y = 0},
  34. pointable = false,
  35. speed = 56,
  36. gravity = 32,
  37. damage = 2,
  38. lifetime = 10
  39. },
  40. player_name = ""
  41. }
  42. function thrown_ender_pearl:on_step(dtime, moveresult)
  43. local collided_with_node = moveresult.collisions[1] and moveresult.collisions[1].type == "node"
  44. if collided_with_node then
  45. local player = minetest.get_player_by_name(self.player_name)
  46. if not player then
  47. self.object:remove()
  48. return
  49. elseif player:get_meta():get_string("ep_can_teleport") == "false" then
  50. self.object:remove()
  51. return
  52. end
  53. -- removing fall damage
  54. player:add_player_velocity(vector.multiply(player:get_player_velocity(), -1))
  55. player:set_pos(vector.add(self.object:get_pos(), {x = 0, y = 1, z = 0}))
  56. player:set_hp(player:get_hp()-self.initial_properties.damage, "enderpearl")
  57. minetest.sound_play("enderpearl_teleport", {max_hear_distance = 10, pos = player:get_pos()})
  58. for i=1, #callbacks do
  59. local node = minetest.get_node(moveresult.collisions[1].node_pos)
  60. callbacks[i](node)
  61. end
  62. self.object:remove()
  63. end
  64. end
  65. function thrown_ender_pearl:on_activate(staticdata)
  66. if not staticdata or not minetest.get_player_by_name(staticdata) then
  67. self.object:remove()
  68. return
  69. end
  70. self.player_name = staticdata
  71. local player = minetest.get_player_by_name(staticdata)
  72. local yaw = player:get_look_horizontal()
  73. local pitch = player:get_look_vertical()
  74. local dir = player:get_look_dir()
  75. self.object:set_rotation({x = -pitch, y = yaw, z = 0})
  76. self.object:set_velocity({
  77. x=(dir.x * self.initial_properties.speed),
  78. y=(dir.y * self.initial_properties.speed),
  79. z=(dir.z * self.initial_properties.speed),
  80. })
  81. self.object:set_acceleration({x=dir.x*-4, y=-self.initial_properties.gravity, z=dir.z*-4})
  82. minetest.after(self.initial_properties.lifetime, function() self.object:remove() end)
  83. end
  84. minetest.register_entity("enderpearl:thrown_ender_pearl", thrown_ender_pearl)
  85. ---------------------------
  86. -- ! Callbacks Section ! --
  87. ---------------------------
  88. -- on_teleport(hit_node)
  89. function enderpearl.on_teleport(func)
  90. table.insert(callbacks, func)
  91. end
  92. -----------------------
  93. -- ! Utils Section ! --
  94. -----------------------
  95. function enderpearl.block_teleport(player, duration)
  96. if duration then
  97. minetest.after(duration, function()
  98. if minetest.get_player_by_name(player:get_player_name()) then
  99. player:get_meta():set_string("ep_can_teleport", "")
  100. end
  101. end)
  102. end
  103. player:get_meta():set_string("ep_can_teleport", "false")
  104. end