diff --git a/baystation12.dme b/baystation12.dme index 3d325141d4..c98d894638 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 40cb84a6d1..1105c84947 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 22c7cbf9d3..5337a4f6f2 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 5380d82f33..e9500a0f6c 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 b2860af20c..20425c7896 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 83ba4e215d..7b58c68f7a 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 7e72529084..4fa1630dd5 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 1efcc9af70..3114f537e3 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 9027ed0023..ce3adee94f 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 57b87ae93f..b2e1f3f557 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 f05d34a3fd..a1043334fd 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 f7535887f9..65a75a0b56 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 0a697d414c..fe46d91232 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 d91c2b56bc..76280d6b56 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 09abb12e1a..987406df37 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 7949cbae65..6726520c80 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 6d939c6016..03665dda37 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 670673179f..a7ee7e827e 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 ab73e09e80..4feca37b7a 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 7c9942f3ae..348b64470b 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 c3d09c48bc..16726cc7ef 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 1923e0cf84..f971a61c63 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 cea7e6e2e9..0aea34dcdb 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 f9e605d55a..22d53ef572 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 5a9defccdc..9458f05a85 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 c111c52acd..af16542f58 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 49b9d3b3fd..d3cba8ecfc 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 dd01888d03..8fa447c9ae 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 e3d27b1256..b9e0187786 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 79157b40fa..35fc955cd2 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 62331f8276..2794e49889 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 c691bd5326..8494727395 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 930877d441..98d3eb1e8f 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 2ad21eb5cd..dd5f262e99 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 fa6178bdee..6dd2fcdb4c 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 e898808c66..8467ab99ff 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"