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.

Mark this place as new area.

"} 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