/* CONTAINS: T-RAY DETECTIVE SCANNER HEALTH ANALYZER GAS ANALYZER PLANT ANALYZER MASS SPECTROMETER REAGENT SCANNER */ /obj/item/device/t_scanner name = "T-ray scanner" desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." icon_state = "t-ray0" var/on = 0 slot_flags = SLOT_BELT w_class = 2 item_state = "electronic" m_amt = 150 origin_tech = "magnets=1;engineering=1" var/scan_range = 1 var/pulse_duration = 10 /obj/item/device/t_scanner/longer_pulse origin_tech = "magnets=2;engineering=2" pulse_duration = 50 /obj/item/device/t_scanner/extended_range origin_tech = "magnets=1;engineering=3" scan_range = 3 /obj/item/device/t_scanner/extended_range/longer_pulse origin_tech = "magnets=2;engineering=3" scan_range = 3 pulse_duration = 50 /obj/item/device/t_scanner/Destroy() if(on) processing_objects.Remove(src) return ..() /obj/item/device/t_scanner/attack_self(mob/user) on = !on icon_state = copytext(icon_state, 1, length(icon_state))+"[on]" if(on) processing_objects.Add(src) /obj/item/device/t_scanner/process() if(!on) processing_objects.Remove(src) return null scan() /obj/item/device/t_scanner/proc/scan() for(var/turf/T in range(scan_range, src.loc) ) if(!T.intact) continue for(var/obj/O in T.contents) if(O.level != 1) continue if(O.invisibility == 101) O.invisibility = 0 O.alpha = 128 spawn(pulse_duration) if(O) var/turf/U = O.loc if(U.intact) O.invisibility = 101 O.alpha = 255 for(var/mob/living/M in T.contents) var/oldalpha = M.alpha if(M.alpha < 255 && istype(M)) M.alpha = 255 spawn(10) if(M) M.alpha = oldalpha var/mob/living/M = locate() in T if(M && M.invisibility == 2) M.invisibility = 0 spawn(2) if(M) M.invisibility = INVISIBILITY_LEVEL_TWO /proc/chemscan(var/mob/living/user, var/mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.reagents) if(H.reagents.reagent_list.len) user.show_message("Subject contains the following reagents:") for(var/datum/reagent/R in H.reagents.reagent_list) user.show_message("[R.volume]u of [R.name][R.overdosed == 1 ? " - OVERDOSING" : "."]") else user.show_message("Subject contains no reagents.") if(H.reagents.addiction_list.len) user.show_message("Subject is addicted to the following reagents:") for(var/datum/reagent/R in H.reagents.addiction_list) user.show_message("[R.name]") else user.show_message("Subject is not addicted to any reagents.") /obj/item/device/healthanalyzer name = "Health Analyzer" icon_state = "health" item_state = "healthanalyzer" icon_override = 'icons/mob/in-hand/tools.dmi' desc = "A hand-held body scanner able to distinguish vital signs of the subject." flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 w_class = 1.0 throw_speed = 5 throw_range = 10 m_amt = 200 origin_tech = "magnets=1;biotech=1" var/upgraded = 0 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("\red You try to analyze the floor's vitals!") for(var/mob/O in viewers(M, null)) O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1) user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1) user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1) user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\blue Body Temperature: ???", 1) return if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") usr << "\red 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) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC))) //these sensors are designed for organic life user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\t Damage Specifics: ? - ? - ? - ?") user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1) user.show_message("\red Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR") user.show_message("\blue 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("\blue Analyzing Results for [M]:\n\t Overall Status: dead") else user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health - M.halloss]% healthy"]") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\t Damage Specifics: [OX] - [TX] - [BU] - [BR]") user.show_message("\blue 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("\blue 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("\blue Localized Damage, Brute/Burn:",1) if(length(damaged)>0) for(var/obj/item/organ/external/org in damaged) user.show_message(text("\blue \t []: [][]\blue - []", \ capitalize(org.name), \ (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \ (org.status & ORGAN_BLEEDING)?"\red \[Bleeding\]":"\t", \ (org.burn_dam > 0) ? "[org.burn_dam]" :0),1) else user.show_message("\blue \t 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 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal" user.show_message("[OX] | [TX] | [BU] | [BR]") if (istype(M, /mob/living/carbon)) if(upgraded) chemscan(user, M) if(M:virus2.len) // WHAT IS TYPECASTING var/mob/living/carbon/C = M for (var/ID in C.virus2) if (ID in virusDB) var/datum/data/record/V = virusDB[ID] user.show_message(text("\red Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]")) // user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood.")) if(M.getStaminaLoss()) user.show_message("Subject appears to be suffering from fatigue.") if (M.getCloneLoss()) user.show_message("Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") // if (M.reagents && M.reagents.get_reagent_amount("epinephrine")) // user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.") if (M.has_brain_worms()) user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") else if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && M:brain_op_stage == 4.0) user.show_message("\red Subject is brain dead.") else if (M.getBrainLoss() >= 60) user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.") else if (M.getBrainLoss() >= 10) user.show_message("\red 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.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")) && !(e.status & ORGAN_SPLINTED)) user.show_message("\red Unsecured fracture in subject [limb]. Splinting recommended for transport.") if(e.has_infected_wound()) user.show_message("\red 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) continue if(e.status & ORGAN_BROKEN) user.show_message(text("\red Bone fractures detected. Advanced scanner required for location."), 1) break for(var/obj/item/organ/external/e in H.organs) for(var/datum/wound/W in e.wounds) if(W.internal) user.show_message(text("\red 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 blood_percent *= 100 if(blood_volume <= 500) user.show_message("\red Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl") else if(blood_volume <= 336) user.show_message("\red Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl") else user.show_message("\blue Blood Level Normal: [blood_percent]% [blood_volume]cl") if(H.heart_attack) user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.") user.show_message("\blue 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/healthanalyzer/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/device/healthupgrade)) if(upgraded) user << "You have already installed an upgraded in the [src]." else user << "You install the upgrade in the [src]." overlays += "advanced" playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) upgraded = 1 qdel(W) /obj/item/device/healthanalyzer/advanced upgraded = 1 /obj/item/device/healthanalyzer/advanced/New() overlays += "advanced" /obj/item/device/healthupgrade name = "Health Analyzer Upgrade" icon_state = "healthupgrade" desc = "An upgrade unit that can be installed on a health analyzer for expanded functionality." w_class = 1.0 origin_tech = "magnets=2;biotech=2" /obj/item/device/analyzer desc = "A hand-held environmental scanner which reports current gas levels." name = "analyzer" icon_state = "atmos" item_state = "analyzer" w_class = 2.0 flags = CONDUCT slot_flags = SLOT_BELT throwforce = 0 throw_speed = 3 throw_range = 7 m_amt = 30 g_amt = 20 origin_tech = "magnets=1;engineering=1" /obj/item/device/analyzer/attack_self(mob/user as mob) if (user.stat) return var/turf/location = user.loc if (!( istype(location, /turf) )) return var/datum/gas_mixture/environment = location.return_air() var/pressure = environment.return_pressure() var/total_moles = environment.total_moles() user.show_message("Results:", 1) if(abs(pressure - ONE_ATMOSPHERE) < 10) user.show_message("Pressure: [round(pressure,0.1)] kPa", 1) else user.show_message("Pressure: [round(pressure,0.1)] kPa", 1) if(total_moles) var/o2_concentration = environment.oxygen/total_moles var/n2_concentration = environment.nitrogen/total_moles var/co2_concentration = environment.carbon_dioxide/total_moles var/plasma_concentration = environment.toxins/total_moles var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration) if(abs(n2_concentration - N2STANDARD) < 20) user.show_message("Nitrogen: [round(n2_concentration*100)] %", 1) else user.show_message("Nitrogen: [round(n2_concentration*100)] %", 1) if(abs(o2_concentration - O2STANDARD) < 2) user.show_message("Oxygen: [round(o2_concentration*100)] %", 1) else user.show_message("Oxygen: [round(o2_concentration*100)] %", 1) if(co2_concentration > 0.01) user.show_message("CO2: [round(co2_concentration*100)] %", 1) else user.show_message("CO2: [round(co2_concentration*100)] %", 1) if(plasma_concentration > 0.01) user.show_message("Plasma: [round(plasma_concentration*100)] %", 1) if(unknown_concentration > 0.01) user.show_message("Unknown: [round(unknown_concentration*100)] %", 1) user.show_message("Temperature: [round(environment.temperature-T0C)] °C", 1) src.add_fingerprint(user) return /obj/item/device/mass_spectrometer desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample." name = "mass-spectrometer" 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 m_amt = 30 g_amt = 20 origin_tech = "magnets=2;biotech=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 (crit_fail) user << "\red This device has critically failed and is no longer functional!" return if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "\red 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 << "\red 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(prob(reliability)) if(details) dat += "[R] ([blood_traces[R]] units) " else dat += "[R] " recent_fail = 0 else if(recent_fail) crit_fail = 1 reagents.clear_reagents() return else recent_fail = 1 user << "[dat]" reagents.clear_reagents() return /obj/item/device/mass_spectrometer/adv name = "advanced mass-spectrometer" icon_state = "adv_spectrometer" details = 1 origin_tech = "magnets=4;biotech=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 m_amt = 30 g_amt = 20 origin_tech = "magnets=2;biotech=2" var/details = 0 var/recent_fail = 0 /obj/item/device/reagent_scanner/afterattack(obj/O, mob/user as mob) if (user.stat) return if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") user << "\red You don't have the dexterity to do this!" return if(!istype(O)) return if (crit_fail) user << "\red This device has critically failed and is no longer functional!" 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) if(prob(reliability)) dat += "\n \t \blue [R][details ? ": [R.volume / one_percent]%" : ""]" recent_fail = 0 else if(recent_fail) crit_fail = 1 dat = null break else recent_fail = 1 if(dat) user << "\blue Chemicals found: [dat]" else user << "\blue No active chemical agents found in [O]." else user << "\blue 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 = "magnets=4;biotech=2" /obj/item/device/slime_scanner name = "slime scanner" icon_state = "adv_spectrometer_s" item_state = "analyzer" origin_tech = "biotech=1" w_class = 2.0 flags = CONDUCT throwforce = 0 throw_speed = 3 throw_range = 7 m_amt = 30 g_amt = 20 /obj/item/device/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob) if (!isslime(M)) user.show_message("This device can only scan slimes!", 1) return var/mob/living/carbon/slime/T = M user.show_message("Slime scan results:", 1) user.show_message(text("[T.colour] [] slime", T.is_adult ? "adult" : "baby"), 1) user.show_message(text("Nutrition: [T.nutrition]/[]", T.get_max_nutrition()), 1) if (T.nutrition < T.get_starve_nutrition()) user.show_message("Warning: slime is starving!", 1) else if (T.nutrition < T.get_hunger_nutrition()) user.show_message("Warning: slime is hungry", 1) user.show_message("Electric change strength: [T.powerlevel]", 1) user.show_message("Health: [T.health]", 1) if (T.slime_mutation[4] == T.colour) user.show_message("This slime does not evolve any further.", 1) else if (T.slime_mutation[3] == T.slime_mutation[4]) if (T.slime_mutation[2] == T.slime_mutation[1]) user.show_message("Possible mutation: [T.slime_mutation[3]]", 1) user.show_message("Genetic destability: [T.mutation_chance/2]% chance of mutation on splitting", 1) else user.show_message("Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]] (x2)", 1) user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting", 1) else user.show_message("Possible mutations: [T.slime_mutation[1]], [T.slime_mutation[2]], [T.slime_mutation[3]], [T.slime_mutation[4]]", 1) user.show_message("Genetic destability: [T.mutation_chance]% chance of mutation on splitting", 1) if (T.cores > 1) user.show_message("Anomalious slime core amount detected", 1) user.show_message("Growth progress: [T.amount_grown]/10", 1)