/* CONTAINS: T-RAY DETECTIVE SCANNER HEALTH ANALYZER GAS ANALYZER MASS SPECTROMETER REAGENT SCANNER */ /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 = "analyzer" flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 w_class = 2.0 throw_speed = 5 throw_range = 10 matter = list(DEFAULT_WALL_MATERIAL = 200) origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1) var/mode = 1; /obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob) if (( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) user << text("You try to analyze the floor's vitals!") for(var/mob/O in viewers(M, null)) O.show_message("\The [user] has analyzed the floor's vitals!", 1) user.show_message("Analyzing Results for The floor:", 1) user.show_message("Overall Status: Healthy", 1) user.show_message(" Damage Specifics: 0-0-0-0", 1) user.show_message("Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("Body Temperature: ???", 1) return if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") usr << "You don't have the dexterity to do this!" return user.visible_message("[user] has analyzed [M]'s vitals.","You have analyzed [M]'s vitals.") if (!istype(M,/mob/living/carbon/human) || M.isSynthetic()) //these sensors are designed for organic life user.show_message("Analyzing Results for ERROR:\n\t Overall Status: ERROR") user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message(" Damage Specifics: ? - ? - ? - ?") user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) user.show_message("Warning: Blood Level ERROR: --% --cl. Type: ERROR") user.show_message("Subject's pulse: -- bpm.") 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 user.show_message("Analyzing Results for [M]:") user.show_message("Overall Status: dead") else user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health - M.halloss]% healthy"]") user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message(" Damage Specifics: [OX] - [TX] - [BU] - [BR]") user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH))) user.show_message("Time of Death: [M.tod]") 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) user.show_message("Localized Damage, Brute/Burn:",1) if(length(damaged)>0) for(var/obj/item/organ/external/org in damaged) user.show_message(text(" [][]: [][] - []", capitalize(org.name), (org.status & ORGAN_ROBOT) ? "(Cybernetic)" : "", (org.brute_dam > 0) ? "[org.brute_dam]" : 0, (org.status & ORGAN_BLEEDING)?"\[Bleeding\]":"", (org.burn_dam > 0) ? "[org.burn_dam]" : 0),1) else user.show_message(" Limbs are OK.",1) 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" user.show_message("[OX] | [TX] | [BU] | [BR]") if(istype(M, /mob/living/carbon)) var/mob/living/carbon/C = M if(C.reagents.total_volume) var/unknown = 0 var/reagentdata[0] for(var/A in C.reagents.reagent_list) var/datum/reagent/R = A if(R.scannable) reagentdata["[R.id]"] = " [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]" else unknown++ if(reagentdata.len) user.show_message("Beneficial reagents detected in subject's blood:") for(var/d in reagentdata) user.show_message(reagentdata[d]) if(unknown) user.show_message("Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.") if(C.ingested && C.ingested.total_volume) var/unknown = 0 for(var/datum/reagent/R in C.ingested.reagent_list) if(R.scannable) user << "[R.name] found in subject's stomach." else ++unknown if(unknown) user << "Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach." if(C.virus2.len) for (var/ID in C.virus2) if (ID in virusDB) var/datum/data/record/V = virusDB[ID] user.show_message("Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]") // user.show_message(text("Warning: Unknown pathogen detected in subject's blood.")) if (M.getCloneLoss()) user.show_message("Subject appears to have been imperfectly cloned.") for(var/datum/disease/D in M.viruses) if(!D.hidden[SCANNER]) user.show_message(text("Warning: [D.form] Detected\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]")) // 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()) user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.") else if (M.getBrainLoss() >= 100 || !M.has_brain()) user.show_message("Subject is brain dead.") else if (M.getBrainLoss() >= 60) user.show_message("Severe brain damage detected. Subject likely to have mental retardation.") else if (M.getBrainLoss() >= 10) user.show_message("Significant brain damage detected. Subject may have had a concussion.") if(ishuman(M)) var/mob/living/carbon/human/H = M for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(!e) continue var/limb = e.name if(e.status & ORGAN_BROKEN) if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) user << "Unsecured fracture in subject [limb]. Splinting recommended for transport." if(e.has_infected_wound()) user << "Infected wound detected in subject [limb]. Disinfection recommended." for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(e && e.status & ORGAN_BROKEN) user.show_message(text("Bone fractures detected. Advanced scanner required for location."), 1) break for(var/obj/item/organ/external/e in H.organs) if(!e) continue for(var/datum/wound/W in e.wounds) if(W.internal) user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) break if(M:vessel) var/blood_volume = round(M:vessel.get_reagent_amount("blood")) var/blood_percent = blood_volume / 560 var/blood_type = M.dna.b_type blood_percent *= 100 if(blood_volume <= 500 && blood_volume > 336) user.show_message("Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]") else if(blood_volume <= 336) user.show_message("Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl. Type: [blood_type]") else user.show_message("Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]") user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") src.add_fingerprint(user) return /obj/item/device/healthanalyzer/verb/toggle_mode() set name = "Switch Verbosity" set category = "Object" mode = !mode switch (mode) if(1) usr << "The scanner now shows specific limb damage." if(0) usr << "The scanner no longer shows limb damage." /obj/item/device/analyzer name = "analyzer" desc = "A hand-held environmental scanner which reports current gas levels." icon_state = "atmos" item_state = "analyzer" w_class = 2.0 flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 throw_range = 20 matter = list(DEFAULT_WALL_MATERIAL = 30,"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 (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") usr << "You don't have the dexterity to do this!" return analyze_gases(src, user) return /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" item_state = "analyzer" w_class = 2.0 flags = CONDUCT | OPENCONTAINER slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 throw_range = 20 matter = list(DEFAULT_WALL_MATERIAL = 30,"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 (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") 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() 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] " 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) /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 = 2.0 flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 throw_range = 20 matter = list(DEFAULT_WALL_MATERIAL = 30,"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/user as mob, proximity) if(!proximity) return if (user.stat) return if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "You don't have the dexterity to do this!" return if(!istype(O)) return if(!isnull(O.reagents)) 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 [R][details ? ": [R.volume / one_percent]%" : ""]" if(dat) user << "Chemicals found: [dat]" else user << "No active chemical agents found in [O]." else user << "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) /obj/item/device/slime_scanner name = "slime scanner" icon_state = "adv_spectrometer" item_state = "analyzer" origin_tech = list(TECH_BIO = 1) w_class = 2.0 flags = CONDUCT throwforce = 0 throw_speed = 3 throw_range = 7 matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20) /obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob) if (!isslime(M)) user << "This device can only scan slimes!" return var/mob/living/carbon/slime/T = M user.show_message("Slime scan results:") user.show_message(text("[T.colour] [] slime", T.is_adult ? "adult" : "baby")) user.show_message(text("Nutrition: [T.nutrition]/[]", T.get_max_nutrition())) if (T.nutrition < T.get_starve_nutrition()) user.show_message("Warning: slime is starving!") else if (T.nutrition < T.get_hunger_nutrition()) user.show_message("Warning: slime is hungry") user.show_message("Electric change strength: [T.powerlevel]") user.show_message("Health: [T.health]") if (T.slime_mutation[4] == T.colour) user.show_message("This slime does not evolve any further") else if (T.slime_mutation[3] == T.slime_mutation[4]) if (T.slime_mutation[2] == T.slime_mutation[1]) user.show_message(text("Possible mutation: []", T.slime_mutation[3])) user.show_message("Genetic destability: [T.mutation_chance/2]% chance of mutation on splitting") else user.show_message(text("Possible mutations: [], [], [] (x2)", T.slime_mutation[1], T.slime_mutation[2], T.slime_mutation[3])) user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting") else user.show_message(text("Possible mutations: [], [], [], []", T.slime_mutation[1], T.slime_mutation[2], T.slime_mutation[3], T.slime_mutation[4])) user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting") if (T.cores > 1) user.show_message("Anomalious slime core amount detected") user.show_message("Growth progress: [T.amount_grown]/10")