diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index edc28e5041b..ec8c320a1c0 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -2,305 +2,514 @@
/datum/song
var/name = "Untitled"
- var/list/lines = new()
+
+ var/sourcestring = ""
+ var/compiledstring = ""
+ var/compilesuccess = 0
+
+ //For those other infidels who uses this datum
+ //VIOLINSSS
+ var/list/lines
+
var/tempo = 5
+ var/global/gid = 1
+ var/id = 0
+ New()
+ id = gid
+ gid++;
+
+//Same text2list, but 20000 cap instead of 1000
+/proc/dd_text2list_highcap(text, separator, var/list/withinList)
+ var/textlength = length(text)
+ var/separatorlength = length(separator)
+ if(withinList && !withinList.len) withinList = null
+ var/list/textList = new()
+ var/searchPosition = 1
+ var/findPosition = 1
+ var/loops = 0
+ while(1)
+ if(loops >= 20000)
+ break
+ loops++
+
+ findPosition = findtext(text, separator, searchPosition, 0)
+ var/buggyText = copytext(text, searchPosition, findPosition)
+ if(!withinList || (buggyText in withinList)) textList += "[buggyText]"
+ if(!findPosition) return textList
+ searchPosition = findPosition + separatorlength
+ if(searchPosition > textlength)
+ textList += ""
+ return textList
+ return
+
/obj/structure/device/piano
name = "space minimoog"
icon = 'icons/obj/musician.dmi'
icon_state = "minimoog"
anchored = 1
density = 1
- var/datum/song/song
+
+ var/datum/song/currentsong = new()
+ var/list/internalsongs = new()
+
var/playing = 0
- var/help = 0
- var/edit = 1
- var/repeat = 0
+ var/repeat = 1
-/obj/structure/device/piano/New()
- if(prob(50))
- name = "space minimoog"
- desc = "This is a minimoog, like a space piano, but more spacey!"
- icon_state = "minimoog"
- else
- name = "space piano"
- desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
- icon_state = "piano"
+ var/showcontrol = 1
+ var/showeditor = 0
+ var/showhelp = 0
-/obj/structure/device/piano/proc/playnote(var/note as text)
- //world << "Note: [note]"
- var/soundfile
- /*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
- Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
- switch(note)
- if("Cn1") soundfile = 'sound/piano/Cn1.ogg'
- if("C#1") soundfile = 'sound/piano/C#1.ogg'
- if("Db1") soundfile = 'sound/piano/Db1.ogg'
- if("Dn1") soundfile = 'sound/piano/Dn1.ogg'
- if("D#1") soundfile = 'sound/piano/D#1.ogg'
- if("Eb1") soundfile = 'sound/piano/Eb1.ogg'
- if("En1") soundfile = 'sound/piano/En1.ogg'
- if("E#1") soundfile = 'sound/piano/E#1.ogg'
- if("Fb1") soundfile = 'sound/piano/Fb1.ogg'
- if("Fn1") soundfile = 'sound/piano/Fn1.ogg'
- if("F#1") soundfile = 'sound/piano/F#1.ogg'
- if("Gb1") soundfile = 'sound/piano/Gb1.ogg'
- if("Gn1") soundfile = 'sound/piano/Gn1.ogg'
- if("G#1") soundfile = 'sound/piano/G#1.ogg'
- if("Ab1") soundfile = 'sound/piano/Ab1.ogg'
- if("An1") soundfile = 'sound/piano/An1.ogg'
- if("A#1") soundfile = 'sound/piano/A#1.ogg'
- if("Bb1") soundfile = 'sound/piano/Bb1.ogg'
- if("Bn1") soundfile = 'sound/piano/Bn1.ogg'
- if("B#1") soundfile = 'sound/piano/B#1.ogg'
- if("Cb2") soundfile = 'sound/piano/Cb2.ogg'
- if("Cn2") soundfile = 'sound/piano/Cn2.ogg'
- if("C#2") soundfile = 'sound/piano/C#2.ogg'
- if("Db2") soundfile = 'sound/piano/Db2.ogg'
- if("Dn2") soundfile = 'sound/piano/Dn2.ogg'
- if("D#2") soundfile = 'sound/piano/D#2.ogg'
- if("Eb2") soundfile = 'sound/piano/Eb2.ogg'
- if("En2") soundfile = 'sound/piano/En2.ogg'
- if("E#2") soundfile = 'sound/piano/E#2.ogg'
- if("Fb2") soundfile = 'sound/piano/Fb2.ogg'
- if("Fn2") soundfile = 'sound/piano/Fn2.ogg'
- if("F#2") soundfile = 'sound/piano/F#2.ogg'
- if("Gb2") soundfile = 'sound/piano/Gb2.ogg'
- if("Gn2") soundfile = 'sound/piano/Gn2.ogg'
- if("G#2") soundfile = 'sound/piano/G#2.ogg'
- if("Ab2") soundfile = 'sound/piano/Ab2.ogg'
- if("An2") soundfile = 'sound/piano/An2.ogg'
- if("A#2") soundfile = 'sound/piano/A#2.ogg'
- if("Bb2") soundfile = 'sound/piano/Bb2.ogg'
- if("Bn2") soundfile = 'sound/piano/Bn2.ogg'
- if("B#2") soundfile = 'sound/piano/B#2.ogg'
- if("Cb3") soundfile = 'sound/piano/Cb3.ogg'
- if("Cn3") soundfile = 'sound/piano/Cn3.ogg'
- if("C#3") soundfile = 'sound/piano/C#3.ogg'
- if("Db3") soundfile = 'sound/piano/Db3.ogg'
- if("Dn3") soundfile = 'sound/piano/Dn3.ogg'
- if("D#3") soundfile = 'sound/piano/D#3.ogg'
- if("Eb3") soundfile = 'sound/piano/Eb3.ogg'
- if("En3") soundfile = 'sound/piano/En3.ogg'
- if("E#3") soundfile = 'sound/piano/E#3.ogg'
- if("Fb3") soundfile = 'sound/piano/Fb3.ogg'
- if("Fn3") soundfile = 'sound/piano/Fn3.ogg'
- if("F#3") soundfile = 'sound/piano/F#3.ogg'
- if("Gb3") soundfile = 'sound/piano/Gb3.ogg'
- if("Gn3") soundfile = 'sound/piano/Gn3.ogg'
- if("G#3") soundfile = 'sound/piano/G#3.ogg'
- if("Ab3") soundfile = 'sound/piano/Ab3.ogg'
- if("An3") soundfile = 'sound/piano/An3.ogg'
- if("A#3") soundfile = 'sound/piano/A#3.ogg'
- if("Bb3") soundfile = 'sound/piano/Bb3.ogg'
- if("Bn3") soundfile = 'sound/piano/Bn3.ogg'
- if("B#3") soundfile = 'sound/piano/B#3.ogg'
- if("Cb4") soundfile = 'sound/piano/Cb4.ogg'
- if("Cn4") soundfile = 'sound/piano/Cn4.ogg'
- if("C#4") soundfile = 'sound/piano/C#4.ogg'
- if("Db4") soundfile = 'sound/piano/Db4.ogg'
- if("Dn4") soundfile = 'sound/piano/Dn4.ogg'
- if("D#4") soundfile = 'sound/piano/D#4.ogg'
- if("Eb4") soundfile = 'sound/piano/Eb4.ogg'
- if("En4") soundfile = 'sound/piano/En4.ogg'
- if("E#4") soundfile = 'sound/piano/E#4.ogg'
- if("Fb4") soundfile = 'sound/piano/Fb4.ogg'
- if("Fn4") soundfile = 'sound/piano/Fn4.ogg'
- if("F#4") soundfile = 'sound/piano/F#4.ogg'
- if("Gb4") soundfile = 'sound/piano/Gb4.ogg'
- if("Gn4") soundfile = 'sound/piano/Gn4.ogg'
- if("G#4") soundfile = 'sound/piano/G#4.ogg'
- if("Ab4") soundfile = 'sound/piano/Ab4.ogg'
- if("An4") soundfile = 'sound/piano/An4.ogg'
- if("A#4") soundfile = 'sound/piano/A#4.ogg'
- if("Bb4") soundfile = 'sound/piano/Bb4.ogg'
- if("Bn4") soundfile = 'sound/piano/Bn4.ogg'
- if("B#4") soundfile = 'sound/piano/B#4.ogg'
- if("Cb5") soundfile = 'sound/piano/Cb5.ogg'
- if("Cn5") soundfile = 'sound/piano/Cn5.ogg'
- if("C#5") soundfile = 'sound/piano/C#5.ogg'
- if("Db5") soundfile = 'sound/piano/Db5.ogg'
- if("Dn5") soundfile = 'sound/piano/Dn5.ogg'
- if("D#5") soundfile = 'sound/piano/D#5.ogg'
- if("Eb5") soundfile = 'sound/piano/Eb5.ogg'
- if("En5") soundfile = 'sound/piano/En5.ogg'
- if("E#5") soundfile = 'sound/piano/E#5.ogg'
- if("Fb5") soundfile = 'sound/piano/Fb5.ogg'
- if("Fn5") soundfile = 'sound/piano/Fn5.ogg'
- if("F#5") soundfile = 'sound/piano/F#5.ogg'
- if("Gb5") soundfile = 'sound/piano/Gb5.ogg'
- if("Gn5") soundfile = 'sound/piano/Gn5.ogg'
- if("G#5") soundfile = 'sound/piano/G#5.ogg'
- if("Ab5") soundfile = 'sound/piano/Ab5.ogg'
- if("An5") soundfile = 'sound/piano/An5.ogg'
- if("A#5") soundfile = 'sound/piano/A#5.ogg'
- if("Bb5") soundfile = 'sound/piano/Bb5.ogg'
- if("Bn5") soundfile = 'sound/piano/Bn5.ogg'
- if("B#5") soundfile = 'sound/piano/B#5.ogg'
- if("Cb6") soundfile = 'sound/piano/Cb6.ogg'
- if("Cn6") soundfile = 'sound/piano/Cn6.ogg'
- if("C#6") soundfile = 'sound/piano/C#6.ogg'
- if("Db6") soundfile = 'sound/piano/Db6.ogg'
- if("Dn6") soundfile = 'sound/piano/Dn6.ogg'
- if("D#6") soundfile = 'sound/piano/D#6.ogg'
- if("Eb6") soundfile = 'sound/piano/Eb6.ogg'
- if("En6") soundfile = 'sound/piano/En6.ogg'
- if("E#6") soundfile = 'sound/piano/E#6.ogg'
- if("Fb6") soundfile = 'sound/piano/Fb6.ogg'
- if("Fn6") soundfile = 'sound/piano/Fn6.ogg'
- if("F#6") soundfile = 'sound/piano/F#6.ogg'
- if("Gb6") soundfile = 'sound/piano/Gb6.ogg'
- if("Gn6") soundfile = 'sound/piano/Gn6.ogg'
- if("G#6") soundfile = 'sound/piano/G#6.ogg'
- if("Ab6") soundfile = 'sound/piano/Ab6.ogg'
- if("An6") soundfile = 'sound/piano/An6.ogg'
- if("A#6") soundfile = 'sound/piano/A#6.ogg'
- if("Bb6") soundfile = 'sound/piano/Bb6.ogg'
- if("Bn6") soundfile = 'sound/piano/Bn6.ogg'
- if("B#6") soundfile = 'sound/piano/B#6.ogg'
- if("Cb7") soundfile = 'sound/piano/Cb7.ogg'
- if("Cn7") soundfile = 'sound/piano/Cn7.ogg'
- if("C#7") soundfile = 'sound/piano/C#7.ogg'
- if("Db7") soundfile = 'sound/piano/Db7.ogg'
- if("Dn7") soundfile = 'sound/piano/Dn7.ogg'
- if("D#7") soundfile = 'sound/piano/D#7.ogg'
- if("Eb7") soundfile = 'sound/piano/Eb7.ogg'
- if("En7") soundfile = 'sound/piano/En7.ogg'
- if("E#7") soundfile = 'sound/piano/E#7.ogg'
- if("Fb7") soundfile = 'sound/piano/Fb7.ogg'
- if("Fn7") soundfile = 'sound/piano/Fn7.ogg'
- if("F#7") soundfile = 'sound/piano/F#7.ogg'
- if("Gb7") soundfile = 'sound/piano/Gb7.ogg'
- if("Gn7") soundfile = 'sound/piano/Gn7.ogg'
- if("G#7") soundfile = 'sound/piano/G#7.ogg'
- if("Ab7") soundfile = 'sound/piano/Ab7.ogg'
- if("An7") soundfile = 'sound/piano/An7.ogg'
- if("A#7") soundfile = 'sound/piano/A#7.ogg'
- if("Bb7") soundfile = 'sound/piano/Bb7.ogg'
- if("Bn7") soundfile = 'sound/piano/Bn7.ogg'
- if("B#7") soundfile = 'sound/piano/B#7.ogg'
- if("Cb8") soundfile = 'sound/piano/Cb8.ogg'
- if("Cn8") soundfile = 'sound/piano/Cn8.ogg'
- if("C#8") soundfile = 'sound/piano/C#8.ogg'
- if("Db8") soundfile = 'sound/piano/Db8.ogg'
- if("Dn8") soundfile = 'sound/piano/Dn8.ogg'
- if("D#8") soundfile = 'sound/piano/D#8.ogg'
- if("Eb8") soundfile = 'sound/piano/Eb8.ogg'
- if("En8") soundfile = 'sound/piano/En8.ogg'
- if("E#8") soundfile = 'sound/piano/E#8.ogg'
- if("Fb8") soundfile = 'sound/piano/Fb8.ogg'
- if("Fn8") soundfile = 'sound/piano/Fn8.ogg'
- if("F#8") soundfile = 'sound/piano/F#8.ogg'
- if("Gb8") soundfile = 'sound/piano/Gb8.ogg'
- if("Gn8") soundfile = 'sound/piano/Gn8.ogg'
- if("G#8") soundfile = 'sound/piano/G#8.ogg'
- if("Ab8") soundfile = 'sound/piano/Ab8.ogg'
- if("An8") soundfile = 'sound/piano/An8.ogg'
- if("A#8") soundfile = 'sound/piano/A#8.ogg'
- if("Bb8") soundfile = 'sound/piano/Bb8.ogg'
- if("Bn8") soundfile = 'sound/piano/Bn8.ogg'
- if("B#8") soundfile = 'sound/piano/B#8.ogg'
- if("Cb9") soundfile = 'sound/piano/Cb9.ogg'
- if("Cn9") soundfile = 'sound/piano/Cn9.ogg'
- else return
+ var/status = "Ok"
- hearers(15, src) << sound(soundfile)
+ var/global/list/soundlist = new()
-/obj/structure/device/piano/proc/playsong()
- do
- var/cur_oct[7]
- var/cur_acc[7]
- for(var/i = 1 to 7)
- cur_oct[i] = "3"
- cur_acc[i] = "n"
+ New()
+ if(prob(50))
+ name = "space minimoog"
+ desc = "This is a minimoog, like a space piano, but more spacey!"
+ icon_state = "minimoog"
+ else
+ name = "space piano"
+ desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
+ icon_state = "piano"
- for(var/line in song.lines)
- //world << line
- for(var/beat in dd_text2list(lowertext(line), ","))
- //world << "beat: [beat]"
- var/list/notes = dd_text2list(beat, "/")
- for(var/note in dd_text2list(notes[1], "-"))
- //world << "note: [note]"
- if(!playing || !anchored)//If the piano is playing, or is loose
- playing = 0
+ //This shit is not used anywhere, but is needed to cache the sounds
+ soundlist["Cn1"] = 'sound/piano/Cn1.ogg'
+ soundlist["C#1"] = 'sound/piano/C#1.ogg'
+ //soundlist["Db1"] = 'sound/piano/Db1.ogg'
+ soundlist["Dn1"] = 'sound/piano/Dn1.ogg'
+ soundlist["D#1"] = 'sound/piano/D#1.ogg'
+ //soundlist["Eb1"] = 'sound/piano/Eb1.ogg'
+ soundlist["En1"] = 'sound/piano/En1.ogg'
+ soundlist["E#1"] = 'sound/piano/E#1.ogg'
+ //soundlist["Fb1"] = 'sound/piano/Fb1.ogg'
+ soundlist["Fn1"] = 'sound/piano/Fn1.ogg'
+ soundlist["F#1"] = 'sound/piano/F#1.ogg'
+ //soundlist["Gb1"] = 'sound/piano/Gb1.ogg'
+ soundlist["Gn1"] = 'sound/piano/Gn1.ogg'
+ soundlist["G#1"] = 'sound/piano/G#1.ogg'
+ //soundlist["Ab1"] = 'sound/piano/Ab1.ogg'
+ soundlist["An1"] = 'sound/piano/An1.ogg'
+ soundlist["A#1"] = 'sound/piano/A#1.ogg'
+ //soundlist["Bb1"] = 'sound/piano/Bb1.ogg'
+ soundlist["Bn1"] = 'sound/piano/Bn1.ogg'
+ soundlist["B#1"] = 'sound/piano/B#1.ogg'
+ soundlist["Cb2"] = 'sound/piano/Cb2.ogg'
+ soundlist["Cn2"] = 'sound/piano/Cn2.ogg'
+ soundlist["C#2"] = 'sound/piano/C#2.ogg'
+ //soundlist["Db2"] = 'sound/piano/Db2.ogg'
+ soundlist["Dn2"] = 'sound/piano/Dn2.ogg'
+ soundlist["D#2"] = 'sound/piano/D#2.ogg'
+ //soundlist["Eb2"] = 'sound/piano/Eb2.ogg'
+ soundlist["En2"] = 'sound/piano/En2.ogg'
+ soundlist["E#2"] = 'sound/piano/E#2.ogg'
+ //soundlist["Fb2"] = 'sound/piano/Fb2.ogg'
+ soundlist["Fn2"] = 'sound/piano/Fn2.ogg'
+ soundlist["F#2"] = 'sound/piano/F#2.ogg'
+ //soundlist["Gb2"] = 'sound/piano/Gb2.ogg'
+ soundlist["Gn2"] = 'sound/piano/Gn2.ogg'
+ soundlist["G#2"] = 'sound/piano/G#2.ogg'
+ //soundlist["Ab2"] = 'sound/piano/Ab2.ogg'
+ soundlist["An2"] = 'sound/piano/An2.ogg'
+ soundlist["A#2"] = 'sound/piano/A#2.ogg'
+ //soundlist["Bb2"] = 'sound/piano/Bb2.ogg'
+ soundlist["Bn2"] = 'sound/piano/Bn2.ogg'
+ soundlist["B#2"] = 'sound/piano/B#2.ogg'
+ soundlist["Cb3"] = 'sound/piano/Cb3.ogg'
+ soundlist["Cn3"] = 'sound/piano/Cn3.ogg'
+ soundlist["C#3"] = 'sound/piano/C#3.ogg'
+ //soundlist["Db3"] = 'sound/piano/Db3.ogg'
+ soundlist["Dn3"] = 'sound/piano/Dn3.ogg'
+ soundlist["D#3"] = 'sound/piano/D#3.ogg'
+ //soundlist["Eb3"] = 'sound/piano/Eb3.ogg'
+ soundlist["En3"] = 'sound/piano/En3.ogg'
+ soundlist["E#3"] = 'sound/piano/E#3.ogg'
+ //soundlist["Fb3"] = 'sound/piano/Fb3.ogg'
+ soundlist["Fn3"] = 'sound/piano/Fn3.ogg'
+ soundlist["F#3"] = 'sound/piano/F#3.ogg'
+ //soundlist["Gb3"] = 'sound/piano/Gb3.ogg'
+ soundlist["Gn3"] = 'sound/piano/Gn3.ogg'
+ soundlist["G#3"] = 'sound/piano/G#3.ogg'
+ //soundlist["Ab3"] = 'sound/piano/Ab3.ogg'
+ soundlist["An3"] = 'sound/piano/An3.ogg'
+ soundlist["A#3"] = 'sound/piano/A#3.ogg'
+ //soundlist["Bb3"] = 'sound/piano/Bb3.ogg'
+ soundlist["Bn3"] = 'sound/piano/Bn3.ogg'
+ soundlist["B#3"] = 'sound/piano/B#3.ogg'
+ soundlist["Cb4"] = 'sound/piano/Cb4.ogg'
+ soundlist["Cn4"] = 'sound/piano/Cn4.ogg'
+ soundlist["C#4"] = 'sound/piano/C#4.ogg'
+ //soundlist["Db4"] = 'sound/piano/Db4.ogg'
+ soundlist["Dn4"] = 'sound/piano/Dn4.ogg'
+ soundlist["D#4"] = 'sound/piano/D#4.ogg'
+ //soundlist["Eb4"] = 'sound/piano/Eb4.ogg'
+ soundlist["En4"] = 'sound/piano/En4.ogg'
+ soundlist["E#4"] = 'sound/piano/E#4.ogg'
+ //soundlist["Fb4"] = 'sound/piano/Fb4.ogg'
+ soundlist["Fn4"] = 'sound/piano/Fn4.ogg'
+ soundlist["F#4"] = 'sound/piano/F#4.ogg'
+ //soundlist["Gb4"] = 'sound/piano/Gb4.ogg'
+ soundlist["Gn4"] = 'sound/piano/Gn4.ogg'
+ soundlist["G#4"] = 'sound/piano/G#4.ogg'
+ //soundlist["Ab4"] = 'sound/piano/Ab4.ogg'
+ soundlist["An4"] = 'sound/piano/An4.ogg'
+ soundlist["A#4"] = 'sound/piano/A#4.ogg'
+ //soundlist["Bb4"] = 'sound/piano/Bb4.ogg'
+ soundlist["Bn4"] = 'sound/piano/Bn4.ogg'
+ soundlist["B#4"] = 'sound/piano/B#4.ogg'
+ soundlist["Cb5"] = 'sound/piano/Cb5.ogg'
+ soundlist["Cn5"] = 'sound/piano/Cn5.ogg'
+ soundlist["C#5"] = 'sound/piano/C#5.ogg'
+ //soundlist["Db5"] = 'sound/piano/Db5.ogg'
+ soundlist["Dn5"] = 'sound/piano/Dn5.ogg'
+ soundlist["D#5"] = 'sound/piano/D#5.ogg'
+ //soundlist["Eb5"] = 'sound/piano/Eb5.ogg'
+ soundlist["En5"] = 'sound/piano/En5.ogg'
+ soundlist["E#5"] = 'sound/piano/E#5.ogg'
+ //soundlist["Fb5"] = 'sound/piano/Fb5.ogg'
+ soundlist["Fn5"] = 'sound/piano/Fn5.ogg'
+ soundlist["F#5"] = 'sound/piano/F#5.ogg'
+ //soundlist["Gb5"] = 'sound/piano/Gb5.ogg'
+ soundlist["Gn5"] = 'sound/piano/Gn5.ogg'
+ soundlist["G#5"] = 'sound/piano/G#5.ogg'
+ //soundlist["Ab5"] = 'sound/piano/Ab5.ogg'
+ soundlist["An5"] = 'sound/piano/An5.ogg'
+ soundlist["A#5"] = 'sound/piano/A#5.ogg'
+ //soundlist["Bb5"] = 'sound/piano/Bb5.ogg'
+ soundlist["Bn5"] = 'sound/piano/Bn5.ogg'
+ soundlist["B#5"] = 'sound/piano/B#5.ogg'
+ soundlist["Cb6"] = 'sound/piano/Cb6.ogg'
+ soundlist["Cn6"] = 'sound/piano/Cn6.ogg'
+ soundlist["C#6"] = 'sound/piano/C#6.ogg'
+ //soundlist["Db6"] = 'sound/piano/Db6.ogg'
+ soundlist["Dn6"] = 'sound/piano/Dn6.ogg'
+ soundlist["D#6"] = 'sound/piano/D#6.ogg'
+ //soundlist["Eb6"] = 'sound/piano/Eb6.ogg'
+ soundlist["En6"] = 'sound/piano/En6.ogg'
+ soundlist["E#6"] = 'sound/piano/E#6.ogg'
+ //soundlist["Fb6"] = 'sound/piano/Fb6.ogg'
+ soundlist["Fn6"] = 'sound/piano/Fn6.ogg'
+ soundlist["F#6"] = 'sound/piano/F#6.ogg'
+ //soundlist["Gb6"] = 'sound/piano/Gb6.ogg'
+ soundlist["Gn6"] = 'sound/piano/Gn6.ogg'
+ soundlist["G#6"] = 'sound/piano/G#6.ogg'
+ //soundlist["Ab6"] = 'sound/piano/Ab6.ogg'
+ soundlist["An6"] = 'sound/piano/An6.ogg'
+ soundlist["A#6"] = 'sound/piano/A#6.ogg'
+ //soundlist["Bb6"] = 'sound/piano/Bb6.ogg'
+ soundlist["Bn6"] = 'sound/piano/Bn6.ogg'
+ soundlist["B#6"] = 'sound/piano/B#6.ogg'
+ soundlist["Cb7"] = 'sound/piano/Cb7.ogg'
+ soundlist["Cn7"] = 'sound/piano/Cn7.ogg'
+ soundlist["C#7"] = 'sound/piano/C#7.ogg'
+ //soundlist["Db7"] = 'sound/piano/Db7.ogg'
+ soundlist["Dn7"] = 'sound/piano/Dn7.ogg'
+ soundlist["D#7"] = 'sound/piano/D#7.ogg'
+ //soundlist["Eb7"] = 'sound/piano/Eb7.ogg'
+ soundlist["En7"] = 'sound/piano/En7.ogg'
+ soundlist["E#7"] = 'sound/piano/E#7.ogg'
+ //soundlist["Fb7"] = 'sound/piano/Fb7.ogg'
+ soundlist["Fn7"] = 'sound/piano/Fn7.ogg'
+ soundlist["F#7"] = 'sound/piano/F#7.ogg'
+ //soundlist["Gb7"] = 'sound/piano/Gb7.ogg'
+ soundlist["Gn7"] = 'sound/piano/Gn7.ogg'
+ soundlist["G#7"] = 'sound/piano/G#7.ogg'
+ //soundlist["Ab7"] = 'sound/piano/Ab7.ogg'
+ soundlist["An7"] = 'sound/piano/An7.ogg'
+ soundlist["A#7"] = 'sound/piano/A#7.ogg'
+ //soundlist["Bb7"] = 'sound/piano/Bb7.ogg'
+ soundlist["Bn7"] = 'sound/piano/Bn7.ogg'
+ soundlist["B#7"] = 'sound/piano/B#7.ogg'
+ soundlist["Cb8"] = 'sound/piano/Cb8.ogg'
+ soundlist["Cn8"] = 'sound/piano/Cn8.ogg'
+ soundlist["C#8"] = 'sound/piano/C#8.ogg'
+ //soundlist["Db8"] = 'sound/piano/Db8.ogg'
+ soundlist["Dn8"] = 'sound/piano/Dn8.ogg'
+ soundlist["D#8"] = 'sound/piano/D#8.ogg'
+ //soundlist["Eb8"] = 'sound/piano/Eb8.ogg'
+ soundlist["En8"] = 'sound/piano/En8.ogg'
+ soundlist["E#8"] = 'sound/piano/E#8.ogg'
+ //soundlist["Fb8"] = 'sound/piano/Fb8.ogg'
+ soundlist["Fn8"] = 'sound/piano/Fn8.ogg'
+ soundlist["F#8"] = 'sound/piano/F#8.ogg'
+ //soundlist["Gb8"] = 'sound/piano/Gb8.ogg'
+ soundlist["Gn8"] = 'sound/piano/Gn8.ogg'
+ soundlist["G#8"] = 'sound/piano/G#8.ogg'
+ //soundlist["Ab8"] = 'sound/piano/Ab8.ogg'
+ soundlist["An8"] = 'sound/piano/An8.ogg'
+ soundlist["A#8"] = 'sound/piano/A#8.ogg'
+ //soundlist["Bb8"] = 'sound/piano/Bb8.ogg'
+ soundlist["Bn8"] = 'sound/piano/Bn8.ogg'
+ soundlist["B#8"] = 'sound/piano/B#8.ogg'
+ soundlist["Cb9"] = 'sound/piano/Cb9.ogg'
+ soundlist["Cn9"] = 'sound/piano/Cn9.ogg'
+
+ proc/statusmsg( var/txt as text )
+ status = txt
+ updateUsrDialog()
+
+ proc/playsong()
+ if(currentsong.compilesuccess == 0)
+ playing = 0
+ statusmsg("Playback Error: Compile it first!")
+ return
+
+ var/list/tokens = dd_text2list_highcap(currentsong.compiledstring, "¤")
+
+ //Remove last token
+ tokens.Cut(tokens.len-1)
+
+ var/repetitions = 0
+ while(repetitions < repeat)
+ repetitions++
+
+ for(var/token in tokens)
+ if(playing == 0)
+ updateUsrDialog()
+ return
+
+ var/type = copytext(token, 1, 2)
+ switch(type)
+ if("x")
+ var/soundfile = copytext(token, 2)
+ soundfile = "sound/piano/[soundfile].ogg"
+
+ hearers(15, src) << sound(soundfile)
+ if("y")
+ sleep(text2num(copytext(token, 2)))
+
+ playing = 0
+ updateUsrDialog()
+
+
+ proc/compilesong()
+ var/compilestring = ""
+
+ var/strippedsourcestring = dd_replacetext(currentsong.sourcestring, "\n", "")
+
+
+ for(var/part in dd_text2list(strippedsourcestring, ","))
+ var/list/x = dd_text2list(part, "/")
+ var/xlen = x.len
+ var/list/tones = dd_text2list(x[1], "-")
+
+ var/tempodiv = 1
+ if(xlen==2)
+ tempodiv = text2num(x[2])
+ if(tempodiv == 0)
+ statusmsg( "Compile Error: Can't divide by 0!\nAt Part:'[part]' Tone:" )
+ return
+ else if(xlen>2)
+ statusmsg( "Compile Error: Tempo Syntax Error!\nAt Part:'[part]' Tone:" )
+ return
+
+ for(var/tone in tones)
+ var/len = lentext(tone)
+
+ if(len==0)
+ break
+ else if(len>3)
+ statusmsg( "Compile Error: Tone Syntax Error!\nAt Part:'[part]' Tone:'[tone]'" )
+ return
+
+ var/note = copytext(tone, 1, 2)
+ var/accidental = "n"
+ var/octave = "3"
+
+ var/notenum = text2ascii(note)
+ if(notenum < 65 || notenum > 71)
+ statusmsg( "Compile Error: Invalid Note Letter (A-G)\nAt Part:'[part]' Tone:'[tone]'" )
+ return
+
+ if(len>=2)
+ var/x2 = copytext(tone, 2, 3)
+ var/x2num = text2num(x2)
+ if(x2 == "b" || x2 == "n" || x2 == "#")
+ accidental = x2
+ else if(x2num >= 1 && x2num <= 9)
+ octave = x2
+ if(len==3)
+ statusmsg( "Compile Error: Tone Syntax Error! (incorrect order)\nAt Part:'[part]' Tone:'[tone]'" )
+ return
+ else
+ statusmsg( "Compile Error: Invalid Letter At Char (2)\nAt Part:'[part]' Tone:'[tone]'" )
return
- if(lentext(note) == 0)
- continue
- //world << "Parse: [copytext(note,1,2)]"
- var/cur_note = text2ascii(note) - 96
- if(cur_note < 1 || cur_note > 7)
- continue
- for(var/i=2 to lentext(note))
- var/ni = copytext(note,i,i+1)
- if(!text2num(ni))
- if(ni == "#" || ni == "b" || ni == "n")
- cur_acc[cur_note] = ni
- else if(ni == "s")
- cur_acc[cur_note] = "#" // so shift is never required
+
+ if(len==3)
+ var/x3 = copytext(tone, 3, 4)
+ var/x3num = text2num(x3)
+ if(x3num >= 1 && x3num <= 9)
+ octave = x3
else
- cur_oct[cur_note] = ni
- playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
- if(notes.len >= 2 && text2num(notes[2]))
- sleep(song.tempo / text2num(notes[2]))
- else
- sleep(song.tempo)
- if(repeat > 0)
- repeat-- //Infinite loops are baaaad.
- while(repeat > 0)
- playing = 0
- updateUsrDialog()
+ statusmsg( "Compile Error: Invalid Octave! (1-9)\nAt Part:'[part]' Tone:'[tone]'" )
+ return
+
+ //Optimize part
+
+ // Replace a flat with a sharp from the note one step darker
+ // If we're on the darkest note, we can't replace it by some darker (note != "C")
+ // C D E F G A B
+ if(accidental == "b" && note != "C")
+ accidental = "#"
+ if(note == "A")
+ note = "G"
+ else
+ note = ascii2text(text2ascii(note)-1) // Decrement by one
+
+ var/finaltone = note + accidental + octave
+ //Check if invalid note
+ if((octave == "9" && (finaltone != "Cb9" && finaltone != "Cn9")) || finaltone == "Cb1")
+ statusmsg( "Compile Error: Invalid Tone! (Check bottom of help for more info)\nAt Part:'[part]' Tone:'[tone]'" )
+ return
+
+ // TODO: OPTIMIZE SHARPS AND FLATS
+ //x indicates its a tone to be played
+ compilestring += "x" + finaltone + "¤"
+
+ //y indicates its a sleep
+ compilestring += "y[round((currentsong.tempo / tempodiv)*100)/100]¤"
+
+ currentsong.compiledstring = compilestring
+ currentsong.compilesuccess = 1
+
+ statusmsg("Compiled successfully!")
/obj/structure/device/piano/attack_hand(var/mob/user as mob)
if(!anchored)
return
usr.machine = src
- var/dat = "
Piano"
- if(song)
- if(song.lines.len > 0 && !(playing))
- dat += "Play Song
"
- dat += "Repeat Song: [repeat] times.
"
- if(playing)
- dat += "Stop Playing
"
- dat += "Repeats left: [repeat].
"
- if(!edit)
- dat += "Show Editor
"
+ /*
+ BPM TO TEMPO
+ ds = 10/(BPM/60)
+
+ TEMPO TO BPM
+ BPM = (10/ds)*60
+ */
+
+ var/calctempo = round((10/currentsong.tempo)*60)
+ var/dat = {"
+
+
+ Piano
+
+
+
+ [src.name == "space piano" ? "Space Piano" : "Space Minimoog"]
+
+
+ "}
+ if(showcontrol)
+ dat += {" Hide Controlpanel"}
else
- dat += " Hide Editor"
- dat += " Start a New Song"
- dat += " Import a Song"
- if(song)
- var/calctempo = (10/song.tempo)*60
- dat += "Tempo : -- [calctempo] BPM ++"
- var/linecount = 0
- for(var/line in song.lines)
- linecount += 1
- dat += "Line [linecount]: [line] Delete Line Modify Line"
- dat += " Add Line"
- if(help)
- dat += " Hide Help"
- dat += {"
- Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
- Every note in a chord will play together, with chord timed by the tempo.
-
- Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
- By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
- Example: C,D,E,F,G,A,B will play a C major scale.
- After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
- Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
- A pause may be denoted by an empty chord: C,E,,C,G
- To make a chord be a different time, end it with /x, where the chord length will be length
- defined by tempo / x: C,G/2,E/4
- Combined, an example is: E-E4/4,/2,G#/8,B/8,E3-E4/4
-
- Lines may be up to 50 characters.
- A song may only contain up to 50 lines.
- "}
- else
- dat += " Show Help"
- dat += ""
- user << browse(dat, "window=piano;size=700x300")
+ dat += {" Show Controlpanel"}
+
+ if(showcontrol)
+ dat += {"
+
+ [playing ? "Stop Playing" : "Play [currentsong.name]"]
+
+ New Song
+ Rename Song
+ Save [currentsong.name]
+
+ Repeat: [repeat]
+ "}
+
+ dat+={"
+
+ |
+
+
+ "}
+ if(showcontrol)
+ for(var/datum/song/isong in internalsongs)
+ dat += " [isong.name]"
+ dat += {"
+
+ |
+
+ "}
+
+ if(showeditor)
+ dat += {"
Hide Editor"}
+ else
+ dat += {"
Show Editor"}
+
+ if(showeditor)
+ dat += {"
+ Tempo:
+
---
+ [calctempo] BPM
+
+++
+
Compile
+
Edit
+
[currentsong.sourcestring]
"}
+ dat+={"
+
+ "}
+
+ if(showhelp)
+ dat += {"
Hide Help"}
+ else
+ dat += {"
Show Help"}
+
+ if(showhelp)
+ dat += {"
+ Songs are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
+ Every note in a chord will play together, with chord timed by the tempo.
+
+ Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
+ By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
+ Octave can be a number between 1 and 9
+ Example:
C,D,E,F,G,A,B will play a C major scale.
+ After a note has an accidental placed, it will be remembered:
C#,C4,Cb,C3 is
C#3,Cn4,Cb3,Cn3
+ Chords can be played simply by seperating each note with a hyphon:
A-C#,Cn-E,E-G#-Gn-B
+ A pause may be denoted by an empty chord:
C,E,,C,G
+ To make a chord be a different time, end it with /x, where the chord length will be length
+ defined by 'tempo / x':
C,G/2,E/4
+ Combined, an example is:
E-Eb4/4,/2,G#/8,B/8,E3-E4/4
+
+ A song may only contain up to 4000 letters.
+ If you're playing a small piece over and over, remember to put a pause at the end for it to sound properly.
+ Note: Due to limitations in the engine, some tones doesn't exist. These are:
+ Cb1
+ All tones in the ninth octave
except Cb9 and Cn9
+ "}
+ dat+={"
+
+
+