mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 18:44:48 +01:00
Merge pull request #13751 from Fox-McCloud/alarm-overhaul
Overhauls and Refactors Alarm System
This commit is contained in:
@@ -47144,7 +47144,7 @@
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/item/circuitboard/powermonitor,
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 3;
|
||||
pixel_y = -3
|
||||
},
|
||||
|
||||
@@ -31415,7 +31415,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
|
||||
@@ -35244,7 +35244,7 @@
|
||||
},
|
||||
/area/bridge)
|
||||
"bnW" = (
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 0;
|
||||
icon_state = "yellow"
|
||||
@@ -72578,7 +72578,7 @@
|
||||
pixel_x = -2;
|
||||
pixel_y = 2
|
||||
},
|
||||
/obj/item/circuitboard/stationalert_all{
|
||||
/obj/item/circuitboard/stationalert{
|
||||
pixel_x = 1;
|
||||
pixel_y = -1
|
||||
},
|
||||
@@ -75846,7 +75846,7 @@
|
||||
pixel_x = 32;
|
||||
pixel_y = 0
|
||||
},
|
||||
/obj/machinery/computer/station_alert/all,
|
||||
/obj/machinery/computer/station_alert,
|
||||
/obj/structure/cable/yellow{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -77210,6 +77210,10 @@
|
||||
pixel_x = -22
|
||||
},
|
||||
/obj/item/stack/tape_roll,
|
||||
/obj/machinery/camera/motion{
|
||||
c_tag = "EVA Motion Sensor";
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
|
||||
+23
-5
@@ -5,11 +5,11 @@
|
||||
var/turf/T = get_turf(A)
|
||||
return T ? T.loc : null
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in world)
|
||||
if(A.name == N)
|
||||
return A
|
||||
return 0
|
||||
/proc/get_area_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
if(!A)
|
||||
return null
|
||||
return format_text ? format_text(A.name) : A.name
|
||||
|
||||
/proc/get_location_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
@@ -31,6 +31,24 @@
|
||||
areas |= T.loc
|
||||
return areas
|
||||
|
||||
/proc/get_open_turf_in_dir(atom/center, dir)
|
||||
var/turf/T = get_ranged_target_turf(center, dir, 1)
|
||||
if(T && !T.density)
|
||||
return T
|
||||
|
||||
/proc/get_adjacent_open_turfs(atom/center)
|
||||
. = list(get_open_turf_in_dir(center, NORTH),
|
||||
get_open_turf_in_dir(center, SOUTH),
|
||||
get_open_turf_in_dir(center, EAST),
|
||||
get_open_turf_in_dir(center, WEST))
|
||||
listclearnulls(.)
|
||||
|
||||
/proc/get_adjacent_open_areas(atom/center)
|
||||
. = list()
|
||||
var/list/adjacent_turfs = get_adjacent_open_turfs(center)
|
||||
for(var/I in adjacent_turfs)
|
||||
. |= get_area(I)
|
||||
|
||||
// Like view but bypasses luminosity check
|
||||
|
||||
/proc/hear(var/range, var/atom/source)
|
||||
|
||||
@@ -672,9 +672,6 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize(last_name)]"
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(ladders)
|
||||
GLOBAL_LIST_INIT(active_diseases, list()) //List of Active disease in all mobs; purely for quick referencing.
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
|
||||
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
|
||||
GLOBAL_LIST_EMPTY(explosive_walls)
|
||||
|
||||
GLOBAL_LIST_EMPTY(engine_beacon_list)
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/obj/screen/ai/alerts/Click()
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.subsystem_alarm_monitor()
|
||||
AI.ai_alerts()
|
||||
|
||||
/obj/screen/ai/announcement
|
||||
name = "Make Announcement"
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
SUBSYSTEM_DEF(alarms)
|
||||
name = "Alarms"
|
||||
init_order = INIT_ORDER_ALARMS // 2
|
||||
offline_implications = "Alarms (Power, camera, fire, etc) will no longer be checked. No immediate action is needed."
|
||||
var/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
var/datum/alarm_handler/burglar/burglar_alarm = new()
|
||||
var/datum/alarm_handler/camera/camera_alarm = new()
|
||||
var/datum/alarm_handler/fire/fire_alarm = new()
|
||||
var/datum/alarm_handler/motion/motion_alarm = new()
|
||||
var/datum/alarm_handler/power/power_alarm = new()
|
||||
var/list/datum/alarm/all_handlers
|
||||
SUBSYSTEM_DEF(alarm)
|
||||
name = "Alarm"
|
||||
flags = SS_NO_INIT | SS_NO_FIRE
|
||||
var/list/alarms = list("Motion" = list(), "Fire" = list(), "Atmosphere" = list(), "Power" = list(), "Camera" = list(), "Burglar" = list())
|
||||
|
||||
/datum/controller/subsystem/alarms/Initialize(start_timeofday)
|
||||
all_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
return ..()
|
||||
/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/alarms/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
/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]
|
||||
srcs -= origin.UID()
|
||||
if(!length(srcs))
|
||||
cleared = TRUE
|
||||
L -= I
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/active_alarms()
|
||||
var/list/all_alarms = new ()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/controller/subsystem/alarms/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
SEND_SIGNAL(SSalarm, COMSIG_CANCELLED_ALARM, class, A, origin, cleared)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
/client/proc/debug_controller(controller in list("failsafe", "Master", "Ticker", "Air", "Jobs", "Sun", "Radio", "Configuration", "pAI",
|
||||
"Cameras", "Garbage", "Event", "Alarm", "Nano", "Vote", "Fires",
|
||||
"Cameras", "Garbage", "Event", "Nano", "Vote", "Fires",
|
||||
"Mob", "NPC Pool", "Shuttle", "Timer", "Weather", "Space", "Mob Hunt Server","Input"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
@@ -65,9 +65,6 @@
|
||||
if("Event")
|
||||
debug_variables(SSevents)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(SSalarms)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Nano")
|
||||
debug_variables(SSnanoui)
|
||||
feedback_add_details("admin_verb","DNano")
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
switch(index)
|
||||
if(AALARM_WIRE_IDSCAN)
|
||||
return "ID Scan"
|
||||
|
||||
|
||||
if(AALARM_WIRE_POWER)
|
||||
return "Power"
|
||||
|
||||
|
||||
if(AALARM_WIRE_SYPHON)
|
||||
return "Syphon"
|
||||
|
||||
|
||||
if(AALARM_WIRE_AI_CONTROL)
|
||||
return "AI Control"
|
||||
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
return "Atmospherics Alarm"
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
// to_chat(world, "Syphon Wire Cut")
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
if(A.alarm_area.atmosalert(2, A))
|
||||
A.post_alert(2)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_DANGER, A))
|
||||
A.post_alert(ATMOS_ALARM_DANGER)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// to_chat(world, "Aalarm wire pulsed")
|
||||
if(A.alarm_area.atmosalert(0, A))
|
||||
A.post_alert(0)
|
||||
if(A.alarm_area.atmosalert(ATMOS_ALARM_NONE, A))
|
||||
A.post_alert(ATMOS_ALARM_NONE)
|
||||
A.update_icon()
|
||||
..()
|
||||
|
||||
@@ -50,10 +50,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/space/atmosalert()
|
||||
return
|
||||
|
||||
/area/space/fire_alert()
|
||||
/area/space/firealert(obj/source)
|
||||
return
|
||||
|
||||
/area/space/fire_reset()
|
||||
/area/space/firereset(obj/source)
|
||||
return
|
||||
|
||||
/area/space/readyalert()
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
/area/ai_monitored
|
||||
name = "AI Monitored Area"
|
||||
var/obj/machinery/camera/motioncamera = null
|
||||
var/list/motioncameras = list()
|
||||
var/list/motionTargets = list()
|
||||
|
||||
|
||||
/area/ai_monitored/LateInitialize()
|
||||
/area/ai_monitored/Initialize(mapload)
|
||||
. = ..()
|
||||
// locate and store the motioncamera
|
||||
for(var/obj/machinery/camera/M in src)
|
||||
if(M.isMotion())
|
||||
motioncamera = M
|
||||
M.area_motion = src
|
||||
break
|
||||
if(mapload)
|
||||
for(var/obj/machinery/camera/M in src)
|
||||
if(M.isMotion())
|
||||
motioncameras.Add(M)
|
||||
M.set_area_motion(src)
|
||||
|
||||
/area/ai_monitored/Entered(atom/movable/O)
|
||||
..()
|
||||
if(ismob(O) && motioncamera)
|
||||
motioncamera.newTarget(O)
|
||||
if(ismob(O) && length(motioncameras))
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.newTarget(O)
|
||||
return
|
||||
|
||||
/area/ai_monitored/Exited(atom/movable/O)
|
||||
if(ismob(O) && motioncamera)
|
||||
motioncamera.lostTarget(O)
|
||||
..()
|
||||
if(ismob(O) && length(motioncameras))
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.lostTargetRef(O.UID())
|
||||
return
|
||||
|
||||
|
||||
|
||||
+195
-63
@@ -57,6 +57,11 @@
|
||||
|
||||
var/list/ambientsounds = GENERIC_SOUNDS
|
||||
|
||||
var/list/firedoors
|
||||
var/list/cameras
|
||||
var/list/firealarms
|
||||
var/firedoors_last_closed_on = 0
|
||||
|
||||
var/fast_despawn = FALSE
|
||||
var/can_get_auto_cryod = TRUE
|
||||
var/hide_attacklogs = FALSE // For areas such as thunderdome, lavaland syndiebase, etc which generate a lot of spammy attacklogs. Reduces log priority.
|
||||
@@ -125,35 +130,6 @@
|
||||
cameras += C
|
||||
return cameras
|
||||
|
||||
|
||||
/area/proc/atmosalert(danger_level, var/alarm_source, var/force = FALSE)
|
||||
if(report_alerts)
|
||||
if(danger_level == ATMOS_ALARM_NONE)
|
||||
SSalarms.atmosphere_alarm.clearAlarm(src, alarm_source)
|
||||
else
|
||||
SSalarms.atmosphere_alarm.triggerAlarm(src, alarm_source, severity = danger_level)
|
||||
|
||||
//Check all the alarms before lowering atmosalm. Raising is perfectly fine. If force = 1 we don't care.
|
||||
for(var/obj/machinery/alarm/AA in src)
|
||||
if(!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level && !force)
|
||||
danger_level = max(danger_level, AA.danger_level)
|
||||
|
||||
if(danger_level != atmosalm)
|
||||
if(danger_level < ATMOS_ALARM_WARNING && atmosalm >= ATMOS_ALARM_WARNING)
|
||||
//closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise
|
||||
air_doors_open()
|
||||
else if(danger_level >= ATMOS_ALARM_DANGER && atmosalm < ATMOS_ALARM_DANGER)
|
||||
air_doors_close()
|
||||
|
||||
atmosalm = danger_level
|
||||
for(var/obj/machinery/alarm/AA in src)
|
||||
AA.update_icon()
|
||||
|
||||
GLOB.air_alarm_repository.update_cache(src)
|
||||
return 1
|
||||
GLOB.air_alarm_repository.update_cache(src)
|
||||
return 0
|
||||
|
||||
/area/proc/air_doors_close()
|
||||
if(!air_doors_activated)
|
||||
air_doors_activated = TRUE
|
||||
@@ -179,44 +155,151 @@
|
||||
D.open()
|
||||
|
||||
|
||||
/area/proc/fire_alert()
|
||||
if(!fire)
|
||||
fire = 1 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_close()
|
||||
/area/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/area/proc/fire_reset()
|
||||
if(fire)
|
||||
fire = 0 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
air_doors_open()
|
||||
/**
|
||||
* Generate a power alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/poweralert(state, obj/source)
|
||||
if(state != poweralm)
|
||||
poweralm = state
|
||||
if(istype(source)) //Only report power alarms on the z-level where the source is located.
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
if(state)
|
||||
C.network -= "Power Alarms"
|
||||
else
|
||||
C.network |= "Power Alarms"
|
||||
|
||||
return
|
||||
if(state)
|
||||
SSalarm.cancelAlarm("Power", src, source)
|
||||
else
|
||||
SSalarm.triggerAlarm("Power", src, cameras, source)
|
||||
|
||||
/area/proc/burglaralert(var/obj/trigger)
|
||||
if(always_unpowered == 1) //no burglar alarms in space/asteroid
|
||||
/**
|
||||
* Generate an atmospheric alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*/
|
||||
/area/proc/atmosalert(danger_level, obj/source)
|
||||
if(danger_level != atmosalm)
|
||||
if(danger_level == ATMOS_ALARM_DANGER)
|
||||
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network |= "Atmosphere Alarms"
|
||||
|
||||
|
||||
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) && is_station_level(C.z))
|
||||
C.network -= "Atmosphere Alarms"
|
||||
|
||||
SSalarm.cancelAlarm("Atmosphere", src, source)
|
||||
|
||||
atmosalm = danger_level
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Try to close all the firedoors in the area
|
||||
*/
|
||||
/area/proc/ModifyFiredoors(opening)
|
||||
if(firedoors)
|
||||
firedoors_last_closed_on = world.time
|
||||
for(var/FD in firedoors)
|
||||
var/obj/machinery/door/firedoor/D = FD
|
||||
var/cont = !D.welded
|
||||
if(cont && opening) //don't open if adjacent area is on fire
|
||||
for(var/I in D.affecting_areas)
|
||||
var/area/A = I
|
||||
if(A.fire)
|
||||
cont = FALSE
|
||||
break
|
||||
if(cont && D.is_operational())
|
||||
if(D.operating)
|
||||
D.nextstate = opening ? FD_OPEN : FD_CLOSED
|
||||
else if(!(D.density ^ opening))
|
||||
INVOKE_ASYNC(D, (opening ? /obj/machinery/door/firedoor.proc/open : /obj/machinery/door/firedoor.proc/close))
|
||||
|
||||
/**
|
||||
* Generate a firealarm alert for this area
|
||||
*
|
||||
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
|
||||
*
|
||||
* Also starts the area processing on SSobj
|
||||
*/
|
||||
/area/proc/firealert(obj/source)
|
||||
if(always_unpowered) //no fire alarms in space/asteroid
|
||||
return
|
||||
|
||||
//Trigger alarm effect
|
||||
set_fire_alarm_effect()
|
||||
if(!fire)
|
||||
set_fire_alarm_effect()
|
||||
ModifyFiredoors(FALSE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
|
||||
//Lockdown airlocks
|
||||
for(var/obj/machinery/door/airlock/A in src)
|
||||
spawn(0)
|
||||
A.close()
|
||||
if(A.density)
|
||||
A.lock()
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network |= "Fire Alarms"
|
||||
|
||||
SSalarms.burglar_alarm.triggerAlarm(src, trigger)
|
||||
spawn(600)
|
||||
SSalarms.burglar_alarm.clearAlarm(src, trigger)
|
||||
SSalarm.triggerAlarm("Fire", src, cameras, source)
|
||||
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = 1
|
||||
updateicon()
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* Reset the firealarm alert for this area
|
||||
*
|
||||
* resets the alert sent to all ai players, alert consoles, drones and alarm monitor programs
|
||||
* in the world
|
||||
*
|
||||
* Also cycles the icons of all firealarms and deregisters the area from processing on SSOBJ
|
||||
*/
|
||||
/area/proc/firereset(obj/source)
|
||||
if(fire)
|
||||
unset_fire_alarm_effects()
|
||||
ModifyFiredoors(TRUE)
|
||||
for(var/item in firealarms)
|
||||
var/obj/machinery/firealarm/F = item
|
||||
F.update_icon()
|
||||
|
||||
for(var/thing in cameras)
|
||||
var/obj/machinery/camera/C = locateUID(thing)
|
||||
if(!QDELETED(C) && is_station_level(C.z))
|
||||
C.network -= "Fire Alarms"
|
||||
|
||||
SSalarm.cancelAlarm("Fire", src, source)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/**
|
||||
* If 100 ticks has elapsed, toggle all the firedoors closed again
|
||||
*/
|
||||
/area/process()
|
||||
if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds
|
||||
ModifyFiredoors(FALSE)
|
||||
|
||||
/**
|
||||
* Close and lock a door passed into this proc
|
||||
*
|
||||
* Does this need to exist on area? probably not
|
||||
*/
|
||||
/area/proc/close_and_lock_door(obj/machinery/door/DOOR)
|
||||
set waitfor = FALSE
|
||||
DOOR.close()
|
||||
if(DOOR.density)
|
||||
DOOR.lock()
|
||||
|
||||
/area/proc/readyalert()
|
||||
if(!eject)
|
||||
@@ -240,13 +323,62 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
updateicon()
|
||||
|
||||
/**
|
||||
* Raise a burglar alert for this area
|
||||
*
|
||||
* Close and locks all doors in the area and alerts silicon mobs of a break in
|
||||
*
|
||||
* Alarm auto resets after 600 ticks
|
||||
*/
|
||||
/area/proc/burglaralert(obj/trigger)
|
||||
if(always_unpowered) //no burglar alarms in space/asteroid
|
||||
return
|
||||
|
||||
//Trigger alarm effect
|
||||
set_fire_alarm_effect()
|
||||
//Lockdown airlocks
|
||||
for(var/obj/machinery/door/DOOR in src)
|
||||
close_and_lock_door(DOOR)
|
||||
|
||||
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
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/set_fire_alarm_effect()
|
||||
fire = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/**
|
||||
* unset the fire alarm visual affects in an area
|
||||
*
|
||||
* Updates the fire light on fire alarms in the area and sets all lights to emergency mode
|
||||
*/
|
||||
/area/proc/unset_fire_alarm_effects()
|
||||
fire = FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
for(var/alarm in firealarms)
|
||||
var/obj/machinery/firealarm/F = alarm
|
||||
F.update_fire_light(fire)
|
||||
for(var/obj/machinery/light/L in src)
|
||||
L.update()
|
||||
|
||||
/area/proc/updateicon()
|
||||
if((fire || eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc.
|
||||
if(fire && !eject && !party)
|
||||
if((eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc.
|
||||
if(!eject && !party)
|
||||
icon_state = "red"
|
||||
else if(!fire && eject && !party)
|
||||
else if(eject && !party)
|
||||
icon_state = "red"
|
||||
else if(party && !fire && !eject)
|
||||
else if(party && !eject)
|
||||
icon_state = "party"
|
||||
else
|
||||
icon_state = "blue-red"
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
temperature_dangerlevel
|
||||
)
|
||||
|
||||
if(old_danger_level!=danger_level)
|
||||
if(old_danger_level != danger_level)
|
||||
apply_danger_level()
|
||||
|
||||
if(mode == AALARM_MODE_REPLACEMENT && environment_pressure < ONE_ATMOSPHERE * 0.05)
|
||||
@@ -534,28 +534,35 @@
|
||||
"checks"= 0,
|
||||
))
|
||||
|
||||
/obj/machinery/alarm/proc/apply_danger_level(var/new_danger_level)
|
||||
if(report_danger_level && alarm_area.atmosalert(new_danger_level, src))
|
||||
post_alert(new_danger_level)
|
||||
/obj/machinery/alarm/proc/apply_danger_level()
|
||||
var/new_area_danger_level = ATMOS_ALARM_NONE
|
||||
for(var/obj/machinery/alarm/AA in alarm_area)
|
||||
if(!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted)
|
||||
new_area_danger_level = max(new_area_danger_level, AA.danger_level)
|
||||
if(alarm_area.atmosalert(new_area_danger_level, src)) //if area was in normal state or if area was in alert state
|
||||
post_alert(new_area_danger_level)
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/alarm/proc/post_alert(alert_level)
|
||||
if(!report_danger_level)
|
||||
return
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(alarm_frequency)
|
||||
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
var/datum/signal/alert_signal = new
|
||||
alert_signal.source = src
|
||||
alert_signal.transmission_method = 1
|
||||
alert_signal.data["zone"] = alarm_area.name
|
||||
alert_signal.data["zone"] = get_area_name(src, TRUE)
|
||||
alert_signal.data["type"] = "Atmospheric"
|
||||
|
||||
if(alert_level==2)
|
||||
if(alert_level == ATMOS_ALARM_DANGER)
|
||||
alert_signal.data["alert"] = "severe"
|
||||
else if(alert_level==1)
|
||||
else if(alert_level == ATMOS_ALARM_WARNING)
|
||||
alert_signal.data["alert"] = "minor"
|
||||
else if(alert_level==0)
|
||||
else if(alert_level == ATMOS_ALARM_NONE)
|
||||
alert_signal.data["alert"] = "clear"
|
||||
|
||||
frequency.post_signal(src, alert_signal)
|
||||
@@ -889,14 +896,14 @@
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_DANGER, src))
|
||||
apply_danger_level(ATMOS_ALARM_DANGER)
|
||||
post_alert(ATMOS_ALARM_DANGER)
|
||||
alarmActivated = 1
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if(alarm_area.atmosalert(ATMOS_ALARM_NONE, src, TRUE))
|
||||
apply_danger_level(ATMOS_ALARM_NONE)
|
||||
post_alert(ATMOS_ALARM_NONE)
|
||||
alarmActivated = 0
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
@@ -28,13 +28,14 @@
|
||||
var/view_range = 7
|
||||
var/short_range = 2
|
||||
|
||||
var/alarm_on = FALSE
|
||||
var/busy = FALSE
|
||||
var/emped = FALSE //Number of consecutive EMP's on this camera
|
||||
|
||||
var/in_use_lights = 0 // TO BE IMPLEMENTED
|
||||
var/toggle_sound = 'sound/items/wirecutter.ogg'
|
||||
|
||||
/obj/machinery/camera/Initialize()
|
||||
/obj/machinery/camera/Initialize(mapload)
|
||||
. = ..()
|
||||
wires = new(src)
|
||||
assembly = new(src)
|
||||
@@ -44,10 +45,15 @@
|
||||
|
||||
GLOB.cameranet.cameras += src
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if(isturf(loc))
|
||||
LAZYADD(myArea.cameras, UID())
|
||||
if(is_station_level(z) && prob(3) && !start_active)
|
||||
toggle_cam(null, FALSE)
|
||||
wires.CutAll()
|
||||
|
||||
/obj/machinery/camera/proc/set_area_motion(area/A)
|
||||
area_motion = A
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
toggle_cam(null, FALSE) //kick anyone viewing out
|
||||
QDEL_NULL(assembly)
|
||||
@@ -59,10 +65,14 @@
|
||||
QDEL_NULL(wires)
|
||||
GLOB.cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
|
||||
GLOB.cameranet.cameras -= src
|
||||
if(isarea(myArea))
|
||||
LAZYREMOVE(myArea.cameras, UID())
|
||||
var/area/ai_monitored/A = get_area(src)
|
||||
if(istype(A))
|
||||
A.motioncamera = null
|
||||
A.motioncameras -= src
|
||||
area_motion = null
|
||||
cancelCameraAlarm()
|
||||
cancelAlarm()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
@@ -282,9 +292,16 @@
|
||||
status = !status
|
||||
if(can_use())
|
||||
GLOB.cameranet.addCamera(src)
|
||||
if(isturf(loc))
|
||||
myArea = get_area(src)
|
||||
LAZYADD(myArea.cameras, UID())
|
||||
else
|
||||
myArea = null
|
||||
else
|
||||
set_light(0)
|
||||
GLOB.cameranet.removeCamera(src)
|
||||
if(isarea(myArea))
|
||||
LAZYREMOVE(myArea.cameras, UID())
|
||||
GLOB.cameranet.updateChunk(x, y, z)
|
||||
var/change_msg = "deactivates"
|
||||
if(status)
|
||||
@@ -313,12 +330,12 @@
|
||||
to_chat(O, "The screen bursts into static.")
|
||||
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm()
|
||||
if(is_station_contact(z))
|
||||
SSalarms.camera_alarm.triggerAlarm(loc, src)
|
||||
alarm_on = TRUE
|
||||
SSalarm.triggerAlarm("Camera", get_area(src), list(UID()), src)
|
||||
|
||||
/obj/machinery/camera/proc/cancelCameraAlarm()
|
||||
if(is_station_contact(z))
|
||||
SSalarms.camera_alarm.clearAlarm(loc, src)
|
||||
alarm_on = FALSE
|
||||
SSalarm.cancelAlarm("Camera", get_area(src), src)
|
||||
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
@@ -414,8 +431,8 @@
|
||||
/obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets.
|
||||
var/turf/prev_turf
|
||||
|
||||
/obj/machinery/camera/portable/New()
|
||||
..()
|
||||
/obj/machinery/camera/portable/Initialize(mapload)
|
||||
. = ..()
|
||||
assembly.state = 0 //These cameras are portable, and so shall be in the portable state if removed.
|
||||
assembly.anchored = 0
|
||||
assembly.update_icon()
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/obj/machinery/camera
|
||||
|
||||
var/list/motionTargets = list()
|
||||
var/list/localMotionTargets = list()
|
||||
var/detectTime = 0
|
||||
var/area/ai_monitored/area_motion = null
|
||||
var/alarm_delay = 100
|
||||
|
||||
var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm()
|
||||
|
||||
/obj/machinery/camera/process()
|
||||
// motion camera event loop
|
||||
if(stat & (EMPED|NOPOWER))
|
||||
return
|
||||
if(!isMotion())
|
||||
. = PROCESS_KILL
|
||||
return
|
||||
if(stat & (EMPED|NOPOWER))
|
||||
return
|
||||
if(detectTime > 0)
|
||||
var/elapsed = world.time - detectTime
|
||||
if(elapsed > alarm_delay)
|
||||
triggerAlarm()
|
||||
else if(detectTime == -1)
|
||||
for(var/mob/target in motionTargets)
|
||||
if(target.stat == 2) lostTarget(target)
|
||||
// If not detecting with motion camera...
|
||||
if(!area_motion)
|
||||
// See if the camera is still in range
|
||||
if(!in_range(src, target))
|
||||
// If they aren't in range, lose the target.
|
||||
lostTarget(target)
|
||||
for(var/thing in getTargetList())
|
||||
var/mob/target = locateUID(thing)
|
||||
if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target)))
|
||||
//If not part of a monitored area and the camera is not in range or the target is dead
|
||||
lostTargetRef(thing)
|
||||
|
||||
/obj/machinery/camera/proc/newTarget(var/mob/target)
|
||||
if(istype(target, /mob/living/silicon/ai)) return 0
|
||||
/obj/machinery/camera/proc/getTargetList()
|
||||
if(area_motion)
|
||||
return area_motion.motionTargets
|
||||
return localMotionTargets
|
||||
|
||||
/obj/machinery/camera/proc/newTarget(mob/target)
|
||||
if(isAI(target))
|
||||
return FALSE
|
||||
if(detectTime == 0)
|
||||
detectTime = world.time // start the clock
|
||||
if(!(target in motionTargets))
|
||||
motionTargets += target
|
||||
return 1
|
||||
var/list/targets = getTargetList()
|
||||
targets |= target.UID()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/proc/lostTarget(var/mob/target)
|
||||
if(target in motionTargets)
|
||||
motionTargets -= target
|
||||
if(motionTargets.len == 0)
|
||||
/obj/machinery/camera/proc/lostTargetRef(uid)
|
||||
var/list/targets = getTargetList()
|
||||
targets -= uid
|
||||
if(length(targets))
|
||||
cancelAlarm()
|
||||
|
||||
/obj/machinery/camera/proc/cancelAlarm()
|
||||
if(!status || (stat & NOPOWER))
|
||||
return FALSE
|
||||
if(detectTime == -1 && is_station_contact(z))
|
||||
SSalarms.motion_alarm.clearAlarm(loc, src)
|
||||
if(detectTime == -1)
|
||||
if(status)
|
||||
SSalarm.cancelAlarm("Motion", get_area(src), src)
|
||||
detectTime = 0
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/camera/proc/triggerAlarm()
|
||||
if(!status || (stat & NOPOWER))
|
||||
if(!detectTime)
|
||||
return FALSE
|
||||
if(!detectTime || !is_station_contact(z))
|
||||
return FALSE
|
||||
SSalarms.motion_alarm.triggerAlarm(loc, src)
|
||||
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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// EMP
|
||||
|
||||
/obj/machinery/camera/emp_proof/Initialize()
|
||||
/obj/machinery/camera/emp_proof/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeEmpProof()
|
||||
|
||||
@@ -11,19 +11,23 @@
|
||||
/obj/machinery/camera/xray
|
||||
icon_state = "xraycam" // Thanks to Krutchen for the icons.
|
||||
|
||||
/obj/machinery/camera/xray/Initialize()
|
||||
/obj/machinery/camera/xray/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeXRay()
|
||||
|
||||
// MOTION
|
||||
/obj/machinery/camera/motion
|
||||
name = "motion-sensitive security camera"
|
||||
|
||||
/obj/machinery/camera/motion/Initialize()
|
||||
/obj/machinery/camera/motion/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeMotion()
|
||||
|
||||
// ALL UPGRADES
|
||||
/obj/machinery/camera/all
|
||||
icon_state = "xraycamera" //mapping icon.
|
||||
|
||||
/obj/machinery/camera/all/Initialize()
|
||||
/obj/machinery/camera/all/Initialize(mapload)
|
||||
. = ..()
|
||||
upgradeEmpProof()
|
||||
upgradeXRay()
|
||||
@@ -78,6 +82,10 @@
|
||||
|
||||
// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
|
||||
/obj/machinery/camera/proc/upgradeMotion()
|
||||
if(isMotion())
|
||||
return
|
||||
if(name == initial(name))
|
||||
name = "motion-sensitive security camera"
|
||||
assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly))
|
||||
setPowerUsage()
|
||||
// Add it to machines that process
|
||||
|
||||
@@ -1,84 +1,90 @@
|
||||
GLOBAL_LIST_EMPTY(priority_air_alarms)
|
||||
GLOBAL_LIST_EMPTY(minor_air_alarms)
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert
|
||||
name = "atmospheric alert computer"
|
||||
desc = "Used to access the station's atmospheric sensors."
|
||||
circuit = /obj/item/circuitboard/atmos_alert
|
||||
var/ui_x = 350
|
||||
var/ui_y = 300
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
var/list/priority_alarms = list()
|
||||
var/list/minor_alarms = list()
|
||||
var/receive_frequency = ATMOS_FIRE_FREQ
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/computer/atmos_alert/New()
|
||||
..()
|
||||
SSalarms.atmosphere_alarm.register(src, /obj/machinery/computer/station_alert/.proc/update_icon)
|
||||
/obj/machinery/computer/atmos_alert/Initialize(mapload)
|
||||
. = ..()
|
||||
set_frequency(receive_frequency)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Destroy()
|
||||
SSalarms.atmosphere_alarm.unregister(src)
|
||||
return ..()
|
||||
SSradio.remove_object(src, receive_frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/atmos_alert/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500)
|
||||
ui = new(user, src, ui_key, "AtmosAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
var/major_alarms[0]
|
||||
var/minor_alarms[0]
|
||||
/obj/machinery/computer/atmos_alert/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
for(var/datum/alarm/alarm in SSalarms.atmosphere_alarm.major_alarms())
|
||||
major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
for(var/datum/alarm/alarm in SSalarms.atmosphere_alarm.minor_alarms())
|
||||
minor_alarms[++minor_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
data["priority_alarms"] = major_alarms
|
||||
data["minor_alarms"] = minor_alarms
|
||||
data["priority"] = list()
|
||||
for(var/zone in priority_alarms)
|
||||
data["priority"] |= zone
|
||||
data["minor"] = list()
|
||||
for(var/zone in minor_alarms)
|
||||
data["minor"] |= zone
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/atmos_alert/update_icon()
|
||||
var/list/alarms = SSalarms.atmosphere_alarm.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
alarms = SSalarms.atmosphere_alarm.minor_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:1"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Topic(href, href_list)
|
||||
/obj/machinery/computer/atmos_alert/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
switch(action)
|
||||
if("clear")
|
||||
var/zone = params["zone"]
|
||||
if(zone in priority_alarms)
|
||||
to_chat(usr, "<span class='notice'>Priority alarm for [zone] cleared.</span>")
|
||||
priority_alarms -= zone
|
||||
. = TRUE
|
||||
if(zone in minor_alarms)
|
||||
to_chat(usr, "<span class='notice'>Minor alarm for [zone] cleared.</span>")
|
||||
minor_alarms -= zone
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
if(href_list["clear_alarm"])
|
||||
var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in SSalarms.atmosphere_alarm.alarms
|
||||
if(alarm)
|
||||
for(var/datum/alarm_source/alarm_source in alarm.sources)
|
||||
var/obj/machinery/alarm/air_alarm = alarm_source.source
|
||||
if(istype(air_alarm))
|
||||
var/list/new_ref = list("atmos_reset" = 1)
|
||||
air_alarm.Topic(href, new_ref, state = GLOB.air_alarm_topic)
|
||||
update_icon()
|
||||
return 1
|
||||
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, receive_frequency)
|
||||
receive_frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA)
|
||||
|
||||
GLOBAL_DATUM_INIT(air_alarm_topic, /datum/topic_state/air_alarm_topic, new)
|
||||
/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
|
||||
if(!signal)
|
||||
return
|
||||
|
||||
/datum/topic_state/air_alarm_topic/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = 1
|
||||
var/zone = signal.data["zone"]
|
||||
var/severity = signal.data["alert"]
|
||||
|
||||
return extra_href
|
||||
if(!zone || !severity)
|
||||
return
|
||||
|
||||
/datum/topic_state/air_alarm_topic/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_INTERACTIVE
|
||||
minor_alarms -= zone
|
||||
priority_alarms -= zone
|
||||
if(severity == "severe")
|
||||
priority_alarms += zone
|
||||
else if(severity == "minor")
|
||||
minor_alarms += zone
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/update_icon()
|
||||
if(length(priority_alarms))
|
||||
icon_screen = "alert:2"
|
||||
else if(length(minor_alarms))
|
||||
icon_screen = "alert:1"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
..()
|
||||
|
||||
@@ -165,12 +165,9 @@
|
||||
/obj/item/circuitboard/stationalert_engineering
|
||||
name = "Circuit Board (Station Alert Console (Engineering))"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/circuitboard/stationalert_security
|
||||
name = "Circuit Board (Station Alert Console (Security))"
|
||||
/obj/item/circuitboard/stationalert
|
||||
name = "Circuit Board (Station Alert Console)"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/circuitboard/stationalert_all
|
||||
name = "Circuit Board (Station Alert Console (All))"
|
||||
build_path = /obj/machinery/computer/station_alert/all
|
||||
/obj/item/circuitboard/atmos_alert
|
||||
name = "Circuit Board (Atmospheric Alert Computer)"
|
||||
build_path = /obj/machinery/computer/atmos_alert
|
||||
|
||||
@@ -6,48 +6,91 @@
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
circuit = /obj/item/circuitboard/stationalert_engineering
|
||||
var/datum/nano_module/alarm_monitor/alarm_monitor
|
||||
var/monitor_type = /datum/nano_module/alarm_monitor/engineering
|
||||
var/ui_x = 325
|
||||
var/ui_y = 500
|
||||
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
|
||||
|
||||
/obj/machinery/computer/station_alert/security
|
||||
monitor_type = /datum/nano_module/alarm_monitor/security
|
||||
circuit = /obj/item/circuitboard/stationalert_security
|
||||
|
||||
/obj/machinery/computer/station_alert/all
|
||||
monitor_type = /datum/nano_module/alarm_monitor/all
|
||||
circuit = /obj/item/circuitboard/stationalert_all
|
||||
|
||||
/obj/machinery/computer/station_alert/New()
|
||||
..()
|
||||
alarm_monitor = new monitor_type(src)
|
||||
alarm_monitor.register(src, /obj/machinery/computer/station_alert/.proc/update_icon)
|
||||
/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()
|
||||
alarm_monitor.unregister(src)
|
||||
QDEL_NULL(alarm_monitor)
|
||||
GLOB.alert_consoles -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/interact(mob/user)
|
||||
alarm_monitor.ui_interact(user)
|
||||
/obj/machinery/computer/station_alert/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "StationAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/station_alert/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["alarms"] = list()
|
||||
for(var/class in SSalarm.alarms)
|
||||
if(!(class in alarms_listend_for))
|
||||
continue
|
||||
data["alarms"][class] = list()
|
||||
for(var/area in SSalarm.alarms[class])
|
||||
for(var/thing in SSalarm.alarms[class][area][3])
|
||||
var/atom/A = locateUID(thing)
|
||||
if(atoms_share_level(A, src))
|
||||
data["alarms"][class] += area
|
||||
|
||||
return data
|
||||
|
||||
/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
|
||||
update_icon()
|
||||
|
||||
/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
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/station_alert/update_icon()
|
||||
if(alarm_monitor)
|
||||
var/list/alarms = alarm_monitor.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
var/active_alarms = FALSE
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
if(length(L))
|
||||
active_alarms = TRUE
|
||||
if(active_alarms)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
|
||||
..()
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
var/nextstate = null
|
||||
var/boltslocked = TRUE
|
||||
var/active_alarm = FALSE
|
||||
var/list/affecting_areas
|
||||
|
||||
/obj/machinery/door/firedoor/Initialize(mapload)
|
||||
. = ..()
|
||||
CalculateAffectingAreas()
|
||||
|
||||
/obj/machinery/door/firedoor/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -40,11 +45,31 @@
|
||||
else
|
||||
. += "<span class='notice'>The bolt locks have been <i>unscrewed</i>, but the bolts themselves are still <b>wrenched</b> to the floor.</span>"
|
||||
|
||||
/obj/machinery/door/firedoor/proc/CalculateAffectingAreas()
|
||||
remove_from_areas()
|
||||
affecting_areas = get_adjacent_open_areas(src) | get_area(src)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYADD(A.firedoors, src)
|
||||
|
||||
/obj/machinery/door/firedoor/closed
|
||||
icon_state = "door_closed"
|
||||
opacity = TRUE
|
||||
density = TRUE
|
||||
|
||||
//see also turf/AfterChange for adjacency shennanigans
|
||||
|
||||
/obj/machinery/door/firedoor/proc/remove_from_areas()
|
||||
if(affecting_areas)
|
||||
for(var/I in affecting_areas)
|
||||
var/area/A = I
|
||||
LAZYREMOVE(A.firedoors, src)
|
||||
|
||||
/obj/machinery/door/firedoor/Destroy()
|
||||
remove_from_areas()
|
||||
affecting_areas.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/firedoor/Bumped(atom/AM)
|
||||
if(panel_open || operating)
|
||||
return
|
||||
|
||||
@@ -25,6 +25,11 @@ FIRE ALARM
|
||||
active_power_usage = 6
|
||||
power_channel = ENVIRON
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
light_power = 0
|
||||
light_range = 7
|
||||
light_color = "#ff3232"
|
||||
|
||||
var/last_process = 0
|
||||
var/wiresexposed = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
@@ -191,6 +196,7 @@ FIRE ALARM
|
||||
/obj/machinery/firealarm/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT) && buildstage != 0) //can't break the electronics if there isn't any inside.
|
||||
stat |= BROKEN
|
||||
LAZYREMOVE(myArea.firealarms, src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/deconstruct(disassembled = TRUE)
|
||||
@@ -203,6 +209,14 @@ FIRE ALARM
|
||||
new /obj/item/stack/cable_coil(loc, 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/firealarm/proc/update_fire_light(fire)
|
||||
if(fire == !!light_power)
|
||||
return // do nothing if we're already active
|
||||
if(fire)
|
||||
set_light(l_power = 0.8)
|
||||
else
|
||||
set_light(l_power = 0)
|
||||
|
||||
/obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
@@ -286,26 +300,16 @@ FIRE ALARM
|
||||
time = min(max(round(time), 0), 120)
|
||||
|
||||
/obj/machinery/firealarm/proc/reset()
|
||||
if(!working)
|
||||
if(!working || !report_fire_alarms)
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
A.fire_reset()
|
||||
A.firereset(src)
|
||||
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
if(is_station_contact(z) && FA.report_fire_alarms)
|
||||
SSalarms.fire_alarm.clearAlarm(loc, FA)
|
||||
|
||||
/obj/machinery/firealarm/proc/alarm(var/duration = 0)
|
||||
if(!working)
|
||||
/obj/machinery/firealarm/proc/alarm()
|
||||
if(!working || !report_fire_alarms)
|
||||
return
|
||||
|
||||
var/area/A = get_area(src)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
if(is_station_contact(z) && FA.report_fire_alarms)
|
||||
SSalarms.fire_alarm.triggerAlarm(loc, FA, duration)
|
||||
else
|
||||
A.fire_alert() // Manually trigger alarms if the alarm isn't reported
|
||||
|
||||
A.firealert(src) // Manually trigger alarms if the alarm isn't reported
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/New(location, direction, building)
|
||||
@@ -323,8 +327,14 @@ FIRE ALARM
|
||||
else
|
||||
overlays += image('icons/obj/monitors.dmi', "overlay_green")
|
||||
|
||||
myArea = get_area(src)
|
||||
LAZYADD(myArea.firealarms, src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/firealarm/Destroy()
|
||||
LAZYREMOVE(myArea.firealarms, src)
|
||||
return ..()
|
||||
|
||||
/*
|
||||
FIRE ALARM CIRCUIT
|
||||
Just a object used in constructing fire alarms
|
||||
|
||||
@@ -221,6 +221,12 @@
|
||||
A.contents += thing
|
||||
thing.change_area(old_area, A)
|
||||
|
||||
var/area/oldA = get_area(get_turf(usr))
|
||||
var/list/firedoors = oldA.firedoors
|
||||
for(var/door in firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = door
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
interact()
|
||||
area_created = TRUE
|
||||
return area_created
|
||||
@@ -236,6 +242,10 @@
|
||||
return
|
||||
set_area_machinery_title(A,str,prevname)
|
||||
A.name = str
|
||||
if(A.firedoors)
|
||||
for(var/D in A.firedoors)
|
||||
var/obj/machinery/door/firedoor/FD = D
|
||||
FD.CalculateAffectingAreas()
|
||||
to_chat(usr, "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>")
|
||||
interact()
|
||||
return 1
|
||||
|
||||
@@ -263,6 +263,13 @@
|
||||
if(SSair && !ignore_air)
|
||||
SSair.add_to_active(src)
|
||||
|
||||
//update firedoor adjacency
|
||||
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
|
||||
for(var/I in turfs_to_check)
|
||||
var/turf/T = I
|
||||
for(var/obj/machinery/door/firedoor/FD in T)
|
||||
FD.CalculateAffectingAreas()
|
||||
|
||||
if(!keep_cabling && !can_have_cabling())
|
||||
for(var/obj/structure/cable/C in contents)
|
||||
qdel(C)
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
#define ALARM_RESET_DELAY 100 // How long will the alarm/trigger remain active once origin/source has been found to be gone?
|
||||
|
||||
/datum/alarm_source
|
||||
var/source = null // The source trigger
|
||||
var/source_name = "" // The name of the source should it be lost (for example a destroyed camera)
|
||||
var/duration = 0 // How long this source will be alarming, 0 for indefinetely.
|
||||
var/severity = 1 // How severe the alarm from this source is.
|
||||
var/start_time = 0 // When this source began alarming.
|
||||
var/end_time = 0 // Use to set when this trigger should clear, in case the source is lost.
|
||||
|
||||
/datum/alarm_source/New(var/atom/source)
|
||||
src.source = source
|
||||
start_time = world.time
|
||||
source_name = source.get_source_name()
|
||||
|
||||
/datum/alarm
|
||||
var/atom/origin //Used to identify the alarm area.
|
||||
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
|
||||
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
|
||||
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
|
||||
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
|
||||
var/area/last_name //The last acquired name, used should origin be lost
|
||||
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
|
||||
var/end_time //Used to set when this alarm should clear, in case the origin is lost.
|
||||
|
||||
/datum/alarm/New(var/atom/origin, var/atom/source, var/duration, var/severity)
|
||||
src.origin = origin
|
||||
|
||||
cameras() // Sets up both cameras and last alarm area.
|
||||
set_source_data(source, duration, severity)
|
||||
|
||||
/datum/alarm/process()
|
||||
// Has origin gone missing?
|
||||
if(!origin && !end_time)
|
||||
end_time = world.time + ALARM_RESET_DELAY
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
// Has the alarm passed its best before date?
|
||||
if((AS.end_time && world.time > AS.end_time) || (AS.duration && world.time > (AS.start_time + AS.duration)))
|
||||
sources -= AS
|
||||
// Has the source gone missing? Then reset the normal duration and set end_time
|
||||
if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinetely.
|
||||
AS.duration = 0
|
||||
AS.end_time = world.time + ALARM_RESET_DELAY
|
||||
|
||||
/datum/alarm/proc/set_source_data(var/atom/source, var/duration, var/severity)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
if(!AS)
|
||||
AS = new/datum/alarm_source(source)
|
||||
sources += AS
|
||||
sources_assoc[source] = AS
|
||||
// Currently only non-0 durations can be altered (normal alarms VS EMP blasts)
|
||||
if(AS.duration)
|
||||
duration = duration SECONDS
|
||||
AS.duration = duration
|
||||
AS.severity = severity
|
||||
|
||||
/datum/alarm/proc/clear(var/source)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
sources -= AS
|
||||
sources_assoc -= source
|
||||
|
||||
/datum/alarm/proc/alarm_area()
|
||||
if(!origin)
|
||||
return last_area
|
||||
|
||||
last_area = origin.get_alarm_area()
|
||||
return last_area
|
||||
|
||||
/datum/alarm/proc/alarm_name()
|
||||
if(!origin)
|
||||
return last_name
|
||||
|
||||
last_name = origin.get_alarm_name()
|
||||
return last_name
|
||||
|
||||
/datum/alarm/proc/cameras()
|
||||
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
||||
if(cameras && (last_camera_area != alarm_area()))
|
||||
cameras = null
|
||||
|
||||
// The list of cameras is also reset by /proc/invalidateCameraCache()
|
||||
if(!cameras)
|
||||
cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras()
|
||||
|
||||
last_camera_area = last_area
|
||||
return cameras
|
||||
|
||||
/datum/alarm/proc/max_severity()
|
||||
var/max_severity = 0
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
max_severity = max(AS.severity, max_severity)
|
||||
|
||||
return max_severity
|
||||
|
||||
/******************
|
||||
* Assisting procs *
|
||||
******************/
|
||||
/atom/proc/get_alarm_area()
|
||||
var/area/A = get_area(src)
|
||||
return A
|
||||
|
||||
/area/get_alarm_area()
|
||||
return src
|
||||
|
||||
/atom/proc/get_alarm_name()
|
||||
var/area/A = get_area(src)
|
||||
return A.name
|
||||
|
||||
/area/get_alarm_name()
|
||||
return name
|
||||
|
||||
/mob/get_alarm_name()
|
||||
return name
|
||||
|
||||
/atom/proc/get_source_name()
|
||||
return name
|
||||
|
||||
/obj/machinery/camera/get_source_name()
|
||||
return c_tag
|
||||
|
||||
/atom/proc/get_alarm_cameras()
|
||||
var/area/A = get_area(src)
|
||||
return A.get_cameras()
|
||||
|
||||
/area/get_alarm_cameras()
|
||||
return get_cameras()
|
||||
|
||||
/mob/living/silicon/robot/get_alarm_cameras()
|
||||
var/list/cameras = ..()
|
||||
if(camera)
|
||||
cameras += camera
|
||||
|
||||
return cameras
|
||||
|
||||
/mob/living/silicon/robot/syndicate/get_alarm_cameras()
|
||||
return list()
|
||||
@@ -1,103 +0,0 @@
|
||||
#define ALARM_RAISED 1
|
||||
#define ALARM_CLEARED 0
|
||||
|
||||
/datum/alarm_handler
|
||||
var/category = ""
|
||||
var/list/datum/alarm/alarms = new // All alarms, to handle cases when an origin has been deleted with one or more active alarms
|
||||
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin.
|
||||
var/list/listeners = new // A list of all objects interested in alarm changes.
|
||||
|
||||
/datum/alarm_handler/process()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
A.process()
|
||||
check_alarm_cleared(A)
|
||||
|
||||
/datum/alarm_handler/proc/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
var/new_alarm
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
new_alarm = 0
|
||||
//see if there is already an alarm of this origin
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.set_source_data(source, duration, severity)
|
||||
else
|
||||
existing = new/datum/alarm(origin, source, duration, severity)
|
||||
new_alarm = 1
|
||||
|
||||
alarms |= existing
|
||||
alarms_assoc[origin] = existing
|
||||
if(new_alarm)
|
||||
alarms = dd_sortedObjectList(alarms)
|
||||
on_alarm_change(existing, ALARM_RAISED)
|
||||
|
||||
return new_alarm
|
||||
|
||||
/datum/alarm_handler/proc/clearAlarm(var/atom/origin, var/source)
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.clear(source)
|
||||
return check_alarm_cleared(existing)
|
||||
|
||||
/datum/alarm_handler/proc/has_major_alarms()
|
||||
if(alarms && alarms.len)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/alarm_handler/proc/major_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/minor_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/check_alarm_cleared(var/datum/alarm/alarm)
|
||||
if((alarm.end_time && world.time > alarm.end_time) || !alarm.sources.len)
|
||||
alarms -= alarm
|
||||
alarms_assoc -= alarm.origin
|
||||
on_alarm_change(alarm, ALARM_CLEARED)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/alarm_handler/proc/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
for(var/obj/machinery/camera/C in alarm.cameras())
|
||||
if(was_raised)
|
||||
C.network.Add(category)
|
||||
else
|
||||
C.network.Remove(category)
|
||||
notify_listeners(alarm, was_raised)
|
||||
|
||||
/datum/alarm_handler/proc/get_alarm_severity_for_origin(var/atom/origin)
|
||||
if(!origin)
|
||||
return
|
||||
|
||||
origin = origin.get_alarm_origin()
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(!existing)
|
||||
return
|
||||
|
||||
return existing.max_severity()
|
||||
|
||||
/atom/proc/get_alarm_origin()
|
||||
return src
|
||||
|
||||
/turf/get_alarm_origin()
|
||||
var/area/area = get_area(src)
|
||||
return area // Very important to get area.master, as dynamic lightning can and will split areas.
|
||||
|
||||
/datum/alarm_handler/proc/register(var/object, var/procName)
|
||||
listeners[object] = procName
|
||||
|
||||
/datum/alarm_handler/proc/unregister(var/object)
|
||||
listeners -= object
|
||||
|
||||
/datum/alarm_handler/proc/notify_listeners(var/alarm, var/was_raised)
|
||||
for(var/listener in listeners)
|
||||
call(listener, listeners[listener])(src, alarm, was_raised)
|
||||
@@ -1,19 +0,0 @@
|
||||
/datum/alarm_handler/atmosphere
|
||||
category = "Atmosphere Alarms"
|
||||
|
||||
/datum/alarm_handler/atmosphere/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
..()
|
||||
|
||||
/datum/alarm_handler/atmosphere/major_alarms()
|
||||
var/list/major_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() > 1)
|
||||
major_alarms.Add(A)
|
||||
return major_alarms
|
||||
|
||||
/datum/alarm_handler/atmosphere/minor_alarms()
|
||||
var/list/minor_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() == 1)
|
||||
minor_alarms.Add(A)
|
||||
return minor_alarms
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/burglar
|
||||
category = "Burglar Alarms"
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/camera
|
||||
category = "Camera Alarms"
|
||||
@@ -1,11 +0,0 @@
|
||||
/datum/alarm_handler/fire
|
||||
category = "Fire Alarms"
|
||||
|
||||
/datum/alarm_handler/fire/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
if(was_raised)
|
||||
A.fire_alert()
|
||||
else
|
||||
A.fire_reset()
|
||||
..()
|
||||
@@ -1,2 +0,0 @@
|
||||
/datum/alarm_handler/motion
|
||||
category = "Motion Alarms"
|
||||
@@ -1,10 +0,0 @@
|
||||
/datum/alarm_handler/power
|
||||
category = "Power Alarms"
|
||||
|
||||
/datum/alarm_handler/power/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
A.power_alert(was_raised)
|
||||
..()
|
||||
|
||||
/area/proc/power_alert(var/alarming)
|
||||
@@ -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())
|
||||
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.
|
||||
@@ -242,6 +242,46 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
return
|
||||
show_borg_info()
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_alerts()
|
||||
var/list/dat = list("<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>"
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
dat += text("<B>[]</B><BR>\n", cat)
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/area_name = alm[1]
|
||||
var/C = alm[2]
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
continue
|
||||
dat += "<NOBR>"
|
||||
if(C && islist(C))
|
||||
var/dat2 = ""
|
||||
for(var/cam in C)
|
||||
var/obj/machinery/camera/I = locateUID(cam)
|
||||
if(!QDELETED(I))
|
||||
dat2 += text("[]<A HREF=?src=[UID()];switchcamera=[cam]>[]</A>", (dat2 == "") ? "" : " | ", I.c_tag)
|
||||
dat += text("-- [] ([])", area_name, (dat2 != "") ? dat2 : "No Camera")
|
||||
else
|
||||
dat += text("-- [] (No Camera)", area_name)
|
||||
if(sources.len > 1)
|
||||
dat += text("- [] sources", sources.len)
|
||||
dat += "</NOBR><BR>\n"
|
||||
if(!L.len)
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
viewalerts = TRUE
|
||||
var/dat_text = dat.Join("")
|
||||
src << browse(dat_text, "window=aialerts&can_close=0")
|
||||
|
||||
/mob/living/silicon/ai/proc/show_borg_info()
|
||||
stat(null, text("Connected cyborgs: [connected_robots.len]"))
|
||||
for(var/thing in connected_robots)
|
||||
@@ -612,7 +652,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
if(href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"])) in GLOB.cameranet.cameras
|
||||
if(href_list["showalerts"])
|
||||
subsystem_alarm_monitor()
|
||||
ai_alerts()
|
||||
if(href_list["show_paper"])
|
||||
if(last_paper_seen)
|
||||
src << browse(last_paper_seen, "window=show_paper")
|
||||
@@ -787,12 +827,49 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
Bot.call_bot(src, waypoint)
|
||||
|
||||
/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
|
||||
if(O)
|
||||
var/obj/machinery/camera/C = locateUID(O[1])
|
||||
if(O.len == 1 && !QDELETED(C) && C.can_use())
|
||||
queueAlarm("--- [class] alarm detected in [A.name]! (<A HREF=?src=[UID()];switchcamera=[O[1]]>[C.c_tag]</A>)", class)
|
||||
else if(O && O.len)
|
||||
var/foo = 0
|
||||
var/dat2 = ""
|
||||
for(var/thing in O)
|
||||
var/obj/machinery/camera/I = locateUID(thing)
|
||||
if(!QDELETED(I))
|
||||
dat2 += text("[]<A HREF=?src=[UID()];switchcamera=[thing]>[]</A>", (!foo) ? "" : " | ", I.c_tag) //I'm not fixing this shit...
|
||||
foo = 1
|
||||
queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
if(viewalerts)
|
||||
ai_alerts()
|
||||
|
||||
/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()
|
||||
|
||||
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
|
||||
|
||||
if(!tracking)
|
||||
cameraFollow = null
|
||||
|
||||
if(!C || stat == DEAD) //C.can_use())
|
||||
if(QDELETED(C) || stat == DEAD) //C.can_use())
|
||||
return FALSE
|
||||
|
||||
if(!eyeobj)
|
||||
|
||||
@@ -132,8 +132,6 @@
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
|
||||
/mob/living/silicon/ai/updatehealth(reason = "none given")
|
||||
if(status_flags & GODMODE)
|
||||
health = 100
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
handle_robot_cell()
|
||||
process_locks()
|
||||
update_items()
|
||||
process_queued_alarms()
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/handle_robot_cell()
|
||||
|
||||
@@ -71,7 +71,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
|
||||
@@ -544,6 +543,43 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
src.verbs -= GLOB.robot_verbs_default
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/verb/cmd_robot_alerts()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Alerts"
|
||||
if(usr.stat == DEAD)
|
||||
to_chat(src, "<span class='userdanger'>Alert: You are dead.</span>")
|
||||
return //won't work if dead
|
||||
robot_alerts()
|
||||
|
||||
/mob/living/silicon/robot/proc/robot_alerts()
|
||||
var/list/dat = list()
|
||||
var/list/list/temp_alarm_list = SSalarm.alarms.Copy()
|
||||
for(var/cat in temp_alarm_list)
|
||||
if(!(cat in alarms_listend_for))
|
||||
continue
|
||||
dat += text("<B>[cat]</B><BR>\n")
|
||||
var/list/list/L = temp_alarm_list[cat].Copy()
|
||||
for(var/alarm in L)
|
||||
var/list/list/alm = L[alarm].Copy()
|
||||
var/list/list/sources = alm[3].Copy()
|
||||
var/area_name = alm[1]
|
||||
for(var/thing in sources)
|
||||
var/atom/A = locateUID(thing)
|
||||
if(A && A.z != z)
|
||||
L -= alarm
|
||||
continue
|
||||
dat += "<NOBR>"
|
||||
dat += text("-- [area_name]")
|
||||
dat += "</NOBR><BR>\n"
|
||||
if(!L.len)
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
var/datum/browser/alerts = new(usr, "robotalerts", "Current Station Alerts", 400, 410)
|
||||
var/dat_text = dat.Join("")
|
||||
alerts.set_content(dat_text)
|
||||
alerts.open()
|
||||
|
||||
/mob/living/silicon/robot/proc/ionpulse()
|
||||
if(!ionpulse_on)
|
||||
return
|
||||
@@ -605,6 +641,23 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
/mob/living/silicon/robot/InCritical()
|
||||
return low_power_mode
|
||||
|
||||
/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
|
||||
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
|
||||
|
||||
/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)
|
||||
|
||||
/mob/living/silicon/robot/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
@@ -1024,10 +1077,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
src << browse(null, t1)
|
||||
return 1
|
||||
|
||||
if(href_list["showalerts"])
|
||||
subsystem_alarm_monitor()
|
||||
return 1
|
||||
|
||||
if(href_list["mod"])
|
||||
var/obj/item/O = locate(href_list["mod"])
|
||||
if(istype(O) && (O.loc == src))
|
||||
@@ -1042,6 +1091,11 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
activate_module(O)
|
||||
installed_modules()
|
||||
|
||||
//Show alerts window if user clicked on "Show alerts" in chat
|
||||
if(href_list["showalerts"])
|
||||
robot_alerts()
|
||||
return TRUE
|
||||
|
||||
if(href_list["deact"])
|
||||
var/obj/item/O = locate(href_list["deact"])
|
||||
if(activated(O))
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
var/list/stating_laws = list()// Channels laws are currently being stated on
|
||||
var/list/alarms_to_show = list()
|
||||
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/list/alarm_handlers = list() // List of alarm handlers this silicon is registered to
|
||||
var/designation = ""
|
||||
var/obj/item/camera/siliconcam/aiCamera = null //photography
|
||||
//Used in say.dm, allows for pAIs to have different say flavor text, as well as silicons, although the latter is not implemented.
|
||||
@@ -25,9 +27,6 @@
|
||||
|
||||
//var/sensor_mode = 0 //Determines the current HUD.
|
||||
|
||||
var/next_alarm_notice
|
||||
var/list/datum/alarm/queued_alarms = new()
|
||||
|
||||
hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD)
|
||||
|
||||
|
||||
@@ -46,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 +56,93 @@
|
||||
|
||||
/mob/living/silicon/Destroy()
|
||||
GLOB.silicon_mob_list -= src
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/proc/alarm_triggered(src, class, area/A, list/O, obj/alarmsource)
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/alarm_cancelled(src, class, area/A, obj/origin, cleared)
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/queueAlarm(message, type, incoming = TRUE)
|
||||
var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0)
|
||||
if(incoming)
|
||||
alarms_to_show += message
|
||||
alarm_types_show[type] += 1
|
||||
else
|
||||
alarms_to_clear += message
|
||||
alarm_types_clear[type] += 1
|
||||
|
||||
if(in_cooldown)
|
||||
return
|
||||
|
||||
addtimer(CALLBACK(src, .proc/show_alarms), 3 SECONDS)
|
||||
|
||||
/mob/living/silicon/proc/show_alarms()
|
||||
if(alarms_to_show.len < 5)
|
||||
for(var/msg in alarms_to_show)
|
||||
to_chat(src, msg)
|
||||
else if(length(alarms_to_show))
|
||||
|
||||
var/list/msg = list("--- ")
|
||||
|
||||
if(alarm_types_show["Burglar"])
|
||||
msg += "BURGLAR: [alarm_types_show["Burglar"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Motion"])
|
||||
msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Fire"])
|
||||
msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Power"])
|
||||
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_show["Camera"]] alarms detected. - "
|
||||
|
||||
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
|
||||
var/msg_text = msg.Join("")
|
||||
to_chat(src, msg_text)
|
||||
|
||||
if(alarms_to_clear.len < 3)
|
||||
for(var/msg in alarms_to_clear)
|
||||
to_chat(src, msg)
|
||||
|
||||
else if(alarms_to_clear.len)
|
||||
var/list/msg = list("--- ")
|
||||
|
||||
if(alarm_types_clear["Motion"])
|
||||
msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Fire"])
|
||||
msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Power"])
|
||||
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_clear["Camera"]] alarms cleared. - "
|
||||
|
||||
msg += "<A href=?src=[UID()];showalerts=1'>\[Show Alerts\]</a>"
|
||||
|
||||
var/msg_text = msg.Join("")
|
||||
to_chat(src, msg_text)
|
||||
|
||||
|
||||
alarms_to_show.Cut()
|
||||
alarms_to_clear.Cut()
|
||||
for(var/key in alarm_types_show)
|
||||
alarm_types_show[key] = 0
|
||||
for(var/key in alarm_types_clear)
|
||||
alarm_types_clear[key] = 0
|
||||
|
||||
/mob/living/silicon/rename_character(oldname, newname)
|
||||
// we actually don't want it changing minds and stuff
|
||||
if(!newname)
|
||||
@@ -283,63 +367,6 @@
|
||||
if("Disable")
|
||||
to_chat(src, "Sensor augmentations disabled.")
|
||||
|
||||
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
|
||||
if(!next_alarm_notice)
|
||||
next_alarm_notice = world.time + 10 SECONDS
|
||||
|
||||
var/list/alarms = queued_alarms[alarm_handler]
|
||||
if(was_raised)
|
||||
// Raised alarms are always set
|
||||
alarms[alarm] = 1
|
||||
else
|
||||
// Alarms that were raised but then cleared before the next notice are instead removed
|
||||
if(alarm in alarms)
|
||||
alarms -= alarm
|
||||
// And alarms that have only been cleared thus far are set as such
|
||||
else
|
||||
alarms[alarm] = -1
|
||||
|
||||
/mob/living/silicon/proc/process_queued_alarms()
|
||||
if(next_alarm_notice && (world.time > next_alarm_notice))
|
||||
next_alarm_notice = 0
|
||||
|
||||
var/alarm_raised = 0
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == 1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
to_chat(src, "<span class='warning'>--- [AH.category] Detected ---</span>")
|
||||
raised_alarm(A)
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == -1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
to_chat(src, "<span class='notice'>--- [AH.category] Cleared ---</span>")
|
||||
to_chat(src, "\The [A.alarm_name()].")
|
||||
|
||||
if(alarm_raised)
|
||||
to_chat(src, "<A HREF=?src=[UID()];showalerts=1>\[Show Alerts\]</A>")
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
alarms.Cut()
|
||||
|
||||
/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
|
||||
to_chat(src, "[A.alarm_name()]!")
|
||||
|
||||
/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
|
||||
var/cameratext = ""
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=[UID()];switchcamera=\ref[C]>[C.c_tag]</A>"
|
||||
to_chat(src, "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])")
|
||||
|
||||
/mob/living/silicon/adjustToxLoss(var/amount)
|
||||
return STATUS_UPDATE_NONE
|
||||
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
/mob/living/silicon
|
||||
var/list/silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager
|
||||
)
|
||||
|
||||
/mob/living/silicon/ai
|
||||
silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_atmos_control,
|
||||
/mob/living/silicon/proc/subsystem_crew_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager,
|
||||
@@ -23,7 +21,6 @@
|
||||
|
||||
/mob/living/silicon/robot/drone
|
||||
silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_law_manager,
|
||||
/mob/living/silicon/proc/subsystem_power_monitor
|
||||
)
|
||||
@@ -32,30 +29,11 @@
|
||||
register_alarms = 0
|
||||
|
||||
/mob/living/silicon/proc/init_subsystems()
|
||||
alarm_monitor = new(src)
|
||||
atmos_control = new(src)
|
||||
crew_monitor = new(src)
|
||||
law_manager = new(src)
|
||||
power_monitor = new(src)
|
||||
|
||||
if(!register_alarms)
|
||||
return
|
||||
|
||||
var/list/register_to = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
for(var/datum/alarm_handler/AH in register_to)
|
||||
AH.register(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
alarm_handlers |= AH
|
||||
|
||||
/********************
|
||||
* Alarm Monitor *
|
||||
********************/
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Subsystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr, state = GLOB.self_state)
|
||||
|
||||
/********************
|
||||
* Atmos Control *
|
||||
********************/
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
/obj/machinery/modular_computer/console/preset/engineering/install_programs()
|
||||
var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD]
|
||||
hard_drive.store_file(new/datum/computer_file/program/power_monitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
|
||||
// hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) //TO-DO:TGUI--Uncomment Modular computers
|
||||
hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor())
|
||||
|
||||
// ===== RESEARCH CONSOLE =====
|
||||
|
||||
@@ -7,65 +7,71 @@
|
||||
requires_ntnet = 1
|
||||
network_destination = "alarm monitoring network"
|
||||
size = 5
|
||||
var/list/datum/alarm_handler/alarm_handlers
|
||||
var/tgui_id = "NtosStationAlertConsole"
|
||||
var/ui_x = 315
|
||||
var/ui_y = 500
|
||||
var/has_alert = 0
|
||||
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/New()
|
||||
/datum/computer_file/program/alarm_monitor/process_tick()
|
||||
..()
|
||||
alarm_handlers = list(SSalarms.atmosphere_alarm, SSalarms.fire_alarm, SSalarms.power_alarm)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register(src, /datum/computer_file/program/alarm_monitor/proc/update_icon)
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/Destroy()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(src)
|
||||
QDEL_NULL(alarm_handlers)
|
||||
return ..()
|
||||
if(has_alert)
|
||||
program_icon_state = "alert-red"
|
||||
ui_header = "alarm_red.gif"
|
||||
update_computer_icon()
|
||||
else
|
||||
program_icon_state = "alert-green"
|
||||
ui_header = "alarm_green.gif"
|
||||
update_computer_icon()
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/proc/update_icon()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
if(AH.has_major_alarms())
|
||||
program_icon_state = "alert-red"
|
||||
ui_header = "alarm_red.gif"
|
||||
update_computer_icon()
|
||||
return 1
|
||||
program_icon_state = "alert-green"
|
||||
ui_header = "alarm_green.gif"
|
||||
update_computer_icon()
|
||||
return 0
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers)
|
||||
assets.send(user)
|
||||
ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring", 575, 700)
|
||||
ui.set_auto_update(1)
|
||||
ui.set_layout_key("program")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/alarm_monitor/ui_data(mob/user)
|
||||
/datum/computer_file/program/alarm_monitor/tgui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
|
||||
var/categories[0]
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
|
||||
for(var/datum/alarm/A in AH.major_alarms())
|
||||
var/cameras[0]
|
||||
var/lost_sources[0]
|
||||
|
||||
if(isAI(user))
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameras[++cameras.len] = C.nano_structure()
|
||||
for(var/datum/alarm_source/AS in A.sources)
|
||||
if(!AS.source)
|
||||
lost_sources[++lost_sources.len] = AS.source_name
|
||||
|
||||
categories[categories.len]["alarms"] += list(list(
|
||||
"name" = sanitize(A.alarm_name()),
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
data["alarms"] = list()
|
||||
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/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(alarmsource.z) || istype(A, /area/ruin))
|
||||
return
|
||||
update_alarm_display()
|
||||
|
||||
/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()
|
||||
|
||||
/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(length(L))
|
||||
has_alert = TRUE
|
||||
|
||||
/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,90 +0,0 @@
|
||||
/datum/nano_module/alarm_monitor
|
||||
name = "Alarm monitor"
|
||||
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
|
||||
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
|
||||
|
||||
/datum/nano_module/alarm_monitor/all/New()
|
||||
..()
|
||||
alarm_handlers = list(SSalarms.atmosphere_alarm, SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.fire_alarm, SSalarms.motion_alarm, SSalarms.power_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/engineering/New()
|
||||
..()
|
||||
alarm_handlers = list(SSalarms.atmosphere_alarm, SSalarms.fire_alarm, SSalarms.power_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/security/New()
|
||||
..()
|
||||
alarm_handlers = list(SSalarms.burglar_alarm, SSalarms.camera_alarm, SSalarms.motion_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/register(var/object, var/procName)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register(object, procName)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/unregister(var/object)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(object)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/all_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/major_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.major_alarms()
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/minor_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.minor_alarms()
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["switchTo"])
|
||||
var/obj/machinery/camera/C = locate(href_list["switchTo"]) in GLOB.cameranet.cameras
|
||||
if(!C || !isAI(usr))
|
||||
return
|
||||
|
||||
usr.switch_to_camera(C)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = GLOB.default_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/alarm_monitor/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
|
||||
var/categories[0]
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
|
||||
for(var/datum/alarm/A in AH.major_alarms())
|
||||
var/cameras[0]
|
||||
var/lost_sources[0]
|
||||
|
||||
if(isAI(user))
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameras[++cameras.len] = C.nano_structure()
|
||||
for(var/datum/alarm_source/AS in A.sources)
|
||||
if(!AS.source)
|
||||
lost_sources[++lost_sources.len] = AS.source_name
|
||||
|
||||
categories[categories.len]["alarms"] += list(list(
|
||||
"name" = sanitize(A.alarm_name()),
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
|
||||
return data
|
||||
+11
-12
@@ -216,8 +216,7 @@
|
||||
area = A
|
||||
name = "\improper [area.name] APC"
|
||||
else
|
||||
area = get_area_name(areastring)
|
||||
name = "\improper [area.name] APC"
|
||||
name = "\improper [get_area_name(area, TRUE)] APC"
|
||||
area.apc |= src
|
||||
|
||||
update_icon()
|
||||
@@ -1192,31 +1191,31 @@
|
||||
lighting = autoset(lighting, 1)
|
||||
environ = autoset(environ, 1)
|
||||
autoflag = 3
|
||||
if(report_power_alarm && is_station_contact(z))
|
||||
SSalarms.power_alarm.clearAlarm(loc, src)
|
||||
if(report_power_alarm)
|
||||
area.poweralert(TRUE, src)
|
||||
else if(cell.charge < 1250 && cell.charge > 750 && longtermpower < 0) // <30%, turn off equipment
|
||||
if(autoflag != 2)
|
||||
equipment = autoset(equipment, 2)
|
||||
lighting = autoset(lighting, 1)
|
||||
environ = autoset(environ, 1)
|
||||
if(report_power_alarm && is_station_contact(z))
|
||||
SSalarms.power_alarm.triggerAlarm(loc, src)
|
||||
if(report_power_alarm)
|
||||
area.poweralert(FALSE, src)
|
||||
autoflag = 2
|
||||
else if(cell.charge < 750 && cell.charge > 10) // <15%, turn off lighting & equipment
|
||||
if((autoflag > 1 && longtermpower < 0) || (autoflag > 1 && longtermpower >= 0))
|
||||
equipment = autoset(equipment, 2)
|
||||
lighting = autoset(lighting, 2)
|
||||
environ = autoset(environ, 1)
|
||||
if(report_power_alarm && is_station_contact(z))
|
||||
SSalarms.power_alarm.triggerAlarm(loc, src)
|
||||
if(report_power_alarm)
|
||||
area.poweralert(FALSE, src)
|
||||
autoflag = 1
|
||||
else if(cell.charge <= 0) // zero charge, turn all off
|
||||
if(autoflag != 0)
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
if(report_power_alarm && is_station_contact(z))
|
||||
SSalarms.power_alarm.triggerAlarm(loc, src)
|
||||
if(report_power_alarm)
|
||||
area.poweralert(FALSE, src)
|
||||
autoflag = 0
|
||||
|
||||
// now trickle-charge the cell
|
||||
@@ -1271,8 +1270,8 @@
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
if(report_power_alarm && is_station_contact(z))
|
||||
SSalarms.power_alarm.triggerAlarm(loc, src)
|
||||
if(report_power_alarm)
|
||||
area.poweralert(FALSE, src)
|
||||
autoflag = 0
|
||||
|
||||
// update icon & area power if anything changed
|
||||
|
||||
@@ -177,6 +177,8 @@
|
||||
var/nightshift_light_power = 0.45
|
||||
var/nightshift_light_color = "#FFDDCC"
|
||||
|
||||
var/bulb_emergency_colour = "#FF3232" // determines the colour of the light while it's in emergency mode
|
||||
|
||||
// the smaller bulb light fixture
|
||||
|
||||
/obj/machinery/light/small
|
||||
@@ -238,7 +240,11 @@
|
||||
|
||||
switch(status) // set icon_states
|
||||
if(LIGHT_OK)
|
||||
icon_state = "[base_state][on]"
|
||||
var/area/A = get_area(src)
|
||||
if(A && A.fire)
|
||||
icon_state = "[base_state]_emergency"
|
||||
else
|
||||
icon_state = "[base_state][on]"
|
||||
if(LIGHT_EMPTY)
|
||||
icon_state = "[base_state]-empty"
|
||||
on = FALSE
|
||||
@@ -260,10 +266,20 @@
|
||||
on = FALSE
|
||||
update_icon()
|
||||
if(on)
|
||||
var/BR = nightshift_enabled ? nightshift_light_range : brightness_range
|
||||
var/PO = nightshift_enabled ? nightshift_light_power : brightness_power
|
||||
var/CO = nightshift_enabled ? nightshift_light_color : brightness_color
|
||||
var/matching = light_range == BR && light_power == PO && light_color == CO
|
||||
var/BR = brightness_range
|
||||
var/PO = brightness_power
|
||||
var/CO = brightness_color
|
||||
if(color)
|
||||
CO = color
|
||||
var/area/A = get_area(src)
|
||||
if(A && A.fire)
|
||||
CO = bulb_emergency_colour
|
||||
else if(nightshift_enabled)
|
||||
BR = nightshift_light_range
|
||||
PO = nightshift_light_power
|
||||
if(!color)
|
||||
CO = nightshift_light_color
|
||||
var/matching = light && BR == light.light_range && PO == light.light_power && CO == light.light_color
|
||||
if(!matching)
|
||||
switchcount++
|
||||
if(rigged)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/area/engine/engineering/power_alert(var/alarming)
|
||||
if(alarming)
|
||||
investigate_log("has a power alarm!","singulo")
|
||||
/area/engine/engineering/poweralert(state, source)
|
||||
if(state != poweralm)
|
||||
investigate_log("has a power alarm!", "singulo")
|
||||
..()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
@@ -1,39 +0,0 @@
|
||||
<!--
|
||||
Title: Alarm Monitor Console (Main content)
|
||||
Used In File(s): \code\modules\nano\modules\alarm_monitor.dm
|
||||
-->
|
||||
|
||||
{{for data.categories}}
|
||||
<h2 style="color: #e9c183;">{{:value.category}}</h2>
|
||||
{{for value.alarms :alarmValue:alarmIndex}}
|
||||
{{if alarmValue.origin_lost}}
|
||||
<b>{{:alarmValue.name}} <span class='notice'>Alarm Origin Lost</span></b><br />
|
||||
{{else}}
|
||||
<b>{{:alarmValue.name}}</b><br />
|
||||
{{/if}}
|
||||
{{if alarmValue.has_cameras || alarmValue.lost_sources != ""}}
|
||||
<div class="item">
|
||||
{{if alarmValue.has_cameras}}
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
{{for alarmValue.cameras :cameraValue:cameraIndex}}
|
||||
{{if cameraValue.deact}}
|
||||
{{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}}
|
||||
{{else}}
|
||||
{{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}}
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
</div>
|
||||
{{else}}
|
||||
No cameras found.
|
||||
{{/if}}
|
||||
{{if alarmValue.lost_sources != ""}}
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
<H4><span class='notice'>Lost Alarm Sources: {{:alarmValue.lost_sources}}</span></H4>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{empty}}
|
||||
<span class="white">--All Systems Nominal</span>
|
||||
{{/for}}
|
||||
{{/for}}
|
||||
@@ -1,18 +0,0 @@
|
||||
<h1>Priority Alerts</h1>
|
||||
{{for data.priority_alarms}}
|
||||
<div class="item">
|
||||
{{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}}
|
||||
</div>
|
||||
{{empty}}
|
||||
No priority alerts detected.
|
||||
{{/for}}
|
||||
|
||||
<h3>Minor Alerts</h3>
|
||||
{{for data.minor_alarms}}
|
||||
<div class="item">
|
||||
{{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}}
|
||||
</div>
|
||||
{{empty}}
|
||||
No minor alerts detected.
|
||||
{{/for}}
|
||||
|
||||
@@ -1242,14 +1242,6 @@
|
||||
#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm"
|
||||
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
|
||||
#include "code\modules\admin\verbs\SDQL2\useful_procs.dm"
|
||||
#include "code\modules\alarm\alarm.dm"
|
||||
#include "code\modules\alarm\alarm_handler.dm"
|
||||
#include "code\modules\alarm\atmosphere_alarm.dm"
|
||||
#include "code\modules\alarm\burglar_alarm.dm"
|
||||
#include "code\modules\alarm\camera_alarm.dm"
|
||||
#include "code\modules\alarm\fire_alarm.dm"
|
||||
#include "code\modules\alarm\motion_alarm.dm"
|
||||
#include "code\modules\alarm\power_alarm.dm"
|
||||
#include "code\modules\antagonists\_common\antag_datum.dm"
|
||||
#include "code\modules\antagonists\_common\antag_helpers.dm"
|
||||
#include "code\modules\antagonists\_common\antag_hud.dm"
|
||||
@@ -2067,7 +2059,6 @@
|
||||
#include "code\modules\modular_computers\file_system\programs\antagonist\revelation.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\command\card.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\command\comms.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\engineering\alarm.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\engineering\sm_monitor.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\generic\configurator.dm"
|
||||
@@ -2105,7 +2096,6 @@
|
||||
#include "code\modules\nano\interaction\physical.dm"
|
||||
#include "code\modules\nano\interaction\self.dm"
|
||||
#include "code\modules\nano\interaction\zlevel.dm"
|
||||
#include "code\modules\nano\modules\alarm_monitor.dm"
|
||||
#include "code\modules\nano\modules\atmos_control.dm"
|
||||
#include "code\modules\nano\modules\ert_manager.dm"
|
||||
#include "code\modules\nano\modules\human_appearance.dm"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Button, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const AtmosAlertConsole = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const priorityAlerts = data.priority || [];
|
||||
const minorAlerts = data.minor || [];
|
||||
return (
|
||||
<Window resizable>
|
||||
<Window.Content scrollable>
|
||||
<Section title="Alarms">
|
||||
<ul>
|
||||
{priorityAlerts.length === 0 && (
|
||||
<li className="color-good">
|
||||
No Priority Alerts
|
||||
</li>
|
||||
)}
|
||||
{priorityAlerts.map(alert => (
|
||||
<li key={alert}>
|
||||
<Button
|
||||
icon="times"
|
||||
content={alert}
|
||||
color="bad"
|
||||
onClick={() => act('clear', { zone: alert })} />
|
||||
</li>
|
||||
))}
|
||||
{minorAlerts.length === 0 && (
|
||||
<li className="color-good">
|
||||
No Minor Alerts
|
||||
</li>
|
||||
)}
|
||||
{minorAlerts.map(alert => (
|
||||
<li key={alert}>
|
||||
<Button
|
||||
icon="times"
|
||||
content={alert}
|
||||
color="average"
|
||||
onClick={() => act('clear', { zone: alert })} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
import { NtosWindow } from '../layouts';
|
||||
import { StationAlertConsoleContent } from './StationAlertConsole';
|
||||
|
||||
export const NtosStationAlertConsole = () => {
|
||||
return (
|
||||
<NtosWindow resizable>
|
||||
<NtosWindow.Content scrollable>
|
||||
<StationAlertConsoleContent />
|
||||
</NtosWindow.Content>
|
||||
</NtosWindow>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const StationAlertConsole = () => {
|
||||
return (
|
||||
<Window resizable>
|
||||
<Window.Content scrollable>
|
||||
<StationAlertConsoleContent />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
export const StationAlertConsoleContent = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
const categories = data.alarms || [];
|
||||
const fire = categories['Fire'] || [];
|
||||
const atmos = categories['Atmosphere'] || [];
|
||||
const power = categories['Power'] || [];
|
||||
return (
|
||||
<Fragment>
|
||||
<Section title="Fire Alarms">
|
||||
<ul>
|
||||
{fire.length === 0 && (
|
||||
<li className="color-good">
|
||||
Systems Nominal
|
||||
</li>
|
||||
)}
|
||||
{fire.map(alert => (
|
||||
<li key={alert} className="color-average">
|
||||
{alert}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Section>
|
||||
<Section title="Atmospherics Alarms">
|
||||
<ul>
|
||||
{atmos.length === 0 && (
|
||||
<li className="color-good">
|
||||
Systems Nominal
|
||||
</li>
|
||||
)}
|
||||
{atmos.map(alert => (
|
||||
<li key={alert} className="color-average">
|
||||
{alert}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Section>
|
||||
<Section title="Power Alarms">
|
||||
<ul>
|
||||
{power.length === 0 && (
|
||||
<li className="color-good">
|
||||
Systems Nominal
|
||||
</li>
|
||||
)}
|
||||
{power.map(alert => (
|
||||
<li key={alert} className="color-average">
|
||||
{alert}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Section>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user