mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-13 08:56:49 +01:00
7a99813dd0
This adds the case dossier program. A program intended for investigators to use for their cases, with the ability to record evidence, photos, documents, people and their notes on a case. The rest of security is able to view cases in the program, but not edit them. Additionally, the forensic skill was added to evidence bags and photos, allowing a person to add the time, place and the person using them, mainly intended to be used with the case dossier program. Fibers and prints can now be gathered from objects inside evidence bags, to avoid contamination. Also fixed some bugs with taking photos of certain objects, such as airlocks. https://github.com/user-attachments/assets/92a880e9-9032-46d4-88c0-43d45b64f979
224 lines
7.5 KiB
Plaintext
224 lines
7.5 KiB
Plaintext
/obj/item/sample
|
|
name = "forensic sample"
|
|
icon = 'icons/obj/forensics.dmi'
|
|
w_class = WEIGHT_CLASS_TINY
|
|
var/list/evidence
|
|
var/list/source
|
|
var/label_text = ""
|
|
|
|
/obj/item/sample/Initialize(var/newloc, var/atom/supplied)
|
|
. = ..(newloc)
|
|
if(supplied)
|
|
copy_evidence(supplied)
|
|
name = "[initial(name)] ([supplied.get_swab_name()])"
|
|
LAZYADD(source, supplied.get_swab_name())
|
|
|
|
/obj/item/sample/print/Initialize(var/newloc, var/atom/supplied)
|
|
. = ..(newloc, supplied)
|
|
if(LAZYLEN(evidence))
|
|
icon_state = "fingerprint1"
|
|
|
|
/obj/item/sample/proc/copy_evidence(var/atom/supplied)
|
|
if(supplied.suit_fibers && supplied.suit_fibers.len)
|
|
LAZYADD(evidence, supplied.suit_fibers.Copy())
|
|
supplied.suit_fibers.Cut()
|
|
|
|
/obj/item/sample/proc/merge_evidence(var/obj/item/sample/supplied, var/mob/user)
|
|
if(!supplied.evidence || !supplied.evidence.len)
|
|
return 0
|
|
LAZYDISTINCTADD(evidence, supplied.evidence)
|
|
LAZYDISTINCTADD(source, supplied.source)
|
|
name = "[initial(name)] (combined)"
|
|
to_chat(user, SPAN_NOTICE("You transfer the contents of \the [initial(supplied.name)] into \the [src]."))
|
|
return 1
|
|
|
|
/obj/item/sample/print/merge_evidence(var/obj/item/sample/supplied, var/mob/user)
|
|
if(!supplied.evidence || !supplied.evidence.len)
|
|
return 0
|
|
for(var/print in supplied.evidence)
|
|
if(LAZYISIN(evidence, print))
|
|
LAZYSET(evidence, print, stringmerge(evidence[print],supplied.evidence[print]))
|
|
else
|
|
LAZYSET(evidence, print, supplied.evidence[print])
|
|
LAZYDISTINCTADD(source, supplied.source)
|
|
name = "[initial(name)] (combined)"
|
|
to_chat(user, SPAN_NOTICE("You overlay \the [src] and \the [initial(supplied.name)], combining the print records."))
|
|
return 1
|
|
|
|
/obj/item/sample/attackby(obj/item/attacking_item, mob/user, params)
|
|
if(attacking_item.type == src.type)
|
|
user.unEquip(attacking_item)
|
|
if(merge_evidence(attacking_item, user))
|
|
qdel(attacking_item)
|
|
return TRUE
|
|
else if (attacking_item.tool_behaviour == TOOL_PEN)
|
|
var/tmp_label = sanitizeSafe( tgui_input_text(user, "Enter a label for [name]", "Label", label_text, MAX_NAME_LEN), MAX_NAME_LEN )
|
|
if(length(tmp_label) > MAX_NAME_LEN)
|
|
to_chat(user, SPAN_WARNING("The label can be at most [MAX_NAME_LEN] characters long."))
|
|
else
|
|
to_chat(user, SPAN_NOTICE("You set the label to \"[tmp_label]\"."))
|
|
label_text = tmp_label
|
|
update_name_label()
|
|
return TRUE
|
|
return ..()
|
|
|
|
/obj/item/sample/proc/update_name_label()
|
|
if(label_text == null)
|
|
name = initial(name)
|
|
else
|
|
name = "[initial(name)] ([label_text])"
|
|
|
|
|
|
/atom/proc/get_swab_name()
|
|
return "\the [initial(name)]"
|
|
|
|
/obj/structure/machinery/door/get_swab_name()
|
|
if(name != initial(name))
|
|
return "\the [initial(name)]: [name]"
|
|
return ..()
|
|
|
|
/obj/item/sample/fibers
|
|
name = "fiber bag"
|
|
desc = "Used to hold fiber evidence for the detective."
|
|
icon_state = "fiberbag"
|
|
|
|
/obj/item/sample/fibers/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "Holds various fibre evidence. Place it in a slide and the slide into a microscope to check them."
|
|
|
|
/obj/item/sample/print
|
|
name = "fingerprint card"
|
|
desc = "Records a set of fingerprints."
|
|
icon = 'icons/obj/card.dmi'
|
|
icon_state = "fingerprint0"
|
|
item_state = "paper"
|
|
|
|
/obj/item/sample/print/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "A sample card for fingerprints. Risks putting your own prints on it if touched without gloves."
|
|
. += "Place the card in a microscope to examine the contents."
|
|
. += "Use in hand to put your prints on it."
|
|
. += "Target hands and click another creature to take their prints."
|
|
|
|
/obj/item/sample/print/attack_self(var/mob/user)
|
|
if(LAZYLEN(evidence))
|
|
return
|
|
if(!ishuman(user))
|
|
return
|
|
var/mob/living/carbon/human/H = user
|
|
if(H.gloves)
|
|
to_chat(user, SPAN_WARNING("Take \the [H.gloves] off first."))
|
|
return
|
|
|
|
to_chat(user, SPAN_NOTICE("You firmly press your fingertips onto the card."))
|
|
var/fullprint = H.get_full_print()
|
|
LAZYSET(evidence, fullprint, fullprint)
|
|
LAZYADD(source, "[H.name]")
|
|
name = "[initial(name)] (\the [H])"
|
|
icon_state = "fingerprint1"
|
|
|
|
/obj/item/sample/print/attack(mob/living/target_mob, mob/living/user, target_zone)
|
|
|
|
var/mob/living/carbon/human/H = target_mob
|
|
if(!istype(H))
|
|
return ..()
|
|
|
|
if(LAZYLEN(evidence))
|
|
return 0
|
|
|
|
|
|
if(H.gloves)
|
|
to_chat(user, SPAN_WARNING("\The [H] is wearing gloves."))
|
|
return 1
|
|
|
|
if(user != H && H.a_intent != "help" && !H.lying)
|
|
user.visible_message(SPAN_DANGER("\The [user] tries to take prints from \the [H], but they move away."))
|
|
return 1
|
|
|
|
if(target_zone == BP_R_HAND || target_zone == BP_L_HAND)
|
|
var/has_hand
|
|
var/obj/item/organ/external/O = H.organs_by_name[BP_R_HAND]
|
|
if(istype(O) && !O.is_stump())
|
|
has_hand = 1
|
|
else
|
|
O = H.organs_by_name[BP_L_HAND]
|
|
if(istype(O) && !O.is_stump())
|
|
has_hand = 1
|
|
if(!has_hand)
|
|
to_chat(user, SPAN_WARNING("They don't have any hands."))
|
|
return 1
|
|
user.visible_message("[user] takes a copy of \the [H]'s fingerprints.")
|
|
var/fullprint = H.get_full_print()
|
|
LAZYSET(evidence, fullprint, fullprint)
|
|
copy_evidence(src)
|
|
LAZYADD(source, "[H.name]")
|
|
name = "[initial(name)] (\the [H])"
|
|
icon_state = "fingerprint1"
|
|
return 1
|
|
return 0
|
|
|
|
/obj/item/sample/print/copy_evidence(var/atom/supplied)
|
|
if(supplied.fingerprints && supplied.fingerprints.len)
|
|
for(var/print in supplied.fingerprints)
|
|
LAZYSET(evidence, print, supplied.fingerprints[print])
|
|
supplied.fingerprints.Cut()
|
|
|
|
/obj/item/forensics/sample_kit
|
|
name = "fiber collection kit"
|
|
desc = "A magnifying glass and tweezers. Used to lift suit fibers."
|
|
icon_state = "m_glass"
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
item_flags = ITEM_FLAG_NO_BLUDGEON
|
|
var/evidence_type = "fiber"
|
|
var/evidence_path = /obj/item/sample/fibers
|
|
|
|
/obj/item/forensics/sample_kit/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "Click drag it onto an object to collect fiber evidence. Alternatively, click on an object with non-Help intent."
|
|
. += "Click an evidence bag to collect evidence from the object within it. Alternatively, using harm intent checks the evidence bag."
|
|
|
|
/obj/item/forensics/sample_kit/proc/can_take_sample(var/mob/user, var/atom/supplied)
|
|
return (supplied.suit_fibers && supplied.suit_fibers.len)
|
|
|
|
/obj/item/forensics/sample_kit/proc/take_sample(var/mob/user, var/atom/supplied)
|
|
var/obj/item/sample/S = new evidence_path(get_turf(user), supplied)
|
|
to_chat(user, SPAN_NOTICE("You transfer [S.evidence.len] [evidence_type]\s to \the [S]."))
|
|
|
|
/obj/item/forensics/sample_kit/afterattack(var/atom/A, var/mob/user, var/proximity)
|
|
if(!proximity)
|
|
return
|
|
add_fingerprint(user)
|
|
|
|
// We can sample items from within an evidence bag
|
|
if(user.a_intent != I_HURT && istype(A, /obj/item/evidencebag))
|
|
var/obj/item/evidencebag/bag = A
|
|
if(bag.stored_item)
|
|
A = bag.stored_item
|
|
|
|
if(can_take_sample(user, A))
|
|
take_sample(user,A)
|
|
return 1
|
|
else
|
|
to_chat(user, SPAN_WARNING("You are unable to locate any [evidence_type]s on \the [A]."))
|
|
return ..()
|
|
|
|
/obj/item/forensics/sample_kit/resolve_attackby(atom/A, mob/user, var/click_parameters)
|
|
if(user.a_intent != I_HELP)
|
|
return FALSE
|
|
. = ..()
|
|
|
|
/obj/item/forensics/sample_kit/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
|
|
var/mob/M = loc
|
|
if(ismob(M) && (M.get_active_hand() == src || M.get_inactive_hand() == src))
|
|
afterattack(over, user, TRUE)
|
|
|
|
/obj/item/forensics/sample_kit/powder
|
|
name = "fingerprint powder"
|
|
desc = "A jar containing aluminum powder and a specialized brush."
|
|
icon_state = "dust"
|
|
evidence_type = "fingerprint"
|
|
evidence_path = /obj/item/sample/print
|
|
|
|
/obj/item/forensics/sample_kit/powder/can_take_sample(var/mob/user, var/atom/supplied)
|
|
return (supplied.fingerprints && supplied.fingerprints.len)
|