action.lua 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. -- Localize for performance.
  2. local vector_distance = vector.distance
  3. local vector_round = vector.round
  4. local math_random = math.random
  5. local function throw_player(e, p)
  6. local p1 = e:get_pos()
  7. local p2 = p:get_pos()
  8. p1.y = p2.y
  9. local vel = vector.subtract(p2, p1)
  10. vel = vector.normalize(vel)
  11. vel = vector.add(vel, {x=0, y=0.5, z=0})
  12. vel = vector.multiply(vel, 10)
  13. p:add_player_velocity(vel)
  14. end
  15. function pm.shove_player(self, target)
  16. if target and target:is_player() then
  17. throw_player(self.object, target)
  18. end
  19. end
  20. function pm.hurt_nearby_players(self)
  21. local pos = self.object:get_pos()
  22. local players = minetest.get_connected_players()
  23. for k, v in ipairs(players) do
  24. if vector_distance(pos, v:get_pos()) < 2 then
  25. throw_player(self.object, v)
  26. v:set_hp(v:get_hp() - 1)
  27. end
  28. end
  29. end
  30. function pm.hurt_nearby_player_or_mob_not_wisp(self)
  31. local pos = self.object:get_pos()
  32. local objects = pm.get_nearby_objects(self, pos, 2)
  33. for k, v in ipairs(objects) do
  34. if v:is_player() then
  35. throw_player(self.object, v)
  36. v:set_hp(v:get_hp() - 1)
  37. else
  38. local ent = v:get_luaentity()
  39. if ent.mob and ent.name ~= "pm:follower" then
  40. local tcaps = tooldata["sword_steel"]
  41. v:punch(v, 1.0, tcaps, nil)
  42. end
  43. end
  44. end
  45. end
  46. function pm.heal_nearby_players(self)
  47. local pos = self.object:get_pos()
  48. local players = minetest.get_connected_players()
  49. for k, v in ipairs(players) do
  50. if vector_distance(pos, v:get_pos()) < 2 then
  51. v:set_hp(v:get_hp() + 1)
  52. end
  53. end
  54. end
  55. function pm.steal_nearby_item(self, target)
  56. if target then
  57. if target:is_player() then
  58. local inv = target:get_inventory()
  59. local max = inv:get_size("main")
  60. local idx = math_random(1, max)
  61. local stack = inv:get_stack("main", idx)
  62. if not passport.is_passport(stack:get_name()) then
  63. if stack:get_count() >= 10 then
  64. local item = stack:take_item(math_random(1, 10))
  65. inv:set_stack("main", idx, stack)
  66. minetest.item_drop(item, target, self.object:get_pos())
  67. end
  68. end
  69. else
  70. local ent = target:get_luaentity()
  71. if ent.name == "__builtin:item" then
  72. target:remove()
  73. end
  74. end
  75. end
  76. end
  77. function pm.explode_nearby_target(self, target)
  78. if target then
  79. tnt.boom(self.object:get_pos(), {
  80. radius = 2,
  81. damage_radius = 3,
  82. ignore_protection = false,
  83. ignore_on_blast = false,
  84. disable_drops = true,
  85. })
  86. end
  87. end
  88. function pm.commit_arson_at_target(pos)
  89. local p = vector_round(pos)
  90. p = minetest.find_node_near(pos, 1, "air", true)
  91. if p and not minetest.test_protection(p, "") then
  92. minetest.set_node(p, {name="fire:basic_flame"})
  93. end
  94. end
  95. function pm.teleport_player_to_prior_location(target)
  96. if target and target:is_player() then
  97. local pname = target:get_player_name()
  98. local positions = ap.get_position_list(pname)
  99. if #positions > 0 then
  100. local tpos = positions[1].pos
  101. preload_tp.execute({
  102. player_name = pname,
  103. target_position = tpos,
  104. emerge_radius = 8,
  105. force_teleport = true,
  106. send_blocks = false, -- Player's client probably already has them loaded.
  107. particle_effects = true,
  108. })
  109. end
  110. end
  111. end