centralized alarms

This commit is contained in:
Fox McCloud
2020-07-11 13:56:11 -04:00
parent 729e9b8922
commit 2fb2fe99f8
11 changed files with 126 additions and 201 deletions
+4
View File
@@ -726,3 +726,7 @@
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
///from monkey CtrlClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
///SSalarm signals
#define COMSIG_TRIGGERED_ALARM "ssalarm_triggered"
#define COMSIG_CANCELLED_ALARM "ssalarm_cancelled"
+32
View File
@@ -0,0 +1,32 @@
SUBSYSTEM_DEF(alarm)
name = "Alarm"
flags = SS_NO_INIT | SS_NO_FIRE
var/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" = list())
/datum/controller/subsystem/alarm/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
var/list/L = alarms[class]
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if(!(alarmsource.UID() in sources))
sources += alarmsource.UID()
return TRUE
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
SEND_SIGNAL(SSalarm, COMSIG_TRIGGERED_ALARM, class, A, O, alarmsource)
return TRUE
/datum/controller/subsystem/alarm/proc/cancelAlarm(class, area/A, obj/origin)
var/list/L = alarms[class]
var/cleared = FALSE
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if(origin.UID() in srcs)
srcs -= origin.UID()
if(srcs.len == 0)
cleared = TRUE
L -= I
SEND_SIGNAL(SSalarm, COMSIG_CANCELLED_ALARM, class, A, origin, cleared)
+13 -61
View File
@@ -176,26 +176,10 @@
else
C.network |= "Power Alarms"
for(var/item in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = item
if(state == 1)
aiPlayer.cancelAlarm("Power", src, source)
else
aiPlayer.triggerAlarm("Power", src, cameras, source)
for(var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
if(state == 1)
a.cancelAlarm("Power", src, source)
else
a.triggerAlarm("Power", src, cameras, source)
/* for(var/item in GLOB.alarmdisplay) //TO-DO:TGUI--Uncomment Modular computers
var/datum/computer_file/program/alarm_monitor/p = item
if(state == 1)
p.cancelAlarm("Power", src, source)
else
p.triggerAlarm("Power", src, cameras, source) */
if(state == 1)
SSalarm.cancelAlarm("Power", src, source)
else
SSalarm.triggerAlarm("Power", src, cameras, source)
/**
* Generate an atmospheric alert for this area
@@ -211,30 +195,16 @@
if(!QDELETED(C))
C.network |= "Atmosphere Alarms"
for(var/item in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Atmosphere", src, cameras, source)
for(var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Atmosphere", src, cameras, source)
/* for(var/item in GLOB.alarmdisplay) //TO-DO:TGUI--Uncomment Modular computers
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Atmosphere", src, cameras, source) */
SSalarm.triggerAlarm("Atmosphere", src, cameras, source)
else if(atmosalm == ATMOS_ALARM_DANGER)
for(var/thing in cameras)
var/obj/machinery/camera/C = locateUID(thing)
if(!QDELETED(C))
C.network -= "Atmosphere Alarms"
for(var/item in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Atmosphere", src, source)
for(var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Atmosphere", src, source)
/* for(var/item in GLOB.alarmdisplay) //TO-DO:TGUI--Uncomment Modular computers
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Atmosphere", src, source) */
SSalarm.cancelAlarm("Atmosphere", src, source)
atmosalm = danger_level
return TRUE
@@ -284,15 +254,7 @@
if(!QDELETED(C))
C.network |= "Fire Alarms"
for(var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Fire", src, cameras, source)
for(var/item in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Fire", src, cameras, source)
/* for(var/item in GLOB.alarmdisplay) //TO-DO:TGUI--Uncomment Modular computers
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Fire", src, cameras, source) */
SSalarm.triggerAlarm("Fire", src, cameras, source)
START_PROCESSING(SSobj, src)
@@ -317,15 +279,7 @@
if(!QDELETED(C))
C.network -= "Fire Alarms"
for(var/item in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Fire", src, source)
for(var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Fire", src, source)
/* for(var/item in GLOB.alarmdisplay) //TO-DO:TGUI--Uncomment Modular computers
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Fire", src, source) */
SSalarm.cancelAlarm("Fire", src, source)
STOP_PROCESSING(SSobj, src)
@@ -386,11 +340,9 @@
for(var/obj/machinery/door/DOOR in src)
close_and_lock_door(DOOR)
for(var/i in GLOB.silicon_mob_list)
var/mob/living/silicon/SILICON = i
if(SILICON.triggerAlarm("Burglar", src, cameras, trigger))
//Cancel silicon alert after 1 minute
addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm, "Burglar", src, trigger), 600)
if(SSalarm.triggerAlarm("Burglar", src, cameras, trigger))
//Cancel silicon alert after 1 minute
addtimer(CALLBACK(SSalarm, /datum/controller/subsystem/alarm.proc/cancelAlarm, "Burglar", src, trigger), 600)
/**
* Trigger the fire alarm visual affects in an area
+2 -4
View File
@@ -332,13 +332,11 @@
/obj/machinery/camera/proc/triggerCameraAlarm()
alarm_on = TRUE
for(var/mob/living/silicon/S in GLOB.silicon_mob_list)
S.triggerAlarm("Camera", get_area(src), list(UID()), src)
SSalarm.triggerAlarm("Camera", get_area(src), list(UID()), src)
/obj/machinery/camera/proc/cancelCameraAlarm()
alarm_on = FALSE
for(var/mob/living/silicon/S in GLOB.silicon_mob_list)
S.cancelAlarm("Camera", get_area(src), src)
SSalarm.cancelAlarm("Camera", get_area(src), src)
/obj/machinery/camera/proc/can_use()
if(!status)
+5 -8
View File
@@ -44,20 +44,17 @@
/obj/machinery/camera/proc/cancelAlarm()
if(detectTime == -1)
for(var/i in GLOB.silicon_mob_list)
var/mob/living/silicon/aiPlayer = i
if(status)
aiPlayer.cancelAlarm("Motion", get_area(src), src)
if(status)
SSalarm.cancelAlarm("Motion", get_area(src), src)
detectTime = 0
return TRUE
/obj/machinery/camera/proc/triggerAlarm()
if(!detectTime)
return FALSE
for(var/mob/living/silicon/aiPlayer in GLOB.player_list)
if(status)
aiPlayer.triggerAlarm("Motion", get_area(src), list(UID()), src)
visible_message("<span class='warning'>A red light flashes on the [src]!</span>")
if(status)
SSalarm.triggerAlarm("Motion", get_area(src), list(UID()), src)
visible_message("<span class='warning'>A red light flashes on the [src]!</span>")
detectTime = -1
return TRUE
+19 -31
View File
@@ -8,11 +8,13 @@
circuit = /obj/item/circuitboard/stationalert_engineering
var/ui_x = 325
var/ui_y = 500
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
/obj/machinery/computer/station_alert/Initialize(mapload)
. = ..()
GLOB.alert_consoles += src
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered)
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled)
/obj/machinery/computer/station_alert/Destroy()
GLOB.alert_consoles -= src
@@ -40,53 +42,39 @@
var/list/data = list()
data["alarms"] = list()
for(var/class in alarms)
for(var/class in SSalarm.alarms)
if(!(class in alarms_listend_for))
continue
data["alarms"][class] = list()
for(var/area in alarms[class])
for(var/area in SSalarm.alarms[class])
data["alarms"][class] += area
return data
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
/obj/machinery/computer/station_alert/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
if(!(class in alarms_listend_for))
return
if(alarmsource.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if(!(alarmsource.UID() in sources))
sources += alarmsource.UID()
return TRUE
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
update_icon()
return TRUE
/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
/obj/machinery/computer/station_alert/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
if(!(class in alarms_listend_for))
return
if(origin.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
var/cleared = FALSE
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if(origin.UID() in srcs)
srcs -= origin.UID()
if(srcs.len == 0)
cleared = TRUE
L -= I
update_icon()
return !cleared
/obj/machinery/computer/station_alert/update_icon()
var/active_alarms = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
for(var/cat in SSalarm.alarms)
if(!(cat in alarms_listend_for))
continue
var/list/L = SSalarm.alarms[cat]
if(L.len)
active_alarms = TRUE
if(active_alarms)
+13 -27
View File
@@ -50,7 +50,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
//var/list/laws = list()
var/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" =list())
alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera", "Burglar")
var/viewalerts = 0
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
@@ -244,9 +244,11 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/ai_alerts()
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
dat += "<A HREF='?src=[UID()];mach_close=aialerts'>Close</A><BR><BR>"
for(var/cat in alarms)
for(var/cat in SSalarm.alarms)
if(!(cat in alarms_listend_for))
continue
dat += text("<B>[]</B><BR>\n", cat)
var/list/L = alarms[cat]
var/list/L = SSalarm.alarms[cat]
if(L.len)
for(var/alarm in L)
var/list/alm = L[alarm]
@@ -818,20 +820,13 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
Bot.call_bot(src, waypoint)
/mob/living/silicon/ai/triggerAlarm(class, area/A, list/O, obj/alarmsource)
/mob/living/silicon/ai/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
if(!(class in alarms_listend_for))
return
if(alarmsource.z != z)
return
if(stat == DEAD)
return TRUE
var/list/L = alarms[class]
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if(!(alarmsource.UID() in sources))
sources += alarmsource.UID()
return TRUE
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
if(O)
var/obj/machinery/camera/C = locateUID(O[1])
if(O.len == 1 && !QDELETED(C) && C.can_use())
@@ -851,25 +846,16 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
if(viewalerts)
ai_alerts()
return TRUE
/mob/living/silicon/ai/cancelAlarm(class, area/A, obj/origin)
var/list/L = alarms[class]
var/cleared = FALSE
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if(origin.UID() in srcs)
srcs -= origin.UID()
if(srcs.len == 0)
cleared = TRUE
L -= I
/mob/living/silicon/ai/alarm_cancelled(src, class, area/A, obj/origin, cleared)
if(cleared)
if(!(class in alarms_listend_for))
return
if(origin.z != z)
return
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
if(viewalerts)
ai_alerts()
return !cleared
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
+13 -28
View File
@@ -72,7 +72,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/list/req_access
var/ident = 0
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list())
var/viewalerts = 0
var/modtype = "Default"
var/lower_mod = 0
@@ -551,9 +550,11 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/proc/robot_alerts()
var/dat = ""
for(var/cat in alarms)
for(var/cat in SSalarm.alarms)
if(!(cat in alarms_listend_for))
continue
dat += text("<B>[cat]</B><BR>\n")
var/list/L = alarms[cat]
var/list/L = SSalarm.alarms[cat]
if(L.len)
for(var/alarm in L)
var/list/alm = L[alarm]
@@ -630,38 +631,22 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/InCritical()
return low_power_mode
/mob/living/silicon/robot/triggerAlarm(class, area/A, list/O, obj/alarmsource)
/mob/living/silicon/robot/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
if(!(class in alarms_listend_for))
return
if(alarmsource.z != z)
return
if(stat == DEAD)
return TRUE
var/list/L = alarms[class]
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if(!(alarmsource.UID() in sources))
sources += alarmsource.UID()
return TRUE
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
return
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
return TRUE
/mob/living/silicon/robot/cancelAlarm(class, area/A, obj/origin)
var/list/L = alarms[class]
var/cleared = 0
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if(origin.UID() in srcs)
srcs -= origin.UID()
if(srcs.len == 0)
cleared = 1
L -= I
/mob/living/silicon/robot/alarm_cancelled(src, class, area/A, obj/origin, cleared)
if(cleared)
if(!(class in alarms_listend_for))
return
if(origin.z != z)
return
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
return !cleared
/mob/living/silicon/robot/ex_act(severity)
switch(severity)
+5 -2
View File
@@ -13,6 +13,7 @@
var/list/alarms_to_clear = list()
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarms_listend_for = list("Motion", "Fire", "Atmosphere", "Power", "Camera")
//var/list/hud_list[10]
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
var/designation = ""
@@ -44,6 +45,8 @@
diag_hud_set_health()
add_language("Galactic Common")
init_subsystems()
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered)
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled)
/mob/living/silicon/med_hud_set_health()
return //we use a different hud
@@ -55,10 +58,10 @@
GLOB.silicon_mob_list -= src
return ..()
/mob/living/silicon/proc/cancelAlarm()
/mob/living/silicon/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
return
/mob/living/silicon/proc/triggerAlarm()
/mob/living/silicon/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
return
/mob/living/silicon/proc/queueAlarm(message, type, incoming = 1)
@@ -10,9 +10,8 @@
var/tgui_id = "NtosStationAlertConsole"
var/ui_x = 315
var/ui_y = 500
var/has_alert = 0
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
/datum/computer_file/program/alarm_monitor/process_tick()
..()
@@ -32,60 +31,36 @@
var/list/data = get_header_data()
data["alarms"] = list()
for(var/class in alarms)
for(var/class in SSalarm.alarms)
if(!(class in alarms_listend_for))
continue
data["alarms"][class] = list()
for(var/area in alarms[class])
data["alarms"][class] += area
return data
/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, list/O, obj/alarmsource)
if(is_station_level(source.z))
/datum/computer_file/program/alarm_monitor/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
if(is_station_level(alarmsource.z))
if(!(A.type in GLOB.the_station_areas))
return
else if(!is_mining_level(source.z) || istype(A, /area/ruin))
else if(!is_mining_level(alarmsource.z) || istype(A, /area/ruin))
return
var/list/L = alarms[class]
for(var/I in L)
if(I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if(!(alarmsource.UID() in sources))
sources += alarmsource.UID()
return TRUE
L[A.name] = list(get_area_name(A, TRUE), O, list(alarmsource.UID()))
update_alarm_display()
return TRUE
/datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin)
var/list/L = alarms[class]
var/cleared = 0
var/arealevelalarm = FALSE // set to TRUE for alarms that set/clear whole areas
if(class == "Fire")
arealevelalarm = TRUE
for(var/I in L)
if(I == A.name)
if(!arealevelalarm) // the traditional behaviour
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if(origin.UID() in srcs)
srcs -= origin.UID()
if(srcs.len == 0)
cleared = 1
L -= I
else
L -= I // wipe the instances entirely
cleared = 1
/datum/computer_file/program/alarm_monitor/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
if(is_station_level(origin.z))
if(!(A.type in GLOB.the_station_areas))
return
else if(!is_mining_level(origin.z) || istype(A, /area/ruin))
return
update_alarm_display()
return !cleared
/datum/computer_file/program/alarm_monitor/proc/update_alarm_display()
has_alert = FALSE
for(var/cat in alarms)
if(!(cat in alarms_listend_for))
continue
var/list/L = alarms[cat]
if(L.len)
has_alert = TRUE
@@ -93,7 +68,11 @@
/datum/computer_file/program/alarm_monitor/run_program(mob/user)
. = ..(user)
GLOB.alarmdisplay += src
RegisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM, .proc/alarm_triggered)
RegisterSignal(SSalarm, COMSIG_CANCELLED_ALARM, .proc/alarm_cancelled)
/datum/computer_file/program/alarm_monitor/kill_program(forced = FALSE)
GLOB.alarmdisplay -= src
UnregisterSignal(SSalarm, COMSIG_TRIGGERED_ALARM)
UnregisterSignal(SSalarm, COMSIG_CANCELLED_ALARM)
..()
+1
View File
@@ -215,6 +215,7 @@
#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\afk.dm"
#include "code\controllers\subsystem\air.dm"
#include "code\controllers\subsystem\alarm.dm"
#include "code\controllers\subsystem\assets.dm"
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\changelog.dm"