From ffb142abae222a793393afa7a8591af6c57ec17a Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 12:07:12 -0700 Subject: [PATCH 1/7] Secure Airlock update! 4 new wires, completely randomised! (2nd bolt wire, 2 only-drop-bolts wires, and an AI alert wire that alerts an AI 20% of the time, when messed with) Emags have a limited number of uses, between 3 and 7, and cost 5 TC Hacktools are more useful than they were, and have a lower chance of alerting the AI (This is unmapped ATM) --- baystation12.dme | 3 - code/defines/obj/weapon.dm | 6 + code/game/events/Events/ElectricalStorm.dm | 2 +- code/game/events/Events/PrisonBreak.dm | 2 +- code/game/gamemodes/game_mode.dm | 4 +- code/game/machinery/bots/bots.dm | 5 + code/game/machinery/bots/mulebot.dm | 5 + code/game/machinery/camera_circuit.dm | 10 + code/game/machinery/cloning.dm | 5 + code/game/machinery/computer/arcade.dm | 5 + code/game/machinery/deployable.dm | 5 + code/game/machinery/doors/airlock.dm | 2125 +++++++++-------- code/game/machinery/doors/door.dm | 21 +- code/game/machinery/doors/windowdoor.dm | 6 + code/game/machinery/kitchen/gibber.dm | 5 + code/game/machinery/portable_turret.dm | 10 + code/game/machinery/telecomms/logbrowser.dm | 5 + code/game/machinery/telecomms/telemonitor.dm | 5 + code/game/machinery/vending.dm | 5 + code/game/magic/library.dm | 5 + code/game/objects/closets/secure/personal.dm | 6 + .../objects/closets/secure/secure_closets.dm | 6 + code/game/objects/closets/walllocker.dm | 5 + code/game/objects/door_assembly.dm | 6 +- code/game/objects/secstorage/secstorage.dm | 8 +- code/game/objects/storage/crates.dm | 6 + code/game/objects/storage/lockbox.dm | 6 + code/game/prisonshuttle.dm | 5 + code/game/supplyshuttle.dm | 5 + code/modules/mining/mine_items.dm | 5 + .../modules/mob/living/silicon/robot/robot.dm | 5 + code/modules/power/apc.dm | 18 +- code/modules/power/pacman2.dm | 5 + code/modules/power/port_gen.dm | 5 + code/modules/research/rdconsole.dm | 5 + code/modules/research/server.dm | 5 + 36 files changed, 1362 insertions(+), 978 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 3d325141d4c..c98d8946384 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -144,10 +144,7 @@ #define FILE_DIR "code/unused/spacecraft" #define FILE_DIR "code/WorkInProgress" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Jumper" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/tajara_sprites" #define FILE_DIR "code/WorkInProgress/mapload" #define FILE_DIR "code/WorkInProgress/Mini" #define FILE_DIR "code/WorkInProgress/organs" diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 40cb84a6d1a..1105c84947e 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -453,6 +453,12 @@ icon_state = "emag" item_state = "card-id" origin_tech = "magnets=2;syndicate=2" + var/uses = 5 + + New() + ..() + uses = rand(3,7) + return /obj/item/weapon/card/id name = "identification card" diff --git a/code/game/events/Events/ElectricalStorm.dm b/code/game/events/Events/ElectricalStorm.dm index 22c7cbf9d3f..5337a4f6f2c 100644 --- a/code/game/events/Events/ElectricalStorm.dm +++ b/code/game/events/Events/ElectricalStorm.dm @@ -17,7 +17,7 @@ APCs += APC for(var/obj/machinery/door/airlock/Door in world) - if(Door.z == 1) + if(Door.z == 1 && !istype(Door,/obj/machinery/door/airlock/secure)) Doors += Door for(var/obj/machinery/telecomms/processor/T in world) diff --git a/code/game/events/Events/PrisonBreak.dm b/code/game/events/Events/PrisonBreak.dm index 5380d82f337..e9500a0f6c8 100644 --- a/code/game/events/Events/PrisonBreak.dm +++ b/code/game/events/Events/PrisonBreak.dm @@ -14,7 +14,7 @@ for (var/obj/machinery/door/airlock/security/temp_airlock in world) if(istype(get_area(temp_airlock), /area/security/brig)) temp_airlock.prison_open() - for (var/obj/machinery/door/airlock/glass_security/temp_glassairlock in world) + for (var/obj/machinery/door/airlock/glass/glass_security/temp_glassairlock in world) if(istype(get_area(temp_glassairlock), /area/security/brig)) temp_glassairlock.prison_open() for (var/obj/machinery/door_timer/temp_timer in world) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index b2860af20c4..20425c78966 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -48,8 +48,8 @@ Stealth and Camouflage Items; /obj/item/weapon/stamperaser:1:Stamp Remover; Whitespace:Seperator; Devices and Tools; -/obj/item/weapon/card/emag:3:Cryptographic Sequencer; -/obj/item/device/hacktool:3:Hacktool; +/obj/item/weapon/card/emag:5:Cryptographic Sequencer (Limited uses, almost full access); +/obj/item/device/hacktool:3:Hacktool (Slow, but stealthy. Unlimited uses); /obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox; /obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module; /obj/item/device/radio/headset/traitor:3:Headset with Binary Translator; diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 83ba4e215d1..7b58c68f7aa 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -69,6 +69,11 @@ else user << "\blue [src] does not need a repair!" else if (istype(W, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return Emag(user) else switch(W.damtype) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 7e725290846..4fa1630dd50 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -123,6 +123,11 @@ // other: chance to knock rider off bot /obj/machinery/bot/mulebot/attackby(var/obj/item/I, var/mob/user) if(istype(I,/obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return locked = !locked user << "\blue You [locked ? "lock" : "unlock"] the mulebot's controls!" flick("mulebot-emagged", src) diff --git a/code/game/machinery/camera_circuit.dm b/code/game/machinery/camera_circuit.dm index 1efcc9af703..3114f537e35 100644 --- a/code/game/machinery/camera_circuit.dm +++ b/code/game/machinery/camera_circuit.dm @@ -39,6 +39,11 @@ ..() if(istype(I,/obj/item/weapon/card/emag)) if(network) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return authorised = 1 user << "\blue You authorised the circuit network!" updateDialog() @@ -103,6 +108,11 @@ authorised = 1 if(istype(I,/obj/item/weapon/card/emag)) if(network) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return authorised = 1 usr << "\blue You authorised the circuit network!" updateDialog() diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 9027ed0023c..ce3adee94fe 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -653,6 +653,11 @@ else if (istype(W, /obj/item/weapon/card/emag)) if (isnull(src.occupant)) return + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return user << "You force an emergency ejection." src.locked = 0 src.go_out() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 57b87ae93fd..b2e1f3f5578 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -202,6 +202,11 @@ /obj/machinery/computer/arcade/attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return temp = "If you die in the game, you die for real!" player_hp = 30 player_mp = 10 diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index f05d34a3fdc..a1043334fd6 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -187,6 +187,11 @@ for reference: return return else if (istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return if (src.emagged == 0) src.emagged = 1 src.req_access = null diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index f7535887f92..65a75a0b569 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -10,6 +10,11 @@ #define AIRLOCK_WIRE_CRUSH 10 #define AIRLOCK_WIRE_LIGHT 11 #define AIRLOCK_WIRE_HOLDOPEN 12 +#define AIRLOCK_WIRE_FAKEBOLT1 13 +#define AIRLOCK_WIRE_FAKEBOLT2 14 +#define AIRLOCK_WIRE_ALERTAI 15 +#define AIRLOCK_WIRE_DOOR_BOLTS_2 16 +//#define AIRLOCK_WIRE_FINGERPRINT 17 /* New methods: @@ -63,132 +68,722 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. icon = 'doorint.dmi' icon_state = "door_closed" - 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/synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no - var/synHacking = 0 // Is hack in process y/n? - var/secondsMainPowerLost = 0 //The number of seconds until power is restored. - var/secondsBackupPowerLost = 0 //The number of seconds until power is restored. - var/spawnPowerRestoreRunning = 0 - var/welded = null - var/locked = 0 - var/wires = 4095 - secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. - var/aiDisabledIdScanner = 0 - var/aiHacking = 0 - var/obj/machinery/door/airlock/closeOther = null - var/closeOtherId = null - var/list/signalers[12] - var/lockdownbyai = 0 - autoclose = 1 - var/doortype = 0 - var/justzap = 0 - var/safetylight = 1 - var/obj/item/weapon/airlock_electronics/electronics = null + 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. + synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no + synHacking = 0 // Is hack in process y/n? + secondsMainPowerLost = 0 //The number of seconds until power is restored. + secondsBackupPowerLost = 0 //The number of seconds until power is restored. + spawnPowerRestoreRunning = 0 + welded = null + locked = 0 + wires = 4095 + aiDisabledIdScanner = 0 + aiHacking = 0 + obj/machinery/door/airlock/closeOther = null + closeOtherId = null + list/signalers[12] + lockdownbyai = 0 + doortype = 0 + justzap = 0 + safetylight = 1 + obj/item/weapon/airlock_electronics/electronics = null + alert_probability = 3 + list/wire_index = list( + "Orange" = 1, + "Dark red" = 2, + "White" = 3, + "Yellow" = 4, + "Red" = 5, + "Blue" = 6, + "Green" = 7, + "Grey" = 8, + "Black" = 9, + "Pink" = 10, + "Brown" = 11, + "Maroon" = 12, + "Aqua" = 13, + "Turgoise" = 14, + "Purple" = 15, + "Rainbow" = 16, + "Atomic Tangerine" = 17, + "Neon Green" = 18, + "Cotton Candy" = 19, + "Plum" = 20, + "Shamrock" = 21, + "Indigo" = 22 + ) + wirenum = 12 holdopen = 1 + autoclose = 1 + secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. -/obj/machinery/door/airlock/command - name = "Airlock" - icon = 'Doorcom.dmi' - doortype = 1 - holdopen = 0 -/obj/machinery/door/airlock/security - name = "Airlock" - icon = 'Doorsec.dmi' - doortype = 2 + command + name = "Airlock" + icon = 'Doorcom.dmi' + doortype = 1 + holdopen = 0 -/obj/machinery/door/airlock/engineering - name = "Airlock" - icon = 'Dooreng.dmi' - doortype = 3 -/obj/machinery/door/airlock/medical - name = "Airlock" - icon = 'Doormed.dmi' - doortype = 4 + security + name = "Airlock" + icon = 'Doorsec.dmi' + doortype = 2 -/obj/machinery/door/airlock/maintenance - name = "Maintenance Access" - icon = 'Doormaint.dmi' - doortype = 5 -/obj/machinery/door/airlock/external - name = "External Airlock" - icon = 'Doorext.dmi' - doortype = 6 - holdopen = 0 + engineering + name = "Airlock" + icon = 'Dooreng.dmi' + doortype = 3 -/obj/machinery/door/airlock/glass - name = "Glass Airlock" - icon = 'Doorglass.dmi' - opacity = 0 - doortype = 7 - glass = 1 -/obj/machinery/door/airlock/centcom - name = "Airlock" - icon = 'Doorele.dmi' - opacity = 0 - doortype = 8 + medical + name = "Airlock" + icon = 'Doormed.dmi' + doortype = 4 -/obj/machinery/door/airlock/vault - name = "Vault" - icon = 'vault.dmi' - opacity = 1 - doortype = 9 -/obj/machinery/door/airlock/glass_large - name = "Glass Airlock" - icon = 'Door2x1glassfull.dmi' - opacity = 0 - doortype = 10 - glass = 1 + maintenance + name = "Maintenance Access" + icon = 'Doormaint.dmi' + doortype = 5 -/obj/machinery/door/airlock/freezer - name = "Freezer Airlock" - icon = 'Doorfreezer.dmi' - opacity = 1 - doortype = 11 + external + name = "External Airlock" + icon = 'Doorext.dmi' + doortype = 6 -/obj/machinery/door/airlock/hatch - name = "Airtight Hatch" - icon = 'Doorhatchele.dmi' - opacity = 1 - doortype = 12 -/obj/machinery/door/airlock/maintenance_hatch - name = "Maintenance Hatch" - icon = 'Doorhatchmaint2.dmi' - opacity = 1 - doortype = 13 + glass + name = "Glass Airlock" + icon = 'Doorglass.dmi' + opacity = 0 + doortype = 7 + glass = 1 -/obj/machinery/door/airlock/glass/glass_command - name = "Maintenance Hatch" - icon = 'Doorcomglass.dmi' - opacity = 0 - doortype = 14 - glass = 1 -/obj/machinery/door/airlock/glass_engineering - name = "Maintenance Hatch" - icon = 'Doorengglass.dmi' - opacity = 0 - doortype = 15 - glass = 1 + glass_command + name = "Maintenance Hatch" + icon = 'Doorcomglass.dmi' + opacity = 0 + doortype = 14 + glass = 1 + + + glass_engineering + name = "Maintenance Hatch" + icon = 'Doorengglass.dmi' + opacity = 0 + doortype = 15 + glass = 1 + + + glass_security + name = "Maintenance Hatch" + icon = 'Doorsecglass.dmi' + opacity = 0 + doortype = 16 + glass = 1 + + + glass_medical + name = "Maintenance Hatch" + icon = 'doormedglass.dmi' + opacity = 0 + doortype = 17 + glass = 1 + + + centcom + name = "Airlock" + icon = 'Doorele.dmi' + opacity = 0 + doortype = 8 + + + vault + name = "Vault" + icon = 'vault.dmi' + opacity = 1 + doortype = 9 + + + glass_large + name = "Glass Airlock" + icon = 'Door2x1glassfull.dmi' + opacity = 0 + doortype = 10 + glass = 1 + + + freezer + name = "Freezer Airlock" + icon = 'Doorfreezer.dmi' + opacity = 1 + doortype = 11 + + + hatch + name = "Airtight Hatch" + icon = 'Doorhatchele.dmi' + opacity = 1 + doortype = 12 + + + maintenance_hatch + name = "Maintenance Hatch" + icon = 'Doorhatchmaint2.dmi' + opacity = 1 + doortype = 13 + + + New() + ..() + if (src.closeOtherId != null) + spawn (5) + for (var/obj/machinery/door/airlock/A in machines) + if (A.closeOtherId == src.closeOtherId && A != src) + src.closeOther = A + break + + + open() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + return 0 + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) + src.closeOther.close() + return ..() + + + close() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + return + ..() + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) + if(killthis) + killthis.ex_act(2)//Smashin windows + return + + + bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite + if (!istype(usr, /mob/living/silicon)) + 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) + user << "\red You feel a powerful shock course through your body!" + user.halloss += 10 + user.stunned += 10 + return + ..(user) + + + update_icon() + if(overlays) overlays = null + if(density) + if(locked && safetylight) + icon_state = "door_locked" + else + icon_state = "door_closed" + if(p_open || welded) + overlays = list() + if(p_open) + overlays += image(icon, "panel_open") + if(welded) + overlays += image(icon, "welded") + else + icon_state = "door_open" + return + + + animate(animation) + switch(animation) + if("opening") + if(overlays) overlays = null + if(p_open) + icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking + else + flick("door_opening", src) + if("closing") + if(overlays) overlays = null + if(p_open) + flick("o_door_closing", src) + else + flick("door_closing", src) + if("spark") + flick("door_spark", src) + if("deny") + flick("door_deny", src) + return + + requiresID() + return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/weapon/screwdriver)) + src.p_open = !( src.p_open ) + src.update_icon() + else if (istype(C, /obj/item/weapon/wirecutters)) + 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/hacktool)) + return src.attack_ai(user, C) + 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) + var/beingcrowbarred = null + if(istype(C, /obj/item/weapon/crowbar) ) + beingcrowbarred = 1 //derp, Agouri + else + beingcrowbarred = 0 + if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) + playsound(src.loc, 'Crowbar.ogg', 100, 1) + user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") + if(do_after(user,40)) + user << "\blue You removed the airlock electronics!" + switch(src.doortype) + if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) + if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) + if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) + if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) + if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) + if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) + if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) + if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) + var/obj/item/weapon/airlock_electronics/ae + if (!electronics) + ae = new/obj/item/weapon/airlock_electronics( src.loc ) + ae.conf_access = src.req_access + else + ae = electronics + electronics = null + ae.loc = src.loc + + del(src) + return + else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) + user << "\blue The airlock's motors resist your efforts to pry it open." + else if (src.locked) + user << "\blue The airlock's bolts prevent it from being pried open." + if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) + + if(beingcrowbarred == 0) //being fireaxe'd + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + user << "\red You need to be wielding the Fire axe to do that." + return + else + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + + else + if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) + if(beingcrowbarred == 0) + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("closing") + + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + else + user << "\red You need to be wielding the Fire axe to do that." + else + spawn( 0 ) + src.operating = 1 + animate("closing") + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + + else + ..() + return + + + attack_paw(mob/user as mob) + return src.attack_hand(user) + + + attack_hand(mob/user as mob) + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 100)) + return + + if (ishuman(user) && prob(40) && src.density) + var/mob/living/carbon/human/H = user + if(H.getBrainLoss() >= 60) + playsound(src.loc, 'bang.ogg', 25, 1) + if(!istype(H.head, /obj/item/clothing/head/helmet)) + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock." + var/datum/organ/external/affecting = H.get_organ("head") + affecting.take_damage(10, 0) + H.Stun(8) + H.Weaken(5) + H.UpdateDamageIcon() + else + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." + return + + if (src.p_open) + user.machine = src + var/t1 = text("Access Panel
\n") + + //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) + t1 += getAirlockWires() + + t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) + + t1 += text("

Close

\n", src) + + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + else + ..(user) + return + +//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 engage engineer smasher, 9 enable bolt indicator, 10 wait for clearance +//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 disable engineer smasher, 9 disable bolt indicator, 10 autoclose + //This has been converted to be called by either the AI or a mob with a hacktool, permitting either to directly operate the airlock + attack_ai(mob/user as mob, obj/item/device/hacktool/C) + if(isAI(user)) + if (!src.canAIControl()) + if (src.canAIHack()) + src.hack(user) + return + else if(user) + if(!C) + return + if(C.in_use) + user << "We are already hacking another airlock." + return + if (!src.canSynControl() && src.canSynHack(C)) + src.synhack(user, C) + return + else + world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" + return + + + //Separate interface for the AI. + user.machine = src + var/t1 = text("Airlock Control
\n") + if (src.secondsMainPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) + else + t1 += text("Main power is offline indefinitely.
\n") + else + t1 += text("Main power is online.") + + if (src.secondsBackupPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) + else + t1 += text("Backup power is offline indefinitely.
\n") + else if (src.secondsMainPowerLost > 0) + t1 += text("Backup power is online.") + else + t1 += text("Backup power is offline, but will turn on if main power fails.") + t1 += "
\n" + + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + t1 += text("IdScan wire is cut.
\n") + else if (src.aiDisabledIdScanner) + t1 += text("IdScan disabled. Enable?
\n", src) + else + t1 += text("IdScan enabled. Disable?
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) + t1 += text("Main Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) + t1 += text("Main Power Output wire is cut.
\n") + if (src.secondsMainPowerLost == 0) + t1 += text("Temporarily disrupt main power?.
\n", src) + if (src.secondsBackupPowerLost == 0) + t1 += text("Temporarily disrupt backup power?.
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) + t1 += text("Backup Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) + t1 += text("Backup Power Output wire is cut.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) + t1 += text("Airlock extra force wire is cut.
\n") + else if(!src.forcecrush) + t1 += text("Airlock extra force disabled Enable it?
\n") + else + t1 += text("Airlock extra force enabled Disable it?
\n") + + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + t1 += text("Door bolt drop wire is cut.
\n") + else if (!src.locked) + t1 += text("Door bolts are up. Drop them?
\n", src) + else + t1 += text("Door bolts are down.") + if (src.arePowerSystemsOn()) + t1 += text(" Raise?
\n", src) + else + t1 += text(" Cannot raise door bolts due to power failure.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + t1 += text("Electrification wire is cut.
\n") + if (src.secondsElectrified==-1) + t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) + else if (src.secondsElectrified>0) + t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) + else + t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) + + if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) + t1 += "Bolt indication light wire is cut.
\n" + else if(!src.safetylight) + t1 += text("Bolt Indication light is disabled Enable it?
\n") + else + t1 += text("Bolt Indication light is enabled Disable it?
\n") + + if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) + t1 += "Behavior Control light wire is cut.
\n" + else if(!src.holdopen) + t1 += text("Door behavior is set to: Automatically close Toggle?
\n") + else + t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") + + if (src.welded) + t1 += text("Door appears to have been welded shut.
\n") + else if (!src.locked) + if (src.density) + t1 += text("Open door
\n", src) + else + t1 += text("Close door
\n", src) + + t1 += text("

Close

\n", src) + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + + proc + hack(mob/user as mob) + if (src.aiHacking==0) + src.aiHacking=1 + spawn(20) + //TODO: Make this take a minute + user << "Airlock AI control has been blocked. Beginning fault-detection." + sleep(50) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Fault confirmed: airlock control wire disabled or cut." + sleep(20) + user << "Attempting to hack into airlock. This may take some time." + sleep(200) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(170) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(50) + //disable blocked control + src.aiControlDisabled = 2 + user << "Receiving control information from airlock." + sleep(10) + //bring up airlock dialog + src.aiHacking = 0 + src.attack_ai(user) + + + synhack(mob/user as mob, obj/item/device/hacktool/I) + if (src.synHacking==0) + src.synHacking=1 + I.in_use = 1 + user << "You begin hacking..." + spawn(20) + user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." + sleep(25) + if (src.canSynControl()) + user << "Hack cancelled, control already possible." + src.synHacking=0 + I.in_use = 0 + return + else if (!src.canSynHack(I)) + user << "\red Connection lost. Stand still and stay near the airlock!" + src.synHacking=0 + I.in_use = 0 + return + user << "Connection established." + sleep(10) + user << "Attempting to hack into airlock. This may take some time." + sleep(50) + + // Alerting the AIs + var/list/cameras = list() + for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area + cameras += C + var/alertoption = prob(alert_probability) // Chance of warning AI, based on doortype's probability + if(alertoption) + if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) + alertoption = 3 + else if (prob(18)) //18% chance of sending the AI just the area + alertoption = 2 + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + switch(alertoption) + if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) + if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + switch(alertoption) + if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") + // ...And done + + if (!src.canSynHack(I)) + user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Local override already in place, hack aborted." + src.synHacking=0 + I.in_use = 0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(35) + if (!src.canSynHack(I)) + user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Upload access aborted, local override already in place." + src.synHacking=0 + I.in_use = 0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(25) + //disable blocked control + src.synDoorHacked = 1 + user << "Bingo! We're in. Airlock control panel coming right up." + sleep(5) + //bring up airlock dialog + src.synHacking = 0 + I.in_use = 0 + src.attack_ai(user, I) + + + canAIControl() + return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); + + + canAIHack() + return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); + + + canSynControl() + return (src.synDoorHacked && (!src.isAllPowerCut())); + + + canSynHack(obj/item/device/hacktool/H) + return (in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()); -/obj/machinery/door/airlock/glass_security - name = "Maintenance Hatch" - icon = 'Doorsecglass.dmi' - opacity = 0 - doortype = 16 - glass = 1 -/obj/machinery/door/airlock/glass_medical - name = "Maintenance Hatch" - icon = 'doormedglass.dmi' - opacity = 0 - doortype = 17 - glass = 1 /* About the new airlock wires panel: @@ -202,615 +797,233 @@ About the new airlock wires panel: * 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) */ -/obj/machinery/door/airlock/bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if (!istype(usr, /mob/living/silicon)) - 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) - user << "\red You feel a powerful shock course through your body!" - user.halloss += 10 - user.stunned += 10 - return - ..(user) + pulse(var/wireColor) + //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function + var/wireIndex = airlockWireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen -/obj/machinery/door/airlock/proc/pulse(var/wireColor) - //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function - var/wireIndex = airlockWireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - animate("deny") - if (AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) - //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). - src.loseMainPower() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - else - if(src.arePowerSystemsOn()) //only can raise bolts if power's on - src.locked = 0 - usr << "You hear a click from inside the door." + cut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) src.updateUsrDialog() - update_icon() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 - if (AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) - //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). - src.loseBackupPower() - if (AIRLOCK_WIRE_AI_CONTROL) - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if (src.secondsElectrified==0) - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 -// src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if (!src.requiresID() || src.check_access(null)) - if (src.density) - open() - else - close() - if(AIRLOCK_WIRE_CRUSH) - src.forcecrush = !src.forcecrush - if(AIRLOCK_WIRE_LIGHT) - src.safetylight = !src.safetylight - if(AIRLOCK_WIRE_HOLDOPEN) - src.holdopen = !src.holdopen - - - -/obj/machinery/door/airlock/proc/cut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) - //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if (src.locked!=1) - src.locked = 1 - update_icon() - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if (src.secondsElectrified != -1) - src.secondsElectrified = -1 - - -/obj/machinery/door/airlock/proc/mend(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - if (src.secondsElectrified == -1) - src.secondsElectrified = 0 - -/obj/machinery/door/airlock/proc/isElectrified() - if(src.secondsElectrified != 0) - return 1 - else return 0 - -/obj/machinery/door/airlock/proc/isWireColorCut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - -/obj/machinery/door/airlock/proc/isWireCut(var/wireIndex) - var/wireFlag = airlockIndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - -/obj/machinery/door/airlock/proc/canAIControl() - return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); - -/obj/machinery/door/airlock/proc/canAIHack() - return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); - -/obj/machinery/door/airlock/proc/canSynControl() - return (src.synDoorHacked && (!src.isAllPowerCut())); - -/obj/machinery/door/airlock/proc/canSynHack(obj/item/device/hacktool/H) - if(in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()) - return 1 - -/obj/machinery/door/airlock/proc/arePowerSystemsOn() - return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) - -/obj/machinery/door/airlock/requiresID() - return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) - -/obj/machinery/door/airlock/proc/isAllPowerCut() - var/retval=0 - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - retval=1 - return retval - -/obj/machinery/door/airlock/proc/regainMainPower() - if (src.secondsMainPowerLost > 0) - src.secondsMainPowerLost = 0 - -/obj/machinery/door/airlock/proc/loseMainPower() - if (src.secondsMainPowerLost <= 0) - src.secondsMainPowerLost = 60 - if (src.secondsBackupPowerLost < 10) - src.secondsBackupPowerLost = 10 - if (!src.spawnPowerRestoreRunning) - src.spawnPowerRestoreRunning = 1 - spawn(0) - var/cont = 1 - while (cont) - sleep(10) - cont = 0 - if (src.secondsMainPowerLost>0) + mend(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.secondsMainPowerLost -= 1 - src.updateDialog() - cont = 1 - - if (src.secondsBackupPowerLost>0) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.secondsBackupPowerLost -= 1 - src.updateDialog() - cont = 1 - src.spawnPowerRestoreRunning = 0 - src.updateDialog() + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 -/obj/machinery/door/airlock/proc/loseBackupPower() - if (src.secondsBackupPowerLost < 60) - src.secondsBackupPowerLost = 60 - -/obj/machinery/door/airlock/proc/regainBackupPower() - if (src.secondsBackupPowerLost > 0) - src.secondsBackupPowerLost = 0 - -// 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/proc/shock(mob/user, prb) - if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 //you lucked out, no shock for you - if(istype(usr.equipped(),/obj/item/weapon/shard)) - return 0 - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() //sparks always. - if (electrocute_mob(user, get_area(src), src)) - return 1 - else - return 0 - - -/obj/machinery/door/airlock/update_icon() - if(overlays) overlays = null - if(density) - if(locked && safetylight) - icon_state = "door_locked" - else - icon_state = "door_closed" - if(p_open || welded) - overlays = list() - if(p_open) - overlays += image(icon, "panel_open") - if(welded) - overlays += image(icon, "welded") - else - icon_state = "door_open" - - return - -/obj/machinery/door/airlock/animate(animation) - switch(animation) - if("opening") - if(overlays) overlays = null - if(p_open) - icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking - else - flick("door_opening", src) - if("closing") - if(overlays) overlays = null - if(p_open) - flick("o_door_closing", src) - else - flick("door_closing", src) - if("spark") - flick("door_spark", src) - if("deny") - flick("door_deny", src) - return - -/obj/machinery/door/airlock/attack_ai(mob/user as mob) - if (!src.canAIControl()) - if (src.canAIHack()) - src.hack(user) - return - - //Separate interface for the AI. - user.machine = src - var/t1 = text("Airlock Control
\n") - if (src.secondsMainPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) - else - t1 += text("Main power is offline indefinitely.
\n") - else - t1 += text("Main power is online.") - - if (src.secondsBackupPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) - else - t1 += text("Backup power is offline indefinitely.
\n") - else if (src.secondsMainPowerLost > 0) - t1 += text("Backup power is online.") - else - t1 += text("Backup power is offline, but will turn on if main power fails.") - t1 += "
\n" - - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - t1 += text("IdScan wire is cut.
\n") - else if (src.aiDisabledIdScanner) - t1 += text("IdScan disabled. Enable?
\n", src) - else - t1 += text("IdScan enabled. Disable?
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) - t1 += text("Main Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - t1 += text("Main Power Output wire is cut.
\n") - if (src.secondsMainPowerLost == 0) - t1 += text("Temporarily disrupt main power?.
\n", src) - if (src.secondsBackupPowerLost == 0) - t1 += text("Temporarily disrupt backup power?.
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) - t1 += text("Backup Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - t1 += text("Backup Power Output wire is cut.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) - t1 += text("Airlock extra force wire is cut.
\n") - else if(!src.forcecrush) - t1 += text("Airlock extra force disabled Enable it?
\n") - else - t1 += text("Airlock extra force enabled Disable it?
\n") - - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - t1 += text("Door bolt drop wire is cut.
\n") - else if (!src.locked) - t1 += text("Door bolts are up. Drop them?
\n", src) - else - t1 += text("Door bolts are down.") - if (src.arePowerSystemsOn()) - t1 += text(" Raise?
\n", src) - else - t1 += text(" Cannot raise door bolts due to power failure.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - t1 += text("Electrification wire is cut.
\n") - if (src.secondsElectrified==-1) - t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) - else if (src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) - else - t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) - - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - t1 += "Bolt indication light wire is cut.
\n" - else if(!src.safetylight) - t1 += text("Bolt Indication light is disabled Enable it?
\n") - else - t1 += text("Bolt Indication light is enabled Disable it?
\n") - - if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) - t1 += "Behavior Control light wire is cut.
\n" - else if(!src.holdopen) - t1 += text("Door behavior is set to: Automatically close Toggle?
\n") - else - t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") - - if (src.welded) - t1 += text("Door appears to have been welded shut.
\n") - else if (!src.locked) - if (src.density) - t1 += text("Open door
\n", src) - else - t1 += text("Close door
\n", src) - - t1 += text("

Close

\n", src) - user << browse(t1, "window=airlock") - onclose(user, "airlock") - -//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door -//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door - -/obj/machinery/door/airlock/proc/attack_hack(mob/user as mob, obj/item/device/hacktool/C) - if(!C) - return - if(C.in_use) - user << "We are already hacking another airlock." - return - if (!src.canSynControl() && src.canSynHack(C)) - src.synhack(user, C) - return - - //Separate interface for the hacker. - var/t1 = text("Airlock Control
\n") - if (src.secondsMainPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) - else - t1 += text("Main power is offline indefinitely.
\n") - else - t1 += text("Main power is online.") - - if (src.secondsBackupPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) - else - t1 += text("Backup power is offline indefinitely.
\n") - else if (src.secondsMainPowerLost > 0) - t1 += text("Backup power is online.") - else - t1 += text("Backup power is offline, but will turn on if main power fails.") - t1 += "
\n" - - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - t1 += text("IdScan wire is cut.
\n") - else if (src.aiDisabledIdScanner) - t1 += text("IdScan disabled. Enable?
\n", src) - else - t1 += text("IdScan enabled. Disable?
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) - t1 += text("Main Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - t1 += text("Main Power Output wire is cut.
\n") - if (src.secondsMainPowerLost == 0) - t1 += text("Temporarily disrupt main power?.
\n", src) - if (src.secondsBackupPowerLost == 0) - t1 += text("Temporarily disrupt backup power?.
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) - t1 += text("Backup Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - t1 += text("Backup Power Output wire is cut.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) - t1 += text("Airlock extra force wire is cut.
\n") - else if(!src.forcecrush) - t1 += text("Airlock extra force disabled Enable it?
\n") - else - t1 += text("Airlock extra force enabled Disable it?
\n") - - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - t1 += text("Door bolt drop wire is cut.
\n") - else if (!src.locked) - t1 += text("Door bolts are up. Drop them?
\n", src) - else - t1 += text("Door bolts are down.") - if (src.arePowerSystemsOn()) - t1 += text(" Raise?
\n", src) - else - t1 += text(" Cannot raise door bolts due to power failure.
\n") - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - t1 += text("Electrification wire is cut.
\n") - if (src.secondsElectrified==-1) - t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) - else if (src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) - else - t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) - - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - t1 += "Bolt indication light wire is cut.
\n" - else if(!src.safetylight) - t1 += text("Bolt indication light is disabled Enable it?
\n") - else - t1 += text("Bolt indication light is enabled Disable it?
\n") - - if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) - t1 += "Behavior Control light wire is cut.
\n" - else if(!src.holdopen) - t1 += text("Door behavior is set to: Automatically close Toggle?
\n") - else - t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") - - if (src.welded) - t1 += text("Door appears to have been welded shut.
\n") - else if (!src.locked) - if (src.density) - t1 += text("Open door
\n", src) - else - t1 += text("Close door
\n", src) - - t1 += text("

Close

\n", src) - user << browse(t1, "window=airlock") - onclose(user, "airlock") - -/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 - user << "Airlock AI control has been blocked. Beginning fault-detection." - sleep(50) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Fault confirmed: airlock control wire disabled or cut." - sleep(20) - user << "Attempting to hack into airlock. This may take some time." - sleep(200) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(170) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(50) - //disable blocked control - src.aiControlDisabled = 2 - user << "Receiving control information from airlock." - sleep(10) - //bring up airlock dialog - src.aiHacking = 0 - src.attack_ai(user) - - -/obj/machinery/door/airlock/attack_paw(mob/user as mob) - return src.attack_hand(user) - -/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 (ishuman(user) && prob(40) && src.density) - var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= 60) - playsound(src.loc, 'bang.ogg', 25, 1) - if(!istype(H.head, /obj/item/clothing/head/helmet)) - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock." - var/datum/organ/external/affecting = H.get_organ("head") - affecting.take_damage(10, 0) - H.Stun(8) - H.Weaken(5) - H.UpdateDamageIcon() - else - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." - return - - if (src.p_open) - user.machine = src - var/t1 = text("Access Panel
\n") - - //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) - var/list/wires = list( - "Orange" = 1, - "Dark red" = 2, - "White" = 3, - "Yellow" = 4, - "Red" = 5, - "Blue" = 6, - "Green" = 7, - "Grey" = 8, - "Black" = 9, - "Pink" = 10, - "Brown" = 11, - "Maroon" = 12 - ) - for(var/wiredesc in wires) - var/is_uncut = src.wires & airlockWireColorToFlag[wires[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wires[wiredesc]]) - t1 += "Detach signaler" + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & airlockWireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" else - t1 += "Attach signaler" - t1 += "
" + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 - t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) + isElectrified() + return (src.secondsElectrified != 0); - t1 += text("

Close

\n", src) + isWireColorCut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) - user << browse(t1, "window=airlock") - onclose(user, "airlock") + isWireCut(var/wireIndex) + var/wireFlag = airlockIndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + arePowerSystemsOn() + return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) + + isAllPowerCut() + return ((src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) && (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + + regainMainPower() + if (src.secondsMainPowerLost > 0) + src.secondsMainPowerLost = 0 + + loseMainPower() + if (src.secondsMainPowerLost <= 0) + src.secondsMainPowerLost = 60 + if (src.secondsBackupPowerLost < 10) + src.secondsBackupPowerLost = 10 + if (!src.spawnPowerRestoreRunning) + src.spawnPowerRestoreRunning = 1 + spawn(0) + var/cont = 1 + while (cont) + sleep(10) + cont = 0 + if (src.secondsMainPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.secondsMainPowerLost -= 1 + src.updateDialog() + cont = 1 + + if (src.secondsBackupPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.secondsBackupPowerLost -= 1 + src.updateDialog() + cont = 1 + src.spawnPowerRestoreRunning = 0 + src.updateDialog() + + loseBackupPower() + if (src.secondsBackupPowerLost < 60) + src.secondsBackupPowerLost = 60 + + regainBackupPower() + if (src.secondsBackupPowerLost > 0) + src.secondsBackupPowerLost = 0 + + // 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 + shock(mob/user, prb) + if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 //you lucked out, no shock for you + if(istype(usr.equipped(),/obj/item/weapon/shard)) + return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src)) + return 1 + else + return 0 + + prison_open() + src.locked = 0 + src.open() + src.locked = 1 + return - else - ..(user) - return /obj/machinery/door/airlock/Topic(href, href_list) @@ -1024,265 +1237,269 @@ About the new airlock wires panel: src.update_icon() src.updateUsrDialog() if((istype(usr.equipped(), /obj/item/device/hacktool))) - attack_hack(usr, usr.equipped()) - + return attack_ai(usr, usr.equipped()) return -/obj/machinery/door/airlock/attackby(C as obj, mob/user as mob) - //world << text("airlock attackby src [] obj [] mob []", src, C, user) - if(istype(C, /obj/item/device/detective_scanner)) - return - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 75)) - return - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/weapon/screwdriver)) - src.p_open = !( src.p_open ) - src.update_icon() - else if (istype(C, /obj/item/weapon/wirecutters)) - 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/hacktool)) - return src.attack_hack(user, C) - 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) - var/beingcrowbarred = null - if(istype(C, /obj/item/weapon/crowbar) ) - beingcrowbarred = 1 //derp, Agouri - else - beingcrowbarred = 0 - if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) - playsound(src.loc, 'Crowbar.ogg', 100, 1) - user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") - if(do_after(user,40)) - user << "\blue You removed the airlock electronics!" - switch(src.doortype) - if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) - if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) - if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) - if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) - if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) - if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) - if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) - if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) - var/obj/item/weapon/airlock_electronics/ae - if (!electronics) - ae = new/obj/item/weapon/airlock_electronics( src.loc ) - ae.conf_access = src.req_access - else - ae = electronics - electronics = null - ae.loc = src.loc - del(src) - return - else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) - user << "\blue The airlock's motors resist your efforts to pry it open." - else if (src.locked) - user << "\blue The airlock's bolts prevent it from being pried open." - if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) - if(beingcrowbarred == 0) //being fireaxe'd - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("opening") +/obj/machinery/door/airlock/secure + name = "Secure Airlock" + desc = "Good lord, at least they left out the overcomplicated death traps. Looks to be a layer of armor plate you might be able to remove with a wrench." + icon = 'Doorhatchele.dmi' - sleep(15) + wires = 65535 + wirenum = 16 + alert_probability = 20 + holdopen = 0 + signalers = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var + list/WireColorToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + is_detached = 0 - layer = 2.7 - src.density = 0 - update_icon() - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - user << "\red You need to be wielding the Fire axe to do that." - return - else - spawn( 0 ) - src.operating = 1 - animate("opening") - sleep(15) - - layer = 2.7 - src.density = 0 - update_icon() - - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - - else - if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) - if(beingcrowbarred == 0) - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("closing") - - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - else - user << "\red You need to be wielding the Fire axe to do that." - else - spawn( 0 ) - src.operating = 1 - animate("closing") - - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - - else + New() ..() - return - -/obj/machinery/door/airlock/proc/synhack(mob/user as mob, obj/item/device/hacktool/I) - if (src.synHacking==0) - src.synHacking=1 - I.in_use = 1 - spawn(20 ) - user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." - sleep(25 ) - if (src.canSynControl()) - user << "Hack cancelled, control already possible." - src.synHacking=0 - I.in_use = 0 - return - else if (!src.canSynHack(I)) - user << "\red Connection lost. Stand still and stay near the airlock!" - src.synHacking=0 - I.in_use = 0 - return - user << "Connection established." - sleep(10 ) - user << "Attempting to hack into airlock. This may take some time." - sleep(100 ) - // Alerting the AIs - var/list/cameras = list() - for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area - cameras += C - - var/alertoption = prob(50) // 50% chance of warning the AI - if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) - alertoption = 3 - else if (prob(18)) //18% chance of sending the AI just the area - alertoption = 2 - - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - switch(alertoption) - if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) - if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - switch(alertoption) - if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") - - // ...And done - - if (!src.canSynHack(I)) - user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Local override already in place, hack aborted." - src.synHacking=0 - I.in_use = 0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(85 ) - if (!src.canSynHack(I)) - user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Upload access aborted, local override already in place." - src.synHacking=0 - I.in_use = 0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(25 ) - //disable blocked control - src.synDoorHacked = 1 - user << "Bingo! We're in. Airlock control panel coming right up." - sleep(5 ) - //bring up airlock dialog - src.synHacking = 0 - I.in_use = 0 - src.attack_hack(user, I) - -/obj/machinery/door/airlock/open() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) - return 0 - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) - src.closeOther.close() - return ..() - -/obj/machinery/door/airlock/close() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/flagIndex = 1 + for (var/flag=1, flag<65536, flag+=flag) + var/valid = 0 + while (!valid) + var/colorIndex = rand(1, 16) + if (WireColorToFlag[colorIndex] == 0) + valid = 1 + WireColorToFlag[colorIndex] = flag + IndexToFlag[flagIndex] = flag + IndexToWireColor[flagIndex] = colorIndex + WireColorToIndex[colorIndex] = flagIndex + flagIndex+=1 return - ..() - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) - if(killthis) - killthis.ex_act(2)//Smashin windows - return - -/obj/machinery/door/airlock/New() - ..() - if (src.closeOtherId != null) - spawn (5) - for (var/obj/machinery/door/airlock/A in machines) - if (A.closeOtherId == src.closeOtherId && A != src) - src.closeOther = A - break -/obj/machinery/door/airlock/proc/prison_open() - src.locked = 0 - src.open() - src.locked = 1 - return \ No newline at end of file + isWireColorCut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + + isWireCut(var/wireIndex) + var/wireFlag = IndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + pulse(var/wireColor) + var/wireIndex = WireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + cut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + mend(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 + + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & WireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if(!src.is_detached) + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/device/hacktool)) + return src.attack_ai(user, C) + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start to remove the armor plate..." + if(do_after(user,30)) + user << "Armor plates removed" + src.is_detached = 1 + else + if (istype(C, /obj/item/weapon/wrench)) + user << "You start to reattach the armor plate..." + if(do_after(user,30)) + user << "Armor plates attached" + src.is_detached = 0 + else + return ..(C, user) \ No newline at end of file diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 0a697d414c1..fe46d91232e 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -137,7 +137,13 @@ if (!src.requiresID()) //don't care who they are or what they have, act as if they're NOTHING user = null - if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + if (src.density && (istype(I, /obj/item/weapon/card/emag) ||istype(I, /obj/item/weapon/melee/energy/blade))) + if(istype(I, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return src.operating = -1 if(istype(I, /obj/item/weapon/melee/energy/blade)) if(istype(src, /obj/machinery/door/airlock)) @@ -342,12 +348,13 @@ if(T) L.loc = T - for(var/obj/item/I in src.loc) // Move items out of the way - if(!I.anchored) - var/list/lst = list(NORTH,SOUTH,EAST,WEST) - var/turf/T = get_random_turf(I, lst) - if(T) - I.loc = T + if(!src.forcecrush) + for(var/obj/item/I in src.loc) // Move items out of the way + if(!I.anchored) + var/list/lst = list(NORTH,SOUTH,EAST,WEST) + var/turf/T = get_random_turf(I, lst) + if(T) + I.loc = T sleep(6) update_icon() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index d91c2b56bca..76280d6b56b 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -121,6 +121,12 @@ //don't care who they are or what they have, act as if they're NOTHING user = null if (src.density && (istype(I, /obj/item/weapon/card/emag)||istype(I, /obj/item/weapon/melee/energy/blade))) + if(istype(I, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return src.operating = -1 if(istype(I, /obj/item/weapon/melee/energy/blade)) var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 09abb12e1ab..987406df374 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -50,6 +50,11 @@ /obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) if(istype(G,/obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = G + if(E.uses) + E.uses-- + else + return user.visible_message( \ "\red [user] swipes a strange card through \the [src]'s control panel!", \ "\red You swipe a strange card through \the [src]'s control panel!", \ diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 7949cbae652..6726520c801 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -172,6 +172,11 @@ Neutralize All Unidentified Life Signs: []
"}, if ((istype(W, /obj/item/weapon/card/emag)) && (!src.emagged)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return // Emagging the turret makes it go bonkers and stun everyone. It also makes // the turret shoot much, much faster. @@ -861,6 +866,11 @@ Neutralize All Unidentified Life Signs: []
"}, /obj/machinery/porta_turret_cover/attackby(obj/item/W as obj, mob/user as mob) if ((istype(W, /obj/item/weapon/card/emag)) && (!Parent_Turret.emagged)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return user << "\red You short out [Parent_Turret]'s threat assessment circuits." spawn(0) for(var/mob/O in hearers(Parent_Turret, null)) diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 6d939c6016a..03665dda37f 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -224,6 +224,11 @@ A.anchored = 1 del(src) else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = D + if(E.uses) + E.uses-- + else + return playsound(src.loc, 'sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" diff --git a/code/game/machinery/telecomms/telemonitor.dm b/code/game/machinery/telecomms/telemonitor.dm index 670673179f6..a7ee7e827e8 100644 --- a/code/game/machinery/telecomms/telemonitor.dm +++ b/code/game/machinery/telecomms/telemonitor.dm @@ -154,6 +154,11 @@ A.anchored = 1 del(src) else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = D + if(E.uses) + E.uses-- + else + return playsound(src.loc, 'sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index ab73e09e80e..4feca37b7a9 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -319,6 +319,11 @@ To combat this, I changed the window name. -- Doohl /obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return src.emagged = 1 user << "You short out the ID lock on [src]" return diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm index 7c9942f3aeb..348b64470bb 100644 --- a/code/game/magic/library.dm +++ b/code/game/magic/library.dm @@ -720,6 +720,11 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f /obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob) if (src.density && istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return src.emagged = 1 if(istype(W, /obj/item/weapon/barcodescanner)) var/obj/item/weapon/barcodescanner/scanner = W diff --git a/code/game/objects/closets/secure/personal.dm b/code/game/objects/closets/secure/personal.dm index c3d09c48bcc..16726cc7ef3 100644 --- a/code/game/objects/closets/secure/personal.dm +++ b/code/game/objects/closets/secure/personal.dm @@ -41,6 +41,12 @@ else user << "\red Access Denied" else if( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken) + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return broken = 1 locked = 0 desc = "It appears to be broken." diff --git a/code/game/objects/closets/secure/secure_closets.dm b/code/game/objects/closets/secure/secure_closets.dm index 1923e0cf847..f971a61c63a 100644 --- a/code/game/objects/closets/secure/secure_closets.dm +++ b/code/game/objects/closets/secure/secure_closets.dm @@ -38,6 +38,12 @@ user << "\red It appears to be broken." return else if((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken) + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return broken = 1 locked = 0 desc = "It appears to be broken." diff --git a/code/game/objects/closets/walllocker.dm b/code/game/objects/closets/walllocker.dm index cea7e6e2e9d..0aea34dcdbc 100644 --- a/code/game/objects/closets/walllocker.dm +++ b/code/game/objects/closets/walllocker.dm @@ -48,6 +48,11 @@ user << "\red It appears to be broken." return else if(istype(W, /obj/item/weapon/card/emag) && !src.broken) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return src.broken = 1 src.locked = 0 src.icon_state = src.icon_broken diff --git a/code/game/objects/door_assembly.dm b/code/game/objects/door_assembly.dm index f9e605d55a2..22d53ef572a 100644 --- a/code/game/objects/door_assembly.dm +++ b/code/game/objects/door_assembly.dm @@ -43,7 +43,7 @@ obj/structure/door_assembly name = "Security Airlock Assembly" icon_state = "door_as_sec1" glass_base_icon_state = "door_as_gsec" - glass_type = /obj/machinery/door/airlock/glass_security + glass_type = /obj/machinery/door/airlock/glass/glass_security airlock_type = /obj/machinery/door/airlock/security anchored = 1 density = 1 @@ -58,7 +58,7 @@ obj/structure/door_assembly name = "Engineering Airlock Assembly" icon_state = "door_as_eng1" glass_base_icon_state = "door_as_geng" - glass_type = /obj/machinery/door/airlock/glass_engineering + glass_type = /obj/machinery/door/airlock/glass/glass_engineering airlock_type = /obj/machinery/door/airlock/engineering anchored = 1 density = 1 @@ -73,7 +73,7 @@ obj/structure/door_assembly name = "Medical Airlock Assembly" icon_state = "door_as_med1" glass_base_icon_state = "door_as_gmed" - glass_type = /obj/machinery/door/airlock/glass_medical + glass_type = /obj/machinery/door/airlock/glass/glass_medical airlock_type = /obj/machinery/door/airlock/medical anchored = 1 density = 1 diff --git a/code/game/objects/secstorage/secstorage.dm b/code/game/objects/secstorage/secstorage.dm index 5a9defccdce..9458f05a853 100644 --- a/code/game/objects/secstorage/secstorage.dm +++ b/code/game/objects/secstorage/secstorage.dm @@ -93,7 +93,13 @@ /obj/item/weapon/secstorage/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() - if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (src.locked == 1) && (!src.emagged)) + if ((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && (src.locked == 1) && (!src.emagged)) + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return emagged = 1 src.overlays += image('storage.dmi', icon_sparking) sleep(6) diff --git a/code/game/objects/storage/crates.dm b/code/game/objects/storage/crates.dm index c111c52acd2..af16542f58a 100644 --- a/code/game/objects/storage/crates.dm +++ b/code/game/objects/storage/crates.dm @@ -258,6 +258,12 @@ overlays += redlight return else if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && locked &&!broken) + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return overlays = null overlays += emag overlays += sparks diff --git a/code/game/objects/storage/lockbox.dm b/code/game/objects/storage/lockbox.dm index 49b9d3b3fda..d3cba8ecfcf 100644 --- a/code/game/objects/storage/lockbox.dm +++ b/code/game/objects/storage/lockbox.dm @@ -34,6 +34,12 @@ else user << "\red Access Denied" else if((istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && !src.broken) + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return broken = 1 locked = 0 desc = "It appears to be broken." diff --git a/code/game/prisonshuttle.dm b/code/game/prisonshuttle.dm index dd01888d035..8fa447c9ae5 100644 --- a/code/game/prisonshuttle.dm +++ b/code/game/prisonshuttle.dm @@ -35,6 +35,11 @@ var/prison_shuttle_timeleft = 0 attackby(I as obj, user as mob) if(istype(I,/obj/item/weapon/card/emag) && (!hacked)) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return hacked = 1 user << "\blue You disable the lock." else diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index e3d27b1256b..b9e01877862 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -402,6 +402,11 @@ var/list/supply_groups = new() /obj/machinery/computer/supplycomp/attackby(I as obj, user as mob) if(istype(I,/obj/item/weapon/card/emag) && !hacked) + var/obj/item/weapon/card/emag/E = I + if(E.uses) + E.uses-- + else + return user << "\blue Special supplies unlocked." src.hacked = 1 return diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 79157b40fa7..35fc955cd26 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -86,6 +86,11 @@ proc/move_mining_shuttle() /obj/machinery/computer/mining_shuttle/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return src.req_access = list() hacked = 1 usr << "You fried the consoles ID checking system. It's now available to everyone!" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 62331f82765..2794e498899 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -421,6 +421,11 @@ user << "\red Access denied." else if(istype(W, /obj/item/weapon/card/emag)) // trying to unlock with an emag card + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return if(!opened)//Cover is closed if(locked) if(prob(90)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index c691bd5326d..8494727395b 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -300,6 +300,12 @@ else user << "\red Access denied." else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card + if(istype(W, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = W + if(E.uses) + E.uses-- + else + return if(opened) user << "You must close the cover to swipe an ID card." else if(wiresexposed) @@ -859,7 +865,7 @@ else src.malfai = usr malfai << "Hack complete. The APC is now under your exclusive control." - updateicon() + updateicon() else if (href_list["occupyapc"]) malfoccupy(usr) @@ -876,21 +882,21 @@ return if(src.z != 1) return - + src.occupant = new /mob/living/silicon/ai(src,malf.laws,null,1) src.occupant.adjustOxyLoss(malf.getOxyLoss()) src.occupant.name = "[malf.name] APC Copy" - + if(malf.parent) src.occupant.parent = malf.parent else src.occupant.parent = malf - + malf.mind.transfer_to(src.occupant) - + if(malf.parent) del(malf) - + src.occupant.verbs += /mob/living/silicon/ai/proc/corereturn src.occupant.cancel_camera() diff --git a/code/modules/power/pacman2.dm b/code/modules/power/pacman2.dm index 930877d441a..98d3eb1e8fa 100644 --- a/code/modules/power/pacman2.dm +++ b/code/modules/power/pacman2.dm @@ -81,6 +81,11 @@ O.loc = src user << "\blue You add the plasma tank to the generator." else if (istype(O, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = O + if(E.uses) + E.uses-- + else + return emagged = 1 emp_act(1) else if(!active) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 2ad21eb5cdc..dd5f262e99d 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -196,6 +196,11 @@ display round(lastgen) and plasmatank amount del(O) user << "\blue You add a coin to the generator." else if (istype(O, /obj/item/weapon/card/emag)) + var/obj/item/weapon/card/emag/E = O + if(E.uses) + E.uses-- + else + return emagged = 1 emp_act(1) else if(!active) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index fa6178bdee2..6dd2fcdb4cb 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -176,6 +176,11 @@ won't update every console in existence) but it's more of a hassle to do. Also, D.loc = src user << "\blue You add the disk to the machine!" else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = D + if(E.uses) + E.uses-- + else + return playsound(src.loc, 'sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index e898808c668..8467ab99ff6 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -326,6 +326,11 @@ A.anchored = 1 del(src) else if(istype(D, /obj/item/weapon/card/emag) && !emagged) + var/obj/item/weapon/card/emag/E = D + if(E.uses) + E.uses-- + else + return playsound(src.loc, 'sparks4.ogg', 75, 1) emagged = 1 user << "\blue You you disable the security protocols" From 7298e8619b25c873aa09a49740e9b4b5edf7e3f6 Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 13:33:55 -0700 Subject: [PATCH 2/7] Adding in cut down hacktool for CE. --- code/defines/obj.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/defines/obj.dm b/code/defines/obj.dm index 4b3cd52c64a..f537f56aaa4 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -356,6 +356,10 @@ m_amt = 60 g_amt = 20 +/obj/item/device/hacktool/engineer + name = "door debugger" + desc = "An item of immense complexion, it appears to work by magic." + /obj/item/blueprints name = "station blueprints" desc = "Blueprints of the station. There's stamp \"Classified\" and several coffee stains on it." From b967f6b5774251096610e56e3b04865d2b38e2fd Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 13:46:10 -0700 Subject: [PATCH 3/7] Should make the engineer hacktool auto raise the bolts, at the cost of alerting the AI. --- code/game/machinery/doors/airlock.dm | 3061 +++++++++++++++++++++++++- 1 file changed, 3054 insertions(+), 7 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 65a75a0b569..b56589fcbc0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -537,6 +537,8 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. if (!src.canSynControl() && src.canSynHack(C)) src.synhack(user, C) return + if(istype(C, /obj/item/device/hacktool/engineer)) + return else world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" return @@ -690,12 +692,18 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. synhack(mob/user as mob, obj/item/device/hacktool/I) if (src.synHacking==0) + var/multiplier = 1 + if(istype(C, /obj/item/device/hacktool/engineer)) + if(!src.locked) + user << "The door bolts are already up!" + return + multiplier++ src.synHacking=1 I.in_use = 1 user << "You begin hacking..." - spawn(20) + spawn(20*multiplier) user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." - sleep(25) + sleep(25*multiplier) if (src.canSynControl()) user << "Hack cancelled, control already possible." src.synHacking=0 @@ -707,15 +715,15 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. I.in_use = 0 return user << "Connection established." - sleep(10) + sleep(10*multiplier) user << "Attempting to hack into airlock. This may take some time." - sleep(50) + sleep(50*multiplier) // Alerting the AIs var/list/cameras = list() for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area cameras += C - var/alertoption = prob(alert_probability) // Chance of warning AI, based on doortype's probability + var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability if(alertoption) if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) alertoption = 3 @@ -745,7 +753,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. I.in_use = 0 return user << "Upload access confirmed. Loading control program into airlock software." - sleep(35) + sleep(35*multiplier) if (!src.canSynHack(I)) user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." src.synHacking=0 @@ -757,8 +765,1499 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. I.in_use = 0 return user << "Transfer complete. Forcing airlock to execute program." - sleep(25) + sleep(25*multiplier) //disable blocked control + if(istype(C, /obj/item/device/hacktool/engineer)) + user << "Raising door bolts..." + src.locked = 0 + update_icon() + return + src.synDoorHacked = 1 + user << "Bingo! We're in. Airlock control panel coming right up." + sleep(5) + //bring up airlock dialog + src.synHacking = 0 + I.in_use = 0 + src.attack_ai(user, I) + + + canAIControl() + return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); + + + canAIHack() + return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); + + + canSynControl() + return (src.synDoorHacked && (!src.isAllPowerCut())); + + + canSynHack(obj/item/device/hacktool/H) + return (in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()); + + + +/* +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 \red 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) +*/ + + pulse(var/wireColor) + //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function + var/wireIndex = airlockWireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + + cut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + + mend(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 + + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & airlockWireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 + + isElectrified() + return (src.secondsElectrified != 0); + + isWireColorCut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + + isWireCut(var/wireIndex) + var/wireFlag = airlockIndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + arePowerSystemsOn() + return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) + + isAllPowerCut() + return ((src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) && (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + + regainMainPower() + if (src.secondsMainPowerLost > 0) + src.secondsMainPowerLost = 0 + + loseMainPower() + if (src.secondsMainPowerLost <= 0) + src.secondsMainPowerLost = 60 + if (src.secondsBackupPowerLost < 10) + src.secondsBackupPowerLost = 10 + if (!src.spawnPowerRestoreRunning) + src.spawnPowerRestoreRunning = 1 + spawn(0) + var/cont = 1 + while (cont) + sleep(10) + cont = 0 + if (src.secondsMainPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.secondsMainPowerLost -= 1 + src.updateDialog() + cont = 1 + + if (src.secondsBackupPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.secondsBackupPowerLost -= 1 + src.updateDialog() + cont = 1 + src.spawnPowerRestoreRunning = 0 + src.updateDialog() + + loseBackupPower() + if (src.secondsBackupPowerLost < 60) + src.secondsBackupPowerLost = 60 + + regainBackupPower() + if (src.secondsBackupPowerLost > 0) + src.secondsBackupPowerLost = 0 + + // 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 + shock(mob/user, prb) + if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 //you lucked out, no shock for you + if(istype(usr.equipped(),/obj/item/weapon/shard)) + return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src)) + return 1 + else + return 0 + + prison_open() + src.locked = 0 + src.open() + src.locked = 1 + return + + + +/obj/machinery/door/airlock/Topic(href, href_list) + ..() + if (usr.stat || usr.restrained() ) + return + if (href_list["close"]) + usr << browse(null, "window=airlock") + if (usr.machine==src) + usr.machine = null + return + if(in_range(src, usr) && istype(src.loc, /turf) && p_open) + usr.machine = src + if (href_list["wires"]) + var/t1 = text2num(href_list["wires"]) + if (!(istype(usr.equipped(), /obj/item/weapon/wirecutters) || istype(usr.equipped(),/obj/item/weapon/shard))) + usr << "You need wirecutters!" + return + if (src.isWireColorCut(t1) && istype(usr.equipped(), /obj/item/weapon/wirecutters)) + src.mend(t1) + else + src.cut(t1) + else if (href_list["pulse"]) + var/t1 = text2num(href_list["pulse"]) + if (!istype(usr.equipped(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return + if (src.isWireColorCut(t1)) + usr << "You can't pulse a cut wire." + return + else + src.pulse(t1) + else if(href_list["signaler"]) + var/wirenum = text2num(href_list["signaler"]) + if(!istype(usr.equipped(), /obj/item/device/assembly/signaler)) + usr << "You need a signaller!" + return + if(src.isWireColorCut(wirenum)) + usr << "You can't attach a signaller to a cut wire." + return + var/obj/item/device/assembly/signaler/R = usr.equipped() + if(R.secured) + usr << "This radio can't be attached!" + return + var/mob/M = usr + M.drop_item() + R.loc = src + R.airlock_wire = wirenum + src.signalers[wirenum] = R + else if(href_list["remove-signaler"]) + var/wirenum = text2num(href_list["remove-signaler"]) + if(!(src.signalers[wirenum])) + usr << "There's no signaller attached to that wire!" + return + var/obj/item/device/assembly/signaler/R = src.signalers[wirenum] + R.loc = usr.loc + R.airlock_wire = null + src.signalers[wirenum] = null + + src.update_icon() + add_fingerprint(usr) + src.updateUsrDialog() + else //AI or Syndicate using hacktool + if (!src.canAIControl() || (istype(usr.equipped(), /obj/item/device/hacktool/) && (!src.canSynControl() || !in_range(src, usr)))) + usr << "Airlock control connection lost!" + return + //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door + //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door + if (href_list["aiDisable"]) + var/code = text2num(href_list["aiDisable"]) + switch (code) + if (1) + //disable idscan + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + usr << "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways." + else if (src.aiDisabledIdScanner) + usr << "You've already disabled the IdScan feature." + else + src.aiDisabledIdScanner = 1 + if (2) + //disrupt main power + if (src.secondsMainPowerLost == 0) + src.loseMainPower() + else + usr << "Main power is already offline." + if (3) + //disrupt backup power + if (src.secondsBackupPowerLost == 0) + src.loseBackupPower() + else + usr << "Backup power is already offline." + if (4) + //drop door bolts + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + usr << "You can't drop the door bolts - The door bolt dropping wire has been cut." + else if (src.locked!=1) + src.locked = 1 + update_icon() + if (5) + //un-electrify door + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("Can't un-electrify the airlock - The electrification wire is cut.
\n") + else if (src.secondsElectrified==-1) + src.secondsElectrified = 0 + else if (src.secondsElectrified>0) + src.secondsElectrified = 0 + if (7) + //close door + if (src.welded) + usr << text("The airlock has been welded shut!
\n") + else if (src.locked) + usr << text("The door bolts are down!
\n") + else if (!src.density) + close() + else + usr << text("The airlock is already closed.
\n") + if (8) + if(!src.forcecrush) + usr << text("Door extra force not enabled!
\n") + else + src.forcecrush = 0 + if (9) + if(!src.safetylight) + usr << text("Bolt indication light not enabled!
\n") + else + src.safetylight = 0 + if (10) + if(!src.holdopen) + usr << text("Door Behavior already set to: Wait for clearance to close
\n") + else + src.holdopen = 0 + + else if (href_list["aiEnable"]) + var/code = text2num(href_list["aiEnable"]) + switch (code) + if (1) + //enable idscan + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + usr << "You can't enable IdScan - The IdScan wire has been cut." + else if (src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 0 + else + usr << "The IdScan feature is not disabled." + if (4) + //raise door bolts + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + usr << text("The door bolt drop wire is cut - you can't raise the door bolts.
\n") + else if (!src.locked) + usr << text("The door bolts are already up.
\n") + else + if (src.arePowerSystemsOn()) + src.locked = 0 + update_icon() + else + usr << text("Cannot raise door bolts due to power failure.
\n") + + if (5) + //electrify door for 30 seconds + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("The electrification wire has been cut.
\n") + else if (src.secondsElectrified==-1) + usr << text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
\n") + else if (src.secondsElectrified!=0) + usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") + else + src.secondsElectrified = 30 + spawn(10) + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + src.updateUsrDialog() + sleep(10) + if (6) + //electrify door indefinitely + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("The electrification wire has been cut.
\n") + else if (src.secondsElectrified==-1) + usr << text("The door is already indefinitely electrified.
\n") + else if (src.secondsElectrified!=0) + usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") + else + src.secondsElectrified = -1 + if (7) + //open door + if (src.welded) + usr << text("The airlock has been welded shut!
\n") + else if (src.locked) + usr << text("The door bolts are down!
\n") + else if (src.density) + open() + // close() + else + usr << text("The airlock is already opened.
\n") + if (8) + if(src.forcecrush) + usr << text("Door extra force already enabled!
\n") + else + src.forcecrush = 1 + if (9) + if(src.safetylight) + usr << text("Bolt indication light already enabled!
\n") + else + src.safetylight = 1 + if (10) + if(src.holdopen) + usr << text("Door Behavior already set to: Automatically close
\n") + else + src.holdopen = 1 + + src.update_icon() + src.updateUsrDialog() + if((istype(usr.equipped(), /obj/item/device/hacktool))) + return attack_ai(usr, usr.equipped()) + return + + + + +/obj/machinery/door/airlock/secure + name = "Secure Airlock" + desc = "Good lord, at least they left out the overcomplicated death traps. Looks to be a layer of armor plate you might be able to remove with a wrench." + icon = 'Doorhatchele.dmi' + + wires = 65535 + wirenum = 16 + alert_probability = 20 + holdopen = 0 + signalers = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var + list/WireColorToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + is_detached = 0 + + + + New() + ..() + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/flagIndex = 1 + for (var/flag=1, flag<65536, flag+=flag) + var/valid = 0 + while (!valid) + var/colorIndex = rand(1, 16) + if (WireColorToFlag[colorIndex] == 0) + valid = 1 + WireColorToFlag[colorIndex] = flag + IndexToFlag[flagIndex] = flag + IndexToWireColor[flagIndex] = colorIndex + WireColorToIndex[colorIndex] = flagIndex + flagIndex+=1 + return + + + isWireColorCut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + + isWireCut(var/wireIndex) + var/wireFlag = IndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + pulse(var/wireColor) + var/wireIndex = WireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + cut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + mend(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 + + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & WireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if(!src.is_detached) + if (!istype(usr, /mob/living/silicon))#define AIRLOCK_WIRE_IDSCAN 1 +#define AIRLOCK_WIRE_MAIN_POWER1 2 +#define AIRLOCK_WIRE_MAIN_POWER2 3 +#define AIRLOCK_WIRE_DOOR_BOLTS 4 +#define AIRLOCK_WIRE_BACKUP_POWER1 5 +#define AIRLOCK_WIRE_BACKUP_POWER2 6 +#define AIRLOCK_WIRE_OPEN_DOOR 7 +#define AIRLOCK_WIRE_AI_CONTROL 8 +#define AIRLOCK_WIRE_ELECTRIFY 9 +#define AIRLOCK_WIRE_CRUSH 10 +#define AIRLOCK_WIRE_LIGHT 11 +#define AIRLOCK_WIRE_HOLDOPEN 12 +#define AIRLOCK_WIRE_FAKEBOLT1 13 +#define AIRLOCK_WIRE_FAKEBOLT2 14 +#define AIRLOCK_WIRE_ALERTAI 15 +#define AIRLOCK_WIRE_DOOR_BOLTS_2 16 +//#define AIRLOCK_WIRE_FINGERPRINT 17 + +/* + New methods: + pulse - sends a pulse into a wire for hacking purposes + cut - cuts a wire and makes any necessary state changes + mend - mends a wire and makes any necessary state changes + isWireColorCut - returns 1 if that color wire is cut, or 0 if not + isWireCut - returns 1 if that wire (e.g. AIRLOCK_WIRE_DOOR_BOLTS) is cut, or 0 if not + canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in) + canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it. + arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that) + requiresIDs - 1 if the airlock is requiring IDs, 0 if not + isAllPowerCut - 1 if the main and backup power both have cut wires. + regainMainPower - handles the effect of main power coming back on. + loseMainPower - handles the effect of main power going offline. Usually (if one isn't already running) spawn a thread to count down how long it will be offline - counting down won't happen if main power was completely cut along with backup power, though, the thread will just sleep. + loseBackupPower - handles the effect of backup power going offline. + regainBackupPower - handles the effect of main power coming back on. + shock - has a chance of electrocuting its target. +*/ + +//This generates the randomized airlock wire assignments for the game. +/proc/RandomAirlockWires() + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var/flagIndex = 1 + for (var/flag=1, flag<4096, flag+=flag) + var/valid = 0 + while (!valid) + var/colorIndex = rand(1, 12) + if (wires[colorIndex] == 0) + valid = 1 + wires[colorIndex] = flag + airlockIndexToFlag[flagIndex] = flag + airlockIndexToWireColor[flagIndex] = colorIndex + airlockWireColorToIndex[colorIndex] = flagIndex + flagIndex+=1 + return wires + +/* Example: +Airlock wires color -> flag are { 64, 128, 256, 2, 16, 4, 8, 32, 1 }. +Airlock wires color -> index are { 7, 8, 9, 2, 5, 3, 4, 6, 1 }. +Airlock index -> flag are { 1, 2, 4, 8, 16, 32, 64, 128, 256 }. +Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. +*/ + +/obj/machinery/door/airlock + name = "Airlock" + icon = 'doorint.dmi' + icon_state = "door_closed" + + 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. + synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no + synHacking = 0 // Is hack in process y/n? + secondsMainPowerLost = 0 //The number of seconds until power is restored. + secondsBackupPowerLost = 0 //The number of seconds until power is restored. + spawnPowerRestoreRunning = 0 + welded = null + locked = 0 + wires = 4095 + aiDisabledIdScanner = 0 + aiHacking = 0 + obj/machinery/door/airlock/closeOther = null + closeOtherId = null + list/signalers[12] + lockdownbyai = 0 + doortype = 0 + justzap = 0 + safetylight = 1 + obj/item/weapon/airlock_electronics/electronics = null + alert_probability = 3 + list/wire_index = list( + "Orange" = 1, + "Dark red" = 2, + "White" = 3, + "Yellow" = 4, + "Red" = 5, + "Blue" = 6, + "Green" = 7, + "Grey" = 8, + "Black" = 9, + "Pink" = 10, + "Brown" = 11, + "Maroon" = 12, + "Aqua" = 13, + "Turgoise" = 14, + "Purple" = 15, + "Rainbow" = 16, + "Atomic Tangerine" = 17, + "Neon Green" = 18, + "Cotton Candy" = 19, + "Plum" = 20, + "Shamrock" = 21, + "Indigo" = 22 + ) + wirenum = 12 + holdopen = 1 + autoclose = 1 + secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + + + command + name = "Airlock" + icon = 'Doorcom.dmi' + doortype = 1 + holdopen = 0 + + + security + name = "Airlock" + icon = 'Doorsec.dmi' + doortype = 2 + + + engineering + name = "Airlock" + icon = 'Dooreng.dmi' + doortype = 3 + + + medical + name = "Airlock" + icon = 'Doormed.dmi' + doortype = 4 + + + maintenance + name = "Maintenance Access" + icon = 'Doormaint.dmi' + doortype = 5 + + external + name = "External Airlock" + icon = 'Doorext.dmi' + doortype = 6 + + + glass + name = "Glass Airlock" + icon = 'Doorglass.dmi' + opacity = 0 + doortype = 7 + glass = 1 + + + glass_command + name = "Maintenance Hatch" + icon = 'Doorcomglass.dmi' + opacity = 0 + doortype = 14 + glass = 1 + + + glass_engineering + name = "Maintenance Hatch" + icon = 'Doorengglass.dmi' + opacity = 0 + doortype = 15 + glass = 1 + + + glass_security + name = "Maintenance Hatch" + icon = 'Doorsecglass.dmi' + opacity = 0 + doortype = 16 + glass = 1 + + + glass_medical + name = "Maintenance Hatch" + icon = 'doormedglass.dmi' + opacity = 0 + doortype = 17 + glass = 1 + + + centcom + name = "Airlock" + icon = 'Doorele.dmi' + opacity = 0 + doortype = 8 + + + vault + name = "Vault" + icon = 'vault.dmi' + opacity = 1 + doortype = 9 + + + glass_large + name = "Glass Airlock" + icon = 'Door2x1glassfull.dmi' + opacity = 0 + doortype = 10 + glass = 1 + + + freezer + name = "Freezer Airlock" + icon = 'Doorfreezer.dmi' + opacity = 1 + doortype = 11 + + + hatch + name = "Airtight Hatch" + icon = 'Doorhatchele.dmi' + opacity = 1 + doortype = 12 + + + maintenance_hatch + name = "Maintenance Hatch" + icon = 'Doorhatchmaint2.dmi' + opacity = 1 + doortype = 13 + + + New() + ..() + if (src.closeOtherId != null) + spawn (5) + for (var/obj/machinery/door/airlock/A in machines) + if (A.closeOtherId == src.closeOtherId && A != src) + src.closeOther = A + break + + + open() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + return 0 + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) + src.closeOther.close() + return ..() + + + close() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + return + ..() + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) + if(killthis) + killthis.ex_act(2)//Smashin windows + return + + + bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite + if (!istype(usr, /mob/living/silicon)) + 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) + user << "\red You feel a powerful shock course through your body!" + user.halloss += 10 + user.stunned += 10 + return + ..(user) + + + update_icon() + if(overlays) overlays = null + if(density) + if(locked && safetylight) + icon_state = "door_locked" + else + icon_state = "door_closed" + if(p_open || welded) + overlays = list() + if(p_open) + overlays += image(icon, "panel_open") + if(welded) + overlays += image(icon, "welded") + else + icon_state = "door_open" + return + + + animate(animation) + switch(animation) + if("opening") + if(overlays) overlays = null + if(p_open) + icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking + else + flick("door_opening", src) + if("closing") + if(overlays) overlays = null + if(p_open) + flick("o_door_closing", src) + else + flick("door_closing", src) + if("spark") + flick("door_spark", src) + if("deny") + flick("door_deny", src) + return + + requiresID() + return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/weapon/screwdriver)) + src.p_open = !( src.p_open ) + src.update_icon() + else if (istype(C, /obj/item/weapon/wirecutters)) + 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/hacktool)) + return src.attack_ai(user, C) + 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) + var/beingcrowbarred = null + if(istype(C, /obj/item/weapon/crowbar) ) + beingcrowbarred = 1 //derp, Agouri + else + beingcrowbarred = 0 + if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) + playsound(src.loc, 'Crowbar.ogg', 100, 1) + user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") + if(do_after(user,40)) + user << "\blue You removed the airlock electronics!" + switch(src.doortype) + if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) + if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) + if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) + if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) + if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) + if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) + if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) + if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) + var/obj/item/weapon/airlock_electronics/ae + if (!electronics) + ae = new/obj/item/weapon/airlock_electronics( src.loc ) + ae.conf_access = src.req_access + else + ae = electronics + electronics = null + ae.loc = src.loc + + del(src) + return + else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) + user << "\blue The airlock's motors resist your efforts to pry it open." + else if (src.locked) + user << "\blue The airlock's bolts prevent it from being pried open." + if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) + + if(beingcrowbarred == 0) //being fireaxe'd + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + user << "\red You need to be wielding the Fire axe to do that." + return + else + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + + else + if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) + if(beingcrowbarred == 0) + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("closing") + + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + else + user << "\red You need to be wielding the Fire axe to do that." + else + spawn( 0 ) + src.operating = 1 + animate("closing") + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + + else + ..() + return + + + attack_paw(mob/user as mob) + return src.attack_hand(user) + + + attack_hand(mob/user as mob) + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 100)) + return + + if (ishuman(user) && prob(40) && src.density) + var/mob/living/carbon/human/H = user + if(H.getBrainLoss() >= 60) + playsound(src.loc, 'bang.ogg', 25, 1) + if(!istype(H.head, /obj/item/clothing/head/helmet)) + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock." + var/datum/organ/external/affecting = H.get_organ("head") + affecting.take_damage(10, 0) + H.Stun(8) + H.Weaken(5) + H.UpdateDamageIcon() + else + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." + return + + if (src.p_open) + user.machine = src + var/t1 = text("Access Panel
\n") + + //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) + t1 += getAirlockWires() + + t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) + + t1 += text("

Close

\n", src) + + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + else + ..(user) + return + +//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 engage engineer smasher, 9 enable bolt indicator, 10 wait for clearance +//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 disable engineer smasher, 9 disable bolt indicator, 10 autoclose + //This has been converted to be called by either the AI or a mob with a hacktool, permitting either to directly operate the airlock + attack_ai(mob/user as mob, obj/item/device/hacktool/C) + if(isAI(user)) + if (!src.canAIControl()) + if (src.canAIHack()) + src.hack(user) + return + else if(user) + if(!C) + return + if(C.in_use) + user << "We are already hacking another airlock." + return + if (!src.canSynControl() && src.canSynHack(C)) + src.synhack(user, C) + return + if(istype(C, /obj/item/device/hacktool/engineer)) + return + else + world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" + return + + + //Separate interface for the AI. + user.machine = src + var/t1 = text("Airlock Control
\n") + if (src.secondsMainPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) + else + t1 += text("Main power is offline indefinitely.
\n") + else + t1 += text("Main power is online.") + + if (src.secondsBackupPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) + else + t1 += text("Backup power is offline indefinitely.
\n") + else if (src.secondsMainPowerLost > 0) + t1 += text("Backup power is online.") + else + t1 += text("Backup power is offline, but will turn on if main power fails.") + t1 += "
\n" + + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + t1 += text("IdScan wire is cut.
\n") + else if (src.aiDisabledIdScanner) + t1 += text("IdScan disabled. Enable?
\n", src) + else + t1 += text("IdScan enabled. Disable?
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) + t1 += text("Main Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) + t1 += text("Main Power Output wire is cut.
\n") + if (src.secondsMainPowerLost == 0) + t1 += text("Temporarily disrupt main power?.
\n", src) + if (src.secondsBackupPowerLost == 0) + t1 += text("Temporarily disrupt backup power?.
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) + t1 += text("Backup Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) + t1 += text("Backup Power Output wire is cut.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) + t1 += text("Airlock extra force wire is cut.
\n") + else if(!src.forcecrush) + t1 += text("Airlock extra force disabled Enable it?
\n") + else + t1 += text("Airlock extra force enabled Disable it?
\n") + + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + t1 += text("Door bolt drop wire is cut.
\n") + else if (!src.locked) + t1 += text("Door bolts are up. Drop them?
\n", src) + else + t1 += text("Door bolts are down.") + if (src.arePowerSystemsOn()) + t1 += text(" Raise?
\n", src) + else + t1 += text(" Cannot raise door bolts due to power failure.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + t1 += text("Electrification wire is cut.
\n") + if (src.secondsElectrified==-1) + t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) + else if (src.secondsElectrified>0) + t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) + else + t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) + + if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) + t1 += "Bolt indication light wire is cut.
\n" + else if(!src.safetylight) + t1 += text("Bolt Indication light is disabled Enable it?
\n") + else + t1 += text("Bolt Indication light is enabled Disable it?
\n") + + if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) + t1 += "Behavior Control light wire is cut.
\n" + else if(!src.holdopen) + t1 += text("Door behavior is set to: Automatically close Toggle?
\n") + else + t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") + + if (src.welded) + t1 += text("Door appears to have been welded shut.
\n") + else if (!src.locked) + if (src.density) + t1 += text("Open door
\n", src) + else + t1 += text("Close door
\n", src) + + t1 += text("

Close

\n", src) + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + + proc + hack(mob/user as mob) + if (src.aiHacking==0) + src.aiHacking=1 + spawn(20) + //TODO: Make this take a minute + user << "Airlock AI control has been blocked. Beginning fault-detection." + sleep(50) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Fault confirmed: airlock control wire disabled or cut." + sleep(20) + user << "Attempting to hack into airlock. This may take some time." + sleep(200) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(170) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(50) + //disable blocked control + src.aiControlDisabled = 2 + user << "Receiving control information from airlock." + sleep(10) + //bring up airlock dialog + src.aiHacking = 0 + src.attack_ai(user) + + + synhack(mob/user as mob, obj/item/device/hacktool/I) + if (src.synHacking==0) + var/multiplier = 1 + if(istype(C, /obj/item/device/hacktool/engineer)) + if(!src.locked) + user << "The door bolts are already up!" + return + multiplier++ + src.synHacking=1 + I.in_use = 1 + user << "You begin hacking..." + spawn(20*multiplier) + user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." + sleep(25*multiplier) + if (src.canSynControl()) + user << "Hack cancelled, control already possible." + src.synHacking=0 + I.in_use = 0 + return + else if (!src.canSynHack(I)) + user << "\red Connection lost. Stand still and stay near the airlock!" + src.synHacking=0 + I.in_use = 0 + return + user << "Connection established." + sleep(10*multiplier) + user << "Attempting to hack into airlock. This may take some time." + sleep(50*multiplier) + + // Alerting the AIs + var/list/cameras = list() + for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area + cameras += C + var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability + if(alertoption) + if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) + alertoption = 3 + else if (prob(18)) //18% chance of sending the AI just the area + alertoption = 2 + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + switch(alertoption) + if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) + if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + switch(alertoption) + if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") + // ...And done + + if (!src.canSynHack(I)) + user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Local override already in place, hack aborted." + src.synHacking=0 + I.in_use = 0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(35*multiplier) + if (!src.canSynHack(I)) + user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Upload access aborted, local override already in place." + src.synHacking=0 + I.in_use = 0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(25*multiplier) + //disable blocked control + if(istype(C, /obj/item/device/hacktool/engineer)) + user << "Raising door bolts..." + src.locked = 0 + update_icon() + return src.synDoorHacked = 1 user << "Bingo! We're in. Airlock control panel coming right up." sleep(5) @@ -1476,6 +2975,1554 @@ About the new airlock wires panel: if(src.shock(user, 75)) return + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/device/hacktool)) + return src.attack_ai(user, C) + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start to remove the armor plate..." + if(do_after(user,30)) + user << "Armor plates removed" + src.is_detached = 1 + else + if (istype(C, /obj/item/weapon/wrench)) + user << "You start to reattach the armor plate..." + if(do_after(user,30)) + user << "Armor plates attached" + src.is_detached = 0 + else + return ..(C, user)#define AIRLOCK_WIRE_IDSCAN 1 +#define AIRLOCK_WIRE_MAIN_POWER1 2 +#define AIRLOCK_WIRE_MAIN_POWER2 3 +#define AIRLOCK_WIRE_DOOR_BOLTS 4 +#define AIRLOCK_WIRE_BACKUP_POWER1 5 +#define AIRLOCK_WIRE_BACKUP_POWER2 6 +#define AIRLOCK_WIRE_OPEN_DOOR 7 +#define AIRLOCK_WIRE_AI_CONTROL 8 +#define AIRLOCK_WIRE_ELECTRIFY 9 +#define AIRLOCK_WIRE_CRUSH 10 +#define AIRLOCK_WIRE_LIGHT 11 +#define AIRLOCK_WIRE_HOLDOPEN 12 +#define AIRLOCK_WIRE_FAKEBOLT1 13 +#define AIRLOCK_WIRE_FAKEBOLT2 14 +#define AIRLOCK_WIRE_ALERTAI 15 +#define AIRLOCK_WIRE_DOOR_BOLTS_2 16 +//#define AIRLOCK_WIRE_FINGERPRINT 17 + +/* + New methods: + pulse - sends a pulse into a wire for hacking purposes + cut - cuts a wire and makes any necessary state changes + mend - mends a wire and makes any necessary state changes + isWireColorCut - returns 1 if that color wire is cut, or 0 if not + isWireCut - returns 1 if that wire (e.g. AIRLOCK_WIRE_DOOR_BOLTS) is cut, or 0 if not + canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in) + canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it. + arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that) + requiresIDs - 1 if the airlock is requiring IDs, 0 if not + isAllPowerCut - 1 if the main and backup power both have cut wires. + regainMainPower - handles the effect of main power coming back on. + loseMainPower - handles the effect of main power going offline. Usually (if one isn't already running) spawn a thread to count down how long it will be offline - counting down won't happen if main power was completely cut along with backup power, though, the thread will just sleep. + loseBackupPower - handles the effect of backup power going offline. + regainBackupPower - handles the effect of main power coming back on. + shock - has a chance of electrocuting its target. +*/ + +//This generates the randomized airlock wire assignments for the game. +/proc/RandomAirlockWires() + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var/flagIndex = 1 + for (var/flag=1, flag<4096, flag+=flag) + var/valid = 0 + while (!valid) + var/colorIndex = rand(1, 12) + if (wires[colorIndex] == 0) + valid = 1 + wires[colorIndex] = flag + airlockIndexToFlag[flagIndex] = flag + airlockIndexToWireColor[flagIndex] = colorIndex + airlockWireColorToIndex[colorIndex] = flagIndex + flagIndex+=1 + return wires + +/* Example: +Airlock wires color -> flag are { 64, 128, 256, 2, 16, 4, 8, 32, 1 }. +Airlock wires color -> index are { 7, 8, 9, 2, 5, 3, 4, 6, 1 }. +Airlock index -> flag are { 1, 2, 4, 8, 16, 32, 64, 128, 256 }. +Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. +*/ + +/obj/machinery/door/airlock + name = "Airlock" + icon = 'doorint.dmi' + icon_state = "door_closed" + + 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. + synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no + synHacking = 0 // Is hack in process y/n? + secondsMainPowerLost = 0 //The number of seconds until power is restored. + secondsBackupPowerLost = 0 //The number of seconds until power is restored. + spawnPowerRestoreRunning = 0 + welded = null + locked = 0 + wires = 4095 + aiDisabledIdScanner = 0 + aiHacking = 0 + obj/machinery/door/airlock/closeOther = null + closeOtherId = null + list/signalers[12] + lockdownbyai = 0 + doortype = 0 + justzap = 0 + safetylight = 1 + obj/item/weapon/airlock_electronics/electronics = null + alert_probability = 3 + list/wire_index = list( + "Orange" = 1, + "Dark red" = 2, + "White" = 3, + "Yellow" = 4, + "Red" = 5, + "Blue" = 6, + "Green" = 7, + "Grey" = 8, + "Black" = 9, + "Pink" = 10, + "Brown" = 11, + "Maroon" = 12, + "Aqua" = 13, + "Turgoise" = 14, + "Purple" = 15, + "Rainbow" = 16, + "Atomic Tangerine" = 17, + "Neon Green" = 18, + "Cotton Candy" = 19, + "Plum" = 20, + "Shamrock" = 21, + "Indigo" = 22 + ) + wirenum = 12 + holdopen = 1 + autoclose = 1 + secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + + + command + name = "Airlock" + icon = 'Doorcom.dmi' + doortype = 1 + holdopen = 0 + + + security + name = "Airlock" + icon = 'Doorsec.dmi' + doortype = 2 + + + engineering + name = "Airlock" + icon = 'Dooreng.dmi' + doortype = 3 + + + medical + name = "Airlock" + icon = 'Doormed.dmi' + doortype = 4 + + + maintenance + name = "Maintenance Access" + icon = 'Doormaint.dmi' + doortype = 5 + + external + name = "External Airlock" + icon = 'Doorext.dmi' + doortype = 6 + + + glass + name = "Glass Airlock" + icon = 'Doorglass.dmi' + opacity = 0 + doortype = 7 + glass = 1 + + + glass_command + name = "Maintenance Hatch" + icon = 'Doorcomglass.dmi' + opacity = 0 + doortype = 14 + glass = 1 + + + glass_engineering + name = "Maintenance Hatch" + icon = 'Doorengglass.dmi' + opacity = 0 + doortype = 15 + glass = 1 + + + glass_security + name = "Maintenance Hatch" + icon = 'Doorsecglass.dmi' + opacity = 0 + doortype = 16 + glass = 1 + + + glass_medical + name = "Maintenance Hatch" + icon = 'doormedglass.dmi' + opacity = 0 + doortype = 17 + glass = 1 + + + centcom + name = "Airlock" + icon = 'Doorele.dmi' + opacity = 0 + doortype = 8 + + + vault + name = "Vault" + icon = 'vault.dmi' + opacity = 1 + doortype = 9 + + + glass_large + name = "Glass Airlock" + icon = 'Door2x1glassfull.dmi' + opacity = 0 + doortype = 10 + glass = 1 + + + freezer + name = "Freezer Airlock" + icon = 'Doorfreezer.dmi' + opacity = 1 + doortype = 11 + + + hatch + name = "Airtight Hatch" + icon = 'Doorhatchele.dmi' + opacity = 1 + doortype = 12 + + + maintenance_hatch + name = "Maintenance Hatch" + icon = 'Doorhatchmaint2.dmi' + opacity = 1 + doortype = 13 + + + New() + ..() + if (src.closeOtherId != null) + spawn (5) + for (var/obj/machinery/door/airlock/A in machines) + if (A.closeOtherId == src.closeOtherId && A != src) + src.closeOther = A + break + + + open() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + return 0 + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) + src.closeOther.close() + return ..() + + + close() + if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + return + ..() + use_power(50) + playsound(src.loc, 'airlock.ogg', 30, 1) + var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) + if(killthis) + killthis.ex_act(2)//Smashin windows + return + + + bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite + if (!istype(usr, /mob/living/silicon)) + 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) + user << "\red You feel a powerful shock course through your body!" + user.halloss += 10 + user.stunned += 10 + return + ..(user) + + + update_icon() + if(overlays) overlays = null + if(density) + if(locked && safetylight) + icon_state = "door_locked" + else + icon_state = "door_closed" + if(p_open || welded) + overlays = list() + if(p_open) + overlays += image(icon, "panel_open") + if(welded) + overlays += image(icon, "welded") + else + icon_state = "door_open" + return + + + animate(animation) + switch(animation) + if("opening") + if(overlays) overlays = null + if(p_open) + icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking + else + flick("door_opening", src) + if("closing") + if(overlays) overlays = null + if(p_open) + flick("o_door_closing", src) + else + flick("door_closing", src) + if("spark") + flick("door_spark", src) + if("deny") + flick("door_deny", src) + return + + requiresID() + return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/weapon/screwdriver)) + src.p_open = !( src.p_open ) + src.update_icon() + else if (istype(C, /obj/item/weapon/wirecutters)) + 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/hacktool)) + return src.attack_ai(user, C) + 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) + var/beingcrowbarred = null + if(istype(C, /obj/item/weapon/crowbar) ) + beingcrowbarred = 1 //derp, Agouri + else + beingcrowbarred = 0 + if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) + playsound(src.loc, 'Crowbar.ogg', 100, 1) + user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") + if(do_after(user,40)) + user << "\blue You removed the airlock electronics!" + switch(src.doortype) + if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) + if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) + if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) + if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) + if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) + if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) + if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) + if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) + var/obj/item/weapon/airlock_electronics/ae + if (!electronics) + ae = new/obj/item/weapon/airlock_electronics( src.loc ) + ae.conf_access = src.req_access + else + ae = electronics + electronics = null + ae.loc = src.loc + + del(src) + return + else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) + user << "\blue The airlock's motors resist your efforts to pry it open." + else if (src.locked) + user << "\blue The airlock's bolts prevent it from being pried open." + if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) + + if(beingcrowbarred == 0) //being fireaxe'd + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + user << "\red You need to be wielding the Fire axe to do that." + return + else + spawn( 0 ) + src.operating = 1 + animate("opening") + + sleep(15) + + layer = 2.7 + src.density = 0 + update_icon() + + if (!istype(src, /obj/machinery/door/airlock/glass)) + src.sd_SetOpacity(0) + src.operating = 0 + return + + else + if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) + if(beingcrowbarred == 0) + var/obj/item/weapon/fireaxe/F = C + if(F.wielded == 1) + spawn( 0 ) + src.operating = 1 + animate("closing") + + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + else + user << "\red You need to be wielding the Fire axe to do that." + else + spawn( 0 ) + src.operating = 1 + animate("closing") + layer = 3.1 + src.density = 1 + sleep(15) + update_icon() + + if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) + src.sd_SetOpacity(1) + src.operating = 0 + + else + ..() + return + + + attack_paw(mob/user as mob) + return src.attack_hand(user) + + + attack_hand(mob/user as mob) + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 100)) + return + + if (ishuman(user) && prob(40) && src.density) + var/mob/living/carbon/human/H = user + if(H.getBrainLoss() >= 60) + playsound(src.loc, 'bang.ogg', 25, 1) + if(!istype(H.head, /obj/item/clothing/head/helmet)) + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock." + var/datum/organ/external/affecting = H.get_organ("head") + affecting.take_damage(10, 0) + H.Stun(8) + H.Weaken(5) + H.UpdateDamageIcon() + else + for(var/mob/M in viewers(src, null)) + M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." + return + + if (src.p_open) + user.machine = src + var/t1 = text("Access Panel
\n") + + //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) + t1 += getAirlockWires() + + t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) + + t1 += text("

Close

\n", src) + + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + else + ..(user) + return + +//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 engage engineer smasher, 9 enable bolt indicator, 10 wait for clearance +//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 disable engineer smasher, 9 disable bolt indicator, 10 autoclose + //This has been converted to be called by either the AI or a mob with a hacktool, permitting either to directly operate the airlock + attack_ai(mob/user as mob, obj/item/device/hacktool/C) + if(isAI(user)) + if (!src.canAIControl()) + if (src.canAIHack()) + src.hack(user) + return + else if(user) + if(!C) + return + if(C.in_use) + user << "We are already hacking another airlock." + return + if (!src.canSynControl() && src.canSynHack(C)) + src.synhack(user, C) + return + if(istype(C, /obj/item/device/hacktool/engineer)) + return + else + world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" + return + + + //Separate interface for the AI. + user.machine = src + var/t1 = text("Airlock Control
\n") + if (src.secondsMainPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) + else + t1 += text("Main power is offline indefinitely.
\n") + else + t1 += text("Main power is online.") + + if (src.secondsBackupPowerLost > 0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) + else + t1 += text("Backup power is offline indefinitely.
\n") + else if (src.secondsMainPowerLost > 0) + t1 += text("Backup power is online.") + else + t1 += text("Backup power is offline, but will turn on if main power fails.") + t1 += "
\n" + + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + t1 += text("IdScan wire is cut.
\n") + else if (src.aiDisabledIdScanner) + t1 += text("IdScan disabled. Enable?
\n", src) + else + t1 += text("IdScan enabled. Disable?
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) + t1 += text("Main Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) + t1 += text("Main Power Output wire is cut.
\n") + if (src.secondsMainPowerLost == 0) + t1 += text("Temporarily disrupt main power?.
\n", src) + if (src.secondsBackupPowerLost == 0) + t1 += text("Temporarily disrupt backup power?.
\n", src) + + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) + t1 += text("Backup Power Input wire is cut.
\n") + if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) + t1 += text("Backup Power Output wire is cut.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) + t1 += text("Airlock extra force wire is cut.
\n") + else if(!src.forcecrush) + t1 += text("Airlock extra force disabled Enable it?
\n") + else + t1 += text("Airlock extra force enabled Disable it?
\n") + + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + t1 += text("Door bolt drop wire is cut.
\n") + else if (!src.locked) + t1 += text("Door bolts are up. Drop them?
\n", src) + else + t1 += text("Door bolts are down.") + if (src.arePowerSystemsOn()) + t1 += text(" Raise?
\n", src) + else + t1 += text(" Cannot raise door bolts due to power failure.
\n") + + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + t1 += text("Electrification wire is cut.
\n") + if (src.secondsElectrified==-1) + t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) + else if (src.secondsElectrified>0) + t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) + else + t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) + + if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) + t1 += "Bolt indication light wire is cut.
\n" + else if(!src.safetylight) + t1 += text("Bolt Indication light is disabled Enable it?
\n") + else + t1 += text("Bolt Indication light is enabled Disable it?
\n") + + if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) + t1 += "Behavior Control light wire is cut.
\n" + else if(!src.holdopen) + t1 += text("Door behavior is set to: Automatically close Toggle?
\n") + else + t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") + + if (src.welded) + t1 += text("Door appears to have been welded shut.
\n") + else if (!src.locked) + if (src.density) + t1 += text("Open door
\n", src) + else + t1 += text("Close door
\n", src) + + t1 += text("

Close

\n", src) + user << browse(t1, "window=airlock") + onclose(user, "airlock") + + + proc + hack(mob/user as mob) + if (src.aiHacking==0) + src.aiHacking=1 + spawn(20) + //TODO: Make this take a minute + user << "Airlock AI control has been blocked. Beginning fault-detection." + sleep(50) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Fault confirmed: airlock control wire disabled or cut." + sleep(20) + user << "Attempting to hack into airlock. This may take some time." + sleep(200) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(170) + if (src.canAIControl()) + user << "Alert cancelled. Airlock control has been restored without our assistance." + src.aiHacking=0 + return + else if (!src.canAIHack()) + user << "We've lost our connection! Unable to hack airlock." + src.aiHacking=0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(50) + //disable blocked control + src.aiControlDisabled = 2 + user << "Receiving control information from airlock." + sleep(10) + //bring up airlock dialog + src.aiHacking = 0 + src.attack_ai(user) + + + synhack(mob/user as mob, obj/item/device/hacktool/I) + if (src.synHacking==0) + var/multiplier = 1 + if(istype(C, /obj/item/device/hacktool/engineer)) + if(!src.locked) + user << "The door bolts are already up!" + return + multiplier++ + src.synHacking=1 + I.in_use = 1 + user << "You begin hacking..." + spawn(20*multiplier) + user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." + sleep(25*multiplier) + if (src.canSynControl()) + user << "Hack cancelled, control already possible." + src.synHacking=0 + I.in_use = 0 + return + else if (!src.canSynHack(I)) + user << "\red Connection lost. Stand still and stay near the airlock!" + src.synHacking=0 + I.in_use = 0 + return + user << "Connection established." + sleep(10*multiplier) + user << "Attempting to hack into airlock. This may take some time." + sleep(50*multiplier) + + // Alerting the AIs + var/list/cameras = list() + for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area + cameras += C + var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability + if(alertoption) + if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) + alertoption = 3 + else if (prob(18)) //18% chance of sending the AI just the area + alertoption = 2 + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + switch(alertoption) + if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) + if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + switch(alertoption) + if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") + // ...And done + + if (!src.canSynHack(I)) + user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Local override already in place, hack aborted." + src.synHacking=0 + I.in_use = 0 + return + user << "Upload access confirmed. Loading control program into airlock software." + sleep(35*multiplier) + if (!src.canSynHack(I)) + user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." + src.synHacking=0 + I.in_use = 0 + return + else if (src.canSynControl()) + user << "Upload access aborted, local override already in place." + src.synHacking=0 + I.in_use = 0 + return + user << "Transfer complete. Forcing airlock to execute program." + sleep(25*multiplier) + //disable blocked control + if(istype(C, /obj/item/device/hacktool/engineer)) + user << "Raising door bolts..." + src.locked = 0 + update_icon() + return + src.synDoorHacked = 1 + user << "Bingo! We're in. Airlock control panel coming right up." + sleep(5) + //bring up airlock dialog + src.synHacking = 0 + I.in_use = 0 + src.attack_ai(user, I) + + + canAIControl() + return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); + + + canAIHack() + return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); + + + canSynControl() + return (src.synDoorHacked && (!src.isAllPowerCut())); + + + canSynHack(obj/item/device/hacktool/H) + return (in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()); + + + +/* +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 \red 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) +*/ + + pulse(var/wireColor) + //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function + var/wireIndex = airlockWireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + + cut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + + mend(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 + + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & airlockWireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 + + isElectrified() + return (src.secondsElectrified != 0); + + isWireColorCut(var/wireColor) + var/wireFlag = airlockWireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + + isWireCut(var/wireIndex) + var/wireFlag = airlockIndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + arePowerSystemsOn() + return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) + + isAllPowerCut() + return ((src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) && (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + + regainMainPower() + if (src.secondsMainPowerLost > 0) + src.secondsMainPowerLost = 0 + + loseMainPower() + if (src.secondsMainPowerLost <= 0) + src.secondsMainPowerLost = 60 + if (src.secondsBackupPowerLost < 10) + src.secondsBackupPowerLost = 10 + if (!src.spawnPowerRestoreRunning) + src.spawnPowerRestoreRunning = 1 + spawn(0) + var/cont = 1 + while (cont) + sleep(10) + cont = 0 + if (src.secondsMainPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.secondsMainPowerLost -= 1 + src.updateDialog() + cont = 1 + + if (src.secondsBackupPowerLost>0) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.secondsBackupPowerLost -= 1 + src.updateDialog() + cont = 1 + src.spawnPowerRestoreRunning = 0 + src.updateDialog() + + loseBackupPower() + if (src.secondsBackupPowerLost < 60) + src.secondsBackupPowerLost = 60 + + regainBackupPower() + if (src.secondsBackupPowerLost > 0) + src.secondsBackupPowerLost = 0 + + // 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 + shock(mob/user, prb) + if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 //you lucked out, no shock for you + if(istype(usr.equipped(),/obj/item/weapon/shard)) + return 0 + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src)) + return 1 + else + return 0 + + prison_open() + src.locked = 0 + src.open() + src.locked = 1 + return + + + +/obj/machinery/door/airlock/Topic(href, href_list) + ..() + if (usr.stat || usr.restrained() ) + return + if (href_list["close"]) + usr << browse(null, "window=airlock") + if (usr.machine==src) + usr.machine = null + return + if(in_range(src, usr) && istype(src.loc, /turf) && p_open) + usr.machine = src + if (href_list["wires"]) + var/t1 = text2num(href_list["wires"]) + if (!(istype(usr.equipped(), /obj/item/weapon/wirecutters) || istype(usr.equipped(),/obj/item/weapon/shard))) + usr << "You need wirecutters!" + return + if (src.isWireColorCut(t1) && istype(usr.equipped(), /obj/item/weapon/wirecutters)) + src.mend(t1) + else + src.cut(t1) + else if (href_list["pulse"]) + var/t1 = text2num(href_list["pulse"]) + if (!istype(usr.equipped(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return + if (src.isWireColorCut(t1)) + usr << "You can't pulse a cut wire." + return + else + src.pulse(t1) + else if(href_list["signaler"]) + var/wirenum = text2num(href_list["signaler"]) + if(!istype(usr.equipped(), /obj/item/device/assembly/signaler)) + usr << "You need a signaller!" + return + if(src.isWireColorCut(wirenum)) + usr << "You can't attach a signaller to a cut wire." + return + var/obj/item/device/assembly/signaler/R = usr.equipped() + if(R.secured) + usr << "This radio can't be attached!" + return + var/mob/M = usr + M.drop_item() + R.loc = src + R.airlock_wire = wirenum + src.signalers[wirenum] = R + else if(href_list["remove-signaler"]) + var/wirenum = text2num(href_list["remove-signaler"]) + if(!(src.signalers[wirenum])) + usr << "There's no signaller attached to that wire!" + return + var/obj/item/device/assembly/signaler/R = src.signalers[wirenum] + R.loc = usr.loc + R.airlock_wire = null + src.signalers[wirenum] = null + + src.update_icon() + add_fingerprint(usr) + src.updateUsrDialog() + else //AI or Syndicate using hacktool + if (!src.canAIControl() || (istype(usr.equipped(), /obj/item/device/hacktool/) && (!src.canSynControl() || !in_range(src, usr)))) + usr << "Airlock control connection lost!" + return + //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door + //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door + if (href_list["aiDisable"]) + var/code = text2num(href_list["aiDisable"]) + switch (code) + if (1) + //disable idscan + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + usr << "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways." + else if (src.aiDisabledIdScanner) + usr << "You've already disabled the IdScan feature." + else + src.aiDisabledIdScanner = 1 + if (2) + //disrupt main power + if (src.secondsMainPowerLost == 0) + src.loseMainPower() + else + usr << "Main power is already offline." + if (3) + //disrupt backup power + if (src.secondsBackupPowerLost == 0) + src.loseBackupPower() + else + usr << "Backup power is already offline." + if (4) + //drop door bolts + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + usr << "You can't drop the door bolts - The door bolt dropping wire has been cut." + else if (src.locked!=1) + src.locked = 1 + update_icon() + if (5) + //un-electrify door + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("Can't un-electrify the airlock - The electrification wire is cut.
\n") + else if (src.secondsElectrified==-1) + src.secondsElectrified = 0 + else if (src.secondsElectrified>0) + src.secondsElectrified = 0 + if (7) + //close door + if (src.welded) + usr << text("The airlock has been welded shut!
\n") + else if (src.locked) + usr << text("The door bolts are down!
\n") + else if (!src.density) + close() + else + usr << text("The airlock is already closed.
\n") + if (8) + if(!src.forcecrush) + usr << text("Door extra force not enabled!
\n") + else + src.forcecrush = 0 + if (9) + if(!src.safetylight) + usr << text("Bolt indication light not enabled!
\n") + else + src.safetylight = 0 + if (10) + if(!src.holdopen) + usr << text("Door Behavior already set to: Wait for clearance to close
\n") + else + src.holdopen = 0 + + else if (href_list["aiEnable"]) + var/code = text2num(href_list["aiEnable"]) + switch (code) + if (1) + //enable idscan + if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + usr << "You can't enable IdScan - The IdScan wire has been cut." + else if (src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 0 + else + usr << "The IdScan feature is not disabled." + if (4) + //raise door bolts + if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + usr << text("The door bolt drop wire is cut - you can't raise the door bolts.
\n") + else if (!src.locked) + usr << text("The door bolts are already up.
\n") + else + if (src.arePowerSystemsOn()) + src.locked = 0 + update_icon() + else + usr << text("Cannot raise door bolts due to power failure.
\n") + + if (5) + //electrify door for 30 seconds + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("The electrification wire has been cut.
\n") + else if (src.secondsElectrified==-1) + usr << text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
\n") + else if (src.secondsElectrified!=0) + usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") + else + src.secondsElectrified = 30 + spawn(10) + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + src.updateUsrDialog() + sleep(10) + if (6) + //electrify door indefinitely + if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) + usr << text("The electrification wire has been cut.
\n") + else if (src.secondsElectrified==-1) + usr << text("The door is already indefinitely electrified.
\n") + else if (src.secondsElectrified!=0) + usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") + else + src.secondsElectrified = -1 + if (7) + //open door + if (src.welded) + usr << text("The airlock has been welded shut!
\n") + else if (src.locked) + usr << text("The door bolts are down!
\n") + else if (src.density) + open() + // close() + else + usr << text("The airlock is already opened.
\n") + if (8) + if(src.forcecrush) + usr << text("Door extra force already enabled!
\n") + else + src.forcecrush = 1 + if (9) + if(src.safetylight) + usr << text("Bolt indication light already enabled!
\n") + else + src.safetylight = 1 + if (10) + if(src.holdopen) + usr << text("Door Behavior already set to: Automatically close
\n") + else + src.holdopen = 1 + + src.update_icon() + src.updateUsrDialog() + if((istype(usr.equipped(), /obj/item/device/hacktool))) + return attack_ai(usr, usr.equipped()) + return + + + + +/obj/machinery/door/airlock/secure + name = "Secure Airlock" + desc = "Good lord, at least they left out the overcomplicated death traps. Looks to be a layer of armor plate you might be able to remove with a wrench." + icon = 'Doorhatchele.dmi' + + wires = 65535 + wirenum = 16 + alert_probability = 20 + holdopen = 0 + signalers = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var + list/WireColorToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + is_detached = 0 + + + + New() + ..() + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/flagIndex = 1 + for (var/flag=1, flag<65536, flag+=flag) + var/valid = 0 + while (!valid) + var/colorIndex = rand(1, 16) + if (WireColorToFlag[colorIndex] == 0) + valid = 1 + WireColorToFlag[colorIndex] = flag + IndexToFlag[flagIndex] = flag + IndexToWireColor[flagIndex] = colorIndex + WireColorToIndex[colorIndex] = flagIndex + flagIndex+=1 + return + + + isWireColorCut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + return ((src.wires & wireFlag) == 0) + + isWireCut(var/wireIndex) + var/wireFlag = IndexToFlag[wireIndex] + return ((src.wires & wireFlag) == 0) + + pulse(var/wireColor) + var/wireIndex = WireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 + // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + cut(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + mend(var/wireColor) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] //not used in this function + wires |= wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) + src.regainMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) + src.regainBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + if (src.secondsElectrified == -1) + src.secondsElectrified = 0 + + getAirlockWires() + var/t1 + var/iterator = 0 + for(var/wiredesc in wire_index) + if(iterator == wirenum) + break + var/is_uncut = src.wires & WireColorToFlag[wire_index[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + if(src.signalers[wire_index[wiredesc]]) + t1 += "Detach signaler" + else + t1 += "Attach signaler" + t1 += "
" + iterator++ + return t1 + + attackby(C as obj, mob/user as mob) + //world << text("airlock attackby src [] obj [] mob []", src, C, user) + if(istype(C, /obj/item/device/detective_scanner)) + return + if(!src.is_detached) + if (!istype(usr, /mob/living/silicon)) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + + src.add_fingerprint(user) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else + return + else if (istype(C, /obj/item/device/hacktool)) + return src.attack_ai(user, C) + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start to remove the armor plate..." + if(do_after(user,30)) + user << "Armor plates removed" + src.is_detached = 1 + else + if (istype(C, /obj/item/weapon/wrench)) + user << "You start to reattach the armor plate..." + if(do_after(user,30)) + user << "Armor plates attached" + src.is_detached = 0 + else + return ..(C, user) + if (src.isElectrified()) + if(src.shock(user, 75)) + return + src.add_fingerprint(user) if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) var/obj/item/weapon/weldingtool/W = C From 6f149af6ba3a85137319581995bc376186822be7 Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 13:48:34 -0700 Subject: [PATCH 4/7] *sigh* Lets hope that worked. --- code/game/machinery/doors/airlock.dm | 3034 -------------------------- 1 file changed, 3034 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index b56589fcbc0..1cb1a6ca9a3 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1479,1492 +1479,6 @@ About the new airlock wires panel: iterator++ return t1 - attackby(C as obj, mob/user as mob) - //world << text("airlock attackby src [] obj [] mob []", src, C, user) - if(istype(C, /obj/item/device/detective_scanner)) - return - if(!src.is_detached) - if (!istype(usr, /mob/living/silicon))#define AIRLOCK_WIRE_IDSCAN 1 -#define AIRLOCK_WIRE_MAIN_POWER1 2 -#define AIRLOCK_WIRE_MAIN_POWER2 3 -#define AIRLOCK_WIRE_DOOR_BOLTS 4 -#define AIRLOCK_WIRE_BACKUP_POWER1 5 -#define AIRLOCK_WIRE_BACKUP_POWER2 6 -#define AIRLOCK_WIRE_OPEN_DOOR 7 -#define AIRLOCK_WIRE_AI_CONTROL 8 -#define AIRLOCK_WIRE_ELECTRIFY 9 -#define AIRLOCK_WIRE_CRUSH 10 -#define AIRLOCK_WIRE_LIGHT 11 -#define AIRLOCK_WIRE_HOLDOPEN 12 -#define AIRLOCK_WIRE_FAKEBOLT1 13 -#define AIRLOCK_WIRE_FAKEBOLT2 14 -#define AIRLOCK_WIRE_ALERTAI 15 -#define AIRLOCK_WIRE_DOOR_BOLTS_2 16 -//#define AIRLOCK_WIRE_FINGERPRINT 17 - -/* - New methods: - pulse - sends a pulse into a wire for hacking purposes - cut - cuts a wire and makes any necessary state changes - mend - mends a wire and makes any necessary state changes - isWireColorCut - returns 1 if that color wire is cut, or 0 if not - isWireCut - returns 1 if that wire (e.g. AIRLOCK_WIRE_DOOR_BOLTS) is cut, or 0 if not - canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in) - canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it. - arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that) - requiresIDs - 1 if the airlock is requiring IDs, 0 if not - isAllPowerCut - 1 if the main and backup power both have cut wires. - regainMainPower - handles the effect of main power coming back on. - loseMainPower - handles the effect of main power going offline. Usually (if one isn't already running) spawn a thread to count down how long it will be offline - counting down won't happen if main power was completely cut along with backup power, though, the thread will just sleep. - loseBackupPower - handles the effect of backup power going offline. - regainBackupPower - handles the effect of main power coming back on. - shock - has a chance of electrocuting its target. -*/ - -//This generates the randomized airlock wire assignments for the game. -/proc/RandomAirlockWires() - //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/flagIndex = 1 - for (var/flag=1, flag<4096, flag+=flag) - var/valid = 0 - while (!valid) - var/colorIndex = rand(1, 12) - if (wires[colorIndex] == 0) - valid = 1 - wires[colorIndex] = flag - airlockIndexToFlag[flagIndex] = flag - airlockIndexToWireColor[flagIndex] = colorIndex - airlockWireColorToIndex[colorIndex] = flagIndex - flagIndex+=1 - return wires - -/* Example: -Airlock wires color -> flag are { 64, 128, 256, 2, 16, 4, 8, 32, 1 }. -Airlock wires color -> index are { 7, 8, 9, 2, 5, 3, 4, 6, 1 }. -Airlock index -> flag are { 1, 2, 4, 8, 16, 32, 64, 128, 256 }. -Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. -*/ - -/obj/machinery/door/airlock - name = "Airlock" - icon = 'doorint.dmi' - icon_state = "door_closed" - - 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. - synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no - synHacking = 0 // Is hack in process y/n? - secondsMainPowerLost = 0 //The number of seconds until power is restored. - secondsBackupPowerLost = 0 //The number of seconds until power is restored. - spawnPowerRestoreRunning = 0 - welded = null - locked = 0 - wires = 4095 - aiDisabledIdScanner = 0 - aiHacking = 0 - obj/machinery/door/airlock/closeOther = null - closeOtherId = null - list/signalers[12] - lockdownbyai = 0 - doortype = 0 - justzap = 0 - safetylight = 1 - obj/item/weapon/airlock_electronics/electronics = null - alert_probability = 3 - list/wire_index = list( - "Orange" = 1, - "Dark red" = 2, - "White" = 3, - "Yellow" = 4, - "Red" = 5, - "Blue" = 6, - "Green" = 7, - "Grey" = 8, - "Black" = 9, - "Pink" = 10, - "Brown" = 11, - "Maroon" = 12, - "Aqua" = 13, - "Turgoise" = 14, - "Purple" = 15, - "Rainbow" = 16, - "Atomic Tangerine" = 17, - "Neon Green" = 18, - "Cotton Candy" = 19, - "Plum" = 20, - "Shamrock" = 21, - "Indigo" = 22 - ) - wirenum = 12 - holdopen = 1 - autoclose = 1 - secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. - - - command - name = "Airlock" - icon = 'Doorcom.dmi' - doortype = 1 - holdopen = 0 - - - security - name = "Airlock" - icon = 'Doorsec.dmi' - doortype = 2 - - - engineering - name = "Airlock" - icon = 'Dooreng.dmi' - doortype = 3 - - - medical - name = "Airlock" - icon = 'Doormed.dmi' - doortype = 4 - - - maintenance - name = "Maintenance Access" - icon = 'Doormaint.dmi' - doortype = 5 - - external - name = "External Airlock" - icon = 'Doorext.dmi' - doortype = 6 - - - glass - name = "Glass Airlock" - icon = 'Doorglass.dmi' - opacity = 0 - doortype = 7 - glass = 1 - - - glass_command - name = "Maintenance Hatch" - icon = 'Doorcomglass.dmi' - opacity = 0 - doortype = 14 - glass = 1 - - - glass_engineering - name = "Maintenance Hatch" - icon = 'Doorengglass.dmi' - opacity = 0 - doortype = 15 - glass = 1 - - - glass_security - name = "Maintenance Hatch" - icon = 'Doorsecglass.dmi' - opacity = 0 - doortype = 16 - glass = 1 - - - glass_medical - name = "Maintenance Hatch" - icon = 'doormedglass.dmi' - opacity = 0 - doortype = 17 - glass = 1 - - - centcom - name = "Airlock" - icon = 'Doorele.dmi' - opacity = 0 - doortype = 8 - - - vault - name = "Vault" - icon = 'vault.dmi' - opacity = 1 - doortype = 9 - - - glass_large - name = "Glass Airlock" - icon = 'Door2x1glassfull.dmi' - opacity = 0 - doortype = 10 - glass = 1 - - - freezer - name = "Freezer Airlock" - icon = 'Doorfreezer.dmi' - opacity = 1 - doortype = 11 - - - hatch - name = "Airtight Hatch" - icon = 'Doorhatchele.dmi' - opacity = 1 - doortype = 12 - - - maintenance_hatch - name = "Maintenance Hatch" - icon = 'Doorhatchmaint2.dmi' - opacity = 1 - doortype = 13 - - - New() - ..() - if (src.closeOtherId != null) - spawn (5) - for (var/obj/machinery/door/airlock/A in machines) - if (A.closeOtherId == src.closeOtherId && A != src) - src.closeOther = A - break - - - open() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) - return 0 - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) - src.closeOther.close() - return ..() - - - close() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - return - ..() - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) - if(killthis) - killthis.ex_act(2)//Smashin windows - return - - - bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if (!istype(usr, /mob/living/silicon)) - 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) - user << "\red You feel a powerful shock course through your body!" - user.halloss += 10 - user.stunned += 10 - return - ..(user) - - - update_icon() - if(overlays) overlays = null - if(density) - if(locked && safetylight) - icon_state = "door_locked" - else - icon_state = "door_closed" - if(p_open || welded) - overlays = list() - if(p_open) - overlays += image(icon, "panel_open") - if(welded) - overlays += image(icon, "welded") - else - icon_state = "door_open" - return - - - animate(animation) - switch(animation) - if("opening") - if(overlays) overlays = null - if(p_open) - icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking - else - flick("door_opening", src) - if("closing") - if(overlays) overlays = null - if(p_open) - flick("o_door_closing", src) - else - flick("door_closing", src) - if("spark") - flick("door_spark", src) - if("deny") - flick("door_deny", src) - return - - requiresID() - return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) - - attackby(C as obj, mob/user as mob) - //world << text("airlock attackby src [] obj [] mob []", src, C, user) - if(istype(C, /obj/item/device/detective_scanner)) - return - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 75)) - return - - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/weapon/screwdriver)) - src.p_open = !( src.p_open ) - src.update_icon() - else if (istype(C, /obj/item/weapon/wirecutters)) - 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/hacktool)) - return src.attack_ai(user, C) - 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) - var/beingcrowbarred = null - if(istype(C, /obj/item/weapon/crowbar) ) - beingcrowbarred = 1 //derp, Agouri - else - beingcrowbarred = 0 - if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) - playsound(src.loc, 'Crowbar.ogg', 100, 1) - user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") - if(do_after(user,40)) - user << "\blue You removed the airlock electronics!" - switch(src.doortype) - if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) - if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) - if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) - if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) - if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) - if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) - if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) - if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) - var/obj/item/weapon/airlock_electronics/ae - if (!electronics) - ae = new/obj/item/weapon/airlock_electronics( src.loc ) - ae.conf_access = src.req_access - else - ae = electronics - electronics = null - ae.loc = src.loc - - del(src) - return - else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) - user << "\blue The airlock's motors resist your efforts to pry it open." - else if (src.locked) - user << "\blue The airlock's bolts prevent it from being pried open." - if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) - - if(beingcrowbarred == 0) //being fireaxe'd - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("opening") - - sleep(15) - - layer = 2.7 - src.density = 0 - update_icon() - - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - user << "\red You need to be wielding the Fire axe to do that." - return - else - spawn( 0 ) - src.operating = 1 - animate("opening") - - sleep(15) - - layer = 2.7 - src.density = 0 - update_icon() - - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - - else - if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) - if(beingcrowbarred == 0) - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("closing") - - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - else - user << "\red You need to be wielding the Fire axe to do that." - else - spawn( 0 ) - src.operating = 1 - animate("closing") - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - - else - ..() - return - - - attack_paw(mob/user as mob) - return src.attack_hand(user) - - - attack_hand(mob/user as mob) - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 100)) - return - - if (ishuman(user) && prob(40) && src.density) - var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= 60) - playsound(src.loc, 'bang.ogg', 25, 1) - if(!istype(H.head, /obj/item/clothing/head/helmet)) - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock." - var/datum/organ/external/affecting = H.get_organ("head") - affecting.take_damage(10, 0) - H.Stun(8) - H.Weaken(5) - H.UpdateDamageIcon() - else - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." - return - - if (src.p_open) - user.machine = src - var/t1 = text("Access Panel
\n") - - //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) - t1 += getAirlockWires() - - t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) - - t1 += text("

Close

\n", src) - - user << browse(t1, "window=airlock") - onclose(user, "airlock") - - else - ..(user) - return - -//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 engage engineer smasher, 9 enable bolt indicator, 10 wait for clearance -//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 disable engineer smasher, 9 disable bolt indicator, 10 autoclose - //This has been converted to be called by either the AI or a mob with a hacktool, permitting either to directly operate the airlock - attack_ai(mob/user as mob, obj/item/device/hacktool/C) - if(isAI(user)) - if (!src.canAIControl()) - if (src.canAIHack()) - src.hack(user) - return - else if(user) - if(!C) - return - if(C.in_use) - user << "We are already hacking another airlock." - return - if (!src.canSynControl() && src.canSynHack(C)) - src.synhack(user, C) - return - if(istype(C, /obj/item/device/hacktool/engineer)) - return - else - world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" - return - - - //Separate interface for the AI. - user.machine = src - var/t1 = text("Airlock Control
\n") - if (src.secondsMainPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) - else - t1 += text("Main power is offline indefinitely.
\n") - else - t1 += text("Main power is online.") - - if (src.secondsBackupPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) - else - t1 += text("Backup power is offline indefinitely.
\n") - else if (src.secondsMainPowerLost > 0) - t1 += text("Backup power is online.") - else - t1 += text("Backup power is offline, but will turn on if main power fails.") - t1 += "
\n" - - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - t1 += text("IdScan wire is cut.
\n") - else if (src.aiDisabledIdScanner) - t1 += text("IdScan disabled. Enable?
\n", src) - else - t1 += text("IdScan enabled. Disable?
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) - t1 += text("Main Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - t1 += text("Main Power Output wire is cut.
\n") - if (src.secondsMainPowerLost == 0) - t1 += text("Temporarily disrupt main power?.
\n", src) - if (src.secondsBackupPowerLost == 0) - t1 += text("Temporarily disrupt backup power?.
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) - t1 += text("Backup Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - t1 += text("Backup Power Output wire is cut.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) - t1 += text("Airlock extra force wire is cut.
\n") - else if(!src.forcecrush) - t1 += text("Airlock extra force disabled Enable it?
\n") - else - t1 += text("Airlock extra force enabled Disable it?
\n") - - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - t1 += text("Door bolt drop wire is cut.
\n") - else if (!src.locked) - t1 += text("Door bolts are up. Drop them?
\n", src) - else - t1 += text("Door bolts are down.") - if (src.arePowerSystemsOn()) - t1 += text(" Raise?
\n", src) - else - t1 += text(" Cannot raise door bolts due to power failure.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - t1 += text("Electrification wire is cut.
\n") - if (src.secondsElectrified==-1) - t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) - else if (src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) - else - t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) - - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - t1 += "Bolt indication light wire is cut.
\n" - else if(!src.safetylight) - t1 += text("Bolt Indication light is disabled Enable it?
\n") - else - t1 += text("Bolt Indication light is enabled Disable it?
\n") - - if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) - t1 += "Behavior Control light wire is cut.
\n" - else if(!src.holdopen) - t1 += text("Door behavior is set to: Automatically close Toggle?
\n") - else - t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") - - if (src.welded) - t1 += text("Door appears to have been welded shut.
\n") - else if (!src.locked) - if (src.density) - t1 += text("Open door
\n", src) - else - t1 += text("Close door
\n", src) - - t1 += text("

Close

\n", src) - user << browse(t1, "window=airlock") - onclose(user, "airlock") - - - proc - hack(mob/user as mob) - if (src.aiHacking==0) - src.aiHacking=1 - spawn(20) - //TODO: Make this take a minute - user << "Airlock AI control has been blocked. Beginning fault-detection." - sleep(50) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Fault confirmed: airlock control wire disabled or cut." - sleep(20) - user << "Attempting to hack into airlock. This may take some time." - sleep(200) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(170) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(50) - //disable blocked control - src.aiControlDisabled = 2 - user << "Receiving control information from airlock." - sleep(10) - //bring up airlock dialog - src.aiHacking = 0 - src.attack_ai(user) - - - synhack(mob/user as mob, obj/item/device/hacktool/I) - if (src.synHacking==0) - var/multiplier = 1 - if(istype(C, /obj/item/device/hacktool/engineer)) - if(!src.locked) - user << "The door bolts are already up!" - return - multiplier++ - src.synHacking=1 - I.in_use = 1 - user << "You begin hacking..." - spawn(20*multiplier) - user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." - sleep(25*multiplier) - if (src.canSynControl()) - user << "Hack cancelled, control already possible." - src.synHacking=0 - I.in_use = 0 - return - else if (!src.canSynHack(I)) - user << "\red Connection lost. Stand still and stay near the airlock!" - src.synHacking=0 - I.in_use = 0 - return - user << "Connection established." - sleep(10*multiplier) - user << "Attempting to hack into airlock. This may take some time." - sleep(50*multiplier) - - // Alerting the AIs - var/list/cameras = list() - for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area - cameras += C - var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability - if(alertoption) - if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) - alertoption = 3 - else if (prob(18)) //18% chance of sending the AI just the area - alertoption = 2 - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - switch(alertoption) - if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) - if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - switch(alertoption) - if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") - // ...And done - - if (!src.canSynHack(I)) - user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Local override already in place, hack aborted." - src.synHacking=0 - I.in_use = 0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(35*multiplier) - if (!src.canSynHack(I)) - user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Upload access aborted, local override already in place." - src.synHacking=0 - I.in_use = 0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(25*multiplier) - //disable blocked control - if(istype(C, /obj/item/device/hacktool/engineer)) - user << "Raising door bolts..." - src.locked = 0 - update_icon() - return - src.synDoorHacked = 1 - user << "Bingo! We're in. Airlock control panel coming right up." - sleep(5) - //bring up airlock dialog - src.synHacking = 0 - I.in_use = 0 - src.attack_ai(user, I) - - - canAIControl() - return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); - - - canAIHack() - return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); - - - canSynControl() - return (src.synDoorHacked && (!src.isAllPowerCut())); - - - canSynHack(obj/item/device/hacktool/H) - return (in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()); - - - -/* -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 \red 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) -*/ - - pulse(var/wireColor) - //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function - var/wireIndex = airlockWireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - animate("deny") - if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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). - src.loseMainPower() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - else - if(src.arePowerSystemsOn()) //only can raise bolts if power's on - src.locked = 0 - usr << "You hear a click from inside the door." - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //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). - src.loseBackupPower() - if (AIRLOCK_WIRE_AI_CONTROL) - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if (src.secondsElectrified==0) - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if (!src.requiresID() || src.check_access(null)) - if (src.density) - open() - else - close() - if(AIRLOCK_WIRE_CRUSH) - src.forcecrush = !src.forcecrush - if(AIRLOCK_WIRE_LIGHT) - src.safetylight = !src.safetylight - if(AIRLOCK_WIRE_HOLDOPEN) - src.holdopen = !src.holdopen - - cut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if (src.locked!=1) - src.locked = 1 - update_icon() - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if (src.secondsElectrified != -1) - src.secondsElectrified = -1 - - mend(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - if (src.secondsElectrified == -1) - src.secondsElectrified = 0 - - getAirlockWires() - var/t1 - var/iterator = 0 - for(var/wiredesc in wire_index) - if(iterator == wirenum) - break - var/is_uncut = src.wires & airlockWireColorToFlag[wire_index[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wire_index[wiredesc]]) - t1 += "Detach signaler" - else - t1 += "Attach signaler" - t1 += "
" - iterator++ - return t1 - - isElectrified() - return (src.secondsElectrified != 0); - - isWireColorCut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - - isWireCut(var/wireIndex) - var/wireFlag = airlockIndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - - arePowerSystemsOn() - return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) - - isAllPowerCut() - return ((src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) && (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - - regainMainPower() - if (src.secondsMainPowerLost > 0) - src.secondsMainPowerLost = 0 - - loseMainPower() - if (src.secondsMainPowerLost <= 0) - src.secondsMainPowerLost = 60 - if (src.secondsBackupPowerLost < 10) - src.secondsBackupPowerLost = 10 - if (!src.spawnPowerRestoreRunning) - src.spawnPowerRestoreRunning = 1 - spawn(0) - var/cont = 1 - while (cont) - sleep(10) - cont = 0 - if (src.secondsMainPowerLost>0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.secondsMainPowerLost -= 1 - src.updateDialog() - cont = 1 - - if (src.secondsBackupPowerLost>0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.secondsBackupPowerLost -= 1 - src.updateDialog() - cont = 1 - src.spawnPowerRestoreRunning = 0 - src.updateDialog() - - loseBackupPower() - if (src.secondsBackupPowerLost < 60) - src.secondsBackupPowerLost = 60 - - regainBackupPower() - if (src.secondsBackupPowerLost > 0) - src.secondsBackupPowerLost = 0 - - // 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 - shock(mob/user, prb) - if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 //you lucked out, no shock for you - if(istype(usr.equipped(),/obj/item/weapon/shard)) - return 0 - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() //sparks always. - if (electrocute_mob(user, get_area(src), src)) - return 1 - else - return 0 - - prison_open() - src.locked = 0 - src.open() - src.locked = 1 - return - - - -/obj/machinery/door/airlock/Topic(href, href_list) - ..() - if (usr.stat || usr.restrained() ) - return - if (href_list["close"]) - usr << browse(null, "window=airlock") - if (usr.machine==src) - usr.machine = null - return - if(in_range(src, usr) && istype(src.loc, /turf) && p_open) - usr.machine = src - if (href_list["wires"]) - var/t1 = text2num(href_list["wires"]) - if (!(istype(usr.equipped(), /obj/item/weapon/wirecutters) || istype(usr.equipped(),/obj/item/weapon/shard))) - usr << "You need wirecutters!" - return - if (src.isWireColorCut(t1) && istype(usr.equipped(), /obj/item/weapon/wirecutters)) - src.mend(t1) - else - src.cut(t1) - else if (href_list["pulse"]) - var/t1 = text2num(href_list["pulse"]) - if (!istype(usr.equipped(), /obj/item/device/multitool)) - usr << "You need a multitool!" - return - if (src.isWireColorCut(t1)) - usr << "You can't pulse a cut wire." - return - else - src.pulse(t1) - else if(href_list["signaler"]) - var/wirenum = text2num(href_list["signaler"]) - if(!istype(usr.equipped(), /obj/item/device/assembly/signaler)) - usr << "You need a signaller!" - return - if(src.isWireColorCut(wirenum)) - usr << "You can't attach a signaller to a cut wire." - return - var/obj/item/device/assembly/signaler/R = usr.equipped() - if(R.secured) - usr << "This radio can't be attached!" - return - var/mob/M = usr - M.drop_item() - R.loc = src - R.airlock_wire = wirenum - src.signalers[wirenum] = R - else if(href_list["remove-signaler"]) - var/wirenum = text2num(href_list["remove-signaler"]) - if(!(src.signalers[wirenum])) - usr << "There's no signaller attached to that wire!" - return - var/obj/item/device/assembly/signaler/R = src.signalers[wirenum] - R.loc = usr.loc - R.airlock_wire = null - src.signalers[wirenum] = null - - src.update_icon() - add_fingerprint(usr) - src.updateUsrDialog() - else //AI or Syndicate using hacktool - if (!src.canAIControl() || (istype(usr.equipped(), /obj/item/device/hacktool/) && (!src.canSynControl() || !in_range(src, usr)))) - usr << "Airlock control connection lost!" - return - //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door - //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door - if (href_list["aiDisable"]) - var/code = text2num(href_list["aiDisable"]) - switch (code) - if (1) - //disable idscan - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways." - else if (src.aiDisabledIdScanner) - usr << "You've already disabled the IdScan feature." - else - src.aiDisabledIdScanner = 1 - if (2) - //disrupt main power - if (src.secondsMainPowerLost == 0) - src.loseMainPower() - else - usr << "Main power is already offline." - if (3) - //disrupt backup power - if (src.secondsBackupPowerLost == 0) - src.loseBackupPower() - else - usr << "Backup power is already offline." - if (4) - //drop door bolts - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << "You can't drop the door bolts - The door bolt dropping wire has been cut." - else if (src.locked!=1) - src.locked = 1 - update_icon() - if (5) - //un-electrify door - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("Can't un-electrify the airlock - The electrification wire is cut.
\n") - else if (src.secondsElectrified==-1) - src.secondsElectrified = 0 - else if (src.secondsElectrified>0) - src.secondsElectrified = 0 - if (7) - //close door - if (src.welded) - usr << text("The airlock has been welded shut!
\n") - else if (src.locked) - usr << text("The door bolts are down!
\n") - else if (!src.density) - close() - else - usr << text("The airlock is already closed.
\n") - if (8) - if(!src.forcecrush) - usr << text("Door extra force not enabled!
\n") - else - src.forcecrush = 0 - if (9) - if(!src.safetylight) - usr << text("Bolt indication light not enabled!
\n") - else - src.safetylight = 0 - if (10) - if(!src.holdopen) - usr << text("Door Behavior already set to: Wait for clearance to close
\n") - else - src.holdopen = 0 - - else if (href_list["aiEnable"]) - var/code = text2num(href_list["aiEnable"]) - switch (code) - if (1) - //enable idscan - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "You can't enable IdScan - The IdScan wire has been cut." - else if (src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 0 - else - usr << "The IdScan feature is not disabled." - if (4) - //raise door bolts - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << text("The door bolt drop wire is cut - you can't raise the door bolts.
\n") - else if (!src.locked) - usr << text("The door bolts are already up.
\n") - else - if (src.arePowerSystemsOn()) - src.locked = 0 - update_icon() - else - usr << text("Cannot raise door bolts due to power failure.
\n") - - if (5) - //electrify door for 30 seconds - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
\n") - else if (src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
\n") - else if (src.secondsElectrified!=0) - usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") - else - src.secondsElectrified = 30 - spawn(10) - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - src.updateUsrDialog() - sleep(10) - if (6) - //electrify door indefinitely - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
\n") - else if (src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified.
\n") - else if (src.secondsElectrified!=0) - usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") - else - src.secondsElectrified = -1 - if (7) - //open door - if (src.welded) - usr << text("The airlock has been welded shut!
\n") - else if (src.locked) - usr << text("The door bolts are down!
\n") - else if (src.density) - open() - // close() - else - usr << text("The airlock is already opened.
\n") - if (8) - if(src.forcecrush) - usr << text("Door extra force already enabled!
\n") - else - src.forcecrush = 1 - if (9) - if(src.safetylight) - usr << text("Bolt indication light already enabled!
\n") - else - src.safetylight = 1 - if (10) - if(src.holdopen) - usr << text("Door Behavior already set to: Automatically close
\n") - else - src.holdopen = 1 - - src.update_icon() - src.updateUsrDialog() - if((istype(usr.equipped(), /obj/item/device/hacktool))) - return attack_ai(usr, usr.equipped()) - return - - - - -/obj/machinery/door/airlock/secure - name = "Secure Airlock" - desc = "Good lord, at least they left out the overcomplicated death traps. Looks to be a layer of armor plate you might be able to remove with a wrench." - icon = 'Doorhatchele.dmi' - - wires = 65535 - wirenum = 16 - alert_probability = 20 - holdopen = 0 - signalers = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var - list/WireColorToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/IndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - is_detached = 0 - - - - New() - ..() - //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/flagIndex = 1 - for (var/flag=1, flag<65536, flag+=flag) - var/valid = 0 - while (!valid) - var/colorIndex = rand(1, 16) - if (WireColorToFlag[colorIndex] == 0) - valid = 1 - WireColorToFlag[colorIndex] = flag - IndexToFlag[flagIndex] = flag - IndexToWireColor[flagIndex] = colorIndex - WireColorToIndex[colorIndex] = flagIndex - flagIndex+=1 - return - - - isWireColorCut(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - - isWireCut(var/wireIndex) - var/wireFlag = IndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - - pulse(var/wireColor) - var/wireIndex = WireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - animate("deny") - if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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). - src.loseMainPower() - if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - else - if(src.arePowerSystemsOn()) //only can raise bolts if power's on - src.locked = 0 - usr << "You hear a click from inside the door." - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //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). - src.loseBackupPower() - if (AIRLOCK_WIRE_AI_CONTROL) - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if (src.secondsElectrified==0) - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if (!src.requiresID() || src.check_access(null)) - if (src.density) - open() - else - close() - if(AIRLOCK_WIRE_CRUSH) - src.forcecrush = !src.forcecrush - if(AIRLOCK_WIRE_LIGHT) - src.safetylight = !src.safetylight - if(AIRLOCK_WIRE_HOLDOPEN) - src.holdopen = !src.holdopen - if(AIRLOCK_WIRE_ALERTAI) - if(prob(alert_probability)) - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - - cut(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - var/wireIndex = WireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if (src.locked!=1) - src.locked = 1 - update_icon() - src.updateUsrDialog() - if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - update_icon() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if (src.secondsElectrified != -1) - src.secondsElectrified = -1 - if(AIRLOCK_WIRE_ALERTAI) - if(prob(alert_probability)) - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - - mend(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - var/wireIndex = WireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - if (src.secondsElectrified == -1) - src.secondsElectrified = 0 - - getAirlockWires() - var/t1 - var/iterator = 0 - for(var/wiredesc in wire_index) - if(iterator == wirenum) - break - var/is_uncut = src.wires & WireColorToFlag[wire_index[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wire_index[wiredesc]]) - t1 += "Detach signaler" - else - t1 += "Attach signaler" - t1 += "
" - iterator++ - return t1 - attackby(C as obj, mob/user as mob) //world << text("airlock attackby src [] obj [] mob []", src, C, user) if(istype(C, /obj/item/device/detective_scanner)) @@ -2975,1554 +1489,6 @@ About the new airlock wires panel: if(src.shock(user, 75)) return - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/device/hacktool)) - return src.attack_ai(user, C) - else if (istype(C, /obj/item/weapon/wrench)) - user << "You start to remove the armor plate..." - if(do_after(user,30)) - user << "Armor plates removed" - src.is_detached = 1 - else - if (istype(C, /obj/item/weapon/wrench)) - user << "You start to reattach the armor plate..." - if(do_after(user,30)) - user << "Armor plates attached" - src.is_detached = 0 - else - return ..(C, user)#define AIRLOCK_WIRE_IDSCAN 1 -#define AIRLOCK_WIRE_MAIN_POWER1 2 -#define AIRLOCK_WIRE_MAIN_POWER2 3 -#define AIRLOCK_WIRE_DOOR_BOLTS 4 -#define AIRLOCK_WIRE_BACKUP_POWER1 5 -#define AIRLOCK_WIRE_BACKUP_POWER2 6 -#define AIRLOCK_WIRE_OPEN_DOOR 7 -#define AIRLOCK_WIRE_AI_CONTROL 8 -#define AIRLOCK_WIRE_ELECTRIFY 9 -#define AIRLOCK_WIRE_CRUSH 10 -#define AIRLOCK_WIRE_LIGHT 11 -#define AIRLOCK_WIRE_HOLDOPEN 12 -#define AIRLOCK_WIRE_FAKEBOLT1 13 -#define AIRLOCK_WIRE_FAKEBOLT2 14 -#define AIRLOCK_WIRE_ALERTAI 15 -#define AIRLOCK_WIRE_DOOR_BOLTS_2 16 -//#define AIRLOCK_WIRE_FINGERPRINT 17 - -/* - New methods: - pulse - sends a pulse into a wire for hacking purposes - cut - cuts a wire and makes any necessary state changes - mend - mends a wire and makes any necessary state changes - isWireColorCut - returns 1 if that color wire is cut, or 0 if not - isWireCut - returns 1 if that wire (e.g. AIRLOCK_WIRE_DOOR_BOLTS) is cut, or 0 if not - canAIControl - 1 if the AI can control the airlock, 0 if not (then check canAIHack to see if it can hack in) - canAIHack - 1 if the AI can hack into the airlock to recover control, 0 if not. Also returns 0 if the AI does not *need* to hack it. - arePowerSystemsOn - 1 if the main or backup power are functioning, 0 if not. Does not check whether the power grid is charged or an APC has equipment on or anything like that. (Check (stat & NOPOWER) for that) - requiresIDs - 1 if the airlock is requiring IDs, 0 if not - isAllPowerCut - 1 if the main and backup power both have cut wires. - regainMainPower - handles the effect of main power coming back on. - loseMainPower - handles the effect of main power going offline. Usually (if one isn't already running) spawn a thread to count down how long it will be offline - counting down won't happen if main power was completely cut along with backup power, though, the thread will just sleep. - loseBackupPower - handles the effect of backup power going offline. - regainBackupPower - handles the effect of main power coming back on. - shock - has a chance of electrocuting its target. -*/ - -//This generates the randomized airlock wire assignments for the game. -/proc/RandomAirlockWires() - //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var/flagIndex = 1 - for (var/flag=1, flag<4096, flag+=flag) - var/valid = 0 - while (!valid) - var/colorIndex = rand(1, 12) - if (wires[colorIndex] == 0) - valid = 1 - wires[colorIndex] = flag - airlockIndexToFlag[flagIndex] = flag - airlockIndexToWireColor[flagIndex] = colorIndex - airlockWireColorToIndex[colorIndex] = flagIndex - flagIndex+=1 - return wires - -/* Example: -Airlock wires color -> flag are { 64, 128, 256, 2, 16, 4, 8, 32, 1 }. -Airlock wires color -> index are { 7, 8, 9, 2, 5, 3, 4, 6, 1 }. -Airlock index -> flag are { 1, 2, 4, 8, 16, 32, 64, 128, 256 }. -Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. -*/ - -/obj/machinery/door/airlock - name = "Airlock" - icon = 'doorint.dmi' - icon_state = "door_closed" - - 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. - synDoorHacked = 0 // Has it been hacked? bool 1 = yes / 0 = no - synHacking = 0 // Is hack in process y/n? - secondsMainPowerLost = 0 //The number of seconds until power is restored. - secondsBackupPowerLost = 0 //The number of seconds until power is restored. - spawnPowerRestoreRunning = 0 - welded = null - locked = 0 - wires = 4095 - aiDisabledIdScanner = 0 - aiHacking = 0 - obj/machinery/door/airlock/closeOther = null - closeOtherId = null - list/signalers[12] - lockdownbyai = 0 - doortype = 0 - justzap = 0 - safetylight = 1 - obj/item/weapon/airlock_electronics/electronics = null - alert_probability = 3 - list/wire_index = list( - "Orange" = 1, - "Dark red" = 2, - "White" = 3, - "Yellow" = 4, - "Red" = 5, - "Blue" = 6, - "Green" = 7, - "Grey" = 8, - "Black" = 9, - "Pink" = 10, - "Brown" = 11, - "Maroon" = 12, - "Aqua" = 13, - "Turgoise" = 14, - "Purple" = 15, - "Rainbow" = 16, - "Atomic Tangerine" = 17, - "Neon Green" = 18, - "Cotton Candy" = 19, - "Plum" = 20, - "Shamrock" = 21, - "Indigo" = 22 - ) - wirenum = 12 - holdopen = 1 - autoclose = 1 - secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. - - - command - name = "Airlock" - icon = 'Doorcom.dmi' - doortype = 1 - holdopen = 0 - - - security - name = "Airlock" - icon = 'Doorsec.dmi' - doortype = 2 - - - engineering - name = "Airlock" - icon = 'Dooreng.dmi' - doortype = 3 - - - medical - name = "Airlock" - icon = 'Doormed.dmi' - doortype = 4 - - - maintenance - name = "Maintenance Access" - icon = 'Doormaint.dmi' - doortype = 5 - - external - name = "External Airlock" - icon = 'Doorext.dmi' - doortype = 6 - - - glass - name = "Glass Airlock" - icon = 'Doorglass.dmi' - opacity = 0 - doortype = 7 - glass = 1 - - - glass_command - name = "Maintenance Hatch" - icon = 'Doorcomglass.dmi' - opacity = 0 - doortype = 14 - glass = 1 - - - glass_engineering - name = "Maintenance Hatch" - icon = 'Doorengglass.dmi' - opacity = 0 - doortype = 15 - glass = 1 - - - glass_security - name = "Maintenance Hatch" - icon = 'Doorsecglass.dmi' - opacity = 0 - doortype = 16 - glass = 1 - - - glass_medical - name = "Maintenance Hatch" - icon = 'doormedglass.dmi' - opacity = 0 - doortype = 17 - glass = 1 - - - centcom - name = "Airlock" - icon = 'Doorele.dmi' - opacity = 0 - doortype = 8 - - - vault - name = "Vault" - icon = 'vault.dmi' - opacity = 1 - doortype = 9 - - - glass_large - name = "Glass Airlock" - icon = 'Door2x1glassfull.dmi' - opacity = 0 - doortype = 10 - glass = 1 - - - freezer - name = "Freezer Airlock" - icon = 'Doorfreezer.dmi' - opacity = 1 - doortype = 11 - - - hatch - name = "Airtight Hatch" - icon = 'Doorhatchele.dmi' - opacity = 1 - doortype = 12 - - - maintenance_hatch - name = "Maintenance Hatch" - icon = 'Doorhatchmaint2.dmi' - opacity = 1 - doortype = 13 - - - New() - ..() - if (src.closeOtherId != null) - spawn (5) - for (var/obj/machinery/door/airlock/A in machines) - if (A.closeOtherId == src.closeOtherId && A != src) - src.closeOther = A - break - - - open() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) - return 0 - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - if (src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density) - src.closeOther.close() - return ..() - - - close() - if (src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - return - ..() - use_power(50) - playsound(src.loc, 'airlock.ogg', 30, 1) - var/obj/structure/window/killthis = (locate(/obj/structure/window) in get_turf(src)) - if(killthis) - killthis.ex_act(2)//Smashin windows - return - - - bumpopen(mob/user as mob) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if (!istype(usr, /mob/living/silicon)) - 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) - user << "\red You feel a powerful shock course through your body!" - user.halloss += 10 - user.stunned += 10 - return - ..(user) - - - update_icon() - if(overlays) overlays = null - if(density) - if(locked && safetylight) - icon_state = "door_locked" - else - icon_state = "door_closed" - if(p_open || welded) - overlays = list() - if(p_open) - overlays += image(icon, "panel_open") - if(welded) - overlays += image(icon, "welded") - else - icon_state = "door_open" - return - - - animate(animation) - switch(animation) - if("opening") - if(overlays) overlays = null - if(p_open) - icon_state = "o_door_opening" //can not use flick due to BYOND bug updating overlays right before flicking - else - flick("door_opening", src) - if("closing") - if(overlays) overlays = null - if(p_open) - flick("o_door_closing", src) - else - flick("door_closing", src) - if("spark") - flick("door_spark", src) - if("deny") - flick("door_deny", src) - return - - requiresID() - return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) - - attackby(C as obj, mob/user as mob) - //world << text("airlock attackby src [] obj [] mob []", src, C, user) - if(istype(C, /obj/item/device/detective_scanner)) - return - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 75)) - return - - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/weapon/screwdriver)) - src.p_open = !( src.p_open ) - src.update_icon() - else if (istype(C, /obj/item/weapon/wirecutters)) - 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/hacktool)) - return src.attack_ai(user, C) - 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 (istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/fireaxe) ) - var/beingcrowbarred = null - if(istype(C, /obj/item/weapon/crowbar) ) - beingcrowbarred = 1 //derp, Agouri - else - beingcrowbarred = 0 - if ( ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) && beingcrowbarred == 1 ) - playsound(src.loc, 'Crowbar.ogg', 100, 1) - user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") - if(do_after(user,40)) - user << "\blue You removed the airlock electronics!" - switch(src.doortype) - if(0) new/obj/structure/door_assembly/door_assembly_0( src.loc ) - if(1) new/obj/structure/door_assembly/door_assembly_com( src.loc ) - if(2) new/obj/structure/door_assembly/door_assembly_sec( src.loc ) - if(3) new/obj/structure/door_assembly/door_assembly_eng( src.loc ) - if(4) new/obj/structure/door_assembly/door_assembly_med( src.loc ) - if(5) new/obj/structure/door_assembly/door_assembly_mai( src.loc ) - if(6) new/obj/structure/door_assembly/door_assembly_ext( src.loc ) - if(7) new/obj/structure/door_assembly/door_assembly_g( src.loc ) - var/obj/item/weapon/airlock_electronics/ae - if (!electronics) - ae = new/obj/item/weapon/airlock_electronics( src.loc ) - ae.conf_access = src.req_access - else - ae = electronics - electronics = null - ae.loc = src.loc - - del(src) - return - else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) - user << "\blue The airlock's motors resist your efforts to pry it open." - else if (src.locked) - user << "\blue The airlock's bolts prevent it from being pried open." - if ((src.density) && (!( src.welded ) && !( src.operating ) && ((!src.arePowerSystemsOn()) || (stat & NOPOWER)) && !( src.locked ))) - - if(beingcrowbarred == 0) //being fireaxe'd - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("opening") - - sleep(15) - - layer = 2.7 - src.density = 0 - update_icon() - - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - user << "\red You need to be wielding the Fire axe to do that." - return - else - spawn( 0 ) - src.operating = 1 - animate("opening") - - sleep(15) - - layer = 2.7 - src.density = 0 - update_icon() - - if (!istype(src, /obj/machinery/door/airlock/glass)) - src.sd_SetOpacity(0) - src.operating = 0 - return - - else - if ((!src.density) && (!( src.welded ) && !( src.operating ) && !( src.locked ))) - if(beingcrowbarred == 0) - var/obj/item/weapon/fireaxe/F = C - if(F.wielded == 1) - spawn( 0 ) - src.operating = 1 - animate("closing") - - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - else - user << "\red You need to be wielding the Fire axe to do that." - else - spawn( 0 ) - src.operating = 1 - animate("closing") - layer = 3.1 - src.density = 1 - sleep(15) - update_icon() - - if ((src.visible) && (!istype(src, /obj/machinery/door/airlock/glass))) - src.sd_SetOpacity(1) - src.operating = 0 - - else - ..() - return - - - attack_paw(mob/user as mob) - return src.attack_hand(user) - - - attack_hand(mob/user as mob) - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 100)) - return - - if (ishuman(user) && prob(40) && src.density) - var/mob/living/carbon/human/H = user - if(H.getBrainLoss() >= 60) - playsound(src.loc, 'bang.ogg', 25, 1) - if(!istype(H.head, /obj/item/clothing/head/helmet)) - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock." - var/datum/organ/external/affecting = H.get_organ("head") - affecting.take_damage(10, 0) - H.Stun(8) - H.Weaken(5) - H.UpdateDamageIcon() - else - for(var/mob/M in viewers(src, null)) - M << "\red [user] headbutts the airlock. Good thing they're wearing a helmet." - return - - if (src.p_open) - user.machine = src - var/t1 = text("Access Panel
\n") - - //t1 += text("[]: ", airlockFeatureNames[airlockWireColorToIndex[9]]) - t1 += getAirlockWires() - - t1 += text("
\n[]
\n[]
\n[]
\n[]
\n[]", (src.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((src.arePowerSystemsOn() && !(stat & NOPOWER)) ? "The test light is on." : "The test light is off!"), (src.aiControlDisabled==0 ? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), (src.secondsElectrified!=0 ? "The safety light is flashing!" : "The safety light is on."), (src.forcecrush==0 ? "The hydraulics control light is a solid green." : "The hydraulics control light is flashing red.")) - - t1 += text("

Close

\n", src) - - user << browse(t1, "window=airlock") - onclose(user, "airlock") - - else - ..(user) - return - -//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 engage engineer smasher, 9 enable bolt indicator, 10 wait for clearance -//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 disable engineer smasher, 9 disable bolt indicator, 10 autoclose - //This has been converted to be called by either the AI or a mob with a hacktool, permitting either to directly operate the airlock - attack_ai(mob/user as mob, obj/item/device/hacktool/C) - if(isAI(user)) - if (!src.canAIControl()) - if (src.canAIHack()) - src.hack(user) - return - else if(user) - if(!C) - return - if(C.in_use) - user << "We are already hacking another airlock." - return - if (!src.canSynControl() && src.canSynHack(C)) - src.synhack(user, C) - return - if(istype(C, /obj/item/device/hacktool/engineer)) - return - else - world << "ERROR: Mob was null when calling attack_ai on [src.name] at [src.x],[src.y],[src.z]" - return - - - //Separate interface for the AI. - user.machine = src - var/t1 = text("Airlock Control
\n") - if (src.secondsMainPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - t1 += text("Main power is offline for [] seconds.
\n", src.secondsMainPowerLost) - else - t1 += text("Main power is offline indefinitely.
\n") - else - t1 += text("Main power is online.") - - if (src.secondsBackupPowerLost > 0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - t1 += text("Backup power is offline for [] seconds.
\n", src.secondsBackupPowerLost) - else - t1 += text("Backup power is offline indefinitely.
\n") - else if (src.secondsMainPowerLost > 0) - t1 += text("Backup power is online.") - else - t1 += text("Backup power is offline, but will turn on if main power fails.") - t1 += "
\n" - - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - t1 += text("IdScan wire is cut.
\n") - else if (src.aiDisabledIdScanner) - t1 += text("IdScan disabled. Enable?
\n", src) - else - t1 += text("IdScan enabled. Disable?
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) - t1 += text("Main Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - t1 += text("Main Power Output wire is cut.
\n") - if (src.secondsMainPowerLost == 0) - t1 += text("Temporarily disrupt main power?.
\n", src) - if (src.secondsBackupPowerLost == 0) - t1 += text("Temporarily disrupt backup power?.
\n", src) - - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) - t1 += text("Backup Power Input wire is cut.
\n") - if (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - t1 += text("Backup Power Output wire is cut.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_CRUSH)) - t1 += text("Airlock extra force wire is cut.
\n") - else if(!src.forcecrush) - t1 += text("Airlock extra force disabled Enable it?
\n") - else - t1 += text("Airlock extra force enabled Disable it?
\n") - - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - t1 += text("Door bolt drop wire is cut.
\n") - else if (!src.locked) - t1 += text("Door bolts are up. Drop them?
\n", src) - else - t1 += text("Door bolts are down.") - if (src.arePowerSystemsOn()) - t1 += text(" Raise?
\n", src) - else - t1 += text(" Cannot raise door bolts due to power failure.
\n") - - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - t1 += text("Electrification wire is cut.
\n") - if (src.secondsElectrified==-1) - t1 += text("Door is electrified indefinitely. Un-electrify it?
\n", src) - else if (src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
\n", src.secondsElectrified, src) - else - t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
\n", src, src) - - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - t1 += "Bolt indication light wire is cut.
\n" - else if(!src.safetylight) - t1 += text("Bolt Indication light is disabled Enable it?
\n") - else - t1 += text("Bolt Indication light is enabled Disable it?
\n") - - if(src.isWireCut(AIRLOCK_WIRE_HOLDOPEN)) - t1 += "Behavior Control light wire is cut.
\n" - else if(!src.holdopen) - t1 += text("Door behavior is set to: Automatically close Toggle?
\n") - else - t1 += text("Door behavior is set to: Wait for clearance to close Toggle?
\n") - - if (src.welded) - t1 += text("Door appears to have been welded shut.
\n") - else if (!src.locked) - if (src.density) - t1 += text("Open door
\n", src) - else - t1 += text("Close door
\n", src) - - t1 += text("

Close

\n", src) - user << browse(t1, "window=airlock") - onclose(user, "airlock") - - - proc - hack(mob/user as mob) - if (src.aiHacking==0) - src.aiHacking=1 - spawn(20) - //TODO: Make this take a minute - user << "Airlock AI control has been blocked. Beginning fault-detection." - sleep(50) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Fault confirmed: airlock control wire disabled or cut." - sleep(20) - user << "Attempting to hack into airlock. This may take some time." - sleep(200) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(170) - if (src.canAIControl()) - user << "Alert cancelled. Airlock control has been restored without our assistance." - src.aiHacking=0 - return - else if (!src.canAIHack()) - user << "We've lost our connection! Unable to hack airlock." - src.aiHacking=0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(50) - //disable blocked control - src.aiControlDisabled = 2 - user << "Receiving control information from airlock." - sleep(10) - //bring up airlock dialog - src.aiHacking = 0 - src.attack_ai(user) - - - synhack(mob/user as mob, obj/item/device/hacktool/I) - if (src.synHacking==0) - var/multiplier = 1 - if(istype(C, /obj/item/device/hacktool/engineer)) - if(!src.locked) - user << "The door bolts are already up!" - return - multiplier++ - src.synHacking=1 - I.in_use = 1 - user << "You begin hacking..." - spawn(20*multiplier) - user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." - sleep(25*multiplier) - if (src.canSynControl()) - user << "Hack cancelled, control already possible." - src.synHacking=0 - I.in_use = 0 - return - else if (!src.canSynHack(I)) - user << "\red Connection lost. Stand still and stay near the airlock!" - src.synHacking=0 - I.in_use = 0 - return - user << "Connection established." - sleep(10*multiplier) - user << "Attempting to hack into airlock. This may take some time." - sleep(50*multiplier) - - // Alerting the AIs - var/list/cameras = list() - for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area - cameras += C - var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability - if(alertoption) - if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) - alertoption = 3 - else if (prob(18)) //18% chance of sending the AI just the area - alertoption = 2 - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - switch(alertoption) - if(3) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc, cameras) - if(2) aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) aiPlayer.triggerUnmarkedAlarm("AirlockHacking") - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - switch(alertoption) - if(2,3) robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - if(1) robotPlayer.triggerUnmarkedAlarm("AirlockHacking") - // ...And done - - if (!src.canSynHack(I)) - user << "\red Hack aborted: landline connection lost. Stay closer to the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Local override already in place, hack aborted." - src.synHacking=0 - I.in_use = 0 - return - user << "Upload access confirmed. Loading control program into airlock software." - sleep(35*multiplier) - if (!src.canSynHack(I)) - user << "\red Hack aborted: cable connection lost. Do not move away from the airlock." - src.synHacking=0 - I.in_use = 0 - return - else if (src.canSynControl()) - user << "Upload access aborted, local override already in place." - src.synHacking=0 - I.in_use = 0 - return - user << "Transfer complete. Forcing airlock to execute program." - sleep(25*multiplier) - //disable blocked control - if(istype(C, /obj/item/device/hacktool/engineer)) - user << "Raising door bolts..." - src.locked = 0 - update_icon() - return - src.synDoorHacked = 1 - user << "Bingo! We're in. Airlock control panel coming right up." - sleep(5) - //bring up airlock dialog - src.synHacking = 0 - I.in_use = 0 - src.attack_ai(user, I) - - - canAIControl() - return ((src.aiControlDisabled!=1) && (!src.isAllPowerCut())); - - - canAIHack() - return ((src.aiControlDisabled==1) && (!src.isAllPowerCut())); - - - canSynControl() - return (src.synDoorHacked && (!src.isAllPowerCut())); - - - canSynHack(obj/item/device/hacktool/H) - return (in_range(src, usr) && get_dist(src, H) <= 1 && src.synDoorHacked==0 && !src.isAllPowerCut()); - - - -/* -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 \red 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) -*/ - - pulse(var/wireColor) - //var/wireFlag = airlockWireColorToFlag[wireColor] //not used in this function - var/wireIndex = airlockWireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - animate("deny") - if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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). - src.loseMainPower() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - else - if(src.arePowerSystemsOn()) //only can raise bolts if power's on - src.locked = 0 - usr << "You hear a click from inside the door." - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //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). - src.loseBackupPower() - if (AIRLOCK_WIRE_AI_CONTROL) - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if (src.secondsElectrified==0) - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if (!src.requiresID() || src.check_access(null)) - if (src.density) - open() - else - close() - if(AIRLOCK_WIRE_CRUSH) - src.forcecrush = !src.forcecrush - if(AIRLOCK_WIRE_LIGHT) - src.safetylight = !src.safetylight - if(AIRLOCK_WIRE_HOLDOPEN) - src.holdopen = !src.holdopen - - cut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_DOOR_BOLTS) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if (src.locked!=1) - src.locked = 1 - update_icon() - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if (src.secondsElectrified != -1) - src.secondsElectrified = -1 - - mend(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - if (src.secondsElectrified == -1) - src.secondsElectrified = 0 - - getAirlockWires() - var/t1 - var/iterator = 0 - for(var/wiredesc in wire_index) - if(iterator == wirenum) - break - var/is_uncut = src.wires & airlockWireColorToFlag[wire_index[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wire_index[wiredesc]]) - t1 += "Detach signaler" - else - t1 += "Attach signaler" - t1 += "
" - iterator++ - return t1 - - isElectrified() - return (src.secondsElectrified != 0); - - isWireColorCut(var/wireColor) - var/wireFlag = airlockWireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - - isWireCut(var/wireIndex) - var/wireFlag = airlockIndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - - arePowerSystemsOn() - return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) - - isAllPowerCut() - return ((src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) && (src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - - regainMainPower() - if (src.secondsMainPowerLost > 0) - src.secondsMainPowerLost = 0 - - loseMainPower() - if (src.secondsMainPowerLost <= 0) - src.secondsMainPowerLost = 60 - if (src.secondsBackupPowerLost < 10) - src.secondsBackupPowerLost = 10 - if (!src.spawnPowerRestoreRunning) - src.spawnPowerRestoreRunning = 1 - spawn(0) - var/cont = 1 - while (cont) - sleep(10) - cont = 0 - if (src.secondsMainPowerLost>0) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.secondsMainPowerLost -= 1 - src.updateDialog() - cont = 1 - - if (src.secondsBackupPowerLost>0) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.secondsBackupPowerLost -= 1 - src.updateDialog() - cont = 1 - src.spawnPowerRestoreRunning = 0 - src.updateDialog() - - loseBackupPower() - if (src.secondsBackupPowerLost < 60) - src.secondsBackupPowerLost = 60 - - regainBackupPower() - if (src.secondsBackupPowerLost > 0) - src.secondsBackupPowerLost = 0 - - // 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 - shock(mob/user, prb) - if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock - return 0 - if(!prob(prb)) - return 0 //you lucked out, no shock for you - if(istype(usr.equipped(),/obj/item/weapon/shard)) - return 0 - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() //sparks always. - if (electrocute_mob(user, get_area(src), src)) - return 1 - else - return 0 - - prison_open() - src.locked = 0 - src.open() - src.locked = 1 - return - - - -/obj/machinery/door/airlock/Topic(href, href_list) - ..() - if (usr.stat || usr.restrained() ) - return - if (href_list["close"]) - usr << browse(null, "window=airlock") - if (usr.machine==src) - usr.machine = null - return - if(in_range(src, usr) && istype(src.loc, /turf) && p_open) - usr.machine = src - if (href_list["wires"]) - var/t1 = text2num(href_list["wires"]) - if (!(istype(usr.equipped(), /obj/item/weapon/wirecutters) || istype(usr.equipped(),/obj/item/weapon/shard))) - usr << "You need wirecutters!" - return - if (src.isWireColorCut(t1) && istype(usr.equipped(), /obj/item/weapon/wirecutters)) - src.mend(t1) - else - src.cut(t1) - else if (href_list["pulse"]) - var/t1 = text2num(href_list["pulse"]) - if (!istype(usr.equipped(), /obj/item/device/multitool)) - usr << "You need a multitool!" - return - if (src.isWireColorCut(t1)) - usr << "You can't pulse a cut wire." - return - else - src.pulse(t1) - else if(href_list["signaler"]) - var/wirenum = text2num(href_list["signaler"]) - if(!istype(usr.equipped(), /obj/item/device/assembly/signaler)) - usr << "You need a signaller!" - return - if(src.isWireColorCut(wirenum)) - usr << "You can't attach a signaller to a cut wire." - return - var/obj/item/device/assembly/signaler/R = usr.equipped() - if(R.secured) - usr << "This radio can't be attached!" - return - var/mob/M = usr - M.drop_item() - R.loc = src - R.airlock_wire = wirenum - src.signalers[wirenum] = R - else if(href_list["remove-signaler"]) - var/wirenum = text2num(href_list["remove-signaler"]) - if(!(src.signalers[wirenum])) - usr << "There's no signaller attached to that wire!" - return - var/obj/item/device/assembly/signaler/R = src.signalers[wirenum] - R.loc = usr.loc - R.airlock_wire = null - src.signalers[wirenum] = null - - src.update_icon() - add_fingerprint(usr) - src.updateUsrDialog() - else //AI or Syndicate using hacktool - if (!src.canAIControl() || (istype(usr.equipped(), /obj/item/device/hacktool/) && (!src.canSynControl() || !in_range(src, usr)))) - usr << "Airlock control connection lost!" - return - //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door - //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door - if (href_list["aiDisable"]) - var/code = text2num(href_list["aiDisable"]) - switch (code) - if (1) - //disable idscan - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways." - else if (src.aiDisabledIdScanner) - usr << "You've already disabled the IdScan feature." - else - src.aiDisabledIdScanner = 1 - if (2) - //disrupt main power - if (src.secondsMainPowerLost == 0) - src.loseMainPower() - else - usr << "Main power is already offline." - if (3) - //disrupt backup power - if (src.secondsBackupPowerLost == 0) - src.loseBackupPower() - else - usr << "Backup power is already offline." - if (4) - //drop door bolts - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << "You can't drop the door bolts - The door bolt dropping wire has been cut." - else if (src.locked!=1) - src.locked = 1 - update_icon() - if (5) - //un-electrify door - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("Can't un-electrify the airlock - The electrification wire is cut.
\n") - else if (src.secondsElectrified==-1) - src.secondsElectrified = 0 - else if (src.secondsElectrified>0) - src.secondsElectrified = 0 - if (7) - //close door - if (src.welded) - usr << text("The airlock has been welded shut!
\n") - else if (src.locked) - usr << text("The door bolts are down!
\n") - else if (!src.density) - close() - else - usr << text("The airlock is already closed.
\n") - if (8) - if(!src.forcecrush) - usr << text("Door extra force not enabled!
\n") - else - src.forcecrush = 0 - if (9) - if(!src.safetylight) - usr << text("Bolt indication light not enabled!
\n") - else - src.safetylight = 0 - if (10) - if(!src.holdopen) - usr << text("Door Behavior already set to: Wait for clearance to close
\n") - else - src.holdopen = 0 - - else if (href_list["aiEnable"]) - var/code = text2num(href_list["aiEnable"]) - switch (code) - if (1) - //enable idscan - if (src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "You can't enable IdScan - The IdScan wire has been cut." - else if (src.aiDisabledIdScanner) - src.aiDisabledIdScanner = 0 - else - usr << "The IdScan feature is not disabled." - if (4) - //raise door bolts - if (src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << text("The door bolt drop wire is cut - you can't raise the door bolts.
\n") - else if (!src.locked) - usr << text("The door bolts are already up.
\n") - else - if (src.arePowerSystemsOn()) - src.locked = 0 - update_icon() - else - usr << text("Cannot raise door bolts due to power failure.
\n") - - if (5) - //electrify door for 30 seconds - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
\n") - else if (src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
\n") - else if (src.secondsElectrified!=0) - usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") - else - src.secondsElectrified = 30 - spawn(10) - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - src.updateUsrDialog() - sleep(10) - if (6) - //electrify door indefinitely - if (src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
\n") - else if (src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified.
\n") - else if (src.secondsElectrified!=0) - usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
\n") - else - src.secondsElectrified = -1 - if (7) - //open door - if (src.welded) - usr << text("The airlock has been welded shut!
\n") - else if (src.locked) - usr << text("The door bolts are down!
\n") - else if (src.density) - open() - // close() - else - usr << text("The airlock is already opened.
\n") - if (8) - if(src.forcecrush) - usr << text("Door extra force already enabled!
\n") - else - src.forcecrush = 1 - if (9) - if(src.safetylight) - usr << text("Bolt indication light already enabled!
\n") - else - src.safetylight = 1 - if (10) - if(src.holdopen) - usr << text("Door Behavior already set to: Automatically close
\n") - else - src.holdopen = 1 - - src.update_icon() - src.updateUsrDialog() - if((istype(usr.equipped(), /obj/item/device/hacktool))) - return attack_ai(usr, usr.equipped()) - return - - - - -/obj/machinery/door/airlock/secure - name = "Secure Airlock" - desc = "Good lord, at least they left out the overcomplicated death traps. Looks to be a layer of armor plate you might be able to remove with a wrench." - icon = 'Doorhatchele.dmi' - - wires = 65535 - wirenum = 16 - alert_probability = 20 - holdopen = 0 - signalers = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - var - list/WireColorToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/IndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - is_detached = 0 - - - - New() - ..() - //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/flagIndex = 1 - for (var/flag=1, flag<65536, flag+=flag) - var/valid = 0 - while (!valid) - var/colorIndex = rand(1, 16) - if (WireColorToFlag[colorIndex] == 0) - valid = 1 - WireColorToFlag[colorIndex] = flag - IndexToFlag[flagIndex] = flag - IndexToWireColor[flagIndex] = colorIndex - WireColorToIndex[colorIndex] = flagIndex - flagIndex+=1 - return - - - isWireColorCut(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - return ((src.wires & wireFlag) == 0) - - isWireCut(var/wireIndex) - var/wireFlag = IndexToFlag[wireIndex] - return ((src.wires & wireFlag) == 0) - - pulse(var/wireColor) - var/wireIndex = WireColorToIndex[wireColor] - switch(wireIndex) - if(AIRLOCK_WIRE_IDSCAN) - //Sending a pulse through this flashes the red light on the door (if the door has power). - if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) - animate("deny") - if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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). - src.loseMainPower() - if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - else - if(src.arePowerSystemsOn()) //only can raise bolts if power's on - src.locked = 0 - usr << "You hear a click from inside the door." - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - update_icon() - - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //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). - src.loseBackupPower() - if (AIRLOCK_WIRE_AI_CONTROL) - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateDialog() - spawn(10) - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if (src.secondsElectrified==0) - src.secondsElectrified = 30 - spawn(10) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if (src.secondsElectrified<0) - src.secondsElectrified = 0 - // src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite - sleep(10) - if(AIRLOCK_WIRE_OPEN_DOOR) - //tries to open the door without ID - //will succeed only if the ID wire is cut or the door requires no access - if (!src.requiresID() || src.check_access(null)) - if (src.density) - open() - else - close() - if(AIRLOCK_WIRE_CRUSH) - src.forcecrush = !src.forcecrush - if(AIRLOCK_WIRE_LIGHT) - src.safetylight = !src.safetylight - if(AIRLOCK_WIRE_HOLDOPEN) - src.holdopen = !src.holdopen - if(AIRLOCK_WIRE_ALERTAI) - if(prob(alert_probability)) - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - - cut(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - var/wireIndex = WireColorToIndex[wireColor] - wires &= ~wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. - src.loseMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) - //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if (src.locked!=1) - src.locked = 1 - update_icon() - src.updateUsrDialog() - if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) - //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), - //raises them if they are down (only if power's on) - if (!src.locked) - src.locked = 1 - src.updateUsrDialog() - update_icon() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. - src.loseBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 0) - src.aiControlDisabled = 1 - else if (src.aiControlDisabled == -1) - src.aiControlDisabled = 2 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if (src.secondsElectrified != -1) - src.secondsElectrified = -1 - if(AIRLOCK_WIRE_ALERTAI) - if(prob(alert_probability)) - for (var/mob/living/silicon/ai/aiPlayer in world) - if (aiPlayer.stat != 2) - aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - for (var/mob/living/silicon/robot/robotPlayer in world) - if (robotPlayer.stat != 2) - robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) - - mend(var/wireColor) - var/wireFlag = WireColorToFlag[wireColor] - var/wireIndex = WireColorToIndex[wireColor] //not used in this function - wires |= wireFlag - switch(wireIndex) - if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.regainMainPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) - if ((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.regainBackupPower() - src.shock(usr, 50) - src.updateUsrDialog() - if (AIRLOCK_WIRE_AI_CONTROL) - //one wire for AI control. 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. - //aiControlDisabled: 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. - if (src.aiControlDisabled == 1) - src.aiControlDisabled = 0 - else if (src.aiControlDisabled == 2) - src.aiControlDisabled = -1 - src.updateUsrDialog() - if (AIRLOCK_WIRE_ELECTRIFY) - if (src.secondsElectrified == -1) - src.secondsElectrified = 0 - - getAirlockWires() - var/t1 - var/iterator = 0 - for(var/wiredesc in wire_index) - if(iterator == wirenum) - break - var/is_uncut = src.wires & WireColorToFlag[wire_index[wiredesc]] - t1 += "[wiredesc] wire: " - if(!is_uncut) - t1 += "Mend" - else - t1 += "Cut " - t1 += "Pulse " - if(src.signalers[wire_index[wiredesc]]) - t1 += "Detach signaler" - else - t1 += "Attach signaler" - t1 += "
" - iterator++ - return t1 - - attackby(C as obj, mob/user as mob) - //world << text("airlock attackby src [] obj [] mob []", src, C, user) - if(istype(C, /obj/item/device/detective_scanner)) - return - if(!src.is_detached) - if (!istype(usr, /mob/living/silicon)) - if (src.isElectrified()) - if(src.shock(user, 75)) - return - - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/device/hacktool)) - return src.attack_ai(user, C) - else if (istype(C, /obj/item/weapon/wrench)) - user << "You start to remove the armor plate..." - if(do_after(user,30)) - user << "Armor plates removed" - src.is_detached = 1 - else - if (istype(C, /obj/item/weapon/wrench)) - user << "You start to reattach the armor plate..." - if(do_after(user,30)) - user << "Armor plates attached" - src.is_detached = 0 - else - return ..(C, user) - if (src.isElectrified()) - if(src.shock(user, 75)) - return - src.add_fingerprint(user) if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) var/obj/item/weapon/weldingtool/W = C From bd756112a184e98d9d32c8631d4f7e1a7b0e98c9 Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 14:18:49 -0700 Subject: [PATCH 5/7] There. That /should/ make it work. --- code/game/machinery/doors/airlock.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1cb1a6ca9a3..914cb684b57 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -704,7 +704,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. spawn(20*multiplier) user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." sleep(25*multiplier) - if (src.canSynControl()) + if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) user << "Hack cancelled, control already possible." src.synHacking=0 I.in_use = 0 @@ -747,7 +747,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. src.synHacking=0 I.in_use = 0 return - else if (src.canSynControl()) + else if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) user << "Local override already in place, hack aborted." src.synHacking=0 I.in_use = 0 @@ -759,7 +759,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. src.synHacking=0 I.in_use = 0 return - else if (src.canSynControl()) + else if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) user << "Upload access aborted, local override already in place." src.synHacking=0 I.in_use = 0 From b5f271c18d555f0e3ff3d67b0eaf759ceb0de641 Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 15:08:21 -0700 Subject: [PATCH 6/7] .dme stuff --- baystation12.dme | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index e179fa09ade..80277811e64 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -144,10 +144,7 @@ #define FILE_DIR "code/unused/spacecraft" #define FILE_DIR "code/WorkInProgress" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Jumper" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/tajara_sprites" #define FILE_DIR "code/WorkInProgress/mapload" #define FILE_DIR "code/WorkInProgress/Mini" #define FILE_DIR "code/WorkInProgress/organs" @@ -179,7 +176,6 @@ #define FILE_DIR "icons/vending_icons" #define FILE_DIR "interface" #define FILE_DIR "maps" -#define FILE_DIR "maps/backup" #define FILE_DIR "sound" #define FILE_DIR "sound/ambience" #define FILE_DIR "sound/announcer" @@ -521,7 +517,7 @@ #include "code\game\machinery\computer\id.dm" #include "code\game\machinery\computer\lockdown.dm" #include "code\game\machinery\computer\medical.dm" -#include "code\game\machinery\computer\operating.dm" +#include "code\game\machinery\computer\Operating.dm" #include "code\game\machinery\computer\power.dm" #include "code\game\machinery\computer\robot.dm" #include "code\game\machinery\computer\security.dm" From 710bcbb42bc792ebe31c6537f721130135de399c Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 8 Feb 2012 17:42:34 -0700 Subject: [PATCH 7/7] Final parts for the airlocks. Wrench -> Weld -> Wrench removes the cover secure/centcom has all wires electrocute Emag is now tweaked Implanted uplink now works. --- code/WorkInProgress/Ported/Abi79/uplinks.dm | 34 ++- code/game/gamemodes/game_mode.dm | 2 +- code/game/machinery/doors/airlock.dm | 242 +++++++++++++++--- .../objects/closets/secure/engineering.dm | 1 + code/game/objects/items/weapons/cards_ids.dm | 2 +- 5 files changed, 236 insertions(+), 45 deletions(-) diff --git a/code/WorkInProgress/Ported/Abi79/uplinks.dm b/code/WorkInProgress/Ported/Abi79/uplinks.dm index b6bcefe1f8a..85ffa1f8914 100644 --- a/code/WorkInProgress/Ported/Abi79/uplinks.dm +++ b/code/WorkInProgress/Ported/Abi79/uplinks.dm @@ -187,7 +187,17 @@ A list of items and costs is stored under the datum of every game mode, alongsid //A Syndicate uplink disguised as a portable radio /obj/item/device/uplink/radio/implanted - uses = 5 + New() + ..() + uses = 5 + return + + explode() + var/obj/item/weapon/implant/uplink/U = src.loc + var/mob/living/A = U.imp_in + A.gib() + ..() + /obj/item/device/uplink/radio name = "ship bounced radio" @@ -228,12 +238,10 @@ A list of items and costs is stored under the datum of every game mode, alongsid if (usr.stat || usr.restrained()) return - var/mob/living/carbon/human/H = usr - - if (!( istype(H, /mob/living/carbon/human))) + if (!( istype(usr, /mob/living/carbon/human))) return 1 - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)) || istype(src.loc,/obj/item/weapon/implant/uplink))) usr.machine = src if(href_list["buy_item"]) @@ -241,6 +249,9 @@ A list of items and costs is stored under the datum of every game mode, alongsid var/path_obj = text2path(href_list["buy_item"]) var/item = new path_obj(get_turf(src.loc)) var/mob/A = src.loc + if(istype(src.loc,/obj/item/weapon/implant/uplink)) + var/obj/item/weapon/implant/uplink/U = src.loc + A = U.imp_in if(ismob(A) && !(locate(item) in NotInHand)) //&& !istype(item, /obj/spawner)) if(!A.r_hand) item:loc = A @@ -295,12 +306,13 @@ A list of items and costs is stored under the datum of every game mode, alongsid else if (href_list["clear_selfdestruct"]) src.temp = null - if (istype(src.loc, /mob)) - attack_self(src.loc) - else - for(var/mob/M in viewers(1, src)) - if (M.client) - src.attack_self(M) + attack_self(usr) +// if (istype(src.loc, /mob)) +// attack_self(src.loc) +// else +// for(var/mob/M in viewers(1, src)) +// if (M.client) +// src.attack_self(M) return proc/explode() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 9b012b32b8c..df605dd7d09 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -48,7 +48,7 @@ Stealth and Camouflage Items; /obj/item/weapon/stamperaser:1:Stamp Remover; Whitespace:Seperator; Devices and Tools; -/obj/item/weapon/card/emag:5:Cryptographic Sequencer (Limited uses, almost full access); +/obj/item/weapon/card/emag:4:Cryptographic Sequencer (Limited uses, almost full access); /obj/item/device/hacktool:3:Hacktool (Slow, but stealthy. Unlimited uses); /obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox; /obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module; diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 914cb684b57..920351ba8cf 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -537,6 +537,9 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. if (!src.canSynControl() && src.canSynHack(C)) src.synhack(user, C) return + if(!src.canSynHack(C)) + user << "The power is cut or something, I can't hack it!" + return if(istype(C, /obj/item/device/hacktool/engineer)) return else @@ -692,19 +695,19 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. synhack(mob/user as mob, obj/item/device/hacktool/I) if (src.synHacking==0) - var/multiplier = 1 - if(istype(C, /obj/item/device/hacktool/engineer)) + var/multiplier = 1.5 + if(istype(I, /obj/item/device/hacktool/engineer)) if(!src.locked) user << "The door bolts are already up!" return - multiplier++ + multiplier -= 0.5 src.synHacking=1 I.in_use = 1 user << "You begin hacking..." spawn(20*multiplier) user << "Jacking in. Stay close to the airlock or you'll rip the cables out and we'll have to start over." sleep(25*multiplier) - if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) + if (src.canSynControl() && !istype(I, /obj/item/device/hacktool/engineer)) user << "Hack cancelled, control already possible." src.synHacking=0 I.in_use = 0 @@ -723,7 +726,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. var/list/cameras = list() for (var/obj/machinery/camera/C in src.loc.loc.contents) // getting all cameras in the area cameras += C - var/alertoption = (prob(alert_probability) || istype(C, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability + var/alertoption = (prob(alert_probability) || istype(I, /obj/item/device/hacktool/engineer)) // Chance of warning AI, based on doortype's probability if(alertoption) if(prob(15)) //15% chance of sending the AI all the details (camera, area, warning) alertoption = 3 @@ -747,7 +750,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. src.synHacking=0 I.in_use = 0 return - else if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) + else if (src.canSynControl() && !istype(I, /obj/item/device/hacktool/engineer)) user << "Local override already in place, hack aborted." src.synHacking=0 I.in_use = 0 @@ -759,7 +762,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. src.synHacking=0 I.in_use = 0 return - else if (src.canSynControl() && !istype(C, /obj/item/device/hacktool/engineer)) + else if (src.canSynControl() && !istype(I, /obj/item/device/hacktool/engineer)) user << "Upload access aborted, local override already in place." src.synHacking=0 I.in_use = 0 @@ -767,9 +770,11 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. user << "Transfer complete. Forcing airlock to execute program." sleep(25*multiplier) //disable blocked control - if(istype(C, /obj/item/device/hacktool/engineer)) + if(istype(I, /obj/item/device/hacktool/engineer)) user << "Raising door bolts..." + src.synHacking = 0 src.locked = 0 + I.in_use = 0 update_icon() return src.synDoorHacked = 1 @@ -1272,6 +1277,7 @@ About the new airlock wires panel: list/IndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) list/WireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) is_detached = 0 + removal_step = 0 @@ -1483,36 +1489,208 @@ About the new airlock wires panel: //world << text("airlock attackby src [] obj [] mob []", src, C, user) if(istype(C, /obj/item/device/detective_scanner)) return - if(!src.is_detached) + if(!src.is_detached && C) if (!istype(usr, /mob/living/silicon)) if (src.isElectrified()) if(src.shock(user, 75)) return - - src.add_fingerprint(user) - if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 - src.update_icon() - return - else - return - else if (istype(C, /obj/item/device/hacktool)) + if (istype(C, /obj/item/device/hacktool)) return src.attack_ai(user, C) - else if (istype(C, /obj/item/weapon/wrench)) - user << "You start to remove the armor plate..." - if(do_after(user,30)) - user << "Armor plates removed" - src.is_detached = 1 + src.add_fingerprint(user) + switch(removal_step) + if(0) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && 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 + src.update_icon() + return + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start to remove the bolts..." + if(do_after(user,30)) + user << "Bolts removed" + src.removal_step = 1 + if(1) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(0,user)) + user << "You start to slice the armor..." + if(do_after(user,20)) + user << "Armor sliced open" + src.removal_step = 2 + return + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start wrench down the bolts..." + if(do_after(user,30)) + user << "Bolts secured." + src.removal_step = 0 + if(2) + if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(0,user)) + user << "You start to fuse together the armor..." + if(do_after(user,20)) + user << "Armor repaired" + src.removal_step = 1 + return + else if (istype(C, /obj/item/weapon/wrench)) + user << "You start to unfasted the armor from the circuits..." + if(do_after(user,40)) + user << "Circuits exposed." + src.removal_step = 3 + src.is_detached = 1 else if (istype(C, /obj/item/weapon/wrench)) - user << "You start to reattach the armor plate..." - if(do_after(user,30)) - user << "Armor plates attached" + user << "You start to fix the armor plate..." + if(do_after(user,40)) + user << "Armor plates are back in position." src.is_detached = 0 + src.removal_step = 2 else - return ..(C, user) \ No newline at end of file + return ..(C, user) + + centcom + name = "CentCom Secure Airlock" + desc = "I hope you have insulated gloves...." + icon = 'Doorhatchele.dmi' + + pulse(var/wireColor) + if (src.secondsElectrified==0) + src.secondsElectrified = 10 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 +// src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + var/wireIndex = WireColorToIndex[wireColor] + switch(wireIndex) + if(AIRLOCK_WIRE_IDSCAN) + //Sending a pulse through this flashes the red light on the door (if the door has power). + if ((src.arePowerSystemsOn()) && (!(stat & NOPOWER))) + animate("deny") + if (AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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). + src.loseMainPower() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + else + if(src.arePowerSystemsOn()) //only can raise bolts if power's on + src.locked = 0 + usr << "You hear a click from inside the door." + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //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). + src.loseBackupPower() + if (AIRLOCK_WIRE_AI_CONTROL) + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateDialog() + spawn(10) + if (src.aiControlDisabled == 1) + src.aiControlDisabled = 0 + else if (src.aiControlDisabled == 2) + src.aiControlDisabled = -1 + src.updateDialog() + if(AIRLOCK_WIRE_OPEN_DOOR) + //tries to open the door without ID + //will succeed only if the ID wire is cut or the door requires no access + if (!src.requiresID() || src.check_access(null)) + if (src.density) + open() + else + close() + if(AIRLOCK_WIRE_CRUSH) + src.forcecrush = !src.forcecrush + if(AIRLOCK_WIRE_LIGHT) + src.safetylight = !src.safetylight + if(AIRLOCK_WIRE_HOLDOPEN) + src.holdopen = !src.holdopen + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + + cut(var/wireColor) + if (src.secondsElectrified==0) + src.secondsElectrified = 30 + spawn(10) + //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 + while (src.secondsElectrified>0) + src.secondsElectrified-=1 + if (src.secondsElectrified<0) + src.secondsElectrified = 0 +// src.updateUsrDialog() //Commented this line out to keep the airlock from clusterfucking you with electricity. --NeoFite + sleep(10) + var/wireFlag = WireColorToFlag[wireColor] + var/wireIndex = WireColorToIndex[wireColor] + wires &= ~wireFlag + switch(wireIndex) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) + //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 crowbarred open, but bolts-raising will not work. Cutting these wires may electocute the user. + src.loseMainPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_DOOR_BOLTS, AIRLOCK_WIRE_DOOR_BOLTS_2) + //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) + if (src.locked!=1) + src.locked = 1 + update_icon() + src.updateUsrDialog() + if (AIRLOCK_WIRE_FAKEBOLT1, AIRLOCK_WIRE_FAKEBOLT2) + //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), + //raises them if they are down (only if power's on) + if (!src.locked) + src.locked = 1 + src.updateUsrDialog() + update_icon() + if (AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) + //Cutting either one disables the backup door power (allowing it to be crowbarred open, but disabling bolts-raising), but may electocute the user. + src.loseBackupPower() + src.shock(usr, 50) + src.updateUsrDialog() + if (AIRLOCK_WIRE_AI_CONTROL) + //one wire for AI control. 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. + //aiControlDisabled: 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. + if (src.aiControlDisabled == 0) + src.aiControlDisabled = 1 + else if (src.aiControlDisabled == -1) + src.aiControlDisabled = 2 + src.updateUsrDialog() + if (AIRLOCK_WIRE_ELECTRIFY) + //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. + if (src.secondsElectrified != -1) + src.secondsElectrified = -1 + if(AIRLOCK_WIRE_ALERTAI) + if(prob(alert_probability)) + for (var/mob/living/silicon/ai/aiPlayer in world) + if (aiPlayer.stat != 2) + aiPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) + for (var/mob/living/silicon/robot/robotPlayer in world) + if (robotPlayer.stat != 2) + robotPlayer.triggerUnmarkedAlarm("AirlockHacking", src.loc.loc) \ No newline at end of file diff --git a/code/game/objects/closets/secure/engineering.dm b/code/game/objects/closets/secure/engineering.dm index f5bb2fefd07..516d6b35fb1 100644 --- a/code/game/objects/closets/secure/engineering.dm +++ b/code/game/objects/closets/secure/engineering.dm @@ -9,6 +9,7 @@ new /obj/item/wardrobe/chief_engineer(src) new /obj/item/wardrobe/chief_engineer(src) new /obj/item/blueprints(src) + new /obj/item/device/hacktool/engineer(src) return diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 83ec575d265..37d1370d4ae 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -24,7 +24,7 @@ FINGERPRINT CARD New() ..() - uses = rand(3,7) + uses = rand(3,5) return // DATA CARDS