diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 3c66cdca92..0bedcfa588 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -106,9 +106,9 @@
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
if(density)
- Topic(src, list("src"= "\ref[src]", "aiEnable"="7"), 1) // 1 meaning no window (consistency!)
+ Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!)
else
- Topic(src, list("src"= "\ref[src]", "aiDisable"="7"), 1)
+ Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "0"), 1)
return
/atom/proc/AICtrlClick()
@@ -116,9 +116,9 @@
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(locked)
- Topic(src, list("src"= "\ref[src]", "aiEnable"="4"), 1)// 1 meaning no window (consistency!)
+ Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!)
else
- Topic(src, list("src"= "\ref[src]", "aiDisable"="4"), 1)
+ Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "1"), 1)
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
Topic(src, list("src"= "\ref[src]", "breaker"="1"), 1) // 1 meaning no window (consistency!)
@@ -130,12 +130,12 @@
AltClick(A)
/obj/machinery/door/airlock/AIAltClick() // Electrifies doors.
- if(!secondsElectrified)
+ if(!electrified_until)
// permanent shock
- Topic(src, list("src"= "\ref[src]", "aiEnable"="6"), 1) // 1 meaning no window (consistency!)
+ Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "1"), 1) // 1 meaning no window (consistency!)
else
// disable/6 is not in Topic; disable/5 disables both temporary and permanent shock
- Topic(src, list("src"= "\ref[src]", "aiDisable"="5"), 1)
+ Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "0"), 1)
return
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
@@ -146,9 +146,9 @@
/obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights.
if(!src.lights)
- Topic(src, list("src"= "\ref[src]", "aiEnable"="10"), 1) // 1 meaning no window (consistency!)
+ Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!)
else
- Topic(src, list("src"= "\ref[src]", "aiDisable"="10"), 1)
+ Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "0"), 1)
return
//
diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm
index 48ba2c633c..49d9bb0924 100644
--- a/code/datums/spells/knock.dm
+++ b/code/datums/spells/knock.dm
@@ -14,6 +14,7 @@
for(var/obj/machinery/door/door in T.contents)
spawn(1)
if(istype(door,/obj/machinery/door/airlock))
- door:unlock(1) //forced because it's magic!
+ var/obj/machinery/door/airlock/A = door
+ A.unlock(1) //forced because it's magic!
door.open()
- return
\ No newline at end of file
+ return
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index f8b796269f..7e8c8779cf 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -35,9 +35,9 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
/datum/wires/airlock/GetInteractWindow()
var/obj/machinery/door/airlock/A = holder
var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on.
-
+
. += ..()
- . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]",
+ . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]",
(A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"),
((haspower) ? "The test light is on." : "The test light is off!"),
@@ -59,9 +59,8 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
A.loseMainPower()
A.shock(usr, 50)
else
- if((!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER2)))
- A.regainMainPower()
- A.shock(usr, 50)
+ A.regainMainPower()
+ A.shock(usr, 50)
if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2)
@@ -70,16 +69,14 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
A.loseBackupPower()
A.shock(usr, 50)
else
- if((!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER2)))
- A.regainBackupPower()
- A.shock(usr, 50)
+ A.regainBackupPower()
+ A.shock(usr, 50)
if(AIRLOCK_WIRE_DOOR_BOLTS)
if(!mended)
//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(A.locked!=1)
- A.locked = 1
+ A.lock(1)
A.update_icon()
if(AIRLOCK_WIRE_AI_CONTROL)
@@ -98,16 +95,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
A.aiControlDisabled = -1
if(AIRLOCK_WIRE_ELECTRIFY)
-
if(!mended)
//Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted.
- if(A.secondsElectrified != -1)
- A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
- add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]")
- A.secondsElectrified = -1
+ A.electrify(-1)
else
- if(A.secondsElectrified == -1)
- A.secondsElectrified = 0
+ A.electrify(0)
return // Don't update the dialog.
if (AIRLOCK_WIRE_SAFETY)
@@ -139,13 +131,9 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
//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(!A.locked)
- A.locked = 1
- A.audible_message("You hear a click from the bottom of the door.", null, 1)
+ A.lock()
else
- if(A.arePowerSystemsOn()) //only can raise bolts if power's on
- A.locked = 0
- A.audible_message("You hear a click from the bottom of the door.", null, 1)
- A.update_icon()
+ A.unlock()
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).
@@ -165,19 +153,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
if(AIRLOCK_WIRE_ELECTRIFY)
//one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds.
- if(A.secondsElectrified==0)
- A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
- add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]")
- A.secondsElectrified = 30
- spawn(10)
- if(A)
- //TODO: Move this into process() and make pulsing reset secondsElectrified to 30
- while (A.secondsElectrified>0)
- A.secondsElectrified-=1
- if(A.secondsElectrified<0)
- A.secondsElectrified = 0
- sleep(10)
- return
+ A.electrify(30)
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 and it's not emagged
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 51bc9b69e6..8942f8434e 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -81,17 +81,16 @@
if(specialfunctions & BOLTS)
D.lock()
if(specialfunctions & SHOCK)
- D.secondsElectrified = -1
+ D.electrify(-1)
if(specialfunctions & SAFE)
D.safe = 0
else
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 0
if(specialfunctions & BOLTS)
- if(!D.isWireCut(4) && D.arePowerSystemsOn())
- D.unlock()
+ D.unlock()
if(specialfunctions & SHOCK)
- D.secondsElectrified = 0
+ D.electrify(0)
if(specialfunctions & SAFE)
D.safe = 1
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index a548739960..366a5f6ffa 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -7,13 +7,13 @@
explosion_resistance = 15
var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
var/hackProof = 0 // if 1, this door can't be hacked by the AI
- var/secondsMainPowerLost = 0 //The number of seconds until power is restored.
- var/secondsBackupPowerLost = 0 //The number of seconds until power is restored.
+ var/electrified_until = 0 // World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it.
+ var/main_power_lost_until = 0 //World time when main power is restored.
+ var/backup_power_lost_until = -1 //World time when backup power is restored.
var/spawnPowerRestoreRunning = 0
var/welded = null
var/locked = 0
var/lights = 1 // bolt lights show by default
- 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
@@ -217,6 +217,17 @@
mineral = "uranium"
var/last_event = 0
+/obj/machinery/door/airlock/process()
+ // Deliberate no call to parent.
+ if(main_power_lost_until > 0 && world.time >= main_power_lost_until)
+ regainMainPower()
+
+ if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until)
+ regainBackupPower()
+
+ else if(electrified_until > 0 && world.time >= electrified_until)
+ electrify(0)
+
/obj/machinery/door/airlock/uranium/process()
if(world.time > last_event+20)
if(prob(50))
@@ -319,7 +330,7 @@ About the new airlock wires panel:
..(user)
/obj/machinery/door/airlock/proc/isElectrified()
- if(src.secondsElectrified != 0)
+ if(src.electrified_until != 0)
return 1
return 0
@@ -336,7 +347,7 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/arePowerSystemsOn()
if (stat & (NOPOWER|BROKEN))
return 0
- return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0)
+ return (src.main_power_lost_until==0 || src.backup_power_lost_until==0)
/obj/machinery/door/airlock/requiresID()
return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner)
@@ -344,48 +355,68 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/isAllPowerLoss()
if(stat & (NOPOWER|BROKEN))
return 1
- 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))
- return 1
+ if(mainPowerCablesCut() && backupPowerCablesCut())
+ return 1
return 0
-/obj/machinery/door/airlock/proc/regainMainPower()
- if(src.secondsMainPowerLost > 0)
- src.secondsMainPowerLost = 0
+/obj/machinery/door/airlock/proc/mainPowerCablesCut()
+ return src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)
+
+/obj/machinery/door/airlock/proc/backupPowerCablesCut()
+ return src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)
/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)
- if((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)))
- src.secondsMainPowerLost -= 1
- src.updateDialog()
- cont = 1
+ main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
- 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()
+ // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running
+ if(backup_power_lost_until == -1 && !backupPowerCablesCut())
+ backup_power_lost_until = world.time + SecondsToTicks(10)
+
+ // Disable electricity if required
+ if(electrified_until && isAllPowerLoss())
+ electrify(0)
/obj/machinery/door/airlock/proc/loseBackupPower()
- if(src.secondsBackupPowerLost < 60)
- src.secondsBackupPowerLost = 60
+ backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60)
+
+ // Disable electricity if required
+ if(electrified_until && isAllPowerLoss())
+ electrify(0)
+
+/obj/machinery/door/airlock/proc/regainMainPower()
+ if(!mainPowerCablesCut())
+ main_power_lost_until = 0
+ // If backup power is currently active then disable, otherwise let it count down and disable itself later
+ if(!backup_power_lost_until)
+ backup_power_lost_until = -1
/obj/machinery/door/airlock/proc/regainBackupPower()
- if(src.secondsBackupPowerLost > 0)
- src.secondsBackupPowerLost = 0
+ if(!backupPowerCablesCut())
+ // Restore backup power only if main power is offline, otherwise permanently disable
+ backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0
+
+/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0)
+ var/message = ""
+ if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY) && arePowerSystemsOn())
+ message = text("The electrification wire is cut - Door permanently electrified.")
+ src.electrified_until = -1
+ else if(duration && !arePowerSystemsOn())
+ message = text("The door is unpowered - Cannot electrify the door.")
+ src.electrified_until = 0
+ else if(!duration && electrified_until != 0)
+ message = "The door is now un-electrified."
+ src.electrified_until = 0
+ else if(duration) //electrify door for the given duration seconds
+ if(usr)
+ shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])")
+ usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]")
+ else
+ shockedby += text("\[[time_stamp()]\] - EMP)")
+ message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]."
+ src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration)
+
+ if(feedback && message)
+ usr << message
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
@@ -460,111 +491,32 @@ About the new airlock wires panel:
return
/obj/machinery/door/airlock/attack_ai(mob/user as mob)
- if (!check_synth_access(user))
- return
+ ui_interact(user)
- //Separate interface for the AI.
- user.set_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.")
+/obj/machinery/door/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
- 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"
+ data["main_power_loss"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1)
+ data["backup_power_loss"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1)
+ data["electrified"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1)
+ data["open"] = !density
- 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)
+ var/commands[0]
+ commands[++commands.len] = list("name" = "IdScan", "command"= "idscan", "active" = !aiDisabledIdScanner, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1)
+ commands[++commands.len] = list("name" = "Bolts", "command"= "bolts", "active" = !locked, "enabled" = "Raised ", "disabled" = "Dropped", "danger" = 0, "act" = 0)
+ commands[++commands.len] = list("name" = "Bolt Lights", "command"= "lights", "active" = lights, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1)
+ commands[++commands.len] = list("name" = "Safeties", "command"= "safeties", "active" = safe, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0)
+ commands[++commands.len] = list("name" = "Timing", "command"= "timing", "active" = normalspeed, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0)
+ commands[++commands.len] = list("name" = "Door State", "command"= "open", "active" = density, "enabled" = "Closed", "disabled" = "Opened", "danger" = 0, "act" = 0)
- 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_DOOR_BOLTS))
- t1 += text("Door bolt control 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_LIGHT))
- t1 += text("Door bolt lights wire is cut.
\n")
- else if(!src.lights)
- t1 += text("Door lights are off. Enable?
\n", src)
- else
- t1 += text("Door lights are on. Disable?
\n", src)
-
- 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_SAFETY))
- t1 += text("Door force sensors not responding.
\n")
- else if(src.safe)
- t1 += text("Door safeties operating normally. Override?
\n",src)
- else
- t1 += text("Danger. Door safeties disabled. Restore?
\n",src)
-
- if(src.isWireCut(AIRLOCK_WIRE_SPEED))
- t1 += text("Door timing circuitry not responding.
\n")
- else if(src.normalspeed)
- t1 += text("Door timing circuitry operating normally. Override?
\n",src)
- else
- t1 += text("Warning. Door timing circuitry operating abnormally. Restore?
\n",src)
-
-
-
-
- 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("
| {{:value.name}}: | +{{:helper.link(value.enabled, null, {'command' : value.command, 'activate' : value.act ? 1 : 0}, null, value.active ? 'selected' : null)}} | +{{:helper.link(value.disabled,null, {'command' : value.command, 'activate' : value.act ? 0 : 1}, null,!value.active ? (value.danger ? 'redButton' : 'selected') : null)}} | +