From fa7a89b25b18a330b97ad7e99532ccacfbe7a9d4 Mon Sep 17 00:00:00 2001 From: MrPerson Date: Fri, 20 Mar 2015 20:40:36 -0700 Subject: [PATCH] Instrument tweaks The piano will stop playing once you walk away from it or get stunned. The song BPM of the piano and violin will generally speaking be wrong because of discrepancies between the sleep between notes and world.tick_lag. I've solved this by locking BPM to points where the stated BPM will actually be the case because tempo == world.tick_lag. Example Current: song @ 5 tempo - 120 BPM: c, c/2, c -> note -> sleep(5) -> 6 ticks (5.4 time passes) -> note -> sleep(2.5) -> 3 ticks (2.7 time passes) -> note. With this PR: song @ 5.4 tempo - 111 BPM: c, c/2, c -> note -> sleep(5.4) -> 6 ticks (5.4 time passes) -> note/2 -> sleep(2.7) -> 3 ticks (2.7 time passes) -> note. I was hoping this would make the damn things sound better but then I realized it wasn't actually messing anything up. Oh well. --- code/game/objects/items/devices/violin.dm | 4 +++ code/game/objects/structures/musician.dm | 36 +++++++++++++---------- 2 files changed, 24 insertions(+), 16 deletions(-) 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!"