Instruments can be synced by setting an ID in their UI (#92413)

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
MrMelbert
2025-08-14 03:04:43 +02:00
committed by GitHub
co-authored by Ghom
parent 889092bff6
commit 76934c9f28
5 changed files with 104 additions and 17 deletions
+8 -5
View File
@@ -23,19 +23,22 @@
QDEL_NULL(song)
return ..()
/obj/item/instrument/proc/should_stop_playing(atom/music_player)
/obj/item/instrument/proc/can_play(atom/music_player)
if(!ismob(music_player))
return STOP_PLAYING
return FALSE
var/mob/user = music_player
if(user.incapacitated || !((loc == user) || (isturf(loc) && Adjacent(user)))) // sorry, no more TK playing.
return STOP_PLAYING
if(user.incapacitated)
return FALSE
if(!Adjacent(user))
return FALSE
return TRUE
/obj/item/instrument/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!"))
return BRUTELOSS
/obj/item/instrument/ui_interact(mob/user, datum/tgui/ui)
song.ui_interact(user)
return song.ui_interact(user)
/obj/item/instrument/violin
name = "space violin"
+46 -2
View File
@@ -8,6 +8,9 @@
/// Name of the song
var/name = "Untitled"
/// ID for syncing songs together
var/id = ""
/// The atom we're attached to/playing from
var/atom/parent
@@ -212,6 +215,32 @@
current_chord = 1
music_player = user
START_PROCESSING(SSinstruments, src)
if(id)
sync_play()
/**
* Attempts to find other instruments with the same ID and syncs them to our song.
*/
/datum/song/proc/sync_play()
for(var/datum/song/other_instrument as anything in SSinstruments.songs)
if(other_instrument == src || other_instrument.id != id)
continue
if(other_instrument.playing)
continue
var/atom/other_player = other_instrument.find_sync_player()
if(isnull(other_player) || !(other_player in view(parent)))
continue
// copies the main song info to target songs
other_instrument.lines = lines.Copy()
other_instrument.max_repeats = max_repeats
other_instrument.tempo = tempo
other_instrument.start_playing(other_player)
/**
* Finds a player which would reasonably be able to play this song.
*/
/datum/song/proc/find_sync_player()
return null
/**
* Stops playing, terminating all sounds if in synthesized mode. Clears hearing_mobs.
@@ -388,7 +417,14 @@
if(. == STOP_PLAYING || . == IGNORE_INSTRUMENT_CHECKS)
return
var/obj/item/instrument/I = parent
return I.should_stop_playing(player)
return I.can_play(player) ? NONE : STOP_PLAYING
/datum/song/handheld/find_sync_player()
var/obj/item/instrument/instrument = parent
var/mob/living/player = get(parent, /mob/living)
if(instrument.can_play(player))
return player
return null
// subtype for stationary structures, like pianos
/datum/song/stationary
@@ -398,4 +434,12 @@
if(. == STOP_PLAYING || . == IGNORE_INSTRUMENT_CHECKS)
return TRUE
var/obj/structure/musician/M = parent
return M.should_stop_playing(player)
return M.can_play(player) ? NONE : STOP_PLAYING
/datum/song/stationary/find_sync_player()
var/obj/structure/musician/piano = parent
for(var/mob/living/player in view(parent, 1))
if(piano.can_play(player))
return player
return null
+6
View File
@@ -9,6 +9,7 @@
/datum/song/ui_data(mob/user)
var/list/data = ..()
data["id"] = id
data["using_instrument"] = using_instrument?.name || "No instrument loaded!"
data["note_shift"] = note_shift
data["octaves"] = round(note_shift / 12, 0.01)
@@ -71,6 +72,11 @@
else
stop_playing()
return TRUE
if("set_instrument_id")
var/new_id = reject_bad_name(LOWER_TEXT(params["id"]), max_length = 20, allow_numbers = TRUE, cap_after_symbols = FALSE)
if(new_id)
id = new_id
return TRUE
if("change_instrument")
var/new_instrument = params["new_instrument"]
//only one instrument, so no need to bother changing it.
+16 -9
View File
@@ -3,9 +3,12 @@
desc = "Something broke, contact coderbus."
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT | INTERACT_ATOM_REQUIRES_DEXTERITY
integrity_failure = 0.25
/// IF FALSE music stops when the piano is unanchored.
var/can_play_unanchored = FALSE
/// Our allowed list of instrument ids. This is nulled on initialize.
var/list/allowed_instrument_ids = list("r3grand","r3harpsi","crharpsi","crgrand1","crbright1", "crichugan", "crihamgan","piano")
var/datum/song/song
/// Our song datum.
var/datum/song/stationary/song
/obj/structure/musician/Initialize(mapload)
. = ..()
@@ -16,18 +19,22 @@
QDEL_NULL(song)
return ..()
/obj/structure/musician/proc/should_stop_playing(atom/music_player)
if(!(anchored || can_play_unanchored) || !ismob(music_player))
return STOP_PLAYING
/obj/structure/musician/proc/can_play(atom/music_player)
if(!anchored && !can_play_unanchored)
return FALSE
if(!ismob(music_player))
return FALSE
var/mob/user = music_player
if(!ISADVANCEDTOOLUSER(user))
to_chat(src, span_warning("You don't have the dexterity to do this!"))
return STOP_PLAYING
return FALSE
if(user.incapacitated)
return FALSE
if(!Adjacent(user))
return FALSE
return TRUE
/obj/structure/musician/ui_interact(mob/user)
. = ..()
song.ui_interact(user)
return song.ui_interact(user)
/obj/structure/musician/wrench_act(mob/living/user, obj/item/tool)
. = ..()