diff --git a/baystation12.dme b/baystation12.dme
index 806edf91683..25420c0bc8e 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -335,7 +335,6 @@
#include "code\game\jobs\job_objectives\science.dm"
#include "code\game\machinery\adv_med.dm"
#include "code\game\machinery\ai_slipper.dm"
-#include "code\game\machinery\airlock_control.dm"
#include "code\game\machinery\alarm.dm"
#include "code\game\machinery\atmo_control.dm"
#include "code\game\machinery\autolathe.dm"
@@ -446,6 +445,7 @@
#include "code\game\machinery\computer\telescience.dm"
#include "code\game\machinery\computer\xenos_shuttle.dm"
#include "code\game\machinery\doors\airlock.dm"
+#include "code\game\machinery\doors\airlock_control.dm"
#include "code\game\machinery\doors\airlock_electronics.dm"
#include "code\game\machinery\doors\alarmlock.dm"
#include "code\game\machinery\doors\brigdoors.dm"
diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm
index f889a37e17e..e0d2b8626d0 100644
--- a/code/controllers/shuttle_controller.dm
+++ b/code/controllers/shuttle_controller.dm
@@ -11,10 +11,10 @@
var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
-datum/shuttle_controller
+datum/shuttle_controller/emergency_shuttle
var/alert = 0 //0 = emergency, 1 = crew cycle
- var/location = 0 //0 = somewhere far away (in spess), 1 = at SS13, 2 = returned from SS13
+ location = 0 //0 = somewhere far away (in spess), 1 = at SS13, 2 = returned from SS13
var/online = 0
var/direction = 1 //-1 = going back to central command, 1 = going to SS13, 2 = in transit to centcom (not recalled)
@@ -52,10 +52,10 @@ datum/shuttle_controller
return SHUTTLEARRIVETIME
-datum/shuttle_controller/proc/shuttlealert(var/X)
+datum/shuttle_controller/emergency_shuttle/proc/shuttlealert(var/X)
alert = X
-datum/shuttle_controller/proc/recall()
+datum/shuttle_controller/emergency_shuttle/proc/recall()
if(direction == 1)
var/timeleft = timeleft()
if(alert == 0)
@@ -78,7 +78,7 @@ datum/shuttle_controller/proc/recall()
// returns the time (in seconds) before shuttle arrival
// note if direction = -1, gives a count-up to SHUTTLEARRIVETIME
-datum/shuttle_controller/proc/timeleft()
+datum/shuttle_controller/emergency_shuttle/proc/timeleft()
if(online)
var/timeleft = round((endtime - world.timeofday)/10 ,1)
if(direction == 1 || direction == 2)
@@ -89,13 +89,13 @@ datum/shuttle_controller/proc/timeleft()
return get_shuttle_arrive_time()
// sets the time left to a given delay (in seconds)
-datum/shuttle_controller/proc/settimeleft(var/delay)
+datum/shuttle_controller/emergency_shuttle/proc/settimeleft(var/delay)
endtime = world.timeofday + delay * 10
timelimit = delay
// sets the shuttle direction
// 1 = towards SS13, -1 = back to centcom
-datum/shuttle_controller/proc/setdirection(var/dirn)
+datum/shuttle_controller/emergency_shuttle/proc/setdirection(var/dirn)
if(direction == dirn)
return
direction = dirn
@@ -104,7 +104,7 @@ datum/shuttle_controller/proc/setdirection(var/dirn)
endtime = world.timeofday + (get_shuttle_arrive_time()*10 - ticksleft)
return
-datum/shuttle_controller/proc/process()
+datum/shuttle_controller/emergency_shuttle/proc/process()
datum/shuttle_controller/emergency_shuttle/process()
if(!online)
diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm
index 9fbb8e571b5..ccca6237877 100644
--- a/code/datums/spells/knock.dm
+++ b/code/datums/spells/knock.dm
@@ -17,6 +17,6 @@
if(istype(door,/obj/machinery/door/airlock/hatch/gamma))
return
if(istype(door,/obj/machinery/door/airlock))
- door:locked = 0
+ door:unlock(1) //forced because it's magic!
door.open()
return
\ No newline at end of file
diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm
index a64525f4c64..c46e325dd71 100644
--- a/code/game/gamemodes/mutiny/mutiny.dm
+++ b/code/game/gamemodes/mutiny/mutiny.dm
@@ -159,7 +159,7 @@ datum/game_mode/mutiny
proc/unbolt_vault_door()
var/obj/machinery/door/airlock/vault = locate(/obj/machinery/door/airlock/vault)
- vault.locked = 0
+ vault.lock()
proc/make_secret_transcript()
var/obj/machinery/computer/telecomms/server/S = locate(/obj/machinery/computer/telecomms/server)
diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm
index 63251c2b688..2dcb0c0b2e0 100644
--- a/code/game/machinery/door_control.dm
+++ b/code/game/machinery/door_control.dm
@@ -93,8 +93,7 @@
if(specialfunctions & IDSCAN)
D.aiDisabledIdScanner = 1
if(specialfunctions & BOLTS)
- D.locked = 1
- D.update_icon()
+ D.lock()
if(specialfunctions & SHOCK)
D.secondsElectrified = -1
if(specialfunctions & SAFE)
@@ -104,8 +103,7 @@
D.aiDisabledIdScanner = 0
if(specialfunctions & BOLTS)
if(!D.isWireCut(4) && D.arePowerSystemsOn())
- D.locked = 0
- D.update_icon()
+ D.unlock()
if(specialfunctions & SHOCK)
D.secondsElectrified = 0
if(specialfunctions & SAFE)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 6d53efc796d..f020ffc9b16 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -325,6 +325,165 @@ About the new airlock wires panel:
..(user)
+/*
+/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)))
+ do_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.lock()
+ else
+ src.unlock()
+ src.updateUsrDialog()
+
+ 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)
+ shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
+ usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]")
+ 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(density) open()
+ else close()
+ if(AIRLOCK_WIRE_SAFETY)
+ safe = !safe
+ if(!src.density)
+ close()
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_SPEED)
+ normalspeed = !normalspeed
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_LIGHT)
+ lights = !lights
+ src.updateUsrDialog()
+
+
+/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)
+ src.lock()
+ 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)
+ shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
+ usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]")
+ src.secondsElectrified = -1
+ if (AIRLOCK_WIRE_SAFETY)
+ safe = 0
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_SPEED)
+ autoclose = 0
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_LIGHT)
+ lights = 0
+ src.updateUsrDialog()
+
+/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
+
+ if (AIRLOCK_WIRE_SAFETY)
+ safe = 1
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_SPEED)
+ autoclose = 1
+ if(!src.density)
+ close()
+ src.updateUsrDialog()
+
+ if(AIRLOCK_WIRE_LIGHT)
+ lights = 1
+ src.updateUsrDialog()
+
+*/
+
/obj/machinery/door/airlock/proc/isElectrified()
if(src.secondsElectrified != 0)
return 1
@@ -507,7 +666,7 @@ About the new airlock wires panel:
t1 += text("Backup Power Output wire is cut.
\n")
if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
- t1 += text("Door bolt drop wire is cut.
\n")
+ t1 += text("Door bolt control wire is cut.
\n")
else if(!src.locked)
t1 += text("Door bolts are up. Drop them?
\n", src)
else
@@ -816,15 +975,11 @@ About the new airlock wires panel:
if(4)
//raise door bolts
if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS))
- usr << text("The door bolt drop wire is cut - you can't raise the door bolts.
\n")
+ usr << text("The door bolt control wire is cut - you can't raise the door bolts.
\n")
else if(!src.locked)
usr << text("The door bolts are already up.
\n")
else
- if(src.arePowerSystemsOn())
- src.locked = 0
- update_icon()
- else
- usr << text("Cannot raise door bolts due to power failure.
\n")
+ src.unlock()
if(5)
//electrify door for 30 seconds
@@ -1089,6 +1244,23 @@ About the new airlock wires panel:
..()
return
+/obj/machinery/door/airlock/proc/lock(var/forced=0)
+ if (src.locked) return
+
+ src.locked = 1
+ for(var/mob/M in range(1,src))
+ M.show_message("You hear a click from the bottom of the door.", 2)
+ update_icon()
+
+/obj/machinery/door/airlock/proc/unlock(var/forced=0)
+ if (!src.locked) return
+
+ if(forced || src.arePowerSystemsOn()) //only can raise bolts if power's on
+ src.locked = 0
+ for(var/mob/M in range(1,src))
+ M.show_message("You hear a click from the bottom of the door.", 2)
+ update_icon()
+
/obj/machinery/door/airlock/New()
..()
wires = new(src)
@@ -1104,7 +1276,7 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/proc/prison_open()
- src.locked = 0
+ src.unlock()
src.open()
src.locked = 1
return
@@ -1165,4 +1337,4 @@ About the new airlock wires panel:
src.update_icon()
return
else
- return
+ return
\ No newline at end of file
diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm
similarity index 88%
rename from code/game/machinery/airlock_control.dm
rename to code/game/machinery/doors/airlock_control.dm
index 02cc0222cfe..b46fd04a4bc 100644
--- a/code/game/machinery/airlock_control.dm
+++ b/code/game/machinery/doors/airlock_control.dm
@@ -1,242 +1,259 @@
-#define AIRLOCK_CONTROL_RANGE 5
-
-// This code allows for airlocks to be controlled externally by setting an id_tag and comm frequency (disables ID access)
-obj/machinery/door/airlock
- var/id_tag
- var/frequency
- var/shockedby = list()
- var/datum/radio_frequency/radio_connection
- explosion_resistance = 15
-
-
-obj/machinery/door/airlock/receive_signal(datum/signal/signal)
- if(!signal || signal.encryption) return
-
- if(id_tag != signal.data["tag"] || !signal.data["command"]) return
-
- switch(signal.data["command"])
- if("open")
- open(1)
-
- if("close")
- close(1)
-
- if("unlock")
- locked = 0
- update_icon()
-
- if("lock")
- locked = 1
- update_icon()
-
- if("secure_open")
- locked = 0
- update_icon()
-
- sleep(2)
- open(1)
-
- locked = 1
- update_icon()
-
- if("secure_close")
- locked = 0
- close(1)
-
- locked = 1
- sleep(2)
- update_icon()
-
- send_status()
-
-
-obj/machinery/door/airlock/proc/send_status()
- if(radio_connection)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = id_tag
- signal.data["timestamp"] = world.time
-
- signal.data["door_status"] = density?("closed"):("open")
- signal.data["lock_status"] = locked?("locked"):("unlocked")
-
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
-
-
-obj/machinery/door/airlock/open(surpress_send)
- . = ..()
- if(!surpress_send) send_status()
-
-
-obj/machinery/door/airlock/close(surpress_send)
- . = ..()
- if(!surpress_send) send_status()
-
-
-obj/machinery/door/airlock/Bumped(atom/AM)
- ..(AM)
- if(istype(AM, /obj/mecha))
- var/obj/mecha/mecha = AM
- if(density && radio_connection && mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = id_tag
- signal.data["timestamp"] = world.time
-
- signal.data["door_status"] = density?("closed"):("open")
- signal.data["lock_status"] = locked?("locked"):("unlocked")
-
- signal.data["bumped_with_access"] = 1
-
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
- return
-
-obj/machinery/door/airlock/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- if(new_frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-
-
-obj/machinery/door/airlock/initialize()
- if(frequency)
- set_frequency(frequency)
-
- update_icon()
-
-
-obj/machinery/door/airlock/New()
- ..()
-
- if(radio_controller)
- set_frequency(frequency)
-
-
-
-
-obj/machinery/airlock_sensor
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "airlock_sensor_off"
- name = "airlock sensor"
-
- anchored = 1
- power_channel = ENVIRON
-
- var/id_tag
- var/master_tag
- var/frequency = 1449
-
- var/datum/radio_frequency/radio_connection
-
- var/on = 1
- var/alert = 0
- var/previousPressure
-
-obj/machinery/airlock_sensor/update_icon()
- if(on)
- if(alert)
- icon_state = "airlock_sensor_alert"
- else
- icon_state = "airlock_sensor_standby"
- else
- icon_state = "airlock_sensor_off"
-
-obj/machinery/airlock_sensor/attack_hand(mob/user)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = master_tag
- signal.data["command"] = "cycle"
-
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
- flick("airlock_sensor_cycle", src)
-
-obj/machinery/airlock_sensor/process()
- if(on)
- var/datum/gas_mixture/air_sample = return_air()
- var/pressure = round(air_sample.return_pressure(),0.1)
-
- if(abs(pressure - previousPressure) > 0.001 || previousPressure == null)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = id_tag
- signal.data["timestamp"] = world.time
- signal.data["pressure"] = num2text(pressure)
-
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
-
- previousPressure = pressure
-
- alert = (pressure < ONE_ATMOSPHERE*0.8)
-
- update_icon()
-
-obj/machinery/airlock_sensor/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-
-obj/machinery/airlock_sensor/initialize()
- set_frequency(frequency)
-
-obj/machinery/airlock_sensor/New()
- ..()
- if(radio_controller)
- set_frequency(frequency)
-
-
-
-
-obj/machinery/access_button
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "access_button_standby"
- name = "access button"
-
- anchored = 1
- power_channel = ENVIRON
-
- var/master_tag
- var/frequency = 1449
- var/command = "cycle"
-
- var/datum/radio_frequency/radio_connection
-
- var/on = 1
-
-
-obj/machinery/access_button/update_icon()
- if(on)
- icon_state = "access_button_standby"
- else
- icon_state = "access_button_off"
-
-
-obj/machinery/access_button/attack_hand(mob/user)
- add_fingerprint(usr)
- if(!allowed(user))
- user << "\red Access Denied"
-
- else if(radio_connection)
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data["tag"] = master_tag
- signal.data["command"] = command
-
- radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
- flick("access_button_cycle", src)
-
-
-obj/machinery/access_button/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
-
-
-obj/machinery/access_button/initialize()
- set_frequency(frequency)
-
-
-obj/machinery/access_button/New()
- ..()
-
- if(radio_controller)
+#define AIRLOCK_CONTROL_RANGE 5
+
+// This code allows for airlocks to be controlled externally by setting an id_tag and comm frequency (disables ID access)
+obj/machinery/door/airlock
+ var/id_tag
+ var/frequency
+ var/shockedby = list()
+ var/datum/radio_frequency/radio_connection
+ explosion_resistance = 15
+
+obj/machinery/door/airlock/proc/can_radio()
+ if( !arePowerSystemsOn() || (stat & NOPOWER) || isWireCut(AIRLOCK_WIRE_AI_CONTROL) )
+ return 0
+ return 1
+
+
+obj/machinery/door/airlock/receive_signal(datum/signal/signal)
+ if (!can_radio()) return
+
+ if(!signal || signal.encryption) return
+
+ if(id_tag != signal.data["tag"] || !signal.data["command"]) return
+
+ switch(signal.data["command"])
+ if("open")
+ open()
+
+ if("close")
+ close()
+
+ if("unlock")
+ unlock()
+
+ if("lock")
+ lock()
+
+ if("secure_open")
+ unlock()
+
+ sleep(2)
+ open()
+
+ lock()
+
+ if("secure_close")
+ unlock()
+ close()
+
+ lock()
+ sleep(2)
+
+ send_status()
+
+
+obj/machinery/door/airlock/proc/send_status()
+ if (!can_radio()) return
+
+ if(radio_connection)
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = id_tag
+ signal.data["timestamp"] = world.time
+
+ signal.data["door_status"] = density?("closed"):("open")
+ signal.data["lock_status"] = locked?("locked"):("unlocked")
+
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+
+
+obj/machinery/door/airlock/open(surpress_send)
+ . = ..()
+ if(!surpress_send) send_status()
+
+
+obj/machinery/door/airlock/close(surpress_send)
+ . = ..()
+ if(!surpress_send) send_status()
+
+
+obj/machinery/door/airlock/Bumped(atom/AM)
+ ..(AM)
+ if(istype(AM, /obj/mecha))
+ var/obj/mecha/mecha = AM
+ if(density && radio_connection && mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = id_tag
+ signal.data["timestamp"] = world.time
+
+ signal.data["door_status"] = density?("closed"):("open")
+ signal.data["lock_status"] = locked?("locked"):("unlocked")
+
+ signal.data["bumped_with_access"] = 1
+
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+ return
+
+obj/machinery/door/airlock/proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ if(new_frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
+
+
+obj/machinery/door/airlock/initialize()
+ if(frequency)
set_frequency(frequency)
+
+ update_icon()
+
+
+obj/machinery/door/airlock/New()
+ ..()
+
+ if(radio_controller)
+ set_frequency(frequency)
+
+
+
+
+obj/machinery/airlock_sensor
+ icon = 'icons/obj/airlock_machines.dmi'
+ icon_state = "airlock_sensor_off"
+ name = "airlock sensor"
+
+ anchored = 1
+ power_channel = ENVIRON
+
+ var/id_tag
+ var/master_tag
+ var/frequency = 1379
+ var/command = "cycle"
+
+ var/datum/radio_frequency/radio_connection
+
+ var/on = 1
+ var/alert = 0
+ var/previousPressure
+
+obj/machinery/airlock_sensor/update_icon()
+ if(on)
+ if(alert)
+ icon_state = "airlock_sensor_alert"
+ else
+ icon_state = "airlock_sensor_standby"
+ else
+ icon_state = "airlock_sensor_off"
+
+obj/machinery/airlock_sensor/attack_hand(mob/user)
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = master_tag
+ signal.data["command"] = command
+
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+ flick("airlock_sensor_cycle", src)
+
+obj/machinery/airlock_sensor/process()
+ if(on)
+ var/datum/gas_mixture/air_sample = return_air()
+ var/pressure = round(air_sample.return_pressure(),0.1)
+
+ if(abs(pressure - previousPressure) > 0.001 || previousPressure == null)
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = id_tag
+ signal.data["timestamp"] = world.time
+ signal.data["pressure"] = num2text(pressure)
+
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+
+ previousPressure = pressure
+
+ alert = (pressure < ONE_ATMOSPHERE*0.8)
+
+ update_icon()
+
+obj/machinery/airlock_sensor/proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
+
+obj/machinery/airlock_sensor/initialize()
+ set_frequency(frequency)
+
+obj/machinery/airlock_sensor/New()
+ ..()
+ if(radio_controller)
+ set_frequency(frequency)
+
+
+obj/machinery/airlock_sensor/airlock_interior
+ command = "cycle_interior"
+
+obj/machinery/airlock_sensor/airlock_exterior
+ command = "cycle_exterior"
+
+obj/machinery/access_button
+ icon = 'icons/obj/airlock_machines.dmi'
+ icon_state = "access_button_standby"
+ name = "access button"
+
+ anchored = 1
+ power_channel = ENVIRON
+
+ var/master_tag
+ var/frequency = 1449
+ var/command = "cycle"
+
+ var/datum/radio_frequency/radio_connection
+
+ var/on = 1
+
+
+obj/machinery/access_button/update_icon()
+ if(on)
+ icon_state = "access_button_standby"
+ else
+ icon_state = "access_button_off"
+
+
+obj/machinery/access_button/attack_hand(mob/user)
+ add_fingerprint(usr)
+ if(!allowed(user))
+ user << "\red Access Denied"
+
+ else if(radio_connection)
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.data["tag"] = master_tag
+ signal.data["command"] = command
+
+ radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK)
+ flick("access_button_cycle", src)
+
+
+obj/machinery/access_button/proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK)
+
+
+obj/machinery/access_button/initialize()
+ set_frequency(frequency)
+
+
+obj/machinery/access_button/New()
+ ..()
+
+ if(radio_controller)
+ set_frequency(frequency)
+
+obj/machinery/access_button/airlock_interior
+ frequency = 1379
+ command = "cycle_interior"
+
+obj/machinery/access_button/airlock_exterior
+ frequency = 1379
+ command = "cycle_exterior"
diff --git a/code/game/machinery/embedded_controller/docking_program.dm b/code/game/machinery/embedded_controller/docking_program.dm
index f4220f831aa..25199cfb3fa 100644
--- a/code/game/machinery/embedded_controller/docking_program.dm
+++ b/code/game/machinery/embedded_controller/docking_program.dm
@@ -10,20 +10,20 @@
/*
*** STATE TABLE ***
-
+
MODE_CLIENT|STATE_UNDOCKED sent a request for docking and now waiting for a reply.
MODE_CLIENT|STATE_DOCKING server told us they are OK to dock, waiting for our docking port to be ready.
MODE_CLIENT|STATE_DOCKED idle - docked as client.
MODE_CLIENT|STATE_UNDOCKING we are either waiting for our docking port to be ready or for the server to give us the OK to undock.
-
+
MODE_SERVER|STATE_UNDOCKED should never happen.
MODE_SERVER|STATE_DOCKING someone requested docking, we are waiting for our docking port to be ready.
MODE_SERVER|STATE_DOCKED idle - docked as server
MODE_SERVER|STATE_UNDOCKING client requested undocking, we are waiting for our docking port to be ready.
-
+
MODE_NONE|STATE_UNDOCKED idle - not docked.
MODE_NONE|anything else should never happen.
-
+
*/
@@ -32,17 +32,17 @@
var/dock_state = STATE_UNDOCKED
var/control_mode = MODE_NONE
var/response_sent = 0 //so we don't spam confirmation messages
-
+
var/override_enabled = 0 //skips checks for the docking port being ready
/datum/computer/file/embedded_program/docking/receive_signal(datum/signal/signal, receive_method, receive_param)
var/receive_tag = signal.data["tag"] //for docking signals, this is the sender id
var/command = signal.data["command"]
var/recipient = signal.data["recipient"] //the intended recipient of the docking signal
-
+
if (recipient != id_tag)
return //this signal is not for us
-
+
switch (command)
if ("confirm_dock")
if (control_mode == MODE_CLIENT && dock_state == STATE_UNDOCKED && receive_tag == tag_target)
@@ -56,7 +56,7 @@
response_sent = 0
else
send_docking_command(tag_target, "abort_dock") //not expecting confirmation for anything - tell the other guy.
-
+
if ("request_dock")
if (control_mode == MODE_NONE && dock_state == STATE_UNDOCKED)
control_mode = MODE_SERVER
@@ -64,17 +64,17 @@
tag_target = receive_tag
if (!override_enabled)
prepare_for_docking()
-
+
if ("confirm_undock")
if (control_mode == MODE_CLIENT && dock_state == STATE_UNDOCKING && receive_tag == tag_target)
send_docking_command(tag_target, "confirm_undock")
reset() //client is done undocking!
-
+
if ("request_undock")
if (control_mode == MODE_SERVER && dock_state == STATE_DOCKED && receive_tag == tag_target)
dock_state = STATE_UNDOCKING
prepare_for_undocking()
-
+
if ("dock_error")
if (receive_tag == tag_target)
reset()
@@ -86,7 +86,7 @@
if (!response_sent)
send_docking_command(tag_target, "confirm_dock") //tell the other guy we're ready
response_sent = 1
-
+
if (control_mode == MODE_CLIENT) //client doesn't need to do anything further
dock_state = STATE_DOCKED
if (!override_enabled)
@@ -101,10 +101,10 @@
else if (control_mode == MODE_SERVER)
send_docking_command(tag_target, "confirm_undock") //tell the client we are OK to undock.
reset() //server is done undocking!
-
+
if (dock_state != STATE_DOCKING && dock_state != STATE_UNDOCKING)
response_sent = 0
-
+
//handle invalid states
if (control_mode == MODE_NONE && dock_state != STATE_UNDOCKED)
if (tag_target)
@@ -117,19 +117,19 @@
/datum/computer/file/embedded_program/docking/proc/initiate_docking(var/target)
if (dock_state != STATE_UNDOCKED || control_mode == MODE_SERVER) //must be undocked and not serving another request to begin a new docking handshake
return
-
+
tag_target = target
control_mode = MODE_CLIENT
-
+
send_docking_command(tag_target, "request_dock")
/datum/computer/file/embedded_program/docking/proc/initiate_undocking()
if (dock_state != STATE_DOCKED || control_mode != MODE_CLIENT) //must be docked and must be client to start undocking
return
-
+
dock_state = STATE_UNDOCKING
prepare_for_undocking()
-
+
send_docking_command(tag_target, "request_undock")
@@ -169,14 +169,6 @@
tag_target = null
response_sent = 0
-/datum/computer/file/embedded_program/docking/proc/force_undock()
- if (tag_target)
- send_docking_command(tag_target, "dock_error")
- reset()
-
-/datum/computer/file/embedded_program/docking/proc/docked()
- return (dock_state == STATE_DOCKED)
-
/datum/computer/file/embedded_program/docking/proc/undocked()
return (dock_state == STATE_UNDOCKED)
@@ -198,10 +190,10 @@
if (STATE_DOCKING) return "docking"
if (STATE_UNDOCKING) return "undocking"
if (STATE_DOCKED) return "docked"
-
-
-
+
+
+
#undef STATE_UNDOCKED
#undef STATE_DOCKING
#undef STATE_UNDOCKING
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 7b231be1901..851836ba067 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2052,7 +2052,7 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","ShA")
- var/shuttle_tag = input("Which shuttle do you want to call?") as null|anything in shuttles.locations
+ var/shuttle_tag = input("Which shuttle do you want to call?") as null|anything in shuttles.location
if(shuttle_tag && !shuttles.moving[shuttle_tag])
shuttles.jump_shuttle(shuttle_tag)
diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm
index d9556df317e..3b6e1a35574 100644
--- a/code/modules/shuttles/shuttle.dm
+++ b/code/modules/shuttles/shuttle.dm
@@ -1,14 +1,14 @@
//These lists are populated in /datum/shuttle_controller/New()
//Shuttle controller is instantiated in master_controller.dm.
-#define STATUS_IDLE
-#define STATUS_WARMUP
-#define STATUS_INTRANSIT
+#define SHUTTLE_IDLE 0
+#define SHUTTLE_WARMUP 1
+#define SHUTTLE_INTRANSIT 2
var/global/datum/shuttle_controller/shuttles
/datum/shuttle_controller //This isn't really a controller...
- var/list/locations = list()
+ var/list/location = list()
var/list/warmup = list()
var/list/moving = list()
var/list/areas_offsite = list()
@@ -26,53 +26,53 @@ var/global/datum/shuttle_controller/shuttles
..()
//Supply and escape shuttles.
- locations["Supply"] = 1
+ location["Supply"] = 1
warmup["Supply"] = 0
- moving["Supply"] = STATUS_IDLE
+ moving["Supply"] = SHUTTLE_IDLE
areas_offsite["Supply"] = locate(/area/supply/dock)
areas_station["Supply"] = locate(/area/supply/station)
docking_targets["Supply"] = list(null, null)
// Admin shuttles.
- locations["Centcom"] = 1
+ location["Centcom"] = 1
warmup["Centcom"] = 0
- moving["Centcom"] = STATUS_IDLE
+ moving["Centcom"] = SHUTTLE_IDLE
areas_offsite["Centcom"] = locate(/area/shuttle/transport1/centcom)
areas_station["Centcom"] = locate(/area/shuttle/transport1/station)
docking_targets["Centcom"] = list(null, null)
- locations["Administration"] = 1
+ location["Administration"] = 1
warmup["Administration"] = 0
- moving["Administration"] = STATUS_IDLE
+ moving["Administration"] = SHUTTLE_IDLE
areas_offsite["Administration"] = locate(/area/shuttle/administration/centcom)
areas_station["Administration"] = locate(/area/shuttle/administration/station)
docking_targets["Administration"] = list(null, null)
- locations["Alien"] = 0
+ location["Alien"] = 0
warmup["Alien"] = 0
- moving["Alien"] = STATUS_IDLE
+ moving["Alien"] = SHUTTLE_IDLE
areas_offsite["Alien"] = locate(/area/shuttle/alien/base)
areas_station["Alien"] = locate(/area/shuttle/alien/mine)
docking_targets["Alien"] = list(null, null)
// Public shuttles.
- locations["Engineering"] = 1
+ location["Engineering"] = 1
warmup["Engineering"] = 10
- moving["Engineering"] = STATUS_IDLE
+ moving["Engineering"] = SHUTTLE_IDLE
areas_offsite["Engineering"] = locate(/area/shuttle/constructionsite/site)
areas_station["Engineering"] = locate(/area/shuttle/constructionsite/station)
docking_targets["Engineering"] = list(null, null)
- locations["Mining"] = 0
+ location["Mining"] = 0
warmup["Mining"] = 10
- moving["Mining"] = STATUS_IDLE
+ moving["Mining"] = SHUTTLE_IDLE
areas_offsite["Mining"] = locate(/area/shuttle/mining/outpost)
areas_station["Mining"] = locate(/area/shuttle/mining/station)
docking_targets["Mining"] = list(null, null)
- locations["Research"] = 0
+ location["Research"] = 0
warmup["Research"] = 10
- moving["Research"] = STATUS_IDLE
+ moving["Research"] = SHUTTLE_IDLE
areas_offsite["Research"] = locate(/area/shuttle/research/outpost)
areas_station["Research"] = locate(/area/shuttle/research/station)
docking_targets["Research"] = list("research_dock_airlock", "research_dock_airlock")
@@ -91,9 +91,9 @@ var/global/datum/shuttle_controller/shuttles
VS.interim = /area/vox_station/transit
multi_shuttles["Vox Skipjack"] = VS
- locations["Vox Skipjack"] = 1
+ location["Vox Skipjack"] = 1
warmup["Vox Skipjack"] = 10
- moving["Vox Skipjack"] = STATUS_IDLE
+ moving["Vox Skipjack"] = SHUTTLE_IDLE
//Nuke Ops shuttle.
var/datum/multi_shuttle/MS = new
@@ -116,24 +116,24 @@ var/global/datum/shuttle_controller/shuttles
MS.interim = /area/syndicate_station/transit
multi_shuttles["Syndicate"] = MS
- locations["Syndicate"] = 1
+ location["Syndicate"] = 1
warmup["Syndicate"] = 10
- moving["Syndicate"] = STATUS_IDLE
+ moving["Syndicate"] = SHUTTLE_IDLE
/datum/shuttle_controller/proc/jump_shuttle(var/shuttle_tag,var/area/origin,var/area/destination)
- if(moving[shuttle_tag] != STATUS_IDLE) return
+ if(moving[shuttle_tag] != SHUTTLE_IDLE) return
- moving[shuttle_tag] = STATUS_WARMUP
+ moving[shuttle_tag] = SHUTTLE_WARMUP
spawn(warmup[shuttle_tag]*10)
move_shuttle(shuttle_tag, origin, destination)
- moving[shuttle_tag] = STATUS_IDLE
+ moving[shuttle_tag] = SHUTTLE_IDLE
//This is for shuttles with a timer before arrival such as the vox skipjack and the escape shuttle.
/datum/shuttle_controller/proc/jump_shuttle_long(var/shuttle_tag,var/area/departing,var/area/destination,var/area/interim,var/travel_time)
- if(moving[shuttle_tag] != STATUS_IDLE) return
+ if(moving[shuttle_tag] != SHUTTLE_IDLE) return
- moving[shuttle_tag] = STATUS_WARMUP
+ moving[shuttle_tag] = SHUTTLE_WARMUP
spawn(warmup[shuttle_tag]*10)
move_shuttle(shuttle_tag,locate(departing),locate(interim))
@@ -142,7 +142,7 @@ var/global/datum/shuttle_controller/shuttles
move_shuttle(shuttle_tag,locate(interim),locate(destination))
- moving[shuttle_tag] = STATUS_IDLE
+ moving[shuttle_tag] = SHUTTLE_IDLE
return
@@ -151,7 +151,7 @@ var/global/datum/shuttle_controller/shuttles
/datum/shuttle_controller/proc/move_shuttle(var/shuttle_tag,var/area/origin,var/area/destination)
//world << "move_shuttle() called for [shuttle_tag] leaving [origin] en route to [destination]."
- if(!shuttle_tag || isnull(locations[shuttle_tag]))
+ if(!shuttle_tag || isnull(location[shuttle_tag]))
return
var/area/area_going_to
@@ -159,16 +159,16 @@ var/global/datum/shuttle_controller/shuttles
//world << "Using supplied destination [destination]."
area_going_to = destination
else
- //world << "Using controller value [(locations[shuttle_tag] == 1 ? areas_station[shuttle_tag] : areas_offsite[shuttle_tag])]."
- area_going_to = (locations[shuttle_tag] == 1 ? areas_station[shuttle_tag] : areas_offsite[shuttle_tag])
+ //world << "Using controller value [(location[shuttle_tag] == 1 ? areas_station[shuttle_tag] : areas_offsite[shuttle_tag])]."
+ area_going_to = (location[shuttle_tag] == 1 ? areas_station[shuttle_tag] : areas_offsite[shuttle_tag])
var/area/area_coming_from
if(origin)
//world << "Using supplied origin [origin]."
area_coming_from = origin
else
- //world << "Using controller value [(locations[shuttle_tag] == 1 ? areas_offsite[shuttle_tag] : areas_station[shuttle_tag])]."
- area_coming_from = (locations[shuttle_tag] == 1 ? areas_offsite[shuttle_tag] : areas_station[shuttle_tag])
+ //world << "Using controller value [(location[shuttle_tag] == 1 ? areas_offsite[shuttle_tag] : areas_station[shuttle_tag])]."
+ area_coming_from = (location[shuttle_tag] == 1 ? areas_offsite[shuttle_tag] : areas_station[shuttle_tag])
//world << "area_coming_from: [area_coming_from]"
//world << "area_going_to: [area_going_to]"
@@ -177,7 +177,7 @@ var/global/datum/shuttle_controller/shuttles
//world << "cancelling move, shuttle will overlap."
return
- moving[shuttle_tag] = STATUS_INTRANSIT
+ moving[shuttle_tag] = SHUTTLE_INTRANSIT
var/list/dstturfs = list()
var/throwy = world.maxy
@@ -202,7 +202,7 @@ var/global/datum/shuttle_controller/shuttles
area_coming_from.move_contents_to(area_going_to)
- locations[shuttle_tag] = !locations[shuttle_tag]
+ location[shuttle_tag] = !location[shuttle_tag]
for(var/mob/M in area_going_to)
if(M.client)
diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm
index e2cfb755d7a..1a063158723 100644
--- a/code/modules/shuttles/shuttle_console.dm
+++ b/code/modules/shuttles/shuttle_console.dm
@@ -1,5 +1,5 @@
/obj/machinery/computer/shuttle_control
- name = "shuttle console"
+ name = "shuttle control console"
icon = 'icons/obj/computer.dmi'
icon_state = "shuttle"
req_access = list(access_engine)
@@ -11,7 +11,7 @@
var/datum/computer/file/embedded_program/docking/docking_controller //the controller itself
var/hacked = 0 // Has been emagged, no access restrictions.
- var/waiting = 0
+ var/wait_for_launch = 0
/obj/machinery/computer/shuttle_control/initialize()
//search for our controller, if we have one.
@@ -20,11 +20,21 @@
if (C.id_tag == docking_controller_tag && istype(C.program, /datum/computer/file/embedded_program/docking))
docking_controller = C.program
+/obj/machinery/computer/shuttle_control/process()
+ if (wait_for_launch)
+ if (docking_controller && docking_controller.can_launch())
+ shuttles.jump_shuttle(shuttle_tag)
+ wait_for_launch = 0
+
+/*
/obj/machinery/computer/shuttle_control/attack_hand(user as mob)
if(..(user))
return
src.add_fingerprint(user)
+
+//ui_interact()
+
var/dat
dat = "