mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 03:26:31 +01:00
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:
@@ -23,8 +23,12 @@
|
||||
QDEL_NULL(song)
|
||||
return ..()
|
||||
|
||||
/obj/item/instrument/proc/should_stop_playing(mob/user)
|
||||
return user.incapacitated() || !((loc == user) || (isturf(loc) && Adjacent(user))) // sorry, no more TK playing.
|
||||
/obj/item/instrument/proc/should_stop_playing(atom/music_player)
|
||||
if(!ismob(music_player))
|
||||
return STOP_PLAYING
|
||||
var/mob/user = music_player
|
||||
if(user.incapacitated() || !((loc == user) || (isturf(loc) && Adjacent(user)))) // sorry, no more TK playing.
|
||||
return STOP_PLAYING
|
||||
|
||||
/obj/item/instrument/suicide_act(mob/user)
|
||||
user.visible_message(span_suicide("[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
@@ -61,63 +65,6 @@
|
||||
inhand_icon_state = "golden_violin"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/instrument/piano_synth
|
||||
name = "synthesizer"
|
||||
desc = "An advanced electronic synthesizer that can be used as various instruments."
|
||||
icon_state = "synth"
|
||||
inhand_icon_state = "synth"
|
||||
allowed_instrument_ids = "piano"
|
||||
|
||||
/obj/item/instrument/piano_synth/Initialize(mapload)
|
||||
. = ..()
|
||||
song.allowed_instrument_ids = SSinstruments.synthesizer_instrument_ids
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones
|
||||
name = "headphones"
|
||||
desc = "Unce unce unce unce. Boop!"
|
||||
icon = 'icons/obj/clothing/accessories.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/clothing_righthand.dmi'
|
||||
icon_state = "headphones"
|
||||
inhand_icon_state = "headphones"
|
||||
slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD
|
||||
force = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
custom_price = PAYCHECK_ASSISTANT * 2.5
|
||||
instrument_range = 1
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
RegisterSignal(src, COMSIG_SONG_START, .proc/start_playing)
|
||||
RegisterSignal(src, COMSIG_SONG_END, .proc/stop_playing)
|
||||
|
||||
/**
|
||||
* Called by a component signal when our song starts playing.
|
||||
*/
|
||||
/obj/item/instrument/piano_synth/headphones/proc/start_playing()
|
||||
SIGNAL_HANDLER
|
||||
icon_state = "[initial(icon_state)]_on"
|
||||
update_appearance()
|
||||
|
||||
/**
|
||||
* Called by a component signal when our song stops playing.
|
||||
*/
|
||||
/obj/item/instrument/piano_synth/headphones/proc/stop_playing()
|
||||
SIGNAL_HANDLER
|
||||
icon_state = "[initial(icon_state)]"
|
||||
update_appearance()
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones/spacepods
|
||||
name = "\improper Nanotrasen space pods"
|
||||
desc = "Flex your money, AND ignore what everyone else says, all at once!"
|
||||
icon_state = "spacepods"
|
||||
inhand_icon_state = "spacepods"
|
||||
slot_flags = ITEM_SLOT_EARS
|
||||
strip_delay = 100 //air pods don't fall out
|
||||
instrument_range = 0 //you're paying for quality here
|
||||
custom_premium_price = PAYCHECK_ASSISTANT * 36 //Save up 5 shifts worth of pay just to lose it down a drainpipe on the sidewalk
|
||||
|
||||
/obj/item/instrument/banjo
|
||||
name = "banjo"
|
||||
desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings."
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
|
||||
/obj/item/instrument/piano_synth
|
||||
name = "synthesizer"
|
||||
desc = "An advanced electronic synthesizer that can be used as various instruments."
|
||||
icon_state = "synth"
|
||||
inhand_icon_state = "synth"
|
||||
allowed_instrument_ids = "piano"
|
||||
var/circuit_type = /obj/item/circuit_component/synth
|
||||
var/shell_capacity = SHELL_CAPACITY_SMALL
|
||||
|
||||
/obj/item/instrument/piano_synth/Initialize(mapload)
|
||||
. = ..()
|
||||
song.allowed_instrument_ids = SSinstruments.synthesizer_instrument_ids
|
||||
AddComponent(/datum/component/shell, list(new circuit_type), shell_capacity)
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones
|
||||
name = "headphones"
|
||||
desc = "Unce unce unce unce. Boop!"
|
||||
icon = 'icons/obj/clothing/accessories.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/clothing_righthand.dmi'
|
||||
icon_state = "headphones"
|
||||
inhand_icon_state = "headphones"
|
||||
slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD
|
||||
force = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
custom_price = PAYCHECK_ASSISTANT * 2.5
|
||||
instrument_range = 1
|
||||
circuit_type = /obj/item/circuit_component/synth/headphones
|
||||
shell_capacity = SHELL_CAPACITY_TINY
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
RegisterSignal(src, COMSIG_SONG_START, .proc/start_playing)
|
||||
RegisterSignal(src, COMSIG_SONG_END, .proc/stop_playing)
|
||||
|
||||
/**
|
||||
* Called by a component signal when our song starts playing.
|
||||
*/
|
||||
/obj/item/instrument/piano_synth/headphones/proc/start_playing()
|
||||
SIGNAL_HANDLER
|
||||
icon_state = "[initial(icon_state)]_on"
|
||||
update_appearance()
|
||||
|
||||
/**
|
||||
* Called by a component signal when our song stops playing.
|
||||
*/
|
||||
/obj/item/instrument/piano_synth/headphones/proc/stop_playing()
|
||||
SIGNAL_HANDLER
|
||||
icon_state = "[initial(icon_state)]"
|
||||
update_appearance()
|
||||
|
||||
/obj/item/instrument/piano_synth/headphones/spacepods
|
||||
name = "\improper Nanotrasen space pods"
|
||||
desc = "Flex your money, AND ignore what everyone else says, all at once!"
|
||||
icon_state = "spacepods"
|
||||
inhand_icon_state = "spacepods"
|
||||
slot_flags = ITEM_SLOT_EARS
|
||||
strip_delay = 100 //air pods don't fall out
|
||||
instrument_range = 0 //you're paying for quality here
|
||||
custom_premium_price = PAYCHECK_ASSISTANT * 36 //Save up 5 shifts worth of pay just to lose it down a drainpipe on the sidewalk
|
||||
|
||||
/obj/item/circuit_component/synth
|
||||
display_name = "Synthesizer"
|
||||
desc = "An advanced electronic synthesizer that can be used as various instruments."
|
||||
|
||||
/// The song, represented in latin alphabet A to G, that'll be played when play is triggered.
|
||||
var/datum/port/input/song
|
||||
/// Starts playing the song.
|
||||
var/datum/port/input/play
|
||||
/// Stop playing the song.
|
||||
var/datum/port/input/stop
|
||||
/// How many times the song will be played.
|
||||
var/datum/port/input/repetitions
|
||||
/// The beats per minute of the song
|
||||
var/datum/port/input/beats_per_min
|
||||
/// The volume of the song
|
||||
var/datum/port/input/volume
|
||||
/// Notes with volume below this threshold will be dead
|
||||
var/datum/port/input/volume_dropoff
|
||||
/// Note shift
|
||||
var/datum/port/input/note_shift
|
||||
/// Sustain Mode
|
||||
var/datum/port/input/sustain_mode
|
||||
/// The value of the above
|
||||
var/datum/port/input/sustain_value
|
||||
/// If set the last held note will decay
|
||||
var/datum/port/input/note_decay
|
||||
/// The list of instruments which sound can be synthesized.
|
||||
var/datum/port/input/option/selected_instrument
|
||||
/// Whether a song is currently playing
|
||||
var/datum/port/output/is_playing
|
||||
/// Sent when a new song has started playing
|
||||
var/datum/port/output/started_playing
|
||||
/// Sent when a song has finished playing
|
||||
var/datum/port/output/stopped_playing
|
||||
|
||||
/// The synthesizer this circut is attached to.
|
||||
var/obj/item/instrument/piano_synth/synth
|
||||
|
||||
/obj/item/circuit_component/synth/populate_ports()
|
||||
song = add_input_port("Song", PORT_TYPE_LIST(PORT_TYPE_STRING), trigger = .proc/import_song)
|
||||
play = add_input_port("Play", PORT_TYPE_SIGNAL, trigger = .proc/start_playing)
|
||||
stop = add_input_port("Stop", PORT_TYPE_SIGNAL, trigger = .proc/stop_playing)
|
||||
repetitions = add_input_port("Repetitions", PORT_TYPE_NUMBER, trigger = .proc/set_repetitions)
|
||||
beats_per_min = add_input_port("BPM", PORT_TYPE_NUMBER, trigger = .proc/set_bpm)
|
||||
selected_instrument = add_option_port("Selected Instrument", SSinstruments.synthesizer_instrument_ids, trigger = .proc/set_instrument)
|
||||
volume = add_input_port("Volume", PORT_TYPE_NUMBER, trigger = .proc/set_volume)
|
||||
volume_dropoff = add_input_port("Volume Dropoff Threshold", PORT_TYPE_NUMBER, trigger = .proc/set_dropoff)
|
||||
note_shift = add_input_port("Note Shift", PORT_TYPE_NUMBER, trigger = .proc/set_note_shift)
|
||||
sustain_mode = add_option_port("Note Sustain Mode", SSinstruments.note_sustain_modes, trigger = .proc/set_sustain_mode)
|
||||
sustain_value = add_input_port("Note Sustain Value", PORT_TYPE_NUMBER, trigger = .proc/set_sustain_value)
|
||||
note_decay = add_input_port("Held Note Decay", PORT_TYPE_NUMBER, trigger = .proc/set_sustain_decay)
|
||||
|
||||
is_playing = add_output_port("Currently Playing", PORT_TYPE_NUMBER)
|
||||
started_playing = add_output_port("Started Playing", PORT_TYPE_SIGNAL)
|
||||
stopped_playing = add_output_port("Stopped Playing", PORT_TYPE_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/synth/register_shell(atom/movable/shell)
|
||||
. = ..()
|
||||
synth = shell
|
||||
RegisterSignal(synth, COMSIG_SONG_START, .proc/on_song_start)
|
||||
RegisterSignal(synth, COMSIG_SONG_END, .proc/on_song_end)
|
||||
RegisterSignal(synth, COMSIG_SONG_SHOULD_STOP_PLAYING, .proc/continue_if_autoplaying)
|
||||
|
||||
/obj/item/circuit_component/synth/unregister_shell(atom/movable/shell)
|
||||
if(synth.song.music_player == src)
|
||||
synth.song.stop_playing()
|
||||
synth = null
|
||||
UnregisterSignal(synth, list(COMSIG_SONG_START, COMSIG_SONG_END, COMSIG_SONG_SHOULD_STOP_PLAYING))
|
||||
return ..()
|
||||
|
||||
/obj/item/circuit_component/synth/proc/start_playing(datum/port/input/port)
|
||||
synth.song.start_playing(src)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/on_song_start()
|
||||
SIGNAL_HANDLER
|
||||
is_playing.set_output(TRUE)
|
||||
started_playing.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/continue_if_autoplaying(datum/source, atom/music_player)
|
||||
SIGNAL_HANDLER
|
||||
if(music_player == src)
|
||||
return IGNORE_INSTRUMENT_CHECKS
|
||||
|
||||
/obj/item/circuit_component/synth/proc/stop_playing(datum/port/input/port)
|
||||
synth.song.stop_playing()
|
||||
|
||||
/obj/item/circuit_component/synth/proc/on_song_end()
|
||||
SIGNAL_HANDLER
|
||||
is_playing.set_output(FALSE)
|
||||
stopped_playing.set_output(COMPONENT_SIGNAL)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/import_song()
|
||||
synth.song.ParseSong(song.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_repetitions()
|
||||
synth.song.set_repeats(repetitions.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_bpm()
|
||||
synth.song.sanitize_tempo(BPM_TO_TEMPO_SETTING(beats_per_min.value))
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_instrument()
|
||||
synth.song.set_instrument(selected_instrument.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_volume()
|
||||
synth.song.set_volume(volume.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_dropoff()
|
||||
synth.song.set_dropoff_volume(volume_dropoff.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_note_shift()
|
||||
synth.song.note_shift = clamp(note_shift.value, synth.song.note_shift_min, synth.song.note_shift_max)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_sustain_mode()
|
||||
synth.song.sustain_mode = SSinstruments.note_sustain_modes[sustain_mode.value]
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_sustain_value()
|
||||
switch(synth.song.sustain_mode)
|
||||
if(SUSTAIN_LINEAR)
|
||||
synth.song.set_linear_falloff_duration(sustain_value.value)
|
||||
if(SUSTAIN_EXPONENTIAL)
|
||||
synth.song.set_exponential_drop_rate(sustain_value.value)
|
||||
|
||||
/obj/item/circuit_component/synth/proc/set_sustain_decay()
|
||||
synth.song.full_sustain_held_note = !!synth.song.full_sustain_held_note
|
||||
|
||||
/obj/item/circuit_component/synth/headphones
|
||||
display_name = "Headphones"
|
||||
desc = "An advanced electronic device that plays music into your ears."
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
QDEL_NULL(song)
|
||||
return ..()
|
||||
|
||||
/obj/structure/musician/proc/should_stop_playing(mob/user)
|
||||
if(!(anchored || can_play_unanchored))
|
||||
return TRUE
|
||||
if(!user)
|
||||
return FALSE
|
||||
return !user.canUseTopic(src, FALSE, TRUE, FALSE, FALSE) //can play with TK and while resting because fun.
|
||||
/obj/structure/musician/proc/should_stop_playing(atom/music_player)
|
||||
if(!(anchored || can_play_unanchored) || !ismob(music_player))
|
||||
return STOP_PLAYING
|
||||
var/mob/user = music_player
|
||||
if(!user.canUseTopic(src, FALSE, TRUE, FALSE, FALSE)) //can play with TK and while resting because fun.
|
||||
return STOP_PLAYING
|
||||
|
||||
/obj/structure/musician/ui_interact(mob/user)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user