Skip to content

Commit

Permalink
w
Browse files Browse the repository at this point in the history
  • Loading branch information
wonderinghost committed Nov 18, 2024
1 parent e94cba9 commit 3dc3e1e
Showing 1 changed file with 33 additions and 41 deletions.
74 changes: 33 additions & 41 deletions code/game/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,22 @@ falloff_distance - Distance at which falloff begins. Sound is at peak volume (in
CRASH("playsound(): source is an area")

if(islist(soundin))
CRASH("playsound(): soundin attempted to pass a list! Consider using pick() source: [source.name]")
CRASH("playsound(): soundin attempted to pass a list! Consider using pick()")

var/turf/turf_source = get_turf(source)

if (!turf_source)
if (!turf_source || !soundin || !vol)
return

//allocate a channel if necessary now so its the same for everyone
channel = channel || SSsounds.random_available_channel()

// Looping through the player list has the added bonus of working for mobs inside containers
var/sound/S = sound(get_sfx(soundin))
var/sound/S = isdatum(soundin) ? soundin : sound(get_sfx(soundin))
var/maxdistance = SOUND_RANGE + extrarange
var/source_z = turf_source.z
var/list/listeners = SSmobs.clients_by_zlevel[source_z].Copy()

. = list() //output everything that successfully heard the sound
. = list()//output everything that successfully heard the sound

var/turf/above_turf = GET_TURF_ABOVE(turf_source)
var/turf/below_turf = GET_TURF_BELOW(turf_source)
Expand All @@ -91,12 +90,10 @@ falloff_distance - Distance at which falloff begins. Sound is at peak volume (in
if(below_turf && istransparentturf(turf_source))
listeners += get_hearers_in_view(maxdistance, below_turf)

for(var/mob/listening_mob as anything in listeners)
if(get_dist(listening_mob, turf_source) <= maxdistance)
listening_mob.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)
for(var/mob/listening_mob as anything in SSmobs.dead_players_by_zlevel[source_z])
for(var/mob/listening_mob in listeners | SSmobs.dead_players_by_zlevel[source_z])//observers always hear through walls
if(get_dist(listening_mob, turf_source) <= maxdistance)
listening_mob.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, S, maxdistance, falloff_distance, 1, use_reverb)
. += listening_mob

/*! playsound
playsound_local is a proc used to play a sound directly on a mob from a specific turf.
Expand All @@ -114,42 +111,37 @@ falloff_distance - Distance at which falloff begins, if this is a 3D sound
distance_multiplier - Can be used to multiply the distance at which the sound is heard
*/

/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/sound_to_use, max_distance, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = 1, use_reverb = TRUE)
if(!client || !can_hear())
return

if(!S)
S = sound(get_sfx(soundin))
if(!sound_to_use)
sound_to_use = sound(get_sfx(soundin))

S.wait = 0 //No queue
S.channel = channel || SSsounds.random_available_channel()
S.volume = vol

if (client?.prefs && !(client.prefs.toggles & SOUND_ALT) && (S.file in GLOB.alt_sound_overrides))
S.file = GLOB.alt_sound_overrides[S.file]
sound_to_use.wait = 0 //No queue
sound_to_use.channel = channel || SSsounds.random_available_channel()
sound_to_use.volume = vol

if(vary)
if(frequency)
S.frequency = frequency
sound_to_use.frequency = frequency
else
S.frequency = get_rand_frequency()
sound_to_use.frequency = get_rand_frequency()

if(isturf(turf_source))
var/turf/T = get_turf(src)
var/turf/turf_loc = get_turf(src)

//sound volume falloff with distance
var/distance = get_dist(T, turf_source)

distance *= distance_multiplier
var/distance = get_dist(turf_loc, turf_source) * distance_multiplier

if(max_distance) //If theres no max_distance we're not a 3D sound, so no falloff.
S.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * S.volume
sound_to_use.volume -= (max(distance - falloff_distance, 0) ** (1 / falloff_exponent)) / ((max(max_distance, distance) - falloff_distance) ** (1 / falloff_exponent)) * sound_to_use.volume
//https://www.desmos.com/calculator/sqdfl8ipgf

if(pressure_affected)
//Atmosphere affects sound
var/pressure_factor = 1
var/datum/gas_mixture/hearer_env = T.return_air()
var/datum/gas_mixture/hearer_env = turf_loc.return_air()
var/datum/gas_mixture/source_env = turf_source.return_air()

if(hearer_env && source_env)
Expand All @@ -162,35 +154,35 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
if(distance <= 1)
pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound

S.volume *= pressure_factor
sound_to_use.volume *= pressure_factor
//End Atmosphere affecting sound

if(S.volume <= 0)
if(sound_to_use.volume <= 0)
return //No sound

var/dx = turf_source.x - T.x // Hearing from the right/left
S.x = dx * distance_multiplier
var/dz = turf_source.y - T.y // Hearing from infront/behind
S.z = dz * distance_multiplier
var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
S.y = dy
var/dx = turf_source.x - turf_loc.x // Hearing from the right/left
sound_to_use.x = dx * distance_multiplier
var/dz = turf_source.y - turf_loc.y // Hearing from infront/behind
sound_to_use.z = dz * distance_multiplier
var/dy = (turf_source.z - turf_loc.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
sound_to_use.y = dy

S.falloff = max_distance || 1 //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.
sound_to_use.falloff = max_distance || 1 //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.

// Sounds can't have their own environment. A sound's environment will be:
// 1. the mob's
// 2. the area's (defaults to SOUND_ENVRIONMENT_NONE)
if(sound_environment_override != SOUND_ENVIRONMENT_NONE)
S.environment = sound_environment_override
sound_to_use.environment = sound_environment_override
else
var/area/A = get_area(src)
S.environment = A.sound_environment
sound_to_use.environment = A.sound_environment

if(use_reverb && S.environment != SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting
S.echo[3] = 0 //Room setting, 0 means normal reverb
S.echo[4] = 0 //RoomHF setting, 0 means normal reverb.
if(use_reverb && sound_to_use.environment != SOUND_ENVIRONMENT_NONE) //We have reverb, reset our echo setting
sound_to_use.echo[3] = 0 //Room setting, 0 means normal reverb
sound_to_use.echo[4] = 0 //RoomHF setting, 0 means normal reverb.

SEND_SOUND(src, S)
SEND_SOUND(src, sound_to_use)

/proc/sound_to_playing_players(soundin, volume = 100, vary = FALSE, frequency = 0, channel = 0, pressure_affected = FALSE, sound/S)
if(!S)
Expand Down

0 comments on commit 3dc3e1e

Please sign in to comment.