stomp.lua 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. local STOMP_RADIUS = 2.5
  2. -- Used for bone placement and stomping.
  3. function armor.find_ground_by_raycast(pos, player)
  4. pos = vector.round(pos)
  5. local p1 = pos
  6. local p2 = vector.offset(pos, 0, -100, 0)
  7. local ray = Raycast(p1, p2, false, false)
  8. local p3 = pos
  9. for pt in ray do
  10. if pt.type == "node" then
  11. local n1 = minetest.get_node(pt.under)
  12. local n2 = minetest.get_node(pt.above)
  13. -- We have found a ground surface suitable for bones or stomping.
  14. if not bones.may_replace(pt.under, player) and bones.may_replace(pt.above, player) then
  15. p3 = pt.above
  16. break
  17. end
  18. end
  19. end
  20. return p3
  21. end
  22. local function boast(stomper, target)
  23. local pname = stomper:get_player_name()
  24. if spam.test_key("stomper" .. pname .. "9353") then
  25. return
  26. end
  27. spam.mark_key("stomper" .. pname .. "9353", 30)
  28. if target:is_player() then
  29. local tname = target:get_player_name()
  30. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> stomped on <" .. rename.gpn(tname) .. ">'s head.")
  31. else
  32. minetest.chat_send_all("# Server: <" .. rename.gpn(pname) .. "> stomped on a mob's head.")
  33. end
  34. end
  35. local function stomp_em(stomper, target, damage)
  36. -- Ignore dead players.
  37. if target:is_player() and target:get_hp() == 0 then
  38. return
  39. end
  40. target:punch(stomper, 1.0, {
  41. full_punch_interval = 1.0,
  42. damage_groups = {crush = damage, from_stomp = 0},
  43. }, nil)--{x=0, y=0.01, z=0})
  44. --minetest.log('stomping! ' .. target:get_player_name() .. ": " .. damage)
  45. if target:is_player() and target:get_hp() == 0 then
  46. boast(stomper, target)
  47. end
  48. end
  49. local function do_stomp(pname, pos, damage)
  50. local stomper = minetest.get_player_by_name(pname)
  51. if not stomper then
  52. return
  53. end
  54. local objs = minetest.get_objects_inside_radius(pos, STOMP_RADIUS)
  55. for k, v in ipairs(objs) do
  56. if v:is_player() and v:get_player_name() ~= pname then
  57. stomp_em(stomper, v, damage)
  58. else
  59. local ent = v:get_luaentity()
  60. if ent and ent.mob then
  61. stomp_em(stomper, v, damage)
  62. end
  63. end
  64. end
  65. end
  66. function armor.stomp_at(stomper, pos, damage)
  67. local pname = stomper:get_player_name()
  68. local objs = minetest.get_objects_inside_radius(pos, STOMP_RADIUS)
  69. local stomped = false
  70. -- Check if we're going to stomp anybody.
  71. for k, v in ipairs(objs) do
  72. if v:is_player() and v:get_player_name() ~= pname then
  73. -- Ignore the dead ones.
  74. if v:get_hp() > 0 then
  75. stomped = true
  76. end
  77. else
  78. local ent = v:get_luaentity()
  79. if ent and ent.mob then
  80. stomped = true
  81. end
  82. end
  83. end
  84. -- Must execute on the next server step, to avoid conflict with currently
  85. -- running armor/hp-change code.
  86. minetest.after(0, function() do_stomp(pname, pos, damage) end)
  87. return stomped
  88. end