Merge remote-tracking branch 'remotes/git-svn' into bs12_with_tgport

Conflicts:
	code/controllers/configuration.dm
	code/game/atoms.dm
	code/game/gamemodes/changeling/modularchangling.dm
	code/game/gamemodes/factions.dm
	code/game/objects/items/devices/uplinks.dm
	code/game/verbs/ooc.dm
	code/game/verbs/who.dm
	code/modules/admin/admin.dm
	code/modules/admin/admin_verbs.dm
	code/modules/admin/player_panel.dm
	code/modules/admin/verbs/adminpm.dm
	code/modules/admin/verbs/getlogs.dm
	code/modules/client/client defines.dm
	code/modules/client/client procs.dm
	code/modules/mob/living/login.dm
	code/modules/mob/new_player/preferences_setup.dm
	code/modules/paperwork/paper.dm
	config/config.txt
	html/changelog.html
	icons/mob/human.dmi
	icons/mob/human_face.dmi

Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
Cael_Aislinn
2012-09-26 18:49:18 +10:00
303 changed files with 14307 additions and 12887 deletions
@@ -34,6 +34,7 @@
if(!broken)
if(prob(50/severity))
src.locked = !src.locked
src.update_icon()
if(prob(20/severity) && !opened)
if(!locked)
open()
+579 -355
View File
@@ -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 = "<HEAD><TITLE>Piano</TITLE></HEAD><BODY>"
if(song)
if(song.lines.len > 0 && !(playing))
dat += "<A href='?src=\ref[src];play=1'>Play Song</A><BR><BR>"
dat += "<A href='?src=\ref[src];repeat=1'>Repeat Song: [repeat] times.</A><BR><BR>"
if(playing)
dat += "<A href='?src=\ref[src];stop=1'>Stop Playing</A><BR>"
dat += "Repeats left: [repeat].<BR><BR>"
if(!edit)
dat += "<A href='?src=\ref[src];edit=2'>Show Editor</A><BR><BR>"
/*
BPM TO TEMPO
ds = 10/(BPM/60)
TEMPO TO BPM
BPM = (10/ds)*60
*/
var/calctempo = round((10/currentsong.tempo)*60)
var/dat = {"
<html>
<head>
<title>Piano</title>
<style type="text/css">
div.content
{
background-color:#AAAAAA;
width:100%;
padding:10;
margin:5;
}
table.noborders {
border-width: 0px;
border-spacing: 0px;
border-style: none;
border-collapse: collapse;
}
table.noborders th {
border-width: 0px;
padding: 0px;
border-style: inset;
}
table.noborders td {
border-width: 0px;
padding: 0px;
border-style: inset;
}
</style>
</head>
<body>
<center><h1>[src.name == "space piano" ? "Space Piano" : "Space Minimoog"]</h1></center>
<table class="noborders" width="100%"><tr>
<td>
<div bgcolor="#AAAAAA" class="content" style="height:100%;">"}
if(showcontrol)
dat += {" <a href='?src=\ref[src];controltoggle=1'>Hide Controlpanel</a><br>"}
else
dat += "<A href='?src=\ref[src];edit=1'>Hide Editor</A><BR>"
dat += "<A href='?src=\ref[src];newsong=1'>Start a New Song</A><BR>"
dat += "<A href='?src=\ref[src];import=1'>Import a Song</A><BR><BR>"
if(song)
var/calctempo = (10/song.tempo)*60
dat += "Tempo : <A href='?src=\ref[src];tempo=10'>-</A><A href='?src=\ref[src];tempo=1'>-</A> [calctempo] BPM <A href='?src=\ref[src];tempo=-1'>+</A><A href='?src=\ref[src];tempo=-10'>+</A><BR><BR>"
var/linecount = 0
for(var/line in song.lines)
linecount += 1
dat += "Line [linecount]: [line] <A href='?src=\ref[src];deleteline=[linecount]'>Delete Line</A> <A href='?src=\ref[src];modifyline=[linecount]'>Modify Line</A><BR>"
dat += "<A href='?src=\ref[src];newline=1'>Add Line</A><BR><BR>"
if(help)
dat += "<A href='?src=\ref[src];help=1'>Hide Help</A><BR>"
dat += {"
Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).<br>
Every note in a chord will play together, with chord timed by the tempo.<br>
<br>
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is C3,C4,C4,C3</i><br>
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
To make a chord be a different time, end it with /x, where the chord length will be length<br>
defined by tempo / x: <i>C,G/2,E/4</i><br>
Combined, an example is: <i>E-E4/4,/2,G#/8,B/8,E3-E4/4</i>
<br>
Lines may be up to 50 characters.<br>
A song may only contain up to 50 lines.<br>
"}
else
dat += "<A href='?src=\ref[src];help=2'>Show Help</A><BR>"
dat += "</BODY></HTML>"
user << browse(dat, "window=piano;size=700x300")
dat += {" <a href='?src=\ref[src];controltoggle=1'>Show Controlpanel</a><br>"}
if(showcontrol)
dat += {"
<a href='?src=\ref[src];toggleplay=1'>[playing ? "Stop Playing" : "Play [currentsong.name]"]</a><br>
<br>
<a href='?src=\ref[src];newsong=1'>New Song</a><br>
<a href='?src=\ref[src];name=1'>Rename Song</a><br>
<a href='?src=\ref[src];savesong=1'>Save [currentsong.name]</a><br>
<br>
<a href='?src=\ref[src];repeat=1'>Repeat: [repeat]</a><br>
<div style="width:auto; height:auto; background-color:#888888;" bgcolor="#888888">
<pre>Status:<br>[status]</pre>
</div>"}
dat+={"
</div>
</td>
<td width="150px">
<div bgcolor="#AAAAAA" class="content" style="width:150px; height:100%; margin-left:0;">
"}
if(showcontrol)
for(var/datum/song/isong in internalsongs)
dat += "<a href='?src=\ref[src];setsong=[isong.id]'>[isong.name]</a><br>"
dat += {"
</div>
</td>
</tr></table>
<div bgcolor="#AAAAAA" class="content" style="margin-top:0;">"}
if(showeditor)
dat += {"<a href='?src=\ref[src];editortoggle=1'>Hide Editor</a><br>"}
else
dat += {"<a href='?src=\ref[src];editortoggle=1'>Show Editor</a><br>"}
if(showeditor)
dat += {"
Tempo:
<a href='?src=\ref[src];tempo=-3'>-</a><a href='?src=\ref[src];tempo=-2'>-</a><a href='?src=\ref[src];tempo=-1'>-</a>
[calctempo] BPM
<a href='?src=\ref[src];tempo=1'>+</a><a href='?src=\ref[src];tempo=2'>+</a><a href='?src=\ref[src];tempo=3'>+</a><br>
<a href='?src=\ref[src];compile=1'>Compile</a>
<a href='?src=\ref[src];edit=1'>Edit</a>
<div bgcolor="#888888" style="padding-left:5px; margin-top:5px; background-color:#888888"><pre>[currentsong.sourcestring]</pre></div>"}
dat+={"
</div>
<div bgcolor="#AAAAAA" class="content">"}
if(showhelp)
dat += {"<a href='?src=\ref[src];helptoggle=1'>Hide Help</a><br>"}
else
dat += {"<a href='?src=\ref[src];helptoggle=1'>Show Help</a><br>"}
if(showhelp)
dat += {"
Songs are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).<br>
Every note in a chord will play together, with chord timed by the tempo.<br>
<br>
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
Octave can be a number between 1 and 9<br>
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
After a note has an accidental placed, it will be remembered: <i>C#,C4,Cb,C3</i> is <i>C#3,Cn4,Cb3,Cn3</i><br>
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#-Gn-B</i><br>
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
To make a chord be a different time, end it with /x, where the chord length will be length<br>
defined by 'tempo / x': <i>C,G/2,E/4</i><br>
Combined, an example is: <i>E-Eb4/4,/2,G#/8,B/8,E3-E4/4</i><br>
<br>
A song may only contain up to 4000 letters.<br>
If you're playing a small piece over and over, remember to put a pause at the end for it to sound properly.<br<
<br>
Note: Due to limitations in the engine, some tones doesn't exist. These are:<br>
Cb1<br>
All tones in the ninth octave <b>except Cb9 and Cn9</b>
"}
dat+={"
</div>
</body>
</html>"}
user << browse(dat, "window=piano;size=700x500")
onclose(user, "piano")
/obj/structure/device/piano/Topic(href, href_list)
@@ -310,98 +519,113 @@
onclose(usr, "piano")
return
if(href_list["newsong"])
song = new()
else if(song)
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.
var/tempnum = input("How many times do you want to repeat this piece? (max:10)") as num|null
if(tempnum > 10)
tempnum = 10
if(tempnum < 0)
tempnum = 0
repeat = round(tempnum)
if(href_list["toggleplay"])
if(playing)
playing = 0
else
playing = 1
spawn() playsong()
updateUsrDialog()
else if(href_list["controltoggle"])
showcontrol = 1-showcontrol
updateUsrDialog()
else if(href_list["editortoggle"])
showeditor = 1-showeditor
updateUsrDialog()
else if(href_list["helptoggle"])
showhelp = 1-showhelp
updateUsrDialog()
else if(href_list["name"])
var/input = html_encode(input(usr, "", "Rename", currentsong.name) as text|null)
currentsong.name = copytext(input,1,30)
updateUsrDialog()
else if(href_list["savesong"])
//Check if the song already exists in the internal
var/foundsong = 0
for(var/datum/song/isong in internalsongs)
if(isong.id == currentsong.id)
foundsong = 1
isong.compiledstring = currentsong.compiledstring
isong.sourcestring = currentsong.sourcestring
isong.name = currentsong.name
break
//If not, add it as new
if(!foundsong)
internalsongs += currentsong
updateUsrDialog()
if(playing)
if(href_list["newsong"]||href_list["setsong"]||href_list["tempo"]||href_list["compile"]||href_list["edit"]||href_list["repeat"])
statusmsg("Playback Error: Stop the song first!")
else
if(href_list["newsong"])
var/answer = alert(usr, "This will overwrite any current song you're editing!", "Are you sure?", "Yes", "No")
if(answer == "No")
return
currentsong = new()
updateUsrDialog()
else if(href_list["setsong"])
var/matchid = text2num(href_list["setsong"])
for(var/datum/song/isong in internalsongs)
if(isong.id == matchid)
currentsong = isong
break
updateUsrDialog()
else if(href_list["tempo"])
song.tempo += round(text2num(href_list["tempo"]))
if(song.tempo < 1)
song.tempo = 1
var/tempoinc = text2num(href_list["tempo"])
else if(href_list["play"])
if(song)
playing = 1
spawn() playsong()
currentsong.tempo += tempoinc*-1
if(currentsong.tempo<1)
currentsong.tempo = 1
currentsong.compilesuccess = 0
else if(href_list["newline"])
var/newline = html_encode(input("Enter your line: ", "Piano") as text|null)
if(!newline)
return
if(song.lines.len > 50)
return
if(lentext(newline) > 50)
newline = copytext(newline, 1, 50)
song.lines.Add(newline)
updateUsrDialog()
else if(href_list["deleteline"])
var/num = round(text2num(href_list["deleteline"]))
if(num > song.lines.len || num < 1)
return
song.lines.Cut(num, num+1)
else if(href_list["compile"])
else if(href_list["modifyline"])
var/num = round(text2num(href_list["modifyline"]),1)
var/content = html_encode(input("Enter your line: ", "Piano", song.lines[num]) as text|null)
if(!content)
return
if(lentext(content) > 50)
content = copytext(content, 1, 50)
if(num > song.lines.len || num < 1)
return
song.lines[num] = content
compilesong()
else if(href_list["stop"])
playing = 0
else if(href_list["help"])
help = text2num(href_list["help"]) - 1
updateUsrDialog()
else if(href_list["edit"])
edit = text2num(href_list["edit"]) - 1
else if(href_list["import"])
var/t = ""
do
t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", src.name), t) as message)
if (!in_range(src, usr))
return
var/input = html_encode(input(usr, "", "Edit", currentsong.sourcestring) as message|null)
if(lentext(t) >= 3072)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(lentext(t) > 3072)
input = dd_replacetext(input, " ", "")
input = dd_replacetext(input, "\t", "")
//split into lines
spawn()
var/list/lines = dd_text2list(t, "\n")
var/tempo = 5
if(copytext(lines[1],1,6) == "BPM: ")
tempo = 600 / text2num(copytext(lines[1],6))
lines.Cut(1,2)
if(lines.len > 50)
usr << "Too many lines!"
lines.Cut(51)
var/linenum = 1
for(var/l in lines)
if(lentext(l) > 50)
usr << "Line [linenum] too long!"
lines.Remove(l)
else
linenum++
song = new()
song.lines = lines
song.tempo = tempo
updateUsrDialog()
if(lentext(input)>4000)
statusmsg("Editor Error: Song too long, end was cutoff (max 4000)")
input = copytext(input, 1, 4001)
currentsong.sourcestring = input
currentsong.compilesuccess = 0
updateUsrDialog()
else if(href_list["repeat"])
var/input = round(input(usr, "", "Repeat", "How many times do you want to repeat? (max 10)") as num|null)
if(input < 1)
input = 1
else if(input > 10)
input = 10
repeat = input
add_fingerprint(usr)
updateUsrDialog()