diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 517d80c5b6f..482c3d8abdf 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -34,6 +34,7 @@ var/global/list/image/splatter_cache=list()
invisibility = 100
amount = 0
processing_objects -= src
+ ..(ignore=1)
/obj/effect/decal/cleanable/blood/Destroy()
for(var/datum/disease/D in viruses)
diff --git a/code/game/objects/effects/decals/Cleanable/tracks.dm b/code/game/objects/effects/decals/Cleanable/tracks.dm
index 0df1a5e12a1..472ea38b932 100644
--- a/code/game/objects/effects/decals/Cleanable/tracks.dm
+++ b/code/game/objects/effects/decals/Cleanable/tracks.dm
@@ -121,7 +121,8 @@ var/global/list/image/fluidtrack_cache=list()
updated=1
dirs |= comingdir|realgoing
- blood_DNA |= DNA.Copy()
+ if (islist(blood_DNA))
+ blood_DNA |= DNA.Copy()
if(updated)
update_icon()
@@ -169,4 +170,4 @@ var/global/list/image/fluidtrack_cache=list()
desc = "They look like tracks left by wheels."
gender = PLURAL
random_icon_states = null
- amount = 0
\ No newline at end of file
+ amount = 0
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 93d6a4bb52e..2db1e5e9486 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,8 +1,11 @@
/obj/effect/decal/cleanable
var/list/random_icon_states = list()
-/obj/effect/decal/cleanable/clean_blood()
- qdel(src)
+/obj/effect/decal/cleanable/clean_blood(var/ignore = 0)
+ if(!ignore)
+ qdel(src)
+ return
+ ..()
/obj/effect/decal/cleanable/New()
if (random_icon_states && length(src.random_icon_states) > 0)
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index c38a307fd2c..31d81167dde 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -12,8 +12,8 @@
/turf/simulated/clean_blood()
for(var/obj/effect/decal/cleanable/blood/B in contents)
- B.fluorescent = 0
- B.invisibility = 100
+ B.clean_blood()
+ ..()
/turf/simulated/New()
..()
@@ -115,6 +115,8 @@
if(istype(M))
for(var/obj/effect/decal/cleanable/blood/B in contents)
+ if(!B.blood_DNA)
+ B.blood_DNA = list()
if(!B.blood_DNA[M.dna.unique_enzymes])
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
B.virus2 = virus_copylist(M.virus2)
diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm
index f420e2ee399..5cc4ef0afba 100644
--- a/code/modules/detectivework/microscope/microscope.dm
+++ b/code/modules/detectivework/microscope/microscope.dm
@@ -89,18 +89,26 @@
user << report.info
return
-/obj/machinery/microscope/AltClick()
- if(usr.lying || !Adjacent(usr) || !ishuman(usr))
+/obj/machinery/microscope/proc/remove_sample(var/mob/living/remover)
+ if(!istype(remover) || remover.stat || !Adjacent(remover))
return ..()
if(!sample)
- usr << "\The [src] does not have a sample in it."
+ remover << "\The [src] does not have a sample in it."
return
- usr << "You remove \the [sample] from \the [src]."
+ remover << "You remove \the [sample] from \the [src]."
sample.forceMove(get_turf(src))
- usr.put_in_hands(sample)
+ remover.put_in_hands(sample)
sample = null
update_icon()
- return
+
+/obj/machinery/microscope/AltClick()
+ remove_sample(usr)
+
+/obj/machinery/microscope/MouseDrop(var/atom/other)
+ if(usr == other)
+ remove_sample(usr)
+ else
+ return ..()
/obj/machinery/microscope/update_icon()
icon_state = "microscope"
diff --git a/code/modules/detectivework/tools/swabs.dm b/code/modules/detectivework/tools/swabs.dm
index ecae69756f6..8319ed093fe 100644
--- a/code/modules/detectivework/tools/swabs.dm
+++ b/code/modules/detectivework/tools/swabs.dm
@@ -15,30 +15,30 @@
return ..()
if(is_used())
- return 0
+ return
var/mob/living/carbon/human/H = M
var/sample_type
if(H.wear_mask)
user << "\The [H] is wearing a mask."
- return 1
+ return
if(!H.dna || !H.dna.unique_enzymes)
user << "They don't seem to have DNA!"
- return 1
+ return
if(user != H && H.a_intent != "help" && !H.lying)
user.visible_message("\The [user] tries to take a swab sample from \the [H], but they move away.")
- return 1
+ return
if(user.zone_sel.selecting == "mouth")
if(!H.organs_by_name["head"])
user << "They don't have a head."
- return 1
+ return
if(H.species && (H.species.flags & NO_SCAN))
user << "They don't have any biological fluids to check!."
- return 1
+ return
user.visible_message("[user] swabs \the [H]'s mouth for a saliva sample.")
dna = list(H.dna.unique_enzymes)
sample_type = "DNA"
@@ -54,24 +54,21 @@
has_hand = 1
if(!has_hand)
user << "They don't have any hands."
- return 1
+ return
user.visible_message("[user] swabs [H]'s palm for a sample.")
sample_type = "GSR"
gsr = H.gunshot_residue
else
- return 0
+ return
if(sample_type)
- used = 1
- name = "[initial(name)] ([sample_type] - [H])"
- desc = "[initial(desc)] The label on the vial reads 'Sample of [sample_type] from [H].'."
- icon_state = "swab_used"
- return 1
- return 0
+ set_used(sample_type, H)
+ return
+ return 1
/obj/item/weapon/forensics/swab/afterattack(var/atom/A, var/mob/user, var/proximity)
- if(!proximity || istype(A, /obj/item/weapon/forensics/slide))
+ if(!proximity || istype(A, /obj/item/weapon/forensics/slide) || istype(A, /obj/machinery/dnaforensics))
return
if(is_used())
@@ -103,6 +100,7 @@
if(!A.blood_DNA || !A.blood_DNA.len) return
dna = A.blood_DNA.Copy()
sample_type = "blood"
+
else if(choice == "Gunshot Residue")
var/obj/item/clothing/B = A
if(!istype(B) || !B.gunshot_residue)
@@ -113,6 +111,10 @@
if(sample_type)
user.visible_message("\The [user] swabs \the [A] for a sample.", "You swab \the [A] for a sample.")
- name = "[initial(name)] ([sample_type] - [A])"
- desc = "[initial(desc)] The label on the vial reads 'Sample of [sample_type] from [A].'."
- icon_state = "swab_used"
+ set_used(sample_type, A)
+
+/obj/item/weapon/forensics/swab/proc/set_used(var/sample_str, var/atom/source)
+ name = "[initial(name)] ([sample_str] - [source])"
+ desc = "[initial(desc)] The label on the vial reads 'Sample of [sample_str] from [source].'."
+ icon_state = "swab_used"
+ used = 1