mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Merge pull request #13751 from Fox-McCloud/alarm-overhaul
Overhauls and Refactors Alarm System
This commit is contained in:
@@ -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")
|
||||
..()
|
||||
|
||||
Reference in New Issue
Block a user