diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 6e99bc182e61..ec5286ca34a4 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -331,6 +331,8 @@
#define GAS_PLUOXIUM "pluox"
#define GAS_FREON "freon"
#define GAS_HYDROGEN "h2"
+#define GAS_CHLORINE "cl2"
+#define GAS_HYDROGEN_CHLORIDE "hcl"
#define GAS_FLAG_DANGEROUS (1<<0)
#define GAS_FLAG_BREATH_PROC (1<<1)
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index d9ca63008c1d..387f87c90acc 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -52,6 +52,7 @@
#define ANTI_TINFOIL_MANEUVER (1<<12) //Hats with negative effects when worn (i.e the tinfoil hat).
#define DANGEROUS_OBJECT (1<<13) //Clothes that cause a larger notification when placed on a person.
#define FAST_EMBARK (1<<14) //Clothes that speed up mech and pod boarding.
+#define SEALS_EYES (1<<15) //Goggles and helmets that seal eyes from the enviroment
/// Flags for the organ_flags var on /obj/item/organ
#define ORGAN_SYNTHETIC (1<<0) //Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index f88f0c9d791c..6a85a5c82fde 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -173,6 +173,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_RESISTCOLD "resist_cold"
#define TRAIT_RESISTHIGHPRESSURE "resist_high_pressure"
#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
+#define TRAIT_METALLIC "metallic" //used on IPCs
#define TRAIT_BOMBIMMUNE "bomb_immunity"
#define TRAIT_RADIMMUNE "rad_immunity"
#define TRAIT_GENELESS "geneless"
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index 5f5c26731d15..a155e570df4f 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -44,6 +44,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD,
"TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE,
"TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE,
+ "TRAIT_METALLIC" = TRAIT_METALLIC,
"TRAIT_BOMBIMMUNE" = TRAIT_BOMBIMMUNE,
"TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE,
"TRAIT_GENELESS" = TRAIT_GENELESS,
diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm
index 2b440f926c32..f8fa1d1ef786 100644
--- a/code/game/machinery/shuttle/shuttle_heater.dm
+++ b/code/game/machinery/shuttle/shuttle_heater.dm
@@ -5,13 +5,14 @@
//it for the engine.
//-----------------------------------------------
+#define CHLORINE_OXIDATION_VALUE 0.5
#define O2_OXIDATION_VALUE 1
#define NITRYL_OXIDATION_VALUE 1
#define NITROUS_OXIDATION_VALUE 3
+#define HYDROGEN_THRUSTER_VALUE 0.5
#define PLASMA_THRUSTER_VALUE 1
#define TRITRIUM_THRUSTER_VALUE 3
-#define HYDROGEN_THRUSTER_VALUE 0.5
#define NITROUS_COOLING_MULTIPIER 500
#define NITROUS_COOLING_MIN 173
diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm
index 835edafc4cb8..662b88046956 100644
--- a/code/modules/atmospherics/auxgm/gas_types.dm
+++ b/code/modules/atmospherics/auxgm/gas_types.dm
@@ -168,3 +168,27 @@
enthalpy = FIRE_HYDROGEN_ENERGY_RELEASED
fire_burn_rate = 2
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
+
+/datum/gas/chlorine
+ id = GAS_CHLORINE
+ specific_heat = 20
+ name = "Chlorine"
+ flags = GAS_FLAG_DANGEROUS
+ moles_visible = MOLES_GAS_VISIBLE * 5
+ gas_overlay = "nitrous_oxide"
+ color = "#FFFB89"
+ fusion_power = 0
+
+/datum/gas/hydrogen_chloride
+ id = GAS_HYDROGEN_CHLORIDE
+ specific_heat = 40
+ name = "Hydrogen Chloride"
+ flags = GAS_FLAG_DANGEROUS
+ moles_visible = MOLES_GAS_VISIBLE * 2
+ gas_overlay = "nitrous_oxide"
+ color = "#5bfd45"
+ fusion_power = 0
+ fire_products = list(GAS_CHLORINE = 1, GAS_H2O = 0.5)
+ enthalpy = 63000
+ fire_burn_rate = 1
+ fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm
index b3a81dbb0e9c..e774d1060ec3 100644
--- a/code/modules/atmospherics/gasmixtures/auxgm.dm
+++ b/code/modules/atmospherics/gasmixtures/auxgm.dm
@@ -1,5 +1,5 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLASMA)) //the main four gases, which were at one time hardcoded
-GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL))) //unable to react amongst themselves
+GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL, GAS_CHLORINE, GAS_HYDROGEN_CHLORIDE))) //unable to react amongst themselves
// Auxgm
// It's a send-up of XGM, like what baystation got.
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index 00ca2d22f76c..b824c1d78d61 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -825,3 +825,32 @@
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.set_temperature(clamp((air.return_temperature()*old_heat_capacity + energy_released)/new_heat_capacity,TCMB,INFINITY))
return REACTING
+
+/datum/gas_reaction/hydrogen_chloride_formation
+ priority = 11
+ name = "Hydrogen Chloride formation"
+ id = "hydrogenchlorideformation"
+
+/datum/gas_reaction/hydrogen_chloride_formation/init_reqs()
+ min_requirements = list(
+ GAS_CHLORINE = 5,
+ GAS_HYDROGEN = 5,
+ "TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
+ )
+
+/datum/gas_reaction/hydrogen_chloride_formation/react(datum/gas_mixture/air)
+ var/temperature = air.return_temperature()
+ var/old_heat_capacity = air.heat_capacity()
+ var/reaction_efficency = min((temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*10)),air.get_moles(GAS_CHLORINE),air.get_moles(GAS_HYDROGEN))
+ var/energy_released = reaction_efficency*185000
+ if ((air.get_moles(GAS_CHLORINE) - reaction_efficency < 0)|| (air.get_moles(GAS_HYDROGEN) - (reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
+ return NO_REACTION
+ air.adjust_moles(GAS_HYDROGEN_CHLORIDE, reaction_efficency)
+ air.adjust_moles(GAS_HYDROGEN, -reaction_efficency)
+ air.adjust_moles(GAS_CHLORINE, -reaction_efficency)
+
+ if(energy_released > 0)
+ var/new_heat_capacity = air.heat_capacity()
+ if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
+ air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
+ return REACTING
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index e5a1be0294d6..236c7b040d99 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -106,6 +106,11 @@
var/alarm_frequency = FREQ_ATMOS_ALARMS
var/datum/radio_frequency/radio_connection
+ //anything outright hazardous (flammable, toxic, generally Weird)
+ var/list/filter_basic = list(GAS_CO2, GAS_PLASMA, GAS_NITROUS, GAS_BZ, GAS_TRITIUM, GAS_NITRYL, GAS_FREON, GAS_HYDROGEN, GAS_CHLORINE, GAS_HYDROGEN_CHLORIDE)
+ //anything that isn't o2 or n2.
+ var/list/filter_extra = list(GAS_CO2, GAS_PLASMA, GAS_NITROUS, GAS_BZ, GAS_TRITIUM, GAS_NITRYL, GAS_FREON, GAS_HYDROGEN, GAS_CHLORINE, GAS_HYDROGEN_CHLORIDE, GAS_H2O, GAS_HYPERNOB, GAS_STIMULUM, GAS_PLUOXIUM)
+
var/list/TLV = list( // Breathable air.
"pressure" = new/datum/tlv(HAZARD_LOW_PRESSURE, WARNING_LOW_PRESSURE, WARNING_HIGH_PRESSURE, HAZARD_HIGH_PRESSURE), // kPa. Values are min2, min1, max1, max2
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66),
@@ -122,7 +127,9 @@
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_FREON = new/datum/tlv/dangerous,
- GAS_HYDROGEN = new/datum/tlv/dangerous
+ GAS_HYDROGEN = new/datum/tlv/dangerous,
+ GAS_CHLORINE = new/datum/tlv/dangerous,
+ GAS_HYDROGEN_CHLORIDE = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
@@ -142,7 +149,9 @@
GAS_NITRYL = new/datum/tlv/no_checks,
GAS_PLUOXIUM = new/datum/tlv/no_checks,
GAS_FREON = new/datum/tlv/no_checks,
- GAS_HYDROGEN = new/datum/tlv/no_checks
+ GAS_HYDROGEN = new/datum/tlv/no_checks,
+ GAS_CHLORINE = new/datum/tlv/dangerous,
+ GAS_HYDROGEN_CHLORIDE = new/datum/tlv/dangerous
)
heating_manage = FALSE
@@ -163,7 +172,9 @@
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_FREON = new/datum/tlv/dangerous,
- GAS_HYDROGEN = new/datum/tlv/dangerous
+ GAS_HYDROGEN = new/datum/tlv/dangerous,
+ GAS_CHLORINE = new/datum/tlv/dangerous,
+ GAS_HYDROGEN_CHLORIDE = new/datum/tlv/dangerous
)
heating_manage = FALSE
@@ -542,7 +553,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
- "set_filters" = list(GAS_CO2, GAS_BZ),
+ "set_filters" = filter_basic,
"scrubbing" = 1,
"widenet" = 0
), signal_source)
@@ -556,20 +567,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
- "set_filters" = list(
- GAS_CO2,
- GAS_PLASMA,
- GAS_H2O,
- GAS_HYPERNOB,
- GAS_NITROUS,
- GAS_NITRYL,
- GAS_TRITIUM,
- GAS_BZ,
- GAS_STIMULUM,
- GAS_PLUOXIUM,
- GAS_FREON,
- GAS_HYDROGEN
- ),
+ "set_filters" = filter_extra,
"scrubbing" = 1,
"widenet" = 1
), signal_source)
@@ -596,7 +594,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27)
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
- "set_filters" = list(GAS_CO2, GAS_BZ),
+ "set_filters" = filter_basic,
"scrubbing" = 1,
"widenet" = 0
), signal_source)
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index f2e563c07b5e..cb6a1b9b0bb0 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -54,7 +54,9 @@
"caution" = /obj/machinery/portable_atmospherics/canister,
"freon" = /obj/machinery/portable_atmospherics/canister/freon,
"hydrogen" = /obj/machinery/portable_atmospherics/canister/hydrogen,
- "fuel mix" = /obj/machinery/portable_atmospherics/canister/fuel
+ "fuel mix" = /obj/machinery/portable_atmospherics/canister/fuel,
+ "cl2" = /obj/machinery/portable_atmospherics/canister/chlorine,
+ "hcl" =/obj/machinery/portable_atmospherics/canister/hydrogen_chloride,
)
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
@@ -170,6 +172,20 @@
air_contents.set_moles(GAS_HYDROGEN, 1000)
air_contents.set_temperature(T20C)
+/obj/machinery/portable_atmospherics/canister/chlorine
+ name = "chlorine canister"
+ desc = "chlorine"
+ icon_state = "greenys"
+ gas_type = GAS_CHLORINE
+ filled = 1
+
+/obj/machinery/portable_atmospherics/canister/hydrogen_chloride
+ name = "hydrogen chloride canister"
+ desc = "awful"
+ icon_state = "greenyshaz"
+ gas_type = GAS_HYDROGEN_CHLORIDE
+ filled = 1
+
/obj/machinery/portable_atmospherics/canister/fusion_test
name = "fusion test canister"
desc = "Don't be a badmin."
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index f33a789156e9..59530e24a542 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -314,7 +314,7 @@
flash_protect = FLASH_PROTECTION_WELDER
custom_materials = list(/datum/material/iron = 250)
tint = 2
- visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
+ visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | SEALS_EYES
flags_cover = GLASSESCOVERSEYES
glass_colour_type = /datum/client_colour/glass_colour/gray
supports_variations = VOX_VARIATION
@@ -485,12 +485,14 @@
desc = "A pair of goggles meant for low temperatures."
icon_state = "cold"
item_state = "cold"
+ flags_cover = GLASSESCOVERSEYES | SEALS_EYES
/obj/item/clothing/glasses/heat
name = "heat goggles"
desc = "A pair of goggles meant for high temperatures."
icon_state = "heat"
item_state = "heat"
+ flags_cover = GLASSESCOVERSEYES | SEALS_EYES
/obj/item/clothing/glasses/orange
name = "orange glasses"
@@ -572,7 +574,7 @@
desc = "Medical, security and diagnostic hud. Alt click to toggle xray."
icon_state = "nvgmeson"
item_state = "nvgmeson"
- flags_cover = GLASSESCOVERSEYES
+ flags_cover = GLASSESCOVERSEYES | SEALS_EYES
darkness_view = 8
flash_protect = FLASH_PROTECTION_WELDER
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index dba4c2f80406..9b28c58d03cf 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -116,7 +116,7 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
/obj/item/clothing/head/hardhat/mining
name = "mining helmet"
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index a6de8769642a..cdfe4672d46f 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -286,7 +286,7 @@
visor_flags_inv = HIDEFACE
toggle_cooldown = 0
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
- visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
dog_fashion = null
/obj/item/clothing/head/helmet/justice
@@ -492,7 +492,7 @@
resistance_flags = FIRE_PROOF | ACID_PROOF
flash_protect = FLASH_PROTECTION_WELDER
flags_inv = HIDEHAIR|HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
strip_delay = 80
/obj/item/clothing/head/helmet/swat/inteq
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 34e77816c941..e5d3717b2b65 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -8,7 +8,7 @@
item_state = "gas_alt"
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
- flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH | PEPPERPROOF
+ flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
resistance_flags = NONE
/obj/item/clothing/mask/gas/atmos
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index cb98f607089c..f96ad54adb88 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -18,7 +18,7 @@
flash_protect = FLASH_PROTECTION_WELDER
strip_delay = 50
equip_delay_other = 50
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
resistance_flags = NONE
dog_fashion = null
content_overlays = FALSE
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index fbcc5318edf3..9db68d733bd1 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -17,7 +17,7 @@
actions_types = list(/datum/action/item_action/toggle_helmet)
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
- visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
var/rad_count = 0
var/rad_record = 0
var/grace_count = 0
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index 43dc5a5dd8d0..895dea5156aa 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -58,7 +58,7 @@
actions_types = list(/datum/action/item_action/toggle_helmet_light)
visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
- flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF
+ flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF | SEALS_EYES
visor_flags_inv = HIDEEYES|HIDEFACE
// WS Begin - plasmeme command helmets buff - used for RD bomb scanner
diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm
index 1131c4e9166c..3ef1628c19b4 100644
--- a/code/modules/clothing/suits/bio.dm
+++ b/code/modules/clothing/suits/bio.dm
@@ -8,7 +8,7 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 30, "acid" = 100)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDEFACE
resistance_flags = ACID_PROOF
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
/obj/item/clothing/suit/bio_suit
name = "bio suit"
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index ac91351c2324..88661d6b835c 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -67,7 +67,7 @@
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
strip_delay = 70
equip_delay_other = 70
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
resistance_flags = NONE
@@ -126,7 +126,7 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30)
strip_delay = 60
equip_delay_other = 60
- flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF | SEALS_EYES
resistance_flags = NONE
flags_1 = RAD_PROTECT_CONTENTS_1
supports_variations = VOX_VARIATION
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 730001819de4..18b6cb9ba40e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -61,6 +61,21 @@
return ONE_ATMOSPHERE
return pressure
+/mob/living/carbon/human/proc/check_for_seal()
+ var/obj/item/clothing/clothing_suit = wear_suit
+ var/obj/item/clothing/clothing_head = head
+ if(istype(clothing_suit) && istype(clothing_head))
+ if (clothing_suit.clothing_flags & clothing_head.clothing_flags & STOPSPRESSUREDAMAGE)
+ return TRUE
+ return FALSE
+
+/mob/living/carbon/human/proc/check_for_goggles()
+ if(head?.flags_cover & SEALS_EYES)
+ return head
+ if(wear_mask?.flags_cover & SEALS_EYES)
+ return wear_mask
+ if(glasses?.flags_cover & SEALS_EYES)
+ return glasses
/mob/living/carbon/human/handle_traits()
if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 60)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index e2a01d29540c..788baa32fbf5 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1,5 +1,7 @@
GLOBAL_LIST_EMPTY(roundstart_races)
+#define MINIMUM_MOLS_TO_HARM 1
+
/**
* # species datum
*
@@ -1793,6 +1795,61 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!H.on_fire || areatemp > H.bodytemperature) // If we are not on fire or the area is hotter
H.adjust_bodytemperature((areatemp - H.bodytemperature), use_insulation=TRUE, use_steps=TRUE, hardsuit_fix=bodytemp_normal - H.bodytemperature)
+ if(H.check_for_seal())
+ return
+
+ var/plasma = environment.get_moles(GAS_PLASMA)
+ var/tritium = environment.get_moles(GAS_TRITIUM)
+ var/chlorine = environment.get_moles(GAS_CHLORINE)
+ var/hydrogen_chloride = environment.get_moles(GAS_HYDROGEN_CHLORIDE)
+ if(chlorine <= MINIMUM_MOLS_TO_HARM && hydrogen_chloride <= MINIMUM_MOLS_TO_HARM && tritium <= MINIMUM_MOLS_TO_HARM && plasma <= MINIMUM_MOLS_TO_HARM)
+ return
+
+ var/eyedamage = FALSE
+ var/irritant = FALSE
+ var/burndamage = 0
+ var/lowerthreshold = 0
+ if(HAS_TRAIT(H, TRAIT_METALLIC)) //makes certain species take more damage and start taking damage at lower air amounts
+ lowerthreshold = 1
+
+ if(plasma > (MINIMUM_MOLS_TO_HARM * 10))
+ eyedamage = TRUE
+ irritant = TRUE
+ if(tritium)
+ burndamage += max(sqrt(tritium) - 2 + lowerthreshold, 0)
+ if(tritium > MINIMUM_MOLS_TO_HARM)
+ eyedamage = TRUE
+ irritant = TRUE
+ if(chlorine)
+ burndamage += max(sqrt(chlorine) - 4 + lowerthreshold, 0)
+ irritant = TRUE
+ if(chlorine > (MINIMUM_MOLS_TO_HARM * 10))
+ eyedamage = TRUE
+ if(hydrogen_chloride)
+ burndamage += max(sqrt(hydrogen_chloride) - 1 + lowerthreshold, 0)
+ eyedamage = TRUE
+ irritant = TRUE
+
+ if(!eyedamage && !burndamage && !irritant)
+ return
+ H.apply_damage(burndamage, BURN, spread_damage = TRUE)
+ if(prob(50) && burndamage)
+ if(lowerthreshold)
+ to_chat(H, "You're corroding!")
+ else
+ to_chat(H, "You're melting!")
+ playsound(H, 'sound/items/welder.ogg', 30, TRUE)
+ if(!H.check_for_goggles() && eyedamage)
+ H.adjustOrganLoss(ORGAN_SLOT_EYES, 1)
+ if(prob(50))
+ to_chat(H, "Your eyes burn!")
+ if(irritant && prob(50))
+ if(lowerthreshold)
+ to_chat(H, "Your outer shell smolders!")
+ else
+ to_chat(H, "Your skin itches.")
+
+
/// Handle the body temperature status effects for the species
/// Traits for resitance to heat or cold are handled here.
/datum/species/proc/handle_body_temperature(mob/living/carbon/human/H)
@@ -2264,3 +2321,5 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/get_harm_descriptors()
return
+
+#undef MINIMUM_MOLS_TO_HARM
diff --git a/code/modules/mob/living/carbon/human/species_types/IPC.dm b/code/modules/mob/living/carbon/human/species_types/IPC.dm
index 9410111c9e4f..20d3f81aa38d 100644
--- a/code/modules/mob/living/carbon/human/species_types/IPC.dm
+++ b/code/modules/mob/living/carbon/human/species_types/IPC.dm
@@ -5,7 +5,7 @@
species_age_min = 0
species_age_max = 300
species_traits = list(NOTRANSSTING,NOEYESPRITES,NO_DNA_COPY,TRAIT_EASYDISMEMBER,NOZOMBIE,MUTCOLORS,REVIVESBYHEALING,NOHUSK,NOMOUTH,NO_BONES) //all of these + whatever we inherit from the real species
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_LIMBATTACHMENT)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_LIMBATTACHMENT, TRAIT_METALLIC)
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
mutantbrain = /obj/item/organ/brain/mmi_holder/posibrain
mutanteyes = /obj/item/organ/eyes/robotic
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 24db5dd524d8..fdfeeb1cda9c 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -626,11 +626,14 @@
name = "Chlorine"
description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless."
reagent_state = GAS
+ metabolization_rate = REAGENTS_METABOLISM * 0.5
color = "#FFFB89" //pale yellow? let's make it light gray
- taste_description = "chlorine"
+ taste_description = "caustic"
/datum/reagent/chlorine/on_mob_life(mob/living/carbon/M)
- M.take_bodypart_damage(1*REM, 0, 0, 0)
+ M.take_bodypart_damage(0, 1*REM, 0, 0)
+ if(prob(25))
+ M.adjustOrganLoss(ORGAN_SLOT_LUNGS,2*REM)
. = 1
..()
@@ -649,6 +652,45 @@
mytray.adjustWater(-round(chems.get_reagent_amount(type) * 0.5))
mytray.adjustWeeds(-rand(1,3))
+/datum/reagent/chlorine/expose_obj(obj/exposed_object, reac_volume)
+ if((!exposed_object) || (!reac_volume))
+ return 0
+ var/temp = holder ? holder.chem_temp : T20C
+ exposed_object.atmos_spawn_air("cl2=[reac_volume/2];TEMP=[temp]")
+
+/datum/reagent/chlorine/expose_turf(turf/open/exposed_turf, reac_volume)
+ if(istype(exposed_turf))
+ var/temp = holder ? holder.chem_temp : T20C
+ exposed_turf.atmos_spawn_air("cl2=[reac_volume/2];TEMP=[temp]")
+ return
+
+/datum/reagent/hydrogen_chloride
+ name = "Hydrogen Chloride"
+ description = "A colorless gas that turns into hydrochloric acid in the presence of water."
+ reagent_state = GAS
+ metabolization_rate = REAGENTS_METABOLISM * 0.5
+ color = "#f4ffe0"
+ taste_description = "acid"
+
+/datum/reagent/hydrogen_chloride/on_mob_life(mob/living/carbon/exposed_mob)
+ exposed_mob.take_bodypart_damage(0, 2*REM, 0, 0)
+ exposed_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS,1*REM)
+ exposed_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH,1*REM)
+ . = 1
+ ..()
+
+/datum/reagent/hydrogen_chloride/expose_obj(obj/exposed_object, reac_volume)
+ if((!exposed_object) || (!reac_volume))
+ return 0
+ var/temp = holder ? holder.chem_temp : T20C
+ exposed_object.atmos_spawn_air("hcl=[reac_volume/2];TEMP=[temp]")
+
+/datum/reagent/hydrogen_chloride/expose_turf(turf/open/exposed_turf, reac_volume)
+ if(istype(exposed_turf))
+ var/temp = holder ? holder.chem_temp : T20C
+ exposed_turf.atmos_spawn_air("hcl=[reac_volume/2];TEMP=[temp]")
+ return
+
/datum/reagent/fluorine
name = "Fluorine"
description = "A comically-reactive chemical element. The universe does not want this stuff to exist in this form in the slightest."
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index 05ca5131e0f9..f6af39b201c0 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -284,6 +284,38 @@
breath.adjust_moles(GAS_FREON, -gas_breathed)
+ // Chlorine
+ var/chlorine_pp = PP(breath,GAS_CHLORINE)
+ if (prob(chlorine_pp))
+ to_chat(H, "Your lungs feel awful!")
+ if (chlorine_pp >40)
+ H.emote("gasp")
+ H.adjustFireLoss(5)
+ if (prob(chlorine_pp/2))
+ to_chat(H, "Your throat closes up!")
+ H.silent = max(H.silent, 3)
+ else
+ H.adjustFireLoss(round(chlorine_pp/8))
+ gas_breathed = breath.get_moles(GAS_CHLORINE)
+ if (gas_breathed > gas_stimulation_min)
+ H.reagents.add_reagent(/datum/reagent/chlorine,1)
+
+ breath.adjust_moles(GAS_CHLORINE, -gas_breathed)
+ // Hydrogen Chloride
+ var/hydrogen_chloride_pp = PP(breath,GAS_HYDROGEN_CHLORIDE)
+ if (prob(hydrogen_chloride_pp))
+ to_chat(H, "Your lungs feel terrible!")
+ if (hydrogen_chloride_pp >20)
+ H.emote("gasp")
+ H.adjustFireLoss(10)
+ if (prob(hydrogen_chloride_pp/2))
+ to_chat(H, "Your throat closes up!")
+ H.silent = max(H.silent, 3)
+ else
+ H.adjustFireLoss(round(hydrogen_chloride_pp/4))
+ if (gas_breathed > gas_stimulation_min)
+ H.reagents.add_reagent(/datum/reagent/hydrogen_chloride)
+
// Stimulum
gas_breathed = PP(breath,GAS_STIMULUM)
if (gas_breathed > gas_stimulation_min)
diff --git a/icons/obj/nutanks.dmi b/icons/obj/nutanks.dmi
index 327bafa81706..94e4c7288512 100644
Binary files a/icons/obj/nutanks.dmi and b/icons/obj/nutanks.dmi differ
diff --git a/tgui/packages/tgui/constants.ts b/tgui/packages/tgui/constants.ts
index d11d5bdec83f..e17958e787f3 100644
--- a/tgui/packages/tgui/constants.ts
+++ b/tgui/packages/tgui/constants.ts
@@ -294,6 +294,20 @@ const GASES = [
label: 'Nitrium',
color: 'brown',
},
+ {
+ id: 'cl2',
+ path: '/datum/gas/cl2',
+ name: 'Chlorine',
+ label: 'Clâ‚‚',
+ color: 'yellow',
+ },
+ {
+ id: 'hcl',
+ path: '/datum/gas/hcl',
+ name: 'Hydrogen Chloride',
+ label: 'HCl',
+ color: 'greenyellow',
+ },
] as const;
// Returns gas label based on gasId