mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 11:37:40 +01:00
Adds the Volume Mixer to adjust individual channel volumes (#15507)
* Adds the Volume Mixer * Address AA * LF -> CRLF * Puts thunderdome.ogg on CHANNEL_ADMIN * Update interface name
This commit is contained in:
@@ -55,7 +55,14 @@
|
||||
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
|
||||
log_admin("[key_name(usr)] used there can be only one.")
|
||||
GLOB.nologevent = 1
|
||||
world << sound('sound/music/thunderdome.ogg')
|
||||
|
||||
var/sound/music = sound('sound/music/thunderdome.ogg', channel = CHANNEL_ADMIN)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client.prefs.sound & SOUND_MIDI)
|
||||
if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY))
|
||||
M.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
music.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN)
|
||||
SEND_SOUND(M, music)
|
||||
|
||||
/client/proc/only_me()
|
||||
if(!SSticker)
|
||||
@@ -101,4 +108,11 @@
|
||||
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ME! -NO ATTACK LOGS WILL BE SENT TO ADMINS FROM THIS POINT FORTH-", 1)
|
||||
log_admin("[key_name(usr)] used there can be only me.")
|
||||
GLOB.nologevent = 1
|
||||
world << sound('sound/music/thunderdome.ogg')
|
||||
|
||||
var/sound/music = sound('sound/music/thunderdome.ogg', channel = CHANNEL_ADMIN)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client.prefs.sound & SOUND_MIDI)
|
||||
if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY))
|
||||
M.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
music.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN)
|
||||
SEND_SOUND(M, music)
|
||||
|
||||
@@ -33,6 +33,7 @@ GLOBAL_LIST_EMPTY(sounds_cache)
|
||||
if(M.client.prefs.sound & SOUND_MIDI)
|
||||
if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY))
|
||||
M.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
uploaded_sound.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN)
|
||||
SEND_SOUND(M, uploaded_sound)
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Global Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -184,8 +184,18 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
|
||||
var/slot_name = ""
|
||||
var/saved = FALSE // Indicates whether the character comes from the database or not
|
||||
|
||||
// jukebox volume
|
||||
var/volume = 100
|
||||
/// Volume mixer, indexed by channel as TEXT (numerical indexes will not work). Volume goes from 0 to 100.
|
||||
var/list/volume_mixer = list(
|
||||
"1024" = 100, // CHANNEL_LOBBYMUSIC
|
||||
"1023" = 100, // CHANNEL_ADMIN
|
||||
"1022" = 100, // CHANNEL_VOX
|
||||
"1021" = 100, // CHANNEL_JUKEBOX
|
||||
"1020" = 100, // CHANNEL_HEARTBEAT
|
||||
"1019" = 100, // CHANNEL_BUZZ
|
||||
"1018" = 100, // CHANNEL_AMBIENCE
|
||||
)
|
||||
/// The volume mixer save timer handle. Used to debounce the DB call to save, to avoid spamming.
|
||||
var/volume_mixer_saving = null
|
||||
|
||||
// BYOND membership
|
||||
var/unlock_content = 0
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
toggles,
|
||||
toggles_2,
|
||||
sound,
|
||||
volume,
|
||||
volume_mixer,
|
||||
lastchangelog,
|
||||
exp,
|
||||
clientfps,
|
||||
@@ -38,7 +38,7 @@
|
||||
toggles = text2num(query.item[7])
|
||||
toggles2 = text2num(query.item[8])
|
||||
sound = text2num(query.item[9])
|
||||
volume = text2num(query.item[10])
|
||||
volume_mixer = deserialize_volume_mixer(query.item[10])
|
||||
lastchangelog = query.item[11]
|
||||
exp = query.item[12]
|
||||
clientfps = text2num(query.item[13])
|
||||
@@ -57,7 +57,6 @@
|
||||
sound = sanitize_integer(sound, 0, 65535, initial(sound))
|
||||
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
|
||||
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
|
||||
volume = sanitize_integer(volume, 0, 100, initial(volume))
|
||||
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
|
||||
exp = sanitize_text(exp, initial(exp))
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps))
|
||||
@@ -74,6 +73,11 @@
|
||||
log_runtime(EXCEPTION("[C.key] had a malformed role entry: '[role]'. Removing!"), src)
|
||||
be_special -= role
|
||||
|
||||
// We're saving volume_mixer here as well, so no point in keeping the timer running
|
||||
if(volume_mixer_saving)
|
||||
deltimer(volume_mixer_saving)
|
||||
volume_mixer_saving = null
|
||||
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE [format_table_name("player")]
|
||||
SET
|
||||
ooccolor=:ooccolour,
|
||||
@@ -86,7 +90,7 @@
|
||||
toggles_2=:toggles2,
|
||||
atklog=:atklog,
|
||||
sound=:sound,
|
||||
volume=:volume,
|
||||
volume_mixer=:volume_mixer,
|
||||
lastchangelog=:lastchangelog,
|
||||
clientfps=:clientfps,
|
||||
parallax=:parallax
|
||||
@@ -103,7 +107,7 @@
|
||||
"toggles2" = num2text(toggles2, CEILING(log(10, (TOGGLES_2_TOTAL)), 1)),
|
||||
"atklog" = atklog,
|
||||
"sound" = sound,
|
||||
"volume" = volume,
|
||||
"volume_mixer" = serialize_volume_mixer(volume_mixer),
|
||||
"lastchangelog" = lastchangelog,
|
||||
"clientfps" = clientfps,
|
||||
"parallax" = parallax,
|
||||
@@ -657,3 +661,24 @@
|
||||
|
||||
saved = FALSE
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Saves [/datum/preferences/proc/volume_mixer] for the current client.
|
||||
*/
|
||||
/datum/preferences/proc/save_volume_mixer()
|
||||
volume_mixer_saving = null
|
||||
|
||||
var/datum/db_query/update_query = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("player")] SET volume_mixer=:volume_mixer WHERE ckey=:ckey",
|
||||
list(
|
||||
"volume_mixer" = serialize_volume_mixer(volume_mixer),
|
||||
"ckey" = parent.ckey
|
||||
)
|
||||
)
|
||||
|
||||
if(!update_query.warn_execute())
|
||||
qdel(update_query)
|
||||
return FALSE
|
||||
|
||||
qdel(update_query)
|
||||
return TRUE
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Returns a DB-friendly version of a volume mixer list.
|
||||
*
|
||||
* Arguments
|
||||
* * vm - The volume mixer list to serialize.
|
||||
*/
|
||||
/datum/preferences/proc/serialize_volume_mixer(list/vm)
|
||||
var/list/temp = list()
|
||||
for(var/channel in vm)
|
||||
if(!get_channel_name(text2num(channel)))
|
||||
continue
|
||||
temp["[channel]"] = vm[channel]
|
||||
return json_encode(temp)
|
||||
|
||||
/**
|
||||
* Returns a volume mixer list from text, usually from the DB.
|
||||
*
|
||||
* Failure to deserialize will return the current value.
|
||||
*
|
||||
* Arguments
|
||||
* * vmt - The volume mixer list to deserialize.
|
||||
*/
|
||||
/datum/preferences/proc/deserialize_volume_mixer(vmt)
|
||||
if(!istext(vmt))
|
||||
return volume_mixer
|
||||
var/list/vm = json_decode(vmt)
|
||||
if(!islist(vm))
|
||||
return volume_mixer
|
||||
var/list/temp = list()
|
||||
// Ensure the default values are present
|
||||
for(var/channel in volume_mixer)
|
||||
temp[channel] = volume_mixer[channel]
|
||||
for(var/channel in vm)
|
||||
if(!get_channel_name(text2num(channel)))
|
||||
continue
|
||||
temp[channel] = vm[channel]
|
||||
return temp
|
||||
|
||||
/**
|
||||
* Changes a channel's volume then queues it for DB save.
|
||||
*
|
||||
* Arguments:
|
||||
* * channel - The channel whose volume to change.
|
||||
* * volume - The new volume, clamped between 0 and 100.
|
||||
* * debounce_save - Whether to debounce the save call to prevent spamming of DB calls.
|
||||
*/
|
||||
/datum/preferences/proc/set_channel_volume(channel, volume, debounce_save = TRUE)
|
||||
if(!get_channel_name(channel))
|
||||
return
|
||||
// Set the volume
|
||||
volume = clamp(volume, 0, 100)
|
||||
volume_mixer["[channel]"] = volume
|
||||
// Update the sound channel
|
||||
var/sound/S = sound(null, channel = channel, volume = volume)
|
||||
S.status = SOUND_UPDATE
|
||||
SEND_SOUND(parent, S)
|
||||
// Save it
|
||||
if(debounce_save)
|
||||
volume_mixer_saving = addtimer(CALLBACK(src, .proc/save_volume_mixer), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE)
|
||||
else
|
||||
if(volume_mixer_saving)
|
||||
deltimer(volume_mixer_saving)
|
||||
save_volume_mixer()
|
||||
|
||||
/**
|
||||
* Returns a volume multiplier for the given channel, from 0 to 1 (default).
|
||||
*
|
||||
* Arguments:
|
||||
* * channel - The channel whose volume to get.
|
||||
*/
|
||||
/datum/preferences/proc/get_channel_volume(channel)
|
||||
if(!istext(channel))
|
||||
channel = "[channel]"
|
||||
if(isnull(volume_mixer[channel]))
|
||||
return 1
|
||||
return clamp(volume_mixer[channel] / 100, 0, 1)
|
||||
|
||||
/client/verb/volume_mixer()
|
||||
set name = "Open Volume Mixer"
|
||||
set category = "Preferences"
|
||||
set hidden = TRUE
|
||||
|
||||
var/datum/ui_module/volume_mixer/VM = new()
|
||||
VM.ui_interact(usr)
|
||||
@@ -179,6 +179,7 @@ GLOBAL_VAR_INIT(announcing_vox, 0) // Stores the time of the last announcement
|
||||
if(M.client && M.client.prefs.sound & SOUND_AI_VOICE)
|
||||
var/turf/T = get_turf(M)
|
||||
if(T && T.z == z_level && M.can_hear())
|
||||
voice.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_VOX)
|
||||
M << voice
|
||||
else
|
||||
only_listener << voice
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/datum/ui_module/volume_mixer
|
||||
name = "Volume Mixer"
|
||||
|
||||
/datum/ui_module/volume_mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "VolumeMixer", name, 400, clamp(80 + 50 * length(user.client.prefs.volume_mixer), 300, 600), master_ui, state)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/datum/ui_module/volume_mixer/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/channels = list()
|
||||
for(var/channel in user.client.prefs.volume_mixer)
|
||||
channels += list(list(
|
||||
"num" = channel,
|
||||
"name" = get_channel_name(text2num(channel)),
|
||||
"volume" = user.client.prefs.volume_mixer[channel]
|
||||
))
|
||||
data["channels"] = channels
|
||||
|
||||
return data
|
||||
|
||||
/datum/ui_module/volume_mixer/ui_act(action, list/params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("volume")
|
||||
var/channel = text2num(params["channel"])
|
||||
var/volume = text2num(params["volume"])
|
||||
if(isnull(channel) || isnull(volume))
|
||||
return FALSE
|
||||
usr.client.prefs.set_channel_volume(channel, volume)
|
||||
else
|
||||
return FALSE
|
||||
Reference in New Issue
Block a user