From fcbeefe7afed7259847eb0924d61632007e902c8 Mon Sep 17 00:00:00 2001 From: Geeves Date: Sat, 24 Apr 2021 03:22:50 +0200 Subject: [PATCH] Infiltration Kit & Overpressure Protection (#11674) --- aurorastation.dme | 1 + code/__defines/items_clothing.dm | 22 +++-- code/datums/uplink/devices and tools.dm | 6 ++ code/game/objects/items.dm | 17 ++++ code/modules/clothing/head/hardhat.dm | 1 + code/modules/clothing/sets/infiltrator.dm | 75 ++++++++++++++++++ code/modules/clothing/spacesuits/breaches.dm | 5 ++ .../clothing/spacesuits/miscellaneous.dm | 7 +- code/modules/clothing/spacesuits/rig/rig.dm | 17 +++- .../clothing/spacesuits/rig/rig_pieces.dm | 2 +- .../clothing/spacesuits/rig/suits/light.dm | 5 +- .../clothing/spacesuits/rig/suits/station.dm | 4 + .../modules/clothing/spacesuits/spacesuits.dm | 8 +- .../clothing/spacesuits/void/station.dm | 6 +- code/modules/clothing/spacesuits/void/void.dm | 2 + code/modules/clothing/suits/armor.dm | 4 +- code/modules/clothing/suits/utility.dm | 7 +- code/modules/mob/inventory.dm | 6 ++ .../mob/living/carbon/carbon_defense.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 29 ++++--- code/modules/mob/mob.dm | 1 + .../geeves-infiltration_slipsuit.yml | 7 ++ icons/clothing/kit/infiltrator.dmi | Bin 0 -> 6884 bytes 24 files changed, 193 insertions(+), 43 deletions(-) create mode 100644 code/modules/clothing/sets/infiltrator.dm create mode 100644 html/changelogs/geeves-infiltration_slipsuit.yml create mode 100644 icons/clothing/kit/infiltrator.dmi diff --git a/aurorastation.dme b/aurorastation.dme index 975cc1e88c8..87b09b2bbfc 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1425,6 +1425,7 @@ #include "code\modules\clothing\rings\rings.dm" #include "code\modules\clothing\sets\acting_captain.dm" #include "code\modules\clothing\sets\captain.dm" +#include "code\modules\clothing\sets\infiltrator.dm" #include "code\modules\clothing\sets\laser_tag.dm" #include "code\modules\clothing\shoes\colour.dm" #include "code\modules\clothing\shoes\jobs.dm" diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index 3e3176bbea5..6639cb065cb 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -34,14 +34,13 @@ //Flags for items (equipment) #define THICKMATERIAL 0x1 // Prevents syringes, parapens and hyposprays if equiped to slot_suit or slot_head. -#define STOPPRESSUREDAMAGE 0x2 // Counts towards pressure protection. Note that like temperature protection, body_parts_covered is considered here as well. -#define AIRTIGHT 0x4 // Functions with internals. -#define NOSLIP 0x8 // Prevents from slipping on wet floors, in space, etc. -#define BLOCK_GAS_SMOKE_EFFECT 0x10 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) -#define FLEXIBLEMATERIAL 0x20 // At the moment, masks with this flag will not prevent eating even if they are covering your face. -#define SOUNDPROTECTION 0x40 // whether wearing this item will protect you from loud noises such as flashbangs | this only works for ear slots or the head slot -#define LIGHTSTEP 0x80 // When applied to footwear, this makes it so that they don't trigger things like landmines and mouse traps -#define INJECTIONPORT 0x100 // Allows syringes and hyposprays to inject, even if the material is thick +#define AIRTIGHT 0x2 // Functions with internals. +#define NOSLIP 0x4 // Prevents from slipping on wet floors, in space, etc. +#define BLOCK_GAS_SMOKE_EFFECT 0x8 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) +#define FLEXIBLEMATERIAL 0x10 // At the moment, masks with this flag will not prevent eating even if they are covering your face. +#define SOUNDPROTECTION 0x20 // whether wearing this item will protect you from loud noises such as flashbangs | this only works for ear slots or the head slot +#define LIGHTSTEP 0x40 // When applied to footwear, this makes it so that they don't trigger things like landmines and mouse traps +#define INJECTIONPORT 0x80 // Allows syringes and hyposprays to inject, even if the material is thick // Flags for pass_flags. #define PASSTABLE 0x1 @@ -171,6 +170,13 @@ #define WARNING_LOW_PRESSURE 50 // This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) #define HAZARD_LOW_PRESSURE 20 // This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) +#define FIRESUIT_MAX_PRESSURE 20 * ONE_ATMOSPHERE // Firesuits and atmos voidsuits +#define RIG_MAX_PRESSURE 10 * ONE_ATMOSPHERE // Rigs +#define LIGHT_RIG_MAX_PRESSURE 5 * ONE_ATMOSPHERE // Rigs +#define ENG_VOIDSUIT_MAX_PRESSURE 10 * ONE_ATMOSPHERE +#define VOIDSUIT_MAX_PRESSURE 5 * ONE_ATMOSPHERE +#define SPACE_SUIT_MAX_PRESSURE 2 * ONE_ATMOSPHERE + #define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 // This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. #define BODYTEMP_AUTORECOVERY_DIVISOR 12 // This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. #define BODYTEMP_AUTORECOVERY_MINIMUM 1 // Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm index 0fb04b8f0ad..0d9731a93c8 100644 --- a/code/datums/uplink/devices and tools.dm +++ b/code/datums/uplink/devices and tools.dm @@ -87,6 +87,12 @@ item_cost = 2 path = /obj/item/storage/box/syndie_kit/space +/datum/uplink_item/item/tools/infiltration_kit + name = "Infiltration Kit" + desc = "A large infiltration case containing an undersuit, a mask, gloves, and shoes. It will protect you against the vacuum of space and two atmospheres of overpressure." + item_cost = 2 + path = /obj/item/storage/toolbox/infiltration + /datum/uplink_item/item/tools/thermal name = "Thermal Imaging Glasses" item_cost = 2 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 47c8d508711..cb4de247051 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -22,6 +22,8 @@ var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags + var/max_pressure_protection // Set this variable if the item protects its wearer against high pressures below an upper bound. Keep at null to disable protection. + var/min_pressure_protection // Set this variable if the item protects its wearer against low pressures above a lower bound. Keep at null to disable protection. 0 represents protection against hard vacuum. var/datum/action/item_action/action var/action_button_name //It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button. @@ -920,3 +922,18 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. if(isFlameSource()) return TRUE return FALSE + +/obj/item/proc/get_pressure_weakness(pressure, zone) + . = 1 + if(pressure > ONE_ATMOSPHERE) + if(max_pressure_protection != null) + if(max_pressure_protection < pressure) + return min(1, round((pressure - max_pressure_protection) / max_pressure_protection, 0.01)) + else + return 0 + if(pressure < ONE_ATMOSPHERE) + if(min_pressure_protection != null) + if(min_pressure_protection > pressure) + return min(1, round((min_pressure_protection - pressure) / min_pressure_protection, 0.01)) + else + return 0 diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 24d1c0df1f3..4a856b14528 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -17,6 +17,7 @@ flags_inv = 0 w_class = ITEMSIZE_NORMAL siemens_coefficient = 0.9 + max_pressure_protection = FIRESUIT_MAX_PRESSURE light_wedge = LIGHT_WIDE drop_sound = 'sound/items/drop/helm.ogg' pickup_sound = 'sound/items/pickup/helm.ogg' diff --git a/code/modules/clothing/sets/infiltrator.dm b/code/modules/clothing/sets/infiltrator.dm new file mode 100644 index 00000000000..8a37caad2a5 --- /dev/null +++ b/code/modules/clothing/sets/infiltrator.dm @@ -0,0 +1,75 @@ +/obj/item/clothing/mask/breath/infiltrator + name = "infiltration balaclava" + desc = "A close-fitting airtight balaclava that can be connected to an air supply." + icon = 'icons/clothing/kit/infiltrator.dmi' + icon_state = "mask" + item_state = "mask" + icon_auto_adapt = TRUE + icon_supported_species_tags = list("una", "taj") + contained_sprite = TRUE + adjustable = FALSE + item_flags = THICKMATERIAL | INJECTIONPORT | AIRTIGHT + flags_inv = HIDEFACE|BLOCKHAIR + body_parts_covered = HEAD|FACE|EYES + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE + min_pressure_protection = 0 + +/obj/item/clothing/under/infiltrator + name = "infiltration suit" + desc = "A tight undersuit with thin pieces of armor bolted to it. It's airtight." + icon = 'icons/clothing/kit/infiltrator.dmi' + icon_state = "uniform" + item_state = "uniform" + contained_sprite = TRUE + item_flags = THICKMATERIAL | INJECTIONPORT | AIRTIGHT + armor = list( + melee = ARMOR_MELEE_SMALL, + bullet = ARMOR_BALLISTIC_SMALL, + laser = ARMOR_LASER_SMALL + ) + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE + min_pressure_protection = 0 + +/obj/item/clothing/gloves/infiltrator + name = "infiltration gloves" + desc = "Tight insulated gloves with interwoven self-cleaning material. It's airtight." + icon = 'icons/clothing/kit/infiltrator.dmi' + icon_state = "gloves" + item_state = "gloves" + contained_sprite = TRUE + siemens_coefficient = 0 + permeability_coefficient = 0.05 + germ_level = 0 + fingerprint_chance = 0 + item_flags = THICKMATERIAL | INJECTIONPORT | AIRTIGHT + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE + min_pressure_protection = 0 + species_restricted = null + +/obj/item/clothing/shoes/infiltrator + name = "infiltration shoes" + desc = "Tight shoes with in-built Silent-Soles. It's airtight." + icon = 'icons/clothing/kit/infiltrator.dmi' + icon_state = "shoes" + item_state = "shoes" + contained_sprite = TRUE + silent = TRUE + item_flags = THICKMATERIAL | INJECTIONPORT | AIRTIGHT + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE + min_pressure_protection = 0 + species_restricted = null + +/obj/item/storage/toolbox/infiltration + name = "infiltration case" + desc = "A case with an ominous red \"S\" painted on it. It seems pretty hefty." + icon = 'icons/clothing/kit/infiltrator.dmi' + icon_state = "case" + item_state = "case" + contained_sprite = TRUE + item_icons = null + starts_with = list( + /obj/item/clothing/mask/breath/infiltrator = 1, + /obj/item/clothing/under/infiltrator = 1, + /obj/item/clothing/gloves/infiltrator = 1, + /obj/item/clothing/shoes/infiltrator = 1 + ) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 75dec914f42..2f9e6c3eb88 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -228,3 +228,8 @@ var/global/list/breach_burn_descriptors = list( if(can_breach && breaches && breaches.len) for(var/datum/breach/B in breaches) to_chat(user, "It has \a [B.descriptor].") + +/obj/item/clothing/suit/space/get_pressure_weakness(pressure) + . = ..() + if(can_breach && damage) + . = min(1, . + damage * 0.1) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 550291d0d1a..bdfcb04f46c 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -17,7 +17,8 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_RESISTANT ) - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + max_pressure_protection = FIRESUIT_MAX_PRESSURE + min_pressure_protection = 0 flags_inv = BLOCKHAIR siemens_coefficient = 0.6 @@ -34,7 +35,6 @@ bullet = ARMOR_BALLISTIC_MINOR, laser = ARMOR_LASER_MINOR ) - item_flags = STOPPRESSUREDAMAGE flags_inv = BLOCKHAIR siemens_coefficient = 0.9 @@ -44,7 +44,6 @@ desc = "Ho ho ho. Merrry X-mas!" icon_state = "santahat" item_state = "santahat" - item_flags = STOPPRESSUREDAMAGE flags_inv = BLOCKHAIR body_parts_covered = HEAD @@ -54,7 +53,6 @@ icon_state = "santa" item_state = "santa" slowdown = 0 - item_flags = STOPPRESSUREDAMAGE allowed = list(/obj/item) //for stuffing exta special presents //Space pirate outfit @@ -72,7 +70,6 @@ bio = ARMOR_BIO_SMALL, rad = ARMOR_RAD_MINOR ) - item_flags = STOPPRESSUREDAMAGE flags_inv = BLOCKHAIR body_parts_covered = 0 siemens_coefficient = 0.4 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 210b221e697..835f09b985d 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -27,6 +27,9 @@ ) min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + max_pressure_protection = RIG_MAX_PRESSURE + min_pressure_protection = 0 + siemens_coefficient = 0.35 permeability_coefficient = 0.1 unacidable = 1 @@ -86,7 +89,7 @@ var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this. var/vision_restriction = TINT_NONE var/offline_vision_restriction = TINT_HEAVY - var/airtight = 1 //If set, will adjust AIRTIGHT and STOPPRESSUREDAMAGE flags on components. Otherwise it should leave them untouched. + var/airtight = 1 //If set, will adjust the AIRTIGHT flag on components. Otherwise it should leave them untouched. var/emp_protection = 0 @@ -210,7 +213,9 @@ if(!piece) continue piece.icon_state = "[initial(icon_state)]" if(airtight) - piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT) + piece.max_pressure_protection = initial(piece.max_pressure_protection) + piece.min_pressure_protection = initial(piece.min_pressure_protection) + piece.item_flags &= ~AIRTIGHT update_icon(1) /obj/item/rig/proc/toggle_seals(var/mob/initiator,var/instant) @@ -341,9 +346,13 @@ /obj/item/rig/proc/update_component_sealed() for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(canremove) - piece.item_flags &= ~(STOPPRESSUREDAMAGE|AIRTIGHT) + piece.max_pressure_protection = initial(piece.max_pressure_protection) + piece.min_pressure_protection = initial(piece.min_pressure_protection) + piece.item_flags &= ~AIRTIGHT else - piece.item_flags |= (STOPPRESSUREDAMAGE|AIRTIGHT) + piece.max_pressure_protection = max_pressure_protection + piece.min_pressure_protection = min_pressure_protection + piece.item_flags |= AIRTIGHT update_icon(1) /obj/item/rig/process() diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index 77ac4d5d91e..eb95e3895bf 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -57,7 +57,7 @@ heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEJUMPSUIT|HIDETAIL - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT + item_flags = THICKMATERIAL|AIRTIGHT slowdown = 0 //will reach 10 breach damage after 25 laser carbine blasts, 3 revolver hits, or ~1 PTR hit. Completely immune to smg or sts hits. breach_threshold = 38 diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index c8c9071f20e..7cd9efeb591 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -14,9 +14,11 @@ ) emp_protection = 10 slowdown = 0 - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL offline_slowdown = 0 offline_vision_restriction = 0 + max_pressure_protection = LIGHT_RIG_MAX_PRESSURE + min_pressure_protection = 0 chest_type = /obj/item/clothing/suit/space/rig/light helm_type = /obj/item/clothing/head/helmet/space/rig/light @@ -240,7 +242,6 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_SHIELDED ) - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL slowdown = -1 offline_slowdown = 0 airtight = 1 diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 7a7fd7b9311..da7841deaed 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -79,6 +79,8 @@ offline_slowdown = 7 offline_vision_restriction = TINT_HEAVY emp_protection = -20 + max_pressure_protection = FIRESUIT_MAX_PRESSURE + min_pressure_protection = 0 helm_type = /obj/item/clothing/head/helmet/space/rig/industrial chest_type = /obj/item/clothing/suit/space/rig/industrial @@ -173,6 +175,8 @@ offline_slowdown = 3 offline_vision_restriction = 0 max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE / 1.5 // Good against fires, but not as good as a proper firesuit / atmos voidsuit + max_pressure_protection = FIRESUIT_MAX_PRESSURE + min_pressure_protection = 0 helm_type = /obj/item/clothing/head/helmet/space/rig/ce glove_type = /obj/item/clothing/gloves/rig/ce diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index ce7e2273b9b..cfeb344b6fb 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -6,7 +6,7 @@ name = "space helmet" icon_state = "space" desc = "A special helmet designed for work in a hazardous, low-pressure environment." - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | INJECTIONPORT | AIRTIGHT + item_flags = THICKMATERIAL | INJECTIONPORT | AIRTIGHT item_state_slots = list( slot_l_hand_str = "s_helmet", slot_r_hand_str = "s_helmet" @@ -20,6 +20,8 @@ body_parts_covered = HEAD|FACE|EYES cold_protection = HEAD min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE + min_pressure_protection = 0 + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE siemens_coefficient = 0.5 species_restricted = list("exclude",BODYTYPE_DIONA,BODYTYPE_GOLEM) flash_protection = FLASH_PROTECTION_MAJOR @@ -40,7 +42,7 @@ w_class = ITEMSIZE_LARGE//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - item_flags = STOPPRESSUREDAMAGE|THICKMATERIAL|INJECTIONPORT + item_flags = THICKMATERIAL|INJECTIONPORT body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/device/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit) slowdown = 3 @@ -51,6 +53,8 @@ flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE + min_pressure_protection = 0 + max_pressure_protection = SPACE_SUIT_MAX_PRESSURE siemens_coefficient = 0.5 species_restricted = list("exclude",BODYTYPE_DIONA,BODYTYPE_GOLEM) diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 8538f7eee0f..e363728e30f 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -16,6 +16,7 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_RESISTANT ) + max_pressure_protection = ENG_VOIDSUIT_MAX_PRESSURE light_overlay = "helmet_light_dual_low" brightness_on = 6 @@ -37,6 +38,7 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_RESISTANT ) + max_pressure_protection = ENG_VOIDSUIT_MAX_PRESSURE allowed = list(/obj/item/device/flashlight,/obj/item/tank,/obj/item/device/suit_cooling_unit,/obj/item/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/pickaxe,/obj/item/material/twohanded/fireaxe,/obj/item/rfd/construction,/obj/item/storage/bag/inflatable) //Mining rig @@ -172,6 +174,7 @@ rad = ARMOR_RAD_SMALL ) max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 10000 // It is a suit designed for fire, enclosed + max_pressure_protection = FIRESUIT_MAX_PRESSURE light_overlay = "helmet_light_dual_low" brightness_on = 6 @@ -192,6 +195,7 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_SMALL ) + max_pressure_protection = FIRESUIT_MAX_PRESSURE allowed = list(/obj/item/device/flashlight,/obj/item/tank,/obj/item/device/suit_cooling_unit,/obj/item/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/pickaxe,/obj/item/material/twohanded/fireaxe,/obj/item/rfd/construction,/obj/item/storage/bag/inflatable) max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE + 10000 // It is a suit designed for fire, enclosed @@ -259,4 +263,4 @@ bomb = ARMOR_BOMB_PADDED, bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_RESISTANT - ) \ No newline at end of file + ) diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index 638ade5ea5d..c53bff8310d 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -15,6 +15,8 @@ rad = ARMOR_RAD_MINOR ) max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + max_pressure_protection = VOIDSUIT_MAX_PRESSURE + min_pressure_protection = 0 siemens_coefficient = 0.5 //Species-specific stuff. diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 71af76981a9..0ebdbbb1f97 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -106,7 +106,7 @@ item_state = "swat_suit" gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL + item_flags = THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS allowed = list(/obj/item/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/handcuffs,/obj/item/tank/emergency_oxygen) slowdown = 1 @@ -119,6 +119,8 @@ bio = ARMOR_BIO_SHIELDED, rad = ARMOR_RAD_SMALL ) + max_pressure_protection = FIRESUIT_MAX_PRESSURE + min_pressure_protection = 0 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 7daa634b93f..7087ddc81f4 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -22,6 +22,7 @@ allowed = list(/obj/item/device/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/extinguisher) slowdown = 1.0 flags_inv = HIDEWRISTS|HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL + max_pressure_protection = FIRESUIT_MAX_PRESSURE heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS @@ -58,7 +59,7 @@ desc = "Use in case of bomb." icon_state = "bombsuit" w_class = ITEMSIZE_HUGE//Too large to fit in a backpack - item_flags = STOPPRESSUREDAMAGE|THICKMATERIAL|BLOCK_GAS_SMOKE_EFFECT + item_flags = THICKMATERIAL|BLOCK_GAS_SMOKE_EFFECT armor = list( melee = ARMOR_MELEE_VERY_HIGH, bullet = ARMOR_BALLISTIC_MINOR, @@ -66,6 +67,7 @@ energy = ARMOR_ENERGY_RESISTANT, bomb = ARMOR_BOMB_SHIELDED ) + max_pressure_protection = FIRESUIT_MAX_PRESSURE siemens_coefficient = 0.1 flags_inv = HIDEMASK|HIDEEARS|HIDEEYES body_parts_covered = HEAD|FACE|EYES @@ -95,12 +97,13 @@ bomb = ARMOR_BOMB_SHIELDED ) siemens_coefficient = 0.1 - item_flags = STOPPRESSUREDAMAGE|THICKMATERIAL + item_flags = THICKMATERIAL flags_inv = HIDEJUMPSUIT|HIDETAIL heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + max_pressure_protection = FIRESUIT_MAX_PRESSURE siemens_coefficient = 0 var/mob/living/carbon/human/wearer = null var/suit_temp = T20C diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index ae9123dfbce..cc181becf5d 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -399,6 +399,12 @@ var/list/slot_equipment_priority = list( \ drop_from_inventory(entry) qdel(entry) +/mob/proc/get_covering_equipped_items(var/body_parts) + . = list() + for(var/entry in get_equipped_items()) + var/obj/item/I = entry + if(I.body_parts_covered & body_parts) + . += I /mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE) var/datum/outfit/O = null diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 514316f5c89..12e394b3f55 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -145,7 +145,7 @@ var/damage_mod = 1 //presumably, if they are wearing a helmet that stops pressure effects, then it probably covers the throat as well var/obj/item/clothing/head/helmet = get_equipped_item(slot_head) - if(istype(helmet) && (helmet.body_parts_covered & HEAD) && (helmet.flags & STOPPRESSUREDAMAGE)) + if(istype(helmet) && (helmet.body_parts_covered & HEAD) && (helmet.min_pressure_protection == 0)) var/datum/component/armor/armor_component = helmet.GetComponent(/datum/component/armor) if(armor_component) damage_mod -= armor_component.get_blocked(BRUTE, damage_flags, W.armor_penetration, W.force*1.5) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c830abcc55a..ca99e8fe2d0 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -149,7 +149,7 @@ emp_act /mob/living/carbon/human/proc/check_head_airtight_coverage() var/list/clothing = list(head, wear_mask, wear_suit) for(var/obj/item/clothing/C in clothing) - if((C.body_parts_covered & HEAD) && (C.item_flags & (AIRTIGHT|STOPPRESSUREDAMAGE))) + if((C.body_parts_covered & HEAD) && (C.item_flags & (AIRTIGHT))) return TRUE return FALSE diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0856ba1f678..32fc04e570e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -104,22 +104,21 @@ if(!InStasis()) ..() -// Calculate how vulnerable the human is to under- and overpressure. -// Returns 0 (equals 0 %) if sealed in an undamaged suit, 1 if unprotected (equals 100%). +// Calculate how vulnerable the human is to the current pressure. +// Returns 0 (equals 0 %) if sealed in an undamaged suit that's rated for the pressure, 1 if unprotected (equals 100%). // Suitdamage can modifiy this in 10% steps. -/mob/living/carbon/human/get_pressure_weakness() - var/pressure_adjustment_coefficient = 1 // Assume no protection at first. - - if(wear_suit && (wear_suit.item_flags & STOPPRESSUREDAMAGE) && head && (head.item_flags & STOPPRESSUREDAMAGE)) // Complete set of pressure-proof suit worn, assume fully sealed. - pressure_adjustment_coefficient = 0 - - // Handles breaches in your space suit. 10 suit damage equals a 100% loss of pressure protection. - if(istype(wear_suit,/obj/item/clothing/suit/space)) - var/obj/item/clothing/suit/space/S = wear_suit - if(S.can_breach && S.damage) - pressure_adjustment_coefficient += S.damage * 0.1 - - pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) // So it isn't less than 0 or larger than 1. +/mob/living/carbon/human/get_pressure_weakness(pressure) + var/pressure_adjustment_coefficient = 0 + var/list/zones = list(HEAD, UPPER_TORSO, LOWER_TORSO, LEGS, FEET, ARMS, HANDS) + for(var/zone in zones) + var/list/covers = get_covering_equipped_items(zone) + var/zone_exposure = 1 + for(var/obj/item/clothing/C in covers) + zone_exposure = min(zone_exposure, C.get_pressure_weakness(pressure,zone)) + if(zone_exposure >= 1) + return 1 + pressure_adjustment_coefficient = max(pressure_adjustment_coefficient, zone_exposure) + pressure_adjustment_coefficient = Clamp(pressure_adjustment_coefficient, 0, 1) // So it isn't less than 0 or larger than 1. return pressure_adjustment_coefficient diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 307be9f0f0e..ff57939d5e3 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1089,6 +1089,7 @@ /mob/proc/get_pressure_weakness() return 1 + /mob/living/proc/flash_strong_pain() return diff --git a/html/changelogs/geeves-infiltration_slipsuit.yml b/html/changelogs/geeves-infiltration_slipsuit.yml new file mode 100644 index 00000000000..2addfbe4738 --- /dev/null +++ b/html/changelogs/geeves-infiltration_slipsuit.yml @@ -0,0 +1,7 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Added an infiltration kit to the Devices and Tools uplink. It spawns a case containing a mask, a uniform, gloves, and shoes, capable of protecting you from the vacuum of space, as well as two atmospheres of overpressure." + - rscadd: "Ported max and min pressure tolerances for items and clothing, meaning that certain gear will now protect better from overpressure, such as atmos voidsuits, firesuits, bomb suits, and to a lesser extent, engineering voidsuits." \ No newline at end of file diff --git a/icons/clothing/kit/infiltrator.dmi b/icons/clothing/kit/infiltrator.dmi new file mode 100644 index 0000000000000000000000000000000000000000..56ca57c101f52fbb0780969c0b94b2ba411ac523 GIT binary patch literal 6884 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 literal 0 HcmV?d00001