Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Sound #6600

Closed
wants to merge 18 commits into from
3 changes: 3 additions & 0 deletions code/__DEFINES/dcs/signals/signals_client.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@

/// Called when something is removed from a client's screen : /client/proc/remove_from_screen(screen_remove)
#define COMSIG_CLIENT_SCREEN_REMOVE "client_screen_remove"

/// From movement.dm: /atom/movable/proc/Moved(atom/oldloc, direction, Forced = FALSE)
#define COMSIG_CLIENT_MOB_MOVED "client_mob_moved"
2 changes: 1 addition & 1 deletion code/datums/diseases/black_goo.dm
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
human.remove_language(LANGUAGE_ENGLISH) // You lose the ability to understand english. Language processing is handled in the mind not the body.
var/datum/species/zombie/zombie_species = GLOB.all_species[SPECIES_ZOMBIE]
zombie_species.handle_alert_ghost(human)
playsound(human.loc, 'sound/hallucinations/wail.ogg', 25, 1)
playsound(human, 'sound/hallucinations/wail.ogg', 25, 1)
human.jitteriness = 0
human.set_species(SPECIES_ZOMBIE)
stage = 4
Expand Down
109 changes: 86 additions & 23 deletions code/datums/soundOutput.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
var/list/soundscape_playlist = list() //Updated on changing areas
var/ambience = null //The file currently being played as ambience
var/status_flags = 0 //For things like ear deafness, psychodelic effects, and other things that change how all sounds behave
var/list/current_sounds = list()
var/list/source_sounds = list()

/// Currently applied environmental reverb.
VAR_PROTECTED/owner_environment = SOUND_ENVIRONMENT_NONE
Expand All @@ -13,18 +15,56 @@
qdel(src)
return
owner = client
RegisterSignal(owner.mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_moved))
RegisterSignal(owner.mob, COMSIG_MOB_LOGOUT, PROC_REF(on_mob_logout))
RegisterSignal(owner, COMSIG_CLIENT_MOB_MOVED, PROC_REF(on_mob_moved))
RegisterSignal(owner, COMSIG_CLIENT_MOB_LOGGED_IN, PROC_REF(on_client_mob_logged_in))
return ..()

/datum/soundOutput/Destroy()
UnregisterSignal(owner.mob, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT))
UnregisterSignal(owner, COMSIG_CLIENT_MOB_MOVED)
UnregisterSignal(owner, COMSIG_CLIENT_MOB_LOGGED_IN)
owner = null
return ..()

/datum/soundOutput/proc/process_sound(datum/sound_template/T)
#define SMOOTHING 1 // [1, 32], 32 Means best sound most lag 1 Means worst sound least lag

/datum/soundOutput/proc/update_sounds(atom/user, direction)
SIGNAL_HANDLER
for(var/channel in current_sounds)
for(var/i in 0 to round(32/SMOOTHING))
i = i * SMOOTHING
switch(direction)
if(1)
process_sound(current_sounds[channel], TRUE, 0, -1+i/32)
if(2)
process_sound(current_sounds[channel], TRUE, 0, 1-i/32)
if(4)
process_sound(current_sounds[channel], TRUE, -1+i/32, 0)
if(8)
process_sound(current_sounds[channel], TRUE, 1-i/32, 0)

/datum/soundOutput/proc/update_sounds_from_source(datum/source, atom/oldloc, direction, Forced)
SIGNAL_HANDLER
for(var/channel in source_sounds)
if(source_sounds[channel] == source)
var/datum/sound_template/template = current_sounds[channel]
for(var/i in 0 to round(32/SMOOTHING))
i = i * SMOOTHING
switch(direction)
if(1)
process_sound(template, TRUE, 0, 1-i/32)
if(2)
process_sound(template, TRUE, 0, -1+i/32)
if(4)
process_sound(template, TRUE, 1-i/32, 0)
if(8)
process_sound(template, TRUE, -1+i/32, 0)
break

/datum/soundOutput/proc/remove_sound(channel)
current_sounds -= channel
source_sounds -= channel

/datum/soundOutput/proc/process_sound(datum/sound_template/T, update=FALSE, offset_x = 0, offset_y = 0)
var/sound/S = sound(T.file, T.wait, T.repeat)
S.volume = owner.volume_preferences[T.volume_cat] * T.volume
if(T.channel == 0)
Expand All @@ -33,8 +73,27 @@
S.channel = T.channel
S.frequency = T.frequency
S.falloff = T.falloff
S.status = T.status
if(T.x && T.y && T.z)
S.params = list("on-end" = ".soundend [S.channel]")

if(!update)
S.status = T.status
else
S.status = SOUND_UPDATE

var/positional_sound = TRUE
var/turf/source_turf
if(T.source && !QDELETED(T.source))
source_turf = get_turf(T.source)

if(!update && istype(T.source, /atom/movable) && T.source != owner.mob && T.use_smoothing)
source_sounds[num2text(T.channel)] = T.source
RegisterSignal(T.source, COMSIG_MOVABLE_MOVED, PROC_REF(update_sounds_from_source))
else if (T.x && T.y && T.z)
source_turf = locate(T.x, T.y, T.z)
else
positional_sound = FALSE

if(positional_sound)
var/turf/owner_turf = get_turf(owner.mob)
if(owner_turf)
// We're in an interior and sound came from outside
Expand All @@ -46,16 +105,29 @@
return // Invalid location
S.falloff /= 2
owner_turf = candidate
S.x = T.x - owner_turf.x
S.x = source_turf.x - owner_turf.x + offset_x
S.y = 0
S.z = T.y - owner_turf.y
S.z = source_turf.y - owner_turf.y + offset_y
S.y += T.y_s_offset
S.x += T.x_s_offset
S.echo = SOUND_ECHO_REVERB_ON //enable environment reverb for positional sounds
S.echo = SOUND_ECHO_REVERB_ON

if(!update && T.source && T.source != owner.mob && T.use_smoothing)
current_sounds[num2text(S.channel)] = T

if(owner.mob.ear_deaf > 0)
S.status |= SOUND_MUTE
S.status |= SOUND_MUTE

sound_to(owner,S)
sound_to(owner, S)

/client/verb/sound_ended(channel as num)
set name = ".soundend"

soundOutput.remove_sound(num2text(channel))

/datum/soundOutput/proc/on_client_mob_logged_in(datum/source, mob/new_mob)
SIGNAL_HANDLER //COMSIG_CLIENT_MOB_LOGGED_IN
update_mob_environment_override()

/datum/soundOutput/proc/update_ambience(area/target_area, ambience_override, force_update = FALSE)
var/status_flags = SOUND_STREAM
Expand Down Expand Up @@ -165,19 +237,10 @@

src.owner_environment = new_environment

/datum/soundOutput/proc/on_mob_moved(datum/source, atom/oldloc, direction, Forced)
SIGNAL_HANDLER //COMSIG_MOVABLE_MOVED
/datum/soundOutput/proc/on_mob_moved(atom/source, direction)
SIGNAL_HANDLER //COMSIG_CLIENT_MOB_MOVED
update_area_environment()

/datum/soundOutput/proc/on_mob_logout(datum/source)
SIGNAL_HANDLER //COMSIG_MOB_LOGOUT
UnregisterSignal(owner.mob, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_LOGOUT))

/datum/soundOutput/proc/on_client_mob_logged_in(datum/source, mob/new_mob)
SIGNAL_HANDLER //COMSIG_CLIENT_MOB_LOGGED_IN
RegisterSignal(owner.mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_moved))
RegisterSignal(owner.mob, COMSIG_MOB_LOGOUT, PROC_REF(on_mob_logout))
update_mob_environment_override()
Git-Nivrak marked this conversation as resolved.
Show resolved Hide resolved
update_sounds(source, direction)

/client/proc/adjust_volume_prefs(volume_key, prompt = "", channel_update = 0)
volume_preferences[volume_key] = (tgui_input_number(src, prompt, "Volume", volume_preferences[volume_key]*100)) / 100
Expand Down
18 changes: 9 additions & 9 deletions code/game/machinery/bots/mulebot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@
/obj/structure/machinery/bot/mulebot/proc/load(atom/movable/C)
if((wires & WIRE_LOADCHECK) && !istype(C,/obj/structure/closet/crate))
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 0)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25, 0)
return // if not emagged, only allow crates to be loaded

//I'm sure someone will come along and ask why this is here... well people were dragging screen items onto the mule, and that was not cool.
Expand Down Expand Up @@ -636,25 +636,25 @@
mode = 4
if(blockcount == 3)
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 25, 0)
playsound(src, 'sound/machines/buzz-two.ogg', 25, 0)

if(blockcount > 5) // attempt 5 times before recomputing
// find new path excluding blocked turf
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 0)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25, 0)

spawn(2)
calc_path(next)
if(length(path) > 0)
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
playsound(src.loc, 'sound/machines/ping.ogg', 25, 0)
playsound(src, 'sound/machines/ping.ogg', 25, 0)
mode = 4
mode =6
return
return
else
src.visible_message("[src] makes an annoyed buzzing sound", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 25, 0)
playsound(src, 'sound/machines/buzz-two.ogg', 25, 0)
mode = 5
return
else
Expand All @@ -671,11 +671,11 @@
blockcount = 0
mode = 4
src.visible_message("[src] makes a delighted ping!", "You hear a ping.")
playsound(src.loc, 'sound/machines/ping.ogg', 25, 0)
playsound(src, 'sound/machines/ping.ogg', 25, 0)

else
src.visible_message("[src] makes a sighing buzz.", "You hear an electronic buzzing sound.")
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 0)
playsound(src, 'sound/machines/buzz-sigh.ogg', 25, 0)

mode = 7
//if(6)
Expand Down Expand Up @@ -720,7 +720,7 @@
/obj/structure/machinery/bot/mulebot/proc/at_target()
if(!reached_target)
src.visible_message("[src] makes a chiming sound!", "You hear a chime.")
playsound(src.loc, 'sound/machines/chime.ogg', 25, 0)
playsound(src, 'sound/machines/chime.ogg', 25, 0)
reached_target = 1

if(load) // if loaded, unload at target
Expand Down Expand Up @@ -770,7 +770,7 @@
// when mulebot is in the same loc
/obj/structure/machinery/bot/mulebot/proc/RunOver(mob/living/carbon/human/H)
src.visible_message(SPAN_DANGER("[src] drives over [H]!"))
playsound(src.loc, 'sound/effects/splat.ogg', 25, 1)
playsound(src, 'sound/effects/splat.ogg', 25, 1)

var/damage = rand(5,15)
H.apply_damage(2*damage, BRUTE, "head")
Expand Down
6 changes: 5 additions & 1 deletion code/game/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
var/z
var/y_s_offset // Vertical sound offset
var/x_s_offset // Horizontal sound offset
var/atom/source
var/use_smoothing = TRUE

/proc/get_free_channel()
var/static/cur_chan = 1
Expand All @@ -36,7 +38,7 @@
//status: the regular 4 sound flags
//falloff: max range till sound volume starts dropping as distance increases

/proc/playsound(atom/source, soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status , falloff = 1, y_s_offset,x_s_offset)
/proc/playsound(atom/source, soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status , falloff = 1, y_s_offset,x_s_offset, smoothing=TRUE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/proc/playsound(atom/source, soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status , falloff = 1, y_s_offset,x_s_offset, smoothing=TRUE)
/proc/playsound(atom/source, soundin, vol = 100, vary = FALSE, sound_range, vol_cat = VOLUME_SFX, channel = 0, status , falloff = 1, y_s_offset,x_s_offset, use_smoothing=TRUE)

You named the argument smoothing but are trying to call it with use_smoothing

if(isarea(source))
error("[source] is an area and is trying to make the sound: [soundin]")
return FALSE
Expand All @@ -56,6 +58,7 @@
S.volume_cat = vol_cat
S.y_s_offset = y_s_offset
S.x_s_offset = x_s_offset
S.use_smoothing = smoothing
if(vary != FALSE)
if(vary > 1)
S.frequency = vary
Expand All @@ -72,6 +75,7 @@
S.x = turf_source.x
S.y = turf_source.y
S.z = turf_source.z
S.source = source

if(!SSinterior)
SSsound.queue(S)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/human/human_abilities.dm
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ CULT

H.put_in_any_hand_if_possible(new /obj/item/device/flashlight, FALSE, TRUE)

playsound(H.loc, 'sound/voice/scream_horror1.ogg', 25)
playsound(H, 'sound/voice/scream_horror1.ogg', 25)

H.visible_message(SPAN_HIGHDANGER("[H] puts on their robes."), SPAN_WARNING("You put on your robes."))
for(var/datum/action/human_action/activable/cult/obtain_equipment/O in H.actions)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/human/say.dm
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
if(M != src)
M.show_message(SPAN_NOTICE("[src] talks into [length(used_radios) ? used_radios[1] : "the radio."]"), SHOW_MESSAGE_VISIBLE)
if(ishumansynth_strict(src))
playsound(src.loc, 'sound/effects/radiostatic.ogg', 15, 1)
playsound(src, 'sound/effects/radiostatic.ogg', 15, 1)

italics = 1
message_range = 2
Expand Down
4 changes: 2 additions & 2 deletions code/modules/mob/living/carbon/human/species/zombie.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@

/datum/species/zombie/handle_unique_behavior(mob/living/carbon/human/zombie)
if(prob(5))
playsound(zombie.loc, basic_moan, 15, basic_variance)
playsound(zombie, basic_moan, 15, basic_variance)
else if(prob(5))
playsound(zombie.loc, rare_moan, 15, rare_variance)
playsound(zombie, rare_moan, 15, rare_variance)

/datum/species/zombie/handle_death(mob/living/carbon/human/zombie, gibbed)
set waitfor = FALSE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/xenomorph/Abilities.dm
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
if(hugger.stat != DEAD)
hugger.die()

playsound(xeno.loc, pick(xeno.screech_sound_effect_list), 75, 0, status = 0)
playsound(xeno, pick(xeno.screech_sound_effect_list), 75, 0, status = 0)
xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] emits an ear-splitting guttural roar!"))
xeno.create_shriekwave(14) //Adds the visual effect. Wom wom wom, 14 shriekwaves

Expand Down
6 changes: 3 additions & 3 deletions code/modules/mob/living/carbon/xenomorph/Facehuggers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@
human.disable_lights()
human.disable_special_items()
if(ishuman_strict(human))
playsound(loc, human.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0)
playsound(human, human.gender == "male" ? 'sound/misc/facehugged_male.ogg' : 'sound/misc/facehugged_female.ogg' , 25, 0)
else if(isyautja(human))
playsound(loc, 'sound/voice/pred_facehugged.ogg', 65, FALSE)
playsound(human, 'sound/voice/pred_facehugged.ogg', 65, FALSE)
if(!sterile)
if(!human.species || !(human.species.flags & IS_SYNTHETIC)) //synthetics aren't paralyzed
human.apply_effect(MIN_IMPREGNATION_TIME * 0.5 * knockout_mod, PARALYZE) //THIS MIGHT NEED TWEAKS
Expand Down Expand Up @@ -435,7 +435,7 @@
stat = DEAD
flags_inventory &= ~CANTSTRIP
visible_message("[icon2html(src, viewers(src))] <span class='danger'>\The [src] curls up into a ball!</span>")
playsound(src.loc, 'sound/voice/alien_facehugger_dies.ogg', 25, 1)
playsound(src, 'sound/voice/alien_facehugger_dies.ogg', 25, 1)

if(ismob(loc)) //Make it fall off the person so we can update their icons. Won't update if they're in containers thou
var/mob/holder_mob = loc
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@

if (pounceAction.freeze_self)
if(pounceAction.freeze_play_sound)
playsound(loc, rand(0, 100) < 95 ? 'sound/voice/alien_pounce.ogg' : 'sound/voice/alien_pounce2.ogg', 25, 1)
playsound(src, rand(0, 100) < 95 ? 'sound/voice/alien_pounce.ogg' : 'sound/voice/alien_pounce2.ogg', 25, 1)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Pounce"))
pounceAction.freeze_timer_id = addtimer(CALLBACK(src, PROC_REF(unfreeze_pounce)), pounceAction.freeze_time, TIMER_STOPPABLE)
pounceAction.additional_effects(M)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
R.take_damage_type(40 / A.acid_delay, "acid", src)
visible_message(SPAN_XENOWARNING("[src] vomits globs of vile stuff at \the [O]. It sizzles under the bubbling mess of acid!"), \
SPAN_XENOWARNING("We vomit globs of vile stuff at [O]. It sizzles under the bubbling mess of acid!"), null, 5)
playsound(loc, "sound/bullets/acid_impact1.ogg", 25)
playsound(O, "sound/bullets/acid_impact1.ogg", 25)
QDEL_IN(A, 20)
return

Expand All @@ -158,7 +158,7 @@
attack_log += text("\[[time_stamp()]\] <font color='green'>Spat acid on [O]</font>")
visible_message(SPAN_XENOWARNING("[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!"), \
SPAN_XENOWARNING("We vomit globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!"), null, 5)
playsound(loc, "sound/bullets/acid_impact1.ogg", 25)
playsound(O, "sound/bullets/acid_impact1.ogg", 25)

/proc/unroot_human(mob/living/carbon/H, trait_source)
if (!isxeno_human(H))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
COMSIG_LIVING_FLAMER_FLAMED,
), PROC_REF(flamer_crossed_immune))
add_traits(list(TRAIT_ABILITY_BURROWED, TRAIT_UNDENSE, TRAIT_IMMOBILIZED), TRAIT_SOURCE_ABILITY("Burrow"))
playsound(src.loc, 'sound/effects/burrowing_b.ogg', 25)
playsound(src, 'sound/effects/burrowing_b.ogg', 25)
update_icons()
addtimer(CALLBACK(src, PROC_REF(do_burrow_cooldown)), (caste ? caste.burrow_cooldown : 5 SECONDS))
burrow_timer = world.time + 90 // How long we can be burrowed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@
if(xeno.ammo.spit_windup)
spitting = TRUE
if(xeno.ammo.pre_spit_warn)
playsound(xeno.loc,"alien_drool", 55, 1)
playsound(xeno, "alien_drool", 55, 1)
to_chat(xeno, SPAN_WARNING("We begin to prepare a large spit!"))
xeno.visible_message(SPAN_WARNING("[xeno] prepares to spit a massive glob!"),\
SPAN_WARNING("We begin to spit [xeno.ammo.name]!"))
Expand All @@ -775,7 +775,7 @@
xeno.visible_message(SPAN_XENOWARNING("[xeno] spits at [atom]!"), \

SPAN_XENOWARNING("We spit [xeno.ammo.name] at [atom]!") )
playsound(xeno.loc, sound_to_play, 25, 1)
playsound(xeno, sound_to_play, 25, 1)

var/obj/projectile/proj = new (current_turf, create_cause_data(xeno.ammo.name, xeno))
proj.generate_bullet(xeno.ammo)
Expand Down
Loading
Loading