diff --git a/code/WorkInProgress/Sayu/cargoprofile.dm b/code/WorkInProgress/Sayu/cargoprofile.dm
index d90b76c8acf..85d00e44605 100644
--- a/code/WorkInProgress/Sayu/cargoprofile.dm
+++ b/code/WorkInProgress/Sayu/cargoprofile.dm
@@ -556,7 +556,7 @@
return "[garbletext(copytext(Text,l/2,0))][pick("#","|","/","*",".","."," ","."," "," ")]"
proc/garble_keeptags(var/Text)
- var/list/L = stringsplit(Text,">")
+ var/list/L = text2list(Text,">")
var/result = ""
for(var/string in L)
var/index = findtextEx(string,"<")
diff --git a/code/WorkInProgress/ZomgPonies/karma.dm b/code/WorkInProgress/ZomgPonies/karma.dm
index 065333927b6..1f116dda6a6 100644
--- a/code/WorkInProgress/ZomgPonies/karma.dm
+++ b/code/WorkInProgress/ZomgPonies/karma.dm
@@ -187,7 +187,7 @@ You've gained [totalkarma] total karma in your time here.
"}
var/list/joblist = text2list(dbjob,",")
if(!(job in joblist))
joblist += job
- var/newjoblist = dd_list2text(joblist,",")
+ var/newjoblist = list2text(joblist,",")
query = dbcon.NewQuery("UPDATE whitelist SET job='[newjoblist]' WHERE ckey='[dbckey]'")
if(!query.Execute())
var/err = query.ErrorMsg()
@@ -233,7 +233,7 @@ You've gained [totalkarma] total karma in your time here.
"}
var/list/specieslist = text2list(dbspecies,",")
if(!(species in specieslist))
specieslist += species
- var/newspecieslist = dd_list2text(specieslist,",")
+ var/newspecieslist = list2text(specieslist,",")
query = dbcon.NewQuery("UPDATE whitelist SET species='[newspecieslist]' WHERE ckey='[dbckey]'")
if(!query.Execute())
var/err = query.ErrorMsg()
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index a493aa9d080..af77addeab0 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -195,32 +195,10 @@ proc/checkhtml(var/t)
* Text modification
*/
/proc/replacetext(text, find, replacement)
- var/find_len = length(find)
- if(find_len < 1) return text
- . = ""
- var/last_found = 1
- while(1)
- var/found = findtext(text, find, last_found, 0)
- . += copytext(text, last_found, found)
- if(found)
- . += replacement
- last_found = found + find_len
- continue
- return .
+ return list2text(text2list(text, find), replacement)
/proc/replacetextEx(text, find, replacement)
- var/find_len = length(find)
- if(find_len < 1) return text
- . = ""
- var/last_found = 1
- while(1)
- var/found = findtextEx(text, find, last_found, 0)
- . += copytext(text, last_found, found)
- if(found)
- . += replacement
- last_found = found + find_len
- continue
- return .
+ return list2text(text2listEx(text, find), replacement)
//Adds 'u' number of zeros ahead of the text 't'
/proc/add_zero(t, u)
@@ -287,27 +265,6 @@ proc/checkhtml(var/t)
return message
return copytext(message, 1, length + 1)
-/*
- * Misc
- */
-
-/proc/stringsplit(txt, character)
- var/cur_text = txt
- var/last_found = 1
- var/found_char = findtext(cur_text,character)
- var/list/list = list()
- if(found_char)
- var/fs = copytext(cur_text,last_found,found_char)
- list += fs
- last_found = found_char+length(character)
- found_char = findtext(cur_text,character,last_found)
- while(found_char)
- var/found_string = copytext(cur_text,last_found,found_char)
- last_found = found_char+length(character)
- list += found_string
- found_char = findtext(cur_text,character,last_found)
- list += copytext(cur_text,last_found,length(cur_text)+1)
- return list
/proc/stringmerge(var/text,var/compare,replace = "*")
//This proc fills in all spaces with the "replace" var (* by default) with whatever
@@ -346,4 +303,4 @@ proc/checkhtml(var/t)
var/new_text = ""
for(var/i = length(text); i > 0; i--)
new_text += copytext(text, i, i+1)
- return new_text
\ No newline at end of file
+ return new_text
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index afcffc098c6..c659eec7fec 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -83,22 +83,86 @@
return hex
-//Attaches each element of a list to a single string seperated by 'seperator'.
-/proc/dd_list2text(var/list/the_list, separator)
- var/total = the_list.len
- if(!total)
- return
- var/count = 2
- var/newText = "[the_list[1]]"
- while(count <= total)
- if(separator)
- newText += separator
- newText += "[the_list[count]]"
- count++
- return newText
+// Concatenates a list of strings into a single string. A seperator may optionally be provided.
+/proc/list2text(list/ls, sep)
+ if(ls.len <= 1) return ls.len ? ls[1] : ""
+ . = ""
+ var/l = ls.len
+ var/i = 0
+
+ if(sep)
+ #define S1 ls[++i]
+ #define S4 S1, sep, S1, sep, S1, sep, S1
+ #define S16 S4, sep, S4, sep, S4, sep, S4
+ #define S64 S16, sep, S16, sep, S16, sep, S16
+
+ while(l-i >= 128)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, sep, S64)
+ if(l-i >= 64)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
+ if(l-i >= 32)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, sep, S16)
+ if(l-i >= 16)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16)
+ if(l-i >= 8)
+ . = text("[][][][][][][][][][][][][][][][]", ., S4, sep, S4)
+ if(l-i >= 4)
+ . = text("[][][][][][][][]", ., S4)
+ if(l-i >= 2)
+ . = text("[][][][]", ., S1, sep, S1)
+ if(l > i)
+ . = text("[][][]", ., sep, S1)
+
+ #undef S64
+ #undef S16
+ #undef S4
+ #undef S1
+
+ else
+ #define S1 ls[++i]
+ #define S4 S1, S1, S1, S1
+ #define S16 S4, S4, S4, S4
+ #define S64 S16, S16, S16, S16
+
+ while(l-i >= 128)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
+ if(l-i >= 64)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
+ [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64)
+ if(l-i >= 32)
+ . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16)
+ if(l-i >= 16)
+ . = text("[][][][][][][][][][][][][][][][][]", ., S16)
+ if(l-i >= 8)
+ . = text("[][][][][][][][][]", ., S4, S4)
+ if(l-i >= 4)
+ . = text("[][][][][]", ., S4)
+ if(l-i >= 2)
+ . = text("[][][]", ., S1, S1)
+ if(l > i)
+ . += S1
+
+ #undef S64
+ #undef S16
+ #undef S4
+ #undef S1
-//slower then dd_list2text, but correctly processes associative lists.
+//slower then list2text, but correctly processes associative lists.
proc/tg_list2text(list/list, glue=",")
if(!istype(list) || !list.len)
return
@@ -108,56 +172,31 @@ proc/tg_list2text(list/list, glue=",")
return output
-//Converts a text string into a list by splitting the string at each seperator found in text (discarding the seperator)
-//Returns an empty list if the text cannot be split, or the split text in a list.
-//Not giving a "" seperator will cause the text to be broken into a list of single letters.
-/proc/text2list(text, seperator="\n")
+//Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator)
+/proc/text2list(text, delimiter="\n")
+ var/delim_len = length(delimiter)
+ if(delim_len < 1) return list(text)
. = list()
+ var/last_found = 1
+ var/found
+ do
+ found = findtext(text, delimiter, last_found, 0)
+ . += copytext(text, last_found, found)
+ last_found = found + delim_len
+ while(found)
- var/text_len = length(text) //length of the input text
- var/seperator_len = length(seperator) //length of the seperator text
-
- if(text_len >= seperator_len)
- var/i
- var/last_i = 1
-
- for(i=1,i<=(text_len+1-seperator_len),i++)
- if( cmptext(copytext(text,i,i+seperator_len), seperator) )
- if(i != last_i)
- . += copytext(text,last_i,i)
- last_i = i + seperator_len
-
- if(last_i <= text_len)
- . += copytext(text, last_i, 0)
- else
- . += text
- return .
-
-//Converts a text string into a list by splitting the string at each seperator found in text (discarding the seperator)
-//Returns an empty list if the text cannot be split, or the split text in a list.
-//Not giving a "" seperator will cause the text to be broken into a list of single letters.
//Case Sensitive!
-/proc/text2listEx(text, seperator="\n")
+/proc/text2listEx(text, delimiter="\n")
+ var/delim_len = length(delimiter)
+ if(delim_len < 1) return list(text)
. = list()
-
- var/text_len = length(text) //length of the input text
- var/seperator_len = length(seperator) //length of the seperator text
-
- if(text_len >= seperator_len)
- var/i
- var/last_i = 1
-
- for(i=1,i<=(text_len+1-seperator_len),i++)
- if( cmptextEx(copytext(text,i,i+seperator_len), seperator) )
- if(i != last_i)
- . += copytext(text,last_i,i)
- last_i = i + seperator_len
-
- if(last_i <= text_len)
- . += copytext(text, last_i, 0)
- else
- . += text
- return .
+ var/last_found = 1
+ var/found
+ do
+ found = findtextEx(text, delimiter, last_found, 0)
+ . += copytext(text, last_found, found)
+ last_found = found + delim_len
+ while(found)
//Splits the text of a file at seperator and returns them in a list.
/proc/file2list(filename, seperator="\n")
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 2c6c33b316c..0e83de642da 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -184,7 +184,7 @@
if(type == "config")
switch (name)
if ("resource_urls")
- config.resource_urls = stringsplit(value, " ")
+ config.resource_urls = text2list(value, " ")
if ("admin_legacy_system")
config.admin_legacy_system = 1
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 95adc92dcc3..376df936782 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -297,7 +297,7 @@ var/list/advance_cures = list(
for(var/datum/symptom/S in symptoms)
L += S.id
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
- var/result = dd_list2text(L, ":")
+ var/result = list2text(L, ":")
id = result
return result
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index e91fe673797..fdff83ab13b 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -274,7 +274,7 @@
if(locked)
user << "\red Circuit controls are locked."
return
- var/existing_networks = dd_list2text(network,",")
+ var/existing_networks = list2text(network,",")
var/input = strip_html(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks))
if(!input)
usr << "No input found please hang up and try your call again."
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 4e7ae4d6488..5c5b1b6fd81 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -1,6 +1,6 @@
/obj/item/blueprints
name = "station blueprints"
- desc = "Blueprints of the station. There's stamp \"Classified\" and several coffee stains on it."
+ desc = "Blueprints of the station. There is a \"Classified\" stamp and several coffee stains on it."
icon = 'icons/obj/items.dmi'
icon_state = "blueprints"
attack_verb = list("attacked", "bapped", "hit")
@@ -21,7 +21,7 @@
/obj/item/blueprints/attack_self(mob/M as mob)
if (!istype(M,/mob/living/carbon/human))
- M << "This is stack of useless pieces of harsh paper." //monkeys cannot into projecting
+ M << "This stack of blue paper means nothing to you." //monkeys cannot into projecting
return
interact()
return
@@ -53,18 +53,18 @@
switch (get_area_type())
if (AREA_SPACE)
text += {"
-
According this blueprints you are in open space now.
+According the blueprints, you are now in outer space. Hold your breath.
"} if (AREA_STATION) text += {" -According this blueprints you are in [A.name] now.
+According the blueprints, you are now in \"[A.name]\".
You may move an amendment to the drawing.
"} if (AREA_SPECIAL) text += {" -This place isn't noted on these blueprints.
+This place isn't noted on the blueprint.
"} else return @@ -105,20 +105,20 @@ move an amendment to the drawing. if(!istype(res,/list)) switch(res) if(ROOM_ERR_SPACE) - usr << "\red New area must be complete airtight!" + usr << "\red The new area must be completely airtight!" return if(ROOM_ERR_TOOLARGE) - usr << "\red New area too large!" + usr << "\red The new area too large!" return else usr << "\red Error! Please notify administration!" return var/list/turf/turfs = res - var/str = trim(stripped_input(usr,"New area title","Blueprints editing", "", MAX_NAME_LEN)) + var/str = trim(stripped_input(usr,"New area name:","Blueprint Editing", "", MAX_NAME_LEN)) if(!str || !length(str)) //cancel return if(length(str) > 50) - usr << "\red Text too long." + usr << "\red Name too long." return var/area/A = new A.name = str @@ -153,8 +153,8 @@ move an amendment to the drawing. /obj/item/blueprints/proc/edit_area() var/area/A = get_area() //world << "DEBUG: edit_area" - var/prevname = A.name - var/str = trim(stripped_input(usr,"New area title","Blueprints editing", prevname, MAX_NAME_LEN)) + var/prevname = "[A.name]" + var/str = trim(stripped_input(usr,"New area name:","Blueprint Editing", prevname, MAX_NAME_LEN)) if(!str || !length(str) || str==prevname) //cancel return if(length(str) > 50) diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index d54d4dfde69..054ebe36b31 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -100,7 +100,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid if (href_list["buy_item"]) var/item = href_list["buy_item"] - var/list/split = stringsplit(item, ":") // throw away variable + var/list/split = text2list(item, ":") // throw away variable if(split.len == 2) // Collect category and number diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index f9a1bbe874e..86ecab5f7d7 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -594,7 +594,7 @@ obj/structure/ex_act(severity) if(text in direction_table) return direction_table[text] - var/list/split_text = stringsplit(text, "-") + var/list/split_text = text2list(text, "-") // If the first token is D, the icon_state represents // a purely decorative tube, and doesn't actually diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 6e642d8aca7..a723fe37956 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -2,7 +2,7 @@ /datum/admins/proc/create_mob(var/mob/user) if (!create_mob_html) var/mobjs = null - mobjs = dd_list2text(typesof(/mob), ";") + mobjs = list2text(typesof(/mob), ";") create_mob_html = file2text('html/create_object.html') create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"") diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index 73e7cef9199..5b5f926e4b1 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -3,7 +3,7 @@ /datum/admins/proc/create_object(var/mob/user) if (!create_object_html) var/objectjs = null - objectjs = dd_list2text(typesof(/obj), ";") + objectjs = list2text(typesof(/obj), ";") create_object_html = file2text('html/create_object.html') create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"") @@ -21,7 +21,7 @@ if (!quick_create_object_html) var/objectjs = null - objectjs = dd_list2text(typesof(path), ";") + objectjs = list2text(typesof(path), ";") quick_create_object_html = file2text('html/create_object.html') quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"") diff --git a/code/modules/admin/create_turf.dm b/code/modules/admin/create_turf.dm index 56f719b47d1..0938b7bd33d 100644 --- a/code/modules/admin/create_turf.dm +++ b/code/modules/admin/create_turf.dm @@ -2,7 +2,7 @@ /datum/admins/proc/create_turf(var/mob/user) if (!create_turf_html) var/turfjs = null - turfjs = dd_list2text(typesof(/turf), ";") + turfjs = list2text(typesof(/turf), ";") create_turf_html = file2text('html/create_object.html') create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index f70bd239438..9d211461884 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1675,7 +1675,7 @@ alert("Select fewer object types, (max 5)") return else if(length(removed_paths)) - alert("Removed:\n" + dd_list2text(removed_paths, "\n")) + alert("Removed:\n" + list2text(removed_paths, "\n")) var/list/offset = text2list(href_list["offset"],",") var/number = dd_range(1, 100, text2num(href_list["object_count"])) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2a704642af3..56171656dfb 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -975,16 +975,16 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs", "Clients","Respawnable Mobs")) if("Players") - usr << dd_list2text(player_list,",") + usr << list2text(player_list,",") if("Admins") - usr << dd_list2text(admins,",") + usr << list2text(admins,",") if("Mobs") - usr << dd_list2text(mob_list,",") + usr << list2text(mob_list,",") if("Living Mobs") - usr << dd_list2text(living_mob_list,",") + usr << list2text(living_mob_list,",") if("Dead Mobs") - usr << dd_list2text(dead_mob_list,",") + usr << list2text(dead_mob_list,",") if("Clients") - usr << dd_list2text(clients,",") + usr << list2text(clients,",") if("Respawnable Mobs") - usr << dd_list2text(respawnable_list,",") + usr << list2text(respawnable_list,",") diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm new file mode 100644 index 00000000000..48d4812bac1 --- /dev/null +++ b/code/modules/detectivework/scanner.dm @@ -0,0 +1,401 @@ +//CONTAINS: Detective's Scanner + + +/obj/item/device/detective_scanner + name = "Scanner" + desc = "Used to scan objects for DNA and fingerprints." + icon_state = "forensic1" + var/amount = 20.0 + var/list/stored = list() + w_class = 3.0 + item_state = "electronic" + flags = FPRINT | TABLEPASS | CONDUCT | NOBLUDGEON + slot_flags = SLOT_BELT + + 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) + add_fingerprint(user) + if (W) + W.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." + flick("forensic0",src) + return 0 + if (( !( istype(M.dna, /datum/dna) ) || M.gloves) ) + user << "\blue No fingerprints found on [M]" + flick("forensic0",src) + return 0 + else + if (src.amount < 1) + user << text("\blue Fingerprints scanned on [M]. Need more cards to print.") + else + src.amount-- + var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc ) + F.amount = 1 + F.add_fingerprint(M) + F.icon_state = "fingerprint1" + F.name = text("FPrintC- '[M.name]'") + + user << "\blue Done printing." + user << "\blue [M]'s Fingerprints: [md5(M.dna.uni_identity)]" + if ( !M.blood_DNA || !M.blood_DNA.len ) + user << "\blue No blood found on [M]" + if(M.blood_DNA) + del(M.blood_DNA) + else + user << "\blue Blood found on [M]. Analysing..." + spawn(15) + for(var/blood in M.blood_DNA) + user << "\blue Blood type: [M.blood_DNA[blood]]\nDNA: [blood]" + return + + afterattack(atom/A as obj|turf|area, mob/user as mob, proximity) + if(!proximity) return + if(loc != user) + return + if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit. + return + if(istype(A,/obj/item/weapon/f_card)) + user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\"" + flick("forensic0",src) + return + + add_fingerprint(user) + + + //Special case for blood splaters. + if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable/blood/gibs)) + if(!isnull(A.blood_DNA)) + for(var/blood in A.blood_DNA) + user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]" + flick("forensic2",src) + return + + //General + if ((!A.fingerprints || !A.fingerprints.len) && !A.suit_fibers && !A.blood_DNA) + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\ + "You hear a faint hum of electrical equipment.") + flick("forensic0",src) + return 0 + + if(add_data(A)) + user << "\blue Object already in internal memory. Consolidating data..." + flick("forensic2",src) + return + + + //PRINTS + if(!A.fingerprints || !A.fingerprints.len) + if(A.fingerprints) + del(A.fingerprints) + else + user << "\blue Isolated [A.fingerprints.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + var/list/complete_prints = list() + for(var/i in A.fingerprints) + var/print = A.fingerprints[i] + if(stringpercent(print) <= FINGERPRINT_COMPLETE) + complete_prints += print + 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]" + + //FIBERS + if(A.suit_fibers) + user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + flick("forensic2",src) + + //Blood + if (A.blood_DNA) + user << "\blue Blood found on [A]. Analysing..." + spawn(15) + for(var/blood in A.blood_DNA) + user << "Blood type: \red [A.blood_DNA[blood]] \t \black DNA: \red [blood]" + if(prob(80) || !A.fingerprints) + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "You finish scanning \the [A].",\ + "You hear a faint hum of electrical equipment.") + flick("forensic2",src) + return 0 + else + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]\n[user.gender == MALE ? "He" : "She"] seems to perk up slightly at the readout." ,\ + "The results of the scan pique your interest.",\ + "You hear a faint hum of electrical equipment, and someone making a thoughtful noise.") + flick("forensic2",src) + return 0 + return + + proc/add_data(atom/A as mob|obj|turf|area) + //I love associative lists. + var/list/data_entry = stored["\ref [A]"] + if(islist(data_entry)) //Yay, it was already stored! + //Merge the fingerprints. + var/list/data_prints = data_entry[1] + for(var/print in A.fingerprints) + var/merged_print = data_prints[print] + if(!merged_print) + data_prints[print] = A.fingerprints[print] + else + data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print]) + + //Now the fibers + var/list/fibers = data_entry[2] + 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 = data_entry[3] + if(!blood) + blood = list() + if(A.blood_DNA && A.blood_DNA.len) + for(var/main_blood in A.blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = A.blood_DNA[blood] + return 1 + var/list/sum_list[4] //Pack it back up! + sum_list[1] = A.fingerprints ? A.fingerprints.Copy() : null + sum_list[2] = A.suit_fibers ? A.suit_fibers.Copy() : null + sum_list[3] = A.blood_DNA ? A.blood_DNA.Copy() : null + sum_list[4] = "\The [A] in \the [get_area(A)]" + stored["\ref [A]"] = sum_list + return 0 + +/obj/item/device/detective_scanner/forger + var/list/custom_forgery[3] + var/forging = 0 + + New() + ..() + custom_forgery[1] = list() + custom_forgery[2] = list() + custom_forgery[3] = list() + + attack_self(var/mob/user as mob) + var/list/customprints = list() + var/list/customfiber = list() + var/list/customblood = list() + if(forging) + user << "\red You are already forging evidence" + return 0 + clear_forgery() + //fingerprint loop + while(1) + var/print = html_encode(input(usr,"Please enter a custom fingerprint or hit cancel to finish fingerprints") as text|null) + if(!usr.client) + forging = 0 + break + if(!print ) + break + customprints[print] = print + while(1) + var/fiber = html_encode(input(usr,"Please enter a custom fiber/material trace or hit cancel to finish fibers/materials") as text|null) + if(!usr.client) + forging = 0 + break + if(!fiber) + break + customfiber[fiber] = null + while(1) + var/blood = html_encode(input(usr,"Please enter a custom Blood DNA or hit cancel to finish forging") as text|null) + var/bloodtype = html_encode(input(usr,"Please enter a custom Blood Type") as text|null) + if(!usr.client) + forging = 0 + break + if(!blood) + break + customblood[blood] = bloodtype + forging = 0 + if(!customprints.len && !customfiber.len) + user << "\blue No forgery saved." + return + user << "\blue Forgery saved and will be tied to the next applicable scanned item." + custom_forgery[1] = customprints ? customprints.Copy() : null + custom_forgery[2] = customfiber ? customfiber.Copy() : null + custom_forgery[3] = customblood ? customblood.Copy() : null + +//shameless copy pasting + afterattack(atom/A as obj|turf|area, mob/user as mob) + var/list/custom_finger = list() + var/list/custom_fiber = list() + var/list/custom_blood = list() + + if(custom_forgery) + custom_finger = custom_forgery[1] + custom_fiber = custom_forgery[2] + custom_blood = custom_forgery[3] + + if(!in_range(A,user)) + return + if(loc != user) + return + if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit. + return + if(istype(A,/obj/item/weapon/f_card)) + user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\"" + return + + add_fingerprint(user) + + + //Special case for blood splaters. + if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune)) + if(!isnull(A.blood_DNA)) + for(var/blood in A.blood_DNA) + user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]" + return + + //General + if ((!A.fingerprints || !A.fingerprints.len) && !A.suit_fibers && !A.blood_DNA) + if(!custom_finger.len && !custom_fiber.len && !custom_blood.len) + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\ + "You hear a faint hum of electrical equipment.") + return 0 + else + user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\ + "\blue Unable to locate any fingerprints, materials, fibers, or blood on [A], loading custom forgery instead.",\ + "You hear a faint hum of electrical equipment.") + + + if(add_data(A)) + user << "\blue Object already in internal memory. Consolidating data..." + return + + + //PRINTS + if(!A.fingerprints || !A.fingerprints.len) + if(A.fingerprints) + del(A.fingerprints) + if(custom_finger.len) + user << "\blue Isolated [custom_finger.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + user << "\blue Found [custom_finger.len] intact prints" + for(var/i in custom_finger) + user << "\blue [i]" + else if(A.fingerprints && A.fingerprints.len) + user << "\blue Isolated [A.fingerprints.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + var/list/complete_prints = list() + for(var/i in A.fingerprints) + var/print = A.fingerprints[i] + if(stringpercent(print) <= FINGERPRINT_COMPLETE) + complete_prints += print + 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]" + + //FIBERS + if(custom_fiber.len) + user << "\blue Forged Fibers/Materials Data Found: Scan with Hi-Res Forensic Scanner to retrieve." + else if(A.suit_fibers) + user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve." + + + //Blood + if(custom_blood.len) + user << "\blue Forged Blood found. Analysing..." + spawn(15) + for(var/blood in custom_blood) + user << "Blood type: \red [custom_blood[blood]] \t \black DNA: \red [blood]" + else if (A.blood_DNA) + user << "\blue Blood found on [A]. Analysing..." + spawn(15) + for(var/blood in A.blood_DNA) + user << "Blood type: \red [A.blood_DNA[blood]] \t \black DNA: \red [blood]" + return + + add_data(atom/A as mob|obj|turf|area) + //I love associative lists. + var/list/data_entry = stored["\ref [A]"] + var/list/custom_finger = list() + var/list/custom_fiber = list() + var/list/custom_blood = list() + + if(custom_forgery) + custom_finger = custom_forgery[1] + custom_fiber = custom_forgery[2] + custom_blood = custom_forgery[3] + + if(islist(data_entry)) //Yay, it was already stored! + //Merge the fingerprints. + var/list/data_prints = data_entry[1] + if(custom_finger.len) + for(var/print in custom_finger) + var/merged_print = data_prints[print] + if(!merged_print) + data_prints[print] = custom_finger + else + data_prints[print] = stringmerge(data_prints[print],custom_finger[print]) + else + for(var/print in A.fingerprints) + var/merged_print = data_prints[print] + if(!merged_print) + data_prints[print] = A.fingerprints[print] + else + data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print]) + + //Now the fibers + var/list/fibers = data_entry[2] + if(!fibers) + fibers = list() + if(custom_fiber.len) + for(var/j = 1, j <= custom_fiber.len, j++) //Fibers~~~ + if(!fibers.Find(custom_fiber[j])) //It isn't! Add! + fibers += custom_fiber[j] + + else 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 = data_entry[3] + if(!blood) + blood = list() + if(custom_blood.len) + for(var/main_blood in custom_blood) + if(!blood[main_blood]) + blood[main_blood] = custom_blood[blood] + else if(A.blood_DNA && A.blood_DNA.len) + for(var/main_blood in A.blood_DNA) + if(!blood[main_blood]) + blood[main_blood] = A.blood_DNA[blood] + return 1 + var/list/sum_list[4] //Pack it back up! + if(custom_finger.len || custom_fiber.len || custom_blood.len) + sum_list[1] = custom_finger ? custom_finger.Copy() : null + sum_list[2] = custom_fiber ? custom_fiber.Copy() : null + sum_list[3] = custom_blood ? custom_blood.Copy() : null + else + sum_list[1] = A.fingerprints ? A.fingerprints.Copy() : null + sum_list[2] = A.suit_fibers ? A.suit_fibers.Copy() : null + sum_list[3] = A.blood_DNA ? A.blood_DNA.Copy() : null + sum_list[4] = "\The [A] in \the [get_area(A)]" + stored["\ref [A]"] = sum_list + clear_forgery() + return 0 + + proc/clear_forgery() + if(custom_forgery.len) + custom_forgery[1] = list() + custom_forgery[2] = list() + custom_forgery[3] = list() \ No newline at end of file diff --git a/code/modules/flufftext/TextFilters.dm b/code/modules/flufftext/TextFilters.dm index 6c6578bb863..44cc91a8e45 100644 --- a/code/modules/flufftext/TextFilters.dm +++ b/code/modules/flufftext/TextFilters.dm @@ -57,7 +57,7 @@ proc/NewStutter(phrase,stunned) split_phrase[index] = word - return sanitize(dd_list2text(split_phrase," ")) + return sanitize(list2text(split_phrase," ")) proc/Stagger(mob/M,d) //Technically not a filter, but it relates to drunkenness. step(M, pick(d,turn(d,90),turn(d,-90))) @@ -78,6 +78,6 @@ proc/Ellipsis(original_msg, chance = 50) else new_words += w - new_msg = dd_list2text(new_words," ") + new_msg = list2text(new_words," ") return new_msg diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index d55db70273d..c737143e026 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -14,7 +14,7 @@ if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue temp_message[H] = ninjaspeak(temp_message[H]) pick_list -= H - message = dd_list2text(temp_message, " ") + message = list2text(temp_message, " ") message = replacetext(message, "o", "¤") message = replacetext(message, "p", "þ") message = replacetext(message, "l", "£") @@ -75,4 +75,3 @@ /mob/living/carbon/human/proc/GetSpecialVoice() return special_voice - diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index e8ab1a3f944..4159ac04845 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -52,7 +52,7 @@ if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue temp_message[H] = ninjaspeak(temp_message[H]) pick_list -= H - message = dd_list2text(temp_message, " ") + message = list2text(temp_message, " ") message = replacetext(message, "o", "¤") message = replacetext(message, "p", "þ") message = replacetext(message, "l", "£") diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 151ac3d9850..9ac4a11e7bf 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -85,7 +85,7 @@ var/const/VOX_PATH = "sound/vox_fem/" if(!message || announcing_vox > world.time) return - var/list/words = stringsplit(trim(message), " ") + var/list/words = text2list(trim(message), " ") var/list/incorrect_words = list() if(words.len > 30) @@ -141,4 +141,4 @@ var/const/VOX_PATH = "sound/vox_fem/" for(var/file in vox_files) // src << "Downloading [file]" var/sound/S = sound("[VOX_PATH][file]") - src << browse_rsc(S) \ No newline at end of file + src << browse_rsc(S) diff --git a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm index 46f78087e69..f5180300758 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm @@ -30,7 +30,7 @@ /*var/l = lentext(msg) if(findtext(msg," ",l,l+1)==0) msg+=" "*/ - seperate = stringsplit(msg, " ") + seperate = text2list(msg, " ") for(var/Xa = 1,Xa