From 44a23181e6a371ec7df850ff5a65f44f52b07249 Mon Sep 17 00:00:00 2001 From: Chompstation Bot Date: Tue, 22 Jun 2021 02:48:57 +0000 Subject: [PATCH 1/2] Makes machinery destroyable by projectiles --- code/game/machinery/computer/computer.dm | 4 +- code/game/machinery/doors/airlock.dm | 3068 ++++++++++++++++++++++ code/game/machinery/machinery.dm | 90 +- code/modules/power/smes.dm | 3 +- sound/machines/machine_die_short.ogg | Bin 0 -> 23746 bytes 5 files changed, 3158 insertions(+), 7 deletions(-) create mode 100644 sound/machines/machine_die_short.ogg diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 110b70ab8c..956c3fe2d7 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -35,11 +35,11 @@ /obj/machinery/computer/ex_act(severity) switch(severity) if(1.0) - qdel(src) + fall_apart(severity) return if(2.0) if (prob(25)) - qdel(src) + fall_apart(severity) return if (prob(50)) for(var/x in verbs) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 28ea1c4816..0e1431e65c 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //VOREStation Edit - Redone a lot of airlock things: /* - Specific department maintenance doors @@ -1530,3 +1531,3070 @@ About the new airlock wires panel: qdel(src) return TRUE return FALSE +||||||| parent of 0051e96509... Merge pull request #10610 from VOREStation/Arokha/machinerybreak +//VOREStation Edit - Redone a lot of airlock things: +/* +- Specific department maintenance doors +- Named doors properly according to type +- Gave them default access levels with the access constants +- Improper'd all of the names in the new() +*/ + +/obj/machinery/door/airlock + name = "Airlock" + icon = 'icons/obj/doors/Doorint.dmi' + icon_state = "door_closed" + power_channel = ENVIRON + + explosion_resistance = 10 + blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime + + var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. + var/hackProof = 0 // if 1, this door can't be hacked by the AI + var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + var/main_power_lost_until = 0 //World time when main power is restored. + var/backup_power_lost_until = -1 //World time when backup power is restored. + var/has_beeped = 0 //If 1, will not beep on failed closing attempt. Resets when door closes. + var/spawnPowerRestoreRunning = 0 + var/welded = null + var/locked = 0 + var/lights = 1 // bolt lights show by default + var/aiDisabledIdScanner = 0 + var/aiHacking = 0 + var/obj/machinery/door/airlock/closeOther = null + var/closeOtherId = null + var/lockdownbyai = 0 + autoclose = 1 + var/assembly_type = /obj/structure/door_assembly + var/mineral = null + var/justzap = 0 + var/safe = 1 + normalspeed = 1 + var/obj/item/weapon/airlock_electronics/electronics = null + var/hasShocked = 0 //Prevents multiple shocks from happening + var/secured_wires = 0 + var/datum/wires/airlock/wires = null + + var/open_sound_powered = 'sound/machines/door/covert1o.ogg' + var/open_sound_unpowered = 'sound/machines/door/airlockforced.ogg' + var/close_sound_powered = 'sound/machines/door/covert1c.ogg' + var/legacy_open_powered = 'sound/machines/door/old_airlock.ogg' + var/legacy_close_powered = 'sound/machines/door/old_airlockclose.ogg' + var/department_open_powered = null + var/department_close_powered = null + var/denied_sound = 'sound/machines/deniedbeep.ogg' + var/bolt_up_sound = 'sound/machines/door/boltsup.ogg' + var/bolt_down_sound = 'sound/machines/door/boltsdown.ogg' + +/obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) + if(stat & (BROKEN|NOPOWER)) + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) + if(src.locked || src.welded) + visible_message("\The [user] begins breaking into \the [src] internals!") + user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. + if(do_after(user,10 SECONDS,src)) + src.locked = 0 + src.welded = 0 + update_icon() + open(1) + if(prob(25)) + src.shock(user, 100) + user.set_AI_busy(FALSE) + else if(src.density) + visible_message("\The [user] forces \the [src] open!") + open(1) + else + visible_message("\The [user] forces \the [src] closed!") + close(1) + else + visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") + return + ..() + +/obj/machinery/door/airlock/attack_alien(var/mob/user) //Familiar, right? Doors. -Mechoid + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/X = user + if(istype(X.species, /datum/species/xenos)) + if(src.locked || src.welded) + visible_message("\The [user] begins digging into \the [src] internals!") + src.do_animate("deny") + if(do_after(user,5 SECONDS,src)) + visible_message("\The [user] forces \the [src] open, sparks flying from its electronics!") + src.do_animate("spark") + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) + src.locked = 0 + src.welded = 0 + update_icon() + open(1) + src.emag_act() + else if(src.density) + visible_message("\The [user] begins forcing \the [src] open!") + if(do_after(user, 5 SECONDS,src)) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) + visible_message("\The [user] forces \the [src] open!") + open(1) + else + visible_message("\The [user] forces \the [src] closed!") + close(1) + else + src.do_animate("deny") + visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") + return + ..() + +/obj/machinery/door/airlock/get_material() + if(mineral) + return get_material_by_name(mineral) + return get_material_by_name(DEFAULT_WALL_MATERIAL) + +/obj/machinery/door/airlock/command + name = "Command Airlock" + icon = 'icons/obj/doors/Doorcom.dmi' + req_one_access = list(access_heads) + assembly_type = /obj/structure/door_assembly/door_assembly_com + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd3o.ogg' + department_close_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/security + name = "Security Airlock" + icon = 'icons/obj/doors/Doorsec.dmi' + req_one_access = list(access_security) + assembly_type = /obj/structure/door_assembly/door_assembly_sec + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' + +/obj/machinery/door/airlock/engineering + name = "Engineering Airlock" + icon = 'icons/obj/doors/Dooreng.dmi' + req_one_access = list(access_engine) + assembly_type = /obj/structure/door_assembly/door_assembly_eng + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/engineeringatmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Doorengatmos.dmi' + req_one_access = list(access_atmospherics) + assembly_type = /obj/structure/door_assembly/door_assembly_eat + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/medical + name = "Medical Airlock" + icon = 'icons/obj/doors/Doormed.dmi' + req_one_access = list(access_medical) + assembly_type = /obj/structure/door_assembly/door_assembly_med + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' + +/obj/machinery/door/airlock/maintenance + name = "Maintenance Access" + icon = 'icons/obj/doors/Doormaint.dmi' + //req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access + assembly_type = /obj/structure/door_assembly/door_assembly_mai + open_sound_powered = 'sound/machines/door/door2o.ogg' + close_sound_powered = 'sound/machines/door/door2c.ogg' + +/obj/machinery/door/airlock/maintenance/cargo + icon = 'icons/obj/doors/Doormaint_cargo.dmi' + req_one_access = list(access_cargo) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/door2o.ogg' + department_close_powered = 'sound/machines/door/door2c.ogg' + +/obj/machinery/door/airlock/maintenance/command + icon = 'icons/obj/doors/Doormaint_command.dmi' + req_one_access = list(access_heads) + +/obj/machinery/door/airlock/maintenance/common + icon = 'icons/obj/doors/Doormaint_common.dmi' + open_sound_powered = 'sound/machines/door/hall3o.ogg' + close_sound_powered = 'sound/machines/door/hall3c.ogg' + +/obj/machinery/door/airlock/maintenance/engi + icon = 'icons/obj/doors/Doormaint_engi.dmi' + req_one_access = list(access_engine) + +/obj/machinery/door/airlock/maintenance/int + icon = 'icons/obj/doors/Doormaint_int.dmi' + +/obj/machinery/door/airlock/maintenance/medical + icon = 'icons/obj/doors/Doormaint_med.dmi' + req_one_access = list(access_medical) + +/obj/machinery/door/airlock/maintenance/rnd + icon = 'icons/obj/doors/Doormaint_rnd.dmi' + req_one_access = list(access_research) + +/obj/machinery/door/airlock/maintenance/sec + icon = 'icons/obj/doors/Doormaint_sec.dmi' + req_one_access = list(access_security) + +/obj/machinery/door/airlock/external + name = "External Airlock" + icon = 'icons/obj/doors/Doorext.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_ext + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' + +/obj/machinery/door/airlock/external/glass/bolted + icon_state = "door_locked" // So it looks visibly bolted in map editor + locked = 1 + +// For convenience in making docking ports: one that is pre-bolted with frequency set! +/obj/machinery/door/airlock/external/glass/bolted/cycling + frequency = 1379 + +/obj/machinery/door/airlock/glass_external + name = "External Airlock" + icon = 'icons/obj/doors/Doorextglass.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_ext + opacity = 0 + glass = 1 + req_one_access = list(access_external_airlocks) + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' + +/obj/machinery/door/airlock/glass + name = "Glass Airlock" + icon = 'icons/obj/doors/Doorglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + open_sound_powered = 'sound/machines/door/hall1o.ogg' + close_sound_powered = 'sound/machines/door/hall1c.ogg' + legacy_open_powered = 'sound/machines/door/windowdoor.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + glass = 1 + +/obj/machinery/door/airlock/centcom + name = "Centcom Airlock" + icon = 'icons/obj/doors/Doorele.dmi' + req_one_access = list(access_cent_general) + opacity = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/glass_centcom + name = "Airlock" + icon = 'icons/obj/doors/Dooreleglass.dmi' + opacity = 0 + glass = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/vault + name = "Vault" + icon = 'icons/obj/doors/vault.dmi' + explosion_resistance = 20 + opacity = 1 + secured_wires = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. + req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/vault1o.ogg' + close_sound_powered = 'sound/machines/door/vault1c.ogg' + +/obj/machinery/door/airlock/vault/bolted + icon_state = "door_locked" + locked = 1 + +/obj/machinery/door/airlock/freezer + name = "Freezer Airlock" + icon = 'icons/obj/doors/Doorfreezer.dmi' + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_fre + +/obj/machinery/door/airlock/hatch + name = "Airtight Hatch" + icon = 'icons/obj/doors/Doorhatchele.dmi' + explosion_resistance = 20 + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_hatch + req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' + +/obj/machinery/door/airlock/maintenance_hatch + name = "Maintenance Hatch" + icon = 'icons/obj/doors/Doorhatchmaint2.dmi' + explosion_resistance = 20 + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_mhatch + req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' + +/obj/machinery/door/airlock/glass_command + name = "Command Airlock" + icon = 'icons/obj/doors/Doorcomglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_com + glass = 1 + req_one_access = list(access_heads) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd1o.ogg' + department_close_powered = 'sound/machines/door/cmd1c.ogg' + +/obj/machinery/door/airlock/glass_engineering + name = "Engineering Airlock" + icon = 'icons/obj/doors/Doorengglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_eng + glass = 1 + req_one_access = list(access_engine) + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/glass_engineeringatmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Doorengatmoglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_eat + glass = 1 + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/glass_security + name = "Security Airlock" + icon = 'icons/obj/doors/Doorsecglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_sec + glass = 1 + req_one_access = list(access_security) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' + +/obj/machinery/door/airlock/glass_medical + name = "Medical Airlock" + icon = 'icons/obj/doors/Doormedglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_med + glass = 1 + req_one_access = list(access_medical) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' + +/obj/machinery/door/airlock/mining + name = "Mining Airlock" + icon = 'icons/obj/doors/Doormining.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_min + req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' + +/obj/machinery/door/airlock/atmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Dooratmo.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_atmo + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/research + name = "Research Airlock" + icon = 'icons/obj/doors/Doorresearch.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_research + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_research + name = "Research Airlock" + icon = 'icons/obj/doors/Doorresearchglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_research + glass = 1 + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_mining + name = "Mining Airlock" + icon = 'icons/obj/doors/Doorminingglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_min + glass = 1 + req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' + +/obj/machinery/door/airlock/glass_atmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Dooratmoglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_atmo + glass = 1 + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/gold + name = "Gold Airlock" + icon = 'icons/obj/doors/Doorgold.dmi' + mineral = "gold" + +/obj/machinery/door/airlock/silver + name = "Silver Airlock" + icon = 'icons/obj/doors/Doorsilver.dmi' + mineral = "silver" + +/obj/machinery/door/airlock/diamond + name = "Diamond Airlock" + icon = 'icons/obj/doors/Doordiamond.dmi' + mineral = "diamond" + +/obj/machinery/door/airlock/uranium + name = "Uranium Airlock" + desc = "And they said I was crazy." + icon = 'icons/obj/doors/Dooruranium.dmi' + mineral = "uranium" + var/last_event = 0 + var/rad_power = 7.5 + +/obj/machinery/door/airlock/process() + // Deliberate no call to parent. + if(main_power_lost_until > 0 && world.time >= main_power_lost_until) + regainMainPower() + + if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until) + regainBackupPower() + + else if(electrified_until > 0 && world.time >= electrified_until) + electrify(0) + + if (..() == PROCESS_KILL && !(main_power_lost_until > 0 || backup_power_lost_until > 0 || electrified_until > 0)) + . = PROCESS_KILL + +/obj/machinery/door/airlock/uranium/process() + if(world.time > last_event+20) + if(prob(50)) + SSradiation.radiate(src, rad_power) + last_event = world.time + ..() + +/obj/machinery/door/airlock/phoron + name = "Phoron Airlock" + desc = "No way this can end badly." + icon = 'icons/obj/doors/Doorphoron.dmi' + mineral = "phoron" + +/obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300) + PhoronBurn(exposed_temperature) + +/obj/machinery/door/airlock/phoron/proc/ignite(exposed_temperature) + if(exposed_temperature > 300) + PhoronBurn(exposed_temperature) + +/obj/machinery/door/airlock/phoron/proc/PhoronBurn(temperature) + for(var/turf/simulated/floor/target_tile in range(2,loc)) + target_tile.assume_gas("phoron", 35, 400+T0C) + spawn (0) target_tile.hotspot_expose(temperature, 400) + for(var/turf/simulated/wall/W in range(3,src)) + W.burn((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame + for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) + D.ignite(temperature/4) + new/obj/structure/door_assembly( src.loc ) + qdel(src) + +/obj/machinery/door/airlock/sandstone + name = "Sandstone Airlock" + icon = 'icons/obj/doors/Doorsand.dmi' + mineral = "sandstone" + +/obj/machinery/door/airlock/science + name = "Research Airlock" + icon = 'icons/obj/doors/Doorsci.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_science + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_science + name = "Glass Airlocks" + icon = 'icons/obj/doors/Doorsciglass.dmi' + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_science + glass = 1 + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/highsecurity + name = "Secure Airlock" + icon = 'icons/obj/doors/hightechsecurity.dmi' + explosion_resistance = 20 + secured_wires = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity + req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/secure1o.ogg' + close_sound_powered = 'sound/machines/door/secure1c.ogg' + +/obj/machinery/door/airlock/voidcraft + name = "voidcraft hatch" + desc = "It's an extra resilient airlock intended for spacefaring vessels." + icon = 'icons/obj/doors/shuttledoors.dmi' + explosion_resistance = 20 + opacity = 0 + glass = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' + +// Airlock opens from top-bottom instead of left-right. +/obj/machinery/door/airlock/voidcraft/vertical + icon = 'icons/obj/doors/shuttledoors_vertical.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' + + +/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock + name = "Precursor Alpha Object - Doors" + desc = "This object appears to be used in order to restrict or allow access to \ + rooms based on its physical state. In other words, a door. \ + Despite being designed and created by unknown ancient alien hands, this door has \ + a large number of similarities to the conventional airlock, such as being driven by \ + electricity, opening and closing by physically moving, and being air tight. \ + It also operates by responding to signals through internal electrical conduits. \ + These characteristics make it possible for one with experience with a multitool \ + to manipulate the door.\ +

\ + The symbol on the door does not match any living species' patterns, giving further \ + implications that this door is very old, and yet it remains operational after \ + thousands of years. It is unknown if that is due to superb construction, or \ + unseen autonomous maintenance having been performed." + value = CATALOGUER_REWARD_EASY + +/obj/machinery/door/airlock/alien + name = "alien airlock" + desc = "You're fairly sure this is a door." + catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock) + icon = 'icons/obj/doors/Dooralien.dmi' + explosion_resistance = 20 + secured_wires = TRUE + hackProof = TRUE + assembly_type = /obj/structure/door_assembly/door_assembly_alien + req_one_access = list(access_alien) + +/obj/machinery/door/airlock/alien/locked + icon_state = "door_locked" + locked = TRUE + +/obj/machinery/door/airlock/alien/public // Entry to UFO. + req_one_access = list() + normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside. + hackProof = TRUE //VOREStation Edit - No borgos + +/* +About the new airlock wires panel: +* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires. +* one wire from the ID scanner. Sending a pulse through this flashes the red light on the door (if the door has power). If you cut this wire, the door will stop recognizing valid IDs. (If the door has 0000 access, it still opens and closes, though) +* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be open, but bolts-raising will not work. Cutting these wires may electrocute the user. +* one wire for door bolts. Sending a pulse through this drops door bolts (whether the door is powered or not) or raises them (if it is). Cutting this wire also drops the door bolts, and mending it does not raise them. If the wire is cut, trying to raise the door bolts will not work. +* two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. +* one wire for opening the door. Sending a pulse through this while the door has power makes it open the door if no access is required. +* one wire for AI control. Sending a pulse through this blocks AI control for a second or so (which is enough to see the AI control light on the panel dialog go off and back on again). Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. +* one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. (Currently it is also STAYING electrified until someone mends the wire) +* one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit. +* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick. +*/ + + + +/obj/machinery/door/airlock/bumpopen(mob/living/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite + if(!issilicon(usr)) + if(src.isElectrified()) + if(!src.justzap) + if(src.shock(user, 100)) + src.justzap = 1 + spawn (10) + src.justzap = 0 + return + else /*if(src.justzap)*/ + return + else if(user.hallucination > 50 && prob(10) && src.operating == 0) + to_chat(user, "You feel a powerful shock course through your body!") + user.halloss += 10 + user.stunned += 10 + return + ..(user) + +/obj/machinery/door/airlock/proc/isElectrified() + if(src.electrified_until != 0) + return 1 + return 0 + +/obj/machinery/door/airlock/proc/canAIControl() + return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); + +/obj/machinery/door/airlock/proc/canAIHack() + return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerLoss())); + +/obj/machinery/door/airlock/proc/arePowerSystemsOn() + if (stat & (NOPOWER|BROKEN)) + return 0 + return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) + +/obj/machinery/door/airlock/requiresID() + return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner) + +/obj/machinery/door/airlock/proc/isAllPowerLoss() + if(stat & (NOPOWER|BROKEN)) + return 1 + if(mainPowerCablesCut() && backupPowerCablesCut()) + return 1 + return 0 + +/obj/machinery/door/airlock/proc/mainPowerCablesCut() + return wires.is_cut(WIRE_MAIN_POWER1) || wires.is_cut(WIRE_MAIN_POWER2) + +/obj/machinery/door/airlock/proc/backupPowerCablesCut() + return wires.is_cut(WIRE_BACKUP_POWER1) || wires.is_cut(WIRE_BACKUP_POWER2) + +/obj/machinery/door/airlock/proc/loseMainPower() + main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) + + // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running + if(backup_power_lost_until == -1 && !backupPowerCablesCut()) + backup_power_lost_until = world.time + SecondsToTicks(10) + + if(main_power_lost_until > 0 || backup_power_lost_until > 0) + START_MACHINE_PROCESSING(src) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) + + update_icon() + +/obj/machinery/door/airlock/proc/loseBackupPower() + backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) + + if(backup_power_lost_until > 0) + START_MACHINE_PROCESSING(src) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) + + update_icon() + +/obj/machinery/door/airlock/proc/regainMainPower() + if(!mainPowerCablesCut()) + main_power_lost_until = 0 + // If backup power is currently active then disable, otherwise let it count down and disable itself later + if(!backup_power_lost_until) + backup_power_lost_until = -1 + + update_icon() + +/obj/machinery/door/airlock/proc/regainBackupPower() + if(!backupPowerCablesCut()) + // Restore backup power only if main power is offline, otherwise permanently disable + backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0 + + update_icon() + +/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) + var/message = "" + if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn()) + message = text("The electrification wire is cut - Door permanently electrified.") + src.electrified_until = -1 + else if(duration && !arePowerSystemsOn()) + message = text("The door is unpowered - Cannot electrify the door.") + src.electrified_until = 0 + else if(!duration && electrified_until != 0) + message = "The door is now un-electrified." + src.electrified_until = 0 + else if(duration) //electrify door for the given duration seconds + if(usr) + shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") + add_attack_logs(usr,name,"Electrified a door") + else + shockedby += text("\[[time_stamp()]\] - EMP)") + message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." + src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) + + if(electrified_until > 0) + START_MACHINE_PROCESSING(src) + + if(feedback && message) + to_chat(usr,message) + +/obj/machinery/door/airlock/proc/set_idscan(var/activate, var/feedback = 0) + var/message = "" + if(wires.is_cut(WIRE_IDSCAN)) + message = "The IdScan wire is cut - IdScan feature permanently disabled." + else if(activate && src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 0 + message = "IdScan feature has been enabled." + else if(!activate && !src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 1 + message = "IdScan feature has been disabled." + + if(feedback && message) + to_chat(usr,message) + +/obj/machinery/door/airlock/proc/set_safeties(var/activate, var/feedback = 0) + var/message = "" + // Safeties! We don't need no stinking safeties! + if (wires.is_cut(WIRE_SAFETY)) + message = text("The safety wire is cut - Cannot enable safeties.") + else if (!activate && src.safe) + safe = 0 + else if (activate && !src.safe) + safe = 1 + + if(feedback && message) + to_chat(usr,message) + +// shock user with probability prb (if all connections & power are working) +// returns 1 if shocked, 0 otherwise +// The preceding comment was borrowed from the grille's shock script +/obj/machinery/door/airlock/shock(mob/user, prb) + if(!arePowerSystemsOn()) + return 0 + if(hasShocked) + return 0 //Already shocked someone recently? + if(..()) + hasShocked = 1 + sleep(10) + hasShocked = 0 + return 1 + else + return 0 + + +/obj/machinery/door/airlock/update_icon() + cut_overlays() + if(density) + if(locked && lights && src.arePowerSystemsOn()) + icon_state = "door_locked" + else + icon_state = "door_closed" + if(p_open || welded) + if(p_open) + add_overlay("panel_open") + if (!(stat & NOPOWER)) + if(stat & BROKEN) + add_overlay("sparks_broken") + else if (health < maxhealth * 3/4) + add_overlay("sparks_damaged") + if(welded) + add_overlay("welded") + else if (health < maxhealth * 3/4 && !(stat & NOPOWER)) + add_overlay("sparks_damaged") + else + icon_state = "door_open" + if((stat & BROKEN) && !(stat & NOPOWER)) + add_overlay("sparks_open") + return + +/obj/machinery/door/airlock/do_animate(animation) + switch(animation) + if("opening") + cut_overlay() + if(p_open) + spawn(2) // The only work around that works. Downside is that the door will be gone for a millisecond. + flick("o_door_opening", src) //can not use flick due to BYOND bug updating overlays right before flicking + update_icon() + else + flick("door_opening", src)//[stat ? "_stat":] + update_icon() + if("closing") + cut_overlay() + if(p_open) + spawn(2) + flick("o_door_closing", src) + update_icon() + else + flick("door_closing", src) + update_icon() + if("spark") + if(density) + flick("door_spark", src) + if("deny") + if(density && src.arePowerSystemsOn()) + flick("door_deny", src) + playsound(src, denied_sound, 50, 0, 3) + return + +/obj/machinery/door/airlock/attack_ai(mob/user as mob) + tgui_interact(user) + +/obj/machinery/door/airlock/attack_ghost(mob/user) + tgui_interact(user) + +/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiAirlock", name) + ui.open() + if(custom_state) + ui.set_state(custom_state) + return TRUE + +/obj/machinery/door/airlock/tgui_data(mob/user) + var/list/data = list() + + var/list/power = list() + power["main"] = main_power_lost_until > 0 ? 0 : 2 + power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) + power["backup"] = backup_power_lost_until > 0 ? 0 : 2 + power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) + data["power"] = power + + data["shock"] = (electrified_until == 0) ? 2 : 0 + data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) + data["id_scanner"] = !aiDisabledIdScanner + data["locked"] = locked // bolted + data["lights"] = lights // bolt lights + data["safe"] = safe // safeties + data["speed"] = normalspeed // safe speed + data["welded"] = welded // welded + data["opened"] = !density // opened + + var/list/wire = list() + wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1) + wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2) + wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1) + wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2) + wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY) + wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN) + wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS) + wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT) + wire["safe"] = !wires.is_cut(WIRE_SAFETY) + wire["timing"] = !wires.is_cut(WIRE_SPEED) + + data["wires"] = wire + return data + +/obj/machinery/door/airlock/proc/hack(mob/user as mob) + if(src.aiHacking==0) + src.aiHacking=1 + spawn(20) + //TODO: Make this take a minute + to_chat(user, "Airlock AI control has been blocked. Beginning fault-detection.") + sleep(50) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Fault confirmed: airlock control wire disabled or cut.") + sleep(20) + to_chat(user, "Attempting to hack into airlock. This may take some time.") + sleep(200) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Upload access confirmed. Loading control program into airlock software.") + sleep(170) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Transfer complete. Forcing airlock to execute program.") + sleep(50) + //disable blocked control + src.aiControlDisabled = 2 + to_chat(user, "Receiving control information from airlock.") + sleep(10) + //bring up airlock dialog + src.aiHacking = 0 + if (user) + src.attack_ai(user) + +/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target) + if (src.isElectrified()) + if (istype(mover, /obj/item)) + var/obj/item/i = mover + if (i.matter && (DEFAULT_WALL_MATERIAL in i.matter) && i.matter[DEFAULT_WALL_MATERIAL] > 0) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + return ..() + +/obj/machinery/door/airlock/attack_hand(mob/user as mob) + if(!istype(usr, /mob/living/silicon)) + if(src.isElectrified()) + if(src.shock(user, 100)) + return + + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/X = user + if(istype(X.species, /datum/species/xenos)) + src.attack_alien(user) + return + + if(src.p_open) + user.set_machine(src) + wires.Interact(user) + else + ..(user) + return + +/obj/machinery/door/airlock/tgui_act(action, params) + if(..()) + return TRUE + if(!user_allowed(usr)) + return TRUE + + switch(action) + if("disrupt-main") + if(!main_power_lost_until) + loseMainPower() + update_icon() + else + to_chat(usr, "Main power is already offline.") + . = TRUE + if("disrupt-backup") + if(!backup_power_lost_until) + loseBackupPower() + update_icon() + else + to_chat(usr, "Backup power is already offline.") + . = TRUE + if("shock-restore") + electrify(0, 1) + . = TRUE + if("shock-temp") + electrify(30, 1) + . = TRUE + if("shock-perm") + electrify(-1, 1) + . = TRUE + if("idscan-toggle") + set_idscan(aiDisabledIdScanner, 1) + . = TRUE + // if("emergency-toggle") + // toggle_emergency(usr) + // . = TRUE + if("bolt-toggle") + toggle_bolt(usr) + . = TRUE + if("light-toggle") + if(wires.is_cut(WIRE_BOLT_LIGHT)) + to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") + return + lights = !lights + update_icon() + . = TRUE + if("safe-toggle") + set_safeties(!safe, 1) + . = TRUE + if("speed-toggle") + if(wires.is_cut(WIRE_SPEED)) + to_chat(usr, "The timing wire is cut - Cannot alter timing.") + return + normalspeed = !normalspeed + . = TRUE + if("open-close") + user_toggle_open(usr) + . = TRUE + + update_icon() + return 1 + +/obj/machinery/door/airlock/proc/user_allowed(mob/user) + var/allowed = (issilicon(user) && canAIControl(user)) + if(!allowed && isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + allowed = TRUE + return allowed + +/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) + if(!user_allowed(user)) + return + if(wires.is_cut(WIRE_DOOR_BOLTS)) + to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") + return + if(locked) + if(!arePowerSystemsOn()) + to_chat(user, "The door has no power - you can't raise the door bolts.") + else + unlock() + to_chat(user, "The door bolts have been raised.") + // log_combat(user, src, "unbolted") + else + lock() + to_chat(user, "The door bolts have been dropped.") + // log_combat(user, src, "bolted") + +/obj/machinery/door/airlock/proc/user_toggle_open(mob/user) + if(!user_allowed(user)) + return + if(welded) + to_chat(user, text("The airlock has been welded shut!")) + else if(locked) + to_chat(user, text("The door bolts are down!")) + else if(!density) + close() + else + open() + +/obj/machinery/door/airlock/proc/can_remove_electronics() + return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) + +/obj/machinery/door/airlock/attackby(obj/item/C, mob/user as mob) + //to_world("airlock attackby src [src] obj [C] mob [user]") + if(!istype(usr, /mob/living/silicon)) + if(src.isElectrified()) + if(src.shock(user, 75)) + return + if(istype(C, /obj/item/taperoll)) + return + + src.add_fingerprint(user) + if (attempt_vr(src,"attackby_vr",list(C, user))) return + if(istype(C, /mob/living)) + ..() + return + if(!repairing && istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(0,user)) + if(!src.welded) + src.welded = 1 + else + src.welded = null + playsound(src, C.usesound, 75, 1) + src.update_icon() + return + else + return + else if(C.is_screwdriver()) + if (src.p_open) + if (stat & BROKEN) + to_chat(usr, "The panel is broken and cannot be closed.") + else + src.p_open = 0 + playsound(src, C.usesound, 50, 1) + else + src.p_open = 1 + playsound(src, C.usesound, 50, 1) + src.update_icon() + else if(C.is_wirecutter()) + return src.attack_hand(user) + else if(istype(C, /obj/item/device/multitool)) + return src.attack_hand(user) + else if(istype(C, /obj/item/device/assembly/signaler)) + return src.attack_hand(user) + else if(istype(C, /obj/item/weapon/pai_cable)) // -- TLE + var/obj/item/weapon/pai_cable/cable = C + cable.plugin(src, user) + else if(!repairing && C.is_crowbar()) + if(can_remove_electronics()) + playsound(src, C.usesound, 75, 1) + user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.") + if(do_after(user,40 * C.toolspeed)) + to_chat(user, "You removed the airlock electronics!") + + var/obj/structure/door_assembly/da = new assembly_type(src.loc) + if (istype(da, /obj/structure/door_assembly/multi_tile)) + da.set_dir(src.dir) + + da.anchored = 1 + if(mineral) + da.glass = mineral + //else if(glass) + else if(glass && !da.glass) + da.glass = 1 + da.state = 1 + da.created_name = src.name + da.update_state() + + if(operating == -1 || (stat & BROKEN)) + new /obj/item/weapon/circuitboard/broken(src.loc) + operating = 0 + else + if (!electronics) create_electronics() + + electronics.loc = src.loc + electronics = null + + qdel(src) + return + else if(arePowerSystemsOn()) + to_chat(user, "The airlock's motors resist your efforts to force it.") + else if(locked) + to_chat(user, "The airlock's bolts prevent it from being forced.") + else + if(density) + spawn(0) open(1) + else + spawn(0) close(1) + + // Check if we're using a crowbar or armblade, and if the airlock's unpowered for whatever reason (off, broken, etc). + else if(istype(C, /obj/item/weapon)) + var/obj/item/weapon/W = C + if((W.pry == 1) && !arePowerSystemsOn()) + if(locked) + to_chat(user, "The airlock's bolts prevent it from being forced.") + else if( !welded && !operating ) + if(istype(C, /obj/item/weapon/material/twohanded/fireaxe)) // If this is a fireaxe, make sure it's held in two hands. + var/obj/item/weapon/material/twohanded/fireaxe/F = C + if(!F.wielded) + to_chat(user, "You need to be wielding \the [F] to do that.") + return + // At this point, it's an armblade or a fireaxe that passed the wielded test, let's try to open it. + if(density) + spawn(0) + open(1) + else + spawn(0) + close(1) + else + ..() + else + ..() + return + +/obj/machinery/door/airlock/phoron/attackby(C as obj, mob/user as mob) + if(C) + ignite(is_hot(C)) + ..() + +/obj/machinery/door/airlock/set_broken() + src.p_open = 1 + stat |= BROKEN + if (secured_wires) + lock() + for (var/mob/O in viewers(src, null)) + if ((O.client && !( O.blinded ))) + O.show_message("[src.name]'s control panel bursts open, sparks spewing out!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + + update_icon() + return + +/obj/machinery/door/airlock/open(var/forced=0) + if(!can_open(forced)) + return 0 + use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people + + //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) // Do we have old sounds enabled? Play these even if we have department door sounds enabled. + if(arePowerSystemsOn()) + sound = legacy_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_open_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else // Else, play these. + if(arePowerSystemsOn()) + sound = open_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) + + if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) + src.closeOther.close() + return ..() + +/obj/machinery/door/airlock/can_open(var/forced=0) + if(!forced) + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) + return 0 + + if(locked || welded) + return 0 + return ..() + +/obj/machinery/door/airlock/can_close(var/forced=0) + if(locked || welded) + return 0 + + if(!forced) + //despite the name, this wire is for general door control. + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) + return 0 + + return ..() + +/atom/movable/proc/blocks_airlock() + return density + +/obj/machinery/door/blocks_airlock() + return 0 + +/obj/machinery/mech_sensor/blocks_airlock() + return 0 + +/mob/living/blocks_airlock() + return 1 + +/atom/movable/proc/airlock_crush(var/crush_damage) + return 0 + +/obj/machinery/portable_atmospherics/canister/airlock_crush(var/crush_damage) + . = ..() + health -= crush_damage + healthcheck() + +/obj/effect/energy_field/airlock_crush(var/crush_damage) + adjust_strength(crush_damage) + +/obj/structure/closet/airlock_crush(var/crush_damage) + ..() + damage(crush_damage) + for(var/atom/movable/AM in src) + AM.airlock_crush() + return 1 + +/mob/living/airlock_crush(var/crush_damage) + . = ..() + adjustBruteLoss(crush_damage) + SetStunned(5) + SetWeakened(5) + var/turf/T = get_turf(src) + T.add_blood(src) + return 1 + +/mob/living/carbon/airlock_crush(var/crush_damage) + . = ..() + if(can_feel_pain()) + emote("scream") + +/mob/living/silicon/robot/airlock_crush(var/crush_damage) + adjustBruteLoss(crush_damage) + return 0 + +/obj/machinery/door/airlock/close(var/forced=0) + if(!can_close(forced)) + return 0 + + if(safe) + for(var/turf/turf in locs) + for(var/atom/movable/AM in turf) + if(AM.blocks_airlock()) + if(!has_beeped) + playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) + has_beeped = 1 + autoclose_in(6) + return + + for(var/turf/turf in locs) + for(var/atom/movable/AM in turf) + if(AM.airlock_crush(DOOR_CRUSH_DAMAGE)) + take_damage(DOOR_CRUSH_DAMAGE) + + use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people + has_beeped = 0 + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) + if(arePowerSystemsOn()) + sound = legacy_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_close_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else + if(arePowerSystemsOn()) + sound = close_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) + for(var/turf/turf in locs) + var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) + if(killthis) + killthis.ex_act(2)//Smashin windows + return ..() + +/obj/machinery/door/airlock/proc/lock(var/forced=0) + if(locked) + return 0 + + if (operating && !forced) return 0 + + src.locked = 1 + playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) + for(var/mob/M in range(1,src)) + M.show_message("You hear a click from the bottom of the door.", 2) + update_icon() + return 1 + +/obj/machinery/door/airlock/proc/unlock(var/forced=0) + if(!src.locked) + return + + if (!forced) + if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return + + src.locked = 0 + playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) + for(var/mob/M in range(1,src)) + M.show_message("You hear a click from the bottom of the door.", 2) + update_icon() + return 1 + +/obj/machinery/door/airlock/allowed(mob/M) + if(locked) + return 0 + return ..(M) + +/obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) + ..() + + //if assembly is given, create the new door from the assembly + if (assembly && istype(assembly)) + assembly_type = assembly.type + + electronics = assembly.electronics + electronics.loc = src + + //update the door's access to match the electronics' + secured_wires = electronics.secure + if(electronics.one_access) + LAZYCLEARLIST(req_access) + req_one_access = src.electronics.conf_access + else + LAZYCLEARLIST(req_one_access) + req_access = src.electronics.conf_access + + //get the name from the assembly + if(assembly.created_name) + name = assembly.created_name + else + name = "[istext(assembly.glass) ? "[assembly.glass] airlock" : assembly.base_name]" + + //get the dir from the assembly + set_dir(assembly.dir) + + //wires + var/turf/T = get_turf(newloc) + if(T && (T.z in using_map.admin_levels)) + secured_wires = 1 + if (secured_wires) + wires = new/datum/wires/airlock/secure(src) + else + wires = new/datum/wires/airlock(src) + +/obj/machinery/door/airlock/Initialize() + if(src.closeOtherId != null) + for (var/obj/machinery/door/airlock/A in machines) + if(A.closeOtherId == src.closeOtherId && A != src) + src.closeOther = A + break + name = "\improper [name]" + . = ..() + +/obj/machinery/door/airlock/Destroy() + qdel(wires) + wires = null + return ..() + +// Most doors will never be deconstructed over the course of a round, +// so as an optimization defer the creation of electronics until +// the airlock is deconstructed +/obj/machinery/door/airlock/proc/create_electronics() + //create new electronics + if (secured_wires) + src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) + else + src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) + + //update the electronics to match the door's access + if(LAZYLEN(req_access)) + electronics.conf_access = req_access + else if (LAZYLEN(req_one_access)) + electronics.conf_access = req_one_access + electronics.one_access = 1 + +/obj/machinery/door/airlock/emp_act(var/severity) + if(prob(40/severity)) + var/duration = world.time + SecondsToTicks(30 / severity) + if(duration > electrified_until) + electrify(duration) + ..() + +/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason + ..() + if(stat & NOPOWER) + // If we lost power, disable electrification + // Keeping door lights on, runs on internal battery or something. + electrified_until = 0 + update_icon() + +/obj/machinery/door/airlock/proc/prison_open() + if(arePowerSystemsOn()) + src.unlock() + src.open() + src.lock() + return + + +/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + // Old RCD code made it cost 10 units to decon an airlock. + // Now the new one costs ten "sheets". + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 + ) + return FALSE + +/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + return FALSE +======= +//VOREStation Edit - Redone a lot of airlock things: +/* +- Specific department maintenance doors +- Named doors properly according to type +- Gave them default access levels with the access constants +- Improper'd all of the names in the new() +*/ + +/obj/machinery/door/airlock + name = "Airlock" + icon = 'icons/obj/doors/Doorint.dmi' + icon_state = "door_closed" + power_channel = ENVIRON + + explosion_resistance = 10 + + // Doors do their own stuff + bullet_vulnerability = 0 + + blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime + + var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. + var/hackProof = 0 // if 1, this door can't be hacked by the AI + var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + var/main_power_lost_until = 0 //World time when main power is restored. + var/backup_power_lost_until = -1 //World time when backup power is restored. + var/has_beeped = 0 //If 1, will not beep on failed closing attempt. Resets when door closes. + var/spawnPowerRestoreRunning = 0 + var/welded = null + var/locked = 0 + var/lights = 1 // bolt lights show by default + var/aiDisabledIdScanner = 0 + var/aiHacking = 0 + var/obj/machinery/door/airlock/closeOther = null + var/closeOtherId = null + var/lockdownbyai = 0 + autoclose = 1 + var/assembly_type = /obj/structure/door_assembly + var/mineral = null + var/justzap = 0 + var/safe = 1 + normalspeed = 1 + var/obj/item/weapon/airlock_electronics/electronics = null + var/hasShocked = 0 //Prevents multiple shocks from happening + var/secured_wires = 0 + var/datum/wires/airlock/wires = null + + var/open_sound_powered = 'sound/machines/door/covert1o.ogg' + var/open_sound_unpowered = 'sound/machines/door/airlockforced.ogg' + var/close_sound_powered = 'sound/machines/door/covert1c.ogg' + var/legacy_open_powered = 'sound/machines/door/old_airlock.ogg' + var/legacy_close_powered = 'sound/machines/door/old_airlockclose.ogg' + var/department_open_powered = null + var/department_close_powered = null + var/denied_sound = 'sound/machines/deniedbeep.ogg' + var/bolt_up_sound = 'sound/machines/door/boltsup.ogg' + var/bolt_down_sound = 'sound/machines/door/boltsdown.ogg' + +/obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) + if(stat & (BROKEN|NOPOWER)) + if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) + if(src.locked || src.welded) + visible_message("\The [user] begins breaking into \the [src] internals!") + user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. + if(do_after(user,10 SECONDS,src)) + src.locked = 0 + src.welded = 0 + update_icon() + open(1) + if(prob(25)) + src.shock(user, 100) + user.set_AI_busy(FALSE) + else if(src.density) + visible_message("\The [user] forces \the [src] open!") + open(1) + else + visible_message("\The [user] forces \the [src] closed!") + close(1) + else + visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") + return + ..() + +/obj/machinery/door/airlock/attack_alien(var/mob/user) //Familiar, right? Doors. -Mechoid + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/X = user + if(istype(X.species, /datum/species/xenos)) + if(src.locked || src.welded) + visible_message("\The [user] begins digging into \the [src] internals!") + src.do_animate("deny") + if(do_after(user,5 SECONDS,src)) + visible_message("\The [user] forces \the [src] open, sparks flying from its electronics!") + src.do_animate("spark") + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) + src.locked = 0 + src.welded = 0 + update_icon() + open(1) + src.emag_act() + else if(src.density) + visible_message("\The [user] begins forcing \the [src] open!") + if(do_after(user, 5 SECONDS,src)) + playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) + visible_message("\The [user] forces \the [src] open!") + open(1) + else + visible_message("\The [user] forces \the [src] closed!") + close(1) + else + src.do_animate("deny") + visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") + return + ..() + +/obj/machinery/door/airlock/get_material() + if(mineral) + return get_material_by_name(mineral) + return get_material_by_name(DEFAULT_WALL_MATERIAL) + +/obj/machinery/door/airlock/command + name = "Command Airlock" + icon = 'icons/obj/doors/Doorcom.dmi' + req_one_access = list(access_heads) + assembly_type = /obj/structure/door_assembly/door_assembly_com + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd3o.ogg' + department_close_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/security + name = "Security Airlock" + icon = 'icons/obj/doors/Doorsec.dmi' + req_one_access = list(access_security) + assembly_type = /obj/structure/door_assembly/door_assembly_sec + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' + +/obj/machinery/door/airlock/engineering + name = "Engineering Airlock" + icon = 'icons/obj/doors/Dooreng.dmi' + req_one_access = list(access_engine) + assembly_type = /obj/structure/door_assembly/door_assembly_eng + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/engineeringatmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Doorengatmos.dmi' + req_one_access = list(access_atmospherics) + assembly_type = /obj/structure/door_assembly/door_assembly_eat + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/medical + name = "Medical Airlock" + icon = 'icons/obj/doors/Doormed.dmi' + req_one_access = list(access_medical) + assembly_type = /obj/structure/door_assembly/door_assembly_med + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' + +/obj/machinery/door/airlock/maintenance + name = "Maintenance Access" + icon = 'icons/obj/doors/Doormaint.dmi' + //req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access + assembly_type = /obj/structure/door_assembly/door_assembly_mai + open_sound_powered = 'sound/machines/door/door2o.ogg' + close_sound_powered = 'sound/machines/door/door2c.ogg' + +/obj/machinery/door/airlock/maintenance/cargo + icon = 'icons/obj/doors/Doormaint_cargo.dmi' + req_one_access = list(access_cargo) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/door2o.ogg' + department_close_powered = 'sound/machines/door/door2c.ogg' + +/obj/machinery/door/airlock/maintenance/command + icon = 'icons/obj/doors/Doormaint_command.dmi' + req_one_access = list(access_heads) + +/obj/machinery/door/airlock/maintenance/common + icon = 'icons/obj/doors/Doormaint_common.dmi' + open_sound_powered = 'sound/machines/door/hall3o.ogg' + close_sound_powered = 'sound/machines/door/hall3c.ogg' + +/obj/machinery/door/airlock/maintenance/engi + icon = 'icons/obj/doors/Doormaint_engi.dmi' + req_one_access = list(access_engine) + +/obj/machinery/door/airlock/maintenance/int + icon = 'icons/obj/doors/Doormaint_int.dmi' + +/obj/machinery/door/airlock/maintenance/medical + icon = 'icons/obj/doors/Doormaint_med.dmi' + req_one_access = list(access_medical) + +/obj/machinery/door/airlock/maintenance/rnd + icon = 'icons/obj/doors/Doormaint_rnd.dmi' + req_one_access = list(access_research) + +/obj/machinery/door/airlock/maintenance/sec + icon = 'icons/obj/doors/Doormaint_sec.dmi' + req_one_access = list(access_security) + +/obj/machinery/door/airlock/external + name = "External Airlock" + icon = 'icons/obj/doors/Doorext.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_ext + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' + +/obj/machinery/door/airlock/external/glass/bolted + icon_state = "door_locked" // So it looks visibly bolted in map editor + locked = 1 + +// For convenience in making docking ports: one that is pre-bolted with frequency set! +/obj/machinery/door/airlock/external/glass/bolted/cycling + frequency = 1379 + +/obj/machinery/door/airlock/glass_external + name = "External Airlock" + icon = 'icons/obj/doors/Doorextglass.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_ext + opacity = 0 + glass = 1 + req_one_access = list(access_external_airlocks) + open_sound_powered = 'sound/machines/door/space1o.ogg' + close_sound_powered = 'sound/machines/door/space1c.ogg' + +/obj/machinery/door/airlock/glass + name = "Glass Airlock" + icon = 'icons/obj/doors/Doorglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + open_sound_powered = 'sound/machines/door/hall1o.ogg' + close_sound_powered = 'sound/machines/door/hall1c.ogg' + legacy_open_powered = 'sound/machines/door/windowdoor.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + glass = 1 + +/obj/machinery/door/airlock/centcom + name = "Centcom Airlock" + icon = 'icons/obj/doors/Doorele.dmi' + req_one_access = list(access_cent_general) + opacity = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/glass_centcom + name = "Airlock" + icon = 'icons/obj/doors/Dooreleglass.dmi' + opacity = 0 + glass = 1 + open_sound_powered = 'sound/machines/door/cmd3o.ogg' + close_sound_powered = 'sound/machines/door/cmd3c.ogg' + +/obj/machinery/door/airlock/vault + name = "Vault" + icon = 'icons/obj/doors/vault.dmi' + explosion_resistance = 20 + opacity = 1 + secured_wires = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. + req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/vault1o.ogg' + close_sound_powered = 'sound/machines/door/vault1c.ogg' + +/obj/machinery/door/airlock/vault/bolted + icon_state = "door_locked" + locked = 1 + +/obj/machinery/door/airlock/freezer + name = "Freezer Airlock" + icon = 'icons/obj/doors/Doorfreezer.dmi' + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_fre + +/obj/machinery/door/airlock/hatch + name = "Airtight Hatch" + icon = 'icons/obj/doors/Doorhatchele.dmi' + explosion_resistance = 20 + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_hatch + req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' + +/obj/machinery/door/airlock/maintenance_hatch + name = "Maintenance Hatch" + icon = 'icons/obj/doors/Doorhatchmaint2.dmi' + explosion_resistance = 20 + opacity = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_mhatch + req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/door/hatchopen.ogg' + close_sound_powered = 'sound/machines/door/hatchclose.ogg' + open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' + +/obj/machinery/door/airlock/glass_command + name = "Command Airlock" + icon = 'icons/obj/doors/Doorcomglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_com + glass = 1 + req_one_access = list(access_heads) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cmd1o.ogg' + department_close_powered = 'sound/machines/door/cmd1c.ogg' + +/obj/machinery/door/airlock/glass_engineering + name = "Engineering Airlock" + icon = 'icons/obj/doors/Doorengglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_eng + glass = 1 + req_one_access = list(access_engine) + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/glass_engineeringatmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Doorengatmoglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_eat + glass = 1 + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/glass_security + name = "Security Airlock" + icon = 'icons/obj/doors/Doorsecglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_sec + glass = 1 + req_one_access = list(access_security) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sec1o.ogg' + department_close_powered = 'sound/machines/door/sec1c.ogg' + +/obj/machinery/door/airlock/glass_medical + name = "Medical Airlock" + icon = 'icons/obj/doors/Doormedglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_med + glass = 1 + req_one_access = list(access_medical) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/med1o.ogg' + department_close_powered = 'sound/machines/door/med1c.ogg' + +/obj/machinery/door/airlock/mining + name = "Mining Airlock" + icon = 'icons/obj/doors/Doormining.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_min + req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' + +/obj/machinery/door/airlock/atmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Dooratmo.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_atmo + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/research + name = "Research Airlock" + icon = 'icons/obj/doors/Doorresearch.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_research + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_research + name = "Research Airlock" + icon = 'icons/obj/doors/Doorresearchglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_research + glass = 1 + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_mining + name = "Mining Airlock" + icon = 'icons/obj/doors/Doorminingglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_min + glass = 1 + req_one_access = list(access_mining) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/cgo1o.ogg' + department_close_powered = 'sound/machines/door/cgo1c.ogg' + +/obj/machinery/door/airlock/glass_atmos + name = "Atmospherics Airlock" + icon = 'icons/obj/doors/Dooratmoglass.dmi' + hitsound = 'sound/effects/Glasshit.ogg' + maxhealth = 300 + explosion_resistance = 5 + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_atmo + glass = 1 + req_one_access = list(access_atmospherics) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/eng1o.ogg' + department_close_powered = 'sound/machines/door/eng1c.ogg' + +/obj/machinery/door/airlock/gold + name = "Gold Airlock" + icon = 'icons/obj/doors/Doorgold.dmi' + mineral = "gold" + +/obj/machinery/door/airlock/silver + name = "Silver Airlock" + icon = 'icons/obj/doors/Doorsilver.dmi' + mineral = "silver" + +/obj/machinery/door/airlock/diamond + name = "Diamond Airlock" + icon = 'icons/obj/doors/Doordiamond.dmi' + mineral = "diamond" + +/obj/machinery/door/airlock/uranium + name = "Uranium Airlock" + desc = "And they said I was crazy." + icon = 'icons/obj/doors/Dooruranium.dmi' + mineral = "uranium" + var/last_event = 0 + var/rad_power = 7.5 + +/obj/machinery/door/airlock/process() + // Deliberate no call to parent. + if(main_power_lost_until > 0 && world.time >= main_power_lost_until) + regainMainPower() + + if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until) + regainBackupPower() + + else if(electrified_until > 0 && world.time >= electrified_until) + electrify(0) + + if (..() == PROCESS_KILL && !(main_power_lost_until > 0 || backup_power_lost_until > 0 || electrified_until > 0)) + . = PROCESS_KILL + +/obj/machinery/door/airlock/uranium/process() + if(world.time > last_event+20) + if(prob(50)) + SSradiation.radiate(src, rad_power) + last_event = world.time + ..() + +/obj/machinery/door/airlock/phoron + name = "Phoron Airlock" + desc = "No way this can end badly." + icon = 'icons/obj/doors/Doorphoron.dmi' + mineral = "phoron" + +/obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300) + PhoronBurn(exposed_temperature) + +/obj/machinery/door/airlock/phoron/proc/ignite(exposed_temperature) + if(exposed_temperature > 300) + PhoronBurn(exposed_temperature) + +/obj/machinery/door/airlock/phoron/proc/PhoronBurn(temperature) + for(var/turf/simulated/floor/target_tile in range(2,loc)) + target_tile.assume_gas("phoron", 35, 400+T0C) + spawn (0) target_tile.hotspot_expose(temperature, 400) + for(var/turf/simulated/wall/W in range(3,src)) + W.burn((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame + for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) + D.ignite(temperature/4) + new/obj/structure/door_assembly( src.loc ) + qdel(src) + +/obj/machinery/door/airlock/sandstone + name = "Sandstone Airlock" + icon = 'icons/obj/doors/Doorsand.dmi' + mineral = "sandstone" + +/obj/machinery/door/airlock/science + name = "Research Airlock" + icon = 'icons/obj/doors/Doorsci.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_science + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/glass_science + name = "Glass Airlocks" + icon = 'icons/obj/doors/Doorsciglass.dmi' + opacity = 0 + assembly_type = /obj/structure/door_assembly/door_assembly_science + glass = 1 + req_one_access = list(access_research) + open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. + department_open_powered = 'sound/machines/door/sci1o.ogg' + department_close_powered = 'sound/machines/door/sci1c.ogg' + +/obj/machinery/door/airlock/highsecurity + name = "Secure Airlock" + icon = 'icons/obj/doors/hightechsecurity.dmi' + explosion_resistance = 20 + secured_wires = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity + req_one_access = list(access_heads_vault) + open_sound_powered = 'sound/machines/door/secure1o.ogg' + close_sound_powered = 'sound/machines/door/secure1c.ogg' + +/obj/machinery/door/airlock/voidcraft + name = "voidcraft hatch" + desc = "It's an extra resilient airlock intended for spacefaring vessels." + icon = 'icons/obj/doors/shuttledoors.dmi' + explosion_resistance = 20 + opacity = 0 + glass = 1 + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' + +// Airlock opens from top-bottom instead of left-right. +/obj/machinery/door/airlock/voidcraft/vertical + icon = 'icons/obj/doors/shuttledoors_vertical.dmi' + assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical + open_sound_powered = 'sound/machines/door/shuttle1o.ogg' + close_sound_powered = 'sound/machines/door/shuttle1c.ogg' + + +/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock + name = "Precursor Alpha Object - Doors" + desc = "This object appears to be used in order to restrict or allow access to \ + rooms based on its physical state. In other words, a door. \ + Despite being designed and created by unknown ancient alien hands, this door has \ + a large number of similarities to the conventional airlock, such as being driven by \ + electricity, opening and closing by physically moving, and being air tight. \ + It also operates by responding to signals through internal electrical conduits. \ + These characteristics make it possible for one with experience with a multitool \ + to manipulate the door.\ +

\ + The symbol on the door does not match any living species' patterns, giving further \ + implications that this door is very old, and yet it remains operational after \ + thousands of years. It is unknown if that is due to superb construction, or \ + unseen autonomous maintenance having been performed." + value = CATALOGUER_REWARD_EASY + +/obj/machinery/door/airlock/alien + name = "alien airlock" + desc = "You're fairly sure this is a door." + catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock) + icon = 'icons/obj/doors/Dooralien.dmi' + explosion_resistance = 20 + secured_wires = TRUE + hackProof = TRUE + assembly_type = /obj/structure/door_assembly/door_assembly_alien + req_one_access = list(access_alien) + +/obj/machinery/door/airlock/alien/locked + icon_state = "door_locked" + locked = TRUE + +/obj/machinery/door/airlock/alien/public // Entry to UFO. + req_one_access = list() + normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside. + hackProof = TRUE //VOREStation Edit - No borgos + +/* +About the new airlock wires panel: +* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires. +* one wire from the ID scanner. Sending a pulse through this flashes the red light on the door (if the door has power). If you cut this wire, the door will stop recognizing valid IDs. (If the door has 0000 access, it still opens and closes, though) +* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be open, but bolts-raising will not work. Cutting these wires may electrocute the user. +* one wire for door bolts. Sending a pulse through this drops door bolts (whether the door is powered or not) or raises them (if it is). Cutting this wire also drops the door bolts, and mending it does not raise them. If the wire is cut, trying to raise the door bolts will not work. +* two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. +* one wire for opening the door. Sending a pulse through this while the door has power makes it open the door if no access is required. +* one wire for AI control. Sending a pulse through this blocks AI control for a second or so (which is enough to see the AI control light on the panel dialog go off and back on again). Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. +* one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. (Currently it is also STAYING electrified until someone mends the wire) +* one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit. +* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick. +*/ + + + +/obj/machinery/door/airlock/bumpopen(mob/living/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite + if(!issilicon(usr)) + if(src.isElectrified()) + if(!src.justzap) + if(src.shock(user, 100)) + src.justzap = 1 + spawn (10) + src.justzap = 0 + return + else /*if(src.justzap)*/ + return + else if(user.hallucination > 50 && prob(10) && src.operating == 0) + to_chat(user, "You feel a powerful shock course through your body!") + user.halloss += 10 + user.stunned += 10 + return + ..(user) + +/obj/machinery/door/airlock/proc/isElectrified() + if(src.electrified_until != 0) + return 1 + return 0 + +/obj/machinery/door/airlock/proc/canAIControl() + return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); + +/obj/machinery/door/airlock/proc/canAIHack() + return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerLoss())); + +/obj/machinery/door/airlock/proc/arePowerSystemsOn() + if (stat & (NOPOWER|BROKEN)) + return 0 + return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) + +/obj/machinery/door/airlock/requiresID() + return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner) + +/obj/machinery/door/airlock/proc/isAllPowerLoss() + if(stat & (NOPOWER|BROKEN)) + return 1 + if(mainPowerCablesCut() && backupPowerCablesCut()) + return 1 + return 0 + +/obj/machinery/door/airlock/proc/mainPowerCablesCut() + return wires.is_cut(WIRE_MAIN_POWER1) || wires.is_cut(WIRE_MAIN_POWER2) + +/obj/machinery/door/airlock/proc/backupPowerCablesCut() + return wires.is_cut(WIRE_BACKUP_POWER1) || wires.is_cut(WIRE_BACKUP_POWER2) + +/obj/machinery/door/airlock/proc/loseMainPower() + main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) + + // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running + if(backup_power_lost_until == -1 && !backupPowerCablesCut()) + backup_power_lost_until = world.time + SecondsToTicks(10) + + if(main_power_lost_until > 0 || backup_power_lost_until > 0) + START_MACHINE_PROCESSING(src) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) + + update_icon() + +/obj/machinery/door/airlock/proc/loseBackupPower() + backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) + + if(backup_power_lost_until > 0) + START_MACHINE_PROCESSING(src) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) + + update_icon() + +/obj/machinery/door/airlock/proc/regainMainPower() + if(!mainPowerCablesCut()) + main_power_lost_until = 0 + // If backup power is currently active then disable, otherwise let it count down and disable itself later + if(!backup_power_lost_until) + backup_power_lost_until = -1 + + update_icon() + +/obj/machinery/door/airlock/proc/regainBackupPower() + if(!backupPowerCablesCut()) + // Restore backup power only if main power is offline, otherwise permanently disable + backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0 + + update_icon() + +/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) + var/message = "" + if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn()) + message = text("The electrification wire is cut - Door permanently electrified.") + src.electrified_until = -1 + else if(duration && !arePowerSystemsOn()) + message = text("The door is unpowered - Cannot electrify the door.") + src.electrified_until = 0 + else if(!duration && electrified_until != 0) + message = "The door is now un-electrified." + src.electrified_until = 0 + else if(duration) //electrify door for the given duration seconds + if(usr) + shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") + add_attack_logs(usr,name,"Electrified a door") + else + shockedby += text("\[[time_stamp()]\] - EMP)") + message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." + src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) + + if(electrified_until > 0) + START_MACHINE_PROCESSING(src) + + if(feedback && message) + to_chat(usr,message) + +/obj/machinery/door/airlock/proc/set_idscan(var/activate, var/feedback = 0) + var/message = "" + if(wires.is_cut(WIRE_IDSCAN)) + message = "The IdScan wire is cut - IdScan feature permanently disabled." + else if(activate && src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 0 + message = "IdScan feature has been enabled." + else if(!activate && !src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 1 + message = "IdScan feature has been disabled." + + if(feedback && message) + to_chat(usr,message) + +/obj/machinery/door/airlock/proc/set_safeties(var/activate, var/feedback = 0) + var/message = "" + // Safeties! We don't need no stinking safeties! + if (wires.is_cut(WIRE_SAFETY)) + message = text("The safety wire is cut - Cannot enable safeties.") + else if (!activate && src.safe) + safe = 0 + else if (activate && !src.safe) + safe = 1 + + if(feedback && message) + to_chat(usr,message) + +// shock user with probability prb (if all connections & power are working) +// returns 1 if shocked, 0 otherwise +// The preceding comment was borrowed from the grille's shock script +/obj/machinery/door/airlock/shock(mob/user, prb) + if(!arePowerSystemsOn()) + return 0 + if(hasShocked) + return 0 //Already shocked someone recently? + if(..()) + hasShocked = 1 + sleep(10) + hasShocked = 0 + return 1 + else + return 0 + + +/obj/machinery/door/airlock/update_icon() + cut_overlays() + if(density) + if(locked && lights && src.arePowerSystemsOn()) + icon_state = "door_locked" + else + icon_state = "door_closed" + if(p_open || welded) + if(p_open) + add_overlay("panel_open") + if (!(stat & NOPOWER)) + if(stat & BROKEN) + add_overlay("sparks_broken") + else if (health < maxhealth * 3/4) + add_overlay("sparks_damaged") + if(welded) + add_overlay("welded") + else if (health < maxhealth * 3/4 && !(stat & NOPOWER)) + add_overlay("sparks_damaged") + else + icon_state = "door_open" + if((stat & BROKEN) && !(stat & NOPOWER)) + add_overlay("sparks_open") + return + +/obj/machinery/door/airlock/do_animate(animation) + switch(animation) + if("opening") + cut_overlay() + if(p_open) + spawn(2) // The only work around that works. Downside is that the door will be gone for a millisecond. + flick("o_door_opening", src) //can not use flick due to BYOND bug updating overlays right before flicking + update_icon() + else + flick("door_opening", src)//[stat ? "_stat":] + update_icon() + if("closing") + cut_overlay() + if(p_open) + spawn(2) + flick("o_door_closing", src) + update_icon() + else + flick("door_closing", src) + update_icon() + if("spark") + if(density) + flick("door_spark", src) + if("deny") + if(density && src.arePowerSystemsOn()) + flick("door_deny", src) + playsound(src, denied_sound, 50, 0, 3) + return + +/obj/machinery/door/airlock/attack_ai(mob/user as mob) + tgui_interact(user) + +/obj/machinery/door/airlock/attack_ghost(mob/user) + tgui_interact(user) + +/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AiAirlock", name) + ui.open() + if(custom_state) + ui.set_state(custom_state) + return TRUE + +/obj/machinery/door/airlock/tgui_data(mob/user) + var/list/data = list() + + var/list/power = list() + power["main"] = main_power_lost_until > 0 ? 0 : 2 + power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) + power["backup"] = backup_power_lost_until > 0 ? 0 : 2 + power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) + data["power"] = power + + data["shock"] = (electrified_until == 0) ? 2 : 0 + data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) + data["id_scanner"] = !aiDisabledIdScanner + data["locked"] = locked // bolted + data["lights"] = lights // bolt lights + data["safe"] = safe // safeties + data["speed"] = normalspeed // safe speed + data["welded"] = welded // welded + data["opened"] = !density // opened + + var/list/wire = list() + wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1) + wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2) + wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1) + wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2) + wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY) + wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN) + wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS) + wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT) + wire["safe"] = !wires.is_cut(WIRE_SAFETY) + wire["timing"] = !wires.is_cut(WIRE_SPEED) + + data["wires"] = wire + return data + +/obj/machinery/door/airlock/proc/hack(mob/user as mob) + if(src.aiHacking==0) + src.aiHacking=1 + spawn(20) + //TODO: Make this take a minute + to_chat(user, "Airlock AI control has been blocked. Beginning fault-detection.") + sleep(50) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Fault confirmed: airlock control wire disabled or cut.") + sleep(20) + to_chat(user, "Attempting to hack into airlock. This may take some time.") + sleep(200) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Upload access confirmed. Loading control program into airlock software.") + sleep(170) + if(src.canAIControl()) + to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") + src.aiHacking=0 + return + else if(!src.canAIHack(user)) + to_chat(user, "We've lost our connection! Unable to hack airlock.") + src.aiHacking=0 + return + to_chat(user, "Transfer complete. Forcing airlock to execute program.") + sleep(50) + //disable blocked control + src.aiControlDisabled = 2 + to_chat(user, "Receiving control information from airlock.") + sleep(10) + //bring up airlock dialog + src.aiHacking = 0 + if (user) + src.attack_ai(user) + +/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target) + if (src.isElectrified()) + if (istype(mover, /obj/item)) + var/obj/item/i = mover + if (i.matter && (DEFAULT_WALL_MATERIAL in i.matter) && i.matter[DEFAULT_WALL_MATERIAL] > 0) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + return ..() + +/obj/machinery/door/airlock/attack_hand(mob/user as mob) + if(!istype(usr, /mob/living/silicon)) + if(src.isElectrified()) + if(src.shock(user, 100)) + return + + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/X = user + if(istype(X.species, /datum/species/xenos)) + src.attack_alien(user) + return + + if(src.p_open) + user.set_machine(src) + wires.Interact(user) + else + ..(user) + return + +/obj/machinery/door/airlock/tgui_act(action, params) + if(..()) + return TRUE + if(!user_allowed(usr)) + return TRUE + + switch(action) + if("disrupt-main") + if(!main_power_lost_until) + loseMainPower() + update_icon() + else + to_chat(usr, "Main power is already offline.") + . = TRUE + if("disrupt-backup") + if(!backup_power_lost_until) + loseBackupPower() + update_icon() + else + to_chat(usr, "Backup power is already offline.") + . = TRUE + if("shock-restore") + electrify(0, 1) + . = TRUE + if("shock-temp") + electrify(30, 1) + . = TRUE + if("shock-perm") + electrify(-1, 1) + . = TRUE + if("idscan-toggle") + set_idscan(aiDisabledIdScanner, 1) + . = TRUE + // if("emergency-toggle") + // toggle_emergency(usr) + // . = TRUE + if("bolt-toggle") + toggle_bolt(usr) + . = TRUE + if("light-toggle") + if(wires.is_cut(WIRE_BOLT_LIGHT)) + to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") + return + lights = !lights + update_icon() + . = TRUE + if("safe-toggle") + set_safeties(!safe, 1) + . = TRUE + if("speed-toggle") + if(wires.is_cut(WIRE_SPEED)) + to_chat(usr, "The timing wire is cut - Cannot alter timing.") + return + normalspeed = !normalspeed + . = TRUE + if("open-close") + user_toggle_open(usr) + . = TRUE + + update_icon() + return 1 + +/obj/machinery/door/airlock/proc/user_allowed(mob/user) + var/allowed = (issilicon(user) && canAIControl(user)) + if(!allowed && isobserver(user)) + var/mob/observer/dead/D = user + if(D.can_admin_interact()) + allowed = TRUE + return allowed + +/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) + if(!user_allowed(user)) + return + if(wires.is_cut(WIRE_DOOR_BOLTS)) + to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") + return + if(locked) + if(!arePowerSystemsOn()) + to_chat(user, "The door has no power - you can't raise the door bolts.") + else + unlock() + to_chat(user, "The door bolts have been raised.") + // log_combat(user, src, "unbolted") + else + lock() + to_chat(user, "The door bolts have been dropped.") + // log_combat(user, src, "bolted") + +/obj/machinery/door/airlock/proc/user_toggle_open(mob/user) + if(!user_allowed(user)) + return + if(welded) + to_chat(user, text("The airlock has been welded shut!")) + else if(locked) + to_chat(user, text("The door bolts are down!")) + else if(!density) + close() + else + open() + +/obj/machinery/door/airlock/proc/can_remove_electronics() + return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) + +/obj/machinery/door/airlock/attackby(obj/item/C, mob/user as mob) + //to_world("airlock attackby src [src] obj [C] mob [user]") + if(!istype(usr, /mob/living/silicon)) + if(src.isElectrified()) + if(src.shock(user, 75)) + return + if(istype(C, /obj/item/taperoll)) + return + + src.add_fingerprint(user) + if (attempt_vr(src,"attackby_vr",list(C, user))) return + if(istype(C, /mob/living)) + ..() + return + if(!repairing && istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(0,user)) + if(!src.welded) + src.welded = 1 + else + src.welded = null + playsound(src, C.usesound, 75, 1) + src.update_icon() + return + else + return + else if(C.is_screwdriver()) + if (src.p_open) + if (stat & BROKEN) + to_chat(usr, "The panel is broken and cannot be closed.") + else + src.p_open = 0 + playsound(src, C.usesound, 50, 1) + else + src.p_open = 1 + playsound(src, C.usesound, 50, 1) + src.update_icon() + else if(C.is_wirecutter()) + return src.attack_hand(user) + else if(istype(C, /obj/item/device/multitool)) + return src.attack_hand(user) + else if(istype(C, /obj/item/device/assembly/signaler)) + return src.attack_hand(user) + else if(istype(C, /obj/item/weapon/pai_cable)) // -- TLE + var/obj/item/weapon/pai_cable/cable = C + cable.plugin(src, user) + else if(!repairing && C.is_crowbar()) + if(can_remove_electronics()) + playsound(src, C.usesound, 75, 1) + user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.") + if(do_after(user,40 * C.toolspeed)) + to_chat(user, "You removed the airlock electronics!") + + var/obj/structure/door_assembly/da = new assembly_type(src.loc) + if (istype(da, /obj/structure/door_assembly/multi_tile)) + da.set_dir(src.dir) + + da.anchored = 1 + if(mineral) + da.glass = mineral + //else if(glass) + else if(glass && !da.glass) + da.glass = 1 + da.state = 1 + da.created_name = src.name + da.update_state() + + if(operating == -1 || (stat & BROKEN)) + new /obj/item/weapon/circuitboard/broken(src.loc) + operating = 0 + else + if (!electronics) create_electronics() + + electronics.loc = src.loc + electronics = null + + qdel(src) + return + else if(arePowerSystemsOn()) + to_chat(user, "The airlock's motors resist your efforts to force it.") + else if(locked) + to_chat(user, "The airlock's bolts prevent it from being forced.") + else + if(density) + spawn(0) open(1) + else + spawn(0) close(1) + + // Check if we're using a crowbar or armblade, and if the airlock's unpowered for whatever reason (off, broken, etc). + else if(istype(C, /obj/item/weapon)) + var/obj/item/weapon/W = C + if((W.pry == 1) && !arePowerSystemsOn()) + if(locked) + to_chat(user, "The airlock's bolts prevent it from being forced.") + else if( !welded && !operating ) + if(istype(C, /obj/item/weapon/material/twohanded/fireaxe)) // If this is a fireaxe, make sure it's held in two hands. + var/obj/item/weapon/material/twohanded/fireaxe/F = C + if(!F.wielded) + to_chat(user, "You need to be wielding \the [F] to do that.") + return + // At this point, it's an armblade or a fireaxe that passed the wielded test, let's try to open it. + if(density) + spawn(0) + open(1) + else + spawn(0) + close(1) + else + ..() + else + ..() + return + +/obj/machinery/door/airlock/phoron/attackby(C as obj, mob/user as mob) + if(C) + ignite(is_hot(C)) + ..() + +/obj/machinery/door/airlock/set_broken() + src.p_open = 1 + stat |= BROKEN + if (secured_wires) + lock() + for (var/mob/O in viewers(src, null)) + if ((O.client && !( O.blinded ))) + O.show_message("[src.name]'s control panel bursts open, sparks spewing out!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + + update_icon() + return + +/obj/machinery/door/airlock/open(var/forced=0) + if(!can_open(forced)) + return 0 + use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people + + //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) // Do we have old sounds enabled? Play these even if we have department door sounds enabled. + if(arePowerSystemsOn()) + sound = legacy_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_open_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_open_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else // Else, play these. + if(arePowerSystemsOn()) + sound = open_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) + + if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) + src.closeOther.close() + return ..() + +/obj/machinery/door/airlock/can_open(var/forced=0) + if(!forced) + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) + return 0 + + if(locked || welded) + return 0 + return ..() + +/obj/machinery/door/airlock/can_close(var/forced=0) + if(locked || welded) + return 0 + + if(!forced) + //despite the name, this wire is for general door control. + if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) + return 0 + + return ..() + +/atom/movable/proc/blocks_airlock() + return density + +/obj/machinery/door/blocks_airlock() + return 0 + +/obj/machinery/mech_sensor/blocks_airlock() + return 0 + +/mob/living/blocks_airlock() + return 1 + +/atom/movable/proc/airlock_crush(var/crush_damage) + return 0 + +/obj/machinery/portable_atmospherics/canister/airlock_crush(var/crush_damage) + . = ..() + health -= crush_damage + healthcheck() + +/obj/effect/energy_field/airlock_crush(var/crush_damage) + adjust_strength(crush_damage) + +/obj/structure/closet/airlock_crush(var/crush_damage) + ..() + damage(crush_damage) + for(var/atom/movable/AM in src) + AM.airlock_crush() + return 1 + +/mob/living/airlock_crush(var/crush_damage) + . = ..() + adjustBruteLoss(crush_damage) + SetStunned(5) + SetWeakened(5) + var/turf/T = get_turf(src) + T.add_blood(src) + return 1 + +/mob/living/carbon/airlock_crush(var/crush_damage) + . = ..() + if(can_feel_pain()) + emote("scream") + +/mob/living/silicon/robot/airlock_crush(var/crush_damage) + adjustBruteLoss(crush_damage) + return 0 + +/obj/machinery/door/airlock/close(var/forced=0) + if(!can_close(forced)) + return 0 + + if(safe) + for(var/turf/turf in locs) + for(var/atom/movable/AM in turf) + if(AM.blocks_airlock()) + if(!has_beeped) + playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) + has_beeped = 1 + autoclose_in(6) + return + + for(var/turf/turf in locs) + for(var/atom/movable/AM in turf) + if(AM.airlock_crush(DOOR_CRUSH_DAMAGE)) + take_damage(DOOR_CRUSH_DAMAGE) + + use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people + has_beeped = 0 + for(var/P in player_list) + var/mob/M = P + if(!M || !M.client) + continue + var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) + var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) + var/sound + var/volume + if(old_sounds) + if(arePowerSystemsOn()) + sound = legacy_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else if(!old_sounds && department_door_sounds && src.department_close_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. + if(arePowerSystemsOn()) + sound = department_close_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + else + if(arePowerSystemsOn()) + sound = close_sound_powered + volume = 50 + else + sound = open_sound_unpowered + volume = 75 + + var/turf/T = get_turf(M) + var/distance = get_dist(T, get_turf(src)) + if(distance <= world.view * 2) + if(T && T.z == get_z(src)) + M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) + for(var/turf/turf in locs) + var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) + if(killthis) + killthis.ex_act(2)//Smashin windows + return ..() + +/obj/machinery/door/airlock/proc/lock(var/forced=0) + if(locked) + return 0 + + if (operating && !forced) return 0 + + src.locked = 1 + playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) + for(var/mob/M in range(1,src)) + M.show_message("You hear a click from the bottom of the door.", 2) + update_icon() + return 1 + +/obj/machinery/door/airlock/proc/unlock(var/forced=0) + if(!src.locked) + return + + if (!forced) + if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return + + src.locked = 0 + playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) + for(var/mob/M in range(1,src)) + M.show_message("You hear a click from the bottom of the door.", 2) + update_icon() + return 1 + +/obj/machinery/door/airlock/allowed(mob/M) + if(locked) + return 0 + return ..(M) + +/obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) + ..() + + //if assembly is given, create the new door from the assembly + if (assembly && istype(assembly)) + assembly_type = assembly.type + + electronics = assembly.electronics + electronics.loc = src + + //update the door's access to match the electronics' + secured_wires = electronics.secure + if(electronics.one_access) + LAZYCLEARLIST(req_access) + req_one_access = src.electronics.conf_access + else + LAZYCLEARLIST(req_one_access) + req_access = src.electronics.conf_access + + //get the name from the assembly + if(assembly.created_name) + name = assembly.created_name + else + name = "[istext(assembly.glass) ? "[assembly.glass] airlock" : assembly.base_name]" + + //get the dir from the assembly + set_dir(assembly.dir) + + //wires + var/turf/T = get_turf(newloc) + if(T && (T.z in using_map.admin_levels)) + secured_wires = 1 + if (secured_wires) + wires = new/datum/wires/airlock/secure(src) + else + wires = new/datum/wires/airlock(src) + +/obj/machinery/door/airlock/Initialize() + if(src.closeOtherId != null) + for (var/obj/machinery/door/airlock/A in machines) + if(A.closeOtherId == src.closeOtherId && A != src) + src.closeOther = A + break + name = "\improper [name]" + . = ..() + +/obj/machinery/door/airlock/Destroy() + qdel(wires) + wires = null + return ..() + +// Most doors will never be deconstructed over the course of a round, +// so as an optimization defer the creation of electronics until +// the airlock is deconstructed +/obj/machinery/door/airlock/proc/create_electronics() + //create new electronics + if (secured_wires) + src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) + else + src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) + + //update the electronics to match the door's access + if(LAZYLEN(req_access)) + electronics.conf_access = req_access + else if (LAZYLEN(req_one_access)) + electronics.conf_access = req_one_access + electronics.one_access = 1 + +/obj/machinery/door/airlock/emp_act(var/severity) + if(prob(40/severity)) + var/duration = world.time + SecondsToTicks(30 / severity) + if(duration > electrified_until) + electrify(duration) + ..() + +/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason + ..() + if(stat & NOPOWER) + // If we lost power, disable electrification + // Keeping door lights on, runs on internal battery or something. + electrified_until = 0 + update_icon() + +/obj/machinery/door/airlock/proc/prison_open() + if(arePowerSystemsOn()) + src.unlock() + src.open() + src.lock() + return + + +/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + // Old RCD code made it cost 10 units to decon an airlock. + // Now the new one costs ten "sheets". + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 + ) + return FALSE + +/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + return FALSE +>>>>>>> 0051e96509... Merge pull request #10610 from VOREStation/Arokha/machinerybreak diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 1900811c8a..4ecc95b7c3 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -111,6 +111,11 @@ Class Procs: var/clickvol = 40 // volume var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/obj/item/weapon/circuitboard/circuit = null + + // 0.0 - 1.0 multipler for prob() based on bullet structure damage + // So if this is 1.0 then a 100 damage bullet will always break this structure + // If this is 0.5 then a 50 damage bullet will break this structure 25% of the time + var/bullet_vulnerability = 0.25 var/speed_process = FALSE //If false, SSmachines. If true, SSfastprocess. @@ -181,15 +186,15 @@ Class Procs: /obj/machinery/ex_act(severity) switch(severity) if(1.0) - qdel(src) + fall_apart(severity) return if(2.0) if(prob(50)) - qdel(src) + fall_apart(severity) return if(3.0) if(prob(25)) - qdel(src) + fall_apart(severity) return else return @@ -476,6 +481,85 @@ Class Procs: qdel(src) return 1 +/obj/machinery/bullet_act(obj/item/projectile/P, def_zone) + . = ..() + if(prob(P.get_structure_damage() * bullet_vulnerability)) + fall_apart() + +/** + * Like an angrier dismantle, where it destroys some of the parts and doesn't give you a frame + ** severity: Same severities as ex_act (so lower is more destructive) + ** scatter: If you want the parts to slide around 1 turf in random directions + */ +/obj/machinery/proc/fall_apart(var/severity = 3, var/scatter = TRUE) + var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() + spark_system.set_up(5, 0, src) + spark_system.attach(src) + + var/atom/droploc = drop_location() + if(!droploc || !contents.len) // not even a circuit? + playsound(src, 'sound/machines/machine_die_short.ogg') + spark_system.start() + qdel(spark_system) + qdel(src) + return + + var/list/surviving_parts = list() + // Deleting IDs is lame, unless this is like nuclear severity + if(severity != 1) + for(var/obj/item/weapon/card/id/I in contents) + surviving_parts |= I + + // May populate some items to throw around + if(!LAZYLEN(component_parts) && circuit) + circuit.apply_default_parts(src) + + var/survivability + switch(severity) + // No survivors + if(1) + survivability = 0 + + // 1 part survives + if(2) + survivability = 0 + var/atom/movable/picked_part = pick(contents) + if(istype(picked_part)) + surviving_parts |= picked_part + + // 50% of parts destroyed on average + if(3) + survivability = 50 + + // No parts destroyed, but you lose the frame + else + survivability = 100 + + for(var/atom/movable/P in contents) + if(prob(survivability)) + surviving_parts |= P + + if(circuit && severity >= 2) + var/datum/frame/frame_types/FT = circuit.board_type + if(istype(FT)) + // Some steel from the frame, but about half + surviving_parts += new /obj/item/stack/material/steel(null, max(1,round(FT.frame_size/2))) + // Two bits of cable, but not the 5 required to rebuild + surviving_parts += new /obj/item/stack/cable_coil(null, 1) + surviving_parts += new /obj/item/stack/cable_coil(null, 1) + + for(var/a in surviving_parts) + var/atom/movable/A = a + A.forceMove(droploc) + if(scatter && isturf(droploc)) + var/turf/T = droploc + A.Move(get_step(T, pick(alldirs))) + + playsound(src, 'sound/machines/machine_die_short.ogg') + spark_system.start() + qdel(spark_system) + qdel(src) + /datum/proc/apply_visual(mob/M) M.sight = 0 //Just reset their mesons and stuff so they can't use them, by default. return diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 365fda6b50..ac091a9fdb 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -460,8 +460,7 @@ GLOBAL_LIST_EMPTY(smeses) ..() /obj/machinery/power/smes/bullet_act(var/obj/item/projectile/Proj) - if(Proj.damage_type == BRUTE || Proj.damage_type == BURN) - take_damage(Proj.damage) + take_damage(Proj.get_structure_damage()) /obj/machinery/power/smes/ex_act(var/severity) // Two strong explosions will destroy a SMES. diff --git a/sound/machines/machine_die_short.ogg b/sound/machines/machine_die_short.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6aac3e93564c13d2fb091285e9768464635760fa GIT binary patch literal 23746 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 rbAAiOo5x}Ecy^ojop Date: Wed, 23 Jun 2021 15:10:01 -0700 Subject: [PATCH 2/2] powder that makes you say yes --- code/game/machinery/doors/airlock.dm | 3072 +------------------------- 1 file changed, 4 insertions(+), 3068 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0e1431e65c..610879f327 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD //VOREStation Edit - Redone a lot of airlock things: /* - Specific department maintenance doors @@ -14,6 +13,10 @@ power_channel = ENVIRON explosion_resistance = 10 + + // Doors do their own stuff + bullet_vulnerability = 0 + blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. @@ -1531,3070 +1534,3 @@ About the new airlock wires panel: qdel(src) return TRUE return FALSE -||||||| parent of 0051e96509... Merge pull request #10610 from VOREStation/Arokha/machinerybreak -//VOREStation Edit - Redone a lot of airlock things: -/* -- Specific department maintenance doors -- Named doors properly according to type -- Gave them default access levels with the access constants -- Improper'd all of the names in the new() -*/ - -/obj/machinery/door/airlock - name = "Airlock" - icon = 'icons/obj/doors/Doorint.dmi' - icon_state = "door_closed" - power_channel = ENVIRON - - explosion_resistance = 10 - blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime - - var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. - var/hackProof = 0 // if 1, this door can't be hacked by the AI - var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. - var/main_power_lost_until = 0 //World time when main power is restored. - var/backup_power_lost_until = -1 //World time when backup power is restored. - var/has_beeped = 0 //If 1, will not beep on failed closing attempt. Resets when door closes. - var/spawnPowerRestoreRunning = 0 - var/welded = null - var/locked = 0 - var/lights = 1 // bolt lights show by default - var/aiDisabledIdScanner = 0 - var/aiHacking = 0 - var/obj/machinery/door/airlock/closeOther = null - var/closeOtherId = null - var/lockdownbyai = 0 - autoclose = 1 - var/assembly_type = /obj/structure/door_assembly - var/mineral = null - var/justzap = 0 - var/safe = 1 - normalspeed = 1 - var/obj/item/weapon/airlock_electronics/electronics = null - var/hasShocked = 0 //Prevents multiple shocks from happening - var/secured_wires = 0 - var/datum/wires/airlock/wires = null - - var/open_sound_powered = 'sound/machines/door/covert1o.ogg' - var/open_sound_unpowered = 'sound/machines/door/airlockforced.ogg' - var/close_sound_powered = 'sound/machines/door/covert1c.ogg' - var/legacy_open_powered = 'sound/machines/door/old_airlock.ogg' - var/legacy_close_powered = 'sound/machines/door/old_airlockclose.ogg' - var/department_open_powered = null - var/department_close_powered = null - var/denied_sound = 'sound/machines/deniedbeep.ogg' - var/bolt_up_sound = 'sound/machines/door/boltsup.ogg' - var/bolt_down_sound = 'sound/machines/door/boltsdown.ogg' - -/obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) - if(stat & (BROKEN|NOPOWER)) - if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) - if(src.locked || src.welded) - visible_message("\The [user] begins breaking into \the [src] internals!") - user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. - if(do_after(user,10 SECONDS,src)) - src.locked = 0 - src.welded = 0 - update_icon() - open(1) - if(prob(25)) - src.shock(user, 100) - user.set_AI_busy(FALSE) - else if(src.density) - visible_message("\The [user] forces \the [src] open!") - open(1) - else - visible_message("\The [user] forces \the [src] closed!") - close(1) - else - visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") - return - ..() - -/obj/machinery/door/airlock/attack_alien(var/mob/user) //Familiar, right? Doors. -Mechoid - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/X = user - if(istype(X.species, /datum/species/xenos)) - if(src.locked || src.welded) - visible_message("\The [user] begins digging into \the [src] internals!") - src.do_animate("deny") - if(do_after(user,5 SECONDS,src)) - visible_message("\The [user] forces \the [src] open, sparks flying from its electronics!") - src.do_animate("spark") - playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) - src.locked = 0 - src.welded = 0 - update_icon() - open(1) - src.emag_act() - else if(src.density) - visible_message("\The [user] begins forcing \the [src] open!") - if(do_after(user, 5 SECONDS,src)) - playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) - visible_message("\The [user] forces \the [src] open!") - open(1) - else - visible_message("\The [user] forces \the [src] closed!") - close(1) - else - src.do_animate("deny") - visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") - return - ..() - -/obj/machinery/door/airlock/get_material() - if(mineral) - return get_material_by_name(mineral) - return get_material_by_name(DEFAULT_WALL_MATERIAL) - -/obj/machinery/door/airlock/command - name = "Command Airlock" - icon = 'icons/obj/doors/Doorcom.dmi' - req_one_access = list(access_heads) - assembly_type = /obj/structure/door_assembly/door_assembly_com - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cmd3o.ogg' - department_close_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/security - name = "Security Airlock" - icon = 'icons/obj/doors/Doorsec.dmi' - req_one_access = list(access_security) - assembly_type = /obj/structure/door_assembly/door_assembly_sec - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sec1o.ogg' - department_close_powered = 'sound/machines/door/sec1c.ogg' - -/obj/machinery/door/airlock/engineering - name = "Engineering Airlock" - icon = 'icons/obj/doors/Dooreng.dmi' - req_one_access = list(access_engine) - assembly_type = /obj/structure/door_assembly/door_assembly_eng - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/engineeringatmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Doorengatmos.dmi' - req_one_access = list(access_atmospherics) - assembly_type = /obj/structure/door_assembly/door_assembly_eat - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/medical - name = "Medical Airlock" - icon = 'icons/obj/doors/Doormed.dmi' - req_one_access = list(access_medical) - assembly_type = /obj/structure/door_assembly/door_assembly_med - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/med1o.ogg' - department_close_powered = 'sound/machines/door/med1c.ogg' - -/obj/machinery/door/airlock/maintenance - name = "Maintenance Access" - icon = 'icons/obj/doors/Doormaint.dmi' - //req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access - assembly_type = /obj/structure/door_assembly/door_assembly_mai - open_sound_powered = 'sound/machines/door/door2o.ogg' - close_sound_powered = 'sound/machines/door/door2c.ogg' - -/obj/machinery/door/airlock/maintenance/cargo - icon = 'icons/obj/doors/Doormaint_cargo.dmi' - req_one_access = list(access_cargo) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/door2o.ogg' - department_close_powered = 'sound/machines/door/door2c.ogg' - -/obj/machinery/door/airlock/maintenance/command - icon = 'icons/obj/doors/Doormaint_command.dmi' - req_one_access = list(access_heads) - -/obj/machinery/door/airlock/maintenance/common - icon = 'icons/obj/doors/Doormaint_common.dmi' - open_sound_powered = 'sound/machines/door/hall3o.ogg' - close_sound_powered = 'sound/machines/door/hall3c.ogg' - -/obj/machinery/door/airlock/maintenance/engi - icon = 'icons/obj/doors/Doormaint_engi.dmi' - req_one_access = list(access_engine) - -/obj/machinery/door/airlock/maintenance/int - icon = 'icons/obj/doors/Doormaint_int.dmi' - -/obj/machinery/door/airlock/maintenance/medical - icon = 'icons/obj/doors/Doormaint_med.dmi' - req_one_access = list(access_medical) - -/obj/machinery/door/airlock/maintenance/rnd - icon = 'icons/obj/doors/Doormaint_rnd.dmi' - req_one_access = list(access_research) - -/obj/machinery/door/airlock/maintenance/sec - icon = 'icons/obj/doors/Doormaint_sec.dmi' - req_one_access = list(access_security) - -/obj/machinery/door/airlock/external - name = "External Airlock" - icon = 'icons/obj/doors/Doorext.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_ext - open_sound_powered = 'sound/machines/door/space1o.ogg' - close_sound_powered = 'sound/machines/door/space1c.ogg' - -/obj/machinery/door/airlock/external/glass/bolted - icon_state = "door_locked" // So it looks visibly bolted in map editor - locked = 1 - -// For convenience in making docking ports: one that is pre-bolted with frequency set! -/obj/machinery/door/airlock/external/glass/bolted/cycling - frequency = 1379 - -/obj/machinery/door/airlock/glass_external - name = "External Airlock" - icon = 'icons/obj/doors/Doorextglass.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_ext - opacity = 0 - glass = 1 - req_one_access = list(access_external_airlocks) - open_sound_powered = 'sound/machines/door/space1o.ogg' - close_sound_powered = 'sound/machines/door/space1c.ogg' - -/obj/machinery/door/airlock/glass - name = "Glass Airlock" - icon = 'icons/obj/doors/Doorglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - open_sound_powered = 'sound/machines/door/hall1o.ogg' - close_sound_powered = 'sound/machines/door/hall1c.ogg' - legacy_open_powered = 'sound/machines/door/windowdoor.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - glass = 1 - -/obj/machinery/door/airlock/centcom - name = "Centcom Airlock" - icon = 'icons/obj/doors/Doorele.dmi' - req_one_access = list(access_cent_general) - opacity = 1 - open_sound_powered = 'sound/machines/door/cmd3o.ogg' - close_sound_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/glass_centcom - name = "Airlock" - icon = 'icons/obj/doors/Dooreleglass.dmi' - opacity = 0 - glass = 1 - open_sound_powered = 'sound/machines/door/cmd3o.ogg' - close_sound_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/vault - name = "Vault" - icon = 'icons/obj/doors/vault.dmi' - explosion_resistance = 20 - opacity = 1 - secured_wires = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. - req_one_access = list(access_heads_vault) - open_sound_powered = 'sound/machines/door/vault1o.ogg' - close_sound_powered = 'sound/machines/door/vault1c.ogg' - -/obj/machinery/door/airlock/vault/bolted - icon_state = "door_locked" - locked = 1 - -/obj/machinery/door/airlock/freezer - name = "Freezer Airlock" - icon = 'icons/obj/doors/Doorfreezer.dmi' - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_fre - -/obj/machinery/door/airlock/hatch - name = "Airtight Hatch" - icon = 'icons/obj/doors/Doorhatchele.dmi' - explosion_resistance = 20 - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_hatch - req_one_access = list(access_maint_tunnels) - open_sound_powered = 'sound/machines/door/hatchopen.ogg' - close_sound_powered = 'sound/machines/door/hatchclose.ogg' - open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' - -/obj/machinery/door/airlock/maintenance_hatch - name = "Maintenance Hatch" - icon = 'icons/obj/doors/Doorhatchmaint2.dmi' - explosion_resistance = 20 - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_mhatch - req_one_access = list(access_maint_tunnels) - open_sound_powered = 'sound/machines/door/hatchopen.ogg' - close_sound_powered = 'sound/machines/door/hatchclose.ogg' - open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' - -/obj/machinery/door/airlock/glass_command - name = "Command Airlock" - icon = 'icons/obj/doors/Doorcomglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_com - glass = 1 - req_one_access = list(access_heads) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cmd1o.ogg' - department_close_powered = 'sound/machines/door/cmd1c.ogg' - -/obj/machinery/door/airlock/glass_engineering - name = "Engineering Airlock" - icon = 'icons/obj/doors/Doorengglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_eng - glass = 1 - req_one_access = list(access_engine) - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/glass_engineeringatmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Doorengatmoglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_eat - glass = 1 - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/glass_security - name = "Security Airlock" - icon = 'icons/obj/doors/Doorsecglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_sec - glass = 1 - req_one_access = list(access_security) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sec1o.ogg' - department_close_powered = 'sound/machines/door/sec1c.ogg' - -/obj/machinery/door/airlock/glass_medical - name = "Medical Airlock" - icon = 'icons/obj/doors/Doormedglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_med - glass = 1 - req_one_access = list(access_medical) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/med1o.ogg' - department_close_powered = 'sound/machines/door/med1c.ogg' - -/obj/machinery/door/airlock/mining - name = "Mining Airlock" - icon = 'icons/obj/doors/Doormining.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_min - req_one_access = list(access_mining) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cgo1o.ogg' - department_close_powered = 'sound/machines/door/cgo1c.ogg' - -/obj/machinery/door/airlock/atmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Dooratmo.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_atmo - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/research - name = "Research Airlock" - icon = 'icons/obj/doors/Doorresearch.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_research - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_research - name = "Research Airlock" - icon = 'icons/obj/doors/Doorresearchglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_research - glass = 1 - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_mining - name = "Mining Airlock" - icon = 'icons/obj/doors/Doorminingglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_min - glass = 1 - req_one_access = list(access_mining) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cgo1o.ogg' - department_close_powered = 'sound/machines/door/cgo1c.ogg' - -/obj/machinery/door/airlock/glass_atmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Dooratmoglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_atmo - glass = 1 - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/gold - name = "Gold Airlock" - icon = 'icons/obj/doors/Doorgold.dmi' - mineral = "gold" - -/obj/machinery/door/airlock/silver - name = "Silver Airlock" - icon = 'icons/obj/doors/Doorsilver.dmi' - mineral = "silver" - -/obj/machinery/door/airlock/diamond - name = "Diamond Airlock" - icon = 'icons/obj/doors/Doordiamond.dmi' - mineral = "diamond" - -/obj/machinery/door/airlock/uranium - name = "Uranium Airlock" - desc = "And they said I was crazy." - icon = 'icons/obj/doors/Dooruranium.dmi' - mineral = "uranium" - var/last_event = 0 - var/rad_power = 7.5 - -/obj/machinery/door/airlock/process() - // Deliberate no call to parent. - if(main_power_lost_until > 0 && world.time >= main_power_lost_until) - regainMainPower() - - if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until) - regainBackupPower() - - else if(electrified_until > 0 && world.time >= electrified_until) - electrify(0) - - if (..() == PROCESS_KILL && !(main_power_lost_until > 0 || backup_power_lost_until > 0 || electrified_until > 0)) - . = PROCESS_KILL - -/obj/machinery/door/airlock/uranium/process() - if(world.time > last_event+20) - if(prob(50)) - SSradiation.radiate(src, rad_power) - last_event = world.time - ..() - -/obj/machinery/door/airlock/phoron - name = "Phoron Airlock" - desc = "No way this can end badly." - icon = 'icons/obj/doors/Doorphoron.dmi' - mineral = "phoron" - -/obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - PhoronBurn(exposed_temperature) - -/obj/machinery/door/airlock/phoron/proc/ignite(exposed_temperature) - if(exposed_temperature > 300) - PhoronBurn(exposed_temperature) - -/obj/machinery/door/airlock/phoron/proc/PhoronBurn(temperature) - for(var/turf/simulated/floor/target_tile in range(2,loc)) - target_tile.assume_gas("phoron", 35, 400+T0C) - spawn (0) target_tile.hotspot_expose(temperature, 400) - for(var/turf/simulated/wall/W in range(3,src)) - W.burn((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame - for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) - D.ignite(temperature/4) - new/obj/structure/door_assembly( src.loc ) - qdel(src) - -/obj/machinery/door/airlock/sandstone - name = "Sandstone Airlock" - icon = 'icons/obj/doors/Doorsand.dmi' - mineral = "sandstone" - -/obj/machinery/door/airlock/science - name = "Research Airlock" - icon = 'icons/obj/doors/Doorsci.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_science - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_science - name = "Glass Airlocks" - icon = 'icons/obj/doors/Doorsciglass.dmi' - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_science - glass = 1 - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/highsecurity - name = "Secure Airlock" - icon = 'icons/obj/doors/hightechsecurity.dmi' - explosion_resistance = 20 - secured_wires = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity - req_one_access = list(access_heads_vault) - open_sound_powered = 'sound/machines/door/secure1o.ogg' - close_sound_powered = 'sound/machines/door/secure1c.ogg' - -/obj/machinery/door/airlock/voidcraft - name = "voidcraft hatch" - desc = "It's an extra resilient airlock intended for spacefaring vessels." - icon = 'icons/obj/doors/shuttledoors.dmi' - explosion_resistance = 20 - opacity = 0 - glass = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft - open_sound_powered = 'sound/machines/door/shuttle1o.ogg' - close_sound_powered = 'sound/machines/door/shuttle1c.ogg' - -// Airlock opens from top-bottom instead of left-right. -/obj/machinery/door/airlock/voidcraft/vertical - icon = 'icons/obj/doors/shuttledoors_vertical.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical - open_sound_powered = 'sound/machines/door/shuttle1o.ogg' - close_sound_powered = 'sound/machines/door/shuttle1c.ogg' - - -/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock - name = "Precursor Alpha Object - Doors" - desc = "This object appears to be used in order to restrict or allow access to \ - rooms based on its physical state. In other words, a door. \ - Despite being designed and created by unknown ancient alien hands, this door has \ - a large number of similarities to the conventional airlock, such as being driven by \ - electricity, opening and closing by physically moving, and being air tight. \ - It also operates by responding to signals through internal electrical conduits. \ - These characteristics make it possible for one with experience with a multitool \ - to manipulate the door.\ -

\ - The symbol on the door does not match any living species' patterns, giving further \ - implications that this door is very old, and yet it remains operational after \ - thousands of years. It is unknown if that is due to superb construction, or \ - unseen autonomous maintenance having been performed." - value = CATALOGUER_REWARD_EASY - -/obj/machinery/door/airlock/alien - name = "alien airlock" - desc = "You're fairly sure this is a door." - catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock) - icon = 'icons/obj/doors/Dooralien.dmi' - explosion_resistance = 20 - secured_wires = TRUE - hackProof = TRUE - assembly_type = /obj/structure/door_assembly/door_assembly_alien - req_one_access = list(access_alien) - -/obj/machinery/door/airlock/alien/locked - icon_state = "door_locked" - locked = TRUE - -/obj/machinery/door/airlock/alien/public // Entry to UFO. - req_one_access = list() - normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside. - hackProof = TRUE //VOREStation Edit - No borgos - -/* -About the new airlock wires panel: -* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires. -* one wire from the ID scanner. Sending a pulse through this flashes the red light on the door (if the door has power). If you cut this wire, the door will stop recognizing valid IDs. (If the door has 0000 access, it still opens and closes, though) -* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be open, but bolts-raising will not work. Cutting these wires may electrocute the user. -* one wire for door bolts. Sending a pulse through this drops door bolts (whether the door is powered or not) or raises them (if it is). Cutting this wire also drops the door bolts, and mending it does not raise them. If the wire is cut, trying to raise the door bolts will not work. -* two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. -* one wire for opening the door. Sending a pulse through this while the door has power makes it open the door if no access is required. -* one wire for AI control. Sending a pulse through this blocks AI control for a second or so (which is enough to see the AI control light on the panel dialog go off and back on again). Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. -* one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. (Currently it is also STAYING electrified until someone mends the wire) -* one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit. -* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick. -*/ - - - -/obj/machinery/door/airlock/bumpopen(mob/living/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if(!issilicon(usr)) - if(src.isElectrified()) - if(!src.justzap) - if(src.shock(user, 100)) - src.justzap = 1 - spawn (10) - src.justzap = 0 - return - else /*if(src.justzap)*/ - return - else if(user.hallucination > 50 && prob(10) && src.operating == 0) - to_chat(user, "You feel a powerful shock course through your body!") - user.halloss += 10 - user.stunned += 10 - return - ..(user) - -/obj/machinery/door/airlock/proc/isElectrified() - if(src.electrified_until != 0) - return 1 - return 0 - -/obj/machinery/door/airlock/proc/canAIControl() - return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); - -/obj/machinery/door/airlock/proc/canAIHack() - return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerLoss())); - -/obj/machinery/door/airlock/proc/arePowerSystemsOn() - if (stat & (NOPOWER|BROKEN)) - return 0 - return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) - -/obj/machinery/door/airlock/requiresID() - return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner) - -/obj/machinery/door/airlock/proc/isAllPowerLoss() - if(stat & (NOPOWER|BROKEN)) - return 1 - if(mainPowerCablesCut() && backupPowerCablesCut()) - return 1 - return 0 - -/obj/machinery/door/airlock/proc/mainPowerCablesCut() - return wires.is_cut(WIRE_MAIN_POWER1) || wires.is_cut(WIRE_MAIN_POWER2) - -/obj/machinery/door/airlock/proc/backupPowerCablesCut() - return wires.is_cut(WIRE_BACKUP_POWER1) || wires.is_cut(WIRE_BACKUP_POWER2) - -/obj/machinery/door/airlock/proc/loseMainPower() - main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) - - // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running - if(backup_power_lost_until == -1 && !backupPowerCablesCut()) - backup_power_lost_until = world.time + SecondsToTicks(10) - - if(main_power_lost_until > 0 || backup_power_lost_until > 0) - START_MACHINE_PROCESSING(src) - - // Disable electricity if required - if(electrified_until && isAllPowerLoss()) - electrify(0) - - update_icon() - -/obj/machinery/door/airlock/proc/loseBackupPower() - backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) - - if(backup_power_lost_until > 0) - START_MACHINE_PROCESSING(src) - - // Disable electricity if required - if(electrified_until && isAllPowerLoss()) - electrify(0) - - update_icon() - -/obj/machinery/door/airlock/proc/regainMainPower() - if(!mainPowerCablesCut()) - main_power_lost_until = 0 - // If backup power is currently active then disable, otherwise let it count down and disable itself later - if(!backup_power_lost_until) - backup_power_lost_until = -1 - - update_icon() - -/obj/machinery/door/airlock/proc/regainBackupPower() - if(!backupPowerCablesCut()) - // Restore backup power only if main power is offline, otherwise permanently disable - backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0 - - update_icon() - -/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) - var/message = "" - if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn()) - message = text("The electrification wire is cut - Door permanently electrified.") - src.electrified_until = -1 - else if(duration && !arePowerSystemsOn()) - message = text("The door is unpowered - Cannot electrify the door.") - src.electrified_until = 0 - else if(!duration && electrified_until != 0) - message = "The door is now un-electrified." - src.electrified_until = 0 - else if(duration) //electrify door for the given duration seconds - if(usr) - shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") - add_attack_logs(usr,name,"Electrified a door") - else - shockedby += text("\[[time_stamp()]\] - EMP)") - message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." - src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) - - if(electrified_until > 0) - START_MACHINE_PROCESSING(src) - - if(feedback && message) - to_chat(usr,message) - -/obj/machinery/door/airlock/proc/set_idscan(var/activate, var/feedback = 0) - var/message = "" - if(wires.is_cut(WIRE_IDSCAN)) - message = "The IdScan wire is cut - IdScan feature permanently disabled." - else if(activate && src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 0 - message = "IdScan feature has been enabled." - else if(!activate && !src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 1 - message = "IdScan feature has been disabled." - - if(feedback && message) - to_chat(usr,message) - -/obj/machinery/door/airlock/proc/set_safeties(var/activate, var/feedback = 0) - var/message = "" - // Safeties! We don't need no stinking safeties! - if (wires.is_cut(WIRE_SAFETY)) - message = text("The safety wire is cut - Cannot enable safeties.") - else if (!activate && src.safe) - safe = 0 - else if (activate && !src.safe) - safe = 1 - - if(feedback && message) - to_chat(usr,message) - -// shock user with probability prb (if all connections & power are working) -// returns 1 if shocked, 0 otherwise -// The preceding comment was borrowed from the grille's shock script -/obj/machinery/door/airlock/shock(mob/user, prb) - if(!arePowerSystemsOn()) - return 0 - if(hasShocked) - return 0 //Already shocked someone recently? - if(..()) - hasShocked = 1 - sleep(10) - hasShocked = 0 - return 1 - else - return 0 - - -/obj/machinery/door/airlock/update_icon() - cut_overlays() - if(density) - if(locked && lights && src.arePowerSystemsOn()) - icon_state = "door_locked" - else - icon_state = "door_closed" - if(p_open || welded) - if(p_open) - add_overlay("panel_open") - if (!(stat & NOPOWER)) - if(stat & BROKEN) - add_overlay("sparks_broken") - else if (health < maxhealth * 3/4) - add_overlay("sparks_damaged") - if(welded) - add_overlay("welded") - else if (health < maxhealth * 3/4 && !(stat & NOPOWER)) - add_overlay("sparks_damaged") - else - icon_state = "door_open" - if((stat & BROKEN) && !(stat & NOPOWER)) - add_overlay("sparks_open") - return - -/obj/machinery/door/airlock/do_animate(animation) - switch(animation) - if("opening") - cut_overlay() - if(p_open) - spawn(2) // The only work around that works. Downside is that the door will be gone for a millisecond. - flick("o_door_opening", src) //can not use flick due to BYOND bug updating overlays right before flicking - update_icon() - else - flick("door_opening", src)//[stat ? "_stat":] - update_icon() - if("closing") - cut_overlay() - if(p_open) - spawn(2) - flick("o_door_closing", src) - update_icon() - else - flick("door_closing", src) - update_icon() - if("spark") - if(density) - flick("door_spark", src) - if("deny") - if(density && src.arePowerSystemsOn()) - flick("door_deny", src) - playsound(src, denied_sound, 50, 0, 3) - return - -/obj/machinery/door/airlock/attack_ai(mob/user as mob) - tgui_interact(user) - -/obj/machinery/door/airlock/attack_ghost(mob/user) - tgui_interact(user) - -/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AiAirlock", name) - ui.open() - if(custom_state) - ui.set_state(custom_state) - return TRUE - -/obj/machinery/door/airlock/tgui_data(mob/user) - var/list/data = list() - - var/list/power = list() - power["main"] = main_power_lost_until > 0 ? 0 : 2 - power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) - power["backup"] = backup_power_lost_until > 0 ? 0 : 2 - power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) - data["power"] = power - - data["shock"] = (electrified_until == 0) ? 2 : 0 - data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) - data["id_scanner"] = !aiDisabledIdScanner - data["locked"] = locked // bolted - data["lights"] = lights // bolt lights - data["safe"] = safe // safeties - data["speed"] = normalspeed // safe speed - data["welded"] = welded // welded - data["opened"] = !density // opened - - var/list/wire = list() - wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1) - wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2) - wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1) - wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2) - wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY) - wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN) - wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS) - wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT) - wire["safe"] = !wires.is_cut(WIRE_SAFETY) - wire["timing"] = !wires.is_cut(WIRE_SPEED) - - data["wires"] = wire - return data - -/obj/machinery/door/airlock/proc/hack(mob/user as mob) - if(src.aiHacking==0) - src.aiHacking=1 - spawn(20) - //TODO: Make this take a minute - to_chat(user, "Airlock AI control has been blocked. Beginning fault-detection.") - sleep(50) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Fault confirmed: airlock control wire disabled or cut.") - sleep(20) - to_chat(user, "Attempting to hack into airlock. This may take some time.") - sleep(200) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Upload access confirmed. Loading control program into airlock software.") - sleep(170) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Transfer complete. Forcing airlock to execute program.") - sleep(50) - //disable blocked control - src.aiControlDisabled = 2 - to_chat(user, "Receiving control information from airlock.") - sleep(10) - //bring up airlock dialog - src.aiHacking = 0 - if (user) - src.attack_ai(user) - -/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target) - if (src.isElectrified()) - if (istype(mover, /obj/item)) - var/obj/item/i = mover - if (i.matter && (DEFAULT_WALL_MATERIAL in i.matter) && i.matter[DEFAULT_WALL_MATERIAL] > 0) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - return ..() - -/obj/machinery/door/airlock/attack_hand(mob/user as mob) - if(!istype(usr, /mob/living/silicon)) - if(src.isElectrified()) - if(src.shock(user, 100)) - return - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/X = user - if(istype(X.species, /datum/species/xenos)) - src.attack_alien(user) - return - - if(src.p_open) - user.set_machine(src) - wires.Interact(user) - else - ..(user) - return - -/obj/machinery/door/airlock/tgui_act(action, params) - if(..()) - return TRUE - if(!user_allowed(usr)) - return TRUE - - switch(action) - if("disrupt-main") - if(!main_power_lost_until) - loseMainPower() - update_icon() - else - to_chat(usr, "Main power is already offline.") - . = TRUE - if("disrupt-backup") - if(!backup_power_lost_until) - loseBackupPower() - update_icon() - else - to_chat(usr, "Backup power is already offline.") - . = TRUE - if("shock-restore") - electrify(0, 1) - . = TRUE - if("shock-temp") - electrify(30, 1) - . = TRUE - if("shock-perm") - electrify(-1, 1) - . = TRUE - if("idscan-toggle") - set_idscan(aiDisabledIdScanner, 1) - . = TRUE - // if("emergency-toggle") - // toggle_emergency(usr) - // . = TRUE - if("bolt-toggle") - toggle_bolt(usr) - . = TRUE - if("light-toggle") - if(wires.is_cut(WIRE_BOLT_LIGHT)) - to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") - return - lights = !lights - update_icon() - . = TRUE - if("safe-toggle") - set_safeties(!safe, 1) - . = TRUE - if("speed-toggle") - if(wires.is_cut(WIRE_SPEED)) - to_chat(usr, "The timing wire is cut - Cannot alter timing.") - return - normalspeed = !normalspeed - . = TRUE - if("open-close") - user_toggle_open(usr) - . = TRUE - - update_icon() - return 1 - -/obj/machinery/door/airlock/proc/user_allowed(mob/user) - var/allowed = (issilicon(user) && canAIControl(user)) - if(!allowed && isobserver(user)) - var/mob/observer/dead/D = user - if(D.can_admin_interact()) - allowed = TRUE - return allowed - -/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) - if(!user_allowed(user)) - return - if(wires.is_cut(WIRE_DOOR_BOLTS)) - to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") - return - if(locked) - if(!arePowerSystemsOn()) - to_chat(user, "The door has no power - you can't raise the door bolts.") - else - unlock() - to_chat(user, "The door bolts have been raised.") - // log_combat(user, src, "unbolted") - else - lock() - to_chat(user, "The door bolts have been dropped.") - // log_combat(user, src, "bolted") - -/obj/machinery/door/airlock/proc/user_toggle_open(mob/user) - if(!user_allowed(user)) - return - if(welded) - to_chat(user, text("The airlock has been welded shut!")) - else if(locked) - to_chat(user, text("The door bolts are down!")) - else if(!density) - close() - else - open() - -/obj/machinery/door/airlock/proc/can_remove_electronics() - return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) - -/obj/machinery/door/airlock/attackby(obj/item/C, mob/user as mob) - //to_world("airlock attackby src [src] obj [C] mob [user]") - if(!istype(usr, /mob/living/silicon)) - if(src.isElectrified()) - if(src.shock(user, 75)) - return - if(istype(C, /obj/item/taperoll)) - return - - src.add_fingerprint(user) - if (attempt_vr(src,"attackby_vr",list(C, user))) return - if(istype(C, /mob/living)) - ..() - return - if(!repairing && istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density) - var/obj/item/weapon/weldingtool/W = C - if(W.remove_fuel(0,user)) - if(!src.welded) - src.welded = 1 - else - src.welded = null - playsound(src, C.usesound, 75, 1) - src.update_icon() - return - else - return - else if(C.is_screwdriver()) - if (src.p_open) - if (stat & BROKEN) - to_chat(usr, "The panel is broken and cannot be closed.") - else - src.p_open = 0 - playsound(src, C.usesound, 50, 1) - else - src.p_open = 1 - playsound(src, C.usesound, 50, 1) - src.update_icon() - else if(C.is_wirecutter()) - return src.attack_hand(user) - else if(istype(C, /obj/item/device/multitool)) - return src.attack_hand(user) - else if(istype(C, /obj/item/device/assembly/signaler)) - return src.attack_hand(user) - else if(istype(C, /obj/item/weapon/pai_cable)) // -- TLE - var/obj/item/weapon/pai_cable/cable = C - cable.plugin(src, user) - else if(!repairing && C.is_crowbar()) - if(can_remove_electronics()) - playsound(src, C.usesound, 75, 1) - user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.") - if(do_after(user,40 * C.toolspeed)) - to_chat(user, "You removed the airlock electronics!") - - var/obj/structure/door_assembly/da = new assembly_type(src.loc) - if (istype(da, /obj/structure/door_assembly/multi_tile)) - da.set_dir(src.dir) - - da.anchored = 1 - if(mineral) - da.glass = mineral - //else if(glass) - else if(glass && !da.glass) - da.glass = 1 - da.state = 1 - da.created_name = src.name - da.update_state() - - if(operating == -1 || (stat & BROKEN)) - new /obj/item/weapon/circuitboard/broken(src.loc) - operating = 0 - else - if (!electronics) create_electronics() - - electronics.loc = src.loc - electronics = null - - qdel(src) - return - else if(arePowerSystemsOn()) - to_chat(user, "The airlock's motors resist your efforts to force it.") - else if(locked) - to_chat(user, "The airlock's bolts prevent it from being forced.") - else - if(density) - spawn(0) open(1) - else - spawn(0) close(1) - - // Check if we're using a crowbar or armblade, and if the airlock's unpowered for whatever reason (off, broken, etc). - else if(istype(C, /obj/item/weapon)) - var/obj/item/weapon/W = C - if((W.pry == 1) && !arePowerSystemsOn()) - if(locked) - to_chat(user, "The airlock's bolts prevent it from being forced.") - else if( !welded && !operating ) - if(istype(C, /obj/item/weapon/material/twohanded/fireaxe)) // If this is a fireaxe, make sure it's held in two hands. - var/obj/item/weapon/material/twohanded/fireaxe/F = C - if(!F.wielded) - to_chat(user, "You need to be wielding \the [F] to do that.") - return - // At this point, it's an armblade or a fireaxe that passed the wielded test, let's try to open it. - if(density) - spawn(0) - open(1) - else - spawn(0) - close(1) - else - ..() - else - ..() - return - -/obj/machinery/door/airlock/phoron/attackby(C as obj, mob/user as mob) - if(C) - ignite(is_hot(C)) - ..() - -/obj/machinery/door/airlock/set_broken() - src.p_open = 1 - stat |= BROKEN - if (secured_wires) - lock() - for (var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message("[src.name]'s control panel bursts open, sparks spewing out!") - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - - update_icon() - return - -/obj/machinery/door/airlock/open(var/forced=0) - if(!can_open(forced)) - return 0 - use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people - - //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator - for(var/P in player_list) - var/mob/M = P - if(!M || !M.client) - continue - var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) - var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) - var/sound - var/volume - if(old_sounds) // Do we have old sounds enabled? Play these even if we have department door sounds enabled. - if(arePowerSystemsOn()) - sound = legacy_open_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else if(!old_sounds && department_door_sounds && src.department_open_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. - if(arePowerSystemsOn()) - sound = department_open_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else // Else, play these. - if(arePowerSystemsOn()) - sound = open_sound_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - - var/turf/T = get_turf(M) - var/distance = get_dist(T, get_turf(src)) - if(distance <= world.view * 2) - if(T && T.z == get_z(src)) - M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) - - if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) - src.closeOther.close() - return ..() - -/obj/machinery/door/airlock/can_open(var/forced=0) - if(!forced) - if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) - return 0 - - if(locked || welded) - return 0 - return ..() - -/obj/machinery/door/airlock/can_close(var/forced=0) - if(locked || welded) - return 0 - - if(!forced) - //despite the name, this wire is for general door control. - if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) - return 0 - - return ..() - -/atom/movable/proc/blocks_airlock() - return density - -/obj/machinery/door/blocks_airlock() - return 0 - -/obj/machinery/mech_sensor/blocks_airlock() - return 0 - -/mob/living/blocks_airlock() - return 1 - -/atom/movable/proc/airlock_crush(var/crush_damage) - return 0 - -/obj/machinery/portable_atmospherics/canister/airlock_crush(var/crush_damage) - . = ..() - health -= crush_damage - healthcheck() - -/obj/effect/energy_field/airlock_crush(var/crush_damage) - adjust_strength(crush_damage) - -/obj/structure/closet/airlock_crush(var/crush_damage) - ..() - damage(crush_damage) - for(var/atom/movable/AM in src) - AM.airlock_crush() - return 1 - -/mob/living/airlock_crush(var/crush_damage) - . = ..() - adjustBruteLoss(crush_damage) - SetStunned(5) - SetWeakened(5) - var/turf/T = get_turf(src) - T.add_blood(src) - return 1 - -/mob/living/carbon/airlock_crush(var/crush_damage) - . = ..() - if(can_feel_pain()) - emote("scream") - -/mob/living/silicon/robot/airlock_crush(var/crush_damage) - adjustBruteLoss(crush_damage) - return 0 - -/obj/machinery/door/airlock/close(var/forced=0) - if(!can_close(forced)) - return 0 - - if(safe) - for(var/turf/turf in locs) - for(var/atom/movable/AM in turf) - if(AM.blocks_airlock()) - if(!has_beeped) - playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) - has_beeped = 1 - autoclose_in(6) - return - - for(var/turf/turf in locs) - for(var/atom/movable/AM in turf) - if(AM.airlock_crush(DOOR_CRUSH_DAMAGE)) - take_damage(DOOR_CRUSH_DAMAGE) - - use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people - has_beeped = 0 - for(var/P in player_list) - var/mob/M = P - if(!M || !M.client) - continue - var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) - var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) - var/sound - var/volume - if(old_sounds) - if(arePowerSystemsOn()) - sound = legacy_close_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else if(!old_sounds && department_door_sounds && src.department_close_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. - if(arePowerSystemsOn()) - sound = department_close_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else - if(arePowerSystemsOn()) - sound = close_sound_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - - var/turf/T = get_turf(M) - var/distance = get_dist(T, get_turf(src)) - if(distance <= world.view * 2) - if(T && T.z == get_z(src)) - M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) - for(var/turf/turf in locs) - var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) - if(killthis) - killthis.ex_act(2)//Smashin windows - return ..() - -/obj/machinery/door/airlock/proc/lock(var/forced=0) - if(locked) - return 0 - - if (operating && !forced) return 0 - - src.locked = 1 - playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) - for(var/mob/M in range(1,src)) - M.show_message("You hear a click from the bottom of the door.", 2) - update_icon() - return 1 - -/obj/machinery/door/airlock/proc/unlock(var/forced=0) - if(!src.locked) - return - - if (!forced) - if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return - - src.locked = 0 - playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) - for(var/mob/M in range(1,src)) - M.show_message("You hear a click from the bottom of the door.", 2) - update_icon() - return 1 - -/obj/machinery/door/airlock/allowed(mob/M) - if(locked) - return 0 - return ..(M) - -/obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) - ..() - - //if assembly is given, create the new door from the assembly - if (assembly && istype(assembly)) - assembly_type = assembly.type - - electronics = assembly.electronics - electronics.loc = src - - //update the door's access to match the electronics' - secured_wires = electronics.secure - if(electronics.one_access) - LAZYCLEARLIST(req_access) - req_one_access = src.electronics.conf_access - else - LAZYCLEARLIST(req_one_access) - req_access = src.electronics.conf_access - - //get the name from the assembly - if(assembly.created_name) - name = assembly.created_name - else - name = "[istext(assembly.glass) ? "[assembly.glass] airlock" : assembly.base_name]" - - //get the dir from the assembly - set_dir(assembly.dir) - - //wires - var/turf/T = get_turf(newloc) - if(T && (T.z in using_map.admin_levels)) - secured_wires = 1 - if (secured_wires) - wires = new/datum/wires/airlock/secure(src) - else - wires = new/datum/wires/airlock(src) - -/obj/machinery/door/airlock/Initialize() - if(src.closeOtherId != null) - for (var/obj/machinery/door/airlock/A in machines) - if(A.closeOtherId == src.closeOtherId && A != src) - src.closeOther = A - break - name = "\improper [name]" - . = ..() - -/obj/machinery/door/airlock/Destroy() - qdel(wires) - wires = null - return ..() - -// Most doors will never be deconstructed over the course of a round, -// so as an optimization defer the creation of electronics until -// the airlock is deconstructed -/obj/machinery/door/airlock/proc/create_electronics() - //create new electronics - if (secured_wires) - src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) - else - src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) - - //update the electronics to match the door's access - if(LAZYLEN(req_access)) - electronics.conf_access = req_access - else if (LAZYLEN(req_one_access)) - electronics.conf_access = req_one_access - electronics.one_access = 1 - -/obj/machinery/door/airlock/emp_act(var/severity) - if(prob(40/severity)) - var/duration = world.time + SecondsToTicks(30 / severity) - if(duration > electrified_until) - electrify(duration) - ..() - -/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason - ..() - if(stat & NOPOWER) - // If we lost power, disable electrification - // Keeping door lights on, runs on internal battery or something. - electrified_until = 0 - update_icon() - -/obj/machinery/door/airlock/proc/prison_open() - if(arePowerSystemsOn()) - src.unlock() - src.open() - src.lock() - return - - -/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_DECONSTRUCT) - // Old RCD code made it cost 10 units to decon an airlock. - // Now the new one costs ten "sheets". - return list( - RCD_VALUE_MODE = RCD_DECONSTRUCT, - RCD_VALUE_DELAY = 5 SECONDS, - RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 - ) - return FALSE - -/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_DECONSTRUCT) - to_chat(user, span("notice", "You deconstruct \the [src].")) - qdel(src) - return TRUE - return FALSE -======= -//VOREStation Edit - Redone a lot of airlock things: -/* -- Specific department maintenance doors -- Named doors properly according to type -- Gave them default access levels with the access constants -- Improper'd all of the names in the new() -*/ - -/obj/machinery/door/airlock - name = "Airlock" - icon = 'icons/obj/doors/Doorint.dmi' - icon_state = "door_closed" - power_channel = ENVIRON - - explosion_resistance = 10 - - // Doors do their own stuff - bullet_vulnerability = 0 - - blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime - - var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. - var/hackProof = 0 // if 1, this door can't be hacked by the AI - var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. - var/main_power_lost_until = 0 //World time when main power is restored. - var/backup_power_lost_until = -1 //World time when backup power is restored. - var/has_beeped = 0 //If 1, will not beep on failed closing attempt. Resets when door closes. - var/spawnPowerRestoreRunning = 0 - var/welded = null - var/locked = 0 - var/lights = 1 // bolt lights show by default - var/aiDisabledIdScanner = 0 - var/aiHacking = 0 - var/obj/machinery/door/airlock/closeOther = null - var/closeOtherId = null - var/lockdownbyai = 0 - autoclose = 1 - var/assembly_type = /obj/structure/door_assembly - var/mineral = null - var/justzap = 0 - var/safe = 1 - normalspeed = 1 - var/obj/item/weapon/airlock_electronics/electronics = null - var/hasShocked = 0 //Prevents multiple shocks from happening - var/secured_wires = 0 - var/datum/wires/airlock/wires = null - - var/open_sound_powered = 'sound/machines/door/covert1o.ogg' - var/open_sound_unpowered = 'sound/machines/door/airlockforced.ogg' - var/close_sound_powered = 'sound/machines/door/covert1c.ogg' - var/legacy_open_powered = 'sound/machines/door/old_airlock.ogg' - var/legacy_close_powered = 'sound/machines/door/old_airlockclose.ogg' - var/department_open_powered = null - var/department_close_powered = null - var/denied_sound = 'sound/machines/deniedbeep.ogg' - var/bolt_up_sound = 'sound/machines/door/boltsup.ogg' - var/bolt_down_sound = 'sound/machines/door/boltsdown.ogg' - -/obj/machinery/door/airlock/attack_generic(var/mob/living/user, var/damage) - if(stat & (BROKEN|NOPOWER)) - if(damage >= STRUCTURE_MIN_DAMAGE_THRESHOLD) - if(src.locked || src.welded) - visible_message("\The [user] begins breaking into \the [src] internals!") - user.set_AI_busy(TRUE) // If the mob doesn't have an AI attached, this won't do anything. - if(do_after(user,10 SECONDS,src)) - src.locked = 0 - src.welded = 0 - update_icon() - open(1) - if(prob(25)) - src.shock(user, 100) - user.set_AI_busy(FALSE) - else if(src.density) - visible_message("\The [user] forces \the [src] open!") - open(1) - else - visible_message("\The [user] forces \the [src] closed!") - close(1) - else - visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") - return - ..() - -/obj/machinery/door/airlock/attack_alien(var/mob/user) //Familiar, right? Doors. -Mechoid - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/X = user - if(istype(X.species, /datum/species/xenos)) - if(src.locked || src.welded) - visible_message("\The [user] begins digging into \the [src] internals!") - src.do_animate("deny") - if(do_after(user,5 SECONDS,src)) - visible_message("\The [user] forces \the [src] open, sparks flying from its electronics!") - src.do_animate("spark") - playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) - src.locked = 0 - src.welded = 0 - update_icon() - open(1) - src.emag_act() - else if(src.density) - visible_message("\The [user] begins forcing \the [src] open!") - if(do_after(user, 5 SECONDS,src)) - playsound(src, 'sound/machines/door/airlock_creaking.ogg', 100, 1, volume_channel = VOLUME_CHANNEL_DOORS) - visible_message("\The [user] forces \the [src] open!") - open(1) - else - visible_message("\The [user] forces \the [src] closed!") - close(1) - else - src.do_animate("deny") - visible_message("\The [user] strains fruitlessly to force \the [src] [density ? "open" : "closed"].") - return - ..() - -/obj/machinery/door/airlock/get_material() - if(mineral) - return get_material_by_name(mineral) - return get_material_by_name(DEFAULT_WALL_MATERIAL) - -/obj/machinery/door/airlock/command - name = "Command Airlock" - icon = 'icons/obj/doors/Doorcom.dmi' - req_one_access = list(access_heads) - assembly_type = /obj/structure/door_assembly/door_assembly_com - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cmd3o.ogg' - department_close_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/security - name = "Security Airlock" - icon = 'icons/obj/doors/Doorsec.dmi' - req_one_access = list(access_security) - assembly_type = /obj/structure/door_assembly/door_assembly_sec - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sec1o.ogg' - department_close_powered = 'sound/machines/door/sec1c.ogg' - -/obj/machinery/door/airlock/engineering - name = "Engineering Airlock" - icon = 'icons/obj/doors/Dooreng.dmi' - req_one_access = list(access_engine) - assembly_type = /obj/structure/door_assembly/door_assembly_eng - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/engineeringatmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Doorengatmos.dmi' - req_one_access = list(access_atmospherics) - assembly_type = /obj/structure/door_assembly/door_assembly_eat - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/medical - name = "Medical Airlock" - icon = 'icons/obj/doors/Doormed.dmi' - req_one_access = list(access_medical) - assembly_type = /obj/structure/door_assembly/door_assembly_med - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/med1o.ogg' - department_close_powered = 'sound/machines/door/med1c.ogg' - -/obj/machinery/door/airlock/maintenance - name = "Maintenance Access" - icon = 'icons/obj/doors/Doormaint.dmi' - //req_one_access = list(access_maint_tunnels) //VOREStation Edit - Maintenance is open access - assembly_type = /obj/structure/door_assembly/door_assembly_mai - open_sound_powered = 'sound/machines/door/door2o.ogg' - close_sound_powered = 'sound/machines/door/door2c.ogg' - -/obj/machinery/door/airlock/maintenance/cargo - icon = 'icons/obj/doors/Doormaint_cargo.dmi' - req_one_access = list(access_cargo) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/door2o.ogg' - department_close_powered = 'sound/machines/door/door2c.ogg' - -/obj/machinery/door/airlock/maintenance/command - icon = 'icons/obj/doors/Doormaint_command.dmi' - req_one_access = list(access_heads) - -/obj/machinery/door/airlock/maintenance/common - icon = 'icons/obj/doors/Doormaint_common.dmi' - open_sound_powered = 'sound/machines/door/hall3o.ogg' - close_sound_powered = 'sound/machines/door/hall3c.ogg' - -/obj/machinery/door/airlock/maintenance/engi - icon = 'icons/obj/doors/Doormaint_engi.dmi' - req_one_access = list(access_engine) - -/obj/machinery/door/airlock/maintenance/int - icon = 'icons/obj/doors/Doormaint_int.dmi' - -/obj/machinery/door/airlock/maintenance/medical - icon = 'icons/obj/doors/Doormaint_med.dmi' - req_one_access = list(access_medical) - -/obj/machinery/door/airlock/maintenance/rnd - icon = 'icons/obj/doors/Doormaint_rnd.dmi' - req_one_access = list(access_research) - -/obj/machinery/door/airlock/maintenance/sec - icon = 'icons/obj/doors/Doormaint_sec.dmi' - req_one_access = list(access_security) - -/obj/machinery/door/airlock/external - name = "External Airlock" - icon = 'icons/obj/doors/Doorext.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_ext - open_sound_powered = 'sound/machines/door/space1o.ogg' - close_sound_powered = 'sound/machines/door/space1c.ogg' - -/obj/machinery/door/airlock/external/glass/bolted - icon_state = "door_locked" // So it looks visibly bolted in map editor - locked = 1 - -// For convenience in making docking ports: one that is pre-bolted with frequency set! -/obj/machinery/door/airlock/external/glass/bolted/cycling - frequency = 1379 - -/obj/machinery/door/airlock/glass_external - name = "External Airlock" - icon = 'icons/obj/doors/Doorextglass.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_ext - opacity = 0 - glass = 1 - req_one_access = list(access_external_airlocks) - open_sound_powered = 'sound/machines/door/space1o.ogg' - close_sound_powered = 'sound/machines/door/space1c.ogg' - -/obj/machinery/door/airlock/glass - name = "Glass Airlock" - icon = 'icons/obj/doors/Doorglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - open_sound_powered = 'sound/machines/door/hall1o.ogg' - close_sound_powered = 'sound/machines/door/hall1c.ogg' - legacy_open_powered = 'sound/machines/door/windowdoor.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - glass = 1 - -/obj/machinery/door/airlock/centcom - name = "Centcom Airlock" - icon = 'icons/obj/doors/Doorele.dmi' - req_one_access = list(access_cent_general) - opacity = 1 - open_sound_powered = 'sound/machines/door/cmd3o.ogg' - close_sound_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/glass_centcom - name = "Airlock" - icon = 'icons/obj/doors/Dooreleglass.dmi' - opacity = 0 - glass = 1 - open_sound_powered = 'sound/machines/door/cmd3o.ogg' - close_sound_powered = 'sound/machines/door/cmd3c.ogg' - -/obj/machinery/door/airlock/vault - name = "Vault" - icon = 'icons/obj/doors/vault.dmi' - explosion_resistance = 20 - opacity = 1 - secured_wires = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. - req_one_access = list(access_heads_vault) - open_sound_powered = 'sound/machines/door/vault1o.ogg' - close_sound_powered = 'sound/machines/door/vault1c.ogg' - -/obj/machinery/door/airlock/vault/bolted - icon_state = "door_locked" - locked = 1 - -/obj/machinery/door/airlock/freezer - name = "Freezer Airlock" - icon = 'icons/obj/doors/Doorfreezer.dmi' - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_fre - -/obj/machinery/door/airlock/hatch - name = "Airtight Hatch" - icon = 'icons/obj/doors/Doorhatchele.dmi' - explosion_resistance = 20 - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_hatch - req_one_access = list(access_maint_tunnels) - open_sound_powered = 'sound/machines/door/hatchopen.ogg' - close_sound_powered = 'sound/machines/door/hatchclose.ogg' - open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' - -/obj/machinery/door/airlock/maintenance_hatch - name = "Maintenance Hatch" - icon = 'icons/obj/doors/Doorhatchmaint2.dmi' - explosion_resistance = 20 - opacity = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_mhatch - req_one_access = list(access_maint_tunnels) - open_sound_powered = 'sound/machines/door/hatchopen.ogg' - close_sound_powered = 'sound/machines/door/hatchclose.ogg' - open_sound_unpowered = 'sound/machines/door/hatchforced.ogg' - -/obj/machinery/door/airlock/glass_command - name = "Command Airlock" - icon = 'icons/obj/doors/Doorcomglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_com - glass = 1 - req_one_access = list(access_heads) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cmd1o.ogg' - department_close_powered = 'sound/machines/door/cmd1c.ogg' - -/obj/machinery/door/airlock/glass_engineering - name = "Engineering Airlock" - icon = 'icons/obj/doors/Doorengglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_eng - glass = 1 - req_one_access = list(access_engine) - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/glass_engineeringatmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Doorengatmoglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_eat - glass = 1 - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/glass_security - name = "Security Airlock" - icon = 'icons/obj/doors/Doorsecglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_sec - glass = 1 - req_one_access = list(access_security) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sec1o.ogg' - department_close_powered = 'sound/machines/door/sec1c.ogg' - -/obj/machinery/door/airlock/glass_medical - name = "Medical Airlock" - icon = 'icons/obj/doors/Doormedglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_med - glass = 1 - req_one_access = list(access_medical) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/med1o.ogg' - department_close_powered = 'sound/machines/door/med1c.ogg' - -/obj/machinery/door/airlock/mining - name = "Mining Airlock" - icon = 'icons/obj/doors/Doormining.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_min - req_one_access = list(access_mining) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cgo1o.ogg' - department_close_powered = 'sound/machines/door/cgo1c.ogg' - -/obj/machinery/door/airlock/atmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Dooratmo.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_atmo - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/research - name = "Research Airlock" - icon = 'icons/obj/doors/Doorresearch.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_research - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_research - name = "Research Airlock" - icon = 'icons/obj/doors/Doorresearchglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_research - glass = 1 - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_mining - name = "Mining Airlock" - icon = 'icons/obj/doors/Doorminingglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_min - glass = 1 - req_one_access = list(access_mining) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/cgo1o.ogg' - department_close_powered = 'sound/machines/door/cgo1c.ogg' - -/obj/machinery/door/airlock/glass_atmos - name = "Atmospherics Airlock" - icon = 'icons/obj/doors/Dooratmoglass.dmi' - hitsound = 'sound/effects/Glasshit.ogg' - maxhealth = 300 - explosion_resistance = 5 - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_atmo - glass = 1 - req_one_access = list(access_atmospherics) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/eng1o.ogg' - department_close_powered = 'sound/machines/door/eng1c.ogg' - -/obj/machinery/door/airlock/gold - name = "Gold Airlock" - icon = 'icons/obj/doors/Doorgold.dmi' - mineral = "gold" - -/obj/machinery/door/airlock/silver - name = "Silver Airlock" - icon = 'icons/obj/doors/Doorsilver.dmi' - mineral = "silver" - -/obj/machinery/door/airlock/diamond - name = "Diamond Airlock" - icon = 'icons/obj/doors/Doordiamond.dmi' - mineral = "diamond" - -/obj/machinery/door/airlock/uranium - name = "Uranium Airlock" - desc = "And they said I was crazy." - icon = 'icons/obj/doors/Dooruranium.dmi' - mineral = "uranium" - var/last_event = 0 - var/rad_power = 7.5 - -/obj/machinery/door/airlock/process() - // Deliberate no call to parent. - if(main_power_lost_until > 0 && world.time >= main_power_lost_until) - regainMainPower() - - if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until) - regainBackupPower() - - else if(electrified_until > 0 && world.time >= electrified_until) - electrify(0) - - if (..() == PROCESS_KILL && !(main_power_lost_until > 0 || backup_power_lost_until > 0 || electrified_until > 0)) - . = PROCESS_KILL - -/obj/machinery/door/airlock/uranium/process() - if(world.time > last_event+20) - if(prob(50)) - SSradiation.radiate(src, rad_power) - last_event = world.time - ..() - -/obj/machinery/door/airlock/phoron - name = "Phoron Airlock" - desc = "No way this can end badly." - icon = 'icons/obj/doors/Doorphoron.dmi' - mineral = "phoron" - -/obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - PhoronBurn(exposed_temperature) - -/obj/machinery/door/airlock/phoron/proc/ignite(exposed_temperature) - if(exposed_temperature > 300) - PhoronBurn(exposed_temperature) - -/obj/machinery/door/airlock/phoron/proc/PhoronBurn(temperature) - for(var/turf/simulated/floor/target_tile in range(2,loc)) - target_tile.assume_gas("phoron", 35, 400+T0C) - spawn (0) target_tile.hotspot_expose(temperature, 400) - for(var/turf/simulated/wall/W in range(3,src)) - W.burn((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame - for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) - D.ignite(temperature/4) - new/obj/structure/door_assembly( src.loc ) - qdel(src) - -/obj/machinery/door/airlock/sandstone - name = "Sandstone Airlock" - icon = 'icons/obj/doors/Doorsand.dmi' - mineral = "sandstone" - -/obj/machinery/door/airlock/science - name = "Research Airlock" - icon = 'icons/obj/doors/Doorsci.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_science - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/glass_science - name = "Glass Airlocks" - icon = 'icons/obj/doors/Doorsciglass.dmi' - opacity = 0 - assembly_type = /obj/structure/door_assembly/door_assembly_science - glass = 1 - req_one_access = list(access_research) - open_sound_powered = 'sound/machines/door/hall1o.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - close_sound_powered = 'sound/machines/door/hall1c.ogg' // VOREStation Edit: Default door sounds for fancy, department-off. - department_open_powered = 'sound/machines/door/sci1o.ogg' - department_close_powered = 'sound/machines/door/sci1c.ogg' - -/obj/machinery/door/airlock/highsecurity - name = "Secure Airlock" - icon = 'icons/obj/doors/hightechsecurity.dmi' - explosion_resistance = 20 - secured_wires = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity - req_one_access = list(access_heads_vault) - open_sound_powered = 'sound/machines/door/secure1o.ogg' - close_sound_powered = 'sound/machines/door/secure1c.ogg' - -/obj/machinery/door/airlock/voidcraft - name = "voidcraft hatch" - desc = "It's an extra resilient airlock intended for spacefaring vessels." - icon = 'icons/obj/doors/shuttledoors.dmi' - explosion_resistance = 20 - opacity = 0 - glass = 1 - assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft - open_sound_powered = 'sound/machines/door/shuttle1o.ogg' - close_sound_powered = 'sound/machines/door/shuttle1c.ogg' - -// Airlock opens from top-bottom instead of left-right. -/obj/machinery/door/airlock/voidcraft/vertical - icon = 'icons/obj/doors/shuttledoors_vertical.dmi' - assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical - open_sound_powered = 'sound/machines/door/shuttle1o.ogg' - close_sound_powered = 'sound/machines/door/shuttle1c.ogg' - - -/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock - name = "Precursor Alpha Object - Doors" - desc = "This object appears to be used in order to restrict or allow access to \ - rooms based on its physical state. In other words, a door. \ - Despite being designed and created by unknown ancient alien hands, this door has \ - a large number of similarities to the conventional airlock, such as being driven by \ - electricity, opening and closing by physically moving, and being air tight. \ - It also operates by responding to signals through internal electrical conduits. \ - These characteristics make it possible for one with experience with a multitool \ - to manipulate the door.\ -

\ - The symbol on the door does not match any living species' patterns, giving further \ - implications that this door is very old, and yet it remains operational after \ - thousands of years. It is unknown if that is due to superb construction, or \ - unseen autonomous maintenance having been performed." - value = CATALOGUER_REWARD_EASY - -/obj/machinery/door/airlock/alien - name = "alien airlock" - desc = "You're fairly sure this is a door." - catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_airlock) - icon = 'icons/obj/doors/Dooralien.dmi' - explosion_resistance = 20 - secured_wires = TRUE - hackProof = TRUE - assembly_type = /obj/structure/door_assembly/door_assembly_alien - req_one_access = list(access_alien) - -/obj/machinery/door/airlock/alien/locked - icon_state = "door_locked" - locked = TRUE - -/obj/machinery/door/airlock/alien/public // Entry to UFO. - req_one_access = list() - normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside. - hackProof = TRUE //VOREStation Edit - No borgos - -/* -About the new airlock wires panel: -* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires. -* one wire from the ID scanner. Sending a pulse through this flashes the red light on the door (if the door has power). If you cut this wire, the door will stop recognizing valid IDs. (If the door has 0000 access, it still opens and closes, though) -* two wires for power. Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). Cutting either one disables the main door power, but unless backup power is also cut, the backup power re-powers the door in 10 seconds. While unpowered, the door may be open, but bolts-raising will not work. Cutting these wires may electrocute the user. -* one wire for door bolts. Sending a pulse through this drops door bolts (whether the door is powered or not) or raises them (if it is). Cutting this wire also drops the door bolts, and mending it does not raise them. If the wire is cut, trying to raise the door bolts will not work. -* two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. -* one wire for opening the door. Sending a pulse through this while the door has power makes it open the door if no access is required. -* one wire for AI control. Sending a pulse through this blocks AI control for a second or so (which is enough to see the AI control light on the panel dialog go off and back on again). Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. -* one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. (Currently it is also STAYING electrified until someone mends the wire) -* one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit. -* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick. -*/ - - - -/obj/machinery/door/airlock/bumpopen(mob/living/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if(!issilicon(usr)) - if(src.isElectrified()) - if(!src.justzap) - if(src.shock(user, 100)) - src.justzap = 1 - spawn (10) - src.justzap = 0 - return - else /*if(src.justzap)*/ - return - else if(user.hallucination > 50 && prob(10) && src.operating == 0) - to_chat(user, "You feel a powerful shock course through your body!") - user.halloss += 10 - user.stunned += 10 - return - ..(user) - -/obj/machinery/door/airlock/proc/isElectrified() - if(src.electrified_until != 0) - return 1 - return 0 - -/obj/machinery/door/airlock/proc/canAIControl() - return ((src.aiControlDisabled!=1) && (!src.isAllPowerLoss())); - -/obj/machinery/door/airlock/proc/canAIHack() - return ((src.aiControlDisabled==1) && (!hackProof) && (!src.isAllPowerLoss())); - -/obj/machinery/door/airlock/proc/arePowerSystemsOn() - if (stat & (NOPOWER|BROKEN)) - return 0 - return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) - -/obj/machinery/door/airlock/requiresID() - return !(wires.is_cut(WIRE_IDSCAN) || aiDisabledIdScanner) - -/obj/machinery/door/airlock/proc/isAllPowerLoss() - if(stat & (NOPOWER|BROKEN)) - return 1 - if(mainPowerCablesCut() && backupPowerCablesCut()) - return 1 - return 0 - -/obj/machinery/door/airlock/proc/mainPowerCablesCut() - return wires.is_cut(WIRE_MAIN_POWER1) || wires.is_cut(WIRE_MAIN_POWER2) - -/obj/machinery/door/airlock/proc/backupPowerCablesCut() - return wires.is_cut(WIRE_BACKUP_POWER1) || wires.is_cut(WIRE_BACKUP_POWER2) - -/obj/machinery/door/airlock/proc/loseMainPower() - main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) - - // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running - if(backup_power_lost_until == -1 && !backupPowerCablesCut()) - backup_power_lost_until = world.time + SecondsToTicks(10) - - if(main_power_lost_until > 0 || backup_power_lost_until > 0) - START_MACHINE_PROCESSING(src) - - // Disable electricity if required - if(electrified_until && isAllPowerLoss()) - electrify(0) - - update_icon() - -/obj/machinery/door/airlock/proc/loseBackupPower() - backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) - - if(backup_power_lost_until > 0) - START_MACHINE_PROCESSING(src) - - // Disable electricity if required - if(electrified_until && isAllPowerLoss()) - electrify(0) - - update_icon() - -/obj/machinery/door/airlock/proc/regainMainPower() - if(!mainPowerCablesCut()) - main_power_lost_until = 0 - // If backup power is currently active then disable, otherwise let it count down and disable itself later - if(!backup_power_lost_until) - backup_power_lost_until = -1 - - update_icon() - -/obj/machinery/door/airlock/proc/regainBackupPower() - if(!backupPowerCablesCut()) - // Restore backup power only if main power is offline, otherwise permanently disable - backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0 - - update_icon() - -/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) - var/message = "" - if(wires.is_cut(WIRE_ELECTRIFY) && arePowerSystemsOn()) - message = text("The electrification wire is cut - Door permanently electrified.") - src.electrified_until = -1 - else if(duration && !arePowerSystemsOn()) - message = text("The door is unpowered - Cannot electrify the door.") - src.electrified_until = 0 - else if(!duration && electrified_until != 0) - message = "The door is now un-electrified." - src.electrified_until = 0 - else if(duration) //electrify door for the given duration seconds - if(usr) - shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") - add_attack_logs(usr,name,"Electrified a door") - else - shockedby += text("\[[time_stamp()]\] - EMP)") - message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." - src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) - - if(electrified_until > 0) - START_MACHINE_PROCESSING(src) - - if(feedback && message) - to_chat(usr,message) - -/obj/machinery/door/airlock/proc/set_idscan(var/activate, var/feedback = 0) - var/message = "" - if(wires.is_cut(WIRE_IDSCAN)) - message = "The IdScan wire is cut - IdScan feature permanently disabled." - else if(activate && src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 0 - message = "IdScan feature has been enabled." - else if(!activate && !src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 1 - message = "IdScan feature has been disabled." - - if(feedback && message) - to_chat(usr,message) - -/obj/machinery/door/airlock/proc/set_safeties(var/activate, var/feedback = 0) - var/message = "" - // Safeties! We don't need no stinking safeties! - if (wires.is_cut(WIRE_SAFETY)) - message = text("The safety wire is cut - Cannot enable safeties.") - else if (!activate && src.safe) - safe = 0 - else if (activate && !src.safe) - safe = 1 - - if(feedback && message) - to_chat(usr,message) - -// shock user with probability prb (if all connections & power are working) -// returns 1 if shocked, 0 otherwise -// The preceding comment was borrowed from the grille's shock script -/obj/machinery/door/airlock/shock(mob/user, prb) - if(!arePowerSystemsOn()) - return 0 - if(hasShocked) - return 0 //Already shocked someone recently? - if(..()) - hasShocked = 1 - sleep(10) - hasShocked = 0 - return 1 - else - return 0 - - -/obj/machinery/door/airlock/update_icon() - cut_overlays() - if(density) - if(locked && lights && src.arePowerSystemsOn()) - icon_state = "door_locked" - else - icon_state = "door_closed" - if(p_open || welded) - if(p_open) - add_overlay("panel_open") - if (!(stat & NOPOWER)) - if(stat & BROKEN) - add_overlay("sparks_broken") - else if (health < maxhealth * 3/4) - add_overlay("sparks_damaged") - if(welded) - add_overlay("welded") - else if (health < maxhealth * 3/4 && !(stat & NOPOWER)) - add_overlay("sparks_damaged") - else - icon_state = "door_open" - if((stat & BROKEN) && !(stat & NOPOWER)) - add_overlay("sparks_open") - return - -/obj/machinery/door/airlock/do_animate(animation) - switch(animation) - if("opening") - cut_overlay() - if(p_open) - spawn(2) // The only work around that works. Downside is that the door will be gone for a millisecond. - flick("o_door_opening", src) //can not use flick due to BYOND bug updating overlays right before flicking - update_icon() - else - flick("door_opening", src)//[stat ? "_stat":] - update_icon() - if("closing") - cut_overlay() - if(p_open) - spawn(2) - flick("o_door_closing", src) - update_icon() - else - flick("door_closing", src) - update_icon() - if("spark") - if(density) - flick("door_spark", src) - if("deny") - if(density && src.arePowerSystemsOn()) - flick("door_deny", src) - playsound(src, denied_sound, 50, 0, 3) - return - -/obj/machinery/door/airlock/attack_ai(mob/user as mob) - tgui_interact(user) - -/obj/machinery/door/airlock/attack_ghost(mob/user) - tgui_interact(user) - -/obj/machinery/door/airlock/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui, datum/tgui_state/custom_state) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "AiAirlock", name) - ui.open() - if(custom_state) - ui.set_state(custom_state) - return TRUE - -/obj/machinery/door/airlock/tgui_data(mob/user) - var/list/data = list() - - var/list/power = list() - power["main"] = main_power_lost_until > 0 ? 0 : 2 - power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) - power["backup"] = backup_power_lost_until > 0 ? 0 : 2 - power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) - data["power"] = power - - data["shock"] = (electrified_until == 0) ? 2 : 0 - data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) - data["id_scanner"] = !aiDisabledIdScanner - data["locked"] = locked // bolted - data["lights"] = lights // bolt lights - data["safe"] = safe // safeties - data["speed"] = normalspeed // safe speed - data["welded"] = welded // welded - data["opened"] = !density // opened - - var/list/wire = list() - wire["main_1"] = !wires.is_cut(WIRE_MAIN_POWER1) - wire["main_2"] = !wires.is_cut(WIRE_MAIN_POWER2) - wire["backup_1"] = !wires.is_cut(WIRE_BACKUP_POWER1) - wire["backup_2"] = !wires.is_cut(WIRE_BACKUP_POWER2) - wire["shock"] = !wires.is_cut(WIRE_ELECTRIFY) - wire["id_scanner"] = !wires.is_cut(WIRE_IDSCAN) - wire["bolts"] = !wires.is_cut(WIRE_DOOR_BOLTS) - wire["lights"] = !wires.is_cut(WIRE_BOLT_LIGHT) - wire["safe"] = !wires.is_cut(WIRE_SAFETY) - wire["timing"] = !wires.is_cut(WIRE_SPEED) - - data["wires"] = wire - return data - -/obj/machinery/door/airlock/proc/hack(mob/user as mob) - if(src.aiHacking==0) - src.aiHacking=1 - spawn(20) - //TODO: Make this take a minute - to_chat(user, "Airlock AI control has been blocked. Beginning fault-detection.") - sleep(50) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Fault confirmed: airlock control wire disabled or cut.") - sleep(20) - to_chat(user, "Attempting to hack into airlock. This may take some time.") - sleep(200) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Upload access confirmed. Loading control program into airlock software.") - sleep(170) - if(src.canAIControl()) - to_chat(user, "Alert cancelled. Airlock control has been restored without our assistance.") - src.aiHacking=0 - return - else if(!src.canAIHack(user)) - to_chat(user, "We've lost our connection! Unable to hack airlock.") - src.aiHacking=0 - return - to_chat(user, "Transfer complete. Forcing airlock to execute program.") - sleep(50) - //disable blocked control - src.aiControlDisabled = 2 - to_chat(user, "Receiving control information from airlock.") - sleep(10) - //bring up airlock dialog - src.aiHacking = 0 - if (user) - src.attack_ai(user) - -/obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target) - if (src.isElectrified()) - if (istype(mover, /obj/item)) - var/obj/item/i = mover - if (i.matter && (DEFAULT_WALL_MATERIAL in i.matter) && i.matter[DEFAULT_WALL_MATERIAL] > 0) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - return ..() - -/obj/machinery/door/airlock/attack_hand(mob/user as mob) - if(!istype(usr, /mob/living/silicon)) - if(src.isElectrified()) - if(src.shock(user, 100)) - return - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/X = user - if(istype(X.species, /datum/species/xenos)) - src.attack_alien(user) - return - - if(src.p_open) - user.set_machine(src) - wires.Interact(user) - else - ..(user) - return - -/obj/machinery/door/airlock/tgui_act(action, params) - if(..()) - return TRUE - if(!user_allowed(usr)) - return TRUE - - switch(action) - if("disrupt-main") - if(!main_power_lost_until) - loseMainPower() - update_icon() - else - to_chat(usr, "Main power is already offline.") - . = TRUE - if("disrupt-backup") - if(!backup_power_lost_until) - loseBackupPower() - update_icon() - else - to_chat(usr, "Backup power is already offline.") - . = TRUE - if("shock-restore") - electrify(0, 1) - . = TRUE - if("shock-temp") - electrify(30, 1) - . = TRUE - if("shock-perm") - electrify(-1, 1) - . = TRUE - if("idscan-toggle") - set_idscan(aiDisabledIdScanner, 1) - . = TRUE - // if("emergency-toggle") - // toggle_emergency(usr) - // . = TRUE - if("bolt-toggle") - toggle_bolt(usr) - . = TRUE - if("light-toggle") - if(wires.is_cut(WIRE_BOLT_LIGHT)) - to_chat(usr, "The bolt lights wire is cut - The door bolt lights are permanently disabled.") - return - lights = !lights - update_icon() - . = TRUE - if("safe-toggle") - set_safeties(!safe, 1) - . = TRUE - if("speed-toggle") - if(wires.is_cut(WIRE_SPEED)) - to_chat(usr, "The timing wire is cut - Cannot alter timing.") - return - normalspeed = !normalspeed - . = TRUE - if("open-close") - user_toggle_open(usr) - . = TRUE - - update_icon() - return 1 - -/obj/machinery/door/airlock/proc/user_allowed(mob/user) - var/allowed = (issilicon(user) && canAIControl(user)) - if(!allowed && isobserver(user)) - var/mob/observer/dead/D = user - if(D.can_admin_interact()) - allowed = TRUE - return allowed - -/obj/machinery/door/airlock/proc/toggle_bolt(mob/user) - if(!user_allowed(user)) - return - if(wires.is_cut(WIRE_DOOR_BOLTS)) - to_chat(user, "The door bolt drop wire is cut - you can't toggle the door bolts.") - return - if(locked) - if(!arePowerSystemsOn()) - to_chat(user, "The door has no power - you can't raise the door bolts.") - else - unlock() - to_chat(user, "The door bolts have been raised.") - // log_combat(user, src, "unbolted") - else - lock() - to_chat(user, "The door bolts have been dropped.") - // log_combat(user, src, "bolted") - -/obj/machinery/door/airlock/proc/user_toggle_open(mob/user) - if(!user_allowed(user)) - return - if(welded) - to_chat(user, text("The airlock has been welded shut!")) - else if(locked) - to_chat(user, text("The door bolts are down!")) - else if(!density) - close() - else - open() - -/obj/machinery/door/airlock/proc/can_remove_electronics() - return src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) - -/obj/machinery/door/airlock/attackby(obj/item/C, mob/user as mob) - //to_world("airlock attackby src [src] obj [C] mob [user]") - if(!istype(usr, /mob/living/silicon)) - if(src.isElectrified()) - if(src.shock(user, 75)) - return - if(istype(C, /obj/item/taperoll)) - return - - src.add_fingerprint(user) - if (attempt_vr(src,"attackby_vr",list(C, user))) return - if(istype(C, /mob/living)) - ..() - return - if(!repairing && istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density) - var/obj/item/weapon/weldingtool/W = C - if(W.remove_fuel(0,user)) - if(!src.welded) - src.welded = 1 - else - src.welded = null - playsound(src, C.usesound, 75, 1) - src.update_icon() - return - else - return - else if(C.is_screwdriver()) - if (src.p_open) - if (stat & BROKEN) - to_chat(usr, "The panel is broken and cannot be closed.") - else - src.p_open = 0 - playsound(src, C.usesound, 50, 1) - else - src.p_open = 1 - playsound(src, C.usesound, 50, 1) - src.update_icon() - else if(C.is_wirecutter()) - return src.attack_hand(user) - else if(istype(C, /obj/item/device/multitool)) - return src.attack_hand(user) - else if(istype(C, /obj/item/device/assembly/signaler)) - return src.attack_hand(user) - else if(istype(C, /obj/item/weapon/pai_cable)) // -- TLE - var/obj/item/weapon/pai_cable/cable = C - cable.plugin(src, user) - else if(!repairing && C.is_crowbar()) - if(can_remove_electronics()) - playsound(src, C.usesound, 75, 1) - user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.") - if(do_after(user,40 * C.toolspeed)) - to_chat(user, "You removed the airlock electronics!") - - var/obj/structure/door_assembly/da = new assembly_type(src.loc) - if (istype(da, /obj/structure/door_assembly/multi_tile)) - da.set_dir(src.dir) - - da.anchored = 1 - if(mineral) - da.glass = mineral - //else if(glass) - else if(glass && !da.glass) - da.glass = 1 - da.state = 1 - da.created_name = src.name - da.update_state() - - if(operating == -1 || (stat & BROKEN)) - new /obj/item/weapon/circuitboard/broken(src.loc) - operating = 0 - else - if (!electronics) create_electronics() - - electronics.loc = src.loc - electronics = null - - qdel(src) - return - else if(arePowerSystemsOn()) - to_chat(user, "The airlock's motors resist your efforts to force it.") - else if(locked) - to_chat(user, "The airlock's bolts prevent it from being forced.") - else - if(density) - spawn(0) open(1) - else - spawn(0) close(1) - - // Check if we're using a crowbar or armblade, and if the airlock's unpowered for whatever reason (off, broken, etc). - else if(istype(C, /obj/item/weapon)) - var/obj/item/weapon/W = C - if((W.pry == 1) && !arePowerSystemsOn()) - if(locked) - to_chat(user, "The airlock's bolts prevent it from being forced.") - else if( !welded && !operating ) - if(istype(C, /obj/item/weapon/material/twohanded/fireaxe)) // If this is a fireaxe, make sure it's held in two hands. - var/obj/item/weapon/material/twohanded/fireaxe/F = C - if(!F.wielded) - to_chat(user, "You need to be wielding \the [F] to do that.") - return - // At this point, it's an armblade or a fireaxe that passed the wielded test, let's try to open it. - if(density) - spawn(0) - open(1) - else - spawn(0) - close(1) - else - ..() - else - ..() - return - -/obj/machinery/door/airlock/phoron/attackby(C as obj, mob/user as mob) - if(C) - ignite(is_hot(C)) - ..() - -/obj/machinery/door/airlock/set_broken() - src.p_open = 1 - stat |= BROKEN - if (secured_wires) - lock() - for (var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message("[src.name]'s control panel bursts open, sparks spewing out!") - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - - update_icon() - return - -/obj/machinery/door/airlock/open(var/forced=0) - if(!can_open(forced)) - return 0 - use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people - - //if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator - for(var/P in player_list) - var/mob/M = P - if(!M || !M.client) - continue - var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) - var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) - var/sound - var/volume - if(old_sounds) // Do we have old sounds enabled? Play these even if we have department door sounds enabled. - if(arePowerSystemsOn()) - sound = legacy_open_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else if(!old_sounds && department_door_sounds && src.department_open_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. - if(arePowerSystemsOn()) - sound = department_open_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else // Else, play these. - if(arePowerSystemsOn()) - sound = open_sound_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - - var/turf/T = get_turf(M) - var/distance = get_dist(T, get_turf(src)) - if(distance <= world.view * 2) - if(T && T.z == get_z(src)) - M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) - - if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) - src.closeOther.close() - return ..() - -/obj/machinery/door/airlock/can_open(var/forced=0) - if(!forced) - if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) - return 0 - - if(locked || welded) - return 0 - return ..() - -/obj/machinery/door/airlock/can_close(var/forced=0) - if(locked || welded) - return 0 - - if(!forced) - //despite the name, this wire is for general door control. - if(!arePowerSystemsOn() || wires.is_cut(WIRE_OPEN_DOOR)) - return 0 - - return ..() - -/atom/movable/proc/blocks_airlock() - return density - -/obj/machinery/door/blocks_airlock() - return 0 - -/obj/machinery/mech_sensor/blocks_airlock() - return 0 - -/mob/living/blocks_airlock() - return 1 - -/atom/movable/proc/airlock_crush(var/crush_damage) - return 0 - -/obj/machinery/portable_atmospherics/canister/airlock_crush(var/crush_damage) - . = ..() - health -= crush_damage - healthcheck() - -/obj/effect/energy_field/airlock_crush(var/crush_damage) - adjust_strength(crush_damage) - -/obj/structure/closet/airlock_crush(var/crush_damage) - ..() - damage(crush_damage) - for(var/atom/movable/AM in src) - AM.airlock_crush() - return 1 - -/mob/living/airlock_crush(var/crush_damage) - . = ..() - adjustBruteLoss(crush_damage) - SetStunned(5) - SetWeakened(5) - var/turf/T = get_turf(src) - T.add_blood(src) - return 1 - -/mob/living/carbon/airlock_crush(var/crush_damage) - . = ..() - if(can_feel_pain()) - emote("scream") - -/mob/living/silicon/robot/airlock_crush(var/crush_damage) - adjustBruteLoss(crush_damage) - return 0 - -/obj/machinery/door/airlock/close(var/forced=0) - if(!can_close(forced)) - return 0 - - if(safe) - for(var/turf/turf in locs) - for(var/atom/movable/AM in turf) - if(AM.blocks_airlock()) - if(!has_beeped) - playsound(src, 'sound/machines/buzz-two.ogg', 50, 0) - has_beeped = 1 - autoclose_in(6) - return - - for(var/turf/turf in locs) - for(var/atom/movable/AM in turf) - if(AM.airlock_crush(DOOR_CRUSH_DAMAGE)) - take_damage(DOOR_CRUSH_DAMAGE) - - use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people - has_beeped = 0 - for(var/P in player_list) - var/mob/M = P - if(!M || !M.client) - continue - var/old_sounds = M.client.is_preference_enabled(/datum/client_preference/old_door_sounds) - var/department_door_sounds = M.client.is_preference_enabled(/datum/client_preference/department_door_sounds) - var/sound - var/volume - if(old_sounds) - if(arePowerSystemsOn()) - sound = legacy_close_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else if(!old_sounds && department_door_sounds && src.department_close_powered) // Else, we have old sounds disabled, the door has per-department door sounds, and we have chosen to play department door sounds, use these. - if(arePowerSystemsOn()) - sound = department_close_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - else - if(arePowerSystemsOn()) - sound = close_sound_powered - volume = 50 - else - sound = open_sound_unpowered - volume = 75 - - var/turf/T = get_turf(M) - var/distance = get_dist(T, get_turf(src)) - if(distance <= world.view * 2) - if(T && T.z == get_z(src)) - M.playsound_local(get_turf(src), sound, volume, 1, null, 0, TRUE, sound(sound), volume_channel = VOLUME_CHANNEL_DOORS) - for(var/turf/turf in locs) - var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf) - if(killthis) - killthis.ex_act(2)//Smashin windows - return ..() - -/obj/machinery/door/airlock/proc/lock(var/forced=0) - if(locked) - return 0 - - if (operating && !forced) return 0 - - src.locked = 1 - playsound(src, bolt_down_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) - for(var/mob/M in range(1,src)) - M.show_message("You hear a click from the bottom of the door.", 2) - update_icon() - return 1 - -/obj/machinery/door/airlock/proc/unlock(var/forced=0) - if(!src.locked) - return - - if (!forced) - if(operating || !src.arePowerSystemsOn() || wires.is_cut(WIRE_DOOR_BOLTS)) return - - src.locked = 0 - playsound(src, bolt_up_sound, 30, 0, 3, volume_channel = VOLUME_CHANNEL_DOORS) - for(var/mob/M in range(1,src)) - M.show_message("You hear a click from the bottom of the door.", 2) - update_icon() - return 1 - -/obj/machinery/door/airlock/allowed(mob/M) - if(locked) - return 0 - return ..(M) - -/obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) - ..() - - //if assembly is given, create the new door from the assembly - if (assembly && istype(assembly)) - assembly_type = assembly.type - - electronics = assembly.electronics - electronics.loc = src - - //update the door's access to match the electronics' - secured_wires = electronics.secure - if(electronics.one_access) - LAZYCLEARLIST(req_access) - req_one_access = src.electronics.conf_access - else - LAZYCLEARLIST(req_one_access) - req_access = src.electronics.conf_access - - //get the name from the assembly - if(assembly.created_name) - name = assembly.created_name - else - name = "[istext(assembly.glass) ? "[assembly.glass] airlock" : assembly.base_name]" - - //get the dir from the assembly - set_dir(assembly.dir) - - //wires - var/turf/T = get_turf(newloc) - if(T && (T.z in using_map.admin_levels)) - secured_wires = 1 - if (secured_wires) - wires = new/datum/wires/airlock/secure(src) - else - wires = new/datum/wires/airlock(src) - -/obj/machinery/door/airlock/Initialize() - if(src.closeOtherId != null) - for (var/obj/machinery/door/airlock/A in machines) - if(A.closeOtherId == src.closeOtherId && A != src) - src.closeOther = A - break - name = "\improper [name]" - . = ..() - -/obj/machinery/door/airlock/Destroy() - qdel(wires) - wires = null - return ..() - -// Most doors will never be deconstructed over the course of a round, -// so as an optimization defer the creation of electronics until -// the airlock is deconstructed -/obj/machinery/door/airlock/proc/create_electronics() - //create new electronics - if (secured_wires) - src.electronics = new/obj/item/weapon/airlock_electronics/secure( src.loc ) - else - src.electronics = new/obj/item/weapon/airlock_electronics( src.loc ) - - //update the electronics to match the door's access - if(LAZYLEN(req_access)) - electronics.conf_access = req_access - else if (LAZYLEN(req_one_access)) - electronics.conf_access = req_one_access - electronics.one_access = 1 - -/obj/machinery/door/airlock/emp_act(var/severity) - if(prob(40/severity)) - var/duration = world.time + SecondsToTicks(30 / severity) - if(duration > electrified_until) - electrify(duration) - ..() - -/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason - ..() - if(stat & NOPOWER) - // If we lost power, disable electrification - // Keeping door lights on, runs on internal battery or something. - electrified_until = 0 - update_icon() - -/obj/machinery/door/airlock/proc/prison_open() - if(arePowerSystemsOn()) - src.unlock() - src.open() - src.lock() - return - - -/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_DECONSTRUCT) - // Old RCD code made it cost 10 units to decon an airlock. - // Now the new one costs ten "sheets". - return list( - RCD_VALUE_MODE = RCD_DECONSTRUCT, - RCD_VALUE_DELAY = 5 SECONDS, - RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 - ) - return FALSE - -/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_DECONSTRUCT) - to_chat(user, span("notice", "You deconstruct \the [src].")) - qdel(src) - return TRUE - return FALSE ->>>>>>> 0051e96509... Merge pull request #10610 from VOREStation/Arokha/machinerybreak