Beginnings of a global volume control system

This commit is contained in:
ShadowLarkens
2020-08-14 16:49:13 -07:00
committed by Rykka
parent 2636620dce
commit 7aaa40b62c
14 changed files with 227 additions and 57 deletions

View File

@@ -462,3 +462,16 @@ var/global/list/##LIST_NAME = list();\
#define FONT_HUGE(X) "<font size='4'>[X]</font>"
#define FONT_GIANT(X) "<font size='5'>[X]</font>"
#define VOLUME_CHANNEL_MASTER "Master"
#define VOLUME_CHANNEL_AMBIENCE "Ambience"
#define VOLUME_CHANNEL_ALARMS "Alarms"
#define VOLUME_CHANNEL_VORE "Vore"
// Make sure you update this or clients won't be able to adjust the channel
GLOBAL_LIST_INIT(all_volume_channels, list(
VOLUME_CHANNEL_MASTER,
VOLUME_CHANNEL_AMBIENCE,
VOLUME_CHANNEL_ALARMS,
VOLUME_CHANNEL_VORE,
))

View File

@@ -377,7 +377,10 @@ var/list/mob/living/forced_ambiance_list = new
/area/proc/play_ambience(var/mob/living/L, initial = TRUE)
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance))) return
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance)))
return
var/volume_mod = L.get_preference_volume_channel(VOLUME_CHANNEL_AMBIENCE)
// If we previously were in an area with force-played ambiance, stop it.
if((L in forced_ambiance_list) && initial)
@@ -392,6 +395,7 @@ var/list/mob/living/forced_ambiance_list = new
var/sound/chosen_ambiance = pick(forced_ambience)
if(!istype(chosen_ambiance))
chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE_FORCED)
chosen_ambiance.volume *= volume_mod
L << chosen_ambiance
else
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
@@ -399,7 +403,7 @@ var/list/mob/living/forced_ambiance_list = new
var/ambience_odds = L?.client.prefs.ambience_chance
if(prob(ambience_odds) && (world.time >= L.client.time_last_ambience_played + 1 MINUTE))
var/sound = pick(ambience)
L << sound(sound, repeat = 0, wait = 0, volume = 50, channel = CHANNEL_AMBIENCE)
L << sound(sound, repeat = 0, wait = 0, volume = 50 * volume_mod, channel = CHANNEL_AMBIENCE)
L.client.time_last_ambience_played = world.time
/area/proc/gravitychange(var/gravitystate = 0)

View File

@@ -155,7 +155,7 @@ FIRE ALARM
for(var/obj/machinery/firealarm/FA in area)
fire_alarm.triggerAlarm(loc, FA, duration, hidden = alarms_hidden)
update_icon()
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4)
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS)
if(user)
log_game("[user] triggered a fire alarm at [COORD(src)]")

View File

@@ -1,4 +1,4 @@
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null)
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null, volume_channel = null)
if(isarea(source))
throw EXCEPTION("playsound(): source is an area")
return
@@ -23,9 +23,9 @@
if(distance <= maxdistance)
if(T && T.z == turf_source.z)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S, preference)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S, preference, volume_channel)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference)
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference, volume_channel = null)
if(!client || ear_deaf > 0)
return
if(preference && !client.is_preference_enabled(preference))
@@ -36,6 +36,11 @@
S.wait = 0 //No queue
S.channel = channel || open_sound_channel()
// I'm not sure if you can modify S.volume, but I'd rather not try to find out what
// horrible things lurk in BYOND's internals, so we're just gonna do vol *=
vol *= client.get_preference_volume_channel(volume_channel)
vol *= client.get_preference_volume_channel(VOLUME_CHANNEL_MASTER)
S.volume = vol
if(vary)

View File

@@ -24,6 +24,7 @@
var/time_died_as_mouse = null //when the client last died as a mouse
var/datum/tooltip/tooltips = null
var/datum/chatOutput/chatOutput
var/datum/volume_panel/volume_panel = null // Initialized by /client/verb/volume_panel()
var/chatOutputLoadedAt
var/adminhelped = 0

View File

@@ -0,0 +1,106 @@
/datum/category_group/player_setup_category/volume_sliders
name = "Sound"
sort_order = 7
category_item_type = /datum/category_item/player_setup_item/volume_sliders
/datum/category_item/player_setup_item/volume_sliders/volume
name = "General Volume"
sort_order = 1
/datum/category_item/player_setup_item/volume_sliders/volume/load_preferences(var/savefile/S)
S["volume_channels"] >> pref.volume_channels
/datum/category_item/player_setup_item/volume_sliders/volume/save_preferences(var/savefile/S)
S["volume_channels"] << pref.volume_channels
/datum/category_item/player_setup_item/volume_sliders/volume/sanitize_preferences()
if(isnull(pref.volume_channels))
pref.volume_channels = list()
for(var/channel in pref.volume_channels)
if(!(channel in GLOB.all_volume_channels))
// Channel no longer exists, yeet
pref.volume_channels.Remove(channel)
for(var/channel in GLOB.all_volume_channels)
if(!(channel in pref.volume_channels))
pref.volume_channels["[channel]"] = 1
else
pref.volume_channels["[channel]"] = clamp(pref.volume_channels["[channel]"], 0, 2)
/datum/category_item/player_setup_item/volume_sliders/volume/content(var/mob/user)
. += "<b>Volume Settings</b><br>"
for(var/channel in pref.volume_channels)
. += "[channel]: <a href='?src=\ref[src];change_volume=[channel];'><b>[pref.volume_channels[channel] * 100]%</b></a><br>"
. += "<br>"
/datum/category_item/player_setup_item/volume_sliders/volume/OnTopic(var/href, var/list/href_list, var/mob/user)
if(href_list["change_volume"])
if(CanUseTopic(user))
var/channel = href_list["change_volume"]
if(!(channel in pref.volume_channels))
pref.volume_channels["[channel]"] = 1
var/value = input("Choose your volume for [channel] (0-200%)", "[channel] volume", (pref.volume_channels[channel] * 100))
if(isnum(value))
value = CLAMP(value, 0, 200)
pref.volume_channels["[channel]"] = (value / 100)
return TOPIC_REFRESH
return ..()
/mob/proc/get_preference_volume_channel(volume_channel)
if(!client)
return 0
return client.get_preference_volume_channel(volume_channel)
/client/proc/get_preference_volume_channel(volume_channel)
if(!volume_channel || !prefs)
return 1
if(!(volume_channel in prefs.volume_channels))
prefs.volume_channels["[volume_channel]"] = 1
return prefs.volume_channels["[volume_channel]"]
// Neat little volume adjuster thing in case you don't wanna touch preferences by hand you lazy fuck
/datum/volume_panel
/datum/volume_panel/tgui_state(mob/user)
return GLOB.tgui_always_state
/datum/volume_panel/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "VolumePanel", "Volume Panel")
ui.open()
/datum/volume_panel/tgui_data(mob/user)
if(!user.client || !user.client.prefs)
return list("error" = TRUE)
var/list/data = ..()
data["volume_channels"] = user.client.prefs.volume_channels
return data
/datum/volume_panel/tgui_act(action, params)
if(..())
return TRUE
if(!usr?.client?.prefs)
return TRUE
var/datum/preferences/P = usr.client.prefs
switch(action)
if("adjust_volume")
var/channel = params["channel"]
if(channel in P.volume_channels)
P.volume_channels["[channel]"] = clamp(params["vol"], 0, 2)
SScharacter_setup.queue_preferences_save(P)
return TRUE
/client/verb/volume_panel()
set name = "Volume Panel"
set category = "Preferences"
set desc = "Allows you to adjust volume levels on the fly."
if(!volume_panel)
volume_panel = new(src)
volume_panel.tgui_interact(mob)

View File

@@ -2,23 +2,23 @@
var/media_volume = 1
var/media_player = 2 // 0 = VLC, 1 = WMP, 2 = HTML5, 3+ = unassigned
/datum/category_item/player_setup_item/player_global/media
/datum/category_item/player_setup_item/volume_sliders/media
name = "Media"
sort_order = 5
sort_order = 2
/datum/category_item/player_setup_item/player_global/media/load_preferences(var/savefile/S)
/datum/category_item/player_setup_item/volume_sliders/media/load_preferences(var/savefile/S)
S["media_volume"] >> pref.media_volume
S["media_player"] >> pref.media_player
/datum/category_item/player_setup_item/player_global/media/save_preferences(var/savefile/S)
/datum/category_item/player_setup_item/volume_sliders/media/save_preferences(var/savefile/S)
S["media_volume"] << pref.media_volume
S["media_player"] << pref.media_player
/datum/category_item/player_setup_item/player_global/media/sanitize_preferences()
/datum/category_item/player_setup_item/volume_sliders/media/sanitize_preferences()
pref.media_volume = isnum(pref.media_volume) ? CLAMP(pref.media_volume, 0, 1) : initial(pref.media_volume)
pref.media_player = sanitize_inlist(pref.media_player, list(0, 1, 2), initial(pref.media_player))
/datum/category_item/player_setup_item/player_global/media/content(var/mob/user)
/datum/category_item/player_setup_item/volume_sliders/media/content(var/mob/user)
. += "<b>Jukebox Volume:</b>"
. += "<a href='?src=\ref[src];change_media_volume=1'><b>[round(pref.media_volume * 100)]%</b></a><br>"
. += "<b>Media Player Type:</b> Depending on you operating system, one of these might work better. "
@@ -30,7 +30,7 @@
. += (pref.media_player == 0) ? "<span class='linkOn'><b>VLC</b></span> " : "<a href='?src=\ref[src];set_media_player=0'>VLC</a> "
. += "<br>"
/datum/category_item/player_setup_item/player_global/media/OnTopic(var/href, var/list/href_list, var/mob/user)
/datum/category_item/player_setup_item/volume_sliders/media/OnTopic(var/href, var/list/href_list, var/mob/user)
if(href_list["change_media_volume"])
if(CanUseTopic(user))
var/value = input("Choose your Jukebox volume (0-100%)", "Jukebox volume", round(pref.media_volume * 100))

View File

@@ -1,7 +1,7 @@
// Global stuff that will put us on the map
/datum/category_group/player_setup_category/vore
name = "VORE"
sort_order = 7
sort_order = 8
category_item_type = /datum/category_item/player_setup_item/vore
// Define a place to save appearance in character setup

View File

@@ -150,6 +150,8 @@ datum/preferences
var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel.
var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off
var/list/volume_channels = list()
/datum/preferences/New(client/C)
player_setup = new(src)

View File

@@ -131,7 +131,7 @@
lift.update_fire_mode(!lift.fire_mode)
if(lift.fire_mode)
audible_message("<span class='danger'>Firefighter Mode Activated. Door safeties disabled. Manual control engaged.</span>")
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4)
playsound(src, 'sound/machines/airalarm.ogg', 25, 0, 4, volume_channel = VOLUME_CHANNEL_ALARMS)
else
audible_message("<span class='warning'>Firefighter Mode Deactivated. Door safeties enabled. Automatic control engaged.</span>")
return

View File

@@ -188,7 +188,7 @@
else
soundfile = fancy_vore_sounds[vore_sound]
if(soundfile)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
recent_sound = TRUE
//Messages if it's a mob
@@ -245,7 +245,7 @@
else
soundfile = fancy_release_sounds[release_sound]
if(soundfile)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
return count
@@ -293,7 +293,7 @@
else
soundfile = fancy_release_sounds[release_sound]
if(soundfile)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises)
playsound(src, soundfile, vol = 100, vary = 1, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/eating_noises, volume_channel = VOLUME_CHANNEL_VORE)
return 1
@@ -559,9 +559,9 @@
struggle_snuggle = sound(get_sfx("classic_struggle_sounds"))
else
struggle_snuggle = sound(get_sfx("fancy_prey_struggle"))
playsound(src, struggle_snuggle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises)
playsound(src, struggle_snuggle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises, volume_channel = VOLUME_CHANNEL_VORE)
else
playsound(src, struggle_rustle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises)
playsound(src, struggle_rustle, vary = 1, vol = 75, falloff = VORE_SOUND_FALLOFF, preference = /datum/client_preference/digestion_noises, volume_channel = VOLUME_CHANNEL_VORE)
if(escapable) //If the stomach has escapable enabled.
if(prob(escapechance)) //Let's have it check to see if the prey escapes first.

View File

@@ -0,0 +1,38 @@
import { round } from 'common/math';
import { Fragment } from 'inferno';
import { useBackend } from "../backend";
import { Box, Button, Flex, Icon, LabeledList, Slider, Section } from "../components";
import { Window } from "../layouts";
export const VolumePanel = (props, context) => {
const { act, data } = useBackend(context);
const {
volume_channels,
} = data;
return (
<Window width={350} height={600}>
<Window.Content>
<Section title="Volume Levels">
<LabeledList>
{Object.keys(volume_channels).map(key => (
<LabeledList.Item label={key} key={key}>
<Slider
width="88%"
minValue={0}
maxValue={200}
value={volume_channels[key] * 100}
onChange={(e, val) => act("adjust_volume", { channel: key, vol: (val / 100) })} />
<Button
ml={1}
icon="undo"
onClick={() => act("adjust_volume", { channel: key, vol: 1 })} />
</LabeledList.Item>
))}
</LabeledList>
</Section>
</Window.Content>
</Window>
);
};

File diff suppressed because one or more lines are too long

View File

@@ -1774,7 +1774,6 @@
#include "code\modules\client\preference_setup\global\02_settings.dm"
#include "code\modules\client\preference_setup\global\03_pai.dm"
#include "code\modules\client\preference_setup\global\04_ooc.dm"
#include "code\modules\client\preference_setup\global\05_media.dm"
#include "code\modules\client\preference_setup\global\setting_datums.dm"
#include "code\modules\client\preference_setup\loadout\gear_tweaks.dm"
#include "code\modules\client\preference_setup\loadout\gear_tweaks_vr.dm"
@@ -1807,6 +1806,8 @@
#include "code\modules\client\preference_setup\loadout\loadout_xeno_vr.dm"
#include "code\modules\client\preference_setup\occupation\occupation.dm"
#include "code\modules\client\preference_setup\skills\skills.dm"
#include "code\modules\client\preference_setup\volume_sliders\01_volume.dm"
#include "code\modules\client\preference_setup\volume_sliders\02_media.dm"
#include "code\modules\client\preference_setup\vore\01_ears.dm"
#include "code\modules\client\preference_setup\vore\02_size.dm"
#include "code\modules\client\preference_setup\vore\03_egg.dm"