diff --git a/code/__DEFINES/sounds.dm b/code/__DEFINES/sounds.dm index 541d95d28189..807305174b34 100644 --- a/code/__DEFINES/sounds.dm +++ b/code/__DEFINES/sounds.dm @@ -60,6 +60,9 @@ #define SOUND_ENVIRONMENT_DIZZY 24 #define SOUND_ENVIRONMENT_PSYCHOTIC 25 +#define SOUND_ECHO_REVERB_ON list(0, 0, 0, 0, 0, 0.0, 0, 0.25, 1.5, 1.0, 0, 1.0, 0, 0.0, 0.0, 0.0, 1.0, 0) +#define SOUND_ECHO_REVERB_OFF list(0, 0, -10000, -10000, 0, 0.0, 0, 0.25, 1.5, 1.0, 0, 1.0, 0, 0.0, 0.0, 0.0, 1.0, 0) //-10000 to Room & RoomHF makes enviromental reverb effectively inaudible + #define AMBIENCE_SHIP 'sound/ambience/shipambience.ogg' #define AMBIENCE_JUNGLE 'sound/ambience/ambienceLV624.ogg' #define AMBIENCE_RIVER 'sound/ambience/ambienceriver.ogg' diff --git a/code/datums/soundOutput.dm b/code/datums/soundOutput.dm index eb7339ceae51..6ebc32c7e41f 100644 --- a/code/datums/soundOutput.dm +++ b/code/datums/soundOutput.dm @@ -4,13 +4,25 @@ 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/echo -/datum/soundOutput/New(client/C) - if(!C) + + /// Currently applied environmental reverb. + VAR_PROTECTED/owner_environment = SOUND_ENVIRONMENT_NONE + +/datum/soundOutput/New(client/client) + if(!client) qdel(src) return - owner = C - . = ..() + 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_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_LOGGED_IN) + owner = null + return ..() /datum/soundOutput/proc/process_sound(datum/sound_template/T) var/sound/S = sound(T.file, T.wait, T.repeat) @@ -22,7 +34,6 @@ S.frequency = T.frequency S.falloff = T.falloff S.status = T.status - S.echo = T.echo if(T.x && T.y && T.z) var/turf/owner_turf = get_turf(owner.mob) if(owner_turf) @@ -38,16 +49,12 @@ S.x = T.x - owner_turf.x S.y = 0 S.z = T.y - owner_turf.y - var/area/A = owner_turf.loc - S.environment = A.sound_environment S.y += T.y_s_offset S.x += T.x_s_offset + S.echo = SOUND_ECHO_REVERB_ON //enable environment reverb for positional sounds if(owner.mob.ear_deaf > 0) S.status |= SOUND_MUTE - if(owner.mob.sound_environment_override != SOUND_ENVIRONMENT_NONE) - S.environment = owner.mob.sound_environment_override - sound_to(owner,S) /datum/soundOutput/proc/update_ambience(area/target_area, ambience_override, force_update = FALSE) @@ -84,7 +91,6 @@ S.status = status_flags if(target_area) - S.environment = target_area.sound_environment var/muffle if(target_area.ceiling_muffle) switch(target_area.ceiling) @@ -128,6 +134,51 @@ S.status = SOUND_UPDATE sound_to(owner, S) +/// Pulls mob's area's sound_environment and applies if necessary and not overridden. +/datum/soundOutput/proc/update_area_environment() + var/area/owner_area = get_area(owner.mob) + var/new_environment = owner_area.sound_environment + + if(owner.mob.sound_environment_override != SOUND_ENVIRONMENT_NONE) //override in effect, can't apply + return + + set_owner_environment(new_environment) + +/// Pulls mob's sound_environment_override and applies if necessary. +/datum/soundOutput/proc/update_mob_environment_override() + var/new_environment_override = owner.mob.sound_environment_override + + if(new_environment_override == SOUND_ENVIRONMENT_NONE) //revert to area environment + update_area_environment() + return + + set_owner_environment(new_environment_override) + +/// Pushes new_environment to owner and updates owner_environment var. +/datum/soundOutput/proc/set_owner_environment(new_environment = SOUND_ENVIRONMENT_NONE) + if(new_environment ~= src.owner_environment) //no need to change + return + + var/sound/sound = sound() + sound.environment = new_environment + sound_to(owner, sound) + + src.owner_environment = new_environment + +/datum/soundOutput/proc/on_mob_moved(datum/source, atom/oldloc, direction, Forced) + SIGNAL_HANDLER //COMSIG_MOVABLE_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() + /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 if(volume_preferences[volume_key] > 1) diff --git a/code/game/sound.dm b/code/game/sound.dm index 49ccb4eb9331..1ab8fc42f41a 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -1,3 +1,5 @@ +/sound + echo = SOUND_ECHO_REVERB_OFF //disable enviroment reverb by default, soundOutput re-enables for positional sounds /datum/sound_template //Basically a sound datum, but only serves as a way to carry info to soundOutput var/file //The sound itself @@ -11,7 +13,6 @@ var/falloff = 1 var/volume_cat = VOLUME_SFX var/range = 0 - var/list/echo var/x //Map coordinates, not sound coordinates var/y var/z @@ -35,7 +36,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, echo, 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) if(isarea(source)) error("[source] is an area and is trying to make the sound: [soundin]") return FALSE @@ -53,7 +54,6 @@ S.falloff = falloff S.volume = vol S.volume_cat = vol_cat - S.echo = echo S.y_s_offset = y_s_offset S.x_s_offset = x_s_offset if(vary != FALSE) @@ -100,7 +100,7 @@ //This is the replacement for playsound_local. Use this for sending sounds directly to a client -/proc/playsound_client(client/client, soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, list/echo, y_s_offset, x_s_offset) +/proc/playsound_client(client/client, soundin, atom/origin, vol = 100, random_freq, vol_cat = VOLUME_SFX, channel = 0, status, y_s_offset, x_s_offset) if(!istype(client) || !client.soundOutput) return FALSE var/datum/sound_template/S = new() if(origin) @@ -123,7 +123,6 @@ S.volume_cat = vol_cat S.channel = channel S.status = status - S.echo = echo S.y_s_offset = y_s_offset S.x_s_offset = x_s_offset SSsound.queue(S, list(client)) @@ -154,13 +153,12 @@ /// Play sound for all on-map clients on a given Z-level. Good for ambient sounds. -/proc/playsound_z(z, soundin, volume = 100, vol_cat = VOLUME_SFX, echo, y_s_offset, x_s_offset) +/proc/playsound_z(z, soundin, volume = 100, vol_cat = VOLUME_SFX, y_s_offset, x_s_offset) var/datum/sound_template/S = new() S.file = soundin S.volume = volume S.channel = SOUND_CHANNEL_Z S.volume_cat = vol_cat - S.echo = echo S.y_s_offset = y_s_offset S.x_s_offset = x_s_offset var/list/hearers = list() diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm index a2b92007d97e..825fa4dcc941 100644 --- a/code/modules/mob/living/init_signals.dm +++ b/code/modules/mob/living/init_signals.dm @@ -26,6 +26,7 @@ if(stat < UNCONSCIOUS) set_stat(UNCONSCIOUS) sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC + client?.soundOutput?.update_mob_environment_override() /// Called when [TRAIT_KNOCKEDOUT] is removed from the mob. /mob/living/proc/on_knockedout_trait_loss(datum/source) @@ -33,6 +34,7 @@ if(stat <= UNCONSCIOUS) update_stat() sound_environment_override = SOUND_ENVIRONMENT_NONE + client?.soundOutput?.update_mob_environment_override() /// Called when [TRAIT_IMMOBILIZED] is added to the mob. /mob/living/proc/on_immobilized_trait_gain(datum/source) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5f917cf6e0d5..27697a8938a7 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -503,12 +503,10 @@ if(CONSCIOUS) if(stat >= UNCONSCIOUS) ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC add_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED), STAT_TRAIT) if(UNCONSCIOUS) if(stat >= UNCONSCIOUS) ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates - sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC if(DEAD) SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_ALIVE) // remove_from_dead_mob_list() @@ -518,12 +516,10 @@ if(CONSCIOUS) if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_NONE remove_traits(list(/*TRAIT_HANDS_BLOCKED, */ TRAIT_INCAPACITATED, TRAIT_FLOORED, /*TRAIT_CRITICAL_CONDITION*/), STAT_TRAIT) if(UNCONSCIOUS) if(. >= UNCONSCIOUS) REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) - sound_environment_override = SOUND_ENVIRONMENT_NONE if(DEAD) SEND_SIGNAL(src, COMSIG_MOB_STAT_SET_DEAD) // REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)