diff --git a/code/__DEFINES/dcs/signals/signals_music.dm b/code/__DEFINES/dcs/signals/signals_music.dm index 2f15f4e6322..107a2bff02a 100644 --- a/code/__DEFINES/dcs/signals/signals_music.dm +++ b/code/__DEFINES/dcs/signals/signals_music.dm @@ -10,3 +10,8 @@ #define COMSIG_INSTRUMENT_REPEAT "instrument_repeat" ///sent to the instrument when tempo changes, skipped on new. (datum/song) #define COMSIG_INSTRUMENT_TEMPO_CHANGE "instrument_tempo_change" + +// /datum/jukebox signals + +///sent to the jukebox when the volume preference is changed and applied +#define COMSIG_MOB_JUKEBOX_PREFERENCE_APPLIED "jukebox_pref_applied" diff --git a/code/datums/components/jukebox.dm b/code/datums/components/jukebox.dm index 675e998cd4f..7e9f9657134 100644 --- a/code/datums/components/jukebox.dm +++ b/code/datums/components/jukebox.dm @@ -100,7 +100,7 @@ var/datum/track/new_track = new() new_track.song_path = file("[global.config.directory]/jukebox_music/sounds/[track_file]") var/list/track_data = splittext(track_file, "+") - if(length(track_data) < 3) // BUBBER EDIT - This is fucking stupid - ORIGINAL: if(length(track_data) != 3) + if(length(track_data) < 3) continue new_track.song_name = track_data[1] new_track.song_length = text2num(track_data[2]) @@ -215,9 +215,9 @@ RegisterSignal(new_listener, COMSIG_MOB_LOGIN, PROC_REF(listener_login)) return - RegisterSignal(new_listener, COMSIG_MOVABLE_MOVED, PROC_REF(listener_moved)) + RegisterSignals(new_listener, list(COMSIG_MOVABLE_MOVED, COMSIG_MOB_JUKEBOX_PREFERENCE_APPLIED), PROC_REF(listener_moved)) RegisterSignals(new_listener, list(SIGNAL_ADDTRAIT(TRAIT_DEAF), SIGNAL_REMOVETRAIT(TRAIT_DEAF)), PROC_REF(listener_deaf)) - var/pref_volume = new_listener.client?.prefs.read_preference(/datum/preference/numeric/volume/sound_instruments) + var/pref_volume = new_listener.client?.prefs.read_preference(/datum/preference/numeric/volume/sound_jukebox) if(HAS_TRAIT(new_listener, TRAIT_DEAF) || !pref_volume) listeners[new_listener] |= SOUND_MUTE @@ -280,7 +280,7 @@ if((reason & MUTE_DEAF) && HAS_TRAIT(listener, TRAIT_DEAF)) return FALSE - var/pref_volume = listener.client?.prefs.read_preference(/datum/preference/numeric/volume/sound_instruments) + var/pref_volume = listener.client?.prefs.read_preference(/datum/preference/numeric/volume/sound_jukebox) if((reason & MUTE_PREF) && !pref_volume) return FALSE @@ -309,6 +309,7 @@ COMSIG_MOB_LOGIN, COMSIG_QDELETING, COMSIG_MOVABLE_MOVED, + COMSIG_MOB_JUKEBOX_PREFERENCE_APPLIED, SIGNAL_ADDTRAIT(TRAIT_DEAF), SIGNAL_REMOVETRAIT(TRAIT_DEAF), )) @@ -342,6 +343,13 @@ active_song_sound.x = new_x active_song_sound.z = new_z + var/pref_volume = listener.client?.prefs.read_preference(/datum/preference/numeric/volume/sound_jukebox) + if(!pref_volume) + listeners[listener] |= SOUND_MUTE + else + unmute_listener(listener, MUTE_PREF) + active_song_sound.volume = volume * (pref_volume/100) + SEND_SOUND(listener, active_song_sound) /// When the jukebox moves, we need to update all listeners. diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm index 9a5b15e34cd..febb1f46af6 100644 --- a/code/modules/client/preferences/sounds.dm +++ b/code/modules/client/preferences/sounds.dm @@ -38,9 +38,16 @@ savefile_key = "sound_instruments" savefile_identifier = PREFERENCE_PLAYER -/datum/preference/numeric/volume/sound_instruments/apply_to_client_updated(client/client, value) - if (!value) - client.mob.stop_sound_channel(CHANNEL_JUKEBOX) +/// Controls jukebox track volume +/datum/preference/numeric/volume/sound_jukebox + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "sound_jukebox" + savefile_identifier = PREFERENCE_PLAYER + +/datum/preference/numeric/volume/sound_jukebox/apply_to_client_updated(client/client, value) + var/mob/client_mob = client.mob + if(!isnull(client_mob)) + SEND_SIGNAL(client_mob, COMSIG_MOB_JUKEBOX_PREFERENCE_APPLIED) /datum/preference/choiced/sound_tts category = PREFERENCE_CATEGORY_GAME_PREFERENCES diff --git a/html/changelogs/AutoChangeLog-pr-90417.yml b/html/changelogs/AutoChangeLog-pr-90417.yml new file mode 100644 index 00000000000..1746f0aecf5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-90417.yml @@ -0,0 +1,5 @@ +author: "LT3" +delete-after: True +changes: + - bugfix: "Jukebox volume preference applies to currently playing music" + - bugfix: "Jukebox volume no longer resets to 100% when adjusted from the object" \ No newline at end of file diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/sounds.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/sounds.dm index 617bfce8206..1c746f8e641 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/sounds.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_helpers/sounds.dm @@ -11,6 +11,7 @@ * frequency - playback speed of audio. * channel - The channel the sound is played at. * pressure_affected - Whether or not difference in pressure affects the sound (E.g. if you can hear in space). + * ignore_walls - Whether or not the sound can pass through walls. * falloff_distance - Distance at which falloff begins. Sound is at peak volume (in regards to falloff) aslong as it is in this range. * pref_to_check - the path of the pref that we want to check */ @@ -24,6 +25,7 @@ frequency = null, channel = 0, pressure_affected = TRUE, + ignore_walls = FALSE, falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, use_reverb = TRUE, pref_to_check = /datum/preference/toggle/erp/sex_toy_sounds, @@ -40,27 +42,45 @@ var/sound/sound_to_play = 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 var/turf/above_turf = GET_TURF_ABOVE(turf_source) var/turf/below_turf = GET_TURF_BELOW(turf_source) - var/list/listeners = get_hearers_in_view(maxdistance, turf_source) - . = list()//output everything that successfully heard the sound + var/audible_distance = CALCULATE_MAX_SOUND_AUDIBLE_DISTANCE(vol, maxdistance, falloff_distance, falloff_exponent) - if(above_turf && istransparentturf(above_turf)) - listeners += get_hearers_in_view(maxdistance, above_turf) + if(ignore_walls) + if(above_turf && istransparentturf(above_turf)) + listeners += SSmobs.clients_by_zlevel[above_turf.z] - if(below_turf && istransparentturf(turf_source)) - listeners += get_hearers_in_view(maxdistance, below_turf) + if(below_turf && istransparentturf(turf_source)) + listeners += SSmobs.clients_by_zlevel[below_turf.z] + + else //these sounds don't carry through walls + listeners = get_hearers_in_view(audible_distance, turf_source) + + if(above_turf && istransparentturf(above_turf)) + listeners += get_hearers_in_view(audible_distance, above_turf) + + if(below_turf && istransparentturf(turf_source)) + listeners += get_hearers_in_view(audible_distance, below_turf) for(var/mob/listening_mob in listeners) - if(!listening_mob?.client?.prefs?.read_preference(pref_to_check)) - continue - if(!(get_dist(listening_mob, turf_source) <= maxdistance)) continue - listening_mob.playsound_local(turf_source, soundin, vol, vary, frequency, falloff_exponent, channel, pressure_affected, sound_to_play, maxdistance, falloff_distance, 1, use_reverb) + var/client_volume_modifier = listening_mob?.client?.prefs?.read_preference(pref_to_check) + if(!client_volume_modifier) + continue + if(client_volume_modifier == 1) // binary on/off prefs get set to volume 100 + client_volume_modifier = 100 + client_volume_modifier = client_volume_modifier / 100 + + var/sound_volume_modifier = vol * client_volume_modifier + listening_mob.playsound_local(turf_source, soundin, sound_volume_modifier, vary, frequency, falloff_exponent, channel, pressure_affected, sound_to_play, maxdistance, falloff_distance, 1, use_reverb) . += listening_mob /// The looping sound datum but we check for prefs and use `conditional_pref_sound` instead of `playsound` @@ -86,5 +106,6 @@ pressure_affected = pressure_affected, falloff_distance = falloff_distance, use_reverb = use_reverb, + ignore_walls = FALSE, pref_to_check = pref_to_check ) diff --git a/modular_skyrat/modules/reagent_forging/code/anvil.dm b/modular_skyrat/modules/reagent_forging/code/anvil.dm index d6cca513a39..49daf07f7a3 100644 --- a/modular_skyrat/modules/reagent_forging/code/anvil.dm +++ b/modular_skyrat/modules/reagent_forging/code/anvil.dm @@ -79,7 +79,7 @@ return ITEM_INTERACT_SUCCESS /obj/structure/reagent_anvil/hammer_act(mob/living/user, obj/item/tool) - conditional_pref_sound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', 50, TRUE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) + conditional_pref_sound(src, 'modular_skyrat/modules/reagent_forging/sound/forge.ogg', vol = 50, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE, ignore_walls = FALSE, pref_to_check = /datum/preference/numeric/volume/sound_ambience_volume) //do we have an incomplete item to hammer out? if so, here is our block of code var/obj/item/forging/incomplete/locate_incomplete = locate() in contents diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx index e6982af7b58..9c265179d5e 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx @@ -56,6 +56,13 @@ export const sound_instruments: Feature = { component: FeatureSliderInput, }; +export const sound_jukebox: Feature = { + name: 'Jukebox volume', + category: 'SOUND', + description: 'Volume of jukebox tracks.', + component: FeatureSliderInput, +}; + export const sound_tts: FeatureChoiced = { name: 'Enable TTS', category: 'SOUND',