beacon.lua 3.1 KB

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