You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

154 lines
6.4 KiB

  1. #define SOUND_EMITTER_LOCAL "local" //Plays the sound like a normal heard sound
  2. #define SOUND_EMITTER_DIRECT "direct" //Plays the sound directly to hearers regardless of pressure/proximity/et cetera
  3. #define SOUND_EMITTER_RADIUS "radius" //Plays the sound to everyone in a radius
  4. #define SOUND_EMITTER_ZLEVEL "zlevel" //Plays the sound to everyone on the z-level
  5. #define SOUND_EMITTER_GLOBAL "global" //Plays the sound to everyone in the game world
  6. //Admin sound emitters with highly customizable functions!
  7. /obj/effect/sound_emitter
  8. name = "sound emitter"
  9. desc = "Emits sounds, presumably."
  10. icon = 'icons/effects/effects.dmi'
  11. icon_state = "shield2"
  12. invisibility = INVISIBILITY_OBSERVER
  13. anchored = TRUE
  14. density = FALSE
  15. opacity = FALSE
  16. alpha = 175
  17. var/sound_file //The sound file the emitter plays
  18. var/sound_volume = 50 //The volume the sound file is played at
  19. var/play_radius = 3 //Any mobs within this many tiles will hear the sounds played if it's using the appropriate mode
  20. var/motus_operandi = SOUND_EMITTER_LOCAL //The mode this sound emitter is using
  21. var/emitter_range = SOUND_EMITTER_ZLEVEL //The range this emitter's sound is heard at; this isn't a number, but a string (see the defines above)
  22. /obj/effect/sound_emitter/Destroy(force)
  23. if(!force)
  24. return QDEL_HINT_LETMELIVE
  25. . = ..()
  26. /obj/effect/sound_emitter/singularity_act()
  27. return
  28. /obj/effect/sound_emitter/singularity_pull()
  29. return
  30. /obj/effect/sound_emitter/examine(mob/user)
  31. . = ..()
  32. if(!isobserver(user))
  33. return
  34. . += "<span class='boldnotice'>Sound File:</span> [sound_file ? sound_file : "None chosen"]"
  35. . += "<span class='boldnotice'>Mode:</span> [motus_operandi]</span>"
  36. . += "<span class='boldnotice'>Range:</span> [emitter_range]</span>"
  37. . += "<b>Sound is playing at [sound_volume]% volume.</b>"
  38. if(user.client.holder)
  39. . += "<b>Alt-click it to quickly activate it!</b>"
  40. //ATTACK GHOST IGNORING PARENT RETURN VALUE
  41. /obj/effect/sound_emitter/attack_ghost(mob/user)
  42. if(!check_rights_for(user.client, R_SOUND))
  43. examine(user)
  44. return
  45. edit_emitter(user)
  46. /obj/effect/sound_emitter/AltClick(mob/user)
  47. if(check_rights_for(user.client, R_SOUND))
  48. activate(user)
  49. to_chat(user, "<span class='notice'>Sound emitter activated.</span>", confidential = TRUE)
  50. /obj/effect/sound_emitter/proc/edit_emitter(mob/user)
  51. var/dat = ""
  52. dat += "<b>Label:</b> <a href='?src=\ref[src];edit_label=1'>[maptext ? maptext : "No label set!"]</a><br>"
  53. dat += "<br>"
  54. dat += "<b>Sound File:</b> <a href='?src=\ref[src];edit_sound_file=1'>[sound_file ? sound_file : "No file chosen!"]</a><br>"
  55. dat += "<b>Volume:</b> <a href='?src=\ref[src];edit_volume=1'>[sound_volume]%</a><br>"
  56. dat += "<br>"
  57. dat += "<b>Mode:</b> <a href='?src=\ref[src];edit_mode=1'>[motus_operandi]</a><br>"
  58. if(motus_operandi != SOUND_EMITTER_LOCAL)
  59. dat += "<b>Range:</b> <a href='?src=\ref[src];edit_range=1'>[emitter_range]</a>[emitter_range == SOUND_EMITTER_RADIUS ? "<a href='?src=\ref[src];edit_radius=1'>[play_radius]-tile radius</a>" : ""]<br>"
  60. dat += "<br>"
  61. dat += "<a href='?src=\ref[src];play=1'>Play Sound</a> (interrupts other sound emitter sounds)"
  62. var/datum/browser/popup = new(user, "emitter", "", 500, 600)
  63. popup.set_content(dat)
  64. popup.open()
  65. /obj/effect/sound_emitter/Topic(href, href_list)
  66. ..()
  67. if(!ismob(usr) || !usr.client || !check_rights_for(usr.client, R_SOUND))
  68. return
  69. var/mob/user = usr
  70. if(href_list["edit_label"])
  71. var/new_label = stripped_input(user, "Choose a new label.", "Sound Emitter")
  72. if(!new_label)
  73. return
  74. maptext = new_label
  75. to_chat(user, "<span class='notice'>Label set to [maptext].</span>", confidential = TRUE)
  76. if(href_list["edit_sound_file"])
  77. var/new_file = input(user, "Choose a sound file.", "Sound Emitter") as null|sound
  78. if(!new_file)
  79. return
  80. sound_file = new_file
  81. to_chat(user, "<span class='notice'>New sound file set to [sound_file].</span>", confidential = TRUE)
  82. if(href_list["edit_volume"])
  83. var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num
  84. if(isnull(new_volume))
  85. return
  86. new_volume = clamp(new_volume, 0, 100)
  87. sound_volume = new_volume
  88. to_chat(user, "<span class='notice'>Volume set to [sound_volume]%.</span>", confidential = TRUE)
  89. if(href_list["edit_mode"])
  90. var/new_mode
  91. var/mode_list = list("Local (normal sound)" = SOUND_EMITTER_LOCAL, "Direct (not affected by environment/location)" = SOUND_EMITTER_DIRECT)
  92. new_mode = input(user, "Choose a new mode.", "Sound Emitter") as null|anything in mode_list
  93. if(!new_mode)
  94. return
  95. motus_operandi = mode_list[new_mode]
  96. to_chat(user, "<span class='notice'>Mode set to [motus_operandi].</span>", confidential = TRUE)
  97. if(href_list["edit_range"])
  98. var/new_range
  99. var/range_list = list("Radius (all mobs within a radius)" = SOUND_EMITTER_RADIUS, "Z-Level (all mobs on the same z)" = SOUND_EMITTER_ZLEVEL, "Global (all players)" = SOUND_EMITTER_GLOBAL)
  100. new_range = input(user, "Choose a new range.", "Sound Emitter") as null|anything in range_list
  101. if(!new_range)
  102. return
  103. emitter_range = range_list[new_range]
  104. to_chat(user, "<span class='notice'>Range set to [emitter_range].</span>", confidential = TRUE)
  105. if(href_list["edit_radius"])
  106. var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num
  107. if(isnull(new_radius))
  108. return
  109. new_radius = clamp(new_radius, 0, 127)
  110. play_radius = new_radius
  111. to_chat(user, "<span class='notice'>Audible radius set to [play_radius].</span>", confidential = TRUE)
  112. if(href_list["play"])
  113. activate(user)
  114. edit_emitter(user) //Refresh the UI to see our changes
  115. /obj/effect/sound_emitter/proc/activate(mob/user)
  116. var/list/hearing_mobs = list()
  117. if(motus_operandi == SOUND_EMITTER_LOCAL)
  118. playsound(src, sound_file, sound_volume, FALSE)
  119. return
  120. switch(emitter_range)
  121. if(SOUND_EMITTER_RADIUS)
  122. for(var/mob/M in GLOB.player_list)
  123. if(get_dist(src, M) <= play_radius)
  124. hearing_mobs += M
  125. if(SOUND_EMITTER_ZLEVEL)
  126. for(var/mob/M in GLOB.player_list)
  127. if(M.z == z)
  128. hearing_mobs += M
  129. if(SOUND_EMITTER_GLOBAL)
  130. hearing_mobs = GLOB.player_list.Copy()
  131. for(var/mob/M in hearing_mobs)
  132. if(M.client.prefs.toggles & SOUND_MIDI)
  133. M.playsound_local(M, sound_file, sound_volume, FALSE, channel = CHANNEL_ADMIN, pressure_affected = FALSE)
  134. if(user)
  135. log_admin("[ADMIN_LOOKUPFLW(user)] activated a sound emitter with file \"[sound_file]\" at [AREACOORD(src)]")
  136. flick("shield1", src)
  137. #undef SOUND_EMITTER_LOCAL
  138. #undef SOUND_EMITTER_DIRECT
  139. #undef SOUND_EMITTER_RADIUS
  140. #undef SOUND_EMITTER_ZLEVEL
  141. #undef SOUND_EMITTER_GLOBAL