/obj/machinery/bodyscanner var/mob/living/carbon/occupant var/locked name = "body scanner" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscanner-open" density = 1 dir = 8 anchored = 1 idle_power_usage = 1250 active_power_usage = 2500 light_color = "#00FF00" /obj/machinery/bodyscanner/power_change() ..() if(!(stat & (BROKEN|NOPOWER))) set_light(2) else set_light(0) /obj/machinery/bodyscanner/process() for(var/mob/M as mob in src) // makes sure that simple mobs don't get stuck inside a sleeper when they resist out of occupant's grasp if(M == occupant) continue else M.forceMove(src.loc) /obj/machinery/bodyscanner/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/bodyscanner(null) component_parts += new /obj/item/weapon/stock_parts/scanning_module(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 2) RefreshParts() /obj/machinery/bodyscanner/upgraded/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/bodyscanner(null) component_parts += new /obj/item/weapon/stock_parts/scanning_module/phasic(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 2) RefreshParts() /obj/machinery/bodyscanner/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) if(istype(G, /obj/item/weapon/screwdriver)) if(src.occupant) to_chat(user, "The maintenance panel is locked.") return default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", G) return if(istype(G, /obj/item/weapon/wrench)) if(src.occupant) to_chat(user, "The scanner is occupied.") return if(panel_open) to_chat(user, "Close the maintenance panel first.") return if(dir == 4) dir = 8 else dir = 4 playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) return if(exchange_parts(user, G)) return if(istype(G, /obj/item/weapon/crowbar)) default_deconstruction_crowbar(G) return if(istype(G, /obj/item/weapon/grab)) var/obj/item/weapon/grab/TYPECAST_YOUR_SHIT = G if(panel_open) to_chat(user, "Close the maintenance panel first.") return if(!ismob(TYPECAST_YOUR_SHIT.affecting)) return if(occupant) to_chat(user, "The scanner is already occupied!") return for(var/mob/living/carbon/slime/M in range(1, TYPECAST_YOUR_SHIT.affecting)) if(M.Victim == TYPECAST_YOUR_SHIT.affecting) to_chat(user, "[TYPECAST_YOUR_SHIT.affecting.name] has a fucking slime attached to them, deal with that first.") return var/mob/M = TYPECAST_YOUR_SHIT.affecting if(M.abiotic()) to_chat(user, "Subject cannot have abiotic items on.") return M.forceMove(src) occupant = M icon_state = "body_scanner_1" add_fingerprint(user) qdel(G) /obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/O, mob/user as mob) if(!istype(O)) return 0 //not a mob if(user.incapacitated()) return 0 //user shouldn't be doing things if(O.anchored) return 0 //mob is anchored??? if(get_dist(user, src) > 1 || get_dist(user, O) > 1) return 0 //doesn't use adjacent() to allow for non-cardinal (fuck my life) if(!ishuman(user) && !isrobot(user)) return 0 //not a borg or human if(panel_open) to_chat(user, "Close the maintenance panel first.") return 0 //panel open if(occupant) to_chat(user, "\The [src] is already occupied.") return 0 //occupied if(O.buckled) return 0 if(O.abiotic()) to_chat(user, "Subject cannot have abiotic items on.") return 0 for(var/mob/living/carbon/slime/M in range(1, O)) if(M.Victim == O) to_chat(user, "[O] has a fucking slime attached to them, deal with that first.") return 0 if(O == user) visible_message("[user] climbs into \the [src].") else visible_message("[user] puts [O] into the body scanner.") O.forceMove(src) occupant = O icon_state = "bodyscanner" add_fingerprint(user) /obj/machinery/bodyscanner/relaymove(mob/user as mob) if(user.incapacitated()) return 0 //maybe they should be able to get out with cuffs, but whatever go_out() /obj/machinery/bodyscanner/verb/eject() set src in oview(1) set category = "Object" set name = "Eject Body Scanner" if(usr.incapacitated()) return go_out() add_fingerprint(usr) /obj/machinery/bodyscanner/proc/go_out() if(!occupant || locked) return occupant.forceMove(loc) occupant = null icon_state = "body_scanner_0" // eject trash the occupant dropped for(var/atom/movable/A in contents - component_parts) A.forceMove(loc) /obj/machinery/bodyscanner/ex_act(severity) switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) A.forceMove(src.loc) A.ex_act(severity) qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) A.forceMove(src.loc) A.ex_act(severity) qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) A.forceMove(src.loc) A.ex_act(severity) qdel(src) return /obj/machinery/bodyscanner/blob_act() if(prob(50)) var/atom/movable/A = occupant go_out() A.blob_act() qdel(src) /obj/machinery/bodyscanner/narsie_act() go_out() new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH! qdel(src) /obj/machinery/bodyscanner/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise if(M.environment_smash) M.do_attack_animation(src) visible_message("[M.name] smashes [src] apart!") go_out() qdel(src) return /obj/machinery/body_scanconsole var/obj/machinery/bodyscanner/connected var/delete var/temphtml name = "Body Scanner Console" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscannerconsole" density = 1 anchored = 1 dir = 8 idle_power_usage = 250 active_power_usage = 500 var/printing = null var/printing_text = null var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking) /obj/machinery/body_scanconsole/power_change() if(stat & BROKEN) icon_state = "bodyscannerconsole-p" else if(powered() && !panel_open) icon_state = initial(icon_state) stat &= ~NOPOWER else spawn(rand(0, 15)) src.icon_state = "bodyscannerconsole-p" stat |= NOPOWER /obj/machinery/body_scanconsole/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/bodyscanner_console(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/weapon/stock_parts/console_screen(null) component_parts += new /obj/item/stack/cable_coil(null, 2) RefreshParts() findscanner() /obj/machinery/body_scanconsole/ex_act(severity) switch(severity) if(1.0) //SN src = null qdel(src) return if(2.0) if(prob(50)) //SN src = null qdel(src) return else return /obj/machinery/body_scanconsole/blob_act() if(prob(50)) qdel(src) /obj/machinery/body_scanconsole/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise if(M.environment_smash) M.do_attack_animation(src) visible_message("[M.name] smashes [src] apart!") qdel(src) return /obj/machinery/body_scanconsole/proc/findscanner() var/obj/machinery/bodyscanner/bodyscannernew = null // Loop through every direction for(dir in list(NORTH,EAST,SOUTH,WEST)) // Try to find a scanner in that direction var/temp = locate(/obj/machinery/bodyscanner, get_step(src, dir)) if(!isnull(temp)) bodyscannernew = temp src.connected = bodyscannernew return /obj/machinery/body_scanconsole/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob, params) if(istype(G, /obj/item/weapon/screwdriver)) default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", G) return if(istype(G, /obj/item/weapon/wrench)) if(panel_open) to_chat(user, "Close the maintenance panel first.") return if(dir == 4) dir = 8 else dir = 4 playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) if(exchange_parts(user, G)) return default_deconstruction_crowbar(G) /obj/machinery/body_scanconsole/attack_ai(user as mob) return attack_hand(user) /obj/machinery/body_scanconsole/attack_ghost(user as mob) return attack_hand(user) /obj/machinery/body_scanconsole/attack_hand(user as mob) if(stat & (NOPOWER|BROKEN)) return if(panel_open) to_chat(user, "Close the maintenance panel first.") return if(!src.connected) findscanner() ui_interact(user) /obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 600) ui.open() ui.set_auto_update(1) /obj/machinery/body_scanconsole/ui_data(mob/user, datum/topic_state/state) var/data[0] data["connected"] = connected ? 1 : 0 if(!connected) return data data["occupied"] = connected.occupant ? 1 : 0 var/occupantData[0] if(connected.occupant) var/mob/living/carbon/human/H = connected.occupant occupantData["name"] = H.name occupantData["stat"] = H.stat occupantData["health"] = H.health occupantData["maxHealth"] = H.maxHealth occupantData["hasVirus"] = H.viruses.len occupantData["bruteLoss"] = H.getBruteLoss() occupantData["oxyLoss"] = H.getOxyLoss() occupantData["toxLoss"] = H.getToxLoss() occupantData["fireLoss"] = H.getFireLoss() occupantData["radLoss"] = H.radiation occupantData["cloneLoss"] = H.getCloneLoss() occupantData["brainLoss"] = H.getBrainLoss() occupantData["paralysis"] = H.paralysis occupantData["paralysisSeconds"] = round(H.paralysis / 4) occupantData["bodyTempC"] = H.bodytemperature-T0C occupantData["bodyTempF"] = (((H.bodytemperature-T0C) * 1.8) + 32) occupantData["hasBorer"] = H.has_brain_worms() var/bloodData[0] bloodData["hasBlood"] = 0 if(ishuman(H) && H.vessel && !(H.species && H.species.flags & NO_BLOOD)) var/blood_type = H.get_blood_name() var/blood_volume = round(H.vessel.get_reagent_amount(blood_type)) bloodData["hasBlood"] = 1 bloodData["volume"] = blood_volume bloodData["percent"] = round(((blood_volume / BLOOD_VOLUME_NORMAL)*100)) bloodData["pulse"] = H.get_pulse(GETPULSE_TOOL) bloodData["bloodLevel"] = blood_volume bloodData["bloodMax"] = H.max_blood occupantData["blood"] = bloodData var/implantData[0] for(var/obj/item/weapon/implant/I in H) if(I.implanted && is_type_in_list(I, known_implants)) var/implantSubData[0] implantSubData["name"] = sanitize(I.name) implantData.Add(list(implantSubData)) occupantData["implant"] = implantData occupantData["implant_len"] = implantData.len var/extOrganData[0] for(var/obj/item/organ/external/E in H.organs) var/organData[0] organData["name"] = E.name organData["open"] = E.open organData["germ_level"] = E.germ_level organData["bruteLoss"] = E.brute_dam organData["fireLoss"] = E.burn_dam organData["totalLoss"] = E.brute_dam + E.burn_dam organData["maxHealth"] = E.max_damage organData["bruised"] = E.min_bruised_damage organData["broken"] = E.min_broken_damage var/shrapnelData[0] for(var/obj/I in E.implants) var/shrapnelSubData[0] shrapnelSubData["name"] = I.name shrapnelData.Add(list(shrapnelSubData)) organData["shrapnel"] = shrapnelData organData["shrapnel_len"] = shrapnelData.len var/organStatus[0] if(E.status & ORGAN_DESTROYED) organStatus["destroyed"] = 1 if(E.status & ORGAN_BROKEN) organStatus["broken"] = E.broken_description if(E.status & ORGAN_ROBOT) organStatus["robotic"] = 1 if(E.status & ORGAN_SPLINTED) organStatus["splinted"] = 1 if(E.status & ORGAN_BLEEDING) organStatus["bleeding"] = 1 if(E.status & ORGAN_DEAD) organStatus["dead"] = 1 organData["status"] = organStatus if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured()) organData["lungRuptured"] = 1 for(var/datum/wound/W in E.wounds) if(W.internal) organData["internalBleeding"] = 1 break extOrganData.Add(list(organData)) occupantData["extOrgan"] = extOrganData var/intOrganData[0] for(var/obj/item/organ/internal/I in H.internal_organs) var/organData[0] organData["name"] = I.name organData["desc"] = I.desc organData["germ_level"] = I.germ_level organData["damage"] = I.damage organData["maxHealth"] = I.max_damage organData["bruised"] = I.min_broken_damage organData["broken"] = I.min_bruised_damage organData["robotic"] = I.robotic organData["dead"] = (I.status & ORGAN_DEAD) intOrganData.Add(list(organData)) occupantData["intOrgan"] = intOrganData occupantData["blind"] = (H.disabilities & BLIND) occupantData["colourblind"] = (H.disabilities & COLOURBLIND) occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) data["occupant"] = occupantData return data /obj/machinery/body_scanconsole/Topic(href, href_list) if(..()) return 1 if(href_list["ejectify"]) src.connected.eject() if(href_list["print_p"]) generate_printing_text() if(!(printing) && printing_text) printing = 1 visible_message("\The [src] rattles and prints out a sheet of paper.") var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) P.info = "
Body Scan - [href_list["name"]]

" P.info += "Time of scan: [worldtime2text(world.time)]

" P.info += "[printing_text]" P.info += "

Notes:
" P.name = "Body Scan - [href_list["name"]]" printing = null printing_text = null /obj/machinery/body_scanconsole/proc/generate_printing_text() var/dat = "" if(connected) var/mob/living/carbon/human/occupant = connected.occupant dat = "Occupant Statistics:
" //Blah obvious if(istype(occupant)) //is there REALLY someone in there? var/t1 switch(occupant.stat) // obvious, see what their status is if(0) t1 = "Conscious" if(1) t1 = "Unconscious" else t1 = "*dead*" dat += "[occupant.health > 50 ? "" : ""]\tHealth %: [occupant.health], ([t1])
" if(occupant.viruses.len) dat += "Viral pathogen detected in blood stream.
" var/extra_font = null extra_font = (occupant.getBruteLoss() < 60 ? "" : "") dat += "[extra_font]\t-Brute Damage %: [occupant.getBruteLoss()]
" extra_font = (occupant.getOxyLoss() < 60 ? "" : "") dat += "[extra_font]\t-Respiratory Damage %: [occupant.getOxyLoss()]
" extra_font = (occupant.getToxLoss() < 60 ? "" : "") dat += "[extra_font]\t-Toxin Content %: [occupant.getToxLoss()]
" extra_font = (occupant.getFireLoss() < 60 ? "" : "") dat += "[extra_font]\t-Burn Severity %: [occupant.getFireLoss()]
" extra_font = (occupant.radiation < 10 ?"" : "") dat += "[extra_font]\tRadiation Level %: [occupant.radiation]
" extra_font = (occupant.getCloneLoss() < 1 ?"" : "") dat += "[extra_font]\tGenetic Tissue Damage %: [occupant.getCloneLoss()]
" extra_font = (occupant.getBrainLoss() < 1 ?"" : "") dat += "[extra_font]\tApprox. Brain Damage %: [occupant.getBrainLoss()]
" dat += "Paralysis Summary %: [occupant.paralysis] ([round(occupant.paralysis / 4)] seconds left!)
" dat += "Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)
" dat += "
" if(occupant.has_brain_worms()) dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
" if(occupant.vessel) var/blood_type = occupant.get_blood_name() var/blood_volume = round(occupant.vessel.get_reagent_amount(blood_type)) var/blood_percent = blood_volume / BLOOD_VOLUME_NORMAL blood_percent *= 100 extra_font = (blood_volume > 448 ? "" : "") dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)
" if(occupant.reagents) dat += "Epinephrine units: [occupant.reagents.get_reagent_amount("Epinephrine")] units
" dat += "Ether: [occupant.reagents.get_reagent_amount("ether")] units
" extra_font = (occupant.reagents.get_reagent_amount("silver_sulfadiazine") < 30 ? "" : "") dat += "[extra_font]\tSilver Sulfadiazine: [occupant.reagents.get_reagent_amount("silver_sulfadiazine")]
" extra_font = (occupant.reagents.get_reagent_amount("styptic_powder") < 30 ? "" : "") dat += "[extra_font]\tStyptic Powder: [occupant.reagents.get_reagent_amount("styptic_powder")] units
" extra_font = (occupant.reagents.get_reagent_amount("salbutamol") < 30 ? "" : "") dat += "[extra_font]\tSalbutamol: [occupant.reagents.get_reagent_amount("salbutamol")] units
" dat += "
" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" for(var/obj/item/organ/external/e in occupant.organs) dat += "" var/AN = "" var/open = "" var/infected = "" var/robot = "" var/imp = "" var/bled = "" var/splint = "" var/internal_bleeding = "" var/lung_ruptured = "" for(var/datum/wound/W in e.wounds) if(W.internal) internal_bleeding = "
Internal bleeding" break if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) lung_ruptured = "Lung ruptured:" if(e.status & ORGAN_SPLINTED) splint = "Splinted:" if(e.status & ORGAN_BLEEDING) bled = "Bleeding:" if(e.status & ORGAN_BROKEN) AN = "[e.broken_description]:" if(e.status & ORGAN_ROBOT) robot = "Prosthetic:" 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.implants) unknown_body++ if(unknown_body || e.hidden) imp += "Unknown body present:" if(!AN && !open && !infected & !imp) AN = "None:" if(!(e.status & ORGAN_DESTROYED)) dat += "" else dat += "" dat += "" for(var/obj/item/organ/internal/i in occupant.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][e.name]--Not Found
[i.name]N/A[i.damage][infection]:[mech]
" if(occupant.disabilities & BLIND) dat += "Cataracts detected.
" if(occupant.disabilities & COLOURBLIND) dat += "Photoreceptor abnormalities detected.
" if(occupant.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" else dat += "\The [src] is empty." else dat = " Error: No Body Scanner connected." printing_text = dat