#define AUTO_TRANSFUSE 1 #define AUTO_AIR 2 #define TRANSFUSE_ACTIVE 4 #define AIR_ACTIVE 8 #define VAMPIRE 16 /* * The more advanced life support table */ /obj/machinery/optable/lifesupport name = "Life Support Enabled Operating Table" desc = "A more advanced version of the standard operating table." icon_state = "table3-idle" modify_state = "table3" flags = OPENCONTAINER idle_power_usage = 3 active_power_usage = 8 var/movable = 0 //For buckling! var/buckled = 0 //Is the patient hooked up to the machine properly? var/active = 0 //Is the machine active, and providing lifesupport? var/expired = 0 //Have we alerted the folks about a dead patient yet? var/program = 0 //Bitfield for containing the programmable settings. var/obj/item/weapon/reagent_containers/blood/bloodbag //Stores the bloodbag that you can add to the machine, for IV dripping shenanigans. var/obj/item/weapon/tank/airsupply //Stores the airtank used for anesthesia. var/obj/item/clothing/mask/breath/medical/airmask //Stores the medical mask used for anesthesia. var/requiredchems = list( "clonexadone" = 0.06, "cryoxadone" = 0.2) //Details what chemicals (use ids, not names) it keeps track of, and the minimum quantities required for operation. Each time process() is called, the associated amount of that chemical is removed from storage. //Cryoxadone will last you around 10 minutes, Clonexadone around 30. (Provided you use the standard, 60 unit beaker.) var/list/internallog = list() //A log of everything that has happened on the table. Has two keys per entry: "time" and "message". /obj/machinery/optable/lifesupport/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/optable_lifesupport(src) component_parts += new /obj/item/weapon/cable_coil(src) component_parts += new /obj/item/weapon/stock_parts/console_screen(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/device/healthanalyzer(src) component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) component_parts += new /obj/item/weapon/stock_parts/scanning_module/adv(src) component_parts += new /obj/item/clothing/mask/breath/medical(src) RefreshParts() /obj/machinery/optable/lifesupport/attackby(obj/item/weapon/W as obj, mob/living/carbon/user as mob) . = ..() if (.) return if (istype(W, /obj/item/weapon/reagent_containers/blood)) if (!bloodbag) user.drop_item() bloodbag = W W.loc = src user << "You load [W] into [src], and hook it up to the machine." return else user << "There is already a bloodbag in [src]!" return if (W.is_open_container()) return 0 if (istype(W, /obj/item/weapon/tank)) if (!airsupply) user.drop_item() airsupply = W W.loc = src user << "You load [W] into [src], and hook it up the machine." return else user << "There is already [airsupply] in [src]!" return if (istype(W, /obj/item/weapon/card/emag)) if (!emagged) emagged = 1 user << "You run [W] through [src], hear the machine quietly whirr. A new option has been unlocked." return else user << "[src] is already emagged!" return /obj/machinery/optable/lifesupport/process() ..() if (active) if ((stat & NOPOWER) || (stat & BROKEN)) //Safety catch number 2: immediate failure of life support, upon power failure or machine damage. toggleactive(1) return //A safety catch. if (!victim || !buckled) toggleactive() if (program & TRANSFUSE_ACTIVE) toggleprogram(TRANSFUSE_ACTIVE) if (program & AIR_ACTIVE) toggleprogram(AIR_ACTIVE) return var/id = checkrequiredchems() if (!id) toggleactive(1) return else reagents.remove_reagent(id, requiredchems[id]) if (victim.stat == 2 && !expired) broadcastalert("ALERT! Patient death detected!") addtolog("Patient death detected.") expired = 1 var/bloodvolume = round(victim.vessel.get_reagent_amount("blood")) if ((program & AUTO_TRANSFUSE) && bloodbag && bloodbag.reagents.total_volume) if (bloodvolume < BLOOD_VOLUME_SAFE && !(program & TRANSFUSE_ACTIVE)) toggleprogram(TRANSFUSE_ACTIVE) else if (bloodvolume >= BLOOD_VOLUME_SAFE && (program & TRANSFUSE_ACTIVE)) toggleprogram(TRANSFUSE_ACTIVE) if (program & TRANSFUSE_ACTIVE) if (!bloodbag || !bloodbag.reagents.total_volume) toggleprogram(TRANSFUSE_ACTIVE) else bloodbag.reagents.trans_to(victim, 4) if ((program & AUTO_AIR) && airsupply && airsupply.air_contents.return_pressure() > 10) if (!(program & AIR_ACTIVE)) toggleprogram(AIR_ACTIVE) if ((program & AIR_ACTIVE) && (!airsupply || airsupply.air_contents.return_pressure() < 10)) toggleprogram(AIR_ACTIVE) if (program & VAMPIRE) victim.vessel.remove_reagent("blood", 5) /obj/machinery/optable/lifesupport/update_icon() if (opened) icon_state = "[modify_state]-open" else if (victim && active) icon_state = victim.pulse ? "[modify_state]-lifeactive" : "[modify_state]-lifeidle" else if (victim) icon_state = victim.pulse ? "[modify_state]-active" : "[modify_state]-idle" else icon_state = "[modify_state]-idle" /obj/machinery/optable/lifesupport/check_table(mob/living/carbon/patient as mob) if (victim) usr << "\blue The table is already occupied!" return 0 return 1 /obj/machinery/optable/lifesupport/onlifesupport() return active /obj/machinery/optable/lifesupport/RefreshParts() var/T = 0 for (var/obj/item/weapon/reagent_containers/glass/G in component_parts) T += G.reagents.maximum_volume var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials. reagents = R R.my_atom = src for (var/obj/item/clothing/mask/breath/medical/E in component_parts) airmask = E /obj/machinery/optable/lifesupport/proc/broadcastalert(var/message as text) playsound(loc, 'sound/machines/chime.ogg', 75, 1) visible_message("\icon[src]The Operating Table pings: [message]") /obj/machinery/optable/lifesupport/proc/checkrequiredchems() for (var/id in requiredchems) if (reagents.has_reagent(id, requiredchems[id])) return id return 0 /obj/machinery/optable/lifesupport/proc/addtolog(var/log as text) var/time = worldtime2text() internallog.Add(list(list("time" = time, "message" = log))) /obj/machinery/optable/lifesupport/proc/clearlog() if (internallog.len) internallog = list() /obj/machinery/optable/lifesupport/proc/eject(var/item as text) switch (item) if ("airsupply") if (airsupply) if (program & AIR_ACTIVE) broadcastalert("ERROR: Internal air supply still connected. Aborting!") return else airsupply.loc = loc airsupply = null broadcastalert("Internal air supply ejected.") addtolog("Internal air supply ejected.") return if ("bloodbag") if (bloodbag) if (program & TRANSFUSE_ACTIVE) broadcastalert("ERROR: Transfusion processes still underway. Aborting!") return else bloodbag.loc = loc bloodbag = null broadcastalert("Internal blood supply ejected.") addtolog("Internal blood supply ejected.") return if ("chems") if (reagents.total_volume) if (active) broadcastalert("ERROR: Life support systems enabled, unable to flush chemicals. Aborting!") return else broadcastalert("Stored chemicals flushed.") addtolog("Stored chemicals flushed.") reagents.clear_reagents() /obj/machinery/optable/lifesupport/proc/buckle(mob/living/carbon/human/patient as mob, mob/living/carbon/human/user as mob) if (!victim) user << "No patient to buckle in!" return if (patient == user) user << "You cannot do this yourself!" return if (active) user << "You cannot do this while lifesupport is enabled!" return if (!buckled) if (patient.wear_mask) user << "You need to remove their [patient.wear_mask] first!" return else if (patient.back) user << "You need to remove their [patient.back] first!" return switch (buckled) if (0) user.visible_message("[user] buckles \the [victim] into \the [src], linking them up to the required tubing and straps.", "You fit \the [victim] into \the [src]'s restraints, and hook them up to the life-support machine.") if (!patient.sleeping && !patient.stat) patient << "[user] buckles you into \the [src] and hooks you up to the lifesupport machinery." buckled = 1 patient.buckled = src patient.update_canmove() patient.equip_to_slot(airmask, slot_wear_mask) addtolog("Restraints activated.") return if (1) user.visible_message("[user] unbuckles \the [victim] from \the [src], disconnecting them from the tubing and straps.", "You remove \the [victim]'s restraints, and unhook them from the life-support machine.") if (!patient.sleeping && !patient.stat) patient << "[user] unbuckles you from \the [src] and disconnects you from the lifesupport machinery." buckled = 0 patient.buckled = null patient.anchored = initial(patient.anchored) patient.update_canmove() patient.u_equip(airmask) airmask.loc = src addtolog("Restraints deactivated.") return /obj/machinery/optable/lifesupport/verb/bucklepatient() set name = "Buckle Patient In" set category = "Object" set src in oview(1) if(usr.stat || !ishuman(usr) || usr.restrained()) return buckle(victim, usr) /obj/machinery/optable/lifesupport/proc/toggleactive(var/override = 0) if (!victim) broadcastalert("ERROR: No patient detected. Aborting!") return if (!buckled) broadcastalert("ERROR: Patient not linked to the machinery. Aborting!") return switch (active) if (0) if (stat & BROKEN) broadcastalert("ERROR: Machine damaged. Aborting!") return if (stat & NOPOWER) broadcastalert("ERROR: Machine not powered. Aborting!") return if (victim.stat == DEAD) broadcastalert("ERROR: No life signs detected from the patient. Unable to enable life support systems.") return if (checkrequiredchems()) active = 1 broadcastalert("Patient detected. Life support systems enabled.") addtolog("Life support systems enabled.") return else broadcastalert("ERROR: Required chemicals not detected in the machine. Aborting!") return if (1) if ((program & AUTO_TRANSFUSE) && (program & TRANSFUSE_ACTIVE)) toggleprogram(TRANSFUSE_ACTIVE) else if (program & TRANSFUSE_ACTIVE) if (!override) broadcastalert("ERROR: Transfusion processes still underway. Aborting!") return else toggleprogram(TRANSFUSE_ACTIVE) if ((program & AUTO_AIR) && (program & AIR_ACTIVE)) toggleprogram(AIR_ACTIVE) else if (program & AIR_ACTIVE) if (!override) broadcastalert("ERROR: Internal air supply still connected. Aborting!") return else toggleprogram(AIR_ACTIVE) active = 0 if (override) broadcastalert("ERROR: Not enough chemicals to sustain lifesupport functionality! Shutting down lifesupport systems!") addtolog("Emergency shutdown of life support systems.") else broadcastalert("Lifesupport systems disabled.") addtolog("Life support systems disabled.") return /obj/machinery/optable/lifesupport/proc/toggleprogram(setting, var/textsetting = null) if (textsetting) switch (textsetting) if ("AUTO_TRANSFUSE") setting = AUTO_TRANSFUSE if ("AUTO_AIR") setting = AUTO_AIR if ("TRANSFUSE_ACTIVE") setting = TRANSFUSE_ACTIVE if ("AIR_ACTIVE") setting = AIR_ACTIVE if ("VAMPIRE") setting = VAMPIRE if (program & setting) switch (setting) if (TRANSFUSE_ACTIVE) broadcastalert("Transfusion processes deactivated.") addtolog("Transfusion processes deactivated.") program &= ~setting return if (AIR_ACTIVE) victim.u_equip(airsupply) airsupply.loc = src if (victim.internals) victim.internals.icon_state = "internal0" broadcastalert("Internal air supply deactivated.") addtolog("Internal air supply deactivated.") program &= ~setting return if (VAMPIRE) if (!emagged) return else program &= ~setting return else var/textname if (setting == AUTO_TRANSFUSE) textname = "Automatic transfusion control" else if (setting == AUTO_AIR) textname = "Automatic air supply control" else textname = "Unknown program" addtolog("[textname] deactivated.") program &= ~setting else switch (setting) if (TRANSFUSE_ACTIVE) if (bloodbag && bloodbag.reagents.total_volume) broadcastalert("Transfusion processes activated.") addtolog("Transfusion processes activated.") program |= setting return else broadcastalert("Bloodbag empty or not connected!") return if (AIR_ACTIVE) if (airsupply && airsupply.air_contents.return_pressure() > 10) victim.equip_to_slot(airsupply, slot_back) victim.internal = airsupply if (victim.internals) victim.internals.icon_state = "internal1" broadcastalert("Internal air supply activated.") addtolog("Internal air supply activated.") program |= setting return else broadcastalert("Air supply empty or not connected!") return if (VAMPIRE) if (!emagged) return else program |= setting else var/textname if (setting == AUTO_TRANSFUSE) textname = "Automatic transfusion control" else if (setting == AUTO_AIR) textname = "Automatic air supply control" else textname = "Unknown program" addtolog("[textname] activated.") program |= setting /obj/machinery/optable/lifesupport/proc/checkprogram(var/textsetting as text) var/setting switch (textsetting) if ("AUTO_TRANSFUSE") setting = AUTO_TRANSFUSE if ("AUTO_AIR") setting = AUTO_AIR if ("TRANSFUSE_ACTIVE") setting = TRANSFUSE_ACTIVE if ("AIR_ACTIVE") setting = AIR_ACTIVE if ("VAMPIRE") setting = VAMPIRE if (program & setting) return 1 else return 0 #undef AUTO_TRANSFUSE #undef AUTO_AIR #undef TRANSFUSE_ACTIVE #undef AIR_ACTIVE #undef VAMPIRE