/obj/item/bodyanalyzer name = "handheld body analyzer" desc = "A handheld scanner capable of deep-scanning an entire body." icon = 'icons/obj/device.dmi' icon_state = "bodyanalyzer_0" worn_icon_state = "healthanalyzer" inhand_icon_state = "healthanalyzer" slot_flags = ITEM_SLOT_BELT w_class = WEIGHT_CLASS_SMALL throw_speed = 5 throw_range = 10 origin_tech = "magnets=6;biotech=6" var/obj/item/stock_parts/cell/cell var/cell_type = /obj/item/stock_parts/cell/high var/ready = TRUE // Ready to scan var/printing = FALSE var/time_to_use = 0 // How much time remaining before next scan is available. var/usecharge = 750 var/scan_time = 5 SECONDS //how long does it take to scan var/scan_cd = 30 SECONDS //how long before we can scan again /obj/item/bodyanalyzer/get_cell() return cell /obj/item/bodyanalyzer/advanced cell_type = /obj/item/stock_parts/cell/super // twice the charge! /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_cd = 20 SECONDS /obj/item/bodyanalyzer/Initialize(mapload) . = ..() cell = new cell_type(src) cell.give(cell.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_state() if(!cell) icon_state = "bodyanalyzer_0" return if(ready) icon_state = "bodyanalyzer_1" else icon_state = "bodyanalyzer_2" /obj/item/bodyanalyzer/update_overlays() . = ..() var/percent = cell.percent() var/overlayid = round(percent / 10) . += "bodyanalyzer_charge[overlayid]" if(printing) . += "bodyanalyzer_printing" /obj/item/bodyanalyzer/attack__legacy__attackchain(mob/living/M, mob/living/carbon/human/user) if(user.incapacitated() || !user.Adjacent(M)) return if(!ready) to_chat(user, SPAN_NOTICE("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(cell.charge >= usecharge) mobScan(M, user) else to_chat(user, SPAN_NOTICE("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__legacy__attackchain(mob/living/M, mob/living/silicon/robot/user) if(user.incapacitated() || !user.Adjacent(M)) return if(!ready) to_chat(user, SPAN_NOTICE("[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, SPAN_NOTICE("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 cell.use(usecharge) ready = FALSE printing = TRUE update_icon() addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/bodyanalyzer, setReady)), scan_cd) addtimer(VARSET_CALLBACK(src, printing, FALSE), 1.4 SECONDS) addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), UPDATE_OVERLAYS), 1.5 SECONDS) else if(iscorgi(M) && M.stat == DEAD) to_chat(user, SPAN_NOTICE("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 update_icon(UPDATE_ICON_STATE) addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/bodyanalyzer, setReady)), scan_cd) time_to_use = world.time + scan_cd else to_chat(user, SPAN_NOTICE("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.IsParalyzed()] ([round(target.AmountParalyzed() / 10)] seconds left!)
" dat += "Body Temperature: [target.bodytemperature-T0C]°C ([target.bodytemperature*1.8-459.67]°F)
" dat += "
" 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 = "" var/liver_cirrhosis = "" if(e.status & ORGAN_INT_BLEEDING) internal_bleeding = "
Internal bleeding" if(istype(e, /obj/item/organ/external/chest) && target.is_lung_ruptured()) lung_ruptured = "Lung ruptured:" if(istype(e, /obj/item/organ/external/groin) && target.has_liver_cirrhosis()) liver_cirrhosis = "Liver cirrhosis:" if(e.status & ORGAN_SPLINTED) splint = "Splinted:" if(e.status & ORGAN_BROKEN) var/datum/wound/fracture = e.get_wound(/datum/wound/fracture) AN = "[fracture.name]:" 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][liver_cirrhosis]
[i.name]N/A[i.damage][infection]:[mech]
" if(HAS_TRAIT(target, TRAIT_BLIND)) dat += "Cataracts detected.
" if(HAS_TRAIT(target, TRAIT_COLORBLIND)) dat += "Photoreceptor abnormalities detected.
" if(HAS_TRAIT(target, TRAIT_NEARSIGHT)) dat += "Retinal misalignment detected.
" if(HAS_TRAIT(target, TRAIT_PARAPLEGIC)) dat += "Lumbar nerves damaged.
" return dat