From f25de59ecdfe795d682f744d220639b8f79c180d Mon Sep 17 00:00:00 2001 From: davipatury Date: Mon, 20 Feb 2017 11:44:34 -0300 Subject: [PATCH] AI Restorer and Alarm Monitor. --- code/modules/alarm/alarm_handler.dm | 5 + .../file_system/programs/airestorer.dm | 138 ++++++++++++++++++ .../file_system/programs/alarm.dm | 70 +++++++++ nano/templates/ai_restorer.tmpl | 45 ++++++ nano/templates/file_manager.tmpl | 16 +- nano/templates/ntnet_dos.tmpl | 4 +- paradise.dme | 2 + 7 files changed, 270 insertions(+), 10 deletions(-) create mode 100644 code/modules/modular_computers/file_system/programs/airestorer.dm create mode 100644 code/modules/modular_computers/file_system/programs/alarm.dm create mode 100644 nano/templates/ai_restorer.tmpl diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm index 9878a4b5e5e..cd09ebe4427 100644 --- a/code/modules/alarm/alarm_handler.dm +++ b/code/modules/alarm/alarm_handler.dm @@ -47,6 +47,11 @@ 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 diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm new file mode 100644 index 00000000000..0f662b427ce --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -0,0 +1,138 @@ + + +/datum/computer_file/program/aidiag + filename = "aidiag" + filedesc = "AI Maintenance Utility" + program_icon_state = "generic" + extended_desc = "This program is capable of reconstructing damaged AI systems. Requires direct AI connection via intellicard slot." + size = 12 + requires_ntnet = 0 + usage_flags = PROGRAM_CONSOLE + transfer_access = access_heads + available_on_ntnet = 1 + var/restoring = FALSE + +/datum/computer_file/program/aidiag/proc/get_ai(cardcheck) + + var/obj/item/weapon/computer_hardware/ai_slot/ai_slot + + if(computer) + ai_slot = computer.all_components[MC_AI] + + if(computer && ai_slot && ai_slot.check_functionality()) + if(cardcheck == 1) + return ai_slot + if(ai_slot.enabled && ai_slot.stored_card) + if(cardcheck == 2) + return ai_slot.stored_card + if(locate(/mob/living/silicon/ai) in ai_slot.stored_card) + return locate(/mob/living/silicon/ai) in ai_slot.stored_card + + return null + +/datum/computer_file/program/aidiag/Topic(href, list/href_list) + if(..()) + return TRUE + + var/mob/living/silicon/ai/A = get_ai() + if(!A) + restoring = FALSE + + switch(href_list["action"]) + if("PRG_beginReconstruction") + if(A && A.health < 100) + restoring = TRUE + return TRUE + if("PRG_eject") + if(computer.all_components[MC_AI]) + var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI] + if(ai_slot && ai_slot.stored_card) + ai_slot.try_eject(0,usr) + return TRUE + +/datum/computer_file/program/aidiag/process_tick() + ..() + if(!restoring) //Put the check here so we don't check for an ai all the time + return + var/obj/item/device/aicard/cardhold = get_ai(2) + + var/obj/item/weapon/computer_hardware/ai_slot/ai_slot = get_ai(1) + + + var/mob/living/silicon/ai/A = get_ai() + if(!A || !cardhold) + restoring = FALSE // If the AI was removed, stop the restoration sequence. + if(ai_slot) + ai_slot.locked = FALSE + return + + if(cardhold.flush) + ai_slot.locked = FALSE + restoring = FALSE + return + ai_slot.locked = TRUE + A.adjustOxyLoss(-1) + A.adjustFireLoss(-1) + A.adjustToxLoss(-1) + A.adjustBruteLoss(-1) + A.updatehealth() + if(A.health >= 0 && A.stat == DEAD) + A.stat = CONSCIOUS + A.lying = 0 + dead_mob_list -= A + living_mob_list += A + // Finished restoring + if(A.health >= 100) + ai_slot.locked = FALSE + restoring = FALSE + + return TRUE + + +/datum/computer_file/program/aidiag/ui_data(mob/user) + var/list/data = get_header_data() + var/mob/living/silicon/ai/AI + // A shortcut for getting the AI stored inside the computer. The program already does necessary checks. + AI = get_ai() + + var/obj/item/device/aicard/aicard = get_ai(2) + + if(!aicard) + data["nocard"] = TRUE + data["error"] = "Please insert an intelliCard." + else + if(!AI) + data["error"] = "No AI located" + else + var/obj/item/device/aicard/cardhold = AI.loc + if(cardhold.flush) + data["error"] = "Flush in progress" + else + data["name"] = AI.name + data["restoring"] = restoring + data["health"] = (AI.health + 100) / 2 + data["isDead"] = AI.stat == DEAD + + var/list/all_laws[0] + for(var/datum/ai_law/L in AI.laws.all_laws()) + all_laws.Add(list(list( + "index" = L.index, + "text" = L.law + ))) + + data["ai_laws"] = all_laws + + return data + +/datum/computer_file/program/aidiag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = nanomanager.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, "ai_restorer.tmpl", "Integrity Restorer", 600, 400) + ui.set_auto_update(1) + ui.open() + +/datum/computer_file/program/aidiag/kill_program(forced) + restoring = FALSE + return ..(forced) \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm new file mode 100644 index 00000000000..17e0a8ad2fb --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -0,0 +1,70 @@ +/datum/computer_file/program/alarm_monitor + filename = "alarmmonitor" + filedesc = "Alarm Monitoring" + ui_header = "alarm_green.gif" + program_icon_state = "alert-green" + extended_desc = "This program provides visual interface for station's alarm system." + requires_ntnet = 1 + network_destination = "alarm monitoring network" + size = 5 + var/list/datum/alarm_handler/alarm_handlers + +/datum/computer_file/program/alarm_monitor/New() + ..() + alarm_handlers = list(atmosphere_alarm, fire_alarm, 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() + ..() + alarm_handlers.unregister(src) + qdel(alarm_handlers) + alarm_handlers = null + +/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 = nanomanager.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.open() + +/datum/computer_file/program/alarm_monitor/ui_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 + + return data \ No newline at end of file diff --git a/nano/templates/ai_restorer.tmpl b/nano/templates/ai_restorer.tmpl new file mode 100644 index 00000000000..bfb23901e19 --- /dev/null +++ b/nano/templates/ai_restorer.tmpl @@ -0,0 +1,45 @@ +{{if data.restoring}} +
Reconstruction in progress!
+{{/if}} + +
+
Inserted AI:
+
{{:helper.link(data.name ? data.name : "-----", 'eject', {'action' : 'PRG_eject'}, data.nocard ? 'disabled' : null)}}
+
+ +{{if data.error}} + ERROR: {{:data.error}} +{{else}} +

System Status

+
+
+
Current AI:
+
{{:data.name}}
+
+
+
Status:
+
{{if data.isDead}}Nonfunctional{{else}}Functional{{/if}}
+
+
+
System Integrity:
+ {{:helper.displayBar(data.health, 0, 100, (data.health > 75) ? 'good' : (health > 50) ? 'average' : 'bad')}} +
+ {{:helper.smoothRound(data.health)}}% +
+
+
+
+ Active Laws: +
+
+ + {{for data.ai_laws}} +
{{:value.index}}: {{:value.text}} + {{/for}} +
+
+
+
+

Operations

+ {{:helper.link('Begin Reconstruction', 'plus', {'action' : 'PRG_beginReconstruction'}, data.restoring ? 'disabled' : null)}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/file_manager.tmpl b/nano/templates/file_manager.tmpl index 7cf1dd8a676..1bdb0cd95c4 100644 --- a/nano/templates/file_manager.tmpl +++ b/nano/templates/file_manager.tmpl @@ -28,12 +28,12 @@ .{{:value.type}} {{:value.size}}GQ - {{:helper.link('VIEW', null, {'action' : 'PRG_openfile', 'name' : value.name})}} - {{:helper.link('DELETE', null, {'action' : 'PRG_deletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{:helper.link('RENAME', null, {'action' : 'PRG_rename', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} - {{:helper.link('CLONE', null, {'action' : 'PRG_clone', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('VIEW', 'eye', {'action' : 'PRG_openfile', 'name' : value.name})}} + {{:helper.link('DELETE', 'trash', {'action' : 'PRG_deletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('RENAME', 'pencil', {'action' : 'PRG_rename', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('CLONE', 'files-o', {'action' : 'PRG_clone', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} {{if data.usbconnected}} - {{:helper.link('EXPORT', null, {'action' : 'PRG_copytousb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('EXPORT', 'upload', {'action' : 'PRG_copytousb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} {{/if}} @@ -56,9 +56,9 @@ .{{:value.type}} {{:value.size}}GQ - {{:helper.link('DELETE', null, {'action' : 'PRG_usbdeletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('DELETE', 'trash', {'action' : 'PRG_usbdeletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} {{if data.usbconnected}} - {{:helper.link('IMPORT', null, {'action' : 'PRG_copyfromusb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} + {{:helper.link('IMPORT', 'download', {'action' : 'PRG_copyfromusb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}} {{/if}} @@ -66,6 +66,6 @@ {{/if}} - {{:helper.link('NEW DATA FILE', null, {'action' : 'PRG_newtextfile'})}} + {{:helper.link('NEW DATA FILE', 'file-text', {'action' : 'PRG_newtextfile'})}} {{/if}} {{/if}} \ No newline at end of file diff --git a/nano/templates/ntnet_dos.tmpl b/nano/templates/ntnet_dos.tmpl index 93faa096bfe..db92c2e84b7 100644 --- a/nano/templates/ntnet_dos.tmpl +++ b/nano/templates/ntnet_dos.tmpl @@ -14,12 +14,12 @@
{{if data.focus}}{{:data.focus}}{{else}}None{{/if}}
- {{:helper.link('EXECUTE', null, { 'PRG_execute' : 1 })}}
+ {{:helper.link('EXECUTE', null, {'action' : 'PRG_execute'})}}
Detected devices on network:
{{for data.relays}} -
{{:helper.link(value.id, null, {'action' : 'PRG_target_relay', 'targid' : value.id})}} +
{{:helper.link(value.id, null, {'action' : 'PRG_target_relay', 'targid' : value.id})}} {{/for}}
{{/if}} \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 996c56dedfe..901804277da 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1769,6 +1769,8 @@ #include "code\modules\modular_computers\file_system\data.dm" #include "code\modules\modular_computers\file_system\program.dm" #include "code\modules\modular_computers\file_system\program_events.dm" +#include "code\modules\modular_computers\file_system\programs\airestorer.dm" +#include "code\modules\modular_computers\file_system\programs\alarm.dm" #include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm"