diff --git a/baystation12.dme b/baystation12.dme
index effaa6313cf..e5f44afd9ef 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -458,11 +458,13 @@
#include "code\game\machinery\doors\spacepod.dm"
#include "code\game\machinery\doors\unpowered.dm"
#include "code\game\machinery\doors\windowdoor.dm"
-#include "code\game\machinery\embedded_controller\access_controller.dm"
-#include "code\game\machinery\embedded_controller\airlock_controller.dm"
+#include "code\game\machinery\embedded_controller\airlock_controllers.dm"
+#include "code\game\machinery\embedded_controller\airlock_docking_controller.dm"
+#include "code\game\machinery\embedded_controller\airlock_program.dm"
+#include "code\game\machinery\embedded_controller\docking_program.dm"
#include "code\game\machinery\embedded_controller\embedded_controller_base.dm"
-#include "code\game\machinery\embedded_controller\simple_vent_controller.dm"
-#include "code\game\machinery\embedded_controller\smart_airlock_controller.dm"
+#include "code\game\machinery\embedded_controller\embedded_program_base.dm"
+#include "code\game\machinery\embedded_controller\simple_docking_controller.dm"
#include "code\game\machinery\kitchen\gibber.dm"
#include "code\game\machinery\kitchen\icecream_vat.dm"
#include "code\game\machinery\kitchen\juicer.dm"
diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm
deleted file mode 100644
index a0d9c847b2f..00000000000
--- a/code/game/machinery/embedded_controller/access_controller.dm
+++ /dev/null
@@ -1,214 +0,0 @@
-//States for airlock_control
-#define ACCESS_STATE_INTERNAL -1
-#define ACCESS_STATE_LOCKED 0
-#define ACCESS_STATE_EXTERNAL 1
-
-datum/computer/file/embedded_program/access_controller
- var/id_tag
- var/exterior_door_tag
- var/interior_door_tag
-
- state = ACCESS_STATE_LOCKED
- var/target_state = ACCESS_STATE_LOCKED
-
- receive_signal(datum/signal/signal, receive_method, receive_param)
- var/receive_tag = signal.data["tag"]
- if(!receive_tag) return
-
- if(receive_tag==exterior_door_tag)
- if(signal.data["door_status"] == "closed")
- if(signal.data["lock_status"] == "locked")
- memory["exterior_status"] = "locked"
- else
- memory["exterior_status"] = "closed"
- else
- memory["exterior_status"] = "open"
-
- else if(receive_tag==interior_door_tag)
- if(signal.data["door_status"] == "closed")
- if(signal.data["lock_status"] == "locked")
- memory["interior_status"] = "locked"
- else
- memory["interior_status"] = "closed"
- else
- memory["interior_status"] = "open"
-
- else if(receive_tag==id_tag)
- switch(signal.data["command"])
- if("cycle_interior")
- target_state = ACCESS_STATE_INTERNAL
- if("cycle_exterior")
- target_state = ACCESS_STATE_EXTERNAL
- if("cycle")
- if(state < ACCESS_STATE_LOCKED)
- target_state = ACCESS_STATE_EXTERNAL
- else
- target_state = ACCESS_STATE_INTERNAL
-
- receive_user_command(command)
- switch(command)
- if("cycle_closed")
- target_state = ACCESS_STATE_LOCKED
- if("cycle_exterior")
- target_state = ACCESS_STATE_EXTERNAL
- if("cycle_interior")
- target_state = ACCESS_STATE_INTERNAL
-
- process()
- var/process_again = 1
- while(process_again)
- process_again = 0
- switch(state)
- if(ACCESS_STATE_INTERNAL) // state -1
- if(target_state > state)
- if(memory["interior_status"] == "locked")
- state = ACCESS_STATE_LOCKED
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- if(memory["interior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
-
- if(ACCESS_STATE_LOCKED)
- if(target_state < state)
- if(memory["exterior_status"] != "locked")
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- if(memory["exterior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else
- if(memory["interior_status"] == "closed" || memory["interior_status"] == "open")
- state = ACCESS_STATE_INTERNAL
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else if(target_state > state)
- if(memory["interior_status"] != "locked")
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- if(memory["interior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else
- if(memory["exterior_status"] == "closed" || memory["exterior_status"] == "open")
- state = ACCESS_STATE_EXTERNAL
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else
- if(memory["interior_status"] != "locked")
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- if(memory["interior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else if(memory["exterior_status"] != "locked")
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- if(memory["exterior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
-
- if(ACCESS_STATE_EXTERNAL) //state 1
- if(target_state < state)
- if(memory["exterior_status"] == "locked")
- state = ACCESS_STATE_LOCKED
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- if(memory["exterior_status"] == "closed")
- signal.data["command"] = "lock"
- else
- signal.data["command"] = "secure_close"
- post_signal(signal)
-
-
- return 1
-
-
-obj/machinery/embedded_controller/radio/access_controller
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "access_control_standby"
-
- name = "Access Console"
- density = 0
- power_channel = ENVIRON
- unacidable = 1
-
- frequency = 1449
-
- // Setup parameters only
- var/id_tag
- var/exterior_door_tag
- var/interior_door_tag
-
- initialize()
- ..()
-
- var/datum/computer/file/embedded_program/access_controller/new_prog = new
-
- new_prog.id_tag = id_tag
- new_prog.exterior_door_tag = exterior_door_tag
- new_prog.interior_door_tag = interior_door_tag
-
- new_prog.master = src
- program = new_prog
-
- update_icon()
- if(on && program)
- if(program.memory["processing"])
- icon_state = "access_control_process"
- else
- icon_state = "access_control_standby"
- else
- icon_state = "access_control_off"
-
-
- return_text()
- var/state_options = null
-
- var/state = 0
- var/exterior_status = "----"
- var/interior_status = "----"
- if(program)
- state = program.state
- exterior_status = program.memory["exterior_status"]
- interior_status = program.memory["interior_status"]
-
- switch(state)
- if(ACCESS_STATE_INTERNAL)
- state_options = {"Lock Interior Airlock
-Cycle to Exterior Airlock
"}
- if(ACCESS_STATE_LOCKED)
- state_options = {"Unlock Interior Airlock
-Unlock Exterior Airlock
"}
- if(ACCESS_STATE_EXTERNAL)
- state_options = {"Cycle to Interior Airlock
-Lock Exterior Airlock
"}
-
- var/output = {"Access Control Console
-[state_options]
-Exterior Door: [exterior_status]
-Interior Door: [interior_status]
"}
-
- return output
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/airlock_controller.dm b/code/game/machinery/embedded_controller/airlock_controller.dm
deleted file mode 100644
index 9aa6a5a8e96..00000000000
--- a/code/game/machinery/embedded_controller/airlock_controller.dm
+++ /dev/null
@@ -1,352 +0,0 @@
-//States for airlock_control
-#define AIRLOCK_STATE_INOPEN -2
-#define AIRLOCK_STATE_PRESSURIZE -1
-#define AIRLOCK_STATE_CLOSED 0
-#define AIRLOCK_STATE_DEPRESSURIZE 1
-#define AIRLOCK_STATE_OUTOPEN 2
-#define AIRLOCK_STATE_BOTHOPEN 3
-
-datum/computer/file/embedded_program/airlock_controller
- var/id_tag
- var/exterior_door_tag
- var/interior_door_tag
- var/airpump_tag
- var/sensor_tag
- var/sensor_tag_int
- var/sanitize_external
-
- state = AIRLOCK_STATE_CLOSED
- var/target_state = AIRLOCK_STATE_CLOSED
- var/sensor_pressure = null
- var/int_sensor_pressure = ONE_ATMOSPHERE
-
- receive_signal(datum/signal/signal, receive_method, receive_param)
- var/receive_tag = signal.data["tag"]
- if(!receive_tag) return
-
- if(receive_tag==sensor_tag)
- if(signal.data["pressure"])
- sensor_pressure = text2num(signal.data["pressure"])
- else if(receive_tag==sensor_tag_int)
- if(signal.data["pressure"])
- int_sensor_pressure = text2num(signal.data["pressure"])
-
- else if(receive_tag==exterior_door_tag)
- memory["exterior_status"] = signal.data["door_status"]
- if(signal.data["bumped_with_access"])
- target_state = AIRLOCK_STATE_OUTOPEN
-
- else if(receive_tag==interior_door_tag)
- memory["interior_status"] = signal.data["door_status"]
- if(signal.data["bumped_with_access"])
- target_state = AIRLOCK_STATE_INOPEN
-
- else if(receive_tag==airpump_tag)
- if(signal.data["power"])
- memory["pump_status"] = signal.data["direction"]
- else
- memory["pump_status"] = "off"
-
- else if(receive_tag==id_tag)
- switch(signal.data["command"])
- if("cycle_exterior")
- target_state = AIRLOCK_STATE_OUTOPEN
- if("cycle_interior")
- target_state = AIRLOCK_STATE_INOPEN
- if("cycle")
- if(state < AIRLOCK_STATE_CLOSED)
- target_state = AIRLOCK_STATE_OUTOPEN
- else
- target_state = AIRLOCK_STATE_INOPEN
- if("cycle_interior")
- target_state = AIRLOCK_STATE_INOPEN
- if("cycle_exterior")
- target_state = AIRLOCK_STATE_OUTOPEN
-
- receive_user_command(command)
- switch(command)
- if("cycle_closed")
- target_state = AIRLOCK_STATE_CLOSED
- if("cycle_exterior")
- target_state = AIRLOCK_STATE_OUTOPEN
- if("cycle_interior")
- target_state = AIRLOCK_STATE_INOPEN
- if("abort")
- target_state = AIRLOCK_STATE_CLOSED
- if("force_both")
- target_state = AIRLOCK_STATE_BOTHOPEN
- state = AIRLOCK_STATE_BOTHOPEN
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- if("force_exterior")
- target_state = AIRLOCK_STATE_OUTOPEN
- state = AIRLOCK_STATE_OUTOPEN
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- if("force_interior")
- target_state = AIRLOCK_STATE_INOPEN
- state = AIRLOCK_STATE_INOPEN
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- if("close")
- target_state = AIRLOCK_STATE_CLOSED
- state = AIRLOCK_STATE_CLOSED
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
- signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
-
- process()
- var/process_again = 1
- while(process_again)
- process_again = 0
- switch(state)
- if(AIRLOCK_STATE_INOPEN) // state -2
- if(target_state > state)
- if(memory["interior_status"] == "closed")
- state = AIRLOCK_STATE_CLOSED
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "power" = 0,
- "sigtype"="command"
- )
- post_signal(signal)
-
- if(AIRLOCK_STATE_PRESSURIZE)
- if(target_state < state)
- if(sensor_pressure >= int_sensor_pressure*0.95)
- if(memory["interior_status"] == "open")
- state = AIRLOCK_STATE_INOPEN
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "sigtype"="command"
- )
- if(memory["pump_status"] == "siphon")
- signal.data["stabalize"] = 1
- else if(memory["pump_status"] != "release")
- signal.data["power"] = 1
- post_signal(signal)
- else if(target_state > state)
- state = AIRLOCK_STATE_CLOSED
- process_again = 1
-
- if(AIRLOCK_STATE_CLOSED)
- if(target_state > state)
- if(memory["interior_status"] == "closed")
- state = AIRLOCK_STATE_DEPRESSURIZE
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = interior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else if(target_state < state)
- if(memory["exterior_status"] == "closed")
- state = AIRLOCK_STATE_PRESSURIZE
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
-
- else
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "power" = 0,
- "sigtype"="command"
- )
- post_signal(signal)
-
- if(AIRLOCK_STATE_DEPRESSURIZE)
- var/target_pressure = ONE_ATMOSPHERE*0.04
- if(sanitize_external)
- target_pressure = ONE_ATMOSPHERE*0.01
-
- if(sensor_pressure <= target_pressure)
- if(target_state > state)
- if(memory["exterior_status"] == "open")
- state = AIRLOCK_STATE_OUTOPEN
- else
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else if(target_state < state)
- state = AIRLOCK_STATE_CLOSED
- process_again = 1
- else if((target_state < state) && !sanitize_external)
- state = AIRLOCK_STATE_CLOSED
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data = list(
- "tag" = airpump_tag,
- "sigtype"="command"
- )
- if(memory["pump_status"] == "release")
- signal.data["purge"] = 1
- else if(memory["pump_status"] != "siphon")
- signal.data["power"] = 1
- post_signal(signal)
-
- if(AIRLOCK_STATE_OUTOPEN) //state 2
- if(target_state < state)
- if(memory["exterior_status"] == "closed")
- if(sanitize_external)
- state = AIRLOCK_STATE_DEPRESSURIZE
- process_again = 1
- else
- state = AIRLOCK_STATE_CLOSED
- process_again = 1
- else
- var/datum/signal/signal = new
- signal.data["tag"] = exterior_door_tag
- signal.data["command"] = "secure_close"
- post_signal(signal)
- else
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "power" = 0,
- "sigtype"="command"
- )
- post_signal(signal)
-
- memory["sensor_pressure"] = sensor_pressure
- memory["int_sensor_pressure"] = int_sensor_pressure
- memory["processing"] = state != target_state
- //sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0
-
- return 1
-
-
-obj/machinery/embedded_controller/radio/airlock_controller
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "airlock_control_standby"
-
- name = "Airlock Console"
- density = 0
- unacidable = 1
-
- frequency = 1449
- power_channel = ENVIRON
-
- // Setup parameters only
- var/id_tag
- var/exterior_door_tag
- var/interior_door_tag
- var/airpump_tag
- var/sensor_tag
- var/sensor_tag_int
- var/sanitize_external
-
- initialize()
- ..()
-
- var/datum/computer/file/embedded_program/airlock_controller/new_prog = new
-
- new_prog.id_tag = id_tag
- new_prog.exterior_door_tag = exterior_door_tag
- new_prog.interior_door_tag = interior_door_tag
- new_prog.airpump_tag = airpump_tag
- new_prog.sensor_tag = sensor_tag
- new_prog.sensor_tag_int = sensor_tag_int
- new_prog.sanitize_external = sanitize_external
-
- new_prog.master = src
- program = new_prog
-
- update_icon()
- if(on && program)
- if(program.memory["processing"])
- icon_state = "airlock_control_process"
- else
- icon_state = "airlock_control_standby"
- else
- icon_state = "airlock_control_off"
-
-
- return_text()
- var/state_options = null
-
- var/state = 0
- var/sensor_pressure = "----"
- var/int_sensor_pressure = "----"
- var/exterior_status = "----"
- var/interior_status = "----"
- var/pump_status = "----"
- if(program)
- state = program.state
- sensor_pressure = program.memory["sensor_pressure"]
- int_sensor_pressure = program.memory["int_sensor_pressure"]
- exterior_status = program.memory["exterior_status"]
- interior_status = program.memory["interior_status"]
- pump_status = program.memory["pump_status"]
-
- switch(state)
- if(AIRLOCK_STATE_INOPEN)
- state_options = {"Close Interior Airlock
-Cycle to Exterior Airlock
"}
- if(AIRLOCK_STATE_PRESSURIZE)
- state_options = "Abort Cycling
"
- if(AIRLOCK_STATE_CLOSED)
- state_options = {"Open Interior Airlock
-Open Exterior Airlock
"}
- if(AIRLOCK_STATE_DEPRESSURIZE)
- state_options = "Abort Cycling
"
- if(AIRLOCK_STATE_OUTOPEN)
- state_options = {"Cycle to Interior Airlock
-Close Exterior Airlock
"}
- if(AIRLOCK_STATE_BOTHOPEN)
- state_options = "Close Airlocks
"
-
- var/output = {"Airlock Control Console
-[state_options]
-Chamber Pressure: [sensor_pressure] kPa
-Internal Pressure: [int_sensor_pressure] kPa
-Exterior Door: [exterior_status]
-Interior Door: [interior_status]
-Control Pump: [pump_status]
"}
-
- if(program && program.state == AIRLOCK_STATE_CLOSED)
- output += {"Force Both Airlocks
- Force Inner Airlock
- Force Outer Airlock"}
-
- return output
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm
new file mode 100644
index 00000000000..4a48558f875
--- /dev/null
+++ b/code/game/machinery/embedded_controller/airlock_controllers.dm
@@ -0,0 +1,186 @@
+//base type for controllers of two-door systems
+/obj/machinery/embedded_controller/radio/airlock
+ // Setup parameters only
+ var/tag_exterior_door
+ var/tag_interior_door
+ var/tag_airpump
+ var/tag_chamber_sensor
+ var/tag_exterior_sensor
+ var/tag_interior_sensor
+ var/tag_secure = 0
+
+/obj/machinery/embedded_controller/radio/airlock/initialize()
+ ..()
+ program = new/datum/computer/file/embedded_program/airlock(src)
+
+//Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks
+/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller
+ name = "Advanced Airlock Controller"
+
+/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ var/data[0]
+
+ data = list(
+ "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]),
+ "external_pressure" = round(program.memory["external_sensor_pressure"]),
+ "internal_pressure" = round(program.memory["internal_sensor_pressure"]),
+ "processing" = program.memory["processing"],
+ "purge" = program.memory["purge"],
+ "secure" = program.memory["secure"]
+ )
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "advanced_airlock_console.tmpl", name, 470, 290)
+
+ ui.set_initial_data(data)
+
+ ui.open()
+
+ ui.set_auto_update(1)
+
+/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ src.add_fingerprint(usr)
+
+ var/clean = 0
+ switch(href_list["command"]) //anti-HTML-hacking checks
+ if("cycle_ext")
+ clean = 1
+ if("cycle_int")
+ clean = 1
+ if("force_ext")
+ clean = 1
+ if("force_int")
+ clean = 1
+ if("abort")
+ clean = 1
+ if("purge")
+ clean = 1
+ if("secure")
+ clean = 1
+
+ if(clean)
+ program.receive_user_command(href_list["command"])
+
+ return 1
+
+
+//Airlock controller for airlock control - most airlocks on the station use this
+/obj/machinery/embedded_controller/radio/airlock/airlock_controller
+ name = "Airlock Controller"
+ tag_secure = 1
+
+/obj/machinery/embedded_controller/radio/airlock/airlock_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ var/data[0]
+
+ data = list(
+ "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]),
+ "exterior_status" = program.memory["exterior_status"],
+ "interior_status" = program.memory["interior_status"],
+ "processing" = program.memory["processing"],
+ )
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "simple_airlock_console.tmpl", name, 470, 290)
+
+ ui.set_initial_data(data)
+
+ ui.open()
+
+ ui.set_auto_update(1)
+
+/obj/machinery/embedded_controller/radio/airlock/airlock_controller/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ src.add_fingerprint(usr)
+
+ var/clean = 0
+ switch(href_list["command"]) //anti-HTML-hacking checks
+ if("cycle_ext")
+ clean = 1
+ if("cycle_int")
+ clean = 1
+ if("force_ext")
+ clean = 1
+ if("force_int")
+ clean = 1
+ if("abort")
+ clean = 1
+
+ if(clean)
+ program.receive_user_command(href_list["command"])
+
+ return 1
+
+
+//Access controller for door control - used in virology and the like
+/obj/machinery/embedded_controller/radio/airlock/access_controller
+ icon = 'icons/obj/airlock_machines.dmi'
+ icon_state = "access_control_standby"
+
+ name = "Access Controller"
+ tag_secure = 1
+
+
+/obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon()
+ if(on && program)
+ if(program.memory["processing"])
+ icon_state = "access_control_process"
+ else
+ icon_state = "access_control_standby"
+ else
+ icon_state = "access_control_off"
+
+/obj/machinery/embedded_controller/radio/airlock/access_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ var/data[0]
+
+ data = list(
+ "exterior_status" = program.memory["exterior_status"],
+ "interior_status" = program.memory["interior_status"],
+ "processing" = program.memory["processing"]
+ )
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "door_access_console.tmpl", name, 330, 220)
+
+ ui.set_initial_data(data)
+
+ ui.open()
+
+ ui.set_auto_update(1)
+
+/obj/machinery/embedded_controller/radio/airlock/access_controller/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ src.add_fingerprint(usr)
+
+ var/clean = 0
+ switch(href_list["command"]) //anti-HTML-hacking checks
+ if("cycle_ext_door")
+ clean = 1
+ if("cycle_int_door")
+ clean = 1
+ if("force_ext")
+ if(program.memory["interior_status"]["state"] == "closed")
+ clean = 1
+ if("force_int")
+ if(program.memory["exterior_status"]["state"] == "closed")
+ clean = 1
+
+ if(clean)
+ program.receive_user_command(href_list["command"])
+
+ return 1
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm
new file mode 100644
index 00000000000..77512f70ffe
--- /dev/null
+++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm
@@ -0,0 +1,174 @@
+//a docking port based on an airlock
+/obj/machinery/embedded_controller/radio/airlock/docking_port
+ name = "docking port controller"
+ var/datum/computer/file/embedded_program/airlock/docking/airlock_program
+ var/datum/computer/file/embedded_program/docking/airlock/docking_program
+ tag_secure = 1
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/initialize()
+ ..()
+ airlock_program = new/datum/computer/file/embedded_program/airlock/docking(src)
+ docking_program = new/datum/computer/file/embedded_program/docking/airlock(src, airlock_program)
+ program = docking_program
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ var/data[0]
+
+ data = list(
+ "chamber_pressure" = round(airlock_program.memory["chamber_sensor_pressure"]),
+ "exterior_status" = airlock_program.memory["exterior_status"],
+ "interior_status" = airlock_program.memory["interior_status"],
+ "processing" = airlock_program.memory["processing"],
+ "docking_status" = docking_program.get_docking_status(),
+ "airlock_disabled" = !(docking_program.undocked() || docking_program.override_enabled),
+ )
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "docking_airlock_console.tmpl", name, 470, 290)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ src.add_fingerprint(usr)
+
+ var/clean = 0
+ switch(href_list["command"]) //anti-HTML-hacking checks
+ if("cycle_ext")
+ clean = 1
+ if("cycle_int")
+ clean = 1
+ if("force_ext")
+ clean = 1
+ if("force_int")
+ clean = 1
+ if("abort")
+ clean = 1
+ if("toggle_override")
+ clean = 1
+
+ if(clean)
+ program.receive_user_command(href_list["command"])
+
+ return 1
+
+
+
+//A docking controller for an airlock based docking port
+/datum/computer/file/embedded_program/docking/airlock
+ var/datum/computer/file/embedded_program/airlock/docking/airlock_program
+
+/datum/computer/file/embedded_program/docking/airlock/New(var/obj/machinery/embedded_controller/M, var/datum/computer/file/embedded_program/airlock/docking/A)
+ ..(M)
+ airlock_program = A
+ airlock_program.master_prog = src
+
+/datum/computer/file/embedded_program/docking/airlock/receive_user_command(command)
+ if (command == "toggle_override")
+ if (override_enabled)
+ disable_override()
+ else
+ enable_override()
+ return
+
+ ..(command)
+ airlock_program.receive_user_command(command) //pass along to subprograms
+
+/datum/computer/file/embedded_program/docking/airlock/process()
+ airlock_program.process()
+ ..()
+
+/datum/computer/file/embedded_program/docking/airlock/receive_signal(datum/signal/signal, receive_method, receive_param)
+ airlock_program.receive_signal(signal, receive_method, receive_param) //pass along to subprograms
+ ..(signal, receive_method, receive_param)
+
+//tell the docking port to start getting ready for docking - e.g. pressurize
+/datum/computer/file/embedded_program/docking/airlock/prepare_for_docking()
+ airlock_program.begin_cycle_in()
+
+//are we ready for docking?
+/datum/computer/file/embedded_program/docking/airlock/ready_for_docking()
+ return airlock_program.done_cycling()
+
+//we are docked, open the doors or whatever.
+/datum/computer/file/embedded_program/docking/airlock/finish_docking()
+ airlock_program.open_doors()
+
+//tell the docking port to start getting ready for undocking - e.g. close those doors.
+/datum/computer/file/embedded_program/docking/airlock/prepare_for_undocking()
+ airlock_program.stop_cycling()
+ airlock_program.close_doors()
+
+//are we ready for undocking?
+/datum/computer/file/embedded_program/docking/airlock/ready_for_undocking()
+ return airlock_program.check_doors_secured()
+
+/datum/computer/file/embedded_program/docking/airlock/reset()
+ airlock_program.stop_cycling()
+ airlock_program.close_doors()
+ ..()
+
+//An airlock controller to be used by the airlock-based docking port controller.
+//Same as a regular airlock controller but allows disabling of the regular airlock functions when docking
+/datum/computer/file/embedded_program/airlock/docking
+
+ var/datum/computer/file/embedded_program/docking/airlock/master_prog
+
+/datum/computer/file/embedded_program/airlock/docking/receive_user_command(command)
+ if (master_prog.undocked() || master_prog.override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled
+ ..(command)
+
+/datum/computer/file/embedded_program/airlock/docking/proc/open_doors()
+ toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "open")
+ toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "open")
+
+/datum/computer/file/embedded_program/airlock/docking/cycleDoors(var/target)
+ if (master_prog.undocked() || master_prog.override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled
+ ..(target)
+
+/*** DEBUG VERBS ***
+
+/datum/computer/file/embedded_program/docking/proc/print_state()
+ world << "id_tag: [id_tag]"
+ world << "dock_state: [dock_state]"
+ world << "control_mode: [control_mode]"
+ world << "tag_target: [tag_target]"
+ world << "response_sent: [response_sent]"
+
+/datum/computer/file/embedded_program/docking/post_signal(datum/signal/signal, comm_line)
+ world << "Program [id_tag] sent a message!"
+ print_state()
+ world << "[id_tag] sent command \"[signal.data["command"]]\" to \"[signal.data["recipient"]]\""
+ ..(signal)
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/verb/view_state()
+ set category = "Debug"
+ set src in view(1)
+ src.program:print_state()
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/verb/spoof_signal(var/command as text, var/sender as text)
+ set category = "Debug"
+ set src in view(1)
+ var/datum/signal/signal = new
+ signal.data["tag"] = sender
+ signal.data["command"] = command
+ signal.data["recipient"] = id_tag
+
+ src.program:receive_signal(signal)
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/verb/debug_init_dock(var/target as text)
+ set category = "Debug"
+ set src in view(1)
+ src.program:initiate_docking(target)
+
+/obj/machinery/embedded_controller/radio/airlock/docking_port/verb/debug_init_undock()
+ set category = "Debug"
+ set src in view(1)
+ src.program:initiate_undocking()
+*/
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm
index baf846ebf4e..72c2427cf05 100644
--- a/code/game/machinery/embedded_controller/airlock_program.dm
+++ b/code/game/machinery/embedded_controller/airlock_program.dm
@@ -8,11 +8,8 @@
#define TARGET_INOPEN -1
#define TARGET_OUTOPEN -2
-/datum/computer/file/embedded_program
- var/list/memory = list()
- var/obj/machinery/embedded_controller/master
- var/id_tag
+/datum/computer/file/embedded_program/airlock
var/tag_exterior_door
var/tag_interior_door
var/tag_airpump
@@ -23,9 +20,9 @@
var/state = STATE_WAIT
var/target_state = TARGET_NONE
-
-/datum/computer/file/embedded_program/New()
- ..()
+/datum/computer/file/embedded_program/airlock/New(var/obj/machinery/embedded_controller/M)
+ ..(M)
+
memory["chamber_sensor_pressure"] = ONE_ATMOSPHERE
memory["external_sensor_pressure"] = 0 //assume vacuum for simple airlock controller
memory["internal_sensor_pressure"] = ONE_ATMOSPHERE
@@ -35,11 +32,22 @@
memory["target_pressure"] = ONE_ATMOSPHERE
memory["purge"] = 0
memory["secure"] = 0
+
+ if (istype(M, /obj/machinery/embedded_controller/radio/airlock)) //if our controller is an airlock controller than we can auto-init our tags
+ var/obj/machinery/embedded_controller/radio/airlock/controller = M
+ tag_exterior_door = controller.tag_exterior_door
+ tag_interior_door = controller.tag_interior_door
+ tag_airpump = controller.tag_airpump
+ tag_chamber_sensor = controller.tag_chamber_sensor
+ tag_exterior_sensor = controller.tag_exterior_sensor
+ tag_interior_sensor = controller.tag_interior_sensor
+ memory["secure"] = controller.tag_secure
+
+ spawn(10)
+ signalDoor(tag_exterior_door, "update") //signals connected doors to update their status
+ signalDoor(tag_interior_door, "update")
-
-
-
-/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
+/datum/computer/file/embedded_program/airlock/receive_signal(datum/signal/signal, receive_method, receive_param)
var/receive_tag = signal.data["tag"]
if(!receive_tag) return
@@ -68,7 +76,7 @@
memory["pump_status"] = "off"
else if(receive_tag==id_tag)
- if(istype(master, /obj/machinery/embedded_controller/radio/access_controller))
+ if(istype(master, /obj/machinery/embedded_controller/radio/airlock/access_controller))
switch(signal.data["command"])
if("cycle_exterior")
receive_user_command("cycle_ext_door")
@@ -92,7 +100,7 @@
receive_user_command("cycle_int")
-/datum/computer/file/embedded_program/proc/receive_user_command(command)
+/datum/computer/file/embedded_program/airlock/receive_user_command(command)
var/shutdown_pump = 0
switch(command)
if("cycle_ext")
@@ -142,7 +150,7 @@
signalPump(tag_airpump, 0) //send a signal to stop pressurizing
-/datum/computer/file/embedded_program/proc/process()
+/datum/computer/file/embedded_program/airlock/process()
if(!state)
if(target_state)
switch(target_state)
@@ -152,8 +160,7 @@
memory["target_pressure"] = memory["external_sensor_pressure"]
//lock down the airlock before activating pumps
- toggleDoor(memory["exterior_status"], tag_exterior_door, 1, "close")
- toggleDoor(memory["interior_status"], tag_interior_door, 1, "close")
+ close_doors()
var/chamber_pressure = memory["chamber_sensor_pressure"]
var/target_pressure = memory["target_pressure"]
@@ -178,7 +185,7 @@
signalPump(tag_airpump, 0)
//the airlock will not allow itself to continue to cycle when any of the doors are forced open.
- if (state && !check_doors_closed())
+ if (state && !check_doors_secured())
stop_cycling()
switch(state)
@@ -215,40 +222,40 @@
return 1
-//these are here so that subtypes don't have to make so many assuptions about our implementation
+//these are here so that other types don't have to make so many assuptions about our implementation
-/datum/computer/file/embedded_program/proc/begin_cycle_in()
+/datum/computer/file/embedded_program/airlock/proc/begin_cycle_in()
state = STATE_WAIT
target_state = TARGET_INOPEN
-/datum/computer/file/embedded_program/proc/begin_cycle_out()
+/datum/computer/file/embedded_program/airlock/proc/begin_cycle_out()
state = STATE_WAIT
target_state = TARGET_OUTOPEN
-/datum/computer/file/embedded_program/proc/stop_cycling()
+/datum/computer/file/embedded_program/airlock/proc/close_doors()
+ toggleDoor(memory["interior_status"], tag_interior_door, 1, "close")
+ toggleDoor(memory["exterior_status"], tag_exterior_door, 1, "close")
+
+/datum/computer/file/embedded_program/airlock/proc/stop_cycling()
state = STATE_WAIT
target_state = TARGET_NONE
-/datum/computer/file/embedded_program/proc/done_cycling()
+/datum/computer/file/embedded_program/airlock/proc/done_cycling()
return (state == STATE_WAIT && target_state == TARGET_NONE)
-/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line)
- if(master)
- master.post_signal(signal, comm_line)
- else
- del(signal)
+//are the doors closed and locked?
+/datum/computer/file/embedded_program/airlock/proc/check_doors_secured()
+ var/ext_closed = (memory["exterior_status"]["state"] == "closed" && memory["exterior_status"]["lock"] == "locked")
+ var/int_closed = (memory["interior_status"]["state"] == "closed" && memory["interior_status"]["lock"] == "locked")
+ return (ext_closed && int_closed)
-/datum/computer/file/embedded_program/proc/check_doors_closed()
- return (memory["interior_status"]["state"] == "closed" && memory["exterior_status"["state"] == "closed")
-
-/datum/computer/file/embedded_program/proc/signalDoor(var/tag, var/command)
+/datum/computer/file/embedded_program/airlock/proc/signalDoor(var/tag, var/command)
var/datum/signal/signal = new
signal.data["tag"] = tag
signal.data["command"] = command
post_signal(signal)
-
-/datum/computer/file/embedded_program/proc/signalPump(var/tag, var/power, var/direction, var/pressure)
+/datum/computer/file/embedded_program/airlock/proc/signalPump(var/tag, var/power, var/direction, var/pressure)
var/datum/signal/signal = new
signal.data = list(
"tag" = tag,
@@ -260,7 +267,7 @@
post_signal(signal)
//this is called to set the appropriate door state at the end of a cycling process, or for the exterior buttons
-/datum/computer/file/embedded_program/proc/cycleDoors(var/target)
+/datum/computer/file/embedded_program/airlock/proc/cycleDoors(var/target)
switch(target)
if(TARGET_OUTOPEN)
toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "close")
@@ -289,7 +296,7 @@ Only sends a command if it is needed, i.e. if the door is
already open, passing an open command to this proc will not
send an additional command to open the door again.
----------------------------------------------------------*/
-/datum/computer/file/embedded_program/proc/toggleDoor(var/list/doorStatus, var/doorTag, var/secure, var/command)
+/datum/computer/file/embedded_program/airlock/proc/toggleDoor(var/list/doorStatus, var/doorTag, var/secure, var/command)
var/doorCommand = null
if(command == "toggle")
diff --git a/code/game/machinery/embedded_controller/docking_program.dm b/code/game/machinery/embedded_controller/docking_program.dm
index 536b035259f..f4220f831aa 100644
--- a/code/game/machinery/embedded_controller/docking_program.dm
+++ b/code/game/machinery/embedded_controller/docking_program.dm
@@ -4,104 +4,209 @@
#define STATE_UNDOCKING 2
#define STATE_DOCKED 3
+#define MODE_NONE 0
+#define MODE_SERVER 1
+#define MODE_CLIENT 2 //The one who initiated the docking, and who can initiate the undocking. The server cannot initiate undocking. (Think server == station, client == shuttle)
-/datum/computer/file/embedded_program/docking_port
+/*
+ *** 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.
+
+*/
+
+
+/datum/computer/file/embedded_program/docking
var/tag_target //the tag of the docking controller that we are trying to dock with
- var/airlock_override = 0 //allows use of the docking port as a normal airlock (normally this is only allowed in STATE_UNDOCKED)
var/dock_state = STATE_UNDOCKED
- var/dock_master = 0 //are we the initiator of the dock?
+ 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_port/receive_signal(datum/signal/signal, receive_method, receive_param)
- var/receive_tag = signal.data["tag"] //for docking signals, this is the sender id
+/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"]
+ var/recipient = signal.data["recipient"] //the intended recipient of the docking signal
- if (recipient == id_tag)
- switch (command)
- if ("request_dock")
- if (state == STATE_UNDOCKED)
- tag_target = receive_tag
- begin_dock()
-
- if ("request_undock")
- if(receive_tag == tag_target)
- begin_undock()
-
- if ("confirm_dock")
- if(receive_tag == tag_target)
- dock_master = 1
- begin_dock()
- else
- send_docking_command(receive_tag, "docking_error") //send an error message
-
- if ("confirm_undock")
- if(receive_tag == tag_target)
- begin_undock()
-
- if ("docking_error")
- if(receive_tag==tag_target)
- //try to return to a good state
- stop_cycling()
-
- //close the doors
- toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "close")
- toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "close")
-
- state = STATE_UNDOCKED
- tag_target = null
- dock_master = 0
+ 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)
+ dock_state = STATE_DOCKING
+ if (!override_enabled)
+ prepare_for_docking()
+ else if (control_mode == MODE_SERVER && dock_state == STATE_DOCKING && receive_tag == tag_target) //client just sent us the confirmation back, we're done with the docking process
+ dock_state = STATE_DOCKED
+ if (!override_enabled)
+ finish_docking() //server done docking!
+ 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
+ dock_state = STATE_DOCKING
+ 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()
-/datum/computer/file/embedded_program/docking_port/receive_user_command(command)
- if (state == STATE_UNDOCKED || airlock_override)
- ..(command)
-
-/datum/computer/file/embedded_program/docking_port/process()
- ..() //process regular airlock stuff first
-
+/datum/computer/file/embedded_program/docking/process()
switch(dock_state)
- if(STATE_DOCKING)
- if(done_cycling() || airlock_override)
- state = STATE_DOCKED
+ if (STATE_DOCKING) //waiting for our docking port to be ready for docking
+ if (ready_for_docking() || override_enabled)
+ if (!response_sent)
+ send_docking_command(tag_target, "confirm_dock") //tell the other guy we're ready
+ response_sent = 1
- if (!dock_master)
- send_docking_command(tag_target, "confirm_dock") //send confirmation
-
- //open doors
- toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "open")
- toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "open")
- if(STATE_UNDOCKING)
- if(check_doors_closed() || airlock_override) //check doors are closed or override
- state = STATE_UNDOCKED
-
- if (!dock_master)
- send_docking_command(tag_target, "confirm_undock") //send confirmation
-
- dock_master = 0
- tag_target = null
-
-/datum/computer/file/embedded_program/docking_port/cycleDoors(var/target)
- if (state == STATE_UNDOCKED || airlock_override)
- ..(target)
-
-//get the docking port into a good state for docking.
-/datum/computer/file/embedded_program/docking_port/proc/begin_dock()
- dock_state = STATE_DOCKING
- begin_cycle_in()
-
-//get the docking port into a good state for undocking.
-/datum/computer/file/embedded_program/docking_port/proc/begin_undock()
- dock_state = STATE_UNDOCKING
- stop_cycling()
+ if (control_mode == MODE_CLIENT) //client doesn't need to do anything further
+ dock_state = STATE_DOCKED
+ if (!override_enabled)
+ finish_docking() //client done docking!
+ response_sent = 0
+ if (STATE_UNDOCKING)
+ if (ready_for_undocking() || override_enabled)
+ if (control_mode == MODE_CLIENT)
+ if (!response_sent)
+ send_docking_command(tag_target, "request_undock") //tell the server we want to undock now.
+ response_sent = 1
+ 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!
- //close the doors
- toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "close")
- toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "close")
+ 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)
+ send_docking_command(tag_target, "dock_error")
+ reset()
+ if (control_mode == MODE_SERVER && dock_state == STATE_UNDOCKED)
+ control_mode = MODE_NONE
-/datum/computer/file/embedded_program/docking_port/proc/send_docking_command(var/recipient, var/command)
+
+/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")
+
+
+//tell the docking port to start getting ready for docking - e.g. pressurize
+/datum/computer/file/embedded_program/docking/proc/prepare_for_docking()
+ return
+
+//are we ready for docking?
+/datum/computer/file/embedded_program/docking/proc/ready_for_docking()
+ return 1
+
+//we are docked, open the doors or whatever.
+/datum/computer/file/embedded_program/docking/proc/finish_docking()
+ return
+
+//tell the docking port to start getting ready for undocking - e.g. close those doors.
+/datum/computer/file/embedded_program/docking/proc/prepare_for_undocking()
+ return
+
+//are we ready for undocking?
+/datum/computer/file/embedded_program/docking/proc/ready_for_undocking()
+ return 1
+
+/datum/computer/file/embedded_program/docking/proc/enable_override()
+ override_enabled = 1
+ //if (tag_target)
+ // send_docking_command(tag_target, "enable_override")
+
+/datum/computer/file/embedded_program/docking/proc/disable_override()
+ override_enabled = 0
+ //if (tag_target)
+ // send_docking_command(tag_target, "disable_override")
+
+/datum/computer/file/embedded_program/docking/proc/reset()
+ dock_state = STATE_UNDOCKED
+ control_mode = MODE_NONE
+ 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)
+
+//returns 1 if we are saftely undocked (and the shuttle can leave)
+/datum/computer/file/embedded_program/docking/proc/can_launch()
+ return undocked()
+
+/datum/computer/file/embedded_program/docking/proc/send_docking_command(var/recipient, var/command)
var/datum/signal/signal = new
signal.data["tag"] = id_tag
signal.data["command"] = command
signal.data["recipient"] = recipient
post_signal(signal)
+
+//this is mostly for NanoUI
+/datum/computer/file/embedded_program/docking/proc/get_docking_status()
+ switch (dock_state)
+ if (STATE_UNDOCKED) return "undocked"
+ if (STATE_DOCKING) return "docking"
+ if (STATE_UNDOCKING) return "undocking"
+ if (STATE_DOCKED) return "docked"
+
+
+
+
+#undef STATE_UNDOCKED
+#undef STATE_DOCKING
+#undef STATE_UNDOCKING
+#undef STATE_DOCKED
+
+#undef MODE_NONE
+#undef MODE_SERVER
+#undef MODE_CLIENT
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index bb991c0e1d7..0d6241211e5 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -1,84 +1,73 @@
-datum/computer/file/embedded_program
- var/list/memory = list()
- var/state
- var/obj/machinery/embedded_controller/master
-
- proc
- post_signal(datum/signal/signal, comm_line)
- if(master)
- master.post_signal(signal, comm_line)
- else
- del(signal)
-
- receive_user_command(command)
-
- receive_signal(datum/signal/signal, receive_method, receive_param)
- return null
-
- process()
- return 0
-
-obj/machinery/embedded_controller
+/obj/machinery/embedded_controller
var/datum/computer/file/embedded_program/program
name = "Embedded Controller"
- density = 0
anchored = 1
var/on = 1
- attack_hand(mob/user)
- user << browse(return_text(), "window=computer")
- user.set_machine(src)
- onclose(user, "computer")
+/obj/machinery/embedded_controller/proc/post_signal(datum/signal/signal, comm_line)
+ return 0
- update_icon()
- proc/return_text()
+/obj/machinery/embedded_controller/receive_signal(datum/signal/signal, receive_method, receive_param)
+ if(!signal || signal.encryption) return
- proc/post_signal(datum/signal/signal, comm_line)
- return 0
-
- receive_signal(datum/signal/signal, receive_method, receive_param)
- if(!signal || signal.encryption) return
-
- if(program)
- program.receive_signal(signal, receive_method, receive_param)
+ if(program)
+ program.receive_signal(signal, receive_method, receive_param)
//spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0
- Topic(href, href_list)
- if(..())
- return 0
+/obj/machinery/embedded_controller/process()
+ if(program)
+ program.process()
- if(program)
- program.receive_user_command(href_list["command"])
- spawn(5) program.process()
+ update_icon()
+ src.updateDialog()
- usr.set_machine(src)
- spawn(5) src.updateDialog()
+/obj/machinery/embedded_controller/attack_ai(mob/user as mob)
+ src.ui_interact(user)
- process()
- if(program)
- program.process()
+/obj/machinery/embedded_controller/attack_paw(mob/user as mob)
+ user << "You do not have the dexterity to use this."
+ return
- update_icon()
- src.updateDialog()
+/obj/machinery/embedded_controller/attack_hand(mob/user as mob)
+ src.ui_interact(user)
- radio
- var/frequency
- var/datum/radio_frequency/radio_connection
+/obj/machinery/embedded_controller/ui_interact()
+ return
- initialize()
- set_frequency(frequency)
+/obj/machinery/embedded_controller/radio
+ icon = 'icons/obj/airlock_machines.dmi'
+ icon_state = "airlock_control_standby"
+ power_channel = ENVIRON
+ density = 0
+
+ var/id_tag
- post_signal(datum/signal/signal)
- signal.transmission_method = TRANSMISSION_RADIO
- if(radio_connection)
- return radio_connection.post_signal(src, signal)
- else
- del(signal)
+ var/frequency = 1379
+ var/datum/radio_frequency/radio_connection
+ unacidable = 1
- proc
- set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency)
\ No newline at end of file
+/obj/machinery/embedded_controller/radio/initialize()
+ set_frequency(frequency)
+
+/obj/machinery/embedded_controller/radio/update_icon()
+ if(on && program)
+ if(program.memory["processing"])
+ icon_state = "airlock_control_process"
+ else
+ icon_state = "airlock_control_standby"
+ else
+ icon_state = "airlock_control_off"
+
+/obj/machinery/embedded_controller/radio/post_signal(datum/signal/signal)
+ signal.transmission_method = TRANSMISSION_RADIO
+ if(radio_connection)
+ return radio_connection.post_signal(src, signal)
+ else
+ del(signal)
+
+/obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency)
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/embedded_program_base.dm b/code/game/machinery/embedded_controller/embedded_program_base.dm
new file mode 100644
index 00000000000..611fcfc52e5
--- /dev/null
+++ b/code/game/machinery/embedded_controller/embedded_program_base.dm
@@ -0,0 +1,27 @@
+
+/datum/computer/file/embedded_program
+ var/list/memory = list()
+ var/obj/machinery/embedded_controller/master
+
+ var/id_tag
+
+/datum/computer/file/embedded_program/New(var/obj/machinery/embedded_controller/M)
+ master = M
+ if (istype(M, /obj/machinery/embedded_controller/radio))
+ var/obj/machinery/embedded_controller/radio/R = M
+ id_tag = R.id_tag
+
+/datum/computer/file/embedded_program/proc/receive_user_command(command)
+ return
+
+/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
+ return
+
+/datum/computer/file/embedded_program/proc/process()
+ return
+
+/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line)
+ if(master)
+ master.post_signal(signal, comm_line)
+ else
+ del(signal)
diff --git a/code/game/machinery/embedded_controller/simple_docking_controller.dm b/code/game/machinery/embedded_controller/simple_docking_controller.dm
new file mode 100644
index 00000000000..2158b04f169
--- /dev/null
+++ b/code/game/machinery/embedded_controller/simple_docking_controller.dm
@@ -0,0 +1,160 @@
+//a docking port that uses a single door
+/obj/machinery/embedded_controller/radio/simple_docking_controller
+ name = "docking hatch controller"
+ var/tag_door
+ var/datum/computer/file/embedded_program/docking/simple/docking_program
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/initialize()
+ ..()
+ docking_program = new/datum/computer/file/embedded_program/docking/simple(src)
+ program = docking_program
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ var/data[0]
+
+ data = list(
+ "docking_status" = docking_program.get_docking_status(),
+ "override_enabled" = docking_program.override_enabled,
+ )
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
+
+ if (!ui)
+ ui = new(user, src, ui_key, "simple_docking_console.tmpl", name, 470, 290)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ src.add_fingerprint(usr)
+
+ var/clean = 0
+ switch(href_list["command"]) //anti-HTML-hacking checks
+ if("force_door")
+ clean = 1
+ if("toggle_override")
+ clean = 1
+
+ if(clean)
+ program.receive_user_command(href_list["command"])
+
+ return 1
+
+
+//A docking controller program for a simple door based docking port
+/datum/computer/file/embedded_program/docking/simple
+ var/tag_door
+
+/datum/computer/file/embedded_program/docking/simple/New(var/obj/machinery/embedded_controller/M)
+ ..(M)
+ memory["door_status"] = list(state = "closed", lock = "locked") //assume closed and locked in case the doors dont report in
+ memory["door_status"] = list(state = "closed", lock = "locked")
+
+ if (istype(M, /obj/machinery/embedded_controller/radio/simple_docking_controller))
+ var/obj/machinery/embedded_controller/radio/simple_docking_controller/controller = M
+
+ tag_door = controller.tag_door
+
+ spawn(10)
+ signal_door("update") //signals connected doors to update their status
+
+
+/datum/computer/file/embedded_program/docking/simple/receive_signal(datum/signal/signal, receive_method, receive_param)
+ var/receive_tag = signal.data["tag"]
+
+ if(!receive_tag) return
+
+ if(receive_tag==tag_door)
+ memory["door_status"]["state"] = signal.data["door_status"]
+ memory["door_status"]["lock"] = signal.data["lock_status"]
+
+ ..(signal, receive_method, receive_param)
+
+/datum/computer/file/embedded_program/docking/simple/receive_user_command(command)
+ switch(command)
+ if("force_door")
+ if (override_enabled)
+ if(memory["door_status"]["state"] == "open")
+ close_door()
+ else
+ open_door()
+ if("toggle_override")
+ if (override_enabled)
+ disable_override()
+ else
+ enable_override()
+
+
+/datum/computer/file/embedded_program/docking/simple/proc/signal_door(var/command)
+ var/datum/signal/signal = new
+ signal.data["tag"] = tag_door
+ signal.data["command"] = command
+ post_signal(signal)
+
+/datum/computer/file/embedded_program/docking/simple/proc/open_door()
+ if(memory["door_status"]["state"] == "closed")
+ signal_door("secure_open")
+ else if(memory["door_status"]["lock"] == "unlocked")
+ signal_door("lock")
+
+/datum/computer/file/embedded_program/docking/simple/proc/close_door()
+ if(memory["door_status"]["state"] == "open")
+ signal_door("secure_close")
+ else if(memory["door_status"]["lock"] == "unlocked")
+ signal_door("lock")
+
+//tell the docking port to start getting ready for docking - e.g. pressurize
+/datum/computer/file/embedded_program/docking/simple/prepare_for_docking()
+ return //don't need to do anything
+
+//are we ready for docking?
+/datum/computer/file/embedded_program/docking/simple/ready_for_docking()
+ return 1 //don't need to do anything
+
+//we are docked, open the doors or whatever.
+/datum/computer/file/embedded_program/docking/simple/finish_docking()
+ open_door()
+
+//tell the docking port to start getting ready for undocking - e.g. close those doors.
+/datum/computer/file/embedded_program/docking/simple/prepare_for_undocking()
+ close_door()
+
+//are we ready for undocking?
+/datum/computer/file/embedded_program/docking/simple/ready_for_undocking()
+ return (memory["door_status"]["state"] == "closed" && memory["door_status"]["lock"] == "locked")
+
+/datum/computer/file/embedded_program/docking/simple/reset()
+ close_door()
+ ..()
+
+/*** DEBUG VERBS ***
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/verb/view_state()
+ set category = "Debug"
+ set src in view(1)
+ src.program:print_state()
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/verb/spoof_signal(var/command as text, var/sender as text)
+ set category = "Debug"
+ set src in view(1)
+ var/datum/signal/signal = new
+ signal.data["tag"] = sender
+ signal.data["command"] = command
+ signal.data["recipient"] = id_tag
+
+ src.program:receive_signal(signal)
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/verb/debug_init_dock(var/target as text)
+ set category = "Debug"
+ set src in view(1)
+ src.program:initiate_docking(target)
+
+/obj/machinery/embedded_controller/radio/simple_docking_controller/verb/debug_init_undock()
+ set category = "Debug"
+ set src in view(1)
+ src.program:initiate_undocking()
+*/
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/simple_vent_controller.dm b/code/game/machinery/embedded_controller/simple_vent_controller.dm
deleted file mode 100644
index f226d33f9ef..00000000000
--- a/code/game/machinery/embedded_controller/simple_vent_controller.dm
+++ /dev/null
@@ -1,79 +0,0 @@
-/datum/computer/file/embedded_program/simple_vent_controller
-
- var/airpump_tag
-
- receive_user_command(command)
- switch(command)
- if("vent_inactive")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "sigtype"="command"
- )
- signal.data["power"] = 0
- post_signal(signal)
-
- if("vent_pump")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = airpump_tag,
- "sigtype"="command"
- )
- signal.data["stabalize"] = 1
- signal.data["power"] = 1
- post_signal(signal)
-
- if("vent_clear")
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data = list(
- "tag" = airpump_tag,
- "sigtype"="command"
- )
- signal.data["purge"] = 1
- signal.data["power"] = 1
- post_signal(signal)
-
- process()
- return 0
-
-
-/obj/machinery/embedded_controller/radio/simple_vent_controller
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "airlock_control_standby"
-
- name = "Vent Controller"
- density = 0
- unacidable = 1
-
- frequency = 1229
- power_channel = ENVIRON
-
- // Setup parameters only
- var/airpump_tag
-
- initialize()
- ..()
-
- var/datum/computer/file/embedded_program/simple_vent_controller/new_prog = new
-
- new_prog.airpump_tag = airpump_tag
- new_prog.master = src
- program = new_prog
-
- update_icon()
- if(on && program)
- icon_state = "airlock_control_standby"
- else
- icon_state = "airlock_control_off"
-
-
- return_text()
- var/state_options = null
- state_options = {"Deactivate Vent
-Activate Vent / Pump
-Activate Vent / Clear
"}
- var/output = {"Vent Control Console
-[state_options]
"}
-
- return output
\ No newline at end of file
diff --git a/code/game/machinery/embedded_controller/smart_airlock_controller.dm b/code/game/machinery/embedded_controller/smart_airlock_controller.dm
deleted file mode 100644
index 032c1fa82c5..00000000000
--- a/code/game/machinery/embedded_controller/smart_airlock_controller.dm
+++ /dev/null
@@ -1,369 +0,0 @@
-//States for airlock_control
-#define AIRLOCK_STATE_WAIT 0
-#define AIRLOCK_STATE_DEPRESSURIZE 1
-#define AIRLOCK_STATE_PRESSURIZE 2
-
-#define AIRLOCK_TARGET_INOPEN -1
-#define AIRLOCK_TARGET_NONE 0
-#define AIRLOCK_TARGET_OUTOPEN 1
-
-datum/computer/file/embedded_program/smart_airlock_controller
- var/id_tag
- var/tag_exterior_door
- var/tag_interior_door
- var/tag_airpump
- var/tag_chamber_sensor
- var/tag_exterior_sensor
- var/tag_interior_sensor
- //var/sanitize_external
-
- state = AIRLOCK_STATE_WAIT
- var/target_state = AIRLOCK_TARGET_NONE
-
-datum/computer/file/embedded_program/smart_airlock_controller/New()
- ..()
- memory["chamber_sensor_pressure"] = ONE_ATMOSPHERE
- memory["external_sensor_pressure"] = ONE_ATMOSPHERE
- memory["internal_sensor_pressure"] = ONE_ATMOSPHERE
- memory["exterior_status"] = "unknown"
- memory["interior_status"] = "unknown"
- memory["pump_status"] = "unknown"
- memory["target_pressure"] = ONE_ATMOSPHERE
-
-datum/computer/file/embedded_program/smart_airlock_controller/receive_signal(datum/signal/signal, receive_method, receive_param)
- var/receive_tag = signal.data["tag"]
- if(!receive_tag) return
-
- if(receive_tag==tag_chamber_sensor)
- if(signal.data["pressure"])
- memory["chamber_sensor_pressure"] = text2num(signal.data["pressure"])
-
- else if(receive_tag==tag_exterior_sensor)
- if(signal.data["pressure"])
- memory["external_sensor_pressure"] = text2num(signal.data["pressure"])
-
- else if(receive_tag==tag_interior_sensor)
- if(signal.data["pressure"])
- memory["internal_sensor_pressure"] = text2num(signal.data["pressure"])
-
- else if(receive_tag==tag_exterior_door)
- memory["exterior_status"] = signal.data["door_status"]
-
- else if(receive_tag==tag_interior_door)
- memory["interior_status"] = signal.data["door_status"]
-
- else if(receive_tag==tag_airpump)
- if(signal.data["power"])
- memory["pump_status"] = signal.data["direction"]
- else
- memory["pump_status"] = "off"
-
- else if(receive_tag==id_tag)
- switch(signal.data["command"])
- if("cycle_exterior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_OUTOPEN
- if("cycle_interior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_INOPEN
-
- master.updateDialog()
-
-datum/computer/file/embedded_program/smart_airlock_controller/receive_user_command(command)
- var/shutdown_pump = 0
- switch(command)
- if("cycle_closed")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_NONE
- if(memory["interior_status"] != "closed")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_interior_door
- signal.data["command"] = "secure_close"
- post_signal(signal)
- if(memory["exterior_status"] != "closed")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_exterior_door
- signal.data["command"] = "secure_close"
- post_signal(signal)
- shutdown_pump = 1
- if("open_interior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_NONE
- if(memory["interior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_interior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- if("close_interior")
- if(memory["interior_status"] != "closed")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_interior_door
- signal.data["command"] = "secure_close"
- post_signal(signal)
- shutdown_pump = 1
- if("close_exterior")
- if(memory["exterior_status"] != "closed")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_exterior_door
- signal.data["command"] = "secure_close"
- post_signal(signal)
- shutdown_pump = 1
- if("open_exterior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_NONE
- if(memory["exterior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_exterior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- if("cycle_exterior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_OUTOPEN
- if("cycle_interior")
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_INOPEN
-
- if(shutdown_pump)
- //send a signal to stop pressurizing
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = tag_airpump,
- "power" = 0,
- "sigtype"="command"
- )
- post_signal(signal)
- master.updateDialog()
-
-datum/computer/file/embedded_program/smart_airlock_controller/process()
- var/process_again = 1
- while(process_again)
- process_again = 0
-
- if(!state && target_state)
- //we're ready to do stuff, now what do we want to do?
- switch(target_state)
- if(AIRLOCK_TARGET_INOPEN)
- memory["target_pressure"] = memory["internal_sensor_pressure"]
- if(AIRLOCK_TARGET_OUTOPEN)
- memory["target_pressure"] = memory["external_sensor_pressure"]
-
- //work out whether we need to pressurize or depressurize the chamber (5% leeway with target pressure)
- var/chamber_pressure = memory["chamber_sensor_pressure"]
- var/target_pressure = memory["target_pressure"]
- if(chamber_pressure <= target_pressure)
- state = AIRLOCK_STATE_PRESSURIZE
-
- //send a signal to start pressurizing
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = tag_airpump,
- "sigtype"="command",
- "power"=1,
- "direction"=1,
- "set_external_pressure"=target_pressure
- )
- post_signal(signal)
-
- else if(chamber_pressure > target_pressure)
- state = AIRLOCK_STATE_DEPRESSURIZE
-
- //send a signal to start depressurizing
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.data = list(
- "tag" = tag_airpump,
- "sigtype"="command",
- "power"=1,
- "direction"=0,
- "set_external_pressure"=target_pressure
- )
- post_signal(signal)
-
- //actually do stuff
- //override commands are handled elsewhere, otherwise everything proceeds automatically
- switch(state)
- if(AIRLOCK_STATE_PRESSURIZE)
- if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
- if(target_state < 0)
- if(memory["interior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_interior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else if(target_state > 0)
- if(memory["exterior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_exterior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_NONE
-
- //send a signal to stop pumping
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = tag_airpump,
- "sigtype"="command",
- "power" = 0
- )
- post_signal(signal)
- master.updateDialog()
-
- if(AIRLOCK_STATE_DEPRESSURIZE)
- if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05)
- if(target_state > 0)
- if(memory["exterior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_exterior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- else if(target_state < 0)
- if(memory["interior_status"] != "open")
- var/datum/signal/signal = new
- signal.data["tag"] = tag_interior_door
- signal.data["command"] = "secure_open"
- post_signal(signal)
- state = AIRLOCK_STATE_WAIT
- target_state = AIRLOCK_TARGET_NONE
-
- //send a signal to stop pumping
- if(memory["pump_status"] != "off")
- var/datum/signal/signal = new
- signal.data = list(
- "tag" = tag_airpump,
- "sigtype"="command",
- "power" = 0
- )
- post_signal(signal)
- master.updateDialog()
-
- //memory["sensor_pressure"] = sensor_pressure
- memory["processing"] = state != target_state
- //sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0
-
- return 1
-
-
-obj/machinery/embedded_controller/radio/smart_airlock_controller
- icon = 'icons/obj/airlock_machines.dmi'
- icon_state = "airlock_control_standby"
-
- name = "Cycling Airlock Console"
- density = 0
- unacidable = 1
- frequency = 1449
- power_channel = ENVIRON
-
- // Setup parameters only
- var/id_tag
- var/tag_exterior_door
- var/tag_interior_door
- var/tag_airpump
- var/tag_chamber_sensor
- var/tag_exterior_sensor
- var/tag_interior_sensor
- //var/sanitize_external
-
- initialize()
- ..()
-
- var/datum/computer/file/embedded_program/smart_airlock_controller/new_prog = new
-
- new_prog.id_tag = id_tag
- new_prog.tag_exterior_door = tag_exterior_door
- new_prog.tag_interior_door = tag_interior_door
- new_prog.tag_airpump = tag_airpump
- new_prog.tag_chamber_sensor = tag_chamber_sensor
- new_prog.tag_exterior_sensor = tag_exterior_sensor
- new_prog.tag_interior_sensor = tag_interior_sensor
- //new_prog.sanitize_external = sanitize_external
-
- new_prog.master = src
- program = new_prog
-
- update_icon()
- if(on && program)
- if(program.memory["processing"])
- icon_state = "airlock_control_process"
- else
- icon_state = "airlock_control_standby"
- else
- icon_state = "airlock_control_off"
-
-
- return_text()
- var/state_options = ""
-
- var/state = 0
- var/chamber_sensor_pressure = "----"
- var/external_sensor_pressure = "----"
- var/internal_sensor_pressure = "----"
- var/exterior_status = "----"
- var/interior_status = "----"
- var/pump_status = "----"
- var/target_pressure = "----"
- if(program)
- state = program.state
- chamber_sensor_pressure = program.memory["chamber_sensor_pressure"]
- external_sensor_pressure = program.memory["external_sensor_pressure"]
- internal_sensor_pressure = program.memory["internal_sensor_pressure"]
- exterior_status = program.memory["exterior_status"]
- interior_status = program.memory["interior_status"]
- pump_status = program.memory["pump_status"]
- target_pressure = program.memory["target_pressure"]
-
- var/exterior_closed = 0
- if(exterior_status == "closed")
- exterior_closed = 1
- var/interior_closed = 0
- if(interior_status == "closed")
- interior_closed = 1
-
- state_options += "Exterior status: [exterior_status] ([external_sensor_pressure] kPa)
"
- if(exterior_closed)
- state_options += "Open exterior airlock "
- if(abs(chamber_sensor_pressure - external_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
- state_options += "WARNING"
- state_options += "
"
- if(!state && exterior_closed && interior_closed)
- state_options += "Cycle to Exterior Airlock
"
- else
- state_options += "
"
- else
- state_options += "Close exterior airlock
"
- state_options += "
"
-
- state_options += "Interior status: [interior_status] ([internal_sensor_pressure] kPa)
"
- if(interior_closed)
- state_options += "Open interior airlock "
- if(abs(chamber_sensor_pressure - internal_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
- state_options += "WARNING"
- state_options += "
"
- if(!state && exterior_closed && interior_closed)
- state_options += "Cycle to Interior Airlock
"
- else
- state_options += "
"
- else
- state_options += "Close interior airlock
"
- state_options += "
"
-
- state_options += "
"
- state_options += "Chamber Pressure: [chamber_sensor_pressure] kPa
"
- state_options += "Target Chamber Pressure: [target_pressure] kPa
"
- state_options += "Control Pump: [pump_status]
"
- if(state)
- state_options += "Abort Cycling
"
- else
- state_options += "
"
-
- return state_options
-
-#undef AIRLOCK_STATE_PRESSURIZE
-#undef AIRLOCK_STATE_WAIT
-#undef AIRLOCK_STATE_DEPRESSURIZE
-
-#undef AIRLOCK_TARGET_INOPEN
-#undef AIRLOCK_TARGET_CLOSED
-#undef AIRLOCK_TARGET_OUTOPEN
diff --git a/maps/backup/cyberiad.dmm b/maps/backup/cyberiad.dmm
index 4c1c83cbbe4..816951614fe 100644
--- a/maps/backup/cyberiad.dmm
+++ b/maps/backup/cyberiad.dmm
@@ -7662,7 +7662,7 @@
"cRr" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cRs" = (/obj/item/flag/syndi,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cRt" = (/obj/structure/table,/obj/item/device/flashlight/lamp{pixel_x = 4; pixel_y = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
-"cRu" = (/obj/machinery/computer/syndicate_station{req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
+"cRu" = (/obj/machinery/computer/shuttle_control/multi/syndicate{req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cRv" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cRw" = (/obj/structure/computerframe,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cRx" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{tag = "icon-gravsnow_corner (WEST)"; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership)
diff --git a/maps/cyberiad.dmm b/maps/cyberiad.dmm
index 816951614fe..2423f6a58af 100644
--- a/maps/cyberiad.dmm
+++ b/maps/cyberiad.dmm
@@ -979,7 +979,7 @@
"asQ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "security_airlock"; name = "interior access button"; pixel_x = 20; pixel_y = 20; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple{dir = 5; icon_state = "intact"; level = 2},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"asR" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "security_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"asS" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "security_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "security_sensor"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
-"asT" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "security_pump"; exterior_door_tag = "security_outer"; frequency = 1379; id_tag = "security_airlock"; interior_door_tag = "security_inner"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"; sensor_tag = "security_sensor"},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
+"asT" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "security_pump"; tag_exterior_door = "security_outer"; frequency = 1379; id_tag = "security_airlock"; tag_interior_door = "security_inner"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"; tag_chamber_sensor = "security_sensor"},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"asU" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "security_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"asV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "security_airlock"; name = "exterior access button"; pixel_x = -20; pixel_y = -20; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/fsmaint)
"asW" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/shuttle/escape_pod1/station)
@@ -1375,7 +1375,7 @@
"aAw" = (/turf/simulated/wall/r_wall,/area/security/checkpoint2)
"aAx" = (/obj/machinery/atmospherics/unary/vent_pump,/obj/structure/closet/secure_closet/personal,/obj/item/clothing/shoes/orange,/obj/item/clothing/under/color/orange,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/checkpoint2)
"aAy" = (/obj/structure/stool/bed,/obj/machinery/atmospherics/unary/vent_scrubber,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/checkpoint2)
-"aAz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "solar_tool_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_tool_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "solar_tool_pump"; exterior_door_tag = "solar_tool_outer"; frequency = 1379; id_tag = "solar_tool_airlock"; interior_door_tag = "solar_tool_inner"; pixel_x = 25; req_access_txt = "13"; sensor_tag = "solar_tool_sensor"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
+"aAz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "solar_tool_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_tool_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_tool_pump"; tag_exterior_door = "solar_tool_outer"; frequency = 1379; id_tag = "solar_tool_airlock"; tag_interior_door = "solar_tool_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_tool_sensor"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
"aAA" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple{icon_state = "intact"; dir = 10; pixel_x = 0; level = 2; initialize_directions = 10},/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/turf/simulated/floor/plating,/area)
"aAB" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
"aAC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
@@ -1458,7 +1458,7 @@
"aCb" = (/obj/machinery/camera{c_tag = "Fitness Room South"; dir = 1},/obj/machinery/light,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/crew_quarters/fitness)
"aCc" = (/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 1},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area)
"aCd" = (/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/window/plasmareinforced{dir = 1},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area)
-"aCe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "solar_chapel_pump"; exterior_door_tag = "solar_chapel_outer"; frequency = 1379; id_tag = "solar_chapel_airlock"; interior_door_tag = "solar_chapel_inner"; pixel_x = 25; req_access_txt = "13"; sensor_tag = "solar_chapel_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_chapel_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "solar_chapel_pump"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
+"aCe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_chapel_pump"; tag_exterior_door = "solar_chapel_outer"; frequency = 1379; id_tag = "solar_chapel_airlock"; tag_interior_door = "solar_chapel_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_chapel_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_chapel_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "solar_chapel_pump"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
"aCf" = (/obj/structure/table/reinforced,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/wood,/area/secret/gaybar)
"aCg" = (/obj/machinery/door/window/southleft{name = "DJ Booth"},/turf/simulated/floor/wood,/area/secret/gaybar)
"aCh" = (/obj/machinery/party/lasermachine,/turf/simulated/floor/wood,/area/secret/gaybar)
@@ -5654,7 +5654,7 @@
"ceL" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator)
"ceM" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/wall/r_wall,/area)
"ceN" = (/obj/machinery/atmospherics/binary/pump{dir = 8; icon_state = "intact_on"; on = 1},/obj/machinery/light/small{dir = 1},/obj/machinery/access_button{command = "cycle_exterior"; layer = 3.1; master_tag = "incinerator_access_control"; name = "Incinerator airlock control"; pixel_x = -22; pixel_y = -10},/obj/structure/sign/fire{pixel_y = 32},/turf/simulated/floor/plating,/area/maintenance/incinerator)
-"ceO" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/embedded_controller/radio/access_controller{exterior_door_tag = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; interior_door_tag = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -26; pixel_y = 6; req_access_txt = "12"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -24; pixel_y = -6},/obj/machinery/meter,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
+"ceO" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; tag_interior_door = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -26; pixel_y = 6; req_access_txt = "12"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = -24; pixel_y = -6},/obj/machinery/meter,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"ceP" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"ceQ" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
"ceR" = (/obj/machinery/atmospherics/pipe/manifold{icon_state = "manifold"; level = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator)
@@ -5943,7 +5943,7 @@
"cko" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; icon_state = "off"; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/toxins/xenobiology)
"ckp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold{_color = "red"; dir = 4; icon_state = "manifold-r-f"; initialize_directions = 11; level = 1; name = "pipe manifold"},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
"ckq" = (/obj/structure/closet/emcloset,/obj/machinery/camera/xray{c_tag = "Xenobiology Access"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/toxins/xenobiology)
-"ckr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "solar_xeno_pump"; exterior_door_tag = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; interior_door_tag = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; sensor_tag = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/solar/starboard)
+"ckr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/solar/starboard)
"cks" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction,/turf/simulated/floor/engine,/area/toxins/mixing)
"ckt" = (/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor/engine,/area/toxins/mixing)
"cku" = (/obj/machinery/igniter{icon_state = "igniter0"; id = "ToxinsIgnitor"; on = 0},/turf/simulated/floor/engine,/area/toxins/mixing)
@@ -6123,7 +6123,7 @@
"cnM" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/toxins/xenobiology)
"cnN" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
"cnO" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/camera{c_tag = "Xenobiology Module North"; dir = 2; network = list("SS13"); pixel_x = 0},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
-"cnP" = (/obj/machinery/embedded_controller/radio/access_controller{exterior_door_tag = "xeno_airlock_exterior"; id_tag = "xeno_airlock_control"; interior_door_tag = "xeno_airlock_interior"; name = "Xenobiology Access Console"; pixel_x = 8; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/light_switch{pixel_x = -6; pixel_y = 26},/turf/simulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/toxins/xenobiology)
+"cnP" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "xeno_airlock_exterior"; id_tag = "xeno_airlock_control"; tag_interior_door = "xeno_airlock_interior"; name = "Xenobiology Access Console"; pixel_x = 8; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/light_switch{pixel_x = -6; pixel_y = 26},/turf/simulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/toxins/xenobiology)
"cnQ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/toxins/xenobiology)
"cnR" = (/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "Xenobiology APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor{dir = 1; icon_state = "whitegreencorner"},/area/toxins/xenobiology)
"cnS" = (/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
@@ -6402,7 +6402,7 @@
"ctf" = (/turf/simulated/floor/plating/airless,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk12"; icon_state = "catwalk12"},/area/solar/port)
"ctg" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "robotics_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk8"; icon_state = "catwalk8"},/area/solar/port)
"cth" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/portsolar)
-"cti" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "robotics_solar_pump"; exterior_door_tag = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; interior_door_tag = "robotics_solar_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; sensor_tag = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/maintenance/portsolar)
+"cti" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"ctj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"ctk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple{dir = 9; icon_state = "intact"; level = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/portsolar)
"ctl" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/portsolar)
@@ -6500,7 +6500,7 @@
"cuZ" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/manifold{_color = "cyan"; dir = 4; icon_state = "manifold-c"; initialize_directions = 11; level = 2},/obj/structure/window/plasmareinforced{dir = 4},/turf/simulated/floor/plating,/area)
"cva" = (/obj/machinery/vending/coffee,/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cvb" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
-"cvc" = (/obj/machinery/embedded_controller/radio/access_controller{exterior_door_tag = "virology_airlock_exterior"; id_tag = "virology_airlock_control"; interior_door_tag = "virology_airlock_interior"; name = "Virology Access Console"; pixel_x = -8; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
+"cvc" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "virology_airlock_exterior"; id_tag = "virology_airlock_control"; tag_interior_door = "virology_airlock_interior"; name = "Virology Access Console"; pixel_x = -8; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cvd" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Lab"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cve" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cvf" = (/obj/machinery/atmospherics/pipe/manifold{_color = "red"; dir = 4; icon_state = "manifold-r-f"; initialize_directions = 11; level = 1; name = "pipe manifold"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
@@ -6957,13 +6957,13 @@
"cDO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/reactor_core)
"cDP" = (/obj/machinery/atmospherics/pipe/simple{_color = "blue"; dir = 6; icon_state = "intact-b"; initialize_directions = 6; level = 2; name = "pipe"},/turf/simulated/floor/plating,/area/engine/reactor_core)
"cDQ" = (/obj/machinery/atmospherics/pipe/simple{_color = "blue"; dir = 9; icon_state = "intact-b-f"; level = 2; name = "pipe"},/turf/simulated/floor/plating,/area/engine/reactor_core)
-"cDR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "engineering_west_pump"; exterior_door_tag = "engineering_west_outer"; frequency = 1379; id_tag = "engineering_west_airlock"; interior_door_tag = "engineering_west_inner"; pixel_x = 25; req_access_txt = "10;13"; sensor_tag = "engineering_west_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_west_sensor"; pixel_x = 25; pixel_y = 12},/turf/simulated/floor/plating,/area/engine/engineering)
+"cDR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "engineering_west_pump"; tag_exterior_door = "engineering_west_outer"; frequency = 1379; id_tag = "engineering_west_airlock"; tag_interior_door = "engineering_west_inner"; pixel_x = 25; req_access_txt = "10;13"; tag_chamber_sensor = "engineering_west_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_west_sensor"; pixel_x = 25; pixel_y = 12},/turf/simulated/floor/plating,/area/engine/engineering)
"cDS" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 4},/turf/simulated/floor/plating,/area)
"cDT" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engine/engineering)
"cDU" = (/obj/item/weapon/wirecutters,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/engine/engineering)
"cDV" = (/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/engine/engineering)
"cDW" = (/obj/structure/grille,/obj/structure/window/plasmareinforced{dir = 8},/turf/simulated/floor/plating,/area)
-"cDX" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "engineering_east_pump"; exterior_door_tag = "engineering_east_outer"; frequency = 1379; id_tag = "engineering_east_airlock"; interior_door_tag = "engineering_east_inner"; pixel_x = -25; req_access_txt = "10;13"; sensor_tag = "engineering_east_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_east_sensor"; pixel_x = -25; pixel_y = 12},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering)
+"cDX" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "engineering_east_pump"; tag_exterior_door = "engineering_east_outer"; frequency = 1379; id_tag = "engineering_east_airlock"; tag_interior_door = "engineering_east_inner"; pixel_x = -25; req_access_txt = "10;13"; tag_chamber_sensor = "engineering_east_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "engineering_east_sensor"; pixel_x = -25; pixel_y = 12},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/engine/engineering)
"cDY" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "engineering_east_pump"},/turf/simulated/floor/plating,/area/engine/engineering)
"cDZ" = (/obj/machinery/camera{c_tag = "Atmospherics South West"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple{_color = "red"; icon_state = "intact-r"; level = 2},/obj/structure/stool,/turf/simulated/floor,/area/atmos)
"cEa" = (/obj/structure/table,/obj/item/pipe,/obj/item/weapon/wrench,/turf/simulated/floor,/area/atmos)
@@ -7774,7 +7774,7 @@
"cTz" = (/obj/machinery/door/window{dir = 4; name = "Equipment Room"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cTA" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "synd_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cTB" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "synd_inner"; locked = 1; name = "Ship External Access"; req_access = null; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
-"cTC" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "synd_pump"; exterior_door_tag = "synd_outer"; frequency = 1331; id_tag = "synd_airlock"; interior_door_tag = "synd_inner"; pixel_x = 25; req_access_txt = "0"; sensor_tag = "synd_sensor"},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "synd_sensor"; pixel_x = 25; pixel_y = 12},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
+"cTC" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "synd_pump"; tag_exterior_door = "synd_outer"; frequency = 1331; id_tag = "synd_airlock"; tag_interior_door = "synd_inner"; pixel_x = 25; req_access_txt = "0"; tag_chamber_sensor = "synd_sensor"},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "synd_sensor"; pixel_x = 25; pixel_y = 12},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cTD" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/wood{tag = "icon-wood-broken4"; icon_state = "wood-broken4"},/area/syndicate_mothership)
"cTE" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Equipment Room"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cTF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/syndicate_station/start)
@@ -9454,7 +9454,7 @@
"dzP" = (/obj/structure/closet/malf/suits,/turf/simulated/floor,/area/tcommsat/entrance)
"dzQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area)
"dzR" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_outer"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/tcommsat/entrance)
-"dzS" = (/obj/machinery/camera/xray{c_tag = "External Airlock"; network = list("Tcomsat")},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1381; id_tag = "telecoms_pump"},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "telecoms_pump"; exterior_door_tag = "telecoms_outer"; frequency = 1381; id_tag = "telecoms_airlock"; interior_door_tag = "telecoms_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; sensor_tag = "telecoms_sensor"},/obj/machinery/airlock_sensor{frequency = 1381; id_tag = "telecoms_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/tcommsat/entrance)
+"dzS" = (/obj/machinery/camera/xray{c_tag = "External Airlock"; network = list("Tcomsat")},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1381; id_tag = "telecoms_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "telecoms_pump"; tag_exterior_door = "telecoms_outer"; frequency = 1381; id_tag = "telecoms_airlock"; tag_interior_door = "telecoms_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "telecoms_sensor"},/obj/machinery/airlock_sensor{frequency = 1381; id_tag = "telecoms_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/tcommsat/entrance)
"dzT" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_inner"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/tcommsat/entrance)
"dzU" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 9},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/tcommsat/entrance)
"dzV" = (/obj/machinery/bluespace_beacon,/turf/simulated/floor,/area/tcommsat/entrance)
@@ -10579,7 +10579,7 @@
"dVw" = (/turf/simulated/floor/mech_bay_recharge_floor{icon_state = "recharge_floor_asteroid"},/area/research_outpost/gearstore)
"dVx" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/research_outpost/gearstore)
"dVy" = (/obj/machinery/atmospherics/pipe/simple{dir = 5; icon_state = "intact-f"},/turf/simulated/wall,/area/research_outpost/gearstore)
-"dVz" = (/obj/machinery/light/small{dir = 8},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "research_pump"; exterior_door_tag = "research_outer"; frequency = 1379; id_tag = "research_airlock"; interior_door_tag = "research_inner"; pixel_x = -25; pixel_y = 0; req_access_txt = null; sensor_tag = "research_sensor"},/obj/machinery/atmospherics/pipe/simple{dir = 4; level = 1},/turf/simulated/floor,/area/research_outpost/gearstore)
+"dVz" = (/obj/machinery/light/small{dir = 8},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "research_pump"; tag_exterior_door = "research_outer"; frequency = 1379; id_tag = "research_airlock"; tag_interior_door = "research_inner"; pixel_x = -25; pixel_y = 0; req_access_txt = null; tag_chamber_sensor = "research_sensor"},/obj/machinery/atmospherics/pipe/simple{dir = 4; level = 1},/turf/simulated/floor,/area/research_outpost/gearstore)
"dVA" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor,/area/research_outpost/gearstore)
"dVB" = (/obj/structure/closet/emcloset,/turf/simulated/floor,/area/research_outpost/gearstore)
"dVC" = (/obj/machinery/door/window/westleft,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/explored)
@@ -10737,7 +10737,7 @@
"dYy" = (/obj/machinery/atmospherics/pipe/simple{dir = 6; icon_state = "intact"; level = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1399; master_tag = "nmining_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/turf/simulated/floor/plating,/area/mine/north_outpost)
"dYz" = (/obj/machinery/door/airlock/external{frequency = 1399; icon_state = "door_locked"; id_tag = "nmining_inner"; locked = 1; name = "North Mining External Access"; req_access = null; req_access_txt = "null"},/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor/plating,/area/mine/north_outpost)
"dYA" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1399; id_tag = "nmining_pump"},/obj/machinery/airlock_sensor{frequency = 1399; id_tag = "nmining_sensor"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/plating,/area/mine/north_outpost)
-"dYB" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "nmining_pump"; exterior_door_tag = "NMining_outer"; frequency = 1399; id_tag = "nmining_airlock"; interior_door_tag = "nmining_inner"; pixel_x = 0; pixel_y = 25; req_access_txt = "null"; sensor_tag = "nmining_sensor"},/obj/machinery/light/small,/turf/simulated/floor/plating,/area/mine/north_outpost)
+"dYB" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "nmining_pump"; tag_exterior_door = "NMining_outer"; frequency = 1399; id_tag = "nmining_airlock"; tag_interior_door = "nmining_inner"; pixel_x = 0; pixel_y = 25; req_access_txt = "null"; tag_chamber_sensor = "nmining_sensor"},/obj/machinery/light/small,/turf/simulated/floor/plating,/area/mine/north_outpost)
"dYC" = (/obj/machinery/door/airlock/external{frequency = 1399; icon_state = "door_locked"; id_tag = "NMining_outer"; locked = 1; name = "North Mining External"; req_access = null; req_access_txt = "null"},/turf/simulated/floor/plating,/area/mine/north_outpost)
"dYD" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1399; master_tag = "nmining_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/turf/simulated/floor/plating/airless,/area/mine/explored)
"dYE" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plating,/area/mine/north_outpost)
@@ -10881,7 +10881,7 @@
"ebm" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/item/clothing/glasses/meson,/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/mine/west_outpost)
"ebn" = (/obj/machinery/door/airlock/glass_mining{name = "Break Room"; req_access_txt = "54"},/turf/simulated/floor,/area/mine/west_outpost)
"ebo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/west_outpost)
-"ebp" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "outpost_west_pump"; exterior_door_tag = "outpost_west_outer"; frequency = 1379; id_tag = "outpost_west_airlock"; interior_door_tag = "outpost_west_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; sensor_tag = "outpost_west_sensor"},/turf/simulated/floor,/area/mine/west_outpost)
+"ebp" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "outpost_west_pump"; tag_exterior_door = "outpost_west_outer"; frequency = 1379; id_tag = "outpost_west_airlock"; tag_interior_door = "outpost_west_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_chamber_sensor = "outpost_west_sensor"},/turf/simulated/floor,/area/mine/west_outpost)
"ebq" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "outpost_west_sensor"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/west_outpost)
"ebr" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters)
"ebs" = (/obj/machinery/camera{c_tag = "Crew Area"; dir = 1; network = list("MINE")},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters)
@@ -10954,7 +10954,7 @@
"ecH" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor,/area/mine/eva)
"ecI" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/turf/simulated/floor,/area/mine/eva)
"ecJ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/turf/simulated/floor,/area/mine/eva)
-"ecK" = (/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "mining_east_pump"; exterior_door_tag = "mining_east_outer"; frequency = 1379; id_tag = "mining_east_airlock"; interior_door_tag = "mining_east_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; sensor_tag = "mining_east_sensor"},/turf/simulated/floor,/area/mine/eva)
+"ecK" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_east_pump"; tag_exterior_door = "mining_east_outer"; frequency = 1379; id_tag = "mining_east_airlock"; tag_interior_door = "mining_east_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_chamber_sensor = "mining_east_sensor"},/turf/simulated/floor,/area/mine/eva)
"ecL" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_east_sensor"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/eva)
"ecM" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_outer"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/turf/simulated/floor/plating,/area/mine/eva)
"ecN" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/turf/simulated/floor/airless{tag = "icon-asteroidwarning (EAST)"; icon_state = "asteroidwarning"; dir = 4},/area/mine/explored)
@@ -11045,7 +11045,7 @@
"eeu" = (/obj/machinery/atmospherics/pipe/manifold{dir = 8},/turf/simulated/floor/plating,/area/mine/living_quarters)
"eev" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/mine/living_quarters)
"eew" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/living_quarters)
-"eex" = (/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_sensor"; pixel_x = 25; pixel_y = -5},/obj/machinery/embedded_controller/radio/airlock_controller{airpump_tag = "mining_west_pump"; exterior_door_tag = "mining_west_outer"; frequency = 1379; id_tag = "mining_west_airlock"; interior_door_tag = "mining_west_inner"; pixel_x = 25; pixel_y = 5; req_access_txt = null; sensor_tag = "mining_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_pump"},/obj/structure/closet/emcloset,/turf/simulated/floor,/area/mine/living_quarters)
+"eex" = (/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_sensor"; pixel_x = 25; pixel_y = -5},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_west_pump"; tag_exterior_door = "mining_west_outer"; frequency = 1379; id_tag = "mining_west_airlock"; tag_interior_door = "mining_west_inner"; pixel_x = 25; pixel_y = 5; req_access_txt = null; tag_chamber_sensor = "mining_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_pump"},/obj/structure/closet/emcloset,/turf/simulated/floor,/area/mine/living_quarters)
"eey" = (/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor,/area/mine/production)
"eez" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor,/area/mine/production)
"eeA" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production)