diff --git a/code/defines/atom.dm b/code/defines/atom.dm
index 0d6a69961e..23b4cadd9d 100644
--- a/code/defines/atom.dm
+++ b/code/defines/atom.dm
@@ -3,11 +3,10 @@
var/level = 2
var/flags = FPRINT
var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
- var/fingerprints = null
- var/list/fingerprintshidden = new/list()
+ var/list/fingerprints = list()
+ var/list/fingerprintshidden = list()
var/fingerprintslast = null
- var/blood_DNA = null
- var/blood_type = null
+ var/list/blood_DNA = list()
var/last_bumped = 0
var/pass_flags = 0
@@ -18,6 +17,9 @@
// replaced by OPENCONTAINER flags and atom/proc/is_open_container()
///Chemistry.
+ //Detective Work, used for the duplicate data points kept in the scanners
+ var/atom/original_atom = null
+
proc/assume_air(datum/air_group/giver)
del(giver)
return null
diff --git a/code/defines/obj/decal.dm b/code/defines/obj/decal.dm
index 68c6245f98..63d094d172 100644
--- a/code/defines/obj/decal.dm
+++ b/code/defines/obj/decal.dm
@@ -49,8 +49,7 @@
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
var/list/viruses = list()
- blood_DNA = null
- blood_type = null
+ blood_DNA = list()
//var/datum/disease2/disease/virus2 = null
Del()
diff --git a/code/defines/obj/vending.dm b/code/defines/obj/vending.dm
index db6c440924..e6711d96fc 100644
--- a/code/defines/obj/vending.dm
+++ b/code/defines/obj/vending.dm
@@ -176,8 +176,8 @@
icon_state = "sec"
icon_deny = "sec-deny"
req_access_txt = "1"
- product_paths = "/obj/item/weapon/handcuffs;/obj/item/weapon/flashbang;/obj/item/device/flash;/obj/item/weapon/reagent_containers/food/snacks/donut"
- product_amounts = "8;4;5;12"
+ product_paths = "/obj/item/weapon/handcuffs;/obj/item/weapon/flashbang;/obj/item/device/flash;/obj/item/weapon/reagent_containers/food/snacks/donut;/obj/item/weapon/storage/box/evidence"
+ product_amounts = "8;4;5;12;6"
product_hidden = "/obj/item/clothing/glasses/sunglasses;/obj/item/kitchen/donut_box"
product_hideamt = "2;2"
product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?"
diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm
index fa8ba91b1f..bfc5d79afd 100644
--- a/code/defines/procs/helpers.dm
+++ b/code/defines/procs/helpers.dm
@@ -1505,4 +1505,37 @@ proc/oview_or_orange(distance = world.view , center = usr , type)
list += found_string
found_char = findtext(cur_text,character,last_found)
list += copytext(cur_text,last_found,length(cur_text)+1)
- return list
\ No newline at end of file
+ return list
+
+/proc/stringmerge(var/text,var/compare,replace = "*")
+//This proc fills in all spaces with the "replace" var (* by default) with whatever
+//is in the other string at the same spot (assuming it is not a replace char).
+//This is used for fingerprints
+ var/newtext = text
+ if(lentext(text) != lentext(compare))
+ return 0
+ for(var/i = 1, i < lentext(text), i++)
+ var/a = copytext(text,i,i+1)
+ var/b = copytext(compare,i,i+1)
+//if it isn't both the same letter, or if they are both the replacement character
+//(no way to know what it was supposed to be)
+ if(a != b)
+ if(a == replace) //if A is the replacement char
+ newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1)
+ else if(b == replace) //if B is the replacement char
+ newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1)
+ else //The lists disagree, Uh-oh!
+ return 0
+ return newtext
+
+/proc/stringpercent(var/text,character = "*")
+//This proc returns the number of chars of the string that is the character
+//This is used for detective work to determine fingerprint completion.
+ if(!text || !character)
+ return 0
+ var/count = 0
+ for(var/i = 1, i <= lentext(text), i++)
+ var/a = copytext(text,i,i+1)
+ if(a == character)
+ count++
+ return count
\ No newline at end of file
diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm
index b9b0263cf7..2f1e4e7ac3 100644
--- a/code/game/atom_procs.dm
+++ b/code/game/atom_procs.dm
@@ -106,33 +106,57 @@
if (!( src.flags ) & 256)
return
if (ishuman(M))
+ add_fibers(M)
var/mob/living/carbon/human/H = M
- if (!istype(H.dna, /datum/dna))
- return 0
- if (H.gloves)
+ if (!istype(H.dna, /datum/dna) || !H.dna.uni_identity || (length(H.dna.uni_identity) != 32))
+ if(!istype(H.dna, /datum/dna))
+ H.dna = new /datum/dna(null)
+ H.check_dna()
+ if (H.gloves && H.gloves != src)
if(src.fingerprintslast != H.key)
- src.fingerprintshidden += text("\[[time_stamp()]\] (Wearing gloves). Real name: [], Key: []",H.real_name, H.key)
- src.fingerprintslast = H.key
- return 0
- if (!( src.fingerprints ))
- src.fingerprints = text("[]", md5(H.dna.uni_identity))
- if(src.fingerprintslast != H.key)
- src.fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",H.real_name, H.key)
- src.fingerprintslast = H.key
- return 1
- else
- var/list/L = params2list(src.fingerprints)
- L -= md5(H.dna.uni_identity)
- while(L.len >= 3)
- L -= L[1]
- L += md5(H.dna.uni_identity)
- src.fingerprints = list2params(L)
- if(src.fingerprintslast != H.key)
- src.fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",H.real_name, H.key)
+ src.fingerprintshidden += text("(Wearing gloves). Real name: [], Key: []",H.real_name, H.key)
src.fingerprintslast = H.key
+ H.gloves.add_fingerprint(M)
+ if(H.gloves != src)
+ if(prob(75) && istype(H.gloves, /obj/item/clothing/gloves/latex))
+ return 0
+ else if(H.gloves && !istype(H.gloves, /obj/item/clothing/gloves/latex))
+ return 0
+ if(src.fingerprintslast != H.key)
+ src.fingerprintshidden += text("Real name: [], Key: []",H.real_name, H.key)
+ src.fingerprintslast = H.key
+ var/new_prints = 0
+ var/prints
+ for(var/i = 1, i <= src.fingerprints.len, i++)
+ var/list/L = params2list(src.fingerprints[i])
+ if(L[num2text(1)] == md5(H.dna.uni_identity))
+ new_prints = i
+ prints = L[num2text(2)]
+ break
+ else
+ var/test_print = stars(L[num2text(2)], rand(80,90))
+ if(stringpercent(test_print) == 32)
+ if(src.fingerprints.len == 1)
+ src.fingerprints = list()
+ else
+ for(var/j = (i + 1), j < (src.fingerprints.len), j++)
+ src.fingerprints[j-1] = src.fingerprints[j]
+ src.fingerprints.len--
+ else
+ src.fingerprints[i] = "1=" + L[num2text(1)] + "&2=" + test_print
+ if(new_prints)
+ src.fingerprints[new_prints] = text("1=[]&2=[]", md5(H.dna.uni_identity), stringmerge(prints,stars(md5(H.dna.uni_identity), (H.gloves ? rand(10,20) : rand(25,40)))))
+ else if(new_prints == 0)
+ if(!src.fingerprints)
+ src.fingerprints = list(text("1=[]&2=[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), H.gloves ? rand(10,20) : rand(25,40))))
+ src.fingerprints += text("1=[]&2=[]", md5(H.dna.uni_identity), stars(md5(H.dna.uni_identity), H.gloves ? rand(10,20) : rand(25,40)))
+ for(var/i = 1, i <= src.fingerprints.len, i++)
+ if(length(src.fingerprints[i]) != 69)
+ src.fingerprints.Remove(src.fingerprints[i])
+ return 1
else
if(src.fingerprintslast != M.key)
- src.fingerprintshidden += text("\[[time_stamp()]\] Real name: [], Key: []",M.real_name, M.key)
+ src.fingerprintshidden += text("Real name: [], Key: []",M.real_name, M.key)
src.fingerprintslast = M.key
return
@@ -140,9 +164,17 @@
/atom/proc/add_blood(mob/living/carbon/human/M as mob)
if (!( istype(M, /mob/living/carbon/human) ))
return 0
+ if (!istype(M.dna, /datum/dna))
+ M.dna = new /datum/dna(null)
+ M.check_dna()
if (!( src.flags ) & 256)
return
- if (!( src.blood_DNA ))
+ if(!blood_DNA)
+ var/turf/Z = get_turf(src)
+ message_admins("\red ERROR: [src] at [Z.x], [Z.y], [Z.z] is missing it's blood_DNA list!")
+ log_game("\red ERROR: [src] at [Z.x], [Z.y], [Z.z] is missing it's blood_DNA list!")
+ return
+ if (blood_DNA.len)
if (istype(src, /obj/item)&&!istype(src, /obj/item/weapon/melee/energy))//Only regular items. Energy melee weapon are not affected.
var/obj/item/source2 = src
source2.icon_old = src.icon
@@ -151,34 +183,53 @@
I.Blend(new /icon('blood.dmi', "itemblood"),ICON_MULTIPLY)
I.Blend(new /icon(src.icon, src.icon_state),ICON_UNDERLAY)
src.icon = I
- src.blood_DNA = M.dna.unique_enzymes
- src.blood_type = M.b_type
+ var/inthere = 0
+ for(var/i = 1, i <= src.blood_DNA.len, i++)
+ var/list/templist = src.blood_DNA[i]
+ if(templist[1] == M.dna.unique_enzymes && templist[2] == M.dna.b_type)
+ inthere = 1
+ break
+ if(!inthere)
+ src.blood_DNA.len++
+ src.blood_DNA[src.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type)
else if (istype(src, /turf/simulated))
var/turf/simulated/source2 = src
var/list/objsonturf = range(0,src)
- var/i
- for(i=1, i<=objsonturf.len, i++)
- if(istype(objsonturf[i],/obj/effect/decal/cleanable/blood))
- return
+ if(objsonturf)
+ for(var/i=1, i<=objsonturf.len, i++)
+ if(istype(objsonturf[i],/obj/effect/decal/cleanable/blood))
+ var/obj/effect/decal/cleanable/blood/this = objsonturf[i]
+ this.blood_DNA.len++
+ this.blood_DNA[this.blood_DNA.len] = list(M.dna.unique_enzymes, M.dna.b_type)
+ for(var/datum/disease/D in M.viruses)
+ var/datum/disease/newDisease = new D.type
+ this.viruses += newDisease
+ newDisease.holder = this
+ return
var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(source2)
- this.blood_DNA = M.dna.unique_enzymes
- this.blood_type = M.b_type
+ var/list/blood_DNA_temp[1]
+ blood_DNA_temp[1] = list(M.dna.unique_enzymes, M.dna.b_type)
+ this.blood_DNA = blood_DNA_temp
for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = new D.type
this.viruses += newDisease
newDisease.holder = this
else if (istype(src, /mob/living/carbon/human))
- src.blood_DNA = M.dna.unique_enzymes
- src.blood_type = M.b_type
+ var/inthere = 0
+ for(var/i = 1, i <= src.blood_DNA.len, i++)
+ var/list/templist = src.blood_DNA[i]
+ if(templist[1] == M.dna.unique_enzymes && templist[2] == M.dna.b_type)
+ inthere = 1
+ break
+ if(!inthere)
+ src.blood_DNA.len++
+ src.blood_DNA[src.blood_DNA.len] = list(M.dna.unique_enzymes,M.dna.b_type)
else
return
else
- var/list/L = params2list(src.blood_DNA)
- L -= M.dna.unique_enzymes
- while(L.len >= 3)
- L -= L[1]
- L += M.dna.unique_enzymes
- src.blood_DNA = list2params(L)
+ var/list/blood_DNA_temp[1]
+ blood_DNA_temp[1] = list(M.dna.unique_enzymes, M.dna.b_type)
+ src.blood_DNA = blood_DNA_temp
return
/atom/proc/add_vomit_floor(mob/living/carbon/M as mob, var/toxvomit = 0)
@@ -200,7 +251,7 @@
if( istype(src, /turf/simulated) )
var/turf/simulated/source1 = src
var/obj/effect/decal/cleanable/blood/this = new /obj/effect/decal/cleanable/blood(source1)
- this.blood_DNA = M.dna.unique_enzymes
+ this.blood_DNA = list(list(M.dna.unique_enzymes,M.dna.b_type))
for(var/datum/disease/D in M.viruses)
var/datum/disease/newDisease = new D.type
this.viruses += newDisease
@@ -230,23 +281,60 @@
if (!( src.flags ) & 256)
return
- if ( src.blood_DNA )
+ if(!blood_DNA)
+ var/turf/Z = get_turf(src)
+ message_admins("\red ERROR: [src] at [Z.x], [Z.y], [Z.z] is missing it's blood_DNA list!")
+ log_game("\red ERROR: [src] at [Z.x], [Z.y], [Z.z] is missing it's blood_DNA list!")
+ blood_DNA = list()
+ return
+ if ( src.blood_DNA.len )
if (istype (src, /mob/living/carbon))
var/obj/item/source2 = src
- source2.blood_DNA = null
+ source2.blood_DNA = list()
//var/icon/I = new /icon(source2.icon_old, source2.icon_state) //doesnt have icon_old
//source2.icon = I
if (istype (src, /obj/item))
var/obj/item/source2 = src
- source2.blood_DNA = null
+ source2.blood_DNA = list()
// var/icon/I = new /icon(source2.icon_old, source2.icon_state)
- source2.icon = source2.icon_old
- source2.update_icon()
+ if(source2.icon_old)
+ source2.icon = source2.icon_old
+ source2.update_icon()
+ else
+ source2.icon = initial(icon)
+ source2.update_icon()
if (istype(src, /turf/simulated))
var/obj/item/source2 = src
- source2.blood_DNA = null
- var/icon/I = new /icon(source2.icon_old, source2.icon_state)
- source2.icon = I
+ source2.blood_DNA = list()
+ if(source2.icon_old)
+ var/icon/I = new /icon(source2.icon_old, source2.icon_state)
+ source2.icon = I
+ else
+ source2.icon = initial(icon)
+ if(src.fingerprints && src.fingerprints.len)
+ var/done = 0
+ while(!done)
+ done = 1
+ for(var/i = 1, i < (src.fingerprints.len + 1), i++)
+ var/list/prints = params2list(src.fingerprints[i])
+ var/test_print = prints["2"]
+ var/new_print = stars(test_print, rand(1,20))
+ if(stringpercent(new_print) == 32)
+ if(src.fingerprints.len == 1)
+ src.fingerprints = list()
+ else
+ for(var/j = (i + 1), j < (src.fingerprints.len), j++)
+ src.fingerprints[j-1] = src.fingerprints[j]
+ src.fingerprints.len--
+ done = 0
+ break
+ else
+ src.fingerprints[i] = "1=" + prints["1"] + "&2=" + new_print
+ if(!src.fingerprints)
+ src.fingerprints = list()
+ if(istype(src, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = src
+ M.update_clothing()
return
/atom/MouseDrop(atom/over_object as mob|obj|turf|area)
diff --git a/code/game/dna.dm b/code/game/dna.dm
index c5bc5fcfed..74227b71a0 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -3,11 +3,71 @@
var/unique_enzymes = null
var/struc_enzymes = null
var/uni_identity = null
+ var/b_type = "A+"
-/datum/dna/proc/check_integrity()
- //Lazy.
- if(length(uni_identity) != 39) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4"
- if(length(struc_enzymes)!= 42) struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4000"
+/datum/dna/proc/check_integrity(var/mob/living/carbon/human/character)
+ if(character)
+ if(length(uni_identity) != 39)
+ //Lazy.
+ var/temp
+ var/hair = 0
+ var/beard
+
+ // determine DNA fragment from hairstyle
+ // :wtc:
+
+ var/list/styles = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
+ var/hrange = round(4095 / styles.len)
+
+ if(character.hair_style)
+ var/style = styles.Find(character.hair_style.type)
+ if(style)
+ hair = style * hrange - rand(1,hrange-1)
+
+ // Beard dna code - mostly copypasted from hair code to allow for more dynamic facial hair style additions
+ var/list/face_styles = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair
+ var/f_hrange = round(4095 / face_styles.len)
+
+ var/f_style = face_styles.Find(character.facial_hair_style.type)
+ if(f_style)
+ beard = f_style * f_hrange - rand(1,f_hrange-1)
+ else
+ beard = 0
+
+ temp = add_zero2(num2hex((character.r_hair),1), 3)
+ temp += add_zero2(num2hex((character.b_hair),1), 3)
+ temp += add_zero2(num2hex((character.g_hair),1), 3)
+ temp += add_zero2(num2hex((character.r_facial),1), 3)
+ temp += add_zero2(num2hex((character.b_facial),1), 3)
+ temp += add_zero2(num2hex((character.g_facial),1), 3)
+ temp += add_zero2(num2hex(((character.s_tone + 220) * 16),1), 3)
+ temp += add_zero2(num2hex((character.r_eyes),1), 3)
+ temp += add_zero2(num2hex((character.g_eyes),1), 3)
+ temp += add_zero2(num2hex((character.b_eyes),1), 3)
+
+ var/gender
+
+ if (character.gender == MALE)
+ gender = add_zero2(num2hex((rand(1,(2050+BLOCKADD))),1), 3)
+ else
+ gender = add_zero2(num2hex((rand((2051+BLOCKADD),4094)),1), 3)
+
+ temp += gender
+ temp += add_zero2(num2hex((beard),1), 3)
+ temp += add_zero2(num2hex((hair),1), 3)
+
+ uni_identity = temp
+ if(length(struc_enzymes)!= 42)
+ var/mutstring = ""
+ for(var/i = 1, i <= 13, i++)
+ mutstring += add_zero2(num2hex(rand(1,1024)),3)
+
+ struc_enzymes = mutstring
+ if(length(unique_enzymes) != 32)
+ unique_enzymes = md5(character.real_name)
+ else
+ if(length(uni_identity) != 39) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4"
+ if(length(struc_enzymes)!= 42) struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4000"
/datum/dna/proc/ready_dna(mob/living/carbon/human/character)
@@ -61,7 +121,9 @@
uni_identity = temp
- var/mutstring = "2013E85C944C19A4B00185144725785DC6406A4508"
+ var/mutstring = ""
+ for(var/i = 1, i <= 13, i++)
+ mutstring += add_zero2(num2hex(rand(1,1024)),3)
struc_enzymes = mutstring
diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index fe208cb98f..a5e769d8a8 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -88,7 +88,7 @@
CIG.light("")
H.equip_if_possible(CIG, H.slot_wear_mask)
H.equip_if_possible(new /obj/item/clothing/gloves/black(H), H.slot_gloves)
- H.equip_if_possible(new /obj/item/weapon/storage/fcard_kit(H.back), H.slot_in_backpack)
+ H.equip_if_possible(new /obj/item/weapon/storage/box/evidence(H.back), H.slot_in_backpack)
H.equip_if_possible(new /obj/item/weapon/fcardholder(H), H.slot_in_backpack)
H.equip_if_possible(new /obj/item/clothing/suit/det_suit(H), H.slot_wear_suit)
H.equip_if_possible(new /obj/item/device/detective_scanner(H), H.slot_in_backpack)
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 784860b11a..7197649b34 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -805,8 +805,7 @@
H.apply_damage(0.5*damage, BRUTE, "r_arm")
var/obj/effect/decal/cleanable/blood/B = new(src.loc)
- B.blood_DNA = H.dna.unique_enzymes
- B.blood_type = H.b_type
+ B.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type))
bloodiness += 4
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 0d3c3918d6..0d77ef48dc 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -14,21 +14,31 @@
a_id = null
temp = null
printing = null
+ can_change_id = 0
+ list/Perp
+ tempname = null
+/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob)
+ if(istype(O, /obj/item/weapon/card/id) && !scan)
+ usr.drop_item()
+ O.loc = src
+ scan = O
+ user << "You insert [O]."
+ ..()
+
/obj/machinery/computer/secure_data/attack_ai(mob/user as mob)
return attack_hand(user)
-
/obj/machinery/computer/secure_data/attack_paw(mob/user as mob)
return attack_hand(user)
-
//Someone needs to break down the dat += into chunks instead of long ass lines.
/obj/machinery/computer/secure_data/attack_hand(mob/user as mob)
if(..())
return
var/dat
+
if (temp)
dat = text("[]
Clear Screen", temp, src)
else
@@ -36,15 +46,57 @@
if (authenticated)
switch(screen)
if(1.0)
- dat += text("Search Records
\nList Records
\nSearch Fingerprints
\nNew General Record
\n
\nRecord Maintenance
\n{Log Out}
\n", src, src, src, src, src, src)
- if(2.0)
- dat += "Record List:
"
+ dat += {"
+"}
+ dat += text("Search Records
", src)
+ dat += text("New Record
", src)
+ dat += {"
+
+
+
+
+| Name |
+ID |
+Rank |
+Fingerprints |
+Criminal Status |
+
"}
for(var/datum/data/record/R in data_core.general)
- dat += text("[R.fields["id"]]: [R.fields["name"]] - [R.fields["rank"]]
")
- dat += text("
Back", src)
+ var/crimstat = ""
+ for(var/datum/data/record/E in data_core.security)
+ if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
+ crimstat = E.fields["criminal"]
+ var/background
+ switch(crimstat)
+ if("*Arrest*")
+ background = "'background-color:#DC143C;'"
+ if("Incarcerated")
+ background = "'background-color:#CD853F;'"
+ if("Parolled")
+ background = "'background-color:#CD853F;'"
+ if("Released")
+ background = "'background-color:#3BB9FF;'"
+ if("None")
+ background = "'background-color:#00FF7F;'"
+ if("")
+ background = "'background-color:#FFFFFF;'"
+ crimstat = "No Record."
+ dat += text("| [] | ", background, src, R, R.fields["name"])
+ dat += text("[] | ", R.fields["id"])
+ dat += text("[] | ", R.fields["rank"])
+ dat += text("[] | ", R.fields["fingerprint"])
+ dat += text("[] |
", crimstat)
+ dat += "
"
+ dat += text("Record Maintenance
", src)
+ dat += text("{Log Out}",src)
+ if(2.0)
+ dat += "Records Maintenance
"
+ dat += "
Delete All Records
Back"
if(3.0)
- dat += text("Records Maintenance
\nDelete All Records
\n
\nBack", src, src)
- if(4.0)
dat += "Security Record
"
if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
dat += text("Name: [] ID: []
\nSex: []
\nAge: []
\nRank: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", src, active1.fields["name"], src, active1.fields["id"], src, active1.fields["sex"], src, active1.fields["age"], src, active1.fields["rank"], src, active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"])
@@ -62,14 +114,60 @@
dat += "Security Record Lost!
"
dat += text("New Security Record
", src)
dat += text("\nDelete Record (ALL)
\nPrint Record
\nBack
", src, src, src)
+ if(4.0)
+ if(!Perp.len)
+ dat += text("ERROR. String could not be located.
Back", src)
+ else
+ dat += {"
+
+ "}
+ dat += text("| Search Results for '[]': | ", tempname)
+ dat += {"
+
+
+
+
+| Name |
+ID |
+Rank |
+Fingerprints |
+Criminal Status |
+
"}
+ for(var/i=1, i<=Perp.len, i += 2)
+ var/crimstat = ""
+ var/datum/data/record/R = Perp[i]
+ if(istype(Perp[i+1],/datum/data/record/))
+ var/datum/data/record/E = Perp[i+1]
+ crimstat = E.fields["criminal"]
+ var/background
+ switch(crimstat)
+ if("*Arrest*")
+ background = "'background-color:#DC143C;'"
+ if("Incarcerated")
+ background = "'background-color:#CD853F;'"
+ if("Parolled")
+ background = "'background-color:#CD853F;'"
+ if("Released")
+ background = "'background-color:#3BB9FF;'"
+ if("None")
+ background = "'background-color:#00FF7F;'"
+ if("")
+ background = "'background-color:#FFFFFF;'"
+ crimstat = "No Record."
+ dat += text("| [] | ", background, src, R, R.fields["name"])
+ dat += text("[] | ", R.fields["id"])
+ dat += text("[] | ", R.fields["rank"])
+ dat += text("[] | ", R.fields["fingerprint"])
+ dat += text("[] |
", crimstat)
+ dat += "
"
+ dat += text("
Return to index.", src)
else
else
dat += text("{Log In}", src)
- user << browse(text("Security Records[]", dat), "window=secure_rec")
+ user << browse(text("Security Records[]", dat), "window=secure_rec;size=600x400")
onclose(user, "secure_rec")
return
-
/*Revised /N
I can't be bothered to look more of the actual code outside of switch but that probably needs revising too.
What a mess.*/
@@ -94,7 +192,10 @@ What a mess.*/
if("Confirm Identity")
if (scan)
- scan.loc = loc
+ if(istype(usr,/mob/living/carbon/human) && !usr.get_active_hand())
+ usr.put_in_hand(scan)
+ else
+ scan.loc = get_turf(src)
scan = null
else
var/obj/item/I = usr.equipped()
@@ -124,31 +225,32 @@ What a mess.*/
rank = scan.assignment
screen = 1
//RECORD FUNCTIONS
- if("List Records")
- screen = 2
- active1 = null
- active2 = null
-
if("Search Records")
- var/t1 = input("Search String: (Name or ID)", "Secure. records", null, null) as text
+ var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr)))
return
- active1 = null
- active2 = null
+ Perp = new/list()
t1 = lowertext(t1)
+ var/list/components = dd_text2list(t1, " ")
+ if(components.len > 5)
+ return //Lets not let them search too greedily.
for(var/datum/data/record/R in data_core.general)
- if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"])))
- active1 = R
- if (!( active1 ))
- temp = text("Could not locate record [].", t1)
- else
+ var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"]
+ for(var/i = 1, i<=components.len, i++)
+ if(findtext(temptext,components[i]))
+ var/prelist = new/list(2)
+ prelist[1] = R
+ Perp += prelist
+ for(var/i = 1, i<=Perp.len, i+=2)
for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"]))
- active2 = E
- screen = 4
+ var/datum/data/record/R = Perp[i]
+ if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
+ Perp[i+1] = E
+ tempname = t1
+ screen = 4
if("Record Maintenance")
- screen = 3
+ screen = 2
active1 = null
active2 = null
@@ -163,9 +265,9 @@ What a mess.*/
S = E
active1 = R
active2 = S
- screen = 4
+ screen = 3
- if ("Search Fingerprints")
+/* if ("Search Fingerprints")
var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text
if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!istype(usr, /mob/living/silicon))))
return
@@ -181,7 +283,7 @@ What a mess.*/
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"]))
active2 = E
- screen = 4
+ screen = 3 */
if ("Print Record")
if (!( printing ))
@@ -202,7 +304,7 @@ What a mess.*/
else
P.info += "Security Record Lost!
"
P.info += ""
- P.name = "paper- 'Security Record'"
+ P.name = "paper - 'Security Record'"
printing = null
//RECORD DELETE
if ("Delete All Records")
@@ -258,7 +360,7 @@ What a mess.*/
R.fields["notes"] = "No notes."
data_core.security += R
active2 = R
- screen = 4
+ screen = 3
if ("New Record (General)")
var/datum/data/record/G = new /datum/data/record()
@@ -273,6 +375,7 @@ What a mess.*/
data_core.general += G
active1 = G
active2 = null
+
//FIELD FUNCTIONS
if ("Edit Field")
var/a1 = active1
@@ -366,6 +469,8 @@ What a mess.*/
if ("Change Rank")
if (active1)
active1.fields["rank"] = href_list["rank"]
+ if(href_list["rank"] in get_all_jobs())
+ active1.fields["real_rank"] = href_list["real_rank"]
if ("Change Criminal Status")
if (active2)
@@ -386,22 +491,20 @@ What a mess.*/
del(active2)
if ("Delete Record (ALL) Execute")
- for(var/datum/data/record/R in data_core.medical)
- if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
- del(R)
- else
+ if (active1)
+ for(var/datum/data/record/R in data_core.medical)
+ if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
+ del(R)
+ else
+ del(active1)
if (active2)
del(active2)
- if (active1)
- del(active1)
else
temp = "This function does not appear to be working at the moment. Our apologies."
add_fingerprint(usr)
updateUsrDialog()
return
-
-
/obj/machinery/computer/secure_data/detective_computer
icon = 'computer.dmi'
icon_state = "messyfiles"
diff --git a/code/game/magic/cultist/ritual.dm b/code/game/magic/cultist/ritual.dm
index 0a73a1bc2d..079c747c80 100644
--- a/code/game/magic/cultist/ritual.dm
+++ b/code/game/magic/cultist/ritual.dm
@@ -557,8 +557,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
R.word2 = w2
R.word3 = w3
R.check_icon()
- R.blood_DNA = H.dna.unique_enzymes
- R.blood_type = H.b_type
+ R.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type))
return
else
user << "The book seems full of illegible scribbles. Is this a joke?"
@@ -603,8 +602,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
var/obj/effect/rune/R = new /obj/effect/rune
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
- R.blood_DNA = H.dna.unique_enzymes
- R.blood_type = H.b_type
+ R.blood_DNA = list(list(H.dna.unique_enzymes, H.dna.b_type))
switch(r)
if("teleport")
var/list/words = list("ire", "ego", "nahlizet", "certum", "veri", "jatkaa", "balaq", "mgar", "karazet", "geeri")
diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm
index b1d990a298..faa4d5deea 100644
--- a/code/game/magic/cultist/runes.dm
+++ b/code/game/magic/cultist/runes.dm
@@ -903,7 +903,7 @@ var/list/sacrificed = list()
culcount++
if(culcount >= 5)
for(var/obj/effect/rune/R in world)
- if(R.blood_DNA == src.blood_DNA && R.blood_type == src.blood_type)
+ if(R.blood_DNA == src.blood_DNA)
for(var/mob/living/M in orange(2,R))
M.take_overall_damage(0,15)
if (R.invisibility>M.see_invisible)
@@ -913,7 +913,7 @@ var/list/sacrificed = list()
var/turf/T = get_turf(R)
T.hotspot_expose(700,125)
for(var/obj/effect/decal/cleanable/blood/B in world)
- if(B.blood_DNA == src.blood_DNA && B.blood_type == src.blood_type)
+ if(B.blood_DNA == src.blood_DNA)
for(var/mob/living/M in orange(1,B))
M.take_overall_damage(0,5)
M << "\red Blood suddenly ignites, burning you!"
diff --git a/code/game/objects/closets/secure/security.dm b/code/game/objects/closets/secure/security.dm
index 61a9b5b26f..41f3e1f0dd 100644
--- a/code/game/objects/closets/secure/security.dm
+++ b/code/game/objects/closets/secure/security.dm
@@ -163,6 +163,7 @@
new /obj/item/weapon/fcardholder(src)
new /obj/item/weapon/clipboard(src)
new /obj/item/device/detective_scanner(src)
+ new /obj/item/weapon/storage/box/evidence(src)
return
diff --git a/code/game/objects/devices/PDA/PDA.dm b/code/game/objects/devices/PDA/PDA.dm
index 6f239bd378..3288bb14e7 100644
--- a/code/game/objects/devices/PDA/PDA.dm
+++ b/code/game/objects/devices/PDA/PDA.dm
@@ -766,12 +766,14 @@
user << "\blue No fingerprints found on [C]"
else
user << text("\blue [C]'s Fingerprints: [md5(C:dna.uni_identity)]")
- if ( !(C:blood_DNA) )
+ if ( !(C:blood_DNA.len) )
user << "\blue No blood found on [C]"
else
user << "\blue Blood found on [C]. Analysing..."
spawn(15)
- user << "\blue Blood type: [C:blood_type]\nDNA: [C:blood_DNA]"
+ for(var/i = 1, i < C:blood_DNA.len, i++)
+ var/list/templist = C:blood_DNA[i]
+ user << "\blue Blood type: [templist[2]]\nDNA: [templist[1]]"
if(4)
for (var/mob/O in viewers(C, null))
@@ -789,10 +791,20 @@
if (!A.fingerprints)
user << "\blue Unable to locate any fingerprints on [A]!"
else
- var/list/L = params2list(A:fingerprints)
- user << "\blue Isolated [L.len] fingerprints."
- for(var/i in L)
- user << "\blue \t [i]"
+ user << "\blue Isolated [A:fingerprints.len] fingerprints."
+ var/list/prints = A:fingerprints
+ var/list/complete_prints = list()
+ for(var/i in prints)
+ var/list/templist = params2list(i)
+ var/temp = stringpercent(templist["2"])
+ if(temp <= 6)
+ complete_prints += templist["2"]
+ if(complete_prints.len < 1)
+ user << "\blue No intact prints found"
+ else
+ user << "\blue Found [complete_prints.len] intact prints"
+ for(var/i in complete_prints)
+ user << "\blue " + i
if(3)
if(!isnull(A.reagents))
diff --git a/code/game/objects/devices/scanners.dm b/code/game/objects/devices/scanners.dm
index a7ff0bd8f7..f443f673ca 100644
--- a/code/game/objects/devices/scanners.dm
+++ b/code/game/objects/devices/scanners.dm
@@ -59,111 +59,209 @@ MASS SPECTROMETER
if(M)
M.invisibility = 2
+
/obj/item/device/detective_scanner
name = "Scanner"
desc = "Used to scan objects for DNA and fingerprints."
- icon_state = "forensic0"
+ icon_state = "forensic1"
var/amount = 20.0
- var/printing = 0.0
+// var/printing = 0.0
+ var/list/stored = list()
w_class = 3.0
item_state = "electronic"
flags = FPRINT | TABLEPASS | ONBELT | CONDUCT | USEDELAY
-/obj/item/device/detective_scanner/attackby(obj/item/weapon/f_card/W as obj, mob/user as mob)
- ..()
+ attackby(obj/item/weapon/f_card/W as obj, mob/user as mob)
+ ..()
+ if (istype(W, /obj/item/weapon/f_card))
+ if (W.fingerprints)
+ return
+ if (src.amount == 20)
+ return
+ if (W.amount + src.amount > 20)
+ src.amount = 20
+ W.amount = W.amount + src.amount - 20
+ else
+ src.amount += W.amount
+ //W = null
+ del(W)
+ src.add_fingerprint(user)
+ if (W)
+ W.add_fingerprint(user)
+ return
- if (istype(W, /obj/item/weapon/f_card))
- if (W.fingerprints)
- return
- if (src.amount == 20)
- return
- if (W.amount + src.amount > 20)
- src.amount = 20
- W.amount = W.amount + src.amount - 20
+// attack_self(mob/user as mob)
+// src.printing = !( src.printing )
+// if(src.printing)
+// user << "\blue Printing turned on"
+// else
+// user << "\blue Printing turned off"
+// src.icon_state = text("forensic[]", src.printing)
+// add_fingerprint(user)
+// return
+
+ attack(mob/living/carbon/human/M as mob, mob/user as mob)
+ if (!ishuman(M))
+ user << "\red [M] is not human and cannot have the fingerprints."
+ return 0
+ if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
+ user << "\blue No fingerprints found on [M]"
+ return 0
else
- src.amount += W.amount
- //W = null
- del(W)
+ if (src.amount < 1)
+ user << text("\blue Fingerprints scanned on [M]. Need more cards to print.")
+// src.printing = 0
+// src.icon_state = text("forensic[]", src.printing)
+// if (src.printing)
+ else
+ src.amount--
+ var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc )
+ F.amount = 1
+ F.fingerprints += md5(M.dna.uni_identity)
+ F.icon_state = "fingerprint1"
+ F.name = text("FPrintC- '[M.name]'")
+
+ user << "\blue Done printing."
+ user << text("\blue [M]'s Fingerprints: [md5(M.dna.uni_identity)]")
+ if ( !(M.blood_DNA.len) )
+ user << "\blue No blood found on [M]"
+ else
+ user << "\blue Blood found on [M]. Analysing..."
+ spawn(15)
+ for(var/i = 1, i <= M.blood_DNA.len, i++)
+ var/list/templist = M.blood_DNA[i]
+ user << "\blue Blood type: [templist[2]]\nDNA: [templist[1]]"
+ return
+
+ afterattack(atom/A as obj|turf|area, mob/user as mob)
+ if(!(locate(A) in oview(1,user)))
+ return
+ if(src.loc != user)
+ return 0
+ if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit.
+ return
+ if(istype(A,/obj/item/weapon/f_card))
+ user << "Haha, nice try. Cheater. (It would break stuff anyways.)"
+ return
src.add_fingerprint(user)
- if (W)
- W.add_fingerprint(user)
- return
+ if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune))
+ if(!isnull(A.blood_DNA.len))
+ for(var/i = 1, i <= A.blood_DNA.len, i++)
+ var/list/templist = A.blood_DNA[i]
+ user << "\blue Blood type: [templist[2]]\nDNA: [templist[1]]"
+ return
+ var/duplicate = 0
+ if ((!A.fingerprints || A.fingerprints.len == 0) && !(A.suit_fibers) && !(A.blood_DNA.len))
+ user << "\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!"
+ return 0
+ else if (A.blood_DNA.len)
+ user << "\blue Blood found on [A]. Analysing..."
+ sleep(15)
+ if(!duplicate)
+ duplicate = 1
+ var/i = add_data(A)
+ if(i)
+ user << "\blue Blood already in memory."
+ for(var/i = 1, i < (A.blood_DNA.len + 1), i++)
+ var/list/templist = A.blood_DNA[i]
+ user << "\blue Blood type: [templist[2]]\nDNA: [templist[1]]"
+ else
+ user << "\blue No Blood Located"
+ if(!A.fingerprints || A.fingerprints.len == 0)
+ user << "\blue No Fingerprints Located."
+ else
+ user << text("\blue Isolated [A.fingerprints.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve.")
+ if(!duplicate)
+ duplicate = 1
+ var/i = add_data(A)
+ if(i)
+ user << "\blue Fingerprints already in memory."
+ if(!A.suit_fibers)
+ user << "\blue No Fibers/Materials Located."
+ else
+ user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
-/obj/item/device/detective_scanner/attack_self(mob/user as mob)
+ if(!duplicate)
+ duplicate = 1
+ var/i = add_data(A)
+ if(i)
+ user << "\blue Fibers/Materials already in memory."
+ // else
+ // if ((src.amount < 1 && src.printing))
+ // user << "\blue Fingerprints found. Need more cards to print."
+ // src.printing = 0
+ // src.icon_state = text("forensic[]", src.printing)
+ // if (src.printing)
+ // src.amount--
+ // var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc )
+ // F.amount = 1
+ // F.fingerprints = A.fingerprints
+ // F.icon_state = "fingerprint1"
+ // user << "\blue Done printing."
+ // for(var/i in L)
+ // user << text("\blue \t [i]")
+ // //Foreach goto(186)
+ return
- src.printing = !( src.printing )
- if(src.printing)
- user << "\blue Printing turned on"
- else
- user << "\blue Printing turned off"
- src.icon_state = text("forensic[]", src.printing)
- add_fingerprint(user)
- return
-
-/obj/item/device/detective_scanner/attack(mob/living/carbon/human/M as mob, mob/user as mob)
-
- if (!ishuman(M))
- user << "\red [M] is not human and cannot have the fingerprints."
- return 0
- if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
- user << "\blue No fingerprints found on [M]"
- return 0
- else
- if ((src.amount < 1 && src.printing))
- user << text("\blue Fingerprints scanned on [M]. Need more cards to print.")
- src.printing = 0
- src.icon_state = text("forensic[]", src.printing)
- if (src.printing)
- src.amount--
- var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc )
- F.amount = 1
- F.fingerprints = md5(M.dna.uni_identity)
- F.icon_state = "fingerprint1"
- F.name = text("FPrintC- '[M.name]'")
- user << "\blue Done printing."
- user << text("\blue [M]'s Fingerprints: [md5(M.dna.uni_identity)]")
- if ( !(M.blood_DNA) )
- user << "\blue No blood found on [M]"
- else
- user << "\blue Blood found on [M]. Analysing..."
- spawn(15)
- user << "\blue Blood type: [M.blood_type]\nDNA: [M.blood_DNA]"
- return
-
-/obj/item/device/detective_scanner/afterattack(atom/A as mob|obj|turf|area, mob/user as mob)
-
- src.add_fingerprint(user)
- if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune))
- if(A.blood_DNA)
- user << "\blue Blood type: [A.blood_type]\nDNA: [A.blood_DNA]"
- else if (A.blood_DNA)
- user << "\blue Blood found on [A]. Analysing..."
- sleep(15)
- user << "\blue Blood type: [A.blood_type]\nDNA: [A.blood_DNA]"
- else
- user << "\blue No blood found on [A]."
- if (!( A.fingerprints ))
- user << "\blue Unable to locate any fingerprints on [A]!"
- return 0
- else
- if ((src.amount < 1 && src.printing))
- user << "\blue Fingerprints found. Need more cards to print."
- src.printing = 0
- src.icon_state = text("forensic[]", src.printing)
- if (src.printing)
- src.amount--
- var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc )
- F.amount = 1
- F.fingerprints = A.fingerprints
- F.icon_state = "fingerprint1"
- user << "\blue Done printing."
- var/list/L = params2list(A.fingerprints)
- user << text("\blue Isolated [L.len] fingerprints.")
- for(var/i in L)
- user << text("\blue \t [i]")
- //Foreach goto(186)
- return
+ proc/add_data(atom/A as mob|obj|turf|area)
+ var/merged = 0
+ for(var/i = 1, i < (stored.len + 1), i++) //Lets see if the object is already in there!
+ var/list/temp = stored[i]
+ var/atom/checker = temp[1]
+ if(checker.original_atom == A || checker.original_atom == A.original_atom) //It is! Merge!
+ merged = 1
+ var/list/prints = temp[2]
+ if(!prints)
+ prints = list()
+ if(A.fingerprints && A.fingerprints.len)
+ for(var/j = 1, j <= A.fingerprints.len, j++) //Fingerprints~~~
+ var/list/print_test1 = params2list(A.fingerprints[j])
+ var/test_print1 = print_test1[num2text(1)]
+ var/found = 0
+ for(var/k = 1, k <= prints.len, k++) //Lets see if the print is already in there
+ var/list/print_test2 = params2list(prints[k])
+ var/test_print2 = print_test2[num2text(1)]
+ if(test_print2 == test_print1) //It is! Merge!
+ prints[k] = test_print2 + "&" + stringmerge(print_test2[num2text(2)],print_test1[num2text(2)])
+ found = 1
+ break //We found it, we're done here.
+ if(!found) //It isn't! Add!
+ prints += A.fingerprints[j]
+ var/list/fibers = temp[3]
+ if(!fibers)
+ fibers = list()
+ if(A.suit_fibers && A.suit_fibers.len)
+ for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~
+ if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add!
+ fibers += A.suit_fibers[j]
+ var/list/blood = temp[4]
+ if(!blood)
+ blood = list()
+ if(A.blood_DNA.len && A.blood_DNA)
+ for(var/j = 1, j <= A.blood_DNA.len, j++) //Blood~~~
+ if(!blood.Find(A.blood_DNA[j])) //It isn't! Add!
+ blood += A.blood_DNA[j]
+ var/list/sum_list[4] //Pack it back up!
+ sum_list[1] = checker
+ sum_list[2] = prints
+ sum_list[3] = fibers
+ sum_list[4] = blood
+ stored[i] = sum_list //Store it!
+ break //We found it, we're done here.
+ if(!merged) //Uh, oh! New data point!
+ var/list/sum_list[4] //Pack it back up!
+ sum_list[1] = A.get_duplicate(src)
+ if(!A.fingerprints)
+ world << "Report this to a dev! [A] was lacking a list() for fingerprints!"
+ sum_list[2] = list()
+ else
+ sum_list[2] = A.fingerprints
+ sum_list[3] = A.suit_fibers
+ sum_list[4] = A.blood_DNA
+ stored.len++
+ stored[stored.len] = sum_list
+ return merged
/obj/item/device/healthanalyzer
diff --git a/code/game/objects/gibs.dm b/code/game/objects/gibs.dm
index 15dcb69af2..21194af2c3 100644
--- a/code/game/objects/gibs.dm
+++ b/code/game/objects/gibs.dm
@@ -1,7 +1,7 @@
//HUMANS
-/proc/gibs(atom/location, var/list/viruses)
- new /obj/effect/gibspawner/human(get_turf(location),viruses)
+/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA)
+ new /obj/effect/gibspawner/human(get_turf(location),viruses,MobDNA)
/proc/xgibs(atom/location, var/list/viruses)
new /obj/effect/gibspawner/xeno(get_turf(location),viruses)
@@ -16,13 +16,13 @@
var/list/gibamounts = list()
var/list/gibdirections = list() //of lists
- New(location, var/list/viruses)
+ New(location, var/list/viruses, var/datum/dna/MobDNA)
..()
if(istype(loc,/turf)) //basically if a badmin spawns it
- Gib(loc,viruses)
+ Gib(loc,viruses,MobDNA)
- proc/Gib(atom/location, var/list/viruses = list())
+ proc/Gib(atom/location, var/list/viruses = list(), var/datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
world << "\red Gib list length mismatch!"
return
@@ -50,6 +50,12 @@
gib.viruses += viruus
viruus.holder = gib
viruus.spread_type = CONTACT_FEET
+ if(MobDNA)
+ gib.blood_DNA = list(list(MobDNA.unique_enzymes, MobDNA.b_type))
+ else if(istype(src, /obj/effect/gibspawner/xeno))
+ gib.blood_DNA = list(list("UNKNOWN DNA", "X*"))
+ else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
+ gib.blood_DNA = list(list("Non-human DNA", "A+"))
var/list/directions = gibdirections[i]
if(directions.len)
gib.streak(directions)
diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm
index 4f59ca3f00..d061dcbb6e 100644
--- a/code/game/objects/items/item.dm
+++ b/code/game/objects/items/item.dm
@@ -100,7 +100,7 @@
t = "huge"
else
if ((usr.mutations & CLUMSY) && prob(50)) t = "funny-looking"
- usr << text("This is a []\icon[][]. It is a [] item.", !src.blood_DNA ? "" : "bloody ",src, src.name, t)
+ usr << text("This is a []\icon[][]. It is a [] item.", !src.blood_DNA.len ? "" : "bloody ",src, src.name, t)
if(src.desc)
usr << src.desc
return
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index bed482b099..2b3176ec27 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -716,4 +716,46 @@