Updated the sound system (#18724)

* sdaf

* sdaf

* sdfa

* sadf

* sfda

* gfd

* reduce thrusters volume

* sdafsadsdaf

* sdfa

* Reduced some sound ranges and made some/more not ignore walls for loops

* health analyzers too

* ivdrip adjustment

* most tools now use play_tool_sound to have the sound played, reduced range for it
This commit is contained in:
Fluffy
2024-03-25 20:40:36 +00:00
committed by GitHub
parent 9faac2d684
commit 1b40dbce82
174 changed files with 1251 additions and 817 deletions
+5 -5
View File
@@ -160,12 +160,12 @@ SUBSYSTEM_DEF(explosives)
// If inside the blast radius + world.view - 2
if (dist <= closedist)
to_chat(M, FONT_LARGE(SPAN_WARNING("You hear the sound of a nearby explosion coming from \the [explosion_dir].")))
M.playsound_simple(epicenter, get_sfx(/singleton/sound_category/explosion_sound), min(100, volume), use_random_freq = TRUE, falloff = 5)
M.playsound_local(epicenter, get_sfx(/singleton/sound_category/explosion_sound), min(100, volume), vary = TRUE, falloff_distance = 5)
else if (dist > closedist && dist <= extendeddist) // People with sensitive hearing get a better idea of how far it is
to_chat(M, FONT_LARGE(SPAN_WARNING("You hear the sound of a semi-close explosion coming from \the [explosion_dir].")))
M.playsound_simple(epicenter, get_sfx(/singleton/sound_category/explosion_sound), min(100, volume), use_random_freq = TRUE, falloff = 5)
M.playsound_local(epicenter, get_sfx(/singleton/sound_category/explosion_sound), min(100, volume), vary = TRUE, falloff_distance = 5)
else //You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
volume = M.playsound_simple(epicenter, 'sound/effects/explosionfar.ogg', volume, use_random_freq = TRUE, falloff = 1000, use_pressure = TRUE)
volume = M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', volume, vary = TRUE, falloff_distance = 1000, pressure_affected = TRUE)
if(volume)
to_chat(M, FONT_LARGE(SPAN_NOTICE("You hear the sound of a distant explosion coming from \the [explosion_dir].")))
@@ -357,10 +357,10 @@ SUBSYSTEM_DEF(explosives)
var/dist = get_dist(M, epicenter) || 1
if ((reception & EXPLFX_SOUND) && !isdeaf(M))
if (dist <= close_dist)
M.playsound_simple(epicenter, explosion_sound, min(100, volume), use_random_freq = TRUE, falloff = 5)
M.playsound_local(epicenter, explosion_sound, min(100, volume), vary = TRUE, falloff_distance = 5)
//You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else
volume = M.playsound_simple(epicenter, 'sound/effects/explosionfar.ogg', volume, use_random_freq = TRUE, falloff = 1000, use_pressure = FALSE)
volume = M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', volume, vary = TRUE, falloff_distance = 1000, pressure_affected = FALSE)
if ((reception & EXPLFX_SHAKE) && volume > 0)
shake_camera(M, min(30, max(2,(power*2) / dist)), min(3.5, ((power/3) / dist)),0.05)
@@ -0,0 +1,3 @@
TIMER_SUBSYSTEM_DEF(sound_loops)
name = "Sound Loops"
priority = FIRE_PRIORITY_SOUND_LOOPS
+159
View File
@@ -0,0 +1,159 @@
#define DATUMLESS "NO_DATUM"
SUBSYSTEM_DEF(sounds)
name = "Sounds"
flags = SS_NO_FIRE
init_order = INIT_ORDER_SOUNDS
var/static/using_channels_max = CHANNEL_HIGHEST_AVAILABLE //BYOND max channels
/// Amount of channels to reserve for random usage rather than reservations being allowed to reserve all channels. Also a nice safeguard for when someone screws up.
var/static/random_channels_min = 50
// Hey uh these two needs to be initialized fast because the whole "things get deleted before init" thing.
/// Assoc list, `"[channel]" =` either the datum using it or TRUE for an unsafe-reserved (datumless reservation) channel
var/list/using_channels
/// Assoc list datum = list(channel1, channel2, ...) for what channels something reserved.
var/list/using_channels_by_datum
// Special datastructure for fast channel management
/// List of all channels as numbers
var/list/channel_list
/// Associative list of all reserved channels associated to their position. `"[channel_number]" =` index as number
var/list/reserved_channels
/// lower iteration position - Incremented and looped to get "random" sound channels for normal sounds. The channel at this index is returned when asking for a random channel.
var/channel_random_low
/// higher reserve position - decremented and incremented to reserve sound channels, anything above this is reserved. The channel at this index is the highest unreserved channel.
var/channel_reserve_high
/// All valid sound files in the sound directory
var/list/all_sounds
/datum/controller/subsystem/sounds/Initialize()
setup_available_channels()
find_all_available_sounds()
return SS_INIT_SUCCESS
/datum/controller/subsystem/sounds/proc/setup_available_channels()
channel_list = list()
reserved_channels = list()
using_channels = list()
using_channels_by_datum = list()
for(var/i in 1 to using_channels_max)
channel_list += i
channel_random_low = 1
channel_reserve_high = length(channel_list)
/datum/controller/subsystem/sounds/proc/find_all_available_sounds()
all_sounds = list()
// Put more common extensions first to speed this up a bit
var/static/list/valid_file_extensions = list(
".ogg",
".wav",
".mid",
".midi",
".mod",
".it",
".s3m",
".xm",
".oxm",
".raw",
".wma",
".aiff",
)
all_sounds = pathwalk("sound/", valid_file_extensions)
/// Removes a channel from using list.
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)
var/text_channel = num2text(channel)
var/using = using_channels[text_channel]
using_channels -= text_channel
if(using != TRUE) // datum channel
using_channels_by_datum[using] -= channel
if(!length(using_channels_by_datum[using]))
using_channels_by_datum -= using
free_channel(channel)
/// Frees all the channels a datum is using.
/datum/controller/subsystem/sounds/proc/free_datum_channels(datum/D)
var/list/L = using_channels_by_datum[D]
if(!L)
return
for(var/channel in L)
using_channels -= num2text(channel)
free_channel(channel)
using_channels_by_datum -= D
/// Frees all datumless channels
/datum/controller/subsystem/sounds/proc/free_datumless_channels()
free_datum_channels(DATUMLESS)
/// NO AUTOMATIC CLEANUP - If you use this, you better manually free it later! Returns an integer for channel.
/datum/controller/subsystem/sounds/proc/reserve_sound_channel_datumless()
. = reserve_channel()
if(!.) //oh no..
return FALSE
var/text_channel = num2text(.)
using_channels[text_channel] = DATUMLESS
LAZYINITLIST(using_channels_by_datum[DATUMLESS])
using_channels_by_datum[DATUMLESS] += .
/// Reserves a channel for a datum. Automatic cleanup only when the datum is deleted. Returns an integer for channel.
/datum/controller/subsystem/sounds/proc/reserve_sound_channel(datum/D)
if(!D) //i don't like typechecks but someone will fuck it up
CRASH("Attempted to reserve sound channel without datum using the managed proc.")
.= reserve_channel()
if(!.)
CRASH("No more sound channels can be reserved")
var/text_channel = num2text(.)
using_channels[text_channel] = D
LAZYINITLIST(using_channels_by_datum[D])
using_channels_by_datum[D] += .
/**
* Reserves a channel and updates the datastructure. Private proc.
*/
/datum/controller/subsystem/sounds/proc/reserve_channel()
PRIVATE_PROC(TRUE)
if(channel_reserve_high <= random_channels_min) // out of channels
return
var/channel = channel_list[channel_reserve_high]
reserved_channels[num2text(channel)] = channel_reserve_high--
return channel
/**
* Frees a channel and updates the datastructure. Private proc.
*/
/datum/controller/subsystem/sounds/proc/free_channel(number)
PRIVATE_PROC(TRUE)
var/text_channel = num2text(number)
var/index = reserved_channels[text_channel]
if(!index)
CRASH("Attempted to (internally) free a channel that wasn't reserved.")
reserved_channels -= text_channel
// push reserve index up, which makes it now on a channel that is reserved
channel_reserve_high++
// swap the reserved channel wtih the unreserved channel so the reserve index is now on an unoccupied channel and the freed channel is next to be used.
channel_list.Swap(channel_reserve_high, index)
// now, an existing reserved channel will likely (exception: unreserving last reserved channel) be at index
// get it, and update position.
var/text_reserved = num2text(channel_list[index])
if(!reserved_channels[text_reserved]) //if it isn't already reserved make sure we don't accidently mistakenly put it on reserved list!
return
reserved_channels[text_reserved] = index
/// Random available channel, returns text.
/datum/controller/subsystem/sounds/proc/random_available_channel_text()
if(channel_random_low > channel_reserve_high)
channel_random_low = 1
. = "[channel_list[channel_random_low++]]"
/// Random available channel, returns number
/datum/controller/subsystem/sounds/proc/random_available_channel()
if(channel_random_low > channel_reserve_high)
channel_random_low = 1
. = channel_list[channel_random_low++]
/// How many channels we have left.
/datum/controller/subsystem/sounds/proc/available_channels_left()
return length(channel_list) - random_channels_min
#undef DATUMLESS