diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index b753e5c78e8..663a5cd4ad7 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -10,6 +10,7 @@ required_enemies = 1 var + changeling_amount const prob_int_murder_target = 50 // intercept names the assassination target half the time prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target @@ -31,7 +32,8 @@ waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - const/changeling_amount = 4 + changeling_min = 2 //lower bound on number of traitors, assuming there are this many players + changeling_max = 3 //upper bound on number of traitors /datum/game_mode/changeling/announce() world << "The current game mode is - Changeling!" @@ -40,6 +42,8 @@ /datum/game_mode/changeling/pre_setup() var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) + changeling_amount = rand(changeling_min, changeling_max) + for(var/datum/mind/player in possible_changelings) for(var/job in restricted_jobs)//Removing robots from the list if(player.assigned_role == job) diff --git a/code/game/magic/musician.dm b/code/game/magic/musician.dm index 66bb60b7fe3..b85c161bb12 100644 --- a/code/game/magic/musician.dm +++ b/code/game/magic/musician.dm @@ -1,7 +1,8 @@ /datum/song var name = "Untitled" - lines[] = list() + list/lines = new() + tempo = 5 /obj/structure/device/piano name = "space piano" @@ -12,10 +13,12 @@ var datum/song/song playing = 0 - tempo = 5 + help = 0 + edit = 1 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.*/ @@ -361,90 +364,168 @@ else return - for(var/mob/M in range(15, src)) + for(var/mob/M in hearers(15, src)) M << sound(soundfile) playsong() + var/cur_oct[7] + var/cur_acc[7] + for(var/i = 1 to 7) + cur_oct[i] = "3" + cur_acc[i] = "n" + for(var/line in song.lines) - for(var/i = 1, i <= length(line), i+=4)//i starts as 1, or beggining of list. Goes up by 4, skipping every fourth character. - if(!playing)//If the piano is playing and you don't want it playing, this will stop the proc. - return - var/currentnote = copytext(line, i, i+3) - playnote(currentnote) - sleep(tempo) + //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)//If the piano is playing and you don't want it playing, this will stop the proc. + 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") + cur_acc[cur_note] = ni + else if(ni == "s") + cur_acc[cur_note] = "#" // so shift is never required + 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) playing = 0 attack_hand(var/mob/user as mob) usr.machine = src - var/dat = "Piano\n " - var/calctempo = (10/tempo)*60 - dat += "Tempo : [calctempo] BPM (-/+)" - dat += "(Start a New Song)
" + var/dat = "Piano" + if(song) - var/linecount = 0 - for(var/line in song.lines) - linecount += 1 - dat += "Bar [linecount]: [line]
"//(Delete bar)
" // TODO: Replace delimeters with spaces, clean up display - dat += "(Write a new bar)
" if(song.lines.len > 0 && !(playing)) - dat += "(Play song)
" + dat += "Play Song

" if(playing) - dat += "(Stop playing)
" - dat += {" -

- Bars are a series of notes separated by asterisks (*) or anything else you want to put there.
- Just know that every fourth character will act as a stop, delaying the next note by tempo.
-
- Notes are played by the names of the note, the accidental, then the octave number.
- Example: An3*Bn3*Cn3*Dn3*En3*Fn3*Gn3 will play a scale.
- Chords can be played simply by listing more than one note before a pause: AB*CD*EF*GA
-
- Bars may be up to 30 characters (including pauses).
- A song may only contain up to 10 bars.
- "} - user << browse(dat, "window=piano") + dat += "Stop Playing

" + + if(!edit) + dat += "Show Editer

" + else + dat += "Hide Editer
" + 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") onclose(user, "piano") Topic(href, href_list) - //You need some safety checks here. Where is the person located, etc. - switch(href_list["choice"]) - if("lowertempo") - tempo += 1 - if(tempo < 1) - tempo = 1 - if("raisetempo") - tempo -= 1 - if(tempo < 1) - tempo = 1 - if("play") + if(in_range(src, usr) && !issilicon(usr)) + if(href_list["tempo"]) + song.tempo += text2num(href_list["tempo"]) + if(song.tempo < 1) + song.tempo = 1 + if(href_list["play"]) if(song) playing = 1 spawn() playsong() - if("newsong") - song = new /datum/song - if("newbar") - var/newbar = input("Enter your bar: ") as text|null - if(!newbar) + if(href_list["newsong"]) + song = new() + if(href_list["newline"]) + var/newline = input("Enter your line: ", "Piano") as text|null + if(!newline) return - if(song.lines.len >= 10) + if(song.lines.len > 50) return - if(lentext(newbar) > 30) - newbar = copytext(newbar, 1, 30) - song.lines.Add(newbar) - if("deletebar") - var/num = href_list["deletebar"] - num -= 1 - var/line = song.lines[num] - usr << "Line found is [line]" - song.lines.Remove(line) - if("stop") + if(lentext(newline) > 50) + newline = copytext(newline, 1, 50) + song.lines.Add(newline) + if(href_list["deleteline"]) + var/num = text2num(href_list["deleteline"]) + song.lines.Cut(num, num+1) + if(href_list["modifyline"]) + var/num = text2num(href_list["modifyline"]) + var/content = input("Enter your line: ", "Piano", song.lines[num]) as text|null + if(!content) + return + if(lentext(content) > 50) + content = copytext(content, 1, 50) + song.lines[num] = content + if(href_list["stop"]) playing = 0 + if(href_list["help"]) + help = text2num(href_list["help"]) - 1 + if(href_list["edit"]) + edit = text2num(href_list["edit"]) - 1 + if(href_list["import"]) + var/t = "" + do + t = input(usr, "Please paste the entire song, formated:", text("[]", src.name), t) as message + if (!in_range(src, usr)) + return + + if(lentext(t) >= MAX_PAPER_MESSAGE_LEN) + 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) > MAX_PAPER_MESSAGE_LEN) + + //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() add_fingerprint(usr) updateUsrDialog() return - -/* playing = 1 - var/datum/song/S = new /datum/song - S.lines.Add("A;B;C;D;E;F;G;A;A;B;B;A;G;A;F;F;A;*;*;*;*;B;C;C;F;G") - S.lines.Add("A;B;C;D;E;F;G;A;A;B;B;A;G;A;F;F;A;*;*;*;*;B;C;C;F;G") - song = S*/ \ No newline at end of file diff --git a/code/game/objects/storage/coat.dm b/code/game/objects/storage/coat.dm index 4fd6ec8ebc6..cab3c8bfd02 100644 --- a/code/game/objects/storage/coat.dm +++ b/code/game/objects/storage/coat.dm @@ -24,12 +24,6 @@ user.client.screen += src.boxes user.client.screen += src.closer user.client.screen += src.contents - var/xs = 7 - var/ys = 7 - for(var/obj/O in src.contents) - O.screen_loc = "[xs],[ys]" - O.layer = 20 - xs++ /obj/item/clothing/suit/storage/proc/close(mob/user as mob) if(!user) @@ -42,6 +36,7 @@ /obj/item/clothing/suit/storage/MouseDrop(atom/A) if(istype(A,/mob/living/carbon)) src.view_inv(A) + src.orient_objs(7,7,9,7) /obj/item/clothing/suit/storage/attackby(obj/item/weapon/W as obj, mob/user as mob) if(W.w_class > 2 || src.loc == W ) @@ -56,7 +51,56 @@ else if(user.s_active == src) close(user) view_inv(user) + orient2hud(user) W.dropped(user) + +/obj/item/clothing/suit/storage/attack_paw(mob/user as mob) + playsound(src.loc, "rustle", 50, 1, -5) + return attack_hand(user) + +/obj/item/clothing/suit/storage/attack_hand(mob/user as mob) + playsound(src.loc, "rustle", 50, 1, -5) + if (src.loc == user) + if (user.s_active) + user.s_active.close(user) + view_inv(user) + orient2hud(user) + else + ..() + for(var/mob/M in range(1)) + if (M.s_active == src) + src.close(M) + src.add_fingerprint(user) + return + +/obj/item/clothing/suit/storage/proc/orient2hud(mob/user as mob) + + if (src == user.l_hand) + src.orient_objs(3, 11, 3, 9) + else if (src == user.r_hand) + src.orient_objs(1, 11, 1, 9) + else if (istype(user,/mob/living/carbon/human) && src == user:wear_suit) + src.orient_objs(1, 11, 3, 11) + else + src.orient_objs(4, 10, 4, 8) + return + +/obj/item/clothing/suit/storage/proc/orient_objs(tx, ty, mx, my) + + var/cx = tx + var/cy = ty + src.boxes.screen_loc = text("[],[] to [],[]", tx, ty, mx, my) + for(var/obj/O in src.contents) + O.screen_loc = text("[],[]", cx, cy) + O.layer = 20 + cx++ + if (cx > mx) + cx = tx + cy-- + //Foreach goto(56) + src.closer.screen_loc = text("[],[]", mx, my) + return + /*/obj/item/clothing/suit/storage/New() src.boxes = new /obj/screen/storage( ) @@ -199,17 +243,4 @@ //Foreach goto(56) src.closer.screen_loc = text("[],[]", mx, my) return - -/obj/item/weapon/storage/proc/orient2hud(mob/user as mob) - - if (src == user.l_hand) - src.orient_objs(3, 11, 3, 4) - else - if (src == user.r_hand) - src.orient_objs(1, 11, 1, 4) - else - if (src == user.back) - src.orient_objs(4, 10, 4, 3) - else - src.orient_objs(4, 10, 4, 3) - return*/ \ No newline at end of file +*/ \ No newline at end of file