diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 32a9a4454f6..d3d339cf546 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -34,6 +34,8 @@
#define AIRLOCK_INTEGRITY_N 300 // Normal airlock integrity
#define AIRLOCK_INTEGRITY_MULTIPLIER 1.5 // How much reinforced doors health increases
+/// How much extra health airlocks get when braced with a seal
+#define AIRLOCK_SEAL_MULTIPLIER 2
#define AIRLOCK_DAMAGE_DEFLECTION_N 21 // Normal airlock damage deflection
#define AIRLOCK_DAMAGE_DEFLECTION_R 30 // Reinforced airlock damage deflection
@@ -70,6 +72,8 @@
var/obj/item/electronics/airlock/electronics
COOLDOWN_DECLARE(shockCooldown)
var/obj/item/note //Any papers pinned to the airlock
+ /// The seal on the airlock
+ var/obj/item/seal
var/detonated = FALSE
var/abandoned = FALSE
var/doorOpen = 'sound/machines/airlock.ogg'
@@ -294,6 +298,7 @@
for(var/obj/machinery/door_buttons/D in GLOB.machines)
D.removeMe(src)
QDEL_NULL(note)
+ QDEL_NULL(seal)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.remove_from_hud(src)
return ..()
@@ -302,6 +307,9 @@
if(A == note)
note = null
update_icon()
+ if(A == seal)
+ seal = null
+ update_icon()
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
@@ -431,6 +439,7 @@
var/mutable_appearance/damag_overlay
var/mutable_appearance/sparks_overlay
var/mutable_appearance/note_overlay
+ var/mutable_appearance/seal_overlay
var/notetype = note_type()
switch(state)
@@ -447,6 +456,8 @@
panel_overlay = get_airlock_overlay("panel_closed", overlays_file)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
+ if(seal)
+ seal_overlay = get_airlock_overlay("sealed", overlays_file)
if(obj_integrity < integrity_failure * max_integrity)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file)
else if(obj_integrity < (0.75 * max_integrity))
@@ -478,6 +489,8 @@
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
+ if(seal)
+ seal_overlay = get_airlock_overlay("sealed", overlays_file)
lights_overlay = get_airlock_overlay("lights_denied", overlays_file)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
@@ -500,6 +513,8 @@
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
+ if(seal)
+ seal_overlay = get_airlock_overlay("sealed", overlays_file)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
@@ -560,6 +575,7 @@
add_overlay(sparks_overlay)
add_overlay(damag_overlay)
add_overlay(note_overlay)
+ add_overlay(seal_overlay)
check_unres()
/proc/get_airlock_overlay(icon_state, icon_file)
@@ -618,7 +634,8 @@
else
. += "There's a [note.name] pinned to the front..."
. += note.examine(user)
-
+ if(seal)
+ . += "It's been braced with a pneumatic seal."
if(panel_open)
switch(security_level)
if(AIRLOCK_SECURITY_NONE)
@@ -813,7 +830,7 @@
user.visible_message("[user] reinforces \the [src] with plasteel.",
"You reinforce \the [src] with plasteel.")
security_level = AIRLOCK_SECURITY_PLASTEEL
- modify_max_integrity(normal_integrity * AIRLOCK_INTEGRITY_MULTIPLIER)
+ modify_max_integrity(max_integrity * AIRLOCK_INTEGRITY_MULTIPLIER)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
update_icon()
return
@@ -844,7 +861,7 @@
user.visible_message("[user] remove \the [src]'s shielding.",
"You remove \the [src]'s inner shielding.")
security_level = AIRLOCK_SECURITY_NONE
- modify_max_integrity(normal_integrity)
+ modify_max_integrity(max_integrity / AIRLOCK_INTEGRITY_MULTIPLIER)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_N
spawn_atom_to_turf(/obj/item/stack/sheet/plasteel, user.loc, 1)
update_icon()
@@ -922,6 +939,33 @@
cable.plugin(src, user)
else if(istype(C, /obj/item/airlock_painter))
change_paintjob(C, user)
+ else if(istype(C, /obj/item/door_seal)) //adding the seal
+ var/obj/item/door_seal/airlockseal = C
+ if(!density)
+ to_chat(user, "[src] must be closed before you can seal it!")
+ return
+ if(seal)
+ to_chat(user, "[src] has already been sealed!")
+ return
+ user.visible_message("[user] begins sealing [src].", "You begin sealing [src].")
+ playsound(src, 'sound/items/jaws_pry.ogg', 30, TRUE)
+ if(!do_after(user, airlockseal.seal_time, target = src))
+ return
+ if(!density)
+ to_chat(user, "[src] must be closed before you can seal it!")
+ return
+ if(seal)
+ to_chat(user, "[src] has already been sealed!")
+ return
+ if(!user.transferItemToLoc(airlockseal, src))
+ to_chat(user, "For some reason, you can't attach [airlockseal]!")
+ return
+ playsound(src, 'sound/machines/airlockforced.ogg', 30, TRUE)
+ user.visible_message("[user] finishes sealing [src].", "You finish sealing [src].")
+ seal = airlockseal
+ modify_max_integrity(max_integrity * AIRLOCK_SEAL_MULTIPLIER)
+ update_icon()
+
else if(istype(C, /obj/item/paper) || istype(C, /obj/item/photo))
if(note)
to_chat(user, "There's already something pinned to this airlock! Use wirecutters to remove it.")
@@ -938,6 +982,9 @@
/obj/machinery/door/airlock/try_to_weld(obj/item/weldingtool/W, mob/user)
if(!operating && density)
+ if(seal)
+ to_chat(user, "[src] is blocked by a seal!")
+ return
if(user.a_intent != INTENT_HELP)
if(!W.tool_start_check(user, amount=0))
return
@@ -968,6 +1015,36 @@
/obj/machinery/door/airlock/proc/weld_checks(obj/item/weldingtool/W, mob/user)
return !operating && density
+/**
+ * Used when attempting to remove a seal from an airlock
+ *
+ * Called when attacking an airlock with an empty hand, returns TRUE (there was a seal and we removed it, or failed to remove it)
+ * or FALSE (there was no seal)
+ * Arguments:
+ * * user - Whoever is attempting to remove the seal
+ */
+/obj/machinery/door/airlock/try_remove_seal(mob/living/user)
+ if(!seal)
+ return FALSE
+ var/obj/item/door_seal/airlockseal = seal
+ if(!ishuman(user))
+ to_chat(user, text("You don't have the dexterity to remove the seal!"))
+ return TRUE
+ user.visible_message("[user] begins removing the seal from [src].", "You begin removing [src]'s pneumatic seal.")
+ playsound(src, 'sound/machines/airlockforced.ogg', 30, TRUE)
+ if(!do_after(user, airlockseal.unseal_time, target = src))
+ return TRUE
+ if(!seal)
+ return TRUE
+ playsound(src, 'sound/items/jaws_pry.ogg', 30, TRUE)
+ airlockseal.forceMove(get_turf(user))
+ user.visible_message("[user] finishes removing the seal from [src].", "You finish removing [src]'s pneumatic seal.")
+ seal = null
+ modify_max_integrity(max_integrity / AIRLOCK_SEAL_MULTIPLIER)
+ update_icon()
+ return TRUE
+
+
/obj/machinery/door/airlock/try_to_crowbar(obj/item/I, mob/living/user, forced = FALSE)
if(I)
var/beingcrowbarred = (I.tool_behaviour == TOOL_CROWBAR)
@@ -977,6 +1054,9 @@
if(I.use_tool(src, user, 40, volume=100))
deconstruct(TRUE, user)
return
+ if(seal)
+ to_chat(user, "Remove the seal first!")
+ return
if(locked)
to_chat(user, "The airlock's bolts prevent it from being forced!")
return
@@ -1018,7 +1098,7 @@
/obj/machinery/door/airlock/open(forced=0)
- if( operating || welded || locked )
+ if( operating || welded || locked || seal )
return FALSE
if(!forced)
if(!hasPower() || wires.is_cut(WIRE_OPEN))
@@ -1060,7 +1140,7 @@
/obj/machinery/door/airlock/close(forced=0)
- if(operating || welded || locked)
+ if(operating || welded || locked || seal)
return
if(density)
return TRUE
@@ -1175,7 +1255,7 @@
return
if(!density) //Already open
return ..()
- if(locked || welded) //Extremely generic, as aliens only understand the basics of how airlocks work.
+ if(locked || welded || seal) //Extremely generic, as aliens only understand the basics of how airlocks work.
if(user.a_intent == INTENT_HARM)
return ..()
to_chat(user, "[src] refuses to budge!")
@@ -1294,6 +1374,9 @@
/obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
if(RCD_DECONSTRUCT)
+ if(seal)
+ to_chat(user, "[src]'s seal needs to be removed first.")
+ return FALSE
if(security_level != AIRLOCK_SECURITY_NONE)
to_chat(user, "[src]'s reinforcement needs to be removed first.")
return FALSE
@@ -1499,6 +1582,7 @@
#undef AIRLOCK_INTEGRITY_N
#undef AIRLOCK_INTEGRITY_MULTIPLIER
+#undef AIRLOCK_SEAL_MULTIPLIER
#undef AIRLOCK_DAMAGE_DEFLECTION_N
#undef AIRLOCK_DAMAGE_DEFLECTION_R
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 0c22882d217..fe92c587e52 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -41,6 +41,7 @@
var/safety_mode = FALSE ///Whether or not the airlock can be opened with bare hands while unpowered
var/can_crush = TRUE /// Whether or not the door can crush mobs.
+
/obj/machinery/door/examine(mob/user)
. = ..()
if(red_alert_access)
@@ -97,6 +98,17 @@
return TRUE
return FALSE
+/**
+ * Called when attempting to remove the seal from an airlock
+ *
+ * Here because we need to call it and return if there was a seal so we don't try to open the door
+ * or try its safety lock while it's sealed
+ * Arguments:
+ * * user - the mob attempting to remove the seal
+ */
+/obj/machinery/door/proc/try_remove_seal(mob/user)
+ return
+
/obj/machinery/door/Bumped(atom/movable/AM)
. = ..()
if(operating || (obj_flags & EMAGGED))
@@ -159,6 +171,8 @@
. = ..()
if(.)
return
+ if(try_remove_seal(user))
+ return
if(try_safety_unlock(user))
return
return try_to_activate_door(user)
diff --git a/code/game/objects/items/door_seal.dm b/code/game/objects/items/door_seal.dm
new file mode 100644
index 00000000000..66c6c0070bc
--- /dev/null
+++ b/code/game/objects/items/door_seal.dm
@@ -0,0 +1,25 @@
+/obj/item/door_seal
+ name = "pneumatic seal"
+ desc = "A brace used to seal and reinforce an airlock. Useful for making areas inaccessible to those without opposable thumbs."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "pneumatic_seal"
+ lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/items_righthand.dmi'
+ flags_1 = CONDUCT_1
+ resistance_flags = FIRE_PROOF | ACID_PROOF
+ force = 5
+ throwforce = 5
+ throw_speed = 2
+ throw_range = 1
+ w_class = WEIGHT_CLASS_BULKY
+ custom_materials = list(/datum/material/iron=5000,/datum/material/plasma=500)
+ /// how long the seal takes to place on the door
+ var/seal_time = 3 SECONDS
+ /// how long it takes to remove the seal from a door
+ var/unseal_time = 2 SECONDS
+
+/obj/item/door_seal/suicide_act(mob/user)
+ user.visible_message("[user] is sealing [user.p_them()]self off from the world with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
+ playsound(src, 'sound/items/jaws_pry.ogg', 30, TRUE)
+ return(BRUTELOSS)
+
diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm
index 5a39a9a9ede..ec7c217089e 100644
--- a/code/modules/research/designs/misc_designs.dm
+++ b/code/modules/research/designs/misc_designs.dm
@@ -324,6 +324,15 @@
build_path = /obj/item/bikehorn/rubberducky/plasticducky
category = list("Equipment")
+/datum/design/pneumatic_seal
+ name = "Pneumatic Seal"
+ desc = "A heavy brace used to seal doors. Useful for keeping out people without the dexterity to remove it."
+ id = "pneumatic_seal"
+ build_type = PROTOLATHE
+ materials = list(/datum/material/iron = 20000, /datum/material/plasma = 10000)
+ build_path = /obj/item/door_seal
+ category = list("Equipment")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SECURITY
/////////////////////////////////////////
////////////Janitor Designs//////////////
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 0e07b819bc7..dceedf4bf98 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -139,7 +139,7 @@
design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "w-recycler" , "emitter", "high_cell", "adv_matter_bin", "scanner_gate",
"atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "welding_goggles", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod",
"apc_control", "cell_charger", "power control", "airlock_board", "firelock_board", "airalarm_electronics", "firealarm_electronics", "cell_charger", "stack_console", "stack_machine",
- "oxygen_tank", "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "electrolyzer", "adv_electrolite")
+ "oxygen_tank", "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "electrolyzer", "adv_electrolite", "pneumatic_seal")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500)
/datum/techweb_node/adv_engi
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 79819e6379a..62cde84497e 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 49c4b6d203f..639f12e8814 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/doors/airlocks/abductor/overlays.dmi b/icons/obj/doors/airlocks/abductor/overlays.dmi
index 6bc8aae620f..855414ca1e0 100644
Binary files a/icons/obj/doors/airlocks/abductor/overlays.dmi and b/icons/obj/doors/airlocks/abductor/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/centcom/overlays.dmi b/icons/obj/doors/airlocks/centcom/overlays.dmi
index 7ec3486053f..a608a7f2110 100644
Binary files a/icons/obj/doors/airlocks/centcom/overlays.dmi and b/icons/obj/doors/airlocks/centcom/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/clockwork/overlays.dmi b/icons/obj/doors/airlocks/clockwork/overlays.dmi
index b34b73fb4e4..c8c4854a117 100644
Binary files a/icons/obj/doors/airlocks/clockwork/overlays.dmi and b/icons/obj/doors/airlocks/clockwork/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/cult/runed/overlays.dmi b/icons/obj/doors/airlocks/cult/runed/overlays.dmi
index 19920538d9d..3bfe88f2df8 100644
Binary files a/icons/obj/doors/airlocks/cult/runed/overlays.dmi and b/icons/obj/doors/airlocks/cult/runed/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/cult/unruned/overlays.dmi b/icons/obj/doors/airlocks/cult/unruned/overlays.dmi
index 5fb77f2676c..2bcbbeafbf0 100644
Binary files a/icons/obj/doors/airlocks/cult/unruned/overlays.dmi and b/icons/obj/doors/airlocks/cult/unruned/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/external/overlays.dmi b/icons/obj/doors/airlocks/external/overlays.dmi
index 1dde58ab5af..0ecffb0aec6 100644
Binary files a/icons/obj/doors/airlocks/external/overlays.dmi and b/icons/obj/doors/airlocks/external/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/glass_large/overlays.dmi b/icons/obj/doors/airlocks/glass_large/overlays.dmi
index 04e7d7093ca..bc9cc86c107 100644
Binary files a/icons/obj/doors/airlocks/glass_large/overlays.dmi and b/icons/obj/doors/airlocks/glass_large/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/hatch/overlays.dmi b/icons/obj/doors/airlocks/hatch/overlays.dmi
index affcbbf2ce4..d3f21a5056f 100644
Binary files a/icons/obj/doors/airlocks/hatch/overlays.dmi and b/icons/obj/doors/airlocks/hatch/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/highsec/overlays.dmi b/icons/obj/doors/airlocks/highsec/overlays.dmi
index 2a6868c34b9..d0499112527 100644
Binary files a/icons/obj/doors/airlocks/highsec/overlays.dmi and b/icons/obj/doors/airlocks/highsec/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/shuttle/overlays.dmi b/icons/obj/doors/airlocks/shuttle/overlays.dmi
index 70df6102127..74472a3b549 100644
Binary files a/icons/obj/doors/airlocks/shuttle/overlays.dmi and b/icons/obj/doors/airlocks/shuttle/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/station/overlays.dmi b/icons/obj/doors/airlocks/station/overlays.dmi
index b0c5780695b..861170d9456 100644
Binary files a/icons/obj/doors/airlocks/station/overlays.dmi and b/icons/obj/doors/airlocks/station/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/station2/overlays.dmi b/icons/obj/doors/airlocks/station2/overlays.dmi
index 4cb389cbf2d..7665b485578 100644
Binary files a/icons/obj/doors/airlocks/station2/overlays.dmi and b/icons/obj/doors/airlocks/station2/overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/survival/survival_overlays.dmi b/icons/obj/doors/airlocks/survival/survival_overlays.dmi
index f8e62144cd8..8f12e9592ee 100644
Binary files a/icons/obj/doors/airlocks/survival/survival_overlays.dmi and b/icons/obj/doors/airlocks/survival/survival_overlays.dmi differ
diff --git a/icons/obj/doors/airlocks/vault/overlays.dmi b/icons/obj/doors/airlocks/vault/overlays.dmi
index f18346acf68..4197ced6fcb 100644
Binary files a/icons/obj/doors/airlocks/vault/overlays.dmi and b/icons/obj/doors/airlocks/vault/overlays.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 2dfa83f5dc2..ae3416570eb 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 2bd37083d55..12f990eac62 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -983,6 +983,7 @@
#include "code\game\objects\items\dice.dm"
#include "code\game\objects\items\dna_injector.dm"
#include "code\game\objects\items\documents.dm"
+#include "code\game\objects\items\door_seal.dm"
#include "code\game\objects\items\dualsaber.dm"
#include "code\game\objects\items\eightball.dm"
#include "code\game\objects\items\emags.dm"