/* CONTAINS: T-RAY DETECTIVE SCANNER HEALTH ANALYZER GAS ANALYZER PLANT ANALYZER REAGENT SCANNER */ /obj/item/t_scanner name = "T-ray scanner" desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes." icon = 'icons/obj/device.dmi' icon_state = "t-ray0" var/on = 0 slot_flags = SLOT_BELT w_class = 2 w_class = WEIGHT_CLASS_SMALL item_state = "electronic" materials = list(MAT_METAL=150) origin_tech = "magnets=1;engineering=1" var/scan_range = 1 var/pulse_duration = 10 /obj/item/t_scanner/longer_pulse pulse_duration = 50 /obj/item/t_scanner/extended_range scan_range = 3 /obj/item/t_scanner/extended_range/longer_pulse scan_range = 3 pulse_duration = 50 /obj/item/t_scanner/Destroy() if(on) STOP_PROCESSING(SSobj, src) return ..() /obj/item/t_scanner/attack_self(mob/user) on = !on icon_state = copytext(icon_state, 1, length(icon_state))+"[on]" if(on) START_PROCESSING(SSobj, src) /obj/item/t_scanner/process() if(!on) STOP_PROCESSING(SSobj, src) return null scan() /obj/item/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 && 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 ? " - 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] Stage: [R.addiction_stage]/5") else user.show_message("Subject is not addicted to any reagents.") /obj/item/healthanalyzer name = "Health Analyzer" icon = 'icons/obj/device.dmi' icon_state = "health" item_state = "healthanalyzer" desc = "A hand-held body scanner able to distinguish vital signs of the subject." flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 w_class = WEIGHT_CLASS_TINY throw_speed = 5 throw_range = 10 materials = list(MAT_METAL=200) origin_tech = "magnets=1;biotech=1" var/upgraded = 0 var/mode = 1; /obj/item/healthanalyzer/attack(mob/living/M, mob/living/user) if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) to_chat(user, text("You try to analyze the floor's vitals!")) for(var/mob/O in viewers(M, null)) O.show_message(text("[user] has analyzed the floor's vitals!"), 1) user.show_message(text("Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1) user.show_message(text("\t Damage Specifics: [0]-[0]-[0]-[0]"), 1) user.show_message("Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("Body Temperature: ???", 1) return 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 user.show_message("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("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/mob/living/carbon/human/H = M var/fake_oxy = max(rand(1,40), H.getOxyLoss(), (300 - (H.getToxLoss() + H.getFireLoss() + H.getBruteLoss()))) var/OX = H.getOxyLoss() > 50 ? "[H.getOxyLoss()]" : H.getOxyLoss() var/TX = H.getToxLoss() > 50 ? "[H.getToxLoss()]" : H.getToxLoss() var/BU = H.getFireLoss() > 50 ? "[H.getFireLoss()]" : H.getFireLoss() var/BR = H.getBruteLoss() > 50 ? "[H.getBruteLoss()]" : H.getBruteLoss() if(H.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy user.show_message("Analyzing Results for [H]:\n\t Overall Status: dead") else user.show_message("Analyzing Results for [H]:\n\t Overall Status: [H.stat > 1 ? "dead" : "[H.health]% healthy"]") user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1) user.show_message("\t Damage Specifics: [OX] - [TX] - [BU] - [BR]") user.show_message("Body Temperature: [H.bodytemperature-T0C]°C ([H.bodytemperature*1.8-459.67]°F)", 1) if(H.timeofdeath && (H.stat == DEAD || (H.status_flags & FAKEDEATH))) user.show_message("Time of Death: [station_time_timestamp("hh:mm:ss", H.timeofdeath)]") var/tdelta = round(world.time - H.timeofdeath) if(tdelta < (DEFIB_TIME_LIMIT * 10)) user.show_message("Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!") if(mode == 1) 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("\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam]" : "0"]-[(org.burn_dam > 0) ? "[org.burn_dam]" : "0"]") OX = H.getOxyLoss() > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" TX = H.getToxLoss() > 50 ? "Dangerous amount of toxins detected" : "Subject bloodstream toxin level minimal" BU = H.getFireLoss() > 50 ? "Severe burn damage detected" : "Subject burn injury status O.K" BR = H.getBruteLoss() > 50 ? "Severe anatomical damage detected" : "Subject brute-force injury status O.K" if(H.status_flags & FAKEDEATH) OX = fake_oxy > 50 ? "Severe oxygen deprivation detected" : "Subject bloodstream oxygen level normal" user.show_message("[OX] | [TX] | [BU] | [BR]") if(upgraded) chemscan(user, H) for(var/thing in H.viruses) var/datum/disease/D = thing if(!(D.visibility_flags & HIDDEN_SCANNER)) user.show_message("Warning: [D.form] detected\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]") if(H.undergoing_cardiac_arrest()) var/obj/item/organ/internal/heart/heart = H.get_int_organ(/obj/item/organ/internal/heart) if(heart && !(heart.status & ORGAN_DEAD)) user.show_message("Warning: Medical Emergency detected\nName: Cardiac Arrest.\nType: The patient's heart has stopped.\nStage: 1/1.\nPossible Cure: Electric Shock") else if(heart && (heart.status & ORGAN_DEAD)) user.show_message("Subject's heart is necrotic.") else if(!heart) user.show_message("Subject has no heart.") if(H.getStaminaLoss()) user.show_message("Subject appears to be suffering from fatigue.") if(H.getCloneLoss()) user.show_message("Subject appears to have [H.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") if(H.has_brain_worms()) user.show_message("Subject suffering from aberrant brain activity. Recommend further scanning.") if(H.get_int_organ(/obj/item/organ/internal/brain)) if(H.getBrainLoss() >= 100) user.show_message("Subject is brain dead.") else if(H.getBrainLoss() >= 60) user.show_message("Severe brain damage detected. Subject likely to have mental retardation.") else if(H.getBrainLoss() >= 10) user.show_message("Significant brain damage detected. Subject may have had a concussion.") else user.show_message("Subject has no brain.") for(var/name in H.bodyparts_by_name) var/obj/item/organ/external/e = H.bodyparts_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("Unsecured fracture in subject [limb]. Splinting recommended for transport.") if(e.has_infected_wound()) user.show_message("Infected wound detected in subject [limb]. Disinfection recommended.") for(var/name in H.bodyparts_by_name) var/obj/item/organ/external/e = H.bodyparts_by_name[name] if(!e) continue if(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.bodyparts) if(e.internal_bleeding) user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) break var/blood_id = H.get_blood_id() if(blood_id) if(H.bleed_rate) user.show_message("Subject is bleeding!") var/blood_percent = round((H.blood_volume / BLOOD_VOLUME_NORMAL)*100) var/blood_type = H.b_type if(blood_id != "blood")//special blood substance var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] if(R) blood_type = R.name else blood_type = blood_id if(H.blood_volume <= BLOOD_VOLUME_SAFE && H.blood_volume > BLOOD_VOLUME_OKAY) user.show_message("LOW blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") else if(H.blood_volume <= BLOOD_VOLUME_OKAY) user.show_message("CRITICAL blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") else user.show_message("Blood level [blood_percent] %, [H.blood_volume] cl, type: [blood_type]") user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.") var/implant_detect for(var/obj/item/organ/internal/cyberimp/CI in H.internal_organs) if(CI.is_robotic()) implant_detect += "[H.name] is modified with a [CI.name].
" if(implant_detect) user.show_message("Detected cybernetic modifications:") user.show_message("[implant_detect]") if(H.gene_stability < 40) user.show_message("Subject's genes are quickly breaking down!") else if(H.gene_stability < 70) user.show_message("Subject's genes are showing signs of spontaneous breakdown.") else if(H.gene_stability < 85) user.show_message("Subject's genes are showing minor signs of instability.") else user.show_message("Subject's genes are stable.") add_fingerprint(user) /obj/item/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/healthanalyzer/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/healthupgrade)) if(upgraded) to_chat(user, "You have already installed an upgraded in the [src].") else to_chat(user, "You install the upgrade in the [src].") overlays += "advanced" playsound(loc, I.usesound, 50, 1) upgraded = TRUE qdel(I) return return ..() /obj/item/healthanalyzer/advanced upgraded = TRUE /obj/item/healthanalyzer/advanced/New() overlays += "advanced" /obj/item/healthupgrade name = "Health Analyzer Upgrade" icon = 'icons/obj/device.dmi' icon_state = "healthupgrade" desc = "An upgrade unit that can be installed on a health analyzer for expanded functionality." w_class = WEIGHT_CLASS_TINY origin_tech = "magnets=2;biotech=2" usesound = 'sound/items/deconstruct.ogg' /obj/item/analyzer desc = "A hand-held environmental scanner which reports current gas levels." name = "analyzer" icon = 'icons/obj/device.dmi' icon_state = "atmos" item_state = "analyzer" w_class = WEIGHT_CLASS_SMALL flags = CONDUCT slot_flags = SLOT_BELT throwforce = 0 throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) origin_tech = "magnets=1;engineering=1" var/cooldown = FALSE var/cooldown_time = 250 var/accuracy // 0 is the best accuracy. /obj/item/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/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens ..() if(!user.incapacitated() && Adjacent(user)) if(cooldown) to_chat(user, "[src]'s barometer function is prepraring itself.") return var/turf/T = get_turf(user) if(!T) return playsound(src, 'sound/effects/pop.ogg', 100) var/area/user_area = T.loc var/datum/weather/ongoing_weather = null if(!user_area.outdoors) to_chat(user, "[src]'s barometer function won't work indoors!") return for(var/V in SSweather.processing) var/datum/weather/W = V if(W.barometer_predictable && (T.z in W.impacted_z_levels) && W.area_type == user_area.type && !(W.stage == END_STAGE)) ongoing_weather = W break if(ongoing_weather) if((ongoing_weather.stage == MAIN_STAGE) || (ongoing_weather.stage == WIND_DOWN_STAGE)) to_chat(user, "[src]'s barometer function can't trace anything while the storm is [ongoing_weather.stage == MAIN_STAGE ? "already here!" : "winding down."]") return to_chat(user, "The next [ongoing_weather] will hit in [butchertime(ongoing_weather.next_hit_time - world.time)].") if(ongoing_weather.aesthetic) to_chat(user, "[src]'s barometer function says that the next storm will breeze on by.") else var/next_hit = SSweather.next_hit_by_zlevel["[T.z]"] var/fixed = next_hit ? next_hit - world.time : -1 if(fixed < 0) to_chat(user, "[src]'s barometer function was unable to trace any weather patterns.") else to_chat(user, "[src]'s barometer function says a storm will land in approximately [butchertime(fixed)].") cooldown = TRUE addtimer(CALLBACK(src,/obj/item/analyzer/proc/ping), cooldown_time) /obj/item/analyzer/proc/ping() if(isliving(loc)) var/mob/living/L = loc to_chat(L, "[src]'s barometer function is ready!") playsound(src, 'sound/machines/click.ogg', 100) cooldown = FALSE /obj/item/analyzer/proc/butchertime(amount) if(!amount) return if(accuracy) var/inaccurate = round(accuracy * (1 / 3)) if(prob(50)) amount -= inaccurate if(prob(50)) amount += inaccurate return DisplayTimeText(max(1, amount)) /obj/item/reagent_scanner name = "reagent scanner" desc = "A hand-held reagent scanner which identifies chemical agents and blood types." icon = 'icons/obj/device.dmi' icon_state = "spectrometer" item_state = "analyzer" w_class = WEIGHT_CLASS_SMALL flags = CONDUCT slot_flags = SLOT_BELT throwforce = 5 throw_speed = 4 throw_range = 20 materials = list(MAT_METAL=30, MAT_GLASS=20) origin_tech = "magnets=2;biotech=1;plasmatech=2" var/details = FALSE var/datatoprint = "" var/scanning = TRUE actions_types = list(/datum/action/item_action/print_report) /obj/item/reagent_scanner/afterattack(obj/O, mob/user as mob) if(user.stat) return if(!user.IsAdvancedToolUser()) to_chat(user, "You don't have the dexterity to do this!") return if(!istype(O)) return if(!isnull(O.reagents)) var/dat = "" var/blood_type = "" 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(R.id != "blood") dat += "
[TAB][R][details ? ": [R.volume / one_percent]%" : ""]" else blood_type = R.data["blood_type"] dat += "
[TAB][R][blood_type ? " [blood_type]" : ""][details ? ": [R.volume / one_percent]%" : ""]" if(dat) to_chat(user, "Chemicals found: [dat]") datatoprint = dat scanning = FALSE else to_chat(user, "No active chemical agents found in [O].") else to_chat(user, "No significant chemical agents found in [O].") return /obj/item/reagent_scanner/adv name = "advanced reagent scanner" icon_state = "adv_spectrometer" details = TRUE origin_tech = "magnets=4;biotech=3;plasmatech=3" /obj/item/reagent_scanner/proc/print_report() if(!scanning) usr.visible_message("[src] rattles and prints out a sheet of paper.") playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1) sleep(50) var/obj/item/paper/P = new(get_turf(src)) P.name = "Reagent Scanner Report: [station_time_timestamp()]" P.info = "
Reagent Scanner

Data Analysis:



Chemical agents detected:
[datatoprint]

" if(ismob(loc)) var/mob/M = loc M.put_in_hands(P) to_chat(M, "Report printed. Log cleared.") datatoprint = "" scanning = TRUE else to_chat(usr, "[src] has no logs or is already in use.") /obj/item/reagent_scanner/ui_action_click() print_report() /obj/item/slime_scanner name = "slime scanner" icon = 'icons/obj/device.dmi' icon_state = "adv_spectrometer_s" item_state = "analyzer" origin_tech = "biotech=2" w_class = WEIGHT_CLASS_SMALL flags = CONDUCT throwforce = 0 throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) /obj/item/slime_scanner/attack(mob/living/M as mob, mob/living/user as mob) slime_scan(M, user) /proc/slime_scan(mob/living/carbon/slime/M, mob/living/user) 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("Anomalous slime core amount detected", 1) user.show_message("Growth progress: [T.amount_grown]/10", 1) /obj/item/bodyanalyzer name = "handheld body analyzer" icon = 'icons/obj/device.dmi' icon_state = "bodyanalyzer_0" item_state = "healthanalyser" desc = "A handheld scanner capable of deep-scanning an entire body." slot_flags = SLOT_BELT throwforce = 3 w_class = WEIGHT_CLASS_TINY throw_speed = 5 throw_range = 10 origin_tech = "magnets=6;biotech=6" var/obj/item/stock_parts/cell/power_supply var/cell_type = /obj/item/stock_parts/cell/upgraded var/ready = TRUE // Ready to scan var/time_to_use = 0 // How much time remaining before next scan is available. var/usecharge = 750 var/scan_time = 10 SECONDS //how long does it take to scan var/scan_cd = 60 SECONDS //how long before we can scan again /obj/item/bodyanalyzer/advanced cell_type = /obj/item/stock_parts/cell/upgraded/plus /obj/item/bodyanalyzer/borg name = "cyborg body analyzer" desc = "Scan an entire body to prepare for field surgery. Consumes power for each scan." /obj/item/bodyanalyzer/borg/syndicate scan_time = 5 SECONDS scan_cd = 20 SECONDS /obj/item/bodyanalyzer/New() ..() power_supply = new cell_type(src) power_supply.give(power_supply.maxcharge) update_icon() /obj/item/bodyanalyzer/proc/setReady() ready = TRUE playsound(src, 'sound/machines/defib_saftyon.ogg', 50, 0) update_icon() /obj/item/bodyanalyzer/update_icon(printing = FALSE) overlays.Cut() var/percent = power_supply.percent() if(ready) icon_state = "bodyanalyzer_1" else icon_state = "bodyanalyzer_2" var/overlayid = round(percent / 10) overlayid = "bodyanalyzer_charge[overlayid]" overlays += icon(icon, overlayid) if(printing) overlays += icon(icon, "bodyanalyzer_printing") /obj/item/bodyanalyzer/attack(mob/living/M, mob/living/carbon/human/user) if(user.incapacitated() || !user.Adjacent(M)) return if(!ready) to_chat(user, "The scanner beeps angrily at you! It's currently recharging - [round((time_to_use - world.time) * 0.1)] seconds remaining.") playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1) return if(power_supply.charge >= usecharge) mobScan(M, user) else to_chat(user, "The scanner beeps angrily at you! It's out of charge!") playsound(user.loc, 'sound/machines/buzz-sigh.ogg', 50, 1) /obj/item/bodyanalyzer/borg/attack(mob/living/M, mob/living/silicon/robot/user) if(user.incapacitated() || !user.Adjacent(M)) return if(!ready) to_chat(user, "[src] is currently recharging - [round((time_to_use - world.time) * 0.1)] seconds remaining.") return if(user.cell.charge >= usecharge) mobScan(M, user) else to_chat(user, "You need to recharge before you can use [src]") /obj/item/bodyanalyzer/proc/mobScan(mob/living/M, mob/user) if(ishuman(M)) var/report = generate_printing_text(M, user) user.visible_message("[user] begins scanning [M] with [src].", "You begin scanning [M].") if(do_after(user, scan_time, target = M)) var/obj/item/paper/printout = new printout.info = report printout.name = "Scan report - [M.name]" playsound(user.loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) user.put_in_hands(printout) time_to_use = world.time + scan_cd if(isrobot(user)) var/mob/living/silicon/robot/R = user R.cell.use(usecharge) else power_supply.use(usecharge) ready = FALSE update_icon(TRUE) addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/setReady), scan_cd) addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/update_icon), 20) else if(iscorgi(M) && M.stat == DEAD) to_chat(user, "You wonder if [M.p_they()] was a good dog. [src] tells you they were the best...") // :'( playsound(loc, 'sound/machines/ping.ogg', 50, 0) ready = FALSE addtimer(CALLBACK(src, /obj/item/bodyanalyzer/.proc/setReady), scan_cd) time_to_use = world.time + scan_cd else to_chat(user, "Scanning error detected. Invalid specimen.") //Unashamedly ripped from adv_med.dm /obj/item/bodyanalyzer/proc/generate_printing_text(mob/living/M, mob/user) var/dat = "" var/mob/living/carbon/human/target = M dat = "Target Statistics:
" var/t1 switch(target.stat) // obvious, see what their status is if(CONSCIOUS) t1 = "Conscious" if(UNCONSCIOUS) t1 = "Unconscious" else t1 = "*dead*" dat += "[target.health > 50 ? "" : ""]\tHealth %: [target.health], ([t1])
" var/found_disease = FALSE for(var/thing in target.viruses) var/datum/disease/D = thing if(D.visibility_flags) //If any visibility flags are on. continue found_disease = TRUE break if(found_disease) dat += "Disease detected in target.
" var/extra_font = null extra_font = (target.getBruteLoss() < 60 ? "" : "") dat += "[extra_font]\t-Brute Damage %: [target.getBruteLoss()]
" extra_font = (target.getOxyLoss() < 60 ? "" : "") dat += "[extra_font]\t-Respiratory Damage %: [target.getOxyLoss()]
" extra_font = (target.getToxLoss() < 60 ? "" : "") dat += "[extra_font]\t-Toxin Content %: [target.getToxLoss()]
" extra_font = (target.getFireLoss() < 60 ? "" : "") dat += "[extra_font]\t-Burn Severity %: [target.getFireLoss()]
" extra_font = (target.radiation < 10 ?"" : "") dat += "[extra_font]\tRadiation Level %: [target.radiation]
" extra_font = (target.getCloneLoss() < 1 ?"" : "") dat += "[extra_font]\tGenetic Tissue Damage %: [target.getCloneLoss()]
" extra_font = (target.getBrainLoss() < 1 ?"" : "") dat += "[extra_font]\tApprox. Brain Damage %: [target.getBrainLoss()]
" dat += "Paralysis Summary %: [target.paralysis] ([round(target.paralysis / 4)] seconds left!)
" dat += "Body Temperature: [target.bodytemperature-T0C]°C ([target.bodytemperature*1.8-459.67]°F)
" dat += "
" if(target.has_brain_worms()) dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" var/blood_percent = round((target.blood_volume / BLOOD_VOLUME_NORMAL)) blood_percent *= 100 extra_font = (target.blood_volume > 448 ? "" : "") dat += "[extra_font]\tBlood Level %: [blood_percent] ([target.blood_volume] units)
" if(target.reagents) dat += "Epinephrine units: [target.reagents.get_reagent_amount("Epinephrine")] units
" dat += "Ether: [target.reagents.get_reagent_amount("ether")] units
" extra_font = (target.reagents.get_reagent_amount("silver_sulfadiazine") < 30 ? "" : "") dat += "[extra_font]\tSilver Sulfadiazine: [target.reagents.get_reagent_amount("silver_sulfadiazine")]
" extra_font = (target.reagents.get_reagent_amount("styptic_powder") < 30 ? "" : "") dat += "[extra_font]\tStyptic Powder: [target.reagents.get_reagent_amount("styptic_powder")] units
" extra_font = (target.reagents.get_reagent_amount("salbutamol") < 30 ? "" : "") dat += "[extra_font]\tSalbutamol: [target.reagents.get_reagent_amount("salbutamol")] units
" dat += "
" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" for(var/obj/item/organ/external/e in target.bodyparts) dat += "" var/AN = "" var/open = "" var/infected = "" var/robot = "" var/imp = "" var/bled = "" var/splint = "" var/internal_bleeding = "" var/lung_ruptured = "" if(e.internal_bleeding) internal_bleeding = "
Internal bleeding" if(istype(e, /obj/item/organ/external/chest) && target.is_lung_ruptured()) lung_ruptured = "Lung ruptured:" if(e.status & ORGAN_SPLINTED) splint = "Splinted:" if(e.status & ORGAN_BROKEN) AN = "[e.broken_description]:" if(e.is_robotic()) robot = "Robotic:" if(e.open) open = "Open:" switch(e.germ_level) if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200) infected = "Mild Infection:" if(INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) infected = "Mild Infection+:" if(INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) infected = "Mild Infection++:" if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) infected = "Acute Infection:" if(INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) infected = "Acute Infection+:" if(INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400) infected = "Acute Infection++:" if(INFECTION_LEVEL_THREE to INFINITY) infected = "Septic:" var/unknown_body = 0 for(var/I in e.embedded_objects) unknown_body++ if(unknown_body || e.hidden) imp += "Unknown body present:" if(!AN && !open && !infected & !imp) AN = "None:" dat += "" dat += "" for(var/obj/item/organ/internal/i in target.internal_organs) var/mech = i.desc var/infection = "None" switch(i.germ_level) if(1 to INFECTION_LEVEL_ONE + 200) infection = "Mild Infection:" if(INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300) infection = "Mild Infection+:" if(INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400) infection = "Mild Infection++:" if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200) infection = "Acute Infection:" if(INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300) infection = "Acute Infection+:" if(INFECTION_LEVEL_TWO + 300 to INFINITY) infection = "Acute Infection++:" dat += "" dat += "" dat += "" dat += "
OrganBurn DamageBrute DamageOther Wounds
[e.name][e.burn_dam][e.brute_dam][robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]
[i.name]N/A[i.damage][infection]:[mech]
" if(target.disabilities & BLIND) dat += "Cataracts detected.
" if(target.disabilities & COLOURBLIND) dat += "Photoreceptor abnormalities detected.
" if(target.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" return dat