From 1c9a384a8daf063eb11d64e2ec00b087f4c229fe Mon Sep 17 00:00:00 2001 From: Mike Date: Wed, 14 May 2014 20:20:30 -0400 Subject: [PATCH] Cherrypick from 'ai-alarms' Refactoring and clean-up of alarm code for AI and robots. --- baystation12.dme | 1 + code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/camera/motion.dm | 4 +- code/modules/mob/living/silicon/ai/ai.dm | 96 +++++---------- code/modules/mob/living/silicon/alarm.dm | 111 ++++++++++++++++++ .../modules/mob/living/silicon/robot/robot.dm | 58 +++------ code/modules/mob/living/silicon/silicon.dm | 80 ------------- 7 files changed, 159 insertions(+), 193 deletions(-) create mode 100644 code/modules/mob/living/silicon/alarm.dm diff --git a/baystation12.dme b/baystation12.dme index f09b367b43..43e4f78c28 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -956,6 +956,7 @@ #include "code\modules\mob\living\carbon\monkey\monkey.dm" #include "code\modules\mob\living\carbon\monkey\powers.dm" #include "code\modules\mob\living\carbon\monkey\update_icons.dm" +#include "code\modules\mob\living\silicon\alarm.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\login.dm" #include "code\modules\mob\living\silicon\say.dm" diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index daea3219d6..5d206b9f94 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -215,7 +215,7 @@ /obj/machinery/camera/proc/cancelCameraAlarm() alarm_on = 0 for(var/mob/living/silicon/S in mob_list) - S.cancelAlarm("Camera", get_area(src), list(src), src) + S.cancelAlarm("Camera", get_area(src), src) /obj/machinery/camera/proc/can_use() if(!status) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 588ab5005c..19f2620630 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -42,14 +42,14 @@ /obj/machinery/camera/proc/cancelAlarm() if (detectTime == -1) for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc) + if (status) aiPlayer.cancelAlarm("Motion", get_area(src), src) detectTime = 0 return 1 /obj/machinery/camera/proc/triggerAlarm() if (!detectTime) return 0 for (var/mob/living/silicon/aiPlayer in player_list) - if (status) aiPlayer.triggerAlarm("Motion", src.loc.loc, src) + if (status) aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) detectTime = -1 return 1 diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index dfda7bae5c..77ec775059 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -24,7 +24,6 @@ var/list/ai_list = 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()) var/viewalerts = 0 var/lawcheck[1] var/ioncheck[1] @@ -237,26 +236,20 @@ var/list/ai_list = list() dat += "Close

" for (var/cat in alarms) dat += text("[]
\n", cat) - var/list/L = alarms[cat] - if (L.len) - for (var/alarm in L) - var/list/alm = L[alarm] - var/area/A = alm[1] - var/C = alm[2] - var/list/sources = alm[3] + var/list/alarmlist = alarms[cat] + if (alarmlist.len) + for (var/area_name in alarmlist) + var/datum/alarm/alarm = alarmlist[area_name] dat += "" - if (C && istype(C, /list)) - var/dat2 = "" - for (var/obj/machinery/camera/I in C) - dat2 += text("[][]", (dat2=="") ? "" : " | ", src, I, I.c_tag) - dat += text("-- [] ([])", A.name, (dat2!="") ? dat2 : "No Camera") - else if (C && istype(C, /obj/machinery/camera)) - var/obj/machinery/camera/Ctmp = C - dat += text("-- [] ([])", A.name, src, C, Ctmp.c_tag) - else - dat += text("-- [] (No Camera)", A.name) - if (sources.len > 1) - dat += text("- [] sources", sources.len) + + var/cameratext = "" + if (alarm.cameras) + for (var/obj/machinery/camera/I in alarm.cameras) + cameratext += text("[][]", (cameratext=="") ? "" : " | ", src, I, I.c_tag) + dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera") + + if (alarm.sources.len > 1) + dat += text(" - [] sources", alarm.sources.len) dat += "
\n" else dat += "-- All Systems Nominal
\n" @@ -534,59 +527,28 @@ var/list/ai_list = list() return 1 -/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource) +/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source) if (stat == 2) return 1 - 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 in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - if (O) - if (C && C.can_use()) - queueAlarm("--- [class] alarm detected in [A.name]! ([C.c_tag])", class) - else if (CL && CL.len) - var/foo = 0 - var/dat2 = "" - for (var/obj/machinery/camera/I in CL) - dat2 += text("[][]", (!foo) ? "" : " | ", src, I, 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) + + ..() + + var/cameratext = "" + for (var/obj/machinery/camera/C in cameralist) + cameratext += "[(cameratext == "")? "" : "|"][C.c_tag]" + + queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class) + if (viewalerts) ai_alerts() - return 1 -/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, obj/origin) - var/list/L = alarms[class] - var/cleared = 0 - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/srcs = alarm[3] - if (origin in srcs) - srcs -= origin - if (srcs.len == 0) - cleared = 1 - L -= I - if (cleared) +/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source) + var/has_alarm = ..() + + if (!has_alarm) queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0) if (viewalerts) ai_alerts() - return !cleared + + return has_alarm /mob/living/silicon/ai/cancel_camera() set category = "AI Commands" diff --git a/code/modules/mob/living/silicon/alarm.dm b/code/modules/mob/living/silicon/alarm.dm new file mode 100644 index 0000000000..ee505fae5c --- /dev/null +++ b/code/modules/mob/living/silicon/alarm.dm @@ -0,0 +1,111 @@ +/datum/alarm + var/area/area //the area associated with the alarm. Used to identify the alarm + var/list/sources //list of things triggering the alarm. Used to determine when the alarm should be cleared. + var/list/cameras //list of cameras that can be switched to, if the player has that capability. + +/datum/alarm/New(area/A, list/sourcelist=list(), list/cameralist=list()) + area = A + sources = sourcelist + cameras = cameralist + +/mob/living/silicon + var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list()) //each sublist stores alarms keyed by the area name + 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) + +/mob/living/silicon/proc/triggerAlarm(var/class, area/A, list/cameralist, var/source) + var/list/alarmlist = alarms[class] + + //see if there is already an alarm of this class for this area + if (A.name in alarmlist) + var/datum/alarm/existing = alarmlist[A.name] + existing.sources += source + existing.cameras |= cameralist + else + alarmlist[A.name] = new /datum/alarm(A, list(source), cameralist) + +/mob/living/silicon/proc/cancelAlarm(var/class, area/A as area, var/source) + var/cleared = 0 + var/list/alarmlist = alarms[class] + + if (A.name in alarmlist) + var/datum/alarm/alarm = alarmlist[A.name] + alarm.sources -= source + + if (!(alarm.sources.len)) + cleared = 1 + alarmlist -= A.name + + return !cleared + +/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1) + 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) + spawn(10 * 10) // 10 seconds + + if(alarms_to_show.len < 5) + for(var/msg in alarms_to_show) + src << msg + else if(alarms_to_show.len) + + var/msg = "--- " + + 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["Power"]] alarms detected. - " + + msg += "\[Show Alerts\]" + src << msg + + if(alarms_to_clear.len < 3) + for(var/msg in alarms_to_clear) + src << msg + + else if(alarms_to_clear.len) + var/msg = "--- " + + 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_show["Power"]] alarms detected. - " + + msg += "\[Show Alerts\]" + src << msg + + + alarms_to_show = list() + alarms_to_clear = list() + for(var/i = 1; i < alarm_types_show.len; i++) + alarm_types_show[i] = 0 + for(var/i = 1; i < alarm_types_clear.len; i++) + alarm_types_clear[i] = 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 6b3bea036b..484fd521c6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -46,7 +46,6 @@ var/list/req_access = list(access_robotics) 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 @@ -328,16 +327,14 @@ dat += "Close

" for (var/cat in alarms) dat += text("[cat]
\n") - var/list/L = alarms[cat] - if (L.len) - for (var/alarm in L) - var/list/alm = L[alarm] - var/area/A = alm[1] - var/list/sources = alm[3] + var/list/alarmlist = alarms[cat] + if (alarmlist.len) + for (var/area_name in alarmlist) + var/datum/alarm/alarm = alarmlist[area_name] dat += "" - dat += text("-- [A.name]") - if (sources.len > 1) - dat += text("- [sources.len] sources") + dat += text("-- [area_name]") + if (alarm.sources.len > 1) + dat += text("- [alarm.sources.len] sources") dat += "
\n" else dat += "-- All Systems Nominal
\n" @@ -529,47 +526,22 @@ return -/mob/living/silicon/robot/triggerAlarm(var/class, area/A, var/O, var/alarmsource) +/mob/living/silicon/robot/triggerAlarm(var/class, area/A, list/cameralist, var/source) if (stat == 2) return 1 - 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 in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) + + ..() + queueAlarm(text("--- [class] alarm detected in [A.name]!"), class) -// if (viewalerts) robot_alerts() - return 1 /mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin) - var/list/L = alarms[class] - var/cleared = 0 - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/srcs = alarm[3] - if (origin in srcs) - srcs -= origin - if (srcs.len == 0) - cleared = 1 - L -= I - if (cleared) + var/has_alarm = ..() + + if (!has_alarm) queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0) // if (viewalerts) robot_alerts() - return !cleared + return has_alarm /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 944063d9e0..9a1fdd85dd 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -4,92 +4,12 @@ voice_name = "synthesized voice" var/syndicate = 0 var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS - var/list/alarms_to_show = list() - var/list/alarms_to_clear = list() immune_to_ssd = 1 var/list/hud_list[9] - 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) - -/mob/living/silicon/proc/cancelAlarm() - return - -/mob/living/silicon/proc/triggerAlarm() - return /mob/living/silicon/proc/show_laws() return -/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1) - 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) - spawn(10 * 10) // 10 seconds - - if(alarms_to_show.len < 5) - for(var/msg in alarms_to_show) - src << msg - else if(alarms_to_show.len) - - var/msg = "--- " - - 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["Power"]] alarms detected. - " - - msg += "\[Show Alerts\]" - src << msg - - if(alarms_to_clear.len < 3) - for(var/msg in alarms_to_clear) - src << msg - - else if(alarms_to_clear.len) - var/msg = "--- " - - 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_show["Power"]] alarms detected. - " - - msg += "\[Show Alerts\]" - src << msg - - - alarms_to_show = list() - alarms_to_clear = list() - for(var/i = 1; i < alarm_types_show.len; i++) - alarm_types_show[i] = 0 - for(var/i = 1; i < alarm_types_clear.len; i++) - alarm_types_clear[i] = 0 - /mob/living/silicon/drop_item() return