beacon.lua 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. -- Localize for performance.
  2. local vector_round = vector.round
  3. -- Spawn a named sound beacon at `pos`, while ensuring that no more than `count`
  4. -- beacons of the same type are spawned within `radius` meters.
  5. function ambiance.spawn_sound_beacon(name, pos, radius, count)
  6. pos = vector_round(pos)
  7. local objs = minetest.get_objects_inside_radius(pos, radius)
  8. local c = 0
  9. for i = 1, #objs, 1 do
  10. local ent = objs[i]:get_luaentity()
  11. if ent then
  12. if ent.name == name then
  13. c = c + 1
  14. if c > count then
  15. -- Too many sound beacons of this type in the region.
  16. return
  17. end
  18. end
  19. end
  20. end
  21. --minetest.chat_send_all("added " .. name .. "!")
  22. minetest.add_entity(pos, name)
  23. end
  24. -- Trigger all sound beacons in a given radius to execute an environment recheck.
  25. function ambiance.recheck_nearby_sound_beacons(pos, radius)
  26. --minetest.chat_send_all('recheck2')
  27. pos = vector_round(pos)
  28. local objs = minetest.get_objects_inside_radius(pos, radius)
  29. for i = 1, #objs, 1 do
  30. local ent = objs[i]:get_luaentity()
  31. if ent then
  32. if ent.name:find("^soundbeacon:") then
  33. --minetest.chat_send_all('recheck')
  34. ent._ctime = 0
  35. end
  36. end
  37. end
  38. end
  39. function ambiance.replay_nearby_sound_beacons(pos, radius)
  40. --minetest.chat_send_all('replay2')
  41. pos = vector_round(pos)
  42. local objs = minetest.get_objects_inside_radius(pos, radius)
  43. for i = 1, #objs, 1 do
  44. local ent = objs[i]:get_luaentity()
  45. if ent then
  46. if ent.name:find("^soundbeacon:") then
  47. --minetest.chat_send_all('replay')
  48. ent._ptime = 0
  49. end
  50. end
  51. end
  52. end
  53. function ambiance.spawn_sound_beacon_inside_area(name, pos, minp, maxp, radius, count)
  54. local p1 = vector.add(pos, minp)
  55. local p2 = vector.add(pos, maxp)
  56. local p3 = {x=0, y=0, z=0}
  57. p3.x = p1.x + p2.x / 2
  58. p3.y = p1.y + p2.y / 2
  59. p3.z = p1.z + p2.z / 2
  60. ambiance.spawn_sound_beacon(name, pos, radius, count)
  61. end
  62. function ambiance.register_sound_beacon(name, callbacks)
  63. local cmin = callbacks.check_time_min
  64. local cmax = callbacks.check_time_max
  65. local pmin = callbacks.play_time_min
  66. local pmax = callbacks.play_time_max
  67. local check = callbacks.on_check_environment
  68. local play = callbacks.on_play_sound
  69. local rand = math.random
  70. local beacondef = {
  71. visual = "wielditem",
  72. visual_size = {x=0, y=0},
  73. collisionbox = {0, 0, 0, 0, 0, 0},
  74. physical = false,
  75. textures = {"air"},
  76. is_visible = false,
  77. on_activate = function(self, staticdata, dtime_s)
  78. end,
  79. on_punch = function(self, puncher, time_from_last_punch, tool_caps, dir)
  80. end,
  81. on_death = function(self, killer)
  82. end,
  83. on_rightclick = function(self, clicker)
  84. end,
  85. get_staticdata = function(self)
  86. return ""
  87. end,
  88. on_step = function(self, dtime)
  89. local pos = vector_round(self.object:get_pos())
  90. self._data = self._data or {}
  91. local d = self._data
  92. self._ctime = (self._ctime or rand(cmin, cmax)) - dtime
  93. self._ptime = (self._ptime or rand(pmin, pmax)) - dtime
  94. self._xtime = (self._xtime or 0) + dtime
  95. if self._ctime < 0 then
  96. self._ctime = rand(cmin, cmax)
  97. if not check(d, pos) then
  98. self.object:remove()
  99. return
  100. end
  101. end
  102. if self._ptime < 0 then
  103. self._ptime = rand(pmin, pmax)
  104. play(d, pos, self._xtime)
  105. self._xtime = 0
  106. end
  107. end,
  108. }
  109. minetest.register_entity(name, beacondef)
  110. end