diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index acd85c1ab7a..74f0bbd499e 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -2,6 +2,8 @@
var/server_name = null // server name (for world name / status)
var/server_suffix = 0 // generate numeric suffix based on server port
+ var/nudge_script_path = "nudge.py" // where the nudge.py script is located
+
var/log_ooc = 0 // log OOC channel
var/log_access = 0 // log login/logout
var/log_say = 0 // log client say
@@ -238,6 +240,9 @@
if ("serversuffix")
config.server_suffix = 1
+ if ("nudge_script_path")
+ config.nudge_script_path = value
+
if ("hostedby")
config.hostedby = value
diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm
index 641d1b7c061..f76e32af0f7 100644
--- a/code/datums/organs/organ_external.dm
+++ b/code/datums/organs/organ_external.dm
@@ -33,8 +33,16 @@
var/open = 0
var/stage = 0
- // how often wounds should be updated, a higher number means less often
+ // how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 20 // update every 20 ticks(roughly every minute)
+ New(var/datum/organ/external/P)
+ if(P)
+ parent = P
+ if(!parent.children)
+ parent.children = list()
+ parent.children.Add(src)
+ return ..()
+
proc/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
// TODO: this proc needs to be rewritten to not update damages directly
@@ -187,7 +195,6 @@
proc/bandage()
var/rval = 0
- status |= ORGAN_BANDAGED
for(var/datum/wound/W in wounds)
rval |= !W.bandaged
W.bandaged = 1
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 29fec512a38..7d9c7e55209 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -1650,6 +1650,11 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
sharp = 1
+/obj/item/weapon/scalpel/stabslash
+ name = "\proper Stabslash The Pains of Healing"
+ desc = "All craftsmanship is of highest quality. On it is image of doctor and patient. Doctor is panicing. Patien is asleep."
+ icon_state = "stabslash"
+
/obj/item/weapon/retractor
name = "retractor"
desc = "Retracts stuff."
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 2ee5374ec58..72660368143 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -20,10 +20,11 @@
..()
if(istype(src, /obj/effect/decal/cleanable/blood/gibs))
return
- if(src.loc && isturf(src.loc))
- for(var/obj/effect/decal/cleanable/blood/B in src.loc)
- if(B != src)
- del(B)
+ if(src.type == /obj/effect/decal/cleanable/blood)
+ if(src.loc && isturf(src.loc))
+ for(var/obj/effect/decal/cleanable/blood/B in src.loc)
+ if(B != src)
+ del(B)
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 883e05a68a9..83447d1a239 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -116,7 +116,6 @@ var/savefile/Banlist
Banlist["temp"] << temp
if (temp)
Banlist["minutes"] << bantimestamp
- notes_add(ckey, "Banned - [reason]")
return 1
/proc/RemoveBan(foldername)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 3d69ce4bca9..35c600dcd53 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -168,6 +168,83 @@ var/global/floorIsLava = 0
feedback_add_details("admin_verb","SPP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/datum/player_info/var/author // admin who authored the information
+/datum/player_info/var/rank //rank of admin who made the notes
+/datum/player_info/var/content // text content of the information
+/datum/player_info/var/timestamp // Because this is bloody annoying
+
+/datum/admins/proc/PlayerNotes()
+ set category = "Admin"
+ set name = "Player Notes"
+ var/dat = "Player notes
"
+ if (!istype(src,/datum/admins))
+ src = usr.client.holder
+ if (!istype(src,/datum/admins))
+ usr << "Error: you are not an admin!"
+ return
+
+ var/savefile/S=new("data/player_notes.sav")
+ var/list/note_keys
+ S >> note_keys
+ if(!note_keys)
+ dat += "No notes found."
+ else
+ sortList(note_keys)
+ for(var/t in note_keys)
+ dat += "| [t] |
"
+ dat += "
"
+ usr << browse(dat, "window=player_notes;size=400x400")
+
+
+/datum/admins/proc/player_has_info(var/key as text)
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos || !infos.len) return 0
+ else return 1
+
+
+/datum/admins/proc/show_player_info(var/key as text)
+ set category = "Admin"
+ set name = "Show Player Info"
+ if (!istype(src,/datum/admins))
+ src = usr.client.holder
+ if (!istype(src,/datum/admins))
+ usr << "Error: you are not an admin!"
+ return
+ var/dat = "Info on [key]"
+ dat += ""
+
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos)
+ dat += "No information found on the given key.
"
+ else
+ var/update_file = 0
+ var/i = 0
+ for(var/datum/player_info/I in infos)
+ i += 1
+ if(!I.timestamp)
+ I.timestamp = "Pre-4/3/2012"
+ update_file = 1
+ if(!I.rank)
+ I.rank = "N/A"
+ update_file = 1
+ dat += "[I.content] by [I.author] ([I.rank]) on [I.timestamp] "
+ if(I.author == usr.key)
+ dat += "Remove"
+ dat += "
"
+ if(update_file) info << infos
+
+ dat += "
"
+ dat += "Add Comment
"
+
+ dat += ""
+ usr << browse(dat, "window=adminplayerinfo;size=480x480")
+
+
+
/datum/admins/proc/access_news_network() //MARKER
set category = "Fun"
set name = "Access Newscaster Network"
@@ -979,21 +1056,6 @@ var/global/floorIsLava = 0
if(istype(H))
H.regenerate_icons()
-/datum/admins/proc/PlayerNotes()
- var/dat = "Player notes
"
-
- var/savefile/S=new("data/player_notes.sav")
- var/list/note_keys
- S >> note_keys
- if(!note_keys)
- dat += "No notes found."
- else
- sortList(note_keys)
- for(var/t in note_keys)
- dat += text("| [t] |
")
- dat += "
"
- usr << browse(dat, "window=player_notes;size=400x400")
-
//
//
//ALL DONE
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 131130c298c..e601f069c68 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -44,5 +44,3 @@
else
src << "Error: admin_investigate: Href Logging is not on."
return
- if("notes")
- holder.notes_show()
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index a7bbd38abff..0e18f44f29a 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -130,6 +130,8 @@
verbs += /client/proc/display_admin_reports
verbs += /datum/admins/proc/show_skills
verbs += /client/proc/admin_ghost
+ verbs += /datum/admins/proc/show_player_info
+ verbs += /datum/admins/proc/PlayerNotes
else return
//Extra moderator commands
diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm
index ffb47bea84c..4fba430ea6c 100644
--- a/code/modules/admin/holder2.dm
+++ b/code/modules/admin/holder2.dm
@@ -594,7 +594,6 @@ var/list/admin_datums = list()
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
if(!msg) msg = job
else msg += ", [job]"
- notes_add(M.ckey, "Banned from [msg] - [reason]")
message_admins("\blue [key_name_admin(usr)] banned [key_name_admin(M)] from [msg]", 1)
M << "\redYou have been jobbanned by [usr.client.ckey] from: [msg]."
M << "\red The reason is: [reason]"
@@ -641,25 +640,6 @@ var/list/admin_datums = list()
//M.client = null
del(M.client)
- //Player Notes
- if(href_list["notes"])
- var/ckey = href_list["ckey"]
- if(!ckey)
- var/mob/M = locate(href_list["mob"])
- if(ismob(M))
- ckey = M.ckey
-
- switch(href_list["notes"])
- if("show")
- notes_show(ckey)
- if("add")
- notes_add(ckey,href_list["text"])
- notes_show(ckey)
- if("remove")
- notes_remove(ckey,text2num(href_list["from"]),text2num(href_list["to"]))
- notes_show(ckey)
- return
-
if (href_list["removejobban"])
if ((src.rank in list("Game Admin", "Game Master" )))
@@ -2590,3 +2570,85 @@ var/list/admin_datums = list()
vsc.ChangeSettingsDialog(usr,vsc.plc.settings)
if(href_list["vsc"] == "default")
vsc.SetDefault(usr)
+
+ // player info stuff
+
+ if(href_list["add_player_info"])
+ var/key = href_list["add_player_info"]
+ var/add = input("Add Player Info") as null|text
+ if(!add) return
+
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos) infos = list()
+
+ var/datum/player_info/P = new
+ P.author = usr.key
+ P.rank = usr.client.holder.rank
+ P.content = add
+ var/modifyer = "th"
+ switch(time2text(world.timeofday, "DD"))
+ if("01","21","31")
+ modifyer = "st"
+ if("02","22",)
+ modifyer = "nd"
+ if("03","23")
+ modifyer = "rd"
+ var/day_string = "[time2text(world.timeofday, "DD")][modifyer]"
+ if(copytext(day_string,1,2) == "0")
+ day_string = copytext(day_string,2)
+ var/full_date = time2text(world.timeofday, "DDD, Month DD of YYYY")
+ var/day_loc = findtext(full_date, time2text(world.timeofday, "DD"))
+ P.timestamp = "[copytext(full_date,1,day_loc)][day_string][copytext(full_date,day_loc+2)]"
+
+ infos += P
+
+ info << infos
+
+ message_admins("\blue [key_name_admin(usr)] has edited [key]'s notes.")
+ log_admin("[key_name(usr)] has edited [key]'s notes.")
+
+ del info
+
+ var/savefile/note_list = new("data/player_notes.sav")
+ var/list/note_keys
+ note_list >> note_keys
+ if(!note_keys) note_keys = list()
+ if(!note_keys.Find(key)) note_keys += key
+ note_list << note_keys
+ del note_list
+
+ show_player_info(key)
+
+ if(href_list["remove_player_info"])
+ var/key = href_list["remove_player_info"]
+ var/index = text2num(href_list["remove_index"])
+
+ var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
+ var/list/infos
+ info >> infos
+ if(!infos || infos.len < index) return
+
+ var/datum/player_info/item = infos[index]
+ infos.Remove(item)
+ info << infos
+
+ message_admins("\blue [key_name_admin(usr)] deleted one of [key]'s notes.")
+ log_admin("[key_name(usr)] deleted one of [key]'s notes.")
+
+ del info
+
+ show_player_info(key)
+
+ if(href_list["notes"])
+ var/ckey = href_list["ckey"]
+ if(!ckey)
+ var/mob/M = locate(href_list["mob"])
+ if(ismob(M))
+ ckey = M.ckey
+
+ switch(href_list["notes"])
+ if("show")
+ show_player_info(ckey)
+ return
\ No newline at end of file
diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm
index 70de3b1c125..e69de29bb2d 100644
--- a/code/modules/admin/player_notes.dm
+++ b/code/modules/admin/player_notes.dm
@@ -1,83 +0,0 @@
-//This stuff was originally intended to be integrated into the ban-system I was working on
-//but it's safe to say that'll never be finished. So I've merged it into the current player panel.
-//enjoy ~Carn
-
-#define NOTESFILE "data/player_notes.sav" //where the player notes are saved
-
-datum/admins/proc/notes_show(var/ckey)
- usr << browse("Player Notes[notes_gethtml(ckey)]","window=player_notes;size=700x400")
-
-
-datum/admins/proc/notes_gethtml(var/ckey)
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return "Error: Cannot access [NOTESFILE]"
- if(ckey)
- . = "Notes for [ckey]: \[+\] \[-\]
"
- notesfile.cd = "/[ckey]"
- var/index = 1
- while( !notesfile.eof )
- var/note
- notesfile >> note
- . += "[note] \[-\]
"
- index++
- else
- . = "All Notes: \[+\] \[-\]
"
- notesfile.cd = "/"
- for(var/dir in notesfile.dir)
- . += "[dir]
"
- return
-
-
-//handles adding notes to the end of a ckey's buffer
-//originally had seperate entries such as var/by to record who left the note and when
-//but the current bansystem is a heap of dung.
-/proc/notes_add(var/ckey, var/note)
- if(!ckey)
- ckey = ckey(input(usr,"Who would you like to add notes for?","Enter a ckey",null) as text|null)
- if(!ckey) return
-
- if(!note)
- note = html_encode(input(usr,"Enter your note:","Enter some text",null) as message|null)
- if(!note) return
-
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return
- notesfile.cd = "/[ckey]"
- notesfile.eof = 1 //move to the end of the buffer
- notesfile << "[time2text(world.realtime,"DD-MMM-YYYY")] | [note][(usr && usr.ckey)?" ~[usr.ckey]":""]"
- return
-
-//handles removing entries from the buffer, or removing the entire directory if no start_index is given
-/proc/notes_remove(var/ckey, var/start_index, var/end_index)
- var/savefile/notesfile = new(NOTESFILE)
- if(!notesfile) return
-
- if(!ckey)
- notesfile.cd = "/"
- ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir)
- if(!ckey) return
-
- if(start_index)
- notesfile.cd = "/[ckey]"
- var/list/noteslist = list()
- if(!end_index) end_index = start_index
- var/index = 0
- while( !notesfile.eof )
- index++
- var/temp
- notesfile >> temp
- if( (start_index <= index) && (index <= end_index) )
- continue
- noteslist += temp
-
- notesfile.eof = -2 //Move to the start of the buffer and then erase.
-
- for( var/note in noteslist )
- notesfile << note
- else
- notesfile.cd = "/"
- if(alert(usr,"Are you sure you want to remove all their notes?","Confirmation","No","Yes - Remove all notes") == "Yes - Remove all notes")
- notesfile.dir.Remove(ckey)
- return
-
-#undef NOTESFILE
\ No newline at end of file
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 235a41ae6e9..9023d34e9f6 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -133,5 +133,5 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an", "monkey", "ali
proc/send2irc(msg,msg2)
if(config.useircbot)
- shell("python nudge.py [msg] [msg2]")
+ shell("python [config.nudge_script_path] [msg] [msg2]")
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 824062cf039..0dc518f992a 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -193,24 +193,33 @@
if(suiciding)
msg += "[t_He] [t_has] bitten off [t_his] own tongue and [t_has] suffered major bloodloss!\n"
- if(stat == DEAD || (status_flags & FAKEDEATH))
- if(brain_op_stage != 4)//Only perform these checks if there is no brain
- msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life"
- if(!key)
+ var/distance = get_dist(usr,src)
+ if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
+ distance = 1
+ if (src.stat == 1 || stat == 2)
+ msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
+ if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3)
+ msg += "[t_He] does not appear to be breathing.\n"
+ if(istype(usr, /mob/living/carbon/human) && usr.stat == 0 && src.stat == 1 && distance <= 1)
+ for(var/mob/O in viewers(usr.loc, null))
+ O.show_message("[usr] checks [src]'s pulse.", 1)
+ spawn(15)
+ usr << "\blue [t_He] has a pulse!"
+
+ if (src.stat == 2 || (status_flags & FAKEDEATH))
+ if(distance <= 1)
+ if(istype(usr, /mob/living/carbon/human) && usr.stat == 0)
+ for(var/mob/O in viewers(usr.loc, null))
+ O.show_message("[usr] checks [src]'s pulse.", 1)
+ spawn(15)
var/foundghost = 0
- if(mind)
- for(var/mob/dead/observer/G in player_list)
- if(G.mind == mind)
- foundghost = 1
- if (G.can_reenter_corpse == 0)
- foundghost = 0
- break
+ if(src.client)
+ foundghost = 1
if(!foundghost)
- msg += " and [t_his] soul has departed"
- msg += "...\n"
- else//Brain is gone, doesn't matter if they are AFK or present
- msg += "It appears that [t_his] brain is missing...\n"
+ usr << "[t_He] has no pulse and [t_his] soul has departed..."
+ else
+ usr << "[t_He] has no pulse..."
msg += ""
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 3cce88cde48..341fd73fa28 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -5,6 +5,10 @@
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
+ var/datum/reagents/vessel
+ // TODO: make this actually affect the way the mob is rendered
+ var/pale = 0
+
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
@@ -23,19 +27,20 @@
//initialise organs
organs = list()
organs_by_name["chest"] = new/datum/organ/external/chest()
- organs_by_name["head"] = new/datum/organ/external/head()
- organs_by_name["l_arm"] = new/datum/organ/external/l_arm()
- organs_by_name["r_arm"] = new/datum/organ/external/r_arm()
- organs_by_name["r_leg"] = new/datum/organ/external/r_leg()
- organs_by_name["l_leg"] = new/datum/organ/external/l_leg()
- organs_by_name["l_hand"] = new/datum/organ/external/l_hand()
- organs_by_name["r_hand"] = new/datum/organ/external/r_hand()
- organs_by_name["l_foot"] = new/datum/organ/external/l_foot()
- organs_by_name["r_foot"] = new/datum/organ/external/r_foot()
- organs_by_name["groin"] = new/datum/organ/external/groin()
+ organs_by_name["groin"] = new/datum/organ/external/groin(organs_by_name["chest"])
+ organs_by_name["head"] = new/datum/organ/external/head(organs_by_name["chest"])
+ organs_by_name["l_arm"] = new/datum/organ/external/l_arm(organs_by_name["chest"])
+ organs_by_name["r_arm"] = new/datum/organ/external/r_arm(organs_by_name["chest"])
+ organs_by_name["r_leg"] = new/datum/organ/external/r_leg(organs_by_name["groin"])
+ organs_by_name["l_leg"] = new/datum/organ/external/l_leg(organs_by_name["groin"])
+ organs_by_name["l_hand"] = new/datum/organ/external/l_hand(organs_by_name["l_arm"])
+ organs_by_name["r_hand"] = new/datum/organ/external/r_hand(organs_by_name["r_arm"])
+ organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
+ organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
+
// connect feet to legs and hands to arms
- var/datum/organ/external/organ = organs_by_name["l_hand"]
+/* var/datum/organ/external/organ = organs_by_name["l_hand"]
organ.parent = organs_by_name["l_arm"]
organ = organs_by_name["r_hand"]
organ.parent = organs_by_name["r_arm"]
@@ -57,7 +62,7 @@
organ.parent = organs_by_name["chest"]
organ = organs_by_name["l_arm"]
organ.parent = organs_by_name["chest"]
-
+ */
for(var/name in organs_by_name)
organs += organs_by_name[name]
@@ -72,6 +77,49 @@
prev_gender = gender // Debug for plural genders
+ vessel = new/datum/reagents(600)
+ vessel.my_atom = src
+ vessel.add_reagent("blood",560)
+ spawn(1)
+ fixblood()
+
+/mob/living/carbon/human/proc/drip(var/amt as num)
+ if(!amt)
+ return
+
+ var/amm = 0.1 * amt
+ var/turf/T = get_turf(src)
+ var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
+ var/list/iconL = list("1","2","3","4","5")
+
+ vessel.remove_reagent("blood",amm)
+
+ for(var/obj/effect/decal/cleanable/blood/drip/G in T)
+ nums += G
+ iconL.Remove(G.icon_state)
+ if(nums.len >= 3)
+ var/obj/effect/decal/cleanable/blood/drip/D = pick(nums)
+ D.blood_DNA[dna.unique_enzymes] = dna.b_type
+ return
+
+ var/obj/effect/decal/cleanable/blood/drip/this = new(T)
+ this.icon_state = pick(iconL)
+ this.blood_DNA = list()
+ this.blood_DNA[dna.unique_enzymes] = dna.b_type
+
+ // replace many drips with something larger
+ if(nums.len > 3)
+ for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
+ del G
+ T.add_blood(src)
+
+
+/mob/living/carbon/human/proc/fixblood()
+ for(var/datum/reagent/blood/B in vessel.reagent_list)
+ if(B.id == "blood")
+ B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type,"resistances"=null,"trace_chem"=null)
+
+
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing))
return
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 4d5f22160b6..bb38be8b039 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -123,6 +123,78 @@
/mob/living/carbon/human
+ proc/handle_blood()
+ // take care of blood and blood loss
+ if(stat < 2)
+ var/blood_volume = round(vessel.get_reagent_amount("blood"))
+ if(blood_volume < 560 && blood_volume)
+ var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
+ if(B) // Make sure there's some blood at all
+ if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
+ for(var/datum/reagent/blood/D in vessel.reagent_list)
+ if(D.data["donor"] == src)
+ B = D
+ break
+ var/datum/reagent/nutriment/F = locate() in vessel.reagent_list
+ if(F != null)
+ if(F.volume >= 1)
+ // nutriment speeds it up quite a bit
+ B.volume += 0.4
+ F.volume -= 0.1
+ else
+ //At this point, we dun care which blood we are adding to, as long as they get more blood.
+ B.volume = B.volume + 0.1 // regenerate blood VERY slowly
+
+
+ switch(blood_volume)
+ if(501 to 10000)
+ if(pale)
+ pale = 0
+ update_body()
+ if(336 to 500)
+ if(!pale)
+ pale = 1
+ update_body()
+ var/word = pick("dizzy","woosey","faint")
+ src << "\red You feel [word]"
+ if(prob(1))
+ var/word = pick("dizzy","woosey","faint")
+ src << "\red You feel [word]"
+ if(oxyloss < 20)
+ // hint that they're getting close to suffocation
+ oxyloss += 3
+ if(224 to 335)
+ if(!pale)
+ pale = 1
+ update_body()
+ eye_blurry += 6
+ if(oxyloss < 50)
+ oxyloss += 10
+ oxyloss += 1
+ if(prob(15))
+ Paralyse(rand(1,3))
+ var/word = pick("dizzy","woosey","faint")
+ src << "\red You feel extremely [word]"
+ if(122 to 244)
+ oxyloss += 5
+ toxloss += 5
+ if(prob(15))
+ var/word = pick("dizzy","woosey","faint")
+ src << "\red You feel extremely [word]"
+ if(0 to 122)
+ death()
+
+
+ var/blood_max = 0
+ for(var/datum/organ/external/temp in organs)
+ if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
+ continue
+ for(var/datum/wound/W in temp.wounds) if(W.bleeding())
+ blood_max += W.damage / 2
+ if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED))
+ blood_max += 20 //Yer missing a fucking limb.
+ drip(blood_max)
+
proc/handle_disabilities()
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1))
@@ -888,6 +960,7 @@
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
handle_organs()
+ handle_blood()
if(health <= config.health_threshold_dead || brain_op_stage == 4.0)
death()
blinded = 1
diff --git a/code/modules/mob/new_player/savefile.dm b/code/modules/mob/new_player/savefile.dm
index 92caa3f98b0..e63714935b8 100644
--- a/code/modules/mob/new_player/savefile.dm
+++ b/code/modules/mob/new_player/savefile.dm
@@ -135,6 +135,7 @@ datum/preferences/proc/savefile_save(mob/user)
// returns 0 if savefile did not exist
datum/preferences/proc/savefile_load(mob/user)
+ if(user.client == null) return 0
if(IsGuestKey(user.key)) return 0
var/path = savefile_path(user)
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 39d3c50595c..efbb2aceb91 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -362,11 +362,11 @@ datum
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
- if(1 to 15)
+ if(10 to 20)
M.eye_blurry = max(M.eye_blurry, 10)
- if(15 to 25)
+ if(20 to 30)
M.drowsyness = max(M.drowsyness, 20)
- if(25 to INFINITY)
+ if(30 to INFINITY)
M.Paralyse(20)
M.drowsyness = max(M.drowsyness, 30)
data++
@@ -1689,12 +1689,12 @@ datum
if(!data) data = 1
data++
switch(data)
- if(1)
+ if(15 to 25)
M.confused += 2
M.drowsyness += 2
- if(2 to 50)
+ if(25 to 60)
M.sleeping += 1
- if(51 to INFINITY)
+ if(61 to INFINITY)
M.sleeping += 1
M.adjustToxLoss(data - 50)
..()
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 3e0d85d766a..48249a67f93 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -75,6 +75,9 @@
if(NOCLONE in T.mutations) //target done been et, no more blood in him
user << "\red You are unable to locate any blood."
return
+ if(ishuman(T))
+ if(T:vessel.get_reagent_amount("blood") < amount)
+ return
B.holder = src
B.volume = amount
//set reagent data
@@ -106,6 +109,9 @@
temp_chem[R.name] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
+ if(ishuman(T))
+ T:vessel.remove_reagent("blood",amount) // Removes blood if human
+
src.reagents.reagent_list += B
src.reagents.update_total()
src.on_reagent_change()
@@ -158,7 +164,18 @@
if(ismob(target) && target == user)
src.reagents.reaction(target, INGEST)
spawn(5)
- var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
+ var/datum/reagent/blood/B
+ for(var/datum/reagent/blood/d in src.reagents.reagent_list)
+ B = d
+ break
+ var/trans
+ if(B && ishuman(target))
+ var/mob/living/carbon/human/H = target
+ trans = B.volume > 5? 5 : B.volume
+ H.vessel.add_reagent("blood",trans,B.data)
+ src.reagents.remove_reagent("blood",trans)
+ else
+ trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "\blue You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units."
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 6343b00685f..76e4beb0ce6 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -1335,3 +1335,13 @@
dirs = alldirs.Copy()
src.streak(dirs)
+
+/obj/effect/decal/cleanable/blood/drip
+ name = "drips of blood"
+ desc = "It's red."
+ gender = PLURAL
+ density = 0
+ anchored = 1
+ layer = 2
+ icon = 'drip.dmi'
+ icon_state = "1"
\ No newline at end of file
diff --git a/code/setup.dm b/code/setup.dm
index 71342dcd138..a500e309132 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -557,7 +557,6 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define ORGAN_GAUZED 2
#define ORGAN_ATTACHABLE 4
#define ORGAN_BLEEDING 8
-#define ORGAN_BANDAGED 16
#define ORGAN_BROKEN 32
#define ORGAN_DESTROYED 64
#define ORGAN_ROBOT 128
diff --git a/code/world.dm b/code/world.dm
index aedc3137ceb..1819bd212f1 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -146,7 +146,7 @@ Starting up. [time2text(world.timeofday, "hh:mm.ss")]
if(revdata) s["revision"] = revdata.revision
s["admins"] = admins
-
+ s["end"] = "#end"
return list2params(s)
diff --git a/config/config.txt b/config/config.txt
index 95a3791a135..803d975a80f 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -173,4 +173,7 @@ SOCKET_TALK 0
#AUTOMUTE_ON
## Uncomment to restrict non-admins from using humanoid alien races
-USEALIENWHITELIST
\ No newline at end of file
+USEALIENWHITELIST
+
+## Location of the nudge.py script
+NUDGE_SCRIPT_PATH nudge.py
\ No newline at end of file
diff --git a/html/changelog.html b/html/changelog.html
index a127d32e5a5..8e28f43da13 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,12 +56,23 @@ Stuff which is in development and not yet visible to players or just code relate
should be listed in the changelog upon commit though. Thanks. -->
+
October 13th, 2012
Cael_Aislinn updated:
- Moderators are now being loaded correctly, and all broken admin and mod verbs should be functioning correctly. Misc other fixes and improvements.
+
CIB updated:
+
+ - Medical stack items(ointment, bandages) aren't instant anymore, but instead stop bleeding and speed up healing.
+ - Cyborgs can now use :h to use their department channel.
+ - Ported BS12 medbots. This means you now have to load them with a chemical, or otherwise they only have inaprovaline.
+ - Ported the BS12 player info features.
+ - Examine now only reveals whether someone is breathing(need to be 3 tiles away or closer). Check pulse from 1 tile distance.
+ - Ported bleeding. Bleeding can be stopped by applying a bandage.
+ - Small delay for chloral hydrate and sleep toxin to take effect.
+
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 4a093d06abc..2cabb9bfd58 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/interface/skin.dmf b/interface/skin.dmf
index ca8afba7cbd..1c18ae6b720 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -147,13 +147,17 @@ macro "macro"
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
+ elem
+ name = "F3"
+ command = "say"
+ is-disabled = false
elem
name = "F4"
- command = "asay"
+ command = "me"
is-disabled = false
elem
name = "F5"
- command = "Aghost"
+ command = "asay"
is-disabled = false
elem
name = "F6"
@@ -389,13 +393,17 @@ macro "hotkeymode"
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
+ elem
+ name = "F3"
+ command = "say"
+ is-disabled = false
elem
name = "F4"
- command = "asay"
+ command = "me"
is-disabled = false
elem
name = "F5"
- command = "msay"
+ command = "asay"
is-disabled = false
elem
name = "F6"