/obj/structure/medical_stand name = "medical stand" icon = 'icons/obj/medical_stand_vr.dmi' desc = "Medical stand used to hang reagents for transfusion and to hold anesthetic tank." icon_state = "medical_stand_empty" //gas stuff var/obj/item/weapon/tank/tank var/mob/living/carbon/human/breather var/obj/item/clothing/mask/breath/contained var/spawn_type = null var/mask_type = /obj/item/clothing/mask/breath/medical var/is_loosen = TRUE var/valve_opened = FALSE //blood stuff var/mob/living/carbon/attached var/mode = 1 // 1 is injecting, 0 is taking blood. var/obj/item/weapon/reagent_containers/beaker var/list/transfer_amounts = list(REM, 1, 2) var/transfer_amount = 1 /obj/structure/medical_stand/New() ..() if (spawn_type) tank = new spawn_type (src) contained = new mask_type (src) update_icon() /obj/structure/medical_stand/update_icon() cut_overlays() if (tank) if (breather) add_overlay("tube_active") else add_overlay("tube") if(istype(tank,/obj/item/weapon/tank/anesthetic)) add_overlay("tank_anest") else if(istype(tank,/obj/item/weapon/tank/nitrogen)) add_overlay("tank_nitro") else if(istype(tank,/obj/item/weapon/tank/oxygen)) add_overlay("tank_oxyg") else if(istype(tank,/obj/item/weapon/tank/phoron)) add_overlay("tank_plasma") //else if(istype(tank,/obj/item/weapon/tank/hydrogen)) // add_overlay("tank_hydro") else add_overlay("tank_other") if(beaker) add_overlay("beaker") if(attached) add_overlay("line_active") else add_overlay("line") var/datum/reagents/reagents = beaker.reagents var/percent = round((reagents.total_volume / beaker.volume) * 100) if(reagents.total_volume) var/image/filling = image('icons/obj/medical_stand_vr.dmi', src, "reagent") switch(percent) if(10 to 24) filling.icon_state = "reagent10" if(25 to 49) filling.icon_state = "reagent25" if(50 to 74) filling.icon_state = "reagent50" if(75 to 79) filling.icon_state = "reagent75" if(80 to 90) filling.icon_state = "reagent80" if(91 to INFINITY) filling.icon_state = "reagent100" if (filling.icon) filling.icon += reagents.get_color() add_overlay(filling) /obj/structure/medical_stand/Destroy() STOP_PROCESSING(SSobj,src) if(breather) breather.internal = null breather.internals?.icon_state = "internal0" if(tank) qdel(tank) if(breather) breather.remove_from_mob(contained) src.visible_message("The mask rapidly retracts just before /the [src] is destroyed!") qdel(contained) contained = null breather = null attached = null qdel(beaker) beaker = null return ..() /obj/structure/medical_stand/attack_robot(var/mob/user) if(Adjacent(user)) attack_hand(user) /obj/structure/medical_stand/MouseDrop(var/mob/living/carbon/human/target, src_location, over_location) ..() if(istype(target)) if(usr.stat == DEAD || !CanMouseDrop(target)) return var/list/available_options = list() if (tank) available_options += "Gas mask" if (beaker) available_options += "Drip needle" var/action_type if(available_options.len > 1) action_type = tgui_input_list(usr, "What do you want to attach/detach?", "Attach/Detach Choice", available_options) else if(available_options.len) action_type = available_options[1] if(usr.stat == DEAD || !CanMouseDrop(target)) return switch (action_type) if("Gas mask") if(!can_apply_to_target(target, usr)) // There is no point in attempting to apply a mask if it's impossible. return if (breather) src.add_fingerprint(usr) if(!do_mob(usr, target, 30) || !can_apply_to_target(target, usr)) return if(tank) tank.forceMove(src) if (breather.wear_mask == contained) breather.remove_from_mob(contained) contained.forceMove(src) else qdel(contained) contained = new mask_type(src) breather = null src.visible_message("\The [contained] slips to \the [src]!") update_icon() return usr.visible_message("\The [usr] begins carefully placing the mask onto [target].", "You begin carefully placing the mask onto [target].") if(!do_mob(usr, target, 100) || !can_apply_to_target(target, usr)) return // place mask and add fingerprints usr.visible_message("\The [usr] has placed \the mask on [target]'s mouth.", "You have placed \the mask on [target]'s mouth.") if(attach_mask(target)) src.add_fingerprint(usr) update_icon() START_PROCESSING(SSobj,src) return if("Drip needle") if(attached) if(!do_mob(usr, target, 20)) return visible_message("\The [attached] is taken off \the [src]") attached = null else if(ishuman(target)) usr.visible_message("\The [usr] begins inserting needle into [target]'s vein.", "You begin inserting needle into [target]'s vein.") if(!do_mob(usr, target, 50)) usr.visible_message("\The [usr]'s hand slips and pricks \the [target].", "Your hand slips and pricks \the [target].") target.apply_damage(3, BRUTE, pick(BP_R_ARM, BP_L_ARM)) return usr.visible_message("\The [usr] hooks \the [target] up to \the [src].", "You hook \the [target] up to \the [src].") attached = target START_PROCESSING(SSobj,src) update_icon() /obj/structure/medical_stand/attack_hand(mob/user as mob) var/list/available_options = list() if (tank) available_options += "Toggle valve" available_options += "Remove tank" if (beaker) available_options += "Remove vessel" var/action_type if(available_options.len > 1) action_type = tgui_input_list(user, "What do you want to do?", "Stand Choice", available_options) else if(available_options.len) action_type = available_options[1] switch (action_type) if ("Remove tank") if (!tank) to_chat(user, "There is no tank in \the [src]!") return else if (tank && is_loosen) user.visible_message("\The [user] removes \the [tank] from \the [src].", "You remove \the [tank] from \the [src].>") user.put_in_hands(tank) tank = null update_icon() return else if (!is_loosen) user.visible_message("\The [user] tries to removes \the [tank] from \the [src] but it won't budge.", "You try to removes \the [tank] from \the [src] but it won't budge.>") return if ("Toggle valve") if (!tank) to_chat(user, "There is no tank in \the [src]!") return else if (valve_opened) src.visible_message("\The [user] closes valve on \the [src]!", "You close valve on \the [src].") if(breather) breather.internals?.icon_state = "internal0" breather.internal = null valve_opened = FALSE update_icon() else src.visible_message("\The [user] opens valve on \the [src]!", "You open valve on \the [src].") if(breather) breather.internal = tank breather.internals?.icon_state = "internal1" valve_opened = TRUE //playsound(src, 'sound/effects/internals.ogg', 100, 1) update_icon() START_PROCESSING(SSobj,src) if ("Remove vessel") if(beaker) beaker.forceMove(loc) beaker = null update_icon() /obj/structure/medical_stand/verb/toggle_mode() set category = "Object" set name = "Toggle IV Mode" set src in view(1) if(!istype(usr, /mob/living)) to_chat(usr, "You can't do that.") return if(usr.incapacitated()) return mode = !mode to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].") /obj/structure/medical_stand/verb/set_APTFT() set name = "Set IV transfer amount" set category = "Object" set src in range(1) var/N = tgui_input_list(usr, "Amount per transfer from this:","[src]", transfer_amounts) if(N) transfer_amount = N /obj/structure/medical_stand/proc/attach_mask(var/mob/living/carbon/C) if(C && istype(C)) if(C.equip_to_slot_if_possible(contained, slot_wear_mask)) if(tank) tank.forceMove(C) breather = C return TRUE /obj/structure/medical_stand/proc/can_apply_to_target(var/mob/living/carbon/human/target, var/mob/user) if(!user) user = target // Check target validity if(!istype(target)) to_chat(user, "\The [target] not compatible with machine.") return if(!target.organs_by_name[BP_HEAD]) to_chat(user, "\The [target] doesn't have a head.") return if(!target.check_has_mouth()) to_chat(user, "\The [target] doesn't have a mouth.") return if(target.wear_mask && target != breather) to_chat(user, "\The [target] is already wearing a mask.") return if(target.head && (target.head.body_parts_covered & FACE)) to_chat(user, "Remove their [target.head] first.") return if(!tank) to_chat(user, "There is no tank in \the [src].") return if(is_loosen) to_chat(user, "Tighten \the nut with a wrench first.") return if(!Adjacent(target)) return //when there is a breather: if(breather && target != breather) to_chat(user, "\The [src] is already in use.") return //Checking if breather is still valid if(target == breather && target.wear_mask != contained) to_chat(user, "\The [target] is not using the supplied mask.") return return 1 /obj/structure/medical_stand/attackby(var/obj/item/weapon/W, var/mob/user) if(istype (W, /obj/item/weapon/tool)) if (valve_opened) to_chat(user, "Close the valve first.") return if (tank) if(!W.is_wrench()) return if (!is_loosen) is_loosen = TRUE else is_loosen = FALSE if (valve_opened) START_PROCESSING(SSobj,src) user.visible_message( "The [user] [is_loosen == TRUE ? "loosen" : "tighten"] the nut holding [tank] in place.", "You [is_loosen == TRUE ? "loosen" : "tighten"] the nut holding [tank] in place.") else to_chat(user, "There is no tank in \the [src].") else if(istype(W, /obj/item/weapon/tank)) if(tank) to_chat(user, "\The [src] already has a tank installed!") else if(!is_loosen) to_chat(user, "Loosen the nut with a wrench first.") else user.drop_item() W.forceMove(src) tank = W user.visible_message("\The [user] attaches \the [tank] to \the [src].", "You attach \the [tank] to \the [src].") src.add_fingerprint(user) update_icon() else if (istype(W, /obj/item/weapon/reagent_containers)) if(!isnull(src.beaker)) to_chat(user, "There is already a reagent container loaded!") return user.drop_item() W.forceMove(src) beaker = W to_chat(user, "You attach \the [W] to \the [src].") update_icon() else return ..() /obj/structure/medical_stand/examine(var/mob/user) . = ..() if (get_dist(src, user) > 2) return if(beaker) . += "The IV drip is [mode ? "injecting" : "taking blood"]." . += "It is set to transfer [transfer_amount]u of chemicals per cycle." if(beaker.reagents && beaker.reagents.total_volume) . += "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid." else . += "Attached is an empty [beaker]." . += "[attached ? attached : "No one"] is hooked up to it." else . += "There is no vessel." if(tank) if (!is_loosen) . += "\The [tank] connected." . += "The meter shows [round(tank.air_contents.return_pressure())]. The valve is [valve_opened == TRUE ? "open" : "closed"]." if (tank.distribute_pressure == 0) . += "Use wrench to replace tank." else . += "There is no tank." /obj/structure/medical_stand/process() //Gas Stuff if(breather) if(!can_apply_to_target(breather)) if(tank) tank.forceMove(src) if (breather.wear_mask == contained) breather.remove_from_mob(contained) contained.forceMove(src) else qdel(contained) contained = new mask_type (src) src.visible_message("\The [contained] slips to \the [src]!") breather = null update_icon() return if(valve_opened) if (tank) breather.internal = tank breather.internals?.icon_state = "internal1" else breather.internals?.icon_state = "internal0" breather.internal = null else if (valve_opened) var/datum/gas_mixture/removed = tank.remove_air(0.01) var/datum/gas_mixture/environment = loc.return_air() environment.merge(removed) //Reagent Stuff if(attached) if(!Adjacent(attached)) visible_message("The needle is ripped out of [src.attached], doesn't that hurt?") attached.apply_damage(3, BRUTE, pick(BP_R_ARM, BP_L_ARM)) attached = null update_icon() if(beaker) if(mode) // Give blood if(beaker.volume > 0) beaker.reagents.trans_to_mob(attached, transfer_amount, CHEM_BLOOD) update_icon() else // Take blood var/amount = beaker.reagents.maximum_volume - beaker.reagents.total_volume amount = min(amount, 4) if(amount == 0) // If the beaker is full, ping if(prob(5)) visible_message("\The [src] pings.") return var/mob/living/carbon/human/H = attached if(!istype(H)) return if(!H.dna) return if(NOCLONE in H.mutations) return if(H.species.flags & NO_BLOOD) return if(!H.should_have_organ(O_HEART)) return // If the human is losing too much blood, beep. if(H.vessel.get_reagent_amount("blood") < H.species.blood_volume*H.species.blood_level_safe) visible_message("\The [src] beeps loudly.") var/datum/reagent/B = H.take_blood(beaker,amount) if (B) beaker.reagents.reagent_list |= B beaker.reagents.update_total() beaker.on_reagent_change() beaker.reagents.handle_reactions() update_icon() if ((!valve_opened || tank.distribute_pressure == 0) && !breather && !attached) return PROCESS_KILL /obj/structure/medical_stand/anesthetic spawn_type = /obj/item/weapon/tank/anesthetic mask_type = /obj/item/clothing/mask/breath/medical is_loosen = FALSE