diff --git a/baystation12.dme b/baystation12.dme
index 8f2c766a274..fcc7b36f2f2 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1228,6 +1228,7 @@
#include "code\modules\nano\nanomapgen.dm"
#include "code\modules\nano\nanoprocs.dm"
#include "code\modules\nano\nanoui.dm"
+#include "code\modules\nano\modules\crew_monitor.dm"
#include "code\modules\nano\modules\rcon.dm"
#include "code\modules\organs\blood.dm"
#include "code\modules\organs\organ.dm"
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index 06fd906ea88..b5394328b83 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -6,11 +6,10 @@
idle_power_usage = 250
active_power_usage = 500
circuit = "/obj/item/weapon/circuitboard/crew"
- var/list/tracked = list( )
-
+ var/obj/nano_module/crew_monitor/crew_monitor
/obj/machinery/computer/crew/New()
- tracked = list()
+ crew_monitor = new(src)
..()
@@ -25,6 +24,8 @@
return
ui_interact(user)
+/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ crew_monitor.ui_interact(user, ui_key, ui, force_open)
/obj/machinery/computer/crew/update_icon()
@@ -38,93 +39,5 @@
icon_state = initial(icon_state)
stat &= ~NOPOWER
-
-/obj/machinery/computer/crew/Topic(href, href_list)
- if(..()) return
- if (src.z > 6)
- usr << "\red Unable to establish a connection: \black You're too far away from the station!"
- return 0
- if( href_list["close"] )
- var/mob/user = usr
- var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
- usr.unset_machine()
- ui.close()
- return 0
- if(href_list["update"])
- src.updateDialog()
- return 1
-
/obj/machinery/computer/crew/interact(mob/user)
- ui_interact(user)
-
-/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
- if(stat & (BROKEN|NOPOWER))
- return
- user.set_machine(src)
- src.scan()
-
- var/data[0]
- var/list/crewmembers = list()
-
- for(var/obj/item/clothing/under/C in src.tracked)
-
- var/turf/pos = get_turf(C)
-
- if((C) && (C.has_sensor) && (pos) && (pos.z == src.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
- if(istype(C.loc, /mob/living/carbon/human))
-
- var/mob/living/carbon/human/H = C.loc
- if(H.w_uniform != C)
- continue
-
- var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1)
-
- crewmemberData["sensor_type"] = C.sensor_mode
- crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
- crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
- crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
-
- if(C.sensor_mode >= SUIT_SENSOR_BINARY)
- crewmemberData["dead"] = H.stat > 1
-
- if(C.sensor_mode >= SUIT_SENSOR_VITAL)
- crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
- crewmemberData["tox"] = round(H.getToxLoss(), 1)
- crewmemberData["fire"] = round(H.getFireLoss(), 1)
- crewmemberData["brute"] = round(H.getBruteLoss(), 1)
-
- if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
- var/area/A = get_area(H)
- crewmemberData["area"] = sanitize(A.name)
- crewmemberData["x"] = pos.x
- crewmemberData["y"] = pos.y
-
- crewmembers[++crewmembers.len] = crewmemberData
-
- crewmembers = sortByKey(crewmembers, "name")
-
- data["crewmembers"] = crewmembers
-
- ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
- if(!ui)
- ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800)
-
- // adding a template with the key "mapContent" enables the map ui functionality
- ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
- // adding a template with the key "mapHeader" replaces the map header content
- ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
-
- ui.set_initial_data(data)
- ui.open()
-
- // should make the UI auto-update; doesn't seem to?
- ui.set_auto_update(1)
-
-
-/obj/machinery/computer/crew/proc/scan()
- for(var/mob/living/carbon/human/H in mob_list)
- if(istype(H.w_uniform, /obj/item/clothing/under))
- var/obj/item/clothing/under/C = H.w_uniform
- if (C.has_sensor)
- tracked |= C
- return 1
+ crew_monitor.ui_interact(user)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index c0601f9c595..7cfb7c76944 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -24,7 +24,8 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/show_laws_verb,
/mob/living/silicon/ai/proc/toggle_acceleration,
/mob/living/silicon/ai/proc/toggle_camera_light,
- /mob/living/silicon/ai/proc/nano_rcon
+ /mob/living/silicon/ai/proc/nano_rcon,
+ /mob/living/silicon/ai/proc/nano_crew_monitor
)
//Not sure why this is necessary...
diff --git a/code/modules/mob/living/silicon/ai/nano.dm b/code/modules/mob/living/silicon/ai/nano.dm
index fe572a0a2f5..6925f2560bd 100644
--- a/code/modules/mob/living/silicon/ai/nano.dm
+++ b/code/modules/mob/living/silicon/ai/nano.dm
@@ -1,6 +1,8 @@
+var/obj/nano_module/crew_monitor/crew_monitor
var/obj/nano_module/rcon/rcon
/mob/living/silicon/ai/proc/init_subsystems()
+ crew_monitor = new(src)
rcon = new(src)
/mob/living/silicon/ai/proc/nano_rcon()
@@ -8,3 +10,9 @@ var/obj/nano_module/rcon/rcon
set name = "RCON"
rcon.ui_interact(usr)
+
+/mob/living/silicon/ai/proc/nano_crew_monitor()
+ set category = "AI Subystems"
+ set name = "Crew Monitor"
+
+ crew_monitor.ui_interact(usr)
diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm
new file mode 100644
index 00000000000..73ba6d482df
--- /dev/null
+++ b/code/modules/nano/modules/crew_monitor.dm
@@ -0,0 +1,86 @@
+/obj/nano_module/crew_monitor
+ var/list/tracked = new
+
+/obj/nano_module/crew_monitor/Topic(href, href_list)
+ if(..()) return
+ if (!(src.loc.z in config.player_levels))
+ usr << "Unable to establish a connection: You're too far away from the station!"
+ return 0
+ if(href_list["close"] )
+ var/mob/user = usr
+ var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
+ usr.unset_machine()
+ ui.close()
+ return 0
+ if(href_list["update"])
+ src.updateDialog()
+ return 1
+
+/obj/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+ src.scan()
+
+ var/data[0]
+ var/list/crewmembers = list()
+
+ for(var/obj/item/clothing/under/C in src.tracked)
+
+ var/turf/pos = get_turf(C)
+
+ if((C) && (C.has_sensor) && (pos) && (pos.z == src.loc.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
+ if(istype(C.loc, /mob/living/carbon/human))
+
+ var/mob/living/carbon/human/H = C.loc
+ if(H.w_uniform != C)
+ continue
+
+ var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1)
+
+ crewmemberData["sensor_type"] = C.sensor_mode
+ crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
+ crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
+ crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
+
+ if(C.sensor_mode >= SUIT_SENSOR_BINARY)
+ crewmemberData["dead"] = H.stat > 1
+
+ if(C.sensor_mode >= SUIT_SENSOR_VITAL)
+ crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
+ crewmemberData["tox"] = round(H.getToxLoss(), 1)
+ crewmemberData["fire"] = round(H.getFireLoss(), 1)
+ crewmemberData["brute"] = round(H.getBruteLoss(), 1)
+
+ if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
+ var/area/A = get_area(H)
+ crewmemberData["area"] = sanitize(A.name)
+ crewmemberData["x"] = pos.x
+ crewmemberData["y"] = pos.y
+
+ crewmembers[++crewmembers.len] = crewmemberData
+
+ crewmembers = sortByKey(crewmembers, "name")
+
+ data["crewmembers"] = crewmembers
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800)
+
+ // adding a template with the key "mapContent" enables the map ui functionality
+ ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
+ // adding a template with the key "mapHeader" replaces the map header content
+ ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
+
+ ui.set_initial_data(data)
+ ui.open()
+
+ // should make the UI auto-update; doesn't seem to?
+ ui.set_auto_update(1)
+
+/obj/nano_module/crew_monitor/proc/scan()
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(istype(H.w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/C = H.w_uniform
+ if (C.has_sensor)
+ tracked |= C
+ return 1