#define EPP "Emergency Positive Pressure system" /obj/item/auto_cpr name = "stabilizer harness" desc = "A specialized medical harness that gives regular compressions to the patient's ribcage for cases of urgent heart issues, and functions as an emergency \ artificial respirator for cases of urgent lung issues." desc_info = "The Stabilizer Harness' CPR mode is capable of restarting the heart much like manual CPR with a chance for rib cracking ONLY IF the patient is flat lining,\ while the EPP mode can keep the patient breathing during transport for as long as there's appropriate air in the installed tank. Both use power from the battery. \
Use this item in your hand to toggle the CPR or EPP modes on/off.
Use a Screwdriver on it to unscrew the panel to be able to remove/add other items. \ The tank can be removed with a Wrench. The battery can be removed with a crowbar. Use the item in your hand the panel unscrewed to remove the breath mask." icon = 'icons/obj/med_harness.dmi' icon_state = "med_harness" item_state = "med_harness" contained_sprite = TRUE w_class = ITEMSIZE_NORMAL origin_tech = list(TECH_MAGNET = 5, TECH_BIO = 3) slot_flags = SLOT_OCLOTHING var/panel_open = FALSE var/last_pump var/last_bm_check var/obj/item/cell/battery = null var/battery_level = 0 var/charge_cost = 7 // 7 for 1 active function. Total of 14 if both CPR and EPP are doing their thing var/cpr_mode = TRUE // Auto-Compressor system. Can be toggled on/off var/mob/living/carbon/human/breather = null var/obj/item/clothing/mask/breath/breath_mask = null var/obj/item/tank/emergency_oxygen/tank = null var/tank_level = 0 var/tank_type = null var/mask_on = FALSE var/epp_mode = FALSE // Emergency Positive Pressure system. Can be toggled on/off var/epp_active = FALSE var/list/mask_blacklist = list( /obj/item/clothing/mask/gas/vaurca, /obj/item/clothing/mask/breath/skrell, /obj/item/clothing/mask/breath/lyodsuit, /obj/item/clothing/mask/breath/infiltrator) /obj/item/auto_cpr/Initialize() . = ..() battery = new /obj/item/cell(src) breath_mask = new /obj/item/clothing/mask/breath/medical(src) tank = new /obj/item/tank/emergency_oxygen/engi(src) update_icon() /obj/item/auto_cpr/Destroy() STOP_PROCESSING(SSprocessing, src) QDEL_NULL(battery) if(breather) breath_mask_off() QDEL_NULL(breath_mask) QDEL_NULL(tank) return ..() /obj/item/auto_cpr/build_additional_parts(H, mob_icon, slot) var/image/I = ..() if(!I) I = image(null) var/c_icon = 'icons/obj/med_harness.dmi' if(battery) var/c_state = "battery[battery_level][contained_sprite ? slot_str_to_contained_flag(slot) : ""]" var/image/battery_overlay = image(c_icon, c_state) battery_overlay.appearance_flags = RESET_ALPHA I.AddOverlays(battery_overlay) if(breath_mask) var/c_state = "mask_[mask_on ? "worn" : "idle"][contained_sprite ? slot_str_to_contained_flag(slot) : ""]" var/image/mask_overlay = image(c_icon, c_state) mask_overlay.appearance_flags = RESET_ALPHA I.AddOverlays(mask_overlay) if(tank) if(tank_level) var/c_state = "tank_indicator[tank_level][contained_sprite ? slot_str_to_contained_flag(slot) : ""]" var/image/tank_level_overlay = image(c_icon, c_state) tank_level_overlay.appearance_flags = RESET_ALPHA I.AddOverlays(tank_level_overlay) var/c_state = "tank_[tank_type][contained_sprite ? slot_str_to_contained_flag(slot) : ""]" var/image/tank_overlay = image(c_icon, c_state) tank_overlay.appearance_flags = RESET_ALPHA I.AddOverlays(tank_overlay) if(epp_active) var/c_state = "epp_active[cpr_mode ? "_cpr" : ""][contained_sprite ? slot_str_to_contained_flag(slot) : ""]" var/image/epp_overlay = image(c_icon, c_state) epp_overlay.appearance_flags = RESET_ALPHA I.AddOverlays(epp_overlay) return I /obj/item/auto_cpr/update_icon() ClearOverlays() item_state = "[cpr_mode ? "med_harness_cpr" : "[initial(item_state)]"]" if(breath_mask) AddOverlays("mask_[mask_on ? "worn" : "idle"]") if(battery) switch(battery.percent()) if(90 to INFINITY) battery_level = 6 if(80 to 90) battery_level = 5 if(60 to 79) battery_level = 4 if(40 to 59) battery_level = 3 if(20 to 39) battery_level = 2 if(05 to 19) battery_level = 1 if(-INFINITY to 4) battery_level = 0 AddOverlays("battery[battery_level]") if(tank) switch(tank.percent()) if(90 to INFINITY) tank_level = 6 if(80 to 90) tank_level = 5 if(60 to 79) tank_level = 4 if(40 to 59) tank_level = 3 if(20 to 39) tank_level = 2 if(05 to 19) tank_level = 1 if(-INFINITY to 4) tank_level = 0 AddOverlays("tank_indicator[tank_level]") if(istype(tank, /obj/item/tank/emergency_oxygen/engi)) tank_type = "engi" else if(istype(tank, /obj/item/tank/emergency_oxygen)) tank_type = "oxy" else tank_type = "other" AddOverlays("tank_[tank_type]") if(epp_active) AddOverlays("epp_active") if(panel_open) AddOverlays("panel_open[battery ? "_battery" : ""]") /obj/item/auto_cpr/mob_can_equip(mob/living/carbon/human/H, slot, disable_warning = 0, force = 0) . = ..() if(slot == slot_wear_suit) if(panel_open) return FALSE return if(force || !istype(H) || slot != slot_wear_suit) return if(H.species.get_bodytype() in list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_SKRELL, BODYTYPE_UNATHI)) //gtfo stinky bugs return else return FALSE /obj/item/auto_cpr/attack(mob/living/carbon/human/H, mob/living/user, var/target_zone) if(istype(H) && user.a_intent == I_HELP) if(panel_open) to_chat(user, SPAN_WARNING("You must screw \the [src]'s panel closed before fitting it onto anyone!")) return 1 if(H.wear_suit) to_chat(user, SPAN_WARNING("Their [H.wear_suit] is in the way, remove it first!")) return 1 user.visible_message(SPAN_NOTICE("[user] starts fitting \the [src] onto [H]'s chest.")) if(!do_after(user, 2 SECONDS, H)) to_chat(user, SPAN_DANGER("Failed fitting \the [src] onto [H]! Both you and [H] must remain still for you to do that!")) return if(user.unEquip(src)) if(!H.equip_to_slot_if_possible(src, slot_wear_suit, delete_on_fail = FALSE, disable_warning = TRUE, redraw_mob = TRUE)) user.put_in_active_hand(src) return 1 else return ..() /obj/item/auto_cpr/attackby(obj/item/attacking_item, mob/user) if(attacking_item.isscrewdriver()) if(ishuman(loc)) var/mob/living/carbon/human/H = loc if(H.get_inventory_slot(src) == slot_wear_suit) to_chat(user, SPAN_WARNING("You must unequip \the [src] before doing that!")) return TRUE panel_open = !panel_open user.visible_message(SPAN_NOTICE("[user] screws \the [src]'s panel [panel_open ? "open" : "closed"]."), SPAN_NOTICE("You screw \the [src]'s panel [panel_open ? "open" : "closed"].")) update_icon() return TRUE if(panel_open) if(attacking_item.iswrench()) if(!tank) to_chat(user, "There isn't a tank to remove!") return TRUE user.visible_message(SPAN_NOTICE("[user] removes \the [tank] from \the [src]."), SPAN_NOTICE("You remove \the [tank] from \the [src].")) tank.forceMove(user.loc) user.put_in_hands(tank) tank = null update_icon() return TRUE if(attacking_item.iscrowbar()) if(!battery) to_chat(user, "There isn't a battery to remove!") return TRUE user.visible_message(SPAN_NOTICE("[user] removes \the [battery] from \the [src]."), SPAN_NOTICE("You remove \the [battery] from \the [src].")) battery.forceMove(user.loc) user.put_in_hands(battery) battery = null update_icon() return TRUE if(istype(attacking_item, /obj/item/cell)) if(battery) to_chat(user, "There is already \a [battery] installed.") return TRUE user.drop_from_inventory(attacking_item, src) battery = attacking_item user.visible_message(SPAN_NOTICE("[user] places \the [attacking_item] in \the [src]."), SPAN_NOTICE("You place \the [attacking_item] in \the [src].")) update_icon() return TRUE if(istype(attacking_item, /obj/item/clothing/mask/breath)) if(is_type_in_list(attacking_item, mask_blacklist)) to_chat(user, "\The [attacking_item] is incompatible with \the [src].") return TRUE if(breath_mask) to_chat(user, "There is already \a [breath_mask] installed.") return TRUE user.drop_from_inventory(attacking_item, src) breath_mask = attacking_item user.visible_message(SPAN_NOTICE("[user] places \the [attacking_item] in \the [src]."), SPAN_NOTICE("You place \the [attacking_item] in \the [src].")) update_icon() return TRUE if(istype(attacking_item, /obj/item/tank/emergency_oxygen)) if(tank) to_chat(user, "There is already \a [tank] installed!") return TRUE user.drop_from_inventory(attacking_item, src) tank = attacking_item user.visible_message(SPAN_NOTICE("[user] places \the [attacking_item] in \the [src]."), SPAN_NOTICE("You place \the [attacking_item] in \the [src].")) update_icon() return TRUE /obj/item/auto_cpr/attack_self(mob/user) if(panel_open) if(!breath_mask) to_chat(user, "There isn't an installed mask to remove!") return user.visible_message(SPAN_NOTICE("[user] removes \the [breath_mask] from \the [src]."), SPAN_NOTICE("You remove \the [breath_mask] from \the [src].")) breath_mask.forceMove(user.loc) user.put_in_hands(breath_mask) breath_mask = null update_icon() return var/list/options = list( "Toggle CPR" = image('icons/mob/screen/radial.dmi', "cpr_mode"), "Toggle EPP" = image('icons/mob/screen/radial.dmi', "iv_epp")) var/chosen_action = show_radial_menu(user, src, options, require_near = TRUE, radius = 42, tooltips = TRUE) if(!chosen_action) return switch(chosen_action) if("Toggle CPR") toggle_cpr() if("Toggle EPP") toggle_epp() /obj/item/auto_cpr/attack_hand(mob/user) ..() /obj/item/auto_cpr/emp_act(severity) . = ..() epp_off() cpr_mode = FALSE if(battery) battery.emp_act(severity) update_icon() /obj/item/auto_cpr/get_cell() return battery /obj/item/auto_cpr/equipped(mob/user, slot) ..() START_PROCESSING(SSprocessing,src) /obj/item/auto_cpr/dropped(mob/user) STOP_PROCESSING(SSprocessing,src) ..() /obj/item/auto_cpr/process() if(!ishuman(loc)) return PROCESS_KILL var/mob/living/carbon/human/H = loc if(H.get_inventory_slot(src) != slot_wear_suit) if(mask_on) breath_mask_off() update_icon() return PROCESS_KILL if(!battery) return PROCESS_KILL if(battery.charge <= 0) if(epp_mode) epp_off() if(cpr_mode) cpr_mode = FALSE visible_message(SPAN_WARNING("\The [src] sputters as it runs out of charge!")) playsound(src, 'sound/machines/synth_no.ogg', 50) update_icon() return PROCESS_KILL if(cpr_mode) cpr_process(H) if(epp_mode) epp_process(H) H.update_inv_wear_suit() update_icon() /obj/item/auto_cpr/proc/cpr_process(mob/living/carbon/human/H) if(world.time > last_pump + 10 SECONDS) last_pump = world.time playsound(src, 'sound/machines/pump.ogg', 25) var/obj/item/organ/internal/heart/heart = H.internal_organs_by_name[BP_HEART] if(heart) heart.external_pump = list(world.time, 0.6) battery.use(charge_cost) if(H.is_asystole()) if(H.stat != DEAD && prob(10)) H.resuscitate() if(prob(5 * rand(2, 3))) var/obj/item/organ/external/chest = H.get_organ(BP_CHEST) if(chest) chest.fracture() /obj/item/auto_cpr/proc/epp_process(mob/living/carbon/human/H) if(!tank || !breath_mask) src.visible_message(SPAN_WARNING("Error! Vital component for \the [src]'s [EPP] missing! Turning function off.")) epp_off() return if(H.species.flags & NO_BREATHE) epp_off() return if(!mask_on) if(world.time > last_bm_check + 7 SECONDS) // Give it a few seconds before trying again last_bm_check = world.time breath_mask_on(H) return var/mask_check = breath_mask.get_equip_slot() if(mask_check != slot_wear_mask) breath_mask_off() return if(breath_mask.hanging) breath_mask_off() return if(breath_mask.loc != breather) breath_mask_off() return var/obj/item/organ/internal/lungs/lungs = H.internal_organs_by_name[BP_LUNGS] var/safe_pressure_min = H.species.breath_pressure + 2 safe_pressure_min *= 1 + rand(1,4) * lungs.damage/lungs.max_damage if(!lungs) epp_off() return if(lungs.checking_rupture == FALSE) src.visible_message(SPAN_WARNING("Error! Patient safety check triggered! Turning the [EPP] off.")) epp_off() return if(tank.air_contents.return_pressure() <= 10) src.visible_message(SPAN_WARNING("Error! Installed [tank] is low or near empty! Turning the [EPP] off.")) epp_off() return if(H.losebreath > 0) if(!epp_active) src.visible_message(SPAN_WARNING("\The [src] beeps, activating it's [EPP]!")) tank.forceMove(H) H.internal = tank if(H.internals) H.internals.icon_state = "internal1" playsound(H, 'sound/machines/windowdoor.ogg', 50) epp_active = TRUE tank.distribute_pressure = safe_pressure_min H.losebreath = 0 to_chat(H, SPAN_NOTICE("You feel fresh air being pushed into your lungs.")) battery.use(charge_cost) /obj/item/auto_cpr/proc/breath_mask_on(mob/living/carbon/human/H) if(!H.organs_by_name[BP_HEAD]) src.visible_message(SPAN_WARNING("Error! Patient lacks a head!")) playsound(src, 'sound/machines/buzz-sigh.ogg', 50) return if(!H.check_has_mouth()) src.visible_message(SPAN_WARNING("Error! Patient lacks a mouth!")) playsound(src, 'sound/machines/buzz-sigh.ogg', 50) return if(H.head && (H.head.body_parts_covered & FACE)) src.visible_message(SPAN_WARNING("Error! Access to patient's head is obstructed!")) playsound(src, 'sound/machines/buzz-sigh.ogg', 50) return if(H.wear_mask) src.visible_message(SPAN_WARNING("Error! Access to patient's mouth is obstructed!")) playsound(src, 'sound/machines/buzz-sigh.ogg', 50) return src.visible_message(SPAN_INFO("\The [src] automatically fastens \the [breath_mask] onto \the [H].")) playsound(H, 'sound/effects/buckle.ogg', 50) breath_mask.forceMove(H.loc) H.equip_to_slot(breath_mask, slot_wear_mask) H.update_inv_wear_mask() breather = H mask_on = TRUE update_icon() /obj/item/auto_cpr/proc/breath_mask_off() src.visible_message(SPAN_WARNING("\The [src] automatically retracts \the [breath_mask]!")) if(epp_active) tank.forceMove(src) if(breather.internals) breather.internals.icon_state = "internal0" breather.internal = null epp_active = FALSE if(breath_mask.hanging) breath_mask.hanging = FALSE breath_mask.adjust_sprites() if(breath_mask.loc != breather) var/loc_check = breath_mask.loc if(ismob(loc_check)) var/mob/living/carbon/human/holder = loc_check holder.remove_from_mob(breath_mask) holder.update_inv_wear_mask() holder.update_inv_l_hand() holder.update_inv_r_hand() breath_mask.forceMove(src) breather = null mask_on = FALSE return breather.remove_from_mob(breath_mask) breather.update_inv_wear_mask() breath_mask.forceMove(src) breather = null mask_on = FALSE /obj/item/auto_cpr/proc/epp_off() if(mask_on) breath_mask_off() playsound(src, 'sound/machines/buzz-two.ogg', 50) epp_mode = FALSE /obj/item/auto_cpr/proc/toggle_check(mob/user) if(!ishuman(user) && !issilicon(user)) to_chat(user, SPAN_WARNING("This mob cannot use this!")) return if(user.stat || user.incapacitated()) to_chat(user, SPAN_WARNING("You are in no shape to do this.")) return return TRUE /obj/item/auto_cpr/verb/toggle_epp() set category = "Object" set name = "Toggle EPP" set src in usr if(!toggle_check(usr)) return if(battery?.charge <= 0) to_chat(usr, SPAN_WARNING("\The [src] doesn't have enough power for you to do that!")) playsound(src, 'sound/machines/synth_no.ogg', 50) return if(epp_mode) epp_off() to_chat(usr, SPAN_NOTICE("You toggle \the [src]'s [EPP] off.")) return epp_mode = TRUE to_chat(usr, SPAN_NOTICE("You toggle \the [src]'s [EPP] on.")) playsound(usr, 'sound/machines/click.ogg', 50) update_icon() /obj/item/auto_cpr/verb/toggle_cpr() set category = "Object" set name = "Toggle CPR" set src in usr if(!toggle_check(usr)) return if(battery?.charge <= 0) to_chat(usr, SPAN_WARNING("\The [src] doesn't have enough power for you to do that!")) playsound(src, 'sound/machines/synth_no.ogg', 50) return cpr_mode = !cpr_mode to_chat(usr, SPAN_NOTICE("You toggle \the [src]'s Auto CPR system [cpr_mode ? "on" : "off"].")) playsound(usr, 'sound/machines/click.ogg', 50) update_icon() /obj/item/auto_cpr/get_examine_text(mob/user, distance, is_adjacent, infix, suffix) . = ..() if(!is_adjacent) return . += SPAN_NOTICE("\The [src]'s [EPP] is currently [epp_mode ? "on" : "off"], while the Auto CPR is [cpr_mode ? "on" : "off"].") if(battery) . += SPAN_NOTICE("It currently has a battery with [battery.percent()]% charge.") if(tank) . += SPAN_NOTICE("It has [icon2html(tank, user)] \the [tank] installed. The meter shows [round(tank.air_contents.return_pressure())]kPa, \ with the pressure set to [round(tank.distribute_pressure)]kPa.[epp_active ? " The [EPP] is active." : ""]") if(breath_mask) . += SPAN_NOTICE("It has [icon2html(breath_mask, user)] \the [breath_mask] installed.") #undef EPP