// Sleeper, Medical Beam, and Syringe gun /obj/item/mecha_parts/mecha_equipment/medical /obj/item/mecha_parts/mecha_equipment/medical/New() ..() START_PROCESSING(SSobj, src) /obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/mecha/medical/M) if(..() && istype(M)) return 1 /obj/item/mecha_parts/mecha_equipment/medical/attach(obj/mecha/M) ..() START_PROCESSING(SSobj, src) /obj/item/mecha_parts/mecha_equipment/medical/Destroy() STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/medical/process() if(!chassis) STOP_PROCESSING(SSobj, src) return 1 /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach() STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/medical/sleeper name = "mounted sleeper" desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." icon = 'icons/obj/Cryogenic2.dmi' icon_state = "sleeper" origin_tech = "engineering=3;biotech=3;plasmatech=2" energy_drain = 20 range = MELEE equip_cooldown = 20 var/mob/living/carbon/patient = null var/inject_amount = 10 salvageable = 0 /obj/item/mecha_parts/mecha_equipment/medical/sleeper/allow_drop() return 0 /obj/item/mecha_parts/mecha_equipment/medical/sleeper/Destroy() for(var/atom/movable/AM in src) AM.forceMove(get_turf(src)) return ..() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/Exit(atom/movable/O) return 0 /obj/item/mecha_parts/mecha_equipment/medical/sleeper/action(mob/living/carbon/target) if(!action_checks(target)) return if(!istype(target)) return if(!patient_insertion_check(target)) return occupant_message("You start putting [target] into [src]...") chassis.visible_message("[chassis] starts putting [target] into \the [src].") if(do_after_cooldown(target)) if(!patient_insertion_check(target)) return target.forceMove(src) patient = target START_PROCESSING(SSobj, src) update_equip_info() occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") chassis.visible_message("[chassis] loads [target] into [src].") log_message("[target] loaded. Life support functions engaged.") /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target) if(target.buckled) occupant_message("[target] will not fit into the sleeper because [target.p_they()] [target.p_are()] buckled to [target.buckled]!") return if(target.has_buckled_mobs()) occupant_message("[target] will not fit into the sleeper because of the creatures attached to it!") return if(patient) occupant_message("The sleeper is already occupied!") return return 1 /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out() if(!patient) return patient.forceMove(get_turf(src)) occupant_message("[patient] ejected. Life support functions disabled.") log_message("[patient] ejected. Life support functions disabled.") STOP_PROCESSING(SSobj, src) patient = null update_equip_info() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach() if(patient) occupant_message("Unable to detach [src] - equipment occupied!") return STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/get_equip_info() var/output = ..() if(output) var/temp = "" if(patient) temp = "
\[Occupant: [patient] ([patient.stat > 1 ? "*DECEASED*" : "Health: [patient.health]%"])\]
View stats|Eject" return "[output] [temp]" return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list) ..() var/datum/topic_input/filter = new /datum/topic_input(href,href_list) if(filter.get("eject")) go_out() if(filter.get("view_stats")) chassis.occupant << browse(get_patient_stats(),"window=msleeper") onclose(chassis.occupant, "msleeper") return if(filter.get("inject")) inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source")) return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats() if(!patient) return return {" [patient] statistics

Health statistics

[get_patient_dam()]

Reagents in bloodstream

[get_patient_reagents()]
[get_available_reagents()]
"} /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_dam() var/t1 switch(patient.stat) if(0) t1 = "Conscious" if(1) t1 = "Unconscious" if(2) t1 = "*dead*" else t1 = "Unknown" return {"Health: [patient.stat > 1 ? "[t1]" : "[patient.health]% ([t1])"]
Core Temperature: [patient.bodytemperature-T0C]°C ([patient.bodytemperature*1.8-459.67]°F)
Brute Damage: [patient.getBruteLoss()]%
Respiratory Damage: [patient.getOxyLoss()]%
Toxin Content: [patient.getToxLoss()]%
Burn Severity: [patient.getFireLoss()]%
[patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]
[patient.getBrainLoss() ? "Significant brain damage detected." : ""]
"} /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_reagents() if(patient.reagents) for(var/datum/reagent/R in patient.reagents.reagent_list) if(R.volume > 0) . += "[R]: [round(R.volume,0.01)]
" return . || "None" /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_available_reagents() var/output var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun) in chassis if(SG && SG.reagents && islist(SG.reagents.reagent_list)) for(var/datum/reagent/R in SG.reagents.reagent_list) if(R.volume > 0) output += "Inject [R.name]
" return output /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/inject_reagent(datum/reagent/R,obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG) if(!R || !patient || !SG || !(SG in chassis.equipment)) return 0 var/to_inject = min(R.volume, inject_amount) if(to_inject && patient.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2) occupant_message("Injecting [patient] with [to_inject] units of [R.name].") log_message("Injecting [patient] with [to_inject] units of [R.name].") add_logs(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)") SG.reagents.trans_id_to(patient,R.id,to_inject) update_equip_info() return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info() if(..()) if(patient) send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam()) send_byjax(chassis.occupant,"msleeper.browser","reagents",get_patient_reagents()) send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) return 1 return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist(mob/living/user) go_out() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/process() if(..()) return if(!chassis.has_charge(energy_drain)) set_ready_state(1) log_message("Deactivated.") occupant_message("[src] deactivated - no power.") STOP_PROCESSING(SSobj, src) return var/mob/living/carbon/M = patient if(!M) return if(M.health > 0) M.adjustOxyLoss(-1) M.updatehealth() M.AdjustStunned(-4) M.AdjustWeakened(-4) M.AdjustStunned(-4) if(M.reagents.get_reagent_amount("epinephrine") < 5) M.reagents.add_reagent("epinephrine", 5) chassis.use_power(energy_drain) update_equip_info() ///////////////////////////////// Syringe Gun /////////////////////////////////////////////////////////////// /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun name = "exosuit syringe gun" desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." icon = 'icons/obj/guns/projectile.dmi' icon_state = "syringegun" var/list/syringes var/list/known_reagents var/list/processed_reagents var/max_syringes = 10 var/max_volume = 75 //max reagent volume var/synth_speed = 5 //[num] reagent units per cycle energy_drain = 10 var/mode = 0 //0 - fire syringe, 1 - analyze reagents. range = MELEE|RANGED equip_cooldown = 10 origin_tech = "materials=3;biotech=4;magnets=4" /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New() ..() create_reagents(max_volume) reagents.set_reacting(FALSE) syringes = new known_reagents = list("epinephrine"="Epinephrine","charcoal"="Charcoal") processed_reagents = new /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach() STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Destroy() STOP_PROCESSING(SSobj, src) return ..() /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() ..() if(reagents) reagents.set_reacting(TRUE) /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) if(..()) if(istype(M)) return 1 return 0 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info() var/output = ..() if(output) return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target) if(!action_checks(target)) return if(istype(target,/obj/item/weapon/reagent_containers/syringe)) return load_syringe(target) if(istype(target,/obj/item/weapon/storage))//Loads syringes from boxes for(var/obj/item/weapon/reagent_containers/syringe/S in target.contents) load_syringe(S) return if(mode) return analyze_reagents(target) if(!syringes.len) occupant_message("No syringes loaded.") return if(reagents.total_volume<=0) occupant_message("No available reagents to load syringe with.") return var/turf/trg = get_turf(target) var/obj/item/weapon/reagent_containers/syringe/mechsyringe = syringes[1] mechsyringe.forceMove(get_turf(chassis)) reagents.trans_to(mechsyringe, min(mechsyringe.volume, reagents.total_volume)) syringes -= mechsyringe mechsyringe.icon = 'icons/obj/chemical.dmi' mechsyringe.icon_state = "syringeproj" playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) log_message("Launched [mechsyringe] from [src], targeting [target].") var/mob/originaloccupant = chassis.occupant spawn(0) src = null //if src is deleted, still process the syringe for(var/i=0, i<6, i++) if(!mechsyringe) break if(step_towards(mechsyringe,trg)) var/list/mobs = new for(var/mob/living/carbon/M in mechsyringe.loc) mobs += M var/mob/living/carbon/M = safepick(mobs) if(M) var/R mechsyringe.visible_message(" [M] was hit by the syringe!") if(M.can_inject(null, 1)) if(mechsyringe.reagents) for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) R += A.id + " (" R += num2text(A.volume) + ")," mechsyringe.icon_state = initial(mechsyringe.icon_state) mechsyringe.icon = initial(mechsyringe.icon) mechsyringe.reagents.reaction(M, INJECT) mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) M.take_bodypart_damage(2) add_logs(originaloccupant, M, "shot", "syringegun") break else if(mechsyringe.loc == trg) mechsyringe.icon_state = initial(mechsyringe.icon_state) mechsyringe.icon = initial(mechsyringe.icon) mechsyringe.update_icon() break else mechsyringe.icon_state = initial(mechsyringe.icon_state) mechsyringe.icon = initial(mechsyringe.icon) mechsyringe.update_icon() break sleep(1) return 1 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list) ..() var/datum/topic_input/filter = new (href,href_list) if(filter.get("toggle_mode")) mode = !mode update_equip_info() return if(filter.get("select_reagents")) processed_reagents.len = 0 var/m = 0 var/message for(var/i=1 to known_reagents.len) if(m>=synth_speed) break var/reagent = filter.get("reagent_[i]") if(reagent && (reagent in known_reagents)) message = "[m ? ", " : null][known_reagents[reagent]]" processed_reagents += reagent m++ if(processed_reagents.len) message += " added to production" START_PROCESSING(SSobj, src) occupant_message(message) occupant_message("Reagent processing started.") log_message("Reagent processing started.") return if(filter.get("show_reagents")) chassis.occupant << browse(get_reagents_page(),"window=msyringegun") if(filter.get("purge_reagent")) var/reagent = filter.get("purge_reagent") if(reagent) reagents.del_reagent(reagent) return if(filter.get("purge_all")) reagents.clear_reagents() return return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_page() var/output = {" Reagent Synthesizer

Current reagents:

[get_current_reagents()]

Reagents production:

[get_reagents_form()]
"} return output /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_form() var/r_list = get_reagents_list() var/inputs if(r_list) inputs += "" inputs += "" inputs += "" var/output = {"
[r_list || "No known reagents"] [inputs]
[r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null] "} return output /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_list() var/output for(var/i=1 to known_reagents.len) var/reagent_id = known_reagents[i] output += {" [known_reagents[reagent_id]]
"} return output /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_current_reagents() var/output for(var/datum/reagent/R in reagents.reagent_list) if(R.volume > 0) output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" if(output) output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" return output || "None" /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) if(syringes.len= 2) occupant_message("The syringe is too far away.") return 0 for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) if(!(D.CanPass(S,src.loc))) occupant_message("Unable to load syringe.") return 0 for(var/obj/machinery/door/D in S.loc)//Checks for doors if(!(D.CanPass(S,src.loc))) occupant_message("Unable to load syringe.") return 0 S.reagents.trans_to(src, S.reagents.total_volume) S.forceMove(src) syringes += S occupant_message("Syringe loaded.") update_equip_info() return 1 occupant_message("The [src] syringe chamber is full.") return 0 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A) if(get_dist(src,A) >= 4) occupant_message("The object is too far away.") return 0 if(!A.reagents || istype(A,/mob)) occupant_message("No reagent info gained from [A].") return 0 occupant_message("Analyzing reagents...") for(var/datum/reagent/R in A.reagents.reagent_list) if(R.can_synth && add_known_reagent(R.id,R.name)) occupant_message("Reagent analyzed, identified as [R.name] and added to database.") send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) occupant_message("Analyzis complete.") return 1 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name) if(!(r_id in known_reagents)) known_reagents += r_id known_reagents[r_id] = r_name return 1 return 0 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info() if(..()) send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) return 1 return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change() ..() update_equip_info() return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process() if(..()) return if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain)) occupant_message("Reagent processing stopped.") log_message("Reagent processing stopped.") STOP_PROCESSING(SSobj, src) return var/amount = synth_speed / processed_reagents.len for(var/reagent in processed_reagents) reagents.add_reagent(reagent,amount) chassis.use_power(energy_drain) ///////////////////////////////// Medical Beam /////////////////////////////////////////////////////////////// /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam name = "exosuit medical beamgun" desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites." icon_state = "mecha_medigun" energy_drain = 10 range = MELEE|RANGED equip_cooldown = 0 origin_tech = "combat=5;materials=6;powerstorage=7;biotech=6" var/obj/item/weapon/gun/medbeam/mech/medigun materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/New() ..() medigun = new(src) /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Destroy() qdel(medigun) return ..() /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/process() if(..()) return medigun.process() /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target) medigun.process_fire(target, loc) /obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach() STOP_PROCESSING(SSobj, src) medigun.LoseTarget() return ..()