diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 86b875b0fce..721851ffaf3 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -6,6 +6,7 @@
#define CHEM_TOUCH 1
#define CHEM_INGEST 2
#define CHEM_INJECT 3
+#define CHEM_INHALE 4
#define MINIMUM_CHEMICAL_VOLUME 0.01
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index 0aeab28bf68..1312d297ad6 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -106,6 +106,7 @@
/obj/item/clothing/shoes/color/white,
/obj/item/clothing/gloves/latex,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight/pen,
/obj/item/chems/syringe)
containertype = /obj/structure/closet/crate/secure
@@ -125,6 +126,7 @@
/obj/item/clothing/shoes/color/white,
/obj/item/clothing/gloves/latex,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight/pen,
/obj/item/chems/syringe)
containertype = /obj/structure/closet/crate/secure
@@ -144,6 +146,7 @@
/obj/item/clothing/gloves/latex,
/obj/item/chems/dropper,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/storage/box/pillbottles,
/obj/item/chems/syringe)
containertype = /obj/structure/closet/crate/secure
@@ -167,6 +170,7 @@
/obj/item/clothing/shoes/jackboots,
/obj/item/clothing/gloves/latex,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight/pen,
/obj/item/chems/syringe,
/obj/item/clothing/accessory/storage/vest)
diff --git a/code/datums/trading/traders/goods.dm b/code/datums/trading/traders/goods.dm
index 19a8d5d05f5..95131be8f22 100644
--- a/code/datums/trading/traders/goods.dm
+++ b/code/datums/trading/traders/goods.dm
@@ -194,6 +194,7 @@ Sells devices, odds and ends, and medical stuff
/obj/item/megaphone = TRADER_THIS_TYPE,
/obj/item/paicard = TRADER_THIS_TYPE,
/obj/item/scanner/health = TRADER_THIS_TYPE,
+ /obj/item/scanner/breath = TRADER_THIS_TYPE,
/obj/item/scanner/gas = TRADER_ALL,
/obj/item/scanner/spectrometer = TRADER_ALL,
/obj/item/scanner/reagent = TRADER_ALL,
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index b7c3f581f02..76e01d982e5 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -19,6 +19,7 @@
var/obj/item/chems/glass/beaker = null
var/filtering = 0
var/pump
+ var/lavage = FALSE // Are we rinsing reagents from the lungs?
var/list/stasis_settings = list(1, 2, 5, 10)
var/stasis = 1
var/pump_speed
@@ -123,6 +124,16 @@
ingested.trans_to_obj(beaker, pump_speed * trans_amt)
else
toggle_pump()
+ if(lavage > 0)
+ if (beaker)
+ if (beaker.reagents.total_volume < beaker.reagents.maximum_volume)
+ var/datum/reagents/inhaled = occupant.get_inhaled_reagents()
+ var/trans_volume = LAZYLEN(inhaled?.reagent_volumes)
+ if(inhaled && trans_volume)
+ inhaled.trans_to_obj(beaker, pump_speed * trans_volume)
+ else
+ toggle_lavage()
+
if(iscarbon(occupant) && stasis > 1)
occupant.SetStasis(stasis)
@@ -189,6 +200,7 @@
data["beaker"] = -1
data["filtering"] = filtering
data["pump"] = pump
+ data["lavage"] = lavage
data["stasis"] = stasis
data["skill_check"] = user.skill_check(SKILL_MEDICAL, SKILL_BASIC)
ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -225,6 +237,10 @@
if(filtering != text2num(href_list["pump"]))
toggle_pump()
return TOPIC_REFRESH
+ if(href_list["lavage"])
+ if(lavage != text2num(href_list["lavage"]))
+ toggle_lavage()
+ return TOPIC_REFRESH
if(href_list["chemical"])
var/obj/canister = locate(href_list["chemical"])
if(istype(canister))
@@ -305,6 +321,16 @@
to_chat(occupant, SPAN_WARNING("You feel a tube jammed down your throat."))
pump = !pump
+/obj/machinery/sleeper/proc/toggle_lavage()
+ if(!occupant || !beaker)
+ lavage = 0
+ return
+ lavage = !lavage
+ if (lavage)
+ to_chat(occupant, SPAN_WARNING("You feel a tube jammed down your throat."))
+ else
+ to_chat(occupant, SPAN_NOTICE("You feel a tube retract from your throat."))
+
/obj/machinery/sleeper/proc/go_in(var/mob/M, var/mob/user)
if(!M || M.anchored)
return
@@ -364,6 +390,7 @@
beaker = null
toggle_filter()
toggle_pump()
+ toggle_lavage()
/obj/machinery/sleeper/proc/inject_chemical(var/mob/living/user, var/obj/canister, var/amount, var/target_transfer_type = CHEM_INJECT)
if(stat & (BROKEN|NOPOWER))
diff --git a/code/game/machinery/vending/medical.dm b/code/game/machinery/vending/medical.dm
index 7b278bad927..e1e2c3afafa 100644
--- a/code/game/machinery/vending/medical.dm
+++ b/code/game/machinery/vending/medical.dm
@@ -18,10 +18,11 @@
/obj/item/chems/syringe/antibiotic = 4,
/obj/item/chems/syringe = 12,
/obj/item/scanner/health = 5,
- /obj/item/chems/glass/beaker = 4,
+ /obj/item/scanner/breath = 5,
+ /obj/item/chems/glass/beaker = 4,
/obj/item/chems/dropper = 2,
- /obj/item/stack/medical/advanced/bruise_pack = 3,
- /obj/item/stack/medical/advanced/ointment = 3,
+ /obj/item/stack/medical/advanced/bruise_pack = 3,
+ /obj/item/stack/medical/advanced/ointment = 3,
/obj/item/stack/medical/splint = 2,
/obj/item/chems/hypospray/autoinjector/pain = 4
)
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 1f01b9fd1f0..b48e787dba5 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -236,7 +236,7 @@ steam.start() -- spawns the effect
M.adjustOxyLoss(1)
if (M.coughedtime != 1)
M.coughedtime = 1
- M.emote("cough")
+ M.cough()
spawn ( 20 )
M.coughedtime = 0
@@ -265,7 +265,7 @@ steam.start() -- spawns the effect
ADJ_STATUS(M, STAT_ASLEEP, 1)
if (M.coughedtime != 1)
M.coughedtime = 1
- M.emote("cough")
+ M.cough()
spawn ( 20 )
M.coughedtime = 0
/////////////////////////////////////////////
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 9aa97fac7e2..63ce53768a3 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -149,9 +149,9 @@
var/list/pinpoint = list(/decl/material/liquid/painkillers=5,/decl/material/liquid/amphetamines=1)
var/list/dilating = list(/decl/material/liquid/psychoactives=5,/decl/material/liquid/hallucinogenics=1,/decl/material/liquid/adrenaline=1)
var/datum/reagents/ingested = H.get_ingested_reagents()
- if(H.reagents.has_any_reagent(pinpoint) || ingested.has_any_reagent(pinpoint))
+ if(H.reagents.has_any_reagent(pinpoint) || ingested?.has_any_reagent(pinpoint))
to_chat(user, "\The [H]'s pupils are already pinpoint and cannot narrow any more.")
- else if(H.shock_stage >= 30 || H.reagents.has_any_reagent(dilating) || ingested.has_any_reagent(dilating))
+ else if(H.shock_stage >= 30 || H.reagents.has_any_reagent(dilating) || ingested?.has_any_reagent(dilating))
to_chat(user, "\The [H]'s pupils narrow slightly, but are still very dilated.")
else
to_chat(user, "\The [H]'s pupils narrow.")
diff --git a/code/game/objects/items/devices/scanners/breath.dm b/code/game/objects/items/devices/scanners/breath.dm
new file mode 100644
index 00000000000..2b201add809
--- /dev/null
+++ b/code/game/objects/items/devices/scanners/breath.dm
@@ -0,0 +1,118 @@
+/obj/item/scanner/breath
+ name = "breath analyzer"
+ desc = "A two-in-one breathalyzer and respirometer, measuring intoxication, breath contents, and respiratory health."
+ icon = 'icons/obj/items/device/scanner/breath_scanner.dmi'
+ icon_state = "breath_analyzer"
+ item_state = "analyzer"
+ item_flags = ITEM_FLAG_NO_BLUDGEON
+ material = /decl/material/solid/metal/aluminium
+ origin_tech = "{'biotech':1}"
+ printout_color = "#deebff"
+ var/mode = 1
+
+/obj/item/scanner/breath/is_valid_scan_target(atom/O)
+ return istype(O, /mob/living/carbon)
+
+/obj/item/scanner/breath/scan(atom/A, mob/user)
+ scan_data = breath_scan_action(A, user, src, mode)
+ playsound(src, 'sound/effects/fastbeep.ogg', 20)
+
+/proc/breath_scan_action(mob/living/carbon/target, mob/living/user, obj/scanner, var/verbose)
+ if (!user.check_dexterity(DEXTERITY_COMPLEX_TOOLS) || !istype(target))
+ return
+
+ . = breath_scan_results(target, verbose, user.get_skill_value(SKILL_MEDICAL))
+ to_chat(user, "
")
+ to_chat(user, .)
+ to_chat(user, "
")
+
+/proc/breath_scan_results(var/mob/living/carbon/C, var/verbose, var/skill_level = SKILL_DEFAULT)
+ . = list()
+ var/header = list()
+ var/b
+ var/endb
+ var/dat = list()
+
+ if(skill_level >= SKILL_BASIC)
+ header += ""
+ header += ""
+ header += ""
+ header += ""
+ header += ""
+ header += ""
+ header += ""
+ b = ""
+ endb = ""
+
+ . += "[b]Breath sample results for \the [C]:[endb]"
+
+ var/obj/item/organ/internal/lungs/lungs = C.get_organ(BP_LUNGS)
+ var/breathing = "none"
+ if(istype(lungs) && !(C.status_flags & FAKEDEATH))
+ if(lungs.breath_fail_ratio < 0.3)
+ breathing = "normal"
+ else if(lungs.breath_fail_ratio < 1)
+ breathing = "shallow"
+
+ switch(breathing)
+ if("none")
+ . += "Alert: No breathing detected."
+ return
+ if("shallow")
+ . += "Subject's breathing is abnormally shallow."
+ if("normal")
+ . += "Subject's breathing is normal."
+
+ // Other general warnings.
+ if(skill_level >= SKILL_BASIC)
+ switch(C.getOxyLoss())
+ if(0 to 25)
+ dat += "Subject oxygen levels nominal."
+ if(25 to 50)
+ dat += "Subject oxygen levels abnormal."
+ if(50 to INFINITY)
+ dat += "[b]Severe oxygen deprivation detected.[endb]"
+
+ if(istype(lungs))
+ if(lungs.is_broken())
+ dat += "[b]Tension pneumothorax detected.[endb]"
+ else if(lungs.is_bruised())
+ dat += "Collapsed lung detected."
+ else
+ dat += "Subject lung health nominal."
+ else
+ dat += "Subject lung health unknown."
+
+ . += (skill_level < SKILL_BASIC) ? shuffle(dat) : dat
+
+ // Reagent data.
+ . += "[b]Reagent scan:[endb]"
+
+ var/print_reagent_default_message = TRUE
+ if (C.has_chemical_effect(CE_ALCOHOL))
+ . += "Alcohol detected in subject's breath."
+ print_reagent_default_message = FALSE
+ if (C.has_chemical_effect(CE_ALCOHOL_TOXIC))
+ . += "Subject is suffering from alcohol poisoning."
+ print_reagent_default_message = FALSE
+
+ var/datum/reagents/inhaled = C.get_inhaled_reagents()
+ if(inhaled && inhaled.total_volume)
+ var/unknown = 0
+ for(var/rtype in inhaled.reagent_volumes)
+ var/decl/material/R = GET_DECL(rtype)
+ if(R.scannable)
+ print_reagent_default_message = FALSE
+ . += "[R.name] found in subject's breath."
+ else
+ ++unknown
+ if(unknown)
+ print_reagent_default_message = FALSE
+ . += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's breath."
+
+ if(print_reagent_default_message)
+ . += "No results."
+
+ header = jointext(header, null)
+ . = jointext(.,"
")
+ . = jointext(list(header,.),null)
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners/health.dm b/code/game/objects/items/devices/scanners/health.dm
index 8837a258951..7c151143881 100644
--- a/code/game/objects/items/devices/scanners/health.dm
+++ b/code/game/objects/items/devices/scanners/health.dm
@@ -296,6 +296,20 @@
print_reagent_default_message = FALSE
. += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach."
+ var/datum/reagents/inhaled = H.get_inhaled_reagents()
+ if(inhaled && inhaled.total_volume)
+ var/unknown = 0
+ for(var/rtype in inhaled.reagent_volumes)
+ var/decl/material/R = GET_DECL(rtype)
+ if(R.scannable)
+ print_reagent_default_message = FALSE
+ . += "[R.name] found in subject's lungs."
+ else
+ ++unknown
+ if(unknown)
+ print_reagent_default_message = FALSE
+ . += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's lungs."
+
if(length(H.chem_doses))
var/list/chemtraces = list()
for(var/T in H.chem_doses)
diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm
index 084e04365a1..6376f551264 100644
--- a/code/game/objects/items/weapons/ecigs.dm
+++ b/code/game/objects/items/weapons/ecigs.dm
@@ -115,7 +115,7 @@
Deactivate()
to_chat(C,"\The [src]'s power meter flashes a low battery warning and shuts down.")
return
- ec_cartridge.reagents.trans_to_mob(C, REM, CHEM_INGEST, 0.4) // Most of it is not inhaled... balance reasons.
+ ec_cartridge.reagents.trans_to_mob(C, REM, CHEM_INHALE, 0.4) // Most of it is not inhaled... balance reasons.
/obj/item/clothing/mask/smokable/ecig/on_update_icon()
..()
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 7b1daf03593..3d9cc02ad7a 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -152,6 +152,7 @@
icon = 'icons/clothing/belt/medical.dmi'
can_hold = list(
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/chems/dropper,
/obj/item/chems/glass/beaker,
/obj/item/chems/glass/bottle,
@@ -166,6 +167,7 @@
/obj/item/clothing/head/surgery,
/obj/item/clothing/gloves/latex,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/clothing/glasses/hud/health,
/obj/item/crowbar,
/obj/item/flashlight,
diff --git a/code/game/objects/items/weapons/storage/med_pouch.dm b/code/game/objects/items/weapons/storage/med_pouch.dm
index fd48e10d392..2e96d802dc7 100644
--- a/code/game/objects/items/weapons/storage/med_pouch.dm
+++ b/code/game/objects/items/weapons/storage/med_pouch.dm
@@ -33,6 +33,9 @@ Single Use Emergency Pouches
for(var/obj/item/chems/hypospray/autoinjector/A in contents)
A.band_color = color
A.update_icon()
+ for(var/obj/item/chems/inhaler/I in contents)
+ I.band_color = color
+ I.update_icon()
/obj/item/storage/med_pouch/on_update_icon()
overlays.Cut()
@@ -113,7 +116,7 @@ Single Use Emergency Pouches
startswith = list(
/obj/item/chems/hypospray/autoinjector/pouch_auto/stabilizer,
- /obj/item/chems/hypospray/autoinjector/pouch_auto/oxy_meds,
+ /obj/item/chems/inhaler/pouch_auto/oxy_meds,
/obj/item/chems/hypospray/autoinjector/pouch_auto/adrenaline,
/obj/item/chems/pill/pouch_pill/stabilizer,
/obj/item/chems/pill/pouch_pill/oxy_meds
@@ -165,9 +168,32 @@ Single Use Emergency Pouches
6) Stay in place once they respond.\
"}
+/obj/item/storage/med_pouch/overdose
+ name = "overdose treatment pouch"
+ injury_type = "overdose"
+ color = COLOR_PALE_BLUE_GRAY
+
+ startswith = list(
+ /obj/item/chems/hypospray/autoinjector/pouch_auto/stabilizer,
+ /obj/item/chems/inhaler/pouch_auto/oxy_meds,
+ /obj/item/chems/inhaler/pouch_auto/detoxifier,
+ /obj/item/chems/hypospray/autoinjector/pouch_auto/adrenaline
+ )
+ instructions = {"
+ 1) Tear open the emergency medical pack using the easy open tab at the top.\n\
+ \t2) Carefully remove all items from the pouch and discard the pouch.\n\
+ \t3) Apply all autoinjectors and autoinhalers to the injured party. DO NOT give the injured party any pills, foods, or liquids.\n\
+ \t5) Contact the medical team with your location.\n\
+ \t6) Find a source of oxygen if possible.\n\
+ \t7) Update the medical team with your new location.\n\
+ 8) Stay in place once they respond.\
+ "}
+
+// Pills
+
/obj/item/chems/pill/pouch_pill
name = "emergency pill"
- desc = "An emergency pill from an emergency medical pouch"
+ desc = "An emergency pill from an emergency medical pouch."
icon_state = "pill2"
var/decl/material/chem_type
var/chem_amount = 15
@@ -195,9 +221,11 @@ Single Use Emergency Pouches
var/decl/material/reagent = GET_DECL(chem_type)
SetName("emergency [reagent.liquid_name] pill ([reagents.total_volume]u)")
+// Injectors
+
/obj/item/chems/hypospray/autoinjector/pouch_auto
name = "emergency autoinjector"
- desc = "An emergency autoinjector from an emergency medical pouch"
+ desc = "An emergency autoinjector from an emergency medical pouch."
/obj/item/chems/hypospray/autoinjector/pouch_auto/stabilizer
name = "emergency stabilizer autoinjector"
@@ -223,3 +251,17 @@ Single Use Emergency Pouches
/obj/item/chems/hypospray/autoinjector/pouch_auto/nanoblood
name = "emergency nanoblood autoinjector"
starts_with = list(/decl/material/liquid/nanoblood = 5)
+
+// Inhalers
+
+/obj/item/chems/inhaler/pouch_auto
+ name = "emergency autoinhaler"
+ desc = "An emergency autoinhaler from an emergency medical pouch."
+
+/obj/item/chems/inhaler/pouch_auto/oxy_meds
+ name = "emergency oxygel autoinjector"
+ starts_with = list(/decl/material/liquid/oxy_meds = 5)
+
+/obj/item/chems/inhaler/pouch_auto/detoxifier
+ name = "emergency detoxifier autoinjector"
+ starts_with = list(/decl/material/liquid/detoxifier = 5)
diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm
index 67eb6906c95..c6f4e8812d8 100644
--- a/code/game/objects/random/random.dm
+++ b/code/game/objects/random/random.dm
@@ -172,13 +172,15 @@
/obj/item/stack/medical/advanced/ointment = 2,
/obj/item/stack/medical/splint = 1,
/obj/item/chems/hypospray/autoinjector = 3,
+ /obj/item/chems/inhaler = 3,
/obj/item/storage/pill_bottle/burn_meds = 2,
/obj/item/storage/pill_bottle/antitox = 2,
/obj/item/storage/med_pouch/trauma = 2,
/obj/item/storage/med_pouch/burn = 2,
/obj/item/storage/med_pouch/toxin = 2,
/obj/item/storage/med_pouch/radiation = 2,
- /obj/item/storage/med_pouch/oxyloss = 2)
+ /obj/item/storage/med_pouch/oxyloss = 2,
+ /obj/item/storage/med_pouch/overdose = 2)
/obj/random/firstaid
name = "Random First Aid Kit"
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index 2ec2efb2655..9818876085b 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -75,6 +75,7 @@
/obj/item/tank/emergency/oxygen/engi,
/obj/item/clothing/glasses/hud/health,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/radio/off,
/obj/random/medical,
/obj/item/crowbar,
@@ -127,7 +128,7 @@
wall_mounted = 1
storage_types = CLOSET_STORAGE_ITEMS
req_access = list(access_medical_equip)
-
+
/obj/structure/closet/secure_closet/medical_wall/Initialize()
. = ..()
tool_interaction_flags &= ~TOOL_INTERACTION_ANCHOR
@@ -179,6 +180,7 @@
/obj/item/clothing/suit/storage/toggle/labcoat/virologist,
/obj/item/clothing/mask/surgical,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/clothing/glasses/hud/health
)
diff --git a/code/game/objects/structures/crates_lockers/med_crate.dm b/code/game/objects/structures/crates_lockers/med_crate.dm
index 1012321c1e3..02f9a8fe2c4 100644
--- a/code/game/objects/structures/crates_lockers/med_crate.dm
+++ b/code/game/objects/structures/crates_lockers/med_crate.dm
@@ -33,7 +33,7 @@
/obj/structure/closet/crate/med_crate/oxyloss/WillContain()
return list(
- /obj/item/scanner/health = 2,
+ /obj/item/scanner/breath = 2,
/obj/item/storage/pill_bottle/oxygen = 2,
/obj/item/storage/pill_bottle/adrenaline
)
diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm
index 252abdb5ed8..5dbac1dda59 100644
--- a/code/modules/clothing/masks/smokable.dm
+++ b/code/modules/clothing/masks/smokable.dm
@@ -57,7 +57,7 @@
var/mob/living/carbon/human/C = loc
smoke_loc = C.loc
if ((src == C.wear_mask || manual) && C.check_has_mouth()) // if it's in the human/monkey mouth, transfer reagents to the mob
- reagents.trans_to_mob(C, smoke_amount * amount, CHEM_INGEST, 0.2)
+ reagents.trans_to_mob(C, smoke_amount * amount, CHEM_INHALE, 0.2)
add_trace_DNA(C)
else // else just remove some of the reagents
reagents.remove_any(smoke_amount * amount)
diff --git a/code/modules/clothing/spacesuits/rig/suits/combat.dm b/code/modules/clothing/spacesuits/rig/suits/combat.dm
index b2a5bf12b5a..5b34663debc 100644
--- a/code/modules/clothing/spacesuits/rig/suits/combat.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/combat.dm
@@ -36,6 +36,7 @@
/obj/item/gun,
/obj/item/storage/firstaid,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/roller,
/obj/item/suit_cooling_unit
)
@@ -108,6 +109,7 @@
/obj/item/gun,
/obj/item/storage/firstaid,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/roller,
/obj/item/suit_cooling_unit
)
diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm
index 696efd244fc..830be840623 100644
--- a/code/modules/clothing/spacesuits/rig/suits/station.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/station.dm
@@ -206,7 +206,7 @@
boots = /obj/item/clothing/shoes/magboots/rig/hazmat
gloves = /obj/item/clothing/gloves/rig/hazmat
- allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/stack/flag,/obj/item/storage/excavation,/obj/item/pickaxe,/obj/item/scanner/health,/obj/item/measuring_tape,/obj/item/ano_scanner,/obj/item/depth_scanner,/obj/item/core_sampler,/obj/item/gps,/obj/item/pinpointer/radio,/obj/item/radio/beacon,/obj/item/pickaxe/xeno,/obj/item/storage/bag/fossils)
+ allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/stack/flag,/obj/item/storage/excavation,/obj/item/pickaxe,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/measuring_tape,/obj/item/ano_scanner,/obj/item/depth_scanner,/obj/item/core_sampler,/obj/item/gps,/obj/item/pinpointer/radio,/obj/item/radio/beacon,/obj/item/pickaxe/xeno,/obj/item/storage/bag/fossils)
anomaly_shielding = 1
req_access = list(access_tox)
@@ -252,7 +252,7 @@
boots = /obj/item/clothing/shoes/magboots/rig/medical
gloves = /obj/item/clothing/gloves/rig/medical
- allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/stack/medical,/obj/item/roller,/obj/item/auto_cpr,/obj/item/inflatable_dispenser)
+ allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/stack/medical,/obj/item/roller,/obj/item/auto_cpr,/obj/item/inflatable_dispenser)
req_access = list(access_medical_equip)
diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm
index 99d7fd41fe7..c9c4df89264 100644
--- a/code/modules/clothing/spacesuits/void/station.dm
+++ b/code/modules/clothing/spacesuits/void/station.dm
@@ -90,7 +90,7 @@
name = "medical voidsuit"
desc = "A sterile voidsuit with minor radiation shielding and a suite of self-cleaning technology. Standard issue in most orbital medical facilities."
icon = 'icons/clothing/spacesuit/void/medical/suit.dmi'
- allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/stack/medical)
+ allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/stack/medical)
armor = list(
melee = ARMOR_MELEE_KNIVES,
laser = ARMOR_LASER_MINOR,
@@ -265,7 +265,7 @@
name = "streamlined medical voidsuit"
desc = "A more recent and stylish model of Vey-Med voidsuit, with a minor upgrade to radiation shielding."
icon = 'icons/clothing/spacesuit/void/medical_alt/suit.dmi'
- allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/stack/medical)
+ allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/storage/firstaid,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/stack/medical)
armor = list(
melee = ARMOR_MELEE_KNIVES,
laser = ARMOR_LASER_MINOR,
diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm
index 7674b586f4b..c81e6de31c2 100644
--- a/code/modules/clothing/suits/bio.dm
+++ b/code/modules/clothing/suits/bio.dm
@@ -5,7 +5,7 @@
desc = "A hood that protects the head and face from biological comtaminants."
permeability_coefficient = 0
armor = list(
- bio = ARMOR_BIO_SHIELDED,
+ bio = ARMOR_BIO_SHIELDED,
rad = ARMOR_RAD_MINOR
)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|BLOCKHAIR
@@ -26,9 +26,9 @@
gas_transfer_coefficient = 0
permeability_coefficient = 0
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS|SLOT_HANDS
- allowed = list(/obj/item/tank/emergency,/obj/item/pen,/obj/item/flashlight/pen,/obj/item/scanner/health,/obj/item/ano_scanner,/obj/item/clothing/head/bio_hood,/obj/item/clothing/mask/gas)
+ allowed = list(/obj/item/tank/emergency,/obj/item/pen,/obj/item/flashlight/pen,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/ano_scanner,/obj/item/clothing/head/bio_hood,/obj/item/clothing/mask/gas)
armor = list(
- bio = ARMOR_BIO_SHIELDED,
+ bio = ARMOR_BIO_SHIELDED,
rad = ARMOR_RAD_MINOR
)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index 5bff1d39d43..80e0f40e62b 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -172,8 +172,10 @@
/obj/item/stack/medical,
/obj/item/chems/dropper,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/chems/syringe,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight,
/obj/item/radio,
/obj/item/tank/emergency,
@@ -195,8 +197,10 @@
/obj/item/stack/medical,
/obj/item/chems/dropper,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/chems/syringe,
- /obj/item/scanner/health,
+ /obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight,
/obj/item/radio,
/obj/item/tank/emergency,
@@ -215,8 +219,10 @@
/obj/item/stack/medical,
/obj/item/chems/dropper,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/chems/syringe,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/flashlight,
/obj/item/radio,
/obj/item/tank/emergency,
diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm
index d7b0bca94c3..6467b1f587d 100644
--- a/code/modules/clothing/suits/labcoat.dm
+++ b/code/modules/clothing/suits/labcoat.dm
@@ -4,7 +4,21 @@
icon = 'icons/clothing/suit/labcoat/default.dmi'
blood_overlay_type = "coat"
body_parts_covered = SLOT_UPPER_BODY|SLOT_ARMS
- allowed = list(/obj/item/scanner/gas,/obj/item/stack/medical,/obj/item/chems/dropper,/obj/item/chems/syringe,/obj/item/chems/hypospray,/obj/item/scanner/health,/obj/item/flashlight/pen,/obj/item/chems/glass/bottle,/obj/item/chems/glass/beaker,/obj/item/chems/pill,/obj/item/storage/pill_bottle,/obj/item/paper)
+ allowed = list(
+ /obj/item/scanner/gas,
+ /obj/item/stack/medical,
+ /obj/item/chems/dropper,
+ /obj/item/chems/syringe,
+ /obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
+ /obj/item/scanner/health,
+ /obj/item/scanner/breath,
+ /obj/item/flashlight/pen,
+ /obj/item/chems/glass/bottle,
+ /obj/item/chems/glass/beaker,
+ /obj/item/chems/pill,
+ /obj/item/storage/pill_bottle,
+ /obj/item/paper)
armor = list(
bio = ARMOR_BIO_RESISTANT
)
@@ -60,4 +74,3 @@
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_ARMS
markings_color = COLOR_BOTTLE_GREEN
markings_icon = "_marking"
-
\ No newline at end of file
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index ba568a06069..874c943ca23 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -19,7 +19,7 @@
body_parts_covered = SLOT_UPPER_BODY | SLOT_LOWER_BODY| SLOT_ARMS
armor = list(laser = ARMOR_LASER_MINOR, energy = ARMOR_ENERGY_MINOR, bomb = ARMOR_BOMB_MINOR)
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency,/obj/item/extinguisher,/obj/item/clothing/head/hardhat)
-
+
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
@@ -45,10 +45,10 @@
desc = "Use in case of bomb."
icon = 'icons/clothing/head/bombsuit.dmi'
armor = list(
- melee = ARMOR_MELEE_VERY_HIGH,
- bullet = ARMOR_BALLISTIC_MINOR,
- laser = ARMOR_LASER_SMALL,
- energy = ARMOR_ENERGY_RESISTANT,
+ melee = ARMOR_MELEE_VERY_HIGH,
+ bullet = ARMOR_BALLISTIC_MINOR,
+ laser = ARMOR_LASER_SMALL,
+ energy = ARMOR_ENERGY_RESISTANT,
bomb = ARMOR_BOMB_SHIELDED
)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|BLOCKHAIR
@@ -63,10 +63,10 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
armor = list(
- melee = ARMOR_MELEE_VERY_HIGH,
- bullet = ARMOR_BALLISTIC_MINOR,
- laser = ARMOR_LASER_SMALL,
- energy = ARMOR_ENERGY_RESISTANT,
+ melee = ARMOR_MELEE_VERY_HIGH,
+ bullet = ARMOR_BALLISTIC_MINOR,
+ laser = ARMOR_LASER_SMALL,
+ energy = ARMOR_ENERGY_RESISTANT,
bomb = ARMOR_BOMB_SHIELDED
)
flags_inv = HIDEJUMPSUIT|HIDETAIL
@@ -97,7 +97,7 @@
flags_inv = BLOCKHAIR
body_parts_covered = SLOT_HEAD|SLOT_FACE|SLOT_EYES
armor = list(
- bio = ARMOR_BIO_RESISTANT,
+ bio = ARMOR_BIO_RESISTANT,
rad = ARMOR_RAD_SHIELDED
)
matter = list(
@@ -117,7 +117,7 @@
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_ARMS|SLOT_HANDS|SLOT_FEET
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency,/obj/item/clothing/head/radiation,/obj/item/clothing/mask/gas,/obj/item/geiger)
armor = list(
- bio = ARMOR_BIO_RESISTANT,
+ bio = ARMOR_BIO_RESISTANT,
rad = ARMOR_RAD_SHIELDED
)
flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDEGLOVES|HIDESHOES
@@ -141,7 +141,7 @@
icon = 'icons/clothing/head/chem_hood.dmi'
permeability_coefficient = 0
armor = list(
- bio = ARMOR_BIO_RESISTANT,
+ bio = ARMOR_BIO_RESISTANT,
rad = ARMOR_RAD_MINOR
)
flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
@@ -162,9 +162,9 @@
gas_transfer_coefficient = 0
permeability_coefficient = 0
body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS|SLOT_HANDS
- allowed = list(/obj/item/tank/emergency,/obj/item/pen,/obj/item/flashlight/pen,/obj/item/scanner/health,/obj/item/ano_scanner,/obj/item/clothing/head/chem_hood,/obj/item/clothing/mask/gas,/obj/item/geiger)
+ allowed = list(/obj/item/tank/emergency,/obj/item/pen,/obj/item/flashlight/pen,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/ano_scanner,/obj/item/clothing/head/chem_hood,/obj/item/clothing/mask/gas,/obj/item/geiger)
armor = list(
- bio = ARMOR_BIO_RESISTANT,
+ bio = ARMOR_BIO_RESISTANT,
rad = ARMOR_RAD_MINOR
)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm
index 25177457d7e..7a2c021a1f7 100644
--- a/code/modules/clothing/under/accessories/storage.dm
+++ b/code/modules/clothing/under/accessories/storage.dm
@@ -140,6 +140,7 @@
/obj/item/chems/syringe,
/obj/item/chems/hypospray,
/obj/item/chems/hypospray/autoinjector,
+ /obj/item/chems/inhaler,
/obj/item/syringe_cartridge,
/obj/item/plastique,
/obj/item/clothing/mask/smokable,
diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm
index 81afb62c415..68436d10dd6 100644
--- a/code/modules/detectivework/tools/rag.dm
+++ b/code/modules/detectivework/tools/rag.dm
@@ -126,7 +126,8 @@
SPAN_DANGER("You smother \the [target] with \the [src]!")
)
//it's inhaled, so... maybe CHEM_INJECT doesn't make a whole lot of sense but it's the best we can do for now
- var/trans_amt = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INJECT)
+ // ^ HA HA HA
+ var/trans_amt = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INHALE)
var/contained_reagents = reagents.get_reagents()
admin_inject_log(user, M, src, contained_reagents, trans_amt)
update_name()
diff --git a/code/modules/emotes/definitions/audible.dm b/code/modules/emotes/definitions/audible.dm
index c69bfb83dec..3a168083087 100644
--- a/code/modules/emotes/definitions/audible.dm
+++ b/code/modules/emotes/definitions/audible.dm
@@ -96,8 +96,19 @@
/decl/emote/audible/cough
key = "cough"
- emote_message_3p = "USER coughs!"
- conscious = 0
+
+/decl/emote/audible/cough/check_user(var/mob/living/carbon/user)
+ . = ..()
+ if(!.)
+ return .
+ var/obj/item/organ/internal/lungs/lung = user.get_organ(BP_LUNGS)
+ . = lung?.active_breathing && !user.isSynthetic()
+
+/decl/emote/audible/cough/do_emote(var/mob/living/carbon/user, var/extra_params)
+ if(!istype(user))
+ to_chat(user, SPAN_WARNING("You are unable to vomit."))
+ return
+ user.cough(deliberate = TRUE)
/decl/emote/audible/cry
key = "cry"
diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm
index 80ad930d04f..35e32760888 100644
--- a/code/modules/materials/_materials.dm
+++ b/code/modules/materials/_materials.dm
@@ -83,6 +83,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/default_solid_form = /obj/item/stack/material/sheet
var/affect_blood_on_ingest = TRUE
+ var/affect_blood_on_inhale = TRUE
var/narcosis = 0 // Not a great word for it. Constant for causing mild confusion when ingested.
var/toxicity = 0 // Organ damage from ingestion.
@@ -209,6 +210,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
var/metabolism = REM // This would be 0.2 normally
var/ingest_met = 0
var/touch_met = 0
+ var/inhale_met = 0
var/overdose = 0
var/scannable = 0 // Shows up on health analyzers.
var/color = COLOR_BEIGE
@@ -522,6 +524,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
removed = ingest_met
if(touch_met && (location == CHEM_TOUCH))
removed = touch_met
+ if(inhale_met && (location == CHEM_INHALE))
+ removed = inhale_met
removed = M.get_adjusted_metabolism(removed)
//adjust effective amounts - removed, dose, and max_dose - for mob size
@@ -539,6 +543,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
affect_ingest(M, alien, effective, holder)
if(CHEM_TOUCH)
affect_touch(M, alien, effective, holder)
+ if(CHEM_INHALE)
+ affect_inhale(M, alien, effective, holder)
holder.remove_reagent(type, removed)
/decl/material/proc/affect_blood(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
@@ -579,6 +585,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay)
if(affect_blood_on_ingest)
affect_blood(M, alien, removed * 0.5, holder)
+/decl/material/proc/affect_inhale(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
+ if(affect_blood_on_inhale)
+ affect_blood(M, alien, removed * 0.5, holder)
+
/decl/material/proc/affect_touch(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
if(!istype(M))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 0b9e25b1955..7de32809f69 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -42,18 +42,18 @@
. = ..()
/mob/living/carbon/human/get_ingested_reagents()
- if(should_have_organ(BP_STOMACH))
- var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH)
- if(stomach)
- return stomach.ingested
- return get_contact_reagents() // Kind of a shitty hack, but makes more sense to me than digesting them.
+ if(!should_have_organ(BP_STOMACH))
+ return
+ var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH)
+ return stomach?.ingested
/mob/living/carbon/human/metabolize_ingested_reagents()
- if(should_have_organ(BP_STOMACH))
- var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH)
- if(stomach)
- stomach.metabolize()
- return stomach?.ingested
+ if(!should_have_organ(BP_STOMACH))
+ return
+ var/obj/item/organ/internal/stomach/stomach = get_organ(BP_STOMACH)
+ if(stomach)
+ stomach.metabolize()
+ return stomach.ingested
/mob/living/carbon/human/get_fullness()
if(!should_have_organ(BP_STOMACH))
@@ -63,6 +63,20 @@
return nutrition + (stomach.ingested?.total_volume * 10)
return 0 //Always hungry, but you can't actually eat. :(
+/mob/living/carbon/human/get_inhaled_reagents()
+ if(!should_have_organ(BP_LUNGS))
+ return
+ var/obj/item/organ/internal/lungs/lungs = get_organ(BP_LUNGS)
+ return lungs?.inhaled
+
+/mob/living/carbon/human/metabolize_inhaled_reagents()
+ if(!should_have_organ(BP_LUNGS))
+ return
+ var/obj/item/organ/internal/lungs/lungs = get_organ(BP_LUNGS)
+ if(lungs)
+ lungs.metabolize()
+ return lungs.inhaled
+
/mob/living/carbon/human/Stat()
. = ..()
if(statpanel("Status"))
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 90b05d0b315..68f11b302c1 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -202,8 +202,7 @@
if(stat != DEAD)
if ((disabilities & COUGHING) && prob(5) && GET_STATUS(src, STAT_PARA) <= 1)
drop_held_items()
- spawn(0)
- emote("cough")
+ cough()
/mob/living/carbon/human/handle_mutations_and_radiation()
if(getFireLoss())
@@ -267,7 +266,7 @@
var/list/limbs = get_external_organs()
if(!isSynthetic() && LAZYLEN(limbs))
var/obj/item/organ/external/O = pick(limbs)
- if(istype(O))
+ if(istype(O))
O.add_autopsy_data("Radiation Poisoning", damage)
/** breathing **/
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 2c69eaebb8b..f0e4bc8186f 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -56,15 +56,16 @@
var/datum/reagents/metabolism/touching_reagents = metabolize_touching_reagents()
var/datum/reagents/metabolism/bloodstr_reagents = metabolize_injected_reagents()
var/datum/reagents/metabolism/ingested_reagents = metabolize_ingested_reagents()
+ var/datum/reagents/metabolism/inhaled_reagents = metabolize_inhaled_reagents()
// Update chem dosage.
// TODO: refactor chem dosage above isSynthetic() and GODMODE checks.
if(length(chem_doses))
for(var/T in chem_doses)
- if(bloodstr_reagents?.has_reagent(T) || ingested_reagents?.has_reagent(T) || touching_reagents?.has_reagent(T))
+ if(bloodstr_reagents?.has_reagent(T) || ingested_reagents?.has_reagent(T) || touching_reagents?.has_reagent(T) || inhaled_reagents?.has_reagent(T))
continue
- var/decl/material/R = T
- var/dose = LAZYACCESS(chem_doses, T) - initial(R.metabolism)*2
+ var/decl/material/R = GET_DECL(T)
+ var/dose = LAZYACCESS(chem_doses, T) - R.metabolism*2
LAZYSET(chem_doses, T, dose)
if(LAZYACCESS(chem_doses, T) <= 0)
LAZYREMOVE(chem_doses, T)
@@ -86,19 +87,25 @@
if(istype(touching_reagents))
touching_reagents.metabolize()
return touching_reagents
-
+
/mob/living/proc/metabolize_injected_reagents()
var/datum/reagents/metabolism/injected_reagents = get_injected_reagents()
if(istype(injected_reagents))
injected_reagents.metabolize()
return injected_reagents
-
+
/mob/living/proc/metabolize_ingested_reagents()
var/datum/reagents/metabolism/ingested_reagents = get_ingested_reagents()
if(istype(ingested_reagents))
ingested_reagents.metabolize()
return ingested_reagents
+/mob/living/proc/metabolize_inhaled_reagents()
+ var/datum/reagents/metabolism/inhaled_reagents = get_inhaled_reagents()
+ if(istype(inhaled_reagents))
+ inhaled_reagents.metabolize()
+ return inhaled_reagents
+
/mob/living/proc/handle_random_events()
return
@@ -213,7 +220,7 @@
else if(eyeobj)
if(eyeobj.owner != src)
reset_view(null)
- else if(z_eye)
+ else if(z_eye)
return
else if(client && !client.adminobs)
reset_view(null)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 845a45ab0e3..f411d82d5aa 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -412,6 +412,9 @@ default behaviour is:
var/datum/reagents/ingested_reagents = get_ingested_reagents()
if(ingested_reagents)
ingested_reagents.clear_reagents()
+ var/datum/reagents/inhaled_reagents = get_inhaled_reagents()
+ if(inhaled_reagents)
+ inhaled_reagents.clear_reagents()
if(reagents)
reagents.clear_reagents()
@@ -804,9 +807,17 @@ default behaviour is:
if(!lying && T.above && !T.above.is_flooded() && T.above.CanZPass(src, UP) && can_overcome_gravity())
return FALSE
if(prob(5))
+ var/datum/reagents/metabolism/inhaled = get_inhaled_reagents()
+ var/datum/reagents/metabolism/ingested = get_ingested_reagents()
var/obj/effect/fluid/F = locate() in loc
to_chat(src, SPAN_DANGER("You choke and splutter as you inhale [(F?.reagents && F.reagents.get_primary_reagent_name()) || "liquid"]!"))
- F?.reagents?.trans_to_holder(get_ingested_reagents(), min(F.reagents.total_volume, rand(2,5)))
+ var/inhale_amount = 0
+ if(inhaled)
+ inhale_amount = rand(2,5)
+ F?.reagents?.trans_to_holder(inhaled, min(F.reagents.total_volume, inhale_amount))
+ if(ingested)
+ var/ingest_amount = 5 - inhale_amount
+ F?.reagents?.trans_to_holder(ingested, min(F.reagents.total_volume, ingest_amount))
T.show_bubbles()
return TRUE // Presumably chemical smoke can't be breathed while you're underwater.
@@ -937,6 +948,9 @@ default behaviour is:
/mob/living/proc/get_injected_reagents()
return reagents
+/mob/living/proc/get_inhaled_reagents()
+ return reagents
+
/mob/living/proc/get_adjusted_metabolism(metabolism)
return metabolism
diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm
index 79905caa915..0690509ec54 100644
--- a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm
+++ b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm
@@ -14,6 +14,7 @@
/obj/item/flash,
/obj/item/borg/sight/hud/med,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/scanner/reagent/adv,
/obj/item/chems/borghypo/crisis,
/obj/item/extinguisher/mini,
diff --git a/code/modules/mob/living/silicon/robot/modules/module_medical.dm b/code/modules/mob/living/silicon/robot/modules/module_medical.dm
index 8301a2f3561..ab8af1208a8 100644
--- a/code/modules/mob/living/silicon/robot/modules/module_medical.dm
+++ b/code/modules/mob/living/silicon/robot/modules/module_medical.dm
@@ -28,6 +28,7 @@
/obj/item/flash,
/obj/item/borg/sight/hud/med,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/chems/borghypo/surgeon,
/obj/item/incision_manager,
/obj/item/hemostat,
@@ -102,6 +103,7 @@
/obj/item/flash,
/obj/item/borg/sight/hud/med,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/scanner/reagent/adv,
/obj/item/robot_rack/body_bag,
/obj/item/chems/borghypo/crisis,
diff --git a/code/modules/organs/ailments/ailments_medical.dm b/code/modules/organs/ailments/ailments_medical.dm
index 16571b88324..cca4bfcb13f 100644
--- a/code/modules/organs/ailments/ailments_medical.dm
+++ b/code/modules/organs/ailments/ailments_medical.dm
@@ -91,8 +91,7 @@
return FALSE
/datum/ailment/coughing/on_ailment_event()
- if(organ.owner.usable_emotes["cough"])
- organ.owner.emote("cough")
+ organ.owner.cough()
organ.owner.setClickCooldown(3)
/datum/ailment/sore_joint
diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm
index 5d034c441ec..2d37cd64c0c 100644
--- a/code/modules/organs/internal/lungs.dm
+++ b/code/modules/organs/internal/lungs.dm
@@ -31,8 +31,33 @@
var/last_successful_breath
var/breath_fail_ratio // How badly they failed a breath. Higher is worse.
+ var/datum/reagents/metabolism/inhaled
+
+/obj/item/organ/internal/lungs/Destroy()
+ QDEL_NULL(inhaled)
+ . = ..()
+
+/obj/item/organ/internal/lungs/setup_reagents()
+ . = ..()
+ if(!inhaled)
+ inhaled = new/datum/reagents/metabolism(240, (owner || src), CHEM_INHALE)
+ if(!inhaled.my_atom)
+ inhaled.my_atom = src
+
+/obj/item/organ/internal/lungs/do_install(mob/living/carbon/human/target, obj/item/organ/external/affected, in_place)
+ if(!(. = ..()))
+ return
+ inhaled.my_atom = owner
+ inhaled.parent = owner
+
+/obj/item/organ/internal/lungs/do_uninstall(in_place, detach, ignore_children)
+ . = ..()
+ if(inhaled)
+ inhaled.my_atom = src
+ inhaled.parent = null
+
/obj/item/organ/internal/lungs/proc/can_drown()
- return (is_broken() || !has_gills)
+ return !has_gills || !is_usable()
/obj/item/organ/internal/lungs/proc/remove_oxygen_deprivation(var/amount)
var/last_suffocation = oxygen_deprivation
@@ -54,6 +79,12 @@
. = ..()
sync_breath_types()
+// This call needs to be split out to make sure that all the ingested things are metabolised
+// before the process call is made on any of the other organs
+/obj/item/organ/internal/lungs/proc/metabolize()
+ if(is_usable())
+ inhaled.metabolize()
+
/**
* Set these lungs' breath types based on the lungs' species
*/
@@ -71,6 +102,7 @@
poison_types = list(/decl/material/gas/chlorine = TRUE)
exhale_type = /decl/material/gas/carbon_dioxide
+
/obj/item/organ/internal/lungs/Process()
..()
if(!owner)
@@ -78,7 +110,7 @@
if (germ_level > INFECTION_LEVEL_ONE && active_breathing)
if(prob(5))
- owner.emote("cough") //respitory tract infection
+ owner.cough() //respitory tract infection
if(is_bruised() && !owner.is_asystole())
if(prob(2))
@@ -155,7 +187,7 @@
var/breatheffect = GET_CHEMICAL_EFFECT(owner, CE_BREATHLOSS)
if(!forced && breatheffect && !GET_CHEMICAL_EFFECT(owner, CE_STABLE)) //opiates are bad mmkay
safe_pressure_min *= 1 + breatheffect
-
+
if(owner.lying)
safe_pressure_min *= 0.8
@@ -204,9 +236,9 @@
continue
// Little bit of sanity so we aren't trying to add 0.0000000001 units of CO2, and so we don't end up with 99999 units of CO2.
var/reagent_amount = breath.gas[gasname] * REAGENT_UNITS_PER_GAS_MOLE * ratio
- if(reagent_amount < 0.05)
+ if(reagent_amount < MINIMUM_CHEMICAL_VOLUME)
continue
- owner.reagents.add_reagent(gasname, reagent_amount)
+ inhaled.add_reagent(gasname, reagent_amount)
breath.adjust_gas(gasname, -breath.gas[gasname], update = 0) //update after
// Moved after reagent injection so we don't instantly poison ourselves with CO2 or whatever.
@@ -335,3 +367,26 @@
/obj/item/organ/internal/lungs/gills
name = "lungs and gills"
has_gills = TRUE
+
+/mob/living/carbon/var/lastcough
+/mob/living/carbon/proc/cough(var/deliberate = FALSE)
+ var/obj/item/organ/internal/lungs/lung = get_organ(BP_LUNGS)
+ if(!lung || !lung.active_breathing || isSynthetic() || stat == DEAD || (deliberate && lastcough + 3 SECONDS > world.time))
+ return
+
+ if(lung.breath_fail_ratio > 0.9 && world.time > lung.last_successful_breath + 2 MINUTES)
+ if(deliberate)
+ to_chat(src, SPAN_WARNING("You try to cough, but no air comes out!"))
+ return
+
+ if(deliberate && incapacitated())
+ to_chat(src, SPAN_WARNING("You cannot do that right now."))
+ return
+
+ audible_message("[src] coughs!", "You cough!", radio_message = "coughs!") // styled like an emote
+
+ lastcough = world.time
+
+ // Coughing clears out 1-2 reagents from the lungs.
+ if(lung.inhaled.total_volume > 0 && loc)
+ lung.inhaled.splash(loc, rand(1, 2))
\ No newline at end of file
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 076243b47a2..37da2a27fd5 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -201,7 +201,7 @@
/obj/item/organ/proc/handle_ailment(var/datum/ailment/ailment)
if(ailment.treated_by_reagent_type)
- for(var/datum/reagents/source in list(owner.get_injected_reagents(), owner.reagents, owner.get_ingested_reagents()))
+ for(var/datum/reagents/source in list(owner.get_injected_reagents(), owner.reagents, owner.get_ingested_reagents(), owner.get_inhaled_reagents()))
for(var/reagent_type in source.reagent_volumes)
if(ailment.treated_by_medication(source.reagent_volumes[reagent_type]))
ailment.was_treated_by_medication(source, reagent_type)
diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm
index d605125acd5..f437b9b2dd6 100644
--- a/code/modules/reagents/Chemistry-Holder.dm
+++ b/code/modules/reagents/Chemistry-Holder.dm
@@ -517,6 +517,10 @@ var/global/obj/temp_reagents_holder = new
var/datum/reagents/R = L.get_contact_reagents()
if(R)
return trans_to_holder(R, amount, multiplier, copy, defer_update = defer_update)
+ if(type == CHEM_INHALE)
+ var/datum/reagents/R = L.get_inhaled_reagents()
+ if(R)
+ return trans_to_holder(R, amount, multiplier, copy, defer_update = defer_update)
var/datum/reagents/R = new /datum/reagents(amount, global.temp_reagents_holder)
. = trans_to_holder(R, amount, multiplier, copy, TRUE, defer_update = defer_update)
R.touch_mob(target)
diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm
index c15b35c2609..2b96ccc530c 100644
--- a/code/modules/reagents/chems/chems_medicines.dm
+++ b/code/modules/reagents/chems/chems_medicines.dm
@@ -14,7 +14,7 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_organ(BP_EYES)
if(E && istype(E) && !E.is_broken())
- ADJ_STATUS(M, STAT_BLURRY, -5)
+ ADJ_STATUS(M, STAT_BLURRY, -5)
ADJ_STATUS(M, STAT_BLIND, -5)
E.damage = max(E.damage - 5 * removed, 0)
@@ -122,10 +122,10 @@
var/removing = (4 * removed)
var/datum/reagents/ingested = M.get_ingested_reagents()
- for(var/R in ingested.reagent_volumes)
+ for(var/R in ingested?.reagent_volumes)
var/decl/material/chem = GET_DECL(R)
if((remove_generic && chem.toxicity) || (R in remove_toxins))
- M.reagents.remove_reagent(R, removing)
+ ingested.remove_reagent(R, removing)
return
for(var/R in M.reagents?.reagent_volumes)
@@ -253,7 +253,7 @@
if(!BP_IS_PROSTHETIC(E) && prob(25) && !(E.status & ORGAN_MUTATED))
E.mutate()
E.limb_flags |= ORGAN_FLAG_DEFORMED
-
+
/decl/material/liquid/retrovirals/affect_blood(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
M.adjustCloneLoss(-20 * removed)
if(LAZYACCESS(M.chem_doses, type) > 10)
@@ -359,3 +359,43 @@
/decl/material/liquid/oxy_meds/affect_blood(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
M.add_chemical_effect(CE_OXYGENATED, 1)
holder.remove_reagent(/decl/material/gas/carbon_monoxide, 2 * removed)
+
+#define DETOXIFIER_EFFECTIVENESS 6 // 6u of opiates removed per 1u of detoxifier; 5u is enough to remove 30u, i.e. an overdose
+#define DETOXIFIER_DOSE_EFFECTIVENESS 2 // 2u of metabolised opiates removed per 1u of detoxifier; will leave you vulnerable to another OD if you use more
+/decl/material/liquid/detoxifier
+ name = "detoxifier"
+ lore_text = "A compound designed to purge opiates and narcotics from the body when inhaled or injected."
+ taste_description = "bitterness"
+ color = "#6666ff"
+ metabolism = REM
+ scannable = TRUE
+ affect_blood_on_inhale = TRUE
+ affect_blood_on_ingest = FALSE
+ value = 1.5
+ uid = "chem_detoxifier"
+
+/decl/material/liquid/detoxifier/affect_blood(var/mob/living/M, var/alien, var/removed, var/datum/reagents/holder)
+ var/charges = removed * DETOXIFIER_EFFECTIVENESS
+ var/dosecharges = LAZYACCESS(M.chem_doses, type) * DETOXIFIER_DOSE_EFFECTIVENESS
+ for(var/datum/reagents/container in list(M.get_ingested_reagents(), M.get_inhaled_reagents(), M.get_injected_reagents()))
+ for(var/reagent_type in container.reagent_volumes)
+ var/decl/material/liquid/painkillers/painkiller = GET_DECL(reagent_type)
+ if(!istype(painkiller) || !painkiller.narcotic)
+ continue
+ var/amount = min(charges, REAGENT_VOLUME(container, reagent_type))
+ if(amount)
+ charges -= amount
+ container.remove_reagent(reagent_type, amount)
+ var/dose_amount = min(dosecharges, LAZYACCESS(M.chem_doses, reagent_type))
+ if(dose_amount)
+ var/dose = LAZYACCESS(M.chem_doses, reagent_type) - dose_amount
+ LAZYSET(M.chem_doses, reagent_type, dose)
+ if(M.chem_doses[reagent_type] <= 0)
+ LAZYREMOVE(M.chem_doses, reagent_type)
+ dosecharges -= dose_amount
+ if(charges <= 0 && dosecharges <= 0)
+ break
+ if(charges <= 0 && dosecharges <= 0)
+ break
+#undef DETOXIFIER_EFFECTIVENESS
+#undef DETOXIFIER_DOSE_EFFECTIVENESS
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 3ee9da59832..20b55e0e1cc 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -153,6 +153,10 @@
origin_tech = "{'materials':2,'biotech':2}"
slot_flags = SLOT_LOWER_BODY | SLOT_EARS
w_class = ITEM_SIZE_TINY
+ matter = list(
+ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT,
+ /decl/material/solid/metal/aluminium = MATTER_AMOUNT_TRACE
+ )
var/list/starts_with = list(/decl/material/liquid/adrenaline = 5)
var/band_color = COLOR_CYAN
@@ -167,12 +171,12 @@
update_icon()
/obj/item/chems/hypospray/autoinjector/on_update_icon()
- overlays.Cut()
+ cut_overlays()
if(reagents.total_volume > 0)
icon_state = "[initial(icon_state)]1"
else
icon_state = "[initial(icon_state)]0"
- overlays+= overlay_image(icon,"injector_band",band_color,RESET_COLOR)
+ add_overlay(overlay_image(icon,"injector_band",band_color,RESET_COLOR))
/obj/item/chems/hypospray/autoinjector/examine(mob/user)
. = ..(user)
diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm
new file mode 100644
index 00000000000..f4ceb610ae0
--- /dev/null
+++ b/code/modules/reagents/reagent_containers/inhaler.dm
@@ -0,0 +1,115 @@
+//Inhalers
+//Just like hypopsray code
+/obj/item/chems/inhaler
+ name = "autoinhaler"
+ desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel."
+ icon = 'icons/obj/syringe.dmi'
+ item_state = "autoinjector"
+ icon_state = "autoinhaler"
+ center_of_mass = @"{'x':16,'y':11}"
+ unacidable = TRUE
+ amount_per_transfer_from_this = 5
+ volume = 5
+ w_class = ITEM_SIZE_SMALL
+ possible_transfer_amounts = null
+ atom_flags = ATOM_FLAG_OPEN_CONTAINER
+ slot_flags = SLOT_LOWER_BODY
+ origin_tech = "{'materials':2,'biotech':2}"
+ var/used = FALSE
+ matter = list(
+ /decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT,
+ /decl/material/solid/metal/aluminium = MATTER_AMOUNT_TRACE
+ )
+ var/list/starts_with = null /// A lazylist of starting reagents. Example: list(/decl/material/liquid/adrenaline = 5)
+ var/band_color = COLOR_GREEN
+
+/obj/item/chems/inhaler/Initialize()
+ . = ..()
+ for(var/T in starts_with)
+ reagents.add_reagent(T, starts_with[T])
+ update_icon()
+
+/obj/item/chems/inhaler/on_update_icon()
+ cut_overlays()
+ if(ATOM_IS_OPEN_CONTAINER(src))
+ add_overlay("[icon_state]_loaded")
+ if(reagents.total_volume > 0)
+ add_overlay("[icon_state]_reagents")
+ add_overlay(overlay_image(icon,"[icon_state]_band",band_color,RESET_COLOR))
+
+/obj/item/chems/inhaler/attack(var/mob/living/carbon/human/target, var/mob/user, var/proximity)
+ if (!istype(target))
+ return ..()
+
+ if(!proximity)
+ return TRUE
+
+ if(!reagents.total_volume)
+ to_chat(user, SPAN_WARNING("\The [src] is empty."))
+ return TRUE
+
+ // This properly handles mouth coverage/presence, but should probably be replaced later.
+ if(user == target)
+ if(!target.can_eat(src))
+ return TRUE
+ else
+ if(!target.can_force_feed(user, src))
+ return TRUE
+
+ user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
+ user.do_attack_animation(target)
+
+ if(user == target)
+ user.visible_message(SPAN_NOTICE("\The [user] inhales from \the [src]."), SPAN_NOTICE("You stick the \the [src] in your mouth and press the injection button."))
+ else
+ user.visible_message(SPAN_WARNING("\The [user] attempts to administer \the [src] to \the [target]..."), SPAN_NOTICE("You attempt to administer \the [src] to \the [target]..."))
+ if (!do_after(user, 1 SECONDS, target))
+ to_chat(user, SPAN_NOTICE("You and the target need to be standing still in order to inject \the [src]."))
+ return TRUE
+
+ user.visible_message(SPAN_NOTICE("\The [user] administers \the [src] to \the [target]."), SPAN_NOTICE("You stick \the [src] in \the [target]'s mouth and press the injection button."))
+
+ var/contained = REAGENT_LIST(src)
+ var/trans = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INHALE)
+ if(trans)
+ admin_inject_log(user, target, src, contained, trans)
+ playsound(src.loc, 'sound/effects/hypospray.ogg', 50, 1)
+ to_chat(user, SPAN_NOTICE("[trans] units administered. [reagents.total_volume] units remaining in \the [src]."))
+ used = TRUE
+
+ update_icon()
+
+ return TRUE
+
+/obj/item/chems/inhaler/attack(mob/M as mob, mob/user as mob)
+ if(ATOM_IS_OPEN_CONTAINER(src))
+ to_chat(user, SPAN_NOTICE("You must secure the reagents inside \the [src] before using it!"))
+ return FALSE
+ . = ..()
+
+/obj/item/chems/inhaler/attack_self(mob/user as mob)
+ if(ATOM_IS_OPEN_CONTAINER(src))
+ if(reagents.total_volume > 0)
+ to_chat(user, SPAN_NOTICE("With a quick twist of \the [src]'s lid, you secure the reagents inside."))
+ atom_flags &= ~ATOM_FLAG_OPEN_CONTAINER
+ update_icon()
+ else
+ to_chat(user, SPAN_NOTICE("You can't secure \the [src] without putting reagents in!"))
+ else
+ to_chat(user, SPAN_NOTICE("The reagents inside \the [src] are already secured."))
+ return TRUE
+
+/obj/item/chems/inhaler/attackby(obj/item/tool, mob/user)
+ if(isScrewdriver(tool) && !ATOM_IS_OPEN_CONTAINER(src))
+ to_chat(user, SPAN_NOTICE("Using \the [tool], you unsecure the inhaler's lid.")) // it locks shut after being secured
+ atom_flags |= ATOM_FLAG_OPEN_CONTAINER
+ update_icon()
+ return TRUE
+ . = ..()
+
+/obj/item/chems/inhaler/examine(mob/user)
+ . = ..(user)
+ if(reagents.total_volume > 0)
+ to_chat(user, SPAN_NOTICE("It is currently loaded."))
+ else
+ to_chat(user, SPAN_NOTICE("It is spent."))
diff --git a/code/modules/spells/spellbook/cleric.dm b/code/modules/spells/spellbook/cleric.dm
index e639f192943..8775b80375e 100644
--- a/code/modules/spells/spellbook/cleric.dm
+++ b/code/modules/spells/spellbook/cleric.dm
@@ -42,6 +42,7 @@
sacrifice_objects = list(
/obj/item/stack/nanopaste,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/stack/medical/advanced/bruise_pack,
/obj/item/stack/medical/advanced/ointment,
/obj/item/bodybag/rescue,
diff --git a/code/modules/surgery/_surgery.dm b/code/modules/surgery/_surgery.dm
index 1ade04bdf37..50a96bd9a9d 100644
--- a/code/modules/surgery/_surgery.dm
+++ b/code/modules/surgery/_surgery.dm
@@ -4,8 +4,10 @@ var/global/list/surgeries_in_progress = list()
var/global/list/surgery_tool_exceptions = list(
/obj/item/auto_cpr,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/shockpaddles,
/obj/item/chems/hypospray,
+ /obj/item/chems/inhaler,
/obj/item/modular_computer,
/obj/item/chems/syringe,
/obj/item/chems/borghypo
diff --git a/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm b/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm
index ab359d5b9cb..828289b20b2 100644
--- a/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm
+++ b/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm
@@ -34,6 +34,7 @@
/obj/item/flash,
/obj/item/flashlight,
/obj/item/scanner/health,
+ /obj/item/scanner/breath,
/obj/item/multitool,
/obj/item/paicard,
/obj/item/radio,
diff --git a/code/modules/xenoarcheaology/tools/equipment.dm b/code/modules/xenoarcheaology/tools/equipment.dm
index c49948b3171..50406fdba94 100644
--- a/code/modules/xenoarcheaology/tools/equipment.dm
+++ b/code/modules/xenoarcheaology/tools/equipment.dm
@@ -22,7 +22,7 @@
rad = ARMOR_RAD_SHIELDED
)
anomaly_shielding = 0.6
- allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/stack/flag,/obj/item/storage/excavation,/obj/item/pickaxe,/obj/item/scanner/health,/obj/item/measuring_tape,/obj/item/ano_scanner,/obj/item/depth_scanner,/obj/item/core_sampler,/obj/item/gps,/obj/item/pinpointer/radio,/obj/item/radio/beacon,/obj/item/pickaxe/xeno,/obj/item/storage/bag/fossils)
+ allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/stack/flag,/obj/item/storage/excavation,/obj/item/pickaxe,/obj/item/scanner/health,/obj/item/scanner/breath,/obj/item/measuring_tape,/obj/item/ano_scanner,/obj/item/depth_scanner,/obj/item/core_sampler,/obj/item/gps,/obj/item/pinpointer/radio,/obj/item/radio/beacon,/obj/item/pickaxe/xeno,/obj/item/storage/bag/fossils)
/obj/item/clothing/head/helmet/space/void/excavation
name = "excavation voidsuit helmet"
diff --git a/icons/obj/items/device/scanner/breath_scanner.dmi b/icons/obj/items/device/scanner/breath_scanner.dmi
new file mode 100644
index 00000000000..648bf78f29f
Binary files /dev/null and b/icons/obj/items/device/scanner/breath_scanner.dmi differ
diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi
index dfcccbd5de1..41e04593521 100644
Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ
diff --git a/nano/templates/sleeper.tmpl b/nano/templates/sleeper.tmpl
index 122ca1a3521..0c9ab51c289 100644
--- a/nano/templates/sleeper.tmpl
+++ b/nano/templates/sleeper.tmpl
@@ -22,6 +22,9 @@
{{:helper.link(data.pump ? "Stomach pump active" : "Stomach pump inactive", null, {'pump' : !data.pump})}}
+
+ {{:helper.link(data.lavage ? "Lung lavage active" : "Lung lavage inactive", null, {'lavage' : !data.lavage})}}
+
{{else}}
There are a few buttons here, but the labels don't make any sense to you.
{{/if}}
diff --git a/nebula.dme b/nebula.dme
index aed9a1fe2c2..a2a174a85e9 100644
--- a/nebula.dme
+++ b/nebula.dme
@@ -987,6 +987,7 @@
#include "code\game\objects\items\devices\radio\intercom.dm"
#include "code\game\objects\items\devices\radio\radio.dm"
#include "code\game\objects\items\devices\scanners\_scanner.dm"
+#include "code\game\objects\items\devices\scanners\breath.dm"
#include "code\game\objects\items\devices\scanners\gas.dm"
#include "code\game\objects\items\devices\scanners\health.dm"
#include "code\game\objects\items\devices\scanners\mass_spectrometer.dm"
@@ -3004,6 +3005,7 @@
#include "code\modules\reagents\reagent_containers\food.dm"
#include "code\modules\reagents\reagent_containers\glass.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
+#include "code\modules\reagents\reagent_containers\inhaler.dm"
#include "code\modules\reagents\reagent_containers\pill.dm"
#include "code\modules\reagents\reagent_containers\spray.dm"
#include "code\modules\reagents\reagent_containers\syringes.dm"