diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm
index dcc3c309c1e..e8481778326 100644
--- a/code/game/objects/items/devices/violin.dm
+++ b/code/game/objects/items/devices/violin.dm
@@ -19,6 +19,10 @@
song = null
..()
+/obj/item/device/violin/initialize()
+ song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
+ ..()
+
/obj/item/device/violin/attack_self(mob/user as mob)
if(!user.IsAdvancedToolUser())
user << "You don't have the dexterity to do this!"
diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index 85875833820..fb1980692d9 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -3,7 +3,7 @@
/datum/song
var/name = "Untitled"
var/list/lines = new()
- var/tempo = 5
+ var/tempo = 5 // delay between notes
var/playing = 0 // if we're playing
var/help = 0 // if help is open
@@ -16,6 +16,7 @@
var/obj/instrumentObj = null // the associated obj playing the sound
/datum/song/New(dir, obj)
+ tempo = sanitize_tempo(tempo)
instrumentDir = dir
instrumentObj = obj
@@ -63,8 +64,10 @@
/datum/song/proc/updateDialog(mob/user as mob)
instrumentObj.updateDialog() // assumes it's an object in world, override if otherwise
-/datum/song/proc/shouldStopPlaying()
+/datum/song/proc/shouldStopPlaying(mob/user)
if(instrumentObj)
+ if(!user.canUseTopic(instrumentObj))
+ return 1
return !instrumentObj.anchored // add special cases to stop in subclasses
else
return 1
@@ -84,7 +87,7 @@
var/list/notes = text2list(beat, "/")
for(var/note in text2list(notes[1], "-"))
//world << "note: [note]"
- if(!playing || shouldStopPlaying())//If the instrument is playing, or special case
+ if(!playing || shouldStopPlaying(user))//If the instrument is playing, or special case
playing = 0
return
if(lentext(note) == 0)
@@ -104,7 +107,7 @@
cur_oct[cur_note] = text2num(ni)
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
if(notes.len >= 2 && text2num(notes[2]))
- sleep(tempo / text2num(notes[2]))
+ sleep(sanitize_tempo(tempo / text2num(notes[2])))
else
sleep(tempo)
repeat--
@@ -136,10 +139,8 @@
dat += "Hide Editor"
dat += " Start a New Song"
dat += " Import a Song
"
- var/calctempo = round(600 / tempo)
- var/calcstep = tempo - 600 / (calctempo+1)
- var/calcstep_b = tempo - 600 / (calctempo+10)
- dat += "Tempo: -- [calctempo] BPM ++
"
+ var/bpm = round(600 / tempo)
+ dat += "Tempo: - [bpm] BPM +
"
var/linecount = 0
for(var/line in lines)
linecount += 1
@@ -183,7 +184,7 @@
if(href_list["newsong"])
lines = new()
- tempo = 5 // default 120 BPM
+ tempo = sanitize_tempo(5) // default 120 BPM
name = ""
else if(href_list["import"])
@@ -203,10 +204,10 @@
spawn()
lines = text2list(t, "\n")
if(copytext(lines[1],1,6) == "BPM: ")
- tempo = 600 / max(1, text2num(copytext(lines[1],6)))
+ tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
lines.Cut(1,2)
else
- tempo = 5 // default 120 BPM
+ tempo = sanitize_tempo(5) // default 120 BPM
if(lines.len > 50)
usr << "Too many lines!"
lines.Cut(51)
@@ -235,11 +236,7 @@
repeat = max_repeats
else if(href_list["tempo"])
- tempo += text2num(href_list["tempo"])
- if(tempo < 1)
- tempo = 1
- if(tempo > 600)
- tempo = 600
+ tempo = sanitize_tempo(tempo + text2num(href_list["tempo"]))
else if(href_list["play"])
playing = 1
@@ -279,6 +276,9 @@
updateDialog(usr)
return
+/datum/song/proc/sanitize_tempo(new_tempo)
+ new_tempo = abs(new_tempo)
+ return max(round(new_tempo, world.tick_lag), world.tick_lag)
// subclass for handheld instruments, like violin
/datum/song/handheld
@@ -322,6 +322,10 @@
song = null
..()
+/obj/structure/piano/initialize()
+ song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
+ ..()
+
/obj/structure/piano/attack_hand(mob/user as mob)
if(!user.IsAdvancedToolUser())
user << "You don't have the dexterity to do this!"