Synthesizers and headphones can now have circuits! (#62825)

About The Pull Request

A circuit and shell components have been added to Synthesizers (headphones and spacepods included, though with a reduced capacity because of their size), so they can now be used for wiremod. Just like for instant cameras, no shell design here. They are meant to be found in dorms or maybe ordered from cargo.
Why It's Good For The Game

The station outside the sci department has plenty of USB ports stuff but is lacking when it comes to circuits shell. This is another small step toward a better and more applicable wiremod.
Changelog

cl
expansion: Synthesizers and headphones can now have circuits installed.
/cl
This commit is contained in:
Ghom
2021-12-02 11:18:36 +13:00
committed by GitHub
parent a49da2531f
commit 2fbd7b20bb
12 changed files with 267 additions and 110 deletions
+35 -21
View File
@@ -74,8 +74,8 @@
var/list/channels_playing = list()
/// List of channels that aren't being used, as text. This is to prevent unnecessary freeing and reallocations from SSsounds/SSinstruments.
var/list/channels_idle = list()
/// Person playing us
var/mob/user_playing
/// Who or what's playing us
var/atom/music_player
//////////////////////////////////////////////////////
/// Last world.time we checked for who can hear us
@@ -197,7 +197,7 @@
/**
* Attempts to start playing our song.
*/
/datum/song/proc/start_playing(mob/user)
/datum/song/proc/start_playing(atom/user)
if(playing)
return
if(!using_instrument?.ready())
@@ -208,7 +208,6 @@
to_chat(user, span_warning("Song is empty."))
return
playing = TRUE
updateDialog(user_playing)
//we can not afford to runtime, since we are going to be doing sound channel reservations and if we runtime it means we have a channel allocation leak.
//wrap the rest of the stuff to ensure stop_playing() is called.
do_hearcheck()
@@ -216,7 +215,9 @@
elapsed_delay = 0
delay_by = 0
current_chord = 1
user_playing = user
music_player = user
if(ismob(music_player))
updateDialog(music_player)
START_PROCESSING(SSinstruments, src)
/**
@@ -232,13 +233,13 @@
SEND_SIGNAL(parent, COMSIG_SONG_END)
terminate_all_sounds(TRUE)
hearing_mobs.len = 0
user_playing = null
music_player = null
/**
* Processes our song.
*/
/datum/song/proc/process_song(wait)
if(!length(compiled_chords) || should_stop_playing(user_playing))
if(!length(compiled_chords) || should_stop_playing(music_player) == STOP_PLAYING)
stop_playing()
return
var/list/chord = compiled_chords[current_chord]
@@ -276,13 +277,26 @@
/datum/song/proc/play_chord(list/chord)
// last value is timing information
for(var/i in 1 to (length(chord) - 1))
legacy? playkey_legacy(chord[i][1], chord[i][2], chord[i][3], user_playing) : playkey_synth(chord[i], user_playing)
legacy? playkey_legacy(chord[i][1], chord[i][2], chord[i][3], music_player) : playkey_synth(chord[i], music_player)
/**
* Checks if we should halt playback.
*/
/datum/song/proc/should_stop_playing(mob/user)
return QDELETED(parent) || !using_instrument || !playing
/datum/song/proc/should_stop_playing(atom/player)
if(QDELETED(player) || !using_instrument || !playing)
return STOP_PLAYING
return SEND_SIGNAL(parent, COMSIG_SONG_SHOULD_STOP_PLAYING, player)
/// Sets and sanitizes the repeats variable.
/datum/song/proc/set_repeats(new_repeats_value)
if(playing)
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
repeat = round(new_repeats_value)
if(repeat < 0)
repeat = 0
if(repeat > max_repeats)
repeat = max_repeats
/**
* Sanitizes tempo to a value that makes sense and fits the current world.tick_lag.
@@ -332,7 +346,7 @@
* Setter for setting output volume.
*/
/datum/song/proc/set_volume(volume)
src.volume = clamp(volume, max(0, min_volume), min(100, max_volume))
src.volume = clamp(round(volume, 1), max(0, min_volume), min(100, max_volume))
update_sustain()
updateDialog()
@@ -340,7 +354,7 @@
* Setter for setting how low the volume has to get before a note is considered "dead" and dropped
*/
/datum/song/proc/set_dropoff_volume(volume)
sustain_dropoff_volume = clamp(volume, INSTRUMENT_MIN_SUSTAIN_DROPOFF, 100)
sustain_dropoff_volume = clamp(round(volume, 0.01), INSTRUMENT_MIN_SUSTAIN_DROPOFF, 100)
update_sustain()
updateDialog()
@@ -348,7 +362,7 @@
* Setter for setting exponential falloff factor.
*/
/datum/song/proc/set_exponential_drop_rate(drop)
sustain_exponential_dropoff = clamp(drop, INSTRUMENT_EXP_FALLOFF_MIN, INSTRUMENT_EXP_FALLOFF_MAX)
sustain_exponential_dropoff = clamp(round(drop, 0.00001), INSTRUMENT_EXP_FALLOFF_MIN, INSTRUMENT_EXP_FALLOFF_MAX)
update_sustain()
updateDialog()
@@ -356,7 +370,7 @@
* Setter for setting linear falloff duration.
*/
/datum/song/proc/set_linear_falloff_duration(duration)
sustain_linear_duration = clamp(duration, 0.1, INSTRUMENT_MAX_TOTAL_SUSTAIN)
sustain_linear_duration = clamp(round(duration * 10, world.tick_lag), 0.1, INSTRUMENT_MAX_TOTAL_SUSTAIN)
update_sustain()
updateDialog()
@@ -379,12 +393,12 @@
/datum/song/handheld/updateDialog(mob/user)
parent.ui_interact(user || usr)
/datum/song/handheld/should_stop_playing(mob/user)
/datum/song/handheld/should_stop_playing(atom/player)
. = ..()
if(.)
return TRUE
if(. == STOP_PLAYING || . == IGNORE_INSTRUMENT_CHECKS)
return
var/obj/item/instrument/I = parent
return I.should_stop_playing(user)
return I.should_stop_playing(player)
// subtype for stationary structures, like pianos
/datum/song/stationary
@@ -392,9 +406,9 @@
/datum/song/stationary/updateDialog(mob/user)
parent.ui_interact(user || usr)
/datum/song/stationary/should_stop_playing(mob/user)
/datum/song/stationary/should_stop_playing(atom/player)
. = ..()
if(.)
if(. == STOP_PLAYING || . == IGNORE_INSTRUMENT_CHECKS)
return TRUE
var/obj/structure/musician/M = parent
return M.should_stop_playing(user)
return M.should_stop_playing(player)
+11 -20
View File
@@ -90,15 +90,15 @@
/**
* Parses a song the user has input into lines and stores them.
*/
/datum/song/proc/ParseSong(text)
/datum/song/proc/ParseSong(new_song)
set waitfor = FALSE
//split into lines
lines = splittext(text, "\n")
lines = islist(new_song) ? new_song : splittext(new_song, "\n")
if(lines.len)
var/bpm_string = "BPM: "
if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1))
var/divisor = text2num(copytext(lines[1], length(bpm_string) + 1)) || 120 // default
tempo = sanitize_tempo(600 / round(divisor, 1))
tempo = sanitize_tempo(BPM_TO_TEMPO_SETTING(divisor))
lines.Cut(1, 2)
else
tempo = sanitize_tempo(5) // default 120 BPM
@@ -148,13 +148,7 @@
editing = text2num(href_list["edit"]) - 1
if(href_list["repeat"]) //Changing this from a toggle to a number of repeats to avoid infinite loops.
if(playing)
return //So that people cant keep adding to repeat. If the do it intentionally, it could result in the server crashing.
repeat += round(text2num(href_list["repeat"]))
if(repeat < 0)
repeat = 0
if(repeat > max_repeats)
repeat = max_repeats
set_repeats(repeat + text2num(href_list["repeat"]))
else if(href_list["tempo"])
tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
@@ -193,22 +187,22 @@
else if(href_list["setlinearfalloff"])
var/amount = input(usr, "Set linear sustain duration in seconds", "Linear Sustain Duration") as null|num
if(!isnull(amount))
set_linear_falloff_duration(round(amount * 10, world.tick_lag))
set_linear_falloff_duration(amount)
else if(href_list["setexpfalloff"])
var/amount = input(usr, "Set exponential sustain factor", "Exponential sustain factor") as null|num
if(!isnull(amount))
set_exponential_drop_rate(round(amount, 0.00001))
set_exponential_drop_rate(amount)
else if(href_list["setvolume"])
var/amount = input(usr, "Set volume", "Volume") as null|num
if(!isnull(amount))
set_volume(round(amount, 1))
set_volume(amount)
else if(href_list["setdropoffvolume"])
var/amount = input(usr, "Set dropoff threshold", "Dropoff Threshold Volume") as null|num
if(!isnull(amount))
set_dropoff_volume(round(amount, 0.01))
set_dropoff_volume(amount)
else if(href_list["switchinstrument"])
if(!length(allowed_instrument_ids))
@@ -238,12 +232,9 @@
note_shift = clamp(amount, note_shift_min, note_shift_max)
else if(href_list["setsustainmode"])
var/choice = input(usr, "Choose a sustain mode", "Sustain Mode") as null|anything in list("Linear", "Exponential")
switch(choice)
if("Linear")
sustain_mode = SUSTAIN_LINEAR
if("Exponential")
sustain_mode = SUSTAIN_EXPONENTIAL
var/choice = input(usr, "Choose a sustain mode", "Sustain Mode") as null|anything in SSinstruments.note_sustain_modes
if(choice)
sustain_mode = SSinstruments.note_sustain_modes[choice]
else if(href_list["togglesustainhold"])
full_sustain_held_note = !full_sustain_held_note
@@ -46,7 +46,7 @@
* * acc is either "b", "n", or "#"
* * oct is 1-8 (or 9 for C)
*/
/datum/song/proc/playkey_legacy(note, acc as text, oct, mob/user)
/datum/song/proc/playkey_legacy(note, acc as text, oct, atom/player)
// handle accidental -> B<>C of E<>F
if(acc == "b" && (note == 3 || note == 6)) // C or F
if(note == 3)
@@ -82,7 +82,7 @@
var/sound/music_played = sound(soundfile)
for(var/i in hearing_mobs)
var/mob/M = i
if(user && HAS_TRAIT(user, TRAIT_MUSICIAN) && isliving(M))
if(player && HAS_TRAIT(player, TRAIT_MUSICIAN) && isliving(M))
var/mob/living/L = M
L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC)
if(!(M?.client?.prefs?.toggles & SOUND_INSTRUMENTS))
@@ -42,7 +42,7 @@
* Plays a specific numerical key from our instrument to anyone who can hear us.
* Does a hearing check if enough time has passed.
*/
/datum/song/proc/playkey_synth(key, mob/user)
/datum/song/proc/playkey_synth(key, atom/player)
if(can_noteshift)
key = clamp(key + note_shift, key_min, key_max)
if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck)
@@ -62,7 +62,7 @@
last_channel_played = channel_text
for(var/i in hearing_mobs)
var/mob/M = i
if(user && HAS_TRAIT(user, TRAIT_MUSICIAN) && isliving(M))
if(player && HAS_TRAIT(player, TRAIT_MUSICIAN) && isliving(M))
var/mob/living/L = M
L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC)
if(!(M?.client?.prefs?.toggles & SOUND_INSTRUMENTS))