scuba.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. -- This file is reloadable.
  2. local done_scuba = function(name)
  3. if ambiance.players[name] ~= nil then
  4. ambiance.players[name].scuba = nil
  5. end
  6. end
  7. local done_splash = function(name)
  8. if ambiance.players[name] ~= nil then
  9. ambiance.players[name].hsplash = nil
  10. end
  11. end
  12. function ambiance.check_water_pressure(pos, player)
  13. local y = pos.y
  14. local c = 45
  15. local w = 0
  16. local n = minetest.get_node(pos)
  17. local d = minetest.registered_nodes[n.name] or {}
  18. local g = d.groups or {}
  19. -- Count water nodes above player, starting with position.
  20. while c > 0 and g.water and g.water > 0 do
  21. w = w + 1
  22. c = c - 1
  23. pos.y = pos.y + 1
  24. n = minetest.get_node(pos)
  25. d = minetest.registered_nodes[n.name] or {}
  26. g = d.groups or {}
  27. end
  28. pos.y = y
  29. local damage = 0
  30. if y < -50 then
  31. if w >= 45 then
  32. damage = 3
  33. elseif w >= 30 then
  34. damage = 2
  35. elseif w >= 15 then
  36. damage = 1
  37. end
  38. end
  39. if damage > 0 then
  40. if player:get_hp() > 0 then
  41. player:set_hp(player:get_hp() - damage)
  42. if player:get_hp() <= 0 then
  43. minetest.chat_send_all("# Server: <" .. rename.gpn(player:get_player_name()) .. "> was wrecked by water pressure.")
  44. end
  45. end
  46. end
  47. -- Return water column count.
  48. return w
  49. end
  50. local scuba_timer = 0
  51. local scuba_step = 1
  52. ambiance.globalstep_scuba = function(dtime)
  53. scuba_timer = scuba_timer + dtime
  54. if scuba_timer < scuba_step then return end
  55. scuba_timer = 0
  56. local players = minetest.get_connected_players()
  57. for k, v in ipairs(players) do
  58. local pos = v:getpos()
  59. local name = v:get_player_name()
  60. local entry = ambiance.players[name]
  61. if entry ~= nil and not gdac.player_is_admin(name) then
  62. local under = ambiance.check_underwater(pos)
  63. if under == 2 then
  64. entry.underwater = true
  65. if entry.scuba == nil then
  66. entry.scuba = minetest.sound_play("scuba", {to_player=name, gain=1.0})
  67. minetest.after(8, done_scuba, name)
  68. end
  69. ambiance.particles_underwater(pos)
  70. ambiance.particles_underwater({x=pos.x, y=pos.y+1, z=pos.z})
  71. -- Water-shaft makers will H8TE this!
  72. ambiance.check_water_pressure(vector.round(pos), v)
  73. sprint.add_stamina(v, -3)
  74. else
  75. entry.underwater = nil
  76. if entry.scuba ~= nil then
  77. minetest.sound_stop(entry.scuba)
  78. ambiance.sound_play("drowning_gasp", pos, 1.0, 30)
  79. entry.scuba = nil
  80. end
  81. end
  82. if under == 1 then
  83. if entry.psplash == nil then entry.psplash = pos end
  84. if vector.distance(entry.psplash, pos) > 0.5 and entry.hsplash == nil then
  85. ambiance.sound_play("splashing", pos, 1.0, 30)
  86. entry.hsplash = true
  87. entry.psplash = pos
  88. minetest.after(3, done_splash, name)
  89. end
  90. ambiance.particles_underwater(pos)
  91. ambiance.particles_swimming({x=pos.x, y=pos.y+1, z=pos.z})
  92. sprint.add_stamina(v, -1)
  93. end
  94. end
  95. end
  96. end