diff --git a/code/game/objects/items/devices/scanners/gas.dm b/code/game/objects/items/devices/scanners/gas.dm
new file mode 100644
index 0000000000..ca35911448
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/gas.dm
@@ -0,0 +1,36 @@
+/obj/item/device/analyzer
+ name = "gas analyzer"
+ desc = "A hand-held environmental scanner which reports current gas levels."
+ icon_state = "atmos"
+ item_state = "analyzer"
+ w_class = ITEMSIZE_SMALL
+ slot_flags = SLOT_BELT
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 20
+
+ matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
+
+ origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
+
+/obj/item/device/analyzer/atmosanalyze(var/mob/user)
+ var/air = user.return_air()
+ if (!air)
+ return
+
+ return atmosanalyzer_scan(src, air, user)
+
+/obj/item/device/analyzer/attack_self(mob/user as mob)
+ if (user.stat)
+ return
+ if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
+ to_chat(usr, "You don't have the dexterity to do this!")
+ return
+
+ analyze_gases(src, user)
+ return
+
+/obj/item/device/analyzer/afterattack(var/obj/O, var/mob/user, var/proximity)
+ if(proximity)
+ analyze_gases(O, user)
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners/halogen.dm b/code/game/objects/items/devices/scanners/halogen.dm
new file mode 100644
index 0000000000..f2f302c334
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/halogen.dm
@@ -0,0 +1,20 @@
+/obj/item/device/halogen_counter
+ name = "halogen counter"
+ icon_state = "eftpos"
+ desc = "A hand-held halogen counter, used to detect the level of irradiation of living beings."
+ w_class = ITEMSIZE_SMALL
+ origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 2)
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 7
+
+/obj/item/device/halogen_counter/attack(mob/living/M as mob, mob/living/user as mob)
+ if(!iscarbon(M))
+ to_chat(user, "This device can only scan organic beings!")
+ return
+ user.visible_message("\The [user] has analyzed [M]'s radiation levels!", "Analyzing Results for [M]:")
+ if(M.radiation)
+ to_chat(user, "Radiation Level: [M.radiation]")
+ else
+ to_chat(user, "No radiation detected.")
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners/health.dm
similarity index 57%
rename from code/game/objects/items/devices/scanners.dm
rename to code/game/objects/items/devices/scanners/health.dm
index 08952cb094..55dd3fa162 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners/health.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD:code/game/objects/items/devices/scanners.dm
#define DEFIB_TIME_LIMIT (10 MINUTES) //VOREStation addition- past this many seconds, defib is useless.
/*
CONTAINS:
@@ -546,3 +547,332 @@ HALOGEN COUNTER - Radcount on mobs
return
#undef DEFIB_TIME_LIMIT //VOREStation addition
+=======
+#define DEFIB_TIME_LIMIT (10 MINUTES) //VOREStation addition- past this many seconds, defib is useless.
+
+/obj/item/device/healthanalyzer
+ name = "health analyzer"
+ desc = "A hand-held body scanner able to distinguish vital signs of the subject."
+ icon_state = "health"
+ item_state = "healthanalyzer"
+ slot_flags = SLOT_BELT
+ throwforce = 3
+ w_class = ITEMSIZE_SMALL
+ throw_speed = 5
+ throw_range = 10
+ matter = list(MAT_STEEL = 200)
+ origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
+ var/mode = 1;
+ var/advscan = 0
+ var/showadvscan = 1
+
+/obj/item/device/healthanalyzer/New()
+ if(advscan >= 1)
+ verbs += /obj/item/device/healthanalyzer/proc/toggle_adv
+ ..()
+
+/obj/item/device/healthanalyzer/do_surgery(mob/living/M, mob/living/user)
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ scan_mob(M, user) //default surgery behaviour is just to scan as usual
+ return 1
+
+/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/user)
+ scan_mob(M, user)
+
+/obj/item/device/healthanalyzer/proc/scan_mob(mob/living/M, mob/living/user)
+ var/dat = ""
+ if ((CLUMSY in user.mutations) && prob(50))
+ user.visible_message("\The [user] has analyzed the floor's vitals!", "You try to analyze the floor's vitals!")
+ dat += "Analyzing Results for the floor:
"
+ dat += "Overall Status: Healthy
"
+ dat += "\tDamage Specifics: 0-0-0-0
"
+ dat += "Key: Suffocation/Toxin/Burns/Brute
"
+ dat += "Body Temperature: ???"
+ user.show_message("[dat]", 1)
+ return
+ if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
+ to_chat(user, "You don't have the dexterity to do this!")
+ return
+
+ flick("[icon_state]-scan", src) //makes it so that it plays the scan animation on a succesful scan
+ user.visible_message("[user] has analyzed [M]'s vitals.","You have analyzed [M]'s vitals.")
+
+ if (!ishuman(M) || M.isSynthetic())
+ //these sensors are designed for organic life
+ dat += "Analyzing Results for ERROR:\n\tOverall Status: ERROR
"
+ dat += "\tKey: Suffocation/Toxin/Burns/Brute
"
+ dat += "\tDamage Specifics: ? - ? - ? - ?
"
+ dat += "Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)
"
+ dat += "Warning: Blood Level ERROR: --% --cl. Type: ERROR
"
+ dat += "Subject's pulse: -- bpm."
+ user.show_message(dat, 1)
+ return
+
+ var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
+ var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss()
+ var/TX = M.getToxLoss() > 50 ? "[M.getToxLoss()]" : M.getToxLoss()
+ var/BU = M.getFireLoss() > 50 ? "[M.getFireLoss()]" : M.getFireLoss()
+ var/BR = M.getBruteLoss() > 50 ? "[M.getBruteLoss()]" : M.getBruteLoss()
+ if(M.status_flags & FAKEDEATH)
+ OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy
+ dat += "Analyzing Results for [M]:
"
+ dat += "Overall Status: dead
"
+ else
+ dat += "Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]
"
+ dat += "\tKey: Suffocation/Toxin/Burns/Brute
"
+ dat += "\tDamage Specifics: [OX] - [TX] - [BU] - [BR]
"
+ dat += "Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)
"
+ //VOREStation edit/addition starts
+ if(M.timeofdeath && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
+ dat += "Time of Death: [worldtime2stationtime(M.timeofdeath)]
"
+ var/tdelta = round(world.time - M.timeofdeath)
+ if(tdelta < (DEFIB_TIME_LIMIT * 10))
+ dat += "Subject died [DisplayTimeText(tdelta)] ago - resuscitation may be possible!
"
+ //VOREStation edit/addition ends
+ if(istype(M, /mob/living/carbon/human) && mode == 1)
+ var/mob/living/carbon/human/H = M
+ var/list/damaged = H.get_damaged_organs(1,1)
+ dat += "Localized Damage, Brute/Burn:
"
+ if(length(damaged)>0)
+ for(var/obj/item/organ/external/org in damaged)
+ if(org.robotic >= ORGAN_ROBOT)
+ continue
+ else
+ dat += " [capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : 0]"
+ dat += "[(org.status & ORGAN_BLEEDING)?"\[Bleeding\]":""] - "
+ dat += "[(org.burn_dam > 0) ? "[org.burn_dam]" : 0]
"
+ else
+ dat += " Limbs are OK.
"
+
+ OX = M.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
+ TX = M.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal"
+ BU = M.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K"
+ BR = M.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K"
+ if(M.status_flags & FAKEDEATH)
+ OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal"
+ dat += "[OX] | [TX] | [BU] | [BR]
"
+ if(M.radiation)
+ if(advscan >= 2 && showadvscan == 1)
+ var/severity = ""
+ if(M.radiation >= 75)
+ severity = "Critical"
+ else if(M.radiation >= 50)
+ severity = "Severe"
+ else if(M.radiation >= 25)
+ severity = "Moderate"
+ else if(M.radiation >= 1)
+ severity = "Low"
+ dat += "[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]
"
+ else
+ dat += "Radiation detected.
"
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(C.reagents.total_volume)
+ var/unknown = 0
+ var/reagentdata[0]
+ var/unknownreagents[0]
+ for(var/datum/reagent/R as anything in C.reagents.reagent_list)
+ if(R.scannable)
+ reagentdata["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ else
+ unknown++
+ unknownreagents["[R.id]"] = "\t[round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ if(reagentdata.len)
+ dat += "Beneficial reagents detected in subject's blood:
"
+ for(var/d in reagentdata)
+ dat += reagentdata[d]
+ if(unknown)
+ if(advscan >= 3 && showadvscan == 1)
+ dat += "Warning: Non-medical reagent[(unknown>1)?"s":""] detected in subject's blood:
"
+ for(var/d in unknownreagents)
+ dat += unknownreagents[d]
+ else
+ dat += "Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.
"
+ if(C.ingested && C.ingested.total_volume)
+ var/unknown = 0
+ var/stomachreagentdata[0]
+ var/stomachunknownreagents[0]
+ for(var/datum/reagent/R as anything in C.ingested.reagent_list)
+ if(R.scannable)
+ stomachreagentdata["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ if (advscan == 0 || showadvscan == 0)
+ dat += "[R.name] found in subject's stomach.
"
+ else
+ ++unknown
+ stomachunknownreagents["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ if(advscan >= 1 && showadvscan == 1)
+ dat += "Beneficial reagents detected in subject's stomach:
"
+ for(var/d in stomachreagentdata)
+ dat += stomachreagentdata[d]
+ if(unknown)
+ if(advscan >= 3 && showadvscan == 1)
+ dat += "Warning: Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach:
"
+ for(var/d in stomachunknownreagents)
+ dat += stomachunknownreagents[d]
+ else
+ dat += "Unknown substance[(unknown > 1)?"s":""] found in subject's stomach.
"
+ if(C.touching && C.touching.total_volume)
+ var/unknown = 0
+ var/touchreagentdata[0]
+ var/touchunknownreagents[0]
+ for(var/datum/reagent/R as anything in C.touching.reagent_list)
+ if(R.scannable)
+ touchreagentdata["[R.id]"] = "\t[round(C.touching.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ if (advscan == 0 || showadvscan == 0)
+ dat += "[R.name] found in subject's dermis.
"
+ else
+ ++unknown
+ touchunknownreagents["[R.id]"] = "\t[round(C.ingested.get_reagent_amount(R.id), 1)]u [R.name][(R.overdose && R.can_overdose_touch && R.volume > R.overdose) ? " - Overdose" : ""]
"
+ if(advscan >= 1 && showadvscan == 1)
+ dat += "Beneficial reagents detected in subject's dermis:
"
+ for(var/d in touchreagentdata)
+ dat += touchreagentdata[d]
+ if(unknown)
+ if(advscan >= 3 && showadvscan == 1)
+ dat += "Warning: Non-medical reagent[(unknown > 1)?"s":""] found in subject's dermis:
"
+ for(var/d in touchunknownreagents)
+ dat += touchunknownreagents[d]
+ else
+ dat += "Unknown substance[(unknown > 1)?"s":""] found in subject's dermis.
"
+ if(C.virus2.len)
+ for (var/ID in C.virus2)
+ if (ID in virusDB)
+ var/datum/data/record/V = virusDB[ID]
+ dat += "Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]
"
+ else
+ dat += "Warning: Unknown pathogen detected in subject's blood.
"
+ if (M.getCloneLoss())
+ dat += "Subject appears to have been imperfectly cloned.
"
+// if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
+// user.show_message("Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.")
+ if (M.has_brain_worms())
+ dat += "Subject suffering from aberrant brain activity. Recommend further scanning.
"
+ else if (M.getBrainLoss() >= 60 || !M.has_brain())
+ dat += "Subject is brain dead.
"
+ else if (M.getBrainLoss() >= 25)
+ dat += "Severe brain damage detected. Subject likely to have a traumatic brain injury.
"
+ else if (M.getBrainLoss() >= 10)
+ dat += "Significant brain damage detected. Subject may have had a concussion.
"
+ else if (M.getBrainLoss() >= 1 && advscan >= 2 && showadvscan == 1)
+ dat += "Minor brain damage detected.
"
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ for(var/obj/item/organ/internal/appendix/a in H.internal_organs)
+ var/severity = ""
+ if(a.inflamed > 3)
+ severity = "Severe"
+ else if(a.inflamed > 2)
+ severity = "Moderate"
+ else if(a.inflamed >= 1)
+ severity = "Mild"
+ if(severity)
+ dat += "[severity] inflammation detected in subject [a.name].
"
+ // Infections, fractures, and IB
+ var/basic_fracture = 0 // If it's a basic scanner
+ var/basic_ib = 0 // If it's a basic scanner
+ var/fracture_dat = "" // All the fractures
+ var/infection_dat = "" // All the infections
+ var/ib_dat = "" // All the IB
+ for(var/obj/item/organ/external/e in H.organs)
+ if(!e)
+ continue
+ // Broken limbs
+ if(e.status & ORGAN_BROKEN)
+ if((e.name in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_HEAD, BP_TORSO, BP_GROIN)) && (!e.splinted))
+ fracture_dat += "Unsecured fracture in subject [e.name]. Splinting recommended for transport.
"
+ else if(advscan >= 1 && showadvscan == 1)
+ fracture_dat += "Bone fractures detected in subject [e.name].
"
+ else
+ basic_fracture = 1
+ // Infections
+ if(e.has_infected_wound())
+ dat += "Infected wound detected in subject [e.name]. Disinfection recommended.
"
+ // IB
+ for(var/datum/wound/W in e.wounds)
+ if(W.internal)
+ if(advscan >= 1 && showadvscan == 1)
+ ib_dat += "Internal bleeding detected in subject [e.name].
"
+ else
+ basic_ib = 1
+ if(basic_fracture)
+ fracture_dat += "Bone fractures detected. Advanced scanner required for location.
"
+ if(basic_ib)
+ ib_dat += "Internal bleeding detected. Advanced scanner required for location.
"
+ dat += fracture_dat
+ dat += infection_dat
+ dat += ib_dat
+
+ // Blood level
+ if(M:vessel)
+ var/blood_volume = H.vessel.get_reagent_amount("blood")
+ var/blood_percent = round((blood_volume / H.species.blood_volume)*100)
+ var/blood_type = H.dna.b_type
+ if(blood_volume <= H.species.blood_volume*H.species.blood_level_danger)
+ dat += "Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]
"
+ else if(blood_volume <= H.species.blood_volume*H.species.blood_level_warning)
+ dat += "Warning: Blood Level VERY LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]
"
+ else if(blood_volume <= H.species.blood_volume*H.species.blood_level_safe)
+ dat += "Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]
"
+ else
+ dat += "Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]
"
+ dat += "Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.
" // VORE Edit: Missed a linebreak here.
+ if(istype(H.species, /datum/species/xenochimera)) // VOREStation Edit Start: Visible feedback for medmains on Xenochimera.
+ if(H.stat == DEAD && H.revive_ready == REVIVING_READY && !H.hasnutriment())
+ dat += "WARNING: Protein levels low. Subject incapable of reconstitution."
+ else if(H.revive_ready == REVIVING_NOW)
+ dat += "Subject is undergoing form reconstruction. Estimated time to finish is in: [round((H.revive_finished - world.time) / 10)] seconds."
+ else if(H.revive_ready == REVIVING_DONE)
+ dat += "Subject is ready to hatch. Transfer to dark room for holding with food available."
+ else if(H.stat == DEAD)
+ dat+= "WARNING: Defib will cause extreme pain and set subject feral. Sedation recommended prior to defibrillation."
+ else // If they bop them and they're not dead or reviving, give 'em a little notice.
+ dat += "Subject is a Xenochimera. Treat accordingly."
+ // VOREStation Edit End
+ user.show_message(dat, 1)
+
+/obj/item/device/healthanalyzer/verb/toggle_mode()
+ set name = "Switch Verbosity"
+ set category = "Object"
+
+ mode = !mode
+ switch (mode)
+ if(1)
+ to_chat(usr, "The scanner now shows specific limb damage.")
+ if(0)
+ to_chat(usr, "The scanner no longer shows limb damage.")
+
+/obj/item/device/healthanalyzer/proc/toggle_adv()
+ set name = "Toggle Advanced Scan"
+ set category = "Object"
+
+ showadvscan = !showadvscan
+ switch (showadvscan)
+ if(1)
+ to_chat(usr, "The scanner will now perform an advanced analysis.")
+ if(0)
+ to_chat(usr, "The scanner will now perform a basic analysis.")
+
+/obj/item/device/healthanalyzer/improved //reports bone fractures, IB, quantity of beneficial reagents in stomach; also regular health analyzer stuff
+ name = "improved health analyzer"
+ desc = "A miracle of medical technology, this handheld scanner can produce an accurate and specific report of a patient's biosigns."
+ advscan = 1
+ origin_tech = list(TECH_MAGNET = 5, TECH_BIO = 6)
+ icon_state = "health1"
+
+/obj/item/device/healthanalyzer/advanced //reports all of the above, as well as radiation severity and minor brain damage
+ name = "advanced health analyzer"
+ desc = "An even more advanced handheld health scanner, complete with a full biosign monitor and on-board radiation and neurological analysis suites."
+ advscan = 2
+ origin_tech = list(TECH_MAGNET = 6, TECH_BIO = 7)
+ icon_state = "health2"
+
+/obj/item/device/healthanalyzer/phasic //reports all of the above, as well as name and quantity of nonmed reagents in stomach
+ name = "phasic health analyzer"
+ desc = "Possibly the most advanced health analyzer to ever have existed, utilising bluespace technology to determine almost everything worth knowing about a patient."
+ advscan = 3
+ origin_tech = list(TECH_MAGNET = 7, TECH_BIO = 8)
+ icon_state = "health3"
+
+#undef DEFIB_TIME_LIMIT //VOREStation addition
+>>>>>>> 09d8a6582b... Merge pull request #13014 from ItsSelis/selis-scanner-split:code/game/objects/items/devices/scanners/health.dm
diff --git a/code/game/objects/items/devices/scanners/mass_spectrometer.dm b/code/game/objects/items/devices/scanners/mass_spectrometer.dm
new file mode 100644
index 0000000000..fee41eb880
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/mass_spectrometer.dm
@@ -0,0 +1,60 @@
+/obj/item/device/mass_spectrometer
+ name = "mass spectrometer"
+ desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample."
+ icon_state = "spectrometer"
+ w_class = ITEMSIZE_SMALL
+ flags = OPENCONTAINER
+ slot_flags = SLOT_BELT
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 20
+
+ matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
+
+ origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
+ var/details = 0
+ var/recent_fail = 0
+
+/obj/item/device/mass_spectrometer/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(5)
+ reagents = R
+ R.my_atom = src
+
+/obj/item/device/mass_spectrometer/on_reagent_change()
+ if(reagents.total_volume)
+ icon_state = initial(icon_state) + "_s"
+ else
+ icon_state = initial(icon_state)
+
+/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
+ if (user.stat)
+ return
+ if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
+ to_chat(user, "You don't have the dexterity to do this!")
+ return
+ if(reagents.total_volume)
+ var/list/blood_traces = list()
+ for(var/datum/reagent/R in reagents.reagent_list)
+ if(R.id != "blood")
+ reagents.clear_reagents()
+ to_chat(user, "The sample was contaminated! Please insert another sample")
+ return
+ else
+ blood_traces = params2list(R.data["trace_chem"])
+ break
+ var/dat = "Trace Chemicals Found: "
+ for(var/R in blood_traces)
+ if(details)
+ dat += "[R] ([blood_traces[R]] units) "
+ else
+ dat += "[R] "
+ to_chat(user, "[dat]")
+ reagents.clear_reagents()
+ return
+
+/obj/item/device/mass_spectrometer/adv
+ name = "advanced mass spectrometer"
+ icon_state = "adv_spectrometer"
+ details = 1
+ origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners/reagents.dm b/code/game/objects/items/devices/scanners/reagents.dm
new file mode 100644
index 0000000000..8310d13fab
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/reagents.dm
@@ -0,0 +1,46 @@
+/obj/item/device/reagent_scanner
+ name = "reagent scanner"
+ desc = "A hand-held reagent scanner which identifies chemical agents."
+ icon_state = "spectrometer"
+ item_state = "analyzer"
+ w_class = ITEMSIZE_SMALL
+ slot_flags = SLOT_BELT
+ throwforce = 5
+ throw_speed = 4
+ throw_range = 20
+ matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
+
+ origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
+ var/details = 0
+ var/recent_fail = 0
+
+/obj/item/device/reagent_scanner/afterattack(obj/O, mob/living/user, proximity)
+ if(!proximity || user.stat || !istype(O))
+ return
+ if(!istype(user))
+ return
+
+ if(!isnull(O.reagents))
+ if(!(O.flags & OPENCONTAINER)) // The idea is that the scanner has to touch the reagents somehow. This is done to prevent cheesing unidentified autoinjectors.
+ to_chat(user, span("warning", "\The [O] is sealed, and cannot be scanned by \the [src] until unsealed."))
+ return
+
+ var/dat = ""
+ if(O.reagents.reagent_list.len > 0)
+ var/one_percent = O.reagents.total_volume / 100
+ for (var/datum/reagent/R in O.reagents.reagent_list)
+ dat += "\n \t " + span("notice", "[R][details ? ": [R.volume / one_percent]%" : ""]")
+ if(dat)
+ to_chat(user, span("notice", "Chemicals found: [dat]"))
+ else
+ to_chat(user, span("notice", "No active chemical agents found in [O]."))
+ else
+ to_chat(user, span("notice", "No significant chemical agents found in [O]."))
+
+ return
+
+/obj/item/device/reagent_scanner/adv
+ name = "advanced reagent scanner"
+ icon_state = "adv_spectrometer"
+ details = 1
+ origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners_vr.dm b/code/game/objects/items/devices/scanners/sleevemate.dm
similarity index 99%
rename from code/game/objects/items/devices/scanners_vr.dm
rename to code/game/objects/items/devices/scanners/sleevemate.dm
index 1722617106..5308e2c842 100644
--- a/code/game/objects/items/devices/scanners_vr.dm
+++ b/code/game/objects/items/devices/scanners/sleevemate.dm
@@ -300,4 +300,4 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
if(stored_mind)
icon_state = "[initial(icon_state)]_on"
else
- icon_state = initial(icon_state)
+ icon_state = initial(icon_state)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners/slime.dm b/code/game/objects/items/devices/scanners/slime.dm
new file mode 100644
index 0000000000..adcdce06a0
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/slime.dm
@@ -0,0 +1,42 @@
+/obj/item/device/slime_scanner
+ name = "slime scanner"
+ icon_state = "xenobio"
+ item_state = "xenobio"
+ origin_tech = list(TECH_BIO = 1)
+ w_class = ITEMSIZE_SMALL
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 7
+ matter = list(MAT_STEEL = 30,MAT_GLASS = 20)
+
+/obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob)
+ if(!istype(M, /mob/living/simple_mob/slime/xenobio))
+ to_chat(user, "This device can only scan lab-grown slimes!")
+ return
+ var/mob/living/simple_mob/slime/xenobio/S = M
+ user.show_message("Slime scan results:
[S.slime_color] [S.is_adult ? "adult" : "baby"] slime
Health: [S.health]
Mutation Probability: [S.mutation_chance]")
+
+ var/list/mutations = list()
+ for(var/potential_color in S.slime_mutation)
+ var/mob/living/simple_mob/slime/xenobio/slime = potential_color
+ mutations.Add(initial(slime.slime_color))
+ user.show_message("Potental to mutate into [english_list(mutations)] colors.
Extract potential: [S.cores]
Nutrition: [S.nutrition]/[S.max_nutrition]")
+
+ if (S.nutrition < S.get_starve_nutrition())
+ user.show_message("Warning: Subject is starving!")
+ else if (S.nutrition < S.get_hunger_nutrition())
+ user.show_message("Warning: Subject is hungry.")
+ user.show_message("Electric change strength: [S.power_charge]")
+
+ if(S.has_AI())
+ var/datum/ai_holder/simple_mob/xenobio_slime/AI = S.ai_holder
+ if(AI.resentment)
+ user.show_message("Warning: Subject is harboring resentment.")
+ if(AI.rabid)
+ user.show_message("Subject is enraged and extremely dangerous!")
+ if(S.harmless)
+ user.show_message("Subject has been pacified.")
+ if(S.unity)
+ user.show_message("Subject is friendly to other slime colors.")
+
+ user.show_message("Growth progress: [S.amount_grown]/10")
\ No newline at end of file
diff --git a/vorestation.dme b/vorestation.dme
index cda95b7998..50eb2ee208 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1258,8 +1258,6 @@
#include "code\game\objects\items\devices\paicard_ch.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
-#include "code\game\objects\items\devices\scanners.dm"
-#include "code\game\objects\items\devices\scanners_vr.dm"
#include "code\game\objects\items\devices\spy_bug.dm"
#include "code\game\objects\items\devices\starcaster_ch.dm"
#include "code\game\objects\items\devices\suit_cooling.dm"
@@ -1296,6 +1294,13 @@
#include "code\game\objects\items\devices\radio\radio_vr.dm"
#include "code\game\objects\items\devices\radio\radio_yw.dm"
#include "code\game\objects\items\devices\radio\radiopack.dm"
+#include "code\game\objects\items\devices\scanners\gas.dm"
+#include "code\game\objects\items\devices\scanners\halogen.dm"
+#include "code\game\objects\items\devices\scanners\health.dm"
+#include "code\game\objects\items\devices\scanners\mass_spectrometer.dm"
+#include "code\game\objects\items\devices\scanners\reagents.dm"
+#include "code\game\objects\items\devices\scanners\sleevemate.dm"
+#include "code\game\objects\items\devices\scanners\slime.dm"
#include "code\game\objects\items\robot\robot_items.dm"
#include "code\game\objects\items\robot\robot_parts.dm"
#include "code\game\objects\items\robot\robot_upgrades.dm"