/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 = "
| Organ | " dat += "Burn Damage | " dat += "Brute Damage | " dat += "Other Wounds | " dat += "||||
|---|---|---|---|---|---|---|---|
| [e.name] | [e.burn_dam] | [e.brute_dam] | [robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured] | " else dat += "[e.name] | - | - | Not Found | " dat += "
| [i.name] | N/A | [i.damage] | [infection]:[mech] | " dat += " |