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"